start.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright (C) 2005-2006 Atmel Corporation
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <config.h>
  23. #include <asm/sysreg.h>
  24. #ifndef PART_SPECIFIC_BOOTSTRAP
  25. # define PART_SPECIFIC_BOOTSTRAP
  26. #endif
  27. #define SYSREG_MMUCR_I_OFFSET 2
  28. #define SYSREG_MMUCR_S_OFFSET 4
  29. #define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
  30. #define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE) \
  31. | SYSREG_BIT(FE) | SYSREG_BIT(RE) \
  32. | SYSREG_BIT(IBE) | SYSREG_BIT(IEE))
  33. .text
  34. .global _start
  35. _start:
  36. PART_SPECIFIC_BOOTSTRAP
  37. /* Reset the Status Register */
  38. mov r0, lo(SR_INIT)
  39. orh r0, hi(SR_INIT)
  40. mtsr SYSREG_SR, r0
  41. /* Reset CPUCR and invalidate the BTB */
  42. mov r2, CPUCR_INIT
  43. mtsr SYSREG_CPUCR, r2
  44. /* Flush the caches */
  45. mov r1, 0
  46. cache r1[4], 8
  47. cache r1[0], 0
  48. sync 0
  49. /* Reset the MMU to default settings */
  50. mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
  51. mtsr SYSREG_MMUCR, r0
  52. /* Internal RAM should not need any initialization. We might
  53. have to initialize external RAM here if the part doesn't
  54. have internal RAM (or we may use the data cache) */
  55. /* Jump to cacheable segment */
  56. lddpc pc, 1f
  57. .align 2
  58. 1: .long 2f
  59. 2: lddpc sp, sp_init
  60. /* Initialize the GOT pointer */
  61. lddpc r6, got_init
  62. 3: rsub r6, pc
  63. /* Let's go */
  64. rjmp board_init_f
  65. .align 2
  66. .type sp_init,@object
  67. sp_init:
  68. .long CFG_INIT_SP_ADDR
  69. got_init:
  70. .long 3b - _GLOBAL_OFFSET_TABLE_
  71. /*
  72. * void relocate_code(new_sp, new_gd, monitor_addr)
  73. *
  74. * Relocate the u-boot image into RAM and continue from there.
  75. * Does not return.
  76. */
  77. .global relocate_code
  78. .type relocate_code,@function
  79. relocate_code:
  80. mov sp, r12 /* use new stack */
  81. mov r12, r11 /* save new_gd */
  82. mov r11, r10 /* save destination address */
  83. /* copy .text section and flush the cache along the way */
  84. lda.w r8, _text
  85. lda.w r9, _etext
  86. sub lr, r10, r8 /* relocation offset */
  87. 1: ldm r8++, r0-r3
  88. stm r10, r0-r3
  89. sub r10, -16
  90. ldm r8++, r0-r3
  91. stm r10, r0-r3
  92. sub r10, -16
  93. cp.w r8, r9
  94. cache r10[-4], 0x0d /* dcache clean/invalidate */
  95. cache r10[-4], 0x01 /* icache invalidate */
  96. brlt 1b
  97. /* flush write buffer */
  98. sync 0
  99. /* copy data sections */
  100. lda.w r9, _edata
  101. 1: ld.d r0, r8++
  102. st.d r10++, r0
  103. cp.w r8, r9
  104. brlt 1b
  105. /* zero out .bss */
  106. mov r0, 0
  107. mov r1, 0
  108. lda.w r9, _end
  109. sub r9, r8
  110. 1: st.d r10++, r0
  111. sub r9, 8
  112. brgt 1b
  113. /* jump to RAM */
  114. sub r0, pc, . - in_ram
  115. add pc, r0, lr
  116. .align 2
  117. in_ram:
  118. /* find the new GOT and relocate it */
  119. lddpc r6, got_init_reloc
  120. 3: rsub r6, pc
  121. mov r8, r6
  122. lda.w r9, _egot
  123. lda.w r10, _got
  124. sub r9, r10
  125. 1: ld.w r0, r8[0]
  126. add r0, lr
  127. st.w r8++, r0
  128. sub r9, 4
  129. brgt 1b
  130. /* Move the exception handlers */
  131. mfsr r2, SYSREG_EVBA
  132. add r2, lr
  133. mtsr SYSREG_EVBA, r2
  134. /* Do the rest of the initialization sequence */
  135. call board_init_r
  136. .align 2
  137. got_init_reloc:
  138. .long 3b - _GLOBAL_OFFSET_TABLE_