start.S 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
  4. * Scott McNutt <smcnutt@psyent.com>
  5. */
  6. #include <asm-offsets.h>
  7. #include <config.h>
  8. #include <version.h>
  9. /*
  10. * icache and dcache configuration used only for start.S.
  11. * the values are chosen so that it will work for all configuration.
  12. */
  13. #define ICACHE_LINE_SIZE 32 /* fixed 32 */
  14. #define ICACHE_SIZE_MAX 0x10000 /* 64k max */
  15. #define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */
  16. #define DCACHE_SIZE_MAX 0x10000 /* 64k max */
  17. /* RESTART */
  18. .text
  19. .global _start, _except_start, _except_end
  20. _start:
  21. wrctl status, r0 /* Disable interrupts */
  22. /*
  23. * ICACHE INIT -- only the icache line at the reset address
  24. * is invalidated at reset. So the init must stay within
  25. * the cache line size (8 words). If GERMS is used, we'll
  26. * just be invalidating the cache a second time. If cache
  27. * is not implemented initi behaves as nop.
  28. */
  29. ori r4, r0, %lo(ICACHE_LINE_SIZE)
  30. movhi r5, %hi(ICACHE_SIZE_MAX)
  31. ori r5, r5, %lo(ICACHE_SIZE_MAX)
  32. 0: initi r5
  33. sub r5, r5, r4
  34. bgt r5, r0, 0b
  35. br _except_end /* Skip the tramp */
  36. /*
  37. * EXCEPTION TRAMPOLINE -- the following gets copied
  38. * to the exception address (below), but is otherwise at the
  39. * default exception vector offset (0x0020).
  40. */
  41. _except_start:
  42. movhi et, %hi(_exception)
  43. ori et, et, %lo(_exception)
  44. jmp et
  45. _except_end:
  46. /*
  47. * INTERRUPTS -- for now, all interrupts masked and globally
  48. * disabled.
  49. */
  50. wrctl ienable, r0 /* All disabled */
  51. /*
  52. * DCACHE INIT -- if dcache not implemented, initd behaves as
  53. * nop.
  54. */
  55. ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN)
  56. movhi r5, %hi(DCACHE_SIZE_MAX)
  57. ori r5, r5, %lo(DCACHE_SIZE_MAX)
  58. mov r6, r0
  59. 1: initd 0(r6)
  60. add r6, r6, r4
  61. bltu r6, r5, 1b
  62. /*
  63. * RELOCATE CODE, DATA & COMMAND TABLE -- the following code
  64. * assumes code, data and the command table are all
  65. * contiguous. This lets us relocate everything as a single
  66. * block. Make sure the linker script matches this ;-)
  67. */
  68. nextpc r4
  69. _cur: movhi r5, %hi(_cur - _start)
  70. ori r5, r5, %lo(_cur - _start)
  71. sub r4, r4, r5 /* r4 <- cur _start */
  72. mov r8, r4
  73. movhi r5, %hi(_start)
  74. ori r5, r5, %lo(_start) /* r5 <- linked _start */
  75. mov sp, r5 /* initial stack below u-boot code */
  76. beq r4, r5, 3f
  77. movhi r6, %hi(CONFIG_SYS_MONITOR_LEN)
  78. ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN)
  79. add r6, r6, r5
  80. 2: ldwio r7, 0(r4)
  81. addi r4, r4, 4
  82. stwio r7, 0(r5)
  83. addi r5, r5, 4
  84. bne r5, r6, 2b
  85. 3:
  86. /* JUMP TO RELOC ADDR */
  87. movhi r4, %hi(_reloc)
  88. ori r4, r4, %lo(_reloc)
  89. jmp r4
  90. _reloc:
  91. /* STACK INIT -- zero top two words for call back chain. */
  92. addi sp, sp, -8
  93. stw r0, 0(sp)
  94. stw r0, 4(sp)
  95. mov fp, sp
  96. #ifdef CONFIG_DEBUG_UART
  97. /* Set up the debug UART */
  98. movhi r2, %hi(debug_uart_init@h)
  99. ori r2, r2, %lo(debug_uart_init@h)
  100. callr r2
  101. #endif
  102. /* Allocate and initialize reserved area, update SP */
  103. mov r4, sp
  104. movhi r2, %hi(board_init_f_alloc_reserve@h)
  105. ori r2, r2, %lo(board_init_f_alloc_reserve@h)
  106. callr r2
  107. mov sp, r2
  108. mov r4, sp
  109. movhi r2, %hi(board_init_f_init_reserve@h)
  110. ori r2, r2, %lo(board_init_f_init_reserve@h)
  111. callr r2
  112. /* Update frame-pointer */
  113. mov fp, sp
  114. /* Call board_init_f -- never returns */
  115. mov r4, r0
  116. movhi r2, %hi(board_init_f@h)
  117. ori r2, r2, %lo(board_init_f@h)
  118. callr r2
  119. /*
  120. * NEVER RETURNS -- but branch to the _start just
  121. * in case ;-)
  122. */
  123. br _start
  124. /*
  125. * relocate_code -- Nios2 handles the relocation above. But
  126. * the generic board code monkeys with the heap, stack, etc.
  127. * (it makes some assumptions that may not be appropriate
  128. * for Nios). Nevertheless, we capitulate here.
  129. *
  130. * We'll call the board_init_r from here since this isn't
  131. * supposed to return.
  132. *
  133. * void relocate_code (ulong sp, gd_t *global_data,
  134. * ulong reloc_addr)
  135. * __attribute__ ((noreturn));
  136. */
  137. .text
  138. .global relocate_code
  139. relocate_code:
  140. mov sp, r4 /* Set the new sp */
  141. mov r4, r5
  142. /*
  143. * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
  144. * and between __bss_start and __bss_end.
  145. */
  146. movhi r5, %hi(__bss_start)
  147. ori r5, r5, %lo(__bss_start)
  148. movhi r6, %hi(__bss_end)
  149. ori r6, r6, %lo(__bss_end)
  150. beq r5, r6, 5f
  151. 4: stw r0, 0(r5)
  152. addi r5, r5, 4
  153. bne r5, r6, 4b
  154. 5:
  155. movhi r8, %hi(board_init_r@h)
  156. ori r8, r8, %lo(board_init_r@h)
  157. callr r8
  158. ret