start.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
  3. * Scott McNutt <smcnutt@psyent.com>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <config.h>
  24. #include <timestamp.h>
  25. #include <version.h>
  26. #if !defined(CONFIG_IDENT_STRING)
  27. #define CONFIG_IDENT_STRING ""
  28. #endif
  29. #define STATUS_INIT 0x8600 /* IE=1, IPRI=2 */
  30. /*************************************************************************
  31. * RESTART
  32. ************************************************************************/
  33. .text
  34. .global _start
  35. _start:
  36. bsr 0f
  37. nop
  38. .long _start
  39. /* GERMS -- The "standard-32" configuration GERMS monitor looks
  40. * for the string "Nios" at flash_base + 0xc (actually it only
  41. * tests for 'N', 'i'). You can leave support for this in place
  42. * as it's only a few words.
  43. */
  44. . = _start + 0x000c
  45. .string "Nios"
  46. .align 4
  47. 0:
  48. /*
  49. * Early setup -- set cwp = HI_LIMIT, IPRI = 2, IE = 1 to
  50. * enable underflow exceptions. Disable cache.
  51. * NOTE: %o7 has return addr -- save in %g7 use later.
  52. */
  53. mov %g7, %o7
  54. pfx 2 /* WVALID */
  55. rdctl %g0
  56. lsri %g0, 1
  57. pfx %hi(STATUS_INIT)
  58. or %g0, %lo(STATUS_INIT)
  59. wrctl %g0 /* update status */
  60. nop
  61. /*
  62. * STACK
  63. */
  64. pfx %hi(CONFIG_SYS_INIT_SP)
  65. movi %sp, %lo(CONFIG_SYS_INIT_SP)
  66. pfx %xhi(CONFIG_SYS_INIT_SP)
  67. movhi %sp, %xlo(CONFIG_SYS_INIT_SP)
  68. mov %fp, %sp
  69. pfx %hi(4*16)
  70. subi %sp, %lo(4*16) /* Space for reg window mgmt */
  71. /*
  72. * RELOCATE -- %g7 has return addr from bsr at _start.
  73. */
  74. pfx %hi(__u_boot_cmd_end)
  75. movi %g5, %lo(__u_boot_cmd_end)
  76. pfx %xhi(__u_boot_cmd_end)
  77. movhi %g5, %xlo(__u_boot_cmd_end) /* %g5 <- end address */
  78. lsli %g7, 1 /* mem = retaddr << 1 */
  79. mov %g6, %g7
  80. subi %g6, 4 /* %g6 <- src addr */
  81. ld %g7, [%g7] /* %g7 <- dst addr */
  82. /* No need to move text sections if we're already located
  83. * at the proper address.
  84. */
  85. cmp %g7, %g6
  86. ifs cc_z
  87. br reloc
  88. nop /* delay slot */
  89. 1: cmp %g7, %g5
  90. skps cc_nz
  91. br 2f
  92. nop /* delay slot */
  93. ld %g0, [%g6]
  94. addi %g6, 4 /* src++ */
  95. st [%g7], %g0
  96. addi %g7, 4 /* dst++ */
  97. br 1b
  98. nop /* delay slot */
  99. 2:
  100. /*
  101. * Jump to relocation address
  102. */
  103. pfx %hi(reloc@h)
  104. movi %g0, %lo(reloc@h)
  105. pfx %xhi(reloc@h)
  106. movhi %g0, %xlo(reloc@h)
  107. jmp %g0
  108. nop /* delay slot */
  109. reloc:
  110. /*
  111. * CLEAR BSS
  112. */
  113. pfx %hi(__bss_end)
  114. movi %g5, %lo(__bss_end)
  115. pfx %xhi(__bss_end)
  116. movhi %g5, %xlo(__bss_end) /* %g5 <- end address */
  117. pfx %hi(__bss_start)
  118. movi %g7, %lo(__bss_start)
  119. pfx %xhi(__bss_start)
  120. movhi %g7, %xlo(__bss_start) /* %g7 <- end address */
  121. movi %g0, 0
  122. 3: cmp %g7, %g5
  123. skps cc_nz
  124. br 4f
  125. nop /* delay slot */
  126. st [%g7], %g0
  127. addi %g7, 4 /* (delay slot) dst++ */
  128. br 3b
  129. nop /* delay slot */
  130. 4:
  131. /*
  132. * INIT VECTOR TABLE
  133. */
  134. pfx %hi(CONFIG_SYS_VECT_BASE)
  135. movi %g0, %lo(CONFIG_SYS_VECT_BASE)
  136. pfx %xhi(CONFIG_SYS_VECT_BASE)
  137. movhi %g0, %xlo(CONFIG_SYS_VECT_BASE) /* dst */
  138. mov %l0, %g0
  139. pfx %hi(_vectors)
  140. movi %g1, %lo(_vectors)
  141. pfx %xhi(_vectors)
  142. movhi %g1, %xlo(_vectors) /* src */
  143. bgen %g2, 6 /* cnt = 64 */
  144. ldp %g3, [%l0, 3] /* bkpt vector */
  145. ldp %g4, [%l0, 4] /* single step vector */
  146. 5: ld %g7, [%g1]
  147. addi %g1, 4 /* src++ */
  148. st [%g0], %g7
  149. addi %g0, 4 /* dst++ */
  150. subi %g2, 1 /* cnt-- */
  151. ifrnz %g2
  152. br 5b
  153. nop /* delay slot */
  154. #if defined(CONFIG_ROM_STUBS)
  155. /* Restore the breakpoint and single step exception
  156. * vectors to their original values.
  157. */
  158. stp [%l0,3], %g3 /* breakpoint */
  159. stp [%l0,4], %g4 /* single step */
  160. #endif
  161. /* For debug startup convenience ... software breakpoints
  162. * set prior to this point may not succeed ;-)
  163. */
  164. .global __start
  165. __start:
  166. /*
  167. * Call board_init -- never returns
  168. */
  169. pfx %hi(board_init@h)
  170. movi %g1, %lo(board_init@h)
  171. pfx %xhi(board_init@h)
  172. movhi %g1, %xlo(board_init@h)
  173. call %g1
  174. nop /* Delaly slot */
  175. /* NEVER RETURNS */
  176. /*
  177. * dly_clks -- Nios doesn't have a time/clk reference for simple
  178. * delay loops, so we do our best by counting instruction cycles.
  179. * A control register that counts system clock cycles would be
  180. * a handy feature -- hint for Altera ;-)
  181. */
  182. .globl dly_clks
  183. /* Each loop is 4 instructions as delay slot is always
  184. * executed. Each instruction is approximately 4 clocks
  185. * (according to some lame info from Altera). So ...
  186. * ... each loop is about 16 clocks.
  187. */
  188. dly_clks:
  189. lsri %o0, 4 /* cnt/16 */
  190. 8: skprnz %o0
  191. br 9f
  192. subi %o0, 1 /* cnt--, Delay slot */
  193. br 8b
  194. nop
  195. 9: lret
  196. nop /* Delay slot */
  197. .data
  198. .globl version_string
  199. version_string:
  200. .ascii U_BOOT_VERSION
  201. .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
  202. .ascii CONFIG_IDENT_STRING, "\0"