start.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * (C) Copyright 2007 Michal Simek
  3. * (C) Copyright 2004 Atmark Techno, Inc.
  4. *
  5. * Michal SIMEK <monstr@monstr.eu>
  6. * Yasushi SHOJI <yashi@atmark-techno.com>
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <asm-offsets.h>
  27. #include <config.h>
  28. .text
  29. .global _start
  30. _start:
  31. /*
  32. * reserve registers:
  33. * r10: Stores little/big endian offset for vectors
  34. * r2: Stores imm opcode
  35. * r3: Stores brai opcode
  36. */
  37. mts rmsr, r0 /* disable cache */
  38. addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET
  39. addi r1, r1, -4 /* Decrement SP to top of memory */
  40. /* Find-out if u-boot is running on BIG/LITTLE endian platform
  41. * There are some steps which is necessary to keep in mind:
  42. * 1. Setup offset value to r6
  43. * 2. Store word offset value to address 0x0
  44. * 3. Load just byte from address 0x0
  45. * 4a) LITTLE endian - r10 contains 0x2 because it is the smallest
  46. * value that's why is on address 0x0
  47. * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3
  48. */
  49. addik r6, r0, 0x2 /* BIG/LITTLE endian offset */
  50. lwi r7, r0, 0x28
  51. swi r6, r0, 0x28 /* used first unused MB vector */
  52. lbui r10, r0, 0x28 /* used first unused MB vector */
  53. swi r7, r0, 0x28
  54. /* add opcode instruction for 32bit jump - 2 instruction imm & brai */
  55. addi r2, r0, 0xb0000000 /* hex b000 opcode imm */
  56. addi r3, r0, 0xb8080000 /* hew b808 opcode brai */
  57. #ifdef CONFIG_SYS_RESET_ADDRESS
  58. /* reset address */
  59. swi r2, r0, 0x0 /* reset address - imm opcode */
  60. swi r3, r0, 0x4 /* reset address - brai opcode */
  61. addik r6, r0, CONFIG_SYS_RESET_ADDRESS
  62. sw r6, r1, r0
  63. lhu r7, r1, r0
  64. shi r7, r0, 0x2
  65. shi r6, r0, 0x6
  66. /*
  67. * Copy U-Boot code to CONFIG_SYS_TEXT_BASE
  68. * solve problem with sbrk_base
  69. */
  70. #if (CONFIG_SYS_RESET_ADDRESS != CONFIG_SYS_TEXT_BASE)
  71. addi r4, r0, __end
  72. addi r5, r0, __text_start
  73. rsub r4, r5, r4 /* size = __end - __text_start */
  74. addi r6, r0, CONFIG_SYS_RESET_ADDRESS /* source address */
  75. addi r7, r0, 0 /* counter */
  76. 4:
  77. lw r8, r6, r7
  78. sw r8, r5, r7
  79. addi r7, r7, 0x4
  80. cmp r8, r4, r7
  81. blti r8, 4b
  82. #endif
  83. #endif
  84. #ifdef CONFIG_SYS_USR_EXCEP
  85. /* user_vector_exception */
  86. swi r2, r0, 0x8 /* user vector exception - imm opcode */
  87. swi r3, r0, 0xC /* user vector exception - brai opcode */
  88. addik r6, r0, _exception_handler
  89. sw r6, r1, r0
  90. /*
  91. * BIG ENDIAN memory map for user exception
  92. * 0x8: 0xB000XXXX
  93. * 0xC: 0xB808XXXX
  94. *
  95. * then it is necessary to count address for storing the most significant
  96. * 16bits from _exception_handler address and copy it to
  97. * 0xa address. Big endian use offset in r10=0 that's why is it just
  98. * 0xa address. The same is done for the least significant 16 bits
  99. * for 0xe address.
  100. *
  101. * LITTLE ENDIAN memory map for user exception
  102. * 0x8: 0xXXXX00B0
  103. * 0xC: 0xXXXX08B8
  104. *
  105. * Offset is for little endian setup to 0x2. rsubi instruction decrease
  106. * address value to ensure that points to proper place which is
  107. * 0x8 for the most significant 16 bits and
  108. * 0xC for the least significant 16 bits
  109. */
  110. lhu r7, r1, r10
  111. rsubi r8, r10, 0xa
  112. sh r7, r0, r8
  113. rsubi r8, r10, 0xe
  114. sh r6, r0, r8
  115. #endif
  116. #ifdef CONFIG_SYS_INTC_0
  117. /* interrupt_handler */
  118. swi r2, r0, 0x10 /* interrupt - imm opcode */
  119. swi r3, r0, 0x14 /* interrupt - brai opcode */
  120. addik r6, r0, _interrupt_handler
  121. sw r6, r1, r0
  122. lhu r7, r1, r10
  123. rsubi r8, r10, 0x12
  124. sh r7, r0, r8
  125. rsubi r8, r10, 0x16
  126. sh r6, r0, r8
  127. #endif
  128. /* hardware exception */
  129. swi r2, r0, 0x20 /* hardware exception - imm opcode */
  130. swi r3, r0, 0x24 /* hardware exception - brai opcode */
  131. addik r6, r0, _hw_exception_handler
  132. sw r6, r1, r0
  133. lhu r7, r1, r10
  134. rsubi r8, r10, 0x22
  135. sh r7, r0, r8
  136. rsubi r8, r10, 0x26
  137. sh r6, r0, r8
  138. /* enable instruction and data cache */
  139. mfs r12, rmsr
  140. ori r12, r12, 0xa0
  141. mts rmsr, r12
  142. clear_bss:
  143. /* clear BSS segments */
  144. addi r5, r0, __bss_start
  145. addi r4, r0, __bss_end
  146. cmp r6, r5, r4
  147. beqi r6, 3f
  148. 2:
  149. swi r0, r5, 0 /* write zero to loc */
  150. addi r5, r5, 4 /* increment to next loc */
  151. cmp r6, r5, r4 /* check if we have reach the end */
  152. bnei r6, 2b
  153. 3: /* jumping to board_init */
  154. brai board_init
  155. 1: bri 1b
  156. /*
  157. * Read 16bit little endian
  158. */
  159. .text
  160. .global in16
  161. .ent in16
  162. .align 2
  163. in16: lhu r3, r0, r5
  164. bslli r4, r3, 8
  165. bsrli r3, r3, 8
  166. andi r4, r4, 0xffff
  167. or r3, r3, r4
  168. rtsd r15, 8
  169. sext16 r3, r3
  170. .end in16
  171. /*
  172. * Write 16bit little endian
  173. * first parameter(r5) - address, second(r6) - short value
  174. */
  175. .text
  176. .global out16
  177. .ent out16
  178. .align 2
  179. out16: bslli r3, r6, 8
  180. bsrli r6, r6, 8
  181. andi r3, r3, 0xffff
  182. or r3, r3, r6
  183. sh r3, r0, r5
  184. rtsd r15, 8
  185. or r0, r0, r0
  186. .end out16