Boot.s 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. MODULE ?cstartup
  2. ;; Forward declaration of sections.
  3. SECTION IRQ_STACK:DATA:NOROOT(3)
  4. SECTION FIQ_STACK:DATA:NOROOT(3)
  5. SECTION SVC_STACK:DATA:NOROOT(3)
  6. SECTION ABT_STACK:DATA:NOROOT(3)
  7. SECTION UND_STACK:DATA:NOROOT(3)
  8. SECTION CSTACK:DATA:NOROOT(3)
  9. //------------------------------------------------------------------------------
  10. // Headers
  11. //------------------------------------------------------------------------------
  12. #define __ASSEMBLY__
  13. //------------------------------------------------------------------------------
  14. // Definitions
  15. //------------------------------------------------------------------------------
  16. #define IRAM_BASE 0x300000
  17. #define SYS_CPU_CTL 0xe4900208
  18. #define AIC 0xFFFFF000
  19. #define AIC_IVR 0x10
  20. #define AIC_EOICR 0x38
  21. #define ARM_MODE_ABT 0x17
  22. #define ARM_MODE_FIQ 0x11
  23. #define ARM_MODE_IRQ 0x12
  24. #define ARM_MODE_SVC 0x13
  25. #define ARM_MODE_SYS 0x1F
  26. #define I_BIT 0x80
  27. #define F_BIT 0x40
  28. //------------------------------------------------------------------------------
  29. // Startup routine
  30. //------------------------------------------------------------------------------
  31. /*
  32. Exception vectors
  33. */
  34. // SECTION .vectors:CODE:NOROOT(2)
  35. SECTION .intvec:CODE:NOROOT(2)
  36. PUBLIC __vector
  37. PUBLIC __iar_program_start
  38. ARM ; Always ARM mode after reset
  39. __vector:
  40. ldr pc, Reset
  41. DCD 0x424b5244
  42. //LDR PC, Undefined_Addr
  43. LDR PC, SWI_Addr
  44. LDR PC, Prefetch_Addr
  45. LDR PC, Abort_Addr
  46. NOP ; Reserved vector
  47. LDR PC, IRQ_Addr
  48. LDR PC, FIQ_Addr
  49. IMPORT undef_handler
  50. IMPORT swi_handler
  51. IMPORT prefetch_handler
  52. IMPORT data_abort_handler
  53. IMPORT irq_handler
  54. IMPORT fiq_handler
  55. Reset: dc32 __iar_program_start
  56. Undefined_Addr: dc32 undef_handler ;Undefined_Handler
  57. SWI_Addr: dc32 swi_handler ;SWI_Handler
  58. Prefetch_Addr: dc32 prefetch_handler ;ExceptionPAB
  59. Abort_Addr: dc32 data_abort_handler ;ExceptionDAB
  60. Reserved_Addr: dc32 0 ;ExceptionREV
  61. IRQ_Addr: dc32 irq_handler
  62. FIQ_Addr: dc32 fiq_handler
  63. MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR
  64. USR_MODE DEFINE 0x10 ; User mode
  65. FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
  66. IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
  67. SVC_MODE DEFINE 0x13 ; Supervisor mode
  68. ABT_MODE DEFINE 0x17 ; Abort mode
  69. UND_MODE DEFINE 0x1B ; Undefined Instruction mode
  70. SYS_MODE DEFINE 0x1F ; System mode
  71. CP_DIS_MASK DEFINE 0xFFFFEFFA
  72. SECTION .text:CODE:NOROOT(2)
  73. EXTERN ?main
  74. REQUIRE __vector
  75. __iar_program_start:
  76. b reset_handler
  77. // DCD 0x424b5241
  78. // DCD 0
  79. // DCD 0
  80. reset_handler:
  81. ;==================================================================
  82. ; Reset registers
  83. ;==================================================================
  84. MOV r2, #0
  85. MOV r3, #0
  86. MOV r4, #0
  87. MOV r5, #0
  88. MOV r6, #0
  89. MOV r7, #0
  90. MOV r8, #0
  91. MOV r9, #0
  92. MOV r10, #0
  93. MOV r11, #0
  94. MOV r12, #0
  95. ;==================================================================
  96. ; Disable caches, MMU and branch prediction in case they were left enabled from an earlier run
  97. ; This does not need to be done from a cold reset
  98. ;==================================================================
  99. MRC p15, 0, r0, c1, c0, 0 ; Read CP15 System Control register
  100. BIC r0, r0, #(0x1 << 12) ; Clear I bit 12 to disable I Cache
  101. ;ORR r0, r0, #(0x1 << 12) ; Set I bit 12 to enable I Cache
  102. BIC r0, r0, #(0x1 << 2) ; Clear C bit 2 to disable D Cache
  103. BIC r0, r0, #0x1 ; Clear M bit 0 to disable MMU
  104. BIC r0, r0, #(0x1 << 11) ; Clear Z bit 11 to disable branch prediction
  105. MCR p15, 0, r0, c1, c0, 0 ; Write value back to CP15 System Control register
  106. ;==================================================================
  107. ; Cache Invalidation code for Cortex-A7
  108. ; NOTE: Neither Caches, nor MMU, nor BTB need post-reset invalidation on Cortex-A7,
  109. ; but forcing a cache invalidation, makes the code more portable to other CPUs (e.g. Cortex-A9)
  110. ;==================================================================
  111. ; Invalidate L1 Instruction Cache
  112. MRC p15, 1, r0, c0, c0, 1 ; Read Cache Level ID Register (CLIDR)
  113. TST r0, #0x3 ; Harvard Cache?
  114. MOV r0, #0 ; SBZ
  115. MCRNE p15, 0, r0, c7, c5, 0 ; ICIALLU - Invalidate instruction cache and flush branch target cache
  116. ; Invalidate Data/Unified Caches
  117. MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR
  118. ANDS r3, r0, #0x07000000 ; Extract coherency level
  119. MOV r3, r3, LSR #23 ; Total cache levels << 1
  120. BEQ Finished ; If 0, no need to clean
  121. MOV r10, #0 ; R10 holds current cache level << 1
  122. Loop1 ADD r2, r10, r10, LSR #1 ; R2 holds cache "Set" position
  123. MOV r1, r0, LSR r2 ; Bottom 3 bits are the Cache-type for this level
  124. AND r1, r1, #7 ; Isolate those lower 3 bits
  125. CMP r1, #2
  126. BLT Skip ; No cache or only instruction cache at this level
  127. MCR p15, 2, r10, c0, c0, 0 ; Write the Cache Size selection register
  128. ISB ; ISB to sync the change to the CacheSizeID reg
  129. MRC p15, 1, r1, c0, c0, 0 ; Reads current Cache Size ID register
  130. AND r2, r1, #7 ; Extract the line length field
  131. ADD r2, r2, #4 ; Add 4 for the line length offset (log2 16 bytes)
  132. LDR r4, =0x3FF
  133. ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned)
  134. CLZ r5, r4 ; R5 is the bit position of the way size increment
  135. LDR r7, =0x7FFF
  136. ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned)
  137. Loop2 MOV r9, r4 ; R9 working copy of the max way size (right aligned)
  138. Loop3 ORR r11, r10, r9, LSL r5 ; Factor in the Way number and cache number into R11
  139. ORR r11, r11, r7, LSL r2 ; Factor in the Set number
  140. MCR p15, 0, r11, c7, c6, 2 ; Invalidate by Set/Way
  141. SUBS r9, r9, #1 ; Decrement the Way number
  142. BGE Loop3
  143. SUBS r7, r7, #1 ; Decrement the Set number
  144. BGE Loop2
  145. Skip ADD r10, r10, #2 ; increment the cache number
  146. CMP r3, r10
  147. BGT Loop1
  148. Finished
  149. ;==================================================================
  150. ; Invalidate TLB
  151. ;==================================================================
  152. MOV r0, #0
  153. MCR p15, 0, r0, c8, c7, 0
  154. ;==================================================================
  155. ; Branch Prediction Enable
  156. ;==================================================================
  157. ;MOV r1, #0
  158. ;MRC p15, 0, r1, c1, c0, 0 /* Read Control Register configuration data */
  159. ;ORR r1, r1, #(0x1 << 11) /* Global BP Enable bit */
  160. ;MCR p15, 0, r1, c1, c0, 0 /* Write Control Register configuration data */
  161. ; Initialize the stack pointers.
  162. ; The pattern below can be used for any of the exception stacks:
  163. ; FIQ, IRQ, SVC, ABT, UND, SYS.
  164. ; The USR mode uses the same stack as SYS.
  165. ; The stack segments must be defined in the linker command file,
  166. ; and be declared above.
  167. mrs r0,cpsr ; Original PSR value
  168. bic r0,r0,#MODE_MSK ; Clear the mode bits
  169. orr r0,r0,#SVC_MODE ; Set Supervisor mode bits
  170. msr cpsr_c,r0 ; Change the mode
  171. ldr sp,=SFE(SVC_STACK) ; End of SVC_STACK
  172. bic r0,r0,#MODE_MSK ; Clear the mode bits
  173. orr r0,r0,#ABT_MODE ; Set Abort mode bits
  174. msr cpsr_c,r0 ; Change the mode
  175. ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK
  176. bic r0,r0,#MODE_MSK ; Clear the mode bits
  177. orr r0,r0,#UND_MODE ; Set Undefined mode bits
  178. msr cpsr_c,r0 ; Change the mode
  179. ldr sp,=SFE(UND_STACK) ; End of UND_STACK
  180. bic r0,r0,#MODE_MSK ; Clear the mode bits
  181. orr r0,r0,#FIQ_MODE ; Set FIR mode bits
  182. msr cpsr_c,r0 ; Change the mode
  183. ldr sp,=SFE(FIQ_STACK) ; End of FIQ_STACK
  184. bic r0,r0,#MODE_MSK ; Clear the mode bits
  185. orr r0,r0,#IRQ_MODE ; Set IRQ mode bits
  186. msr cpsr_c,r0 ; Change the mode
  187. ldr sp,=SFE(IRQ_STACK) ; End of IRQ_STACK
  188. bic r0,r0,#MODE_MSK ; Clear the mode bits
  189. orr r0,r0,#SYS_MODE ; Set System mode bits
  190. msr cpsr_c,r0 ; Change the mode
  191. ldr sp,=SFE(CSTACK) ; End of CSTACK
  192. /* Branch to main() */
  193. LDR r0, =?main
  194. BLX r0
  195. /* Loop indefinitely when program is finished */
  196. loop4:
  197. B loop4
  198. END