crtat91sam7s_bootrom.S 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. /*
  2. * Copyright (C) 2005-2008 by egnite Software GmbH.
  3. * Copyright (C) 2008 by egnite GmbH.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. *
  34. */
  35. /*
  36. * Revision 1.1 2010/12/14 18:12:58 ve2yag
  37. * New .vectors section copied to sram at begin of .data segment.
  38. * sram is remapped before call NutInit.
  39. *
  40. * $Id: crtat91sam7s_bootrom.S 3256 2010-12-16 02:15:18Z ve2yag $
  41. */
  42. #include <cfg/clock.h>
  43. #include <cfg/memory.h>
  44. #include <arch/arm.h>
  45. #ifndef PLL_MUL_VAL
  46. #define PLL_MUL_VAL 72
  47. #endif
  48. #ifndef PLL_DIV_VAL
  49. #define PLL_DIV_VAL 14
  50. #endif
  51. #if MASTER_CLOCK_PRES == 1
  52. #define AT91MCK_PRES PMC_PRES_CLK
  53. #elif MASTER_CLOCK_PRES == 4
  54. #define AT91MCK_PRES PMC_PRES_CLK_4
  55. #elif MASTER_CLOCK_PRES == 8
  56. #define AT91MCK_PRES PMC_PRES_CLK_8
  57. #elif MASTER_CLOCK_PRES == 16
  58. #define AT91MCK_PRES PMC_PRES_CLK_16
  59. #elif MASTER_CLOCK_PRES == 32
  60. #define AT91MCK_PRES PMC_PRES_CLK_32
  61. #elif MASTER_CLOCK_PRES == 64
  62. #define AT91MCK_PRES PMC_PRES_CLK_64
  63. #else
  64. #define AT91MCK_PRES PMC_PRES_CLK_2
  65. #endif
  66. #ifndef IRQ_STACK_SIZE
  67. #define IRQ_STACK_SIZE 512
  68. #endif
  69. #ifndef FIQ_STACK_SIZE
  70. #define FIQ_STACK_SIZE 256
  71. #endif
  72. #ifndef ABT_STACK_SIZE
  73. #define ABT_STACK_SIZE 128
  74. #endif
  75. #ifndef UND_STACK_SIZE
  76. #define UND_STACK_SIZE 128
  77. #endif
  78. #ifdef NUTMEM_SDRAM_BASE
  79. #if NUTMEM_SDRAM_BANKS == 2
  80. #define SDRAMC_CFG_NB 0
  81. #else
  82. #define SDRAMC_CFG_NB SDRAMC_NB
  83. #endif
  84. #if NUTMEM_SDRAM_COLBITS == 8
  85. #define SDRAMC_CFG_NC SDRAMC_NC_8
  86. #elif NUTMEM_SDRAM_COLBITS == 9
  87. #define SDRAMC_CFG_NC SDRAMC_NC_9
  88. #elif NUTMEM_SDRAM_COLBITS == 10
  89. #define SDRAMC_CFG_NC SDRAMC_NC_10
  90. #else
  91. #define SDRAMC_CFG_NC SDRAMC_NC_11
  92. #endif
  93. #if NUTMEM_SDRAM_ROWBITS == 11
  94. #define SDRAMC_CFG_NR SDRAMC_NR_11
  95. #elif NUTMEM_SDRAM_ROWBITS == 12
  96. #define SDRAMC_CFG_NR SDRAMC_NR_12
  97. #else
  98. #define SDRAMC_CFG_NR SDRAMC_NR_13
  99. #endif
  100. #if NUTMEM_SDRAM_CASLAT == 1
  101. #define SDRAMC_CFG_CAS SDRAMC_CAS_1
  102. #elif NUTMEM_SDRAM_CASLAT == 2
  103. #define SDRAMC_CFG_CAS SDRAMC_CAS_2
  104. #else
  105. #define SDRAMC_CFG_CAS SDRAMC_CAS_3
  106. #endif
  107. #endif /* NUTMEM_SDRAM_BASE */
  108. /*
  109. * Section 0b: Vector table and reset entry.
  110. */
  111. .section .vectors,"ax",%progbits
  112. ldr pc, [pc, #24] /* Reset */
  113. ldr pc, [pc, #24] /* Undefined instruction */
  114. ldr pc, [pc, #24] /* Software interrupt */
  115. ldr pc, [pc, #24] /* Prefetch abort */
  116. ldr pc, [pc, #24] /* Data abort */
  117. ldr pc, [pc, #24] /* Reserved */
  118. /*
  119. * On IRQ the PC will be loaded from AIC_IVR, which
  120. * provides the address previously set in AIC_SVR.
  121. * The interrupt routine will be called in ARM_MODE_IRQ
  122. * with IRQ disabled and FIQ unchanged.
  123. */
  124. ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */
  125. ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */
  126. .word _start
  127. .word __undef
  128. .word __swi
  129. .word __prefetch_abort
  130. .word __data_abort
  131. .ltorg
  132. /*
  133. * Section 0: Vector table and reset entry.
  134. */
  135. .section .init0,"ax",%progbits
  136. .global __vectors
  137. __vectors:
  138. ldr pc, [pc, #24] /* Reset */
  139. ldr pc, [pc, #24] /* Undefined instruction */
  140. ldr pc, [pc, #24] /* Software interrupt */
  141. ldr pc, [pc, #24] /* Prefetch abort */
  142. ldr pc, [pc, #24] /* Data abort */
  143. ldr pc, [pc, #24] /* Reserved */
  144. /*
  145. * On IRQ the PC will be loaded from AIC_IVR, which
  146. * provides the address previously set in AIC_SVR.
  147. * The interrupt routine will be called in ARM_MODE_IRQ
  148. * with IRQ disabled and FIQ unchanged.
  149. */
  150. ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */
  151. ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */
  152. .word _start
  153. .word __undef
  154. .word __swi
  155. .word __prefetch_abort
  156. .word __data_abort
  157. .weak __undef
  158. .set __undef, __xcpt_dummy
  159. .weak __swi
  160. .set __swi, __xcpt_dummy
  161. .weak __prefetch_abort
  162. .set __prefetch_abort, __xcpt_dummy
  163. .weak __data_abort
  164. .set __data_abort, __xcpt_dummy
  165. .global __xcpt_dummy
  166. __xcpt_dummy:
  167. b __xcpt_dummy
  168. .ltorg
  169. /*
  170. * Section 1: Hardware initialization.
  171. */
  172. .section .init1, "ax", %progbits
  173. .globl _start
  174. _start:
  175. /*
  176. * Use 2 cycles for flash access.
  177. */
  178. ldr r1, =MC_BASE
  179. mov r0, #MC_FWS_2R3W
  180. str r0, [r1, #MC_FMR_OFF]
  181. /*
  182. * Disable all interrupts. Useful for debugging w/o target reset.
  183. */
  184. ldr r1, =AIC_BASE
  185. mvn r0, #0
  186. str r0, [r1, #AIC_EOICR_OFF]
  187. str r0, [r1, #AIC_IDCR_OFF]
  188. /*
  189. * The watchdog is enabled after processor reset.
  190. */
  191. #ifdef NUT_WDT_START
  192. #if NUT_WDT_START
  193. /* Configure the watchdog. */
  194. ldr r1, =WDT_BASE
  195. ldr r0, =NUT_WDT_START
  196. str r0, [r1, #WDT_MR_OFF]
  197. #endif
  198. #else
  199. /* Disable the watchdog. */
  200. ldr r1, =WDT_BASE
  201. ldr r0, =WDT_WDDIS
  202. str r0, [r1, #WDT_MR_OFF]
  203. #endif
  204. /*
  205. * Enable the main oscillator. Set startup time of 6 * 8 slow
  206. * clock cycles and wait until oscillator is stabilized.
  207. */
  208. ldr r1, =PMC_BASE
  209. mov r0, #(6 << 8)
  210. orr r0, r0, #CKGR_MOSCEN
  211. str r0, [r1, #CKGR_MOR_OFF]
  212. wait_moscs:
  213. ldr r0, [r1, #PMC_SR_OFF]
  214. tst r0, #PMC_MOSCS
  215. beq wait_moscs
  216. /*
  217. * Switch to Slow clock in case PLL was already set up.
  218. */
  219. ldr r0, [r1, #PMC_MCKR_OFF]
  220. and r0, r0, #~PMC_CSS
  221. /* Slow Clock. The next statement really isn't needed.
  222. ** It is included for code clarity */
  223. orr r0, r0, #PMC_CSS_SLOW_CLK
  224. str r0, [r1, #PMC_MCKR_OFF]
  225. wait_slowsel:
  226. ldr r0, [r1, #PMC_SR_OFF]
  227. tst r0, #PMC_MCKRDY
  228. beq wait_slowsel
  229. /*
  230. * Set PLL:
  231. * PLLfreq = crystal / divider * (multiplier + 1)
  232. * Wait 28 clock cycles until PLL is locked.
  233. */
  234. ldr r0, =((PLL_MUL_VAL << CKGR_MUL_LSB) | (28 << CKGR_PLLCOUNT_LSB) | (PLL_DIV_VAL << CKGR_DIV_LSB))
  235. str r0, [r1, #CKGR_PLLR_OFF]
  236. wait_lock:
  237. ldr r0, [r1, #PMC_SR_OFF]
  238. tst r0, #PMC_LOCK
  239. beq wait_lock
  240. /*
  241. * Set master clock prescaler.
  242. */
  243. mov r0, #AT91MCK_PRES
  244. str r0, [r1, #PMC_MCKR_OFF]
  245. wait_presrdy:
  246. ldr r0, [r1, #PMC_SR_OFF]
  247. tst r0, #PMC_MCKRDY
  248. beq wait_presrdy
  249. /*
  250. * Switch to PLL clock.
  251. */
  252. ldr r0, [r1, #PMC_MCKR_OFF]
  253. orr r0, r0, #PMC_CSS_PLL_CLK
  254. str r0, [r1, #PMC_MCKR_OFF]
  255. wait_pllsel:
  256. ldr r0, [r1, #PMC_SR_OFF]
  257. tst r0, #PMC_MCKRDY
  258. beq wait_pllsel
  259. /*
  260. * Enable SDRAM interface, if configured.
  261. */
  262. #ifdef NUTMEM_SDRAM_BASE
  263. /* Enable SDRAM control at PIO A. */
  264. ldr r1, =PIOA_BASE
  265. ldr r0, =(_BV(PA23_NWR1_B) \
  266. | _BV(PA24_SDA10_B) \
  267. | _BV(PA25_SDCKE_B) \
  268. | _BV(PA26_NCS1_B) \
  269. | _BV(PA27_SDWE_B) \
  270. | _BV(PA28_CAS_B) \
  271. | _BV(PA29_RAS_B))
  272. str r0, [r1, #PIO_BSR_OFF]
  273. str r0, [r1, #PIO_PDR_OFF]
  274. /* Enable address bus (A0, A2-A11, A13-A17) at PIO B. */
  275. ldr r1, =PIOB_BASE
  276. ldr r0, =(_BV(PB0_A0_B) \
  277. | _BV(PB2_A2_B) \
  278. | _BV(PB3_A3_B) \
  279. | _BV(PB4_A4_B) \
  280. | _BV(PB5_A5_B) \
  281. | _BV(PB6_A6_B) \
  282. | _BV(PB7_A7_B) \
  283. | _BV(PB8_A8_B) \
  284. | _BV(PB9_A9_B) \
  285. | _BV(PB10_A10_B) \
  286. | _BV(PB11_A11_B) \
  287. | _BV(PB13_A13_B) \
  288. | _BV(PB14_A14_B) \
  289. | _BV(PB15_A15_B) \
  290. | _BV(PB16_A16_B) \
  291. | _BV(PB17_A17_B))
  292. str r0, [r1, #PIO_BSR_OFF]
  293. str r0, [r1, #PIO_PDR_OFF]
  294. /* Enable 16 bit data bus at PIO C. */
  295. ldr r1, =PIOC_BASE
  296. ldr r0, =(_BV(PC0_D0_A) \
  297. | _BV(PC1_D1_A) \
  298. | _BV(PC2_D2_A) \
  299. | _BV(PC3_D3_A) \
  300. | _BV(PC4_D4_A) \
  301. | _BV(PC5_D5_A) \
  302. | _BV(PC6_D6_A) \
  303. | _BV(PC7_D7_A) \
  304. | _BV(PC8_D8_A) \
  305. | _BV(PC9_D9_A) \
  306. | _BV(PC10_D10_A) \
  307. | _BV(PC11_D11_A) \
  308. | _BV(PC12_D12_A) \
  309. | _BV(PC13_D13_A) \
  310. | _BV(PC14_D14_A) \
  311. | _BV(PC15_D15_A))
  312. str r0, [r1, #PIO_ASR_OFF]
  313. str r0, [r1, #PIO_PDR_OFF]
  314. /* Enable SDRAM chip select. */
  315. ldr r1, =EBI_BASE
  316. ldr r0, =EBI_CS1A
  317. str r0, [r1, #EBI_CSA_OFF]
  318. /* Load SDRAM controller base address. */
  319. ldr r1, =SDRAMC_BASE
  320. /* Set SDRAM characteristics in configuration register. */
  321. /* Hard coded values for MT48LC32M16A2 with 48MHz CPU. */
  322. ldr r0, =(SDRAMC_CFG_NC | SDRAMC_CFG_NR \
  323. | SDRAMC_CFG_NB | SDRAMC_CFG_CAS \
  324. | (NUTMEM_SDRAM_TWR << SDRAMC_TWR_LSB) \
  325. | (NUTMEM_SDRAM_TRC << SDRAMC_TRC_LSB) \
  326. | (NUTMEM_SDRAM_TRP << SDRAMC_TRP_LSB) \
  327. | (NUTMEM_SDRAM_TRCD << SDRAMC_TRCD_LSB) \
  328. | (NUTMEM_SDRAM_TRAS << SDRAMC_TRAS_LSB) \
  329. | (NUTMEM_SDRAM_TXSR << SDRAMC_TXSR_LSB))
  330. str r0, [r1, #SDRAMC_CR_OFF]
  331. /* 200us delay minimum. */
  332. mov r3, #0x2000
  333. 1:
  334. subs r3, r3, #1
  335. bne 1b
  336. /* Load SDRAM base address. */
  337. mov r2, #NUTMEM_SDRAM_BASE
  338. /* Issue 16 bit SDRAM command: NOP. */
  339. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_NOP)
  340. str r0, [r1, #SDRAMC_MR_OFF]
  341. mov r3, #0
  342. str r3, [r2, #0]
  343. /* Issue 16 bit SDRAM command: Precharge all. */
  344. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_PRCGALL)
  345. str r0, [r1, #SDRAMC_MR_OFF]
  346. str r3, [r2, #0]
  347. /* Issue 8 auto-refresh cycles. */
  348. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_RFSH)
  349. str r0, [r1, #SDRAMC_MR_OFF]
  350. str r3, [r2, #0]
  351. str r0, [r1, #SDRAMC_MR_OFF]
  352. str r3, [r2, #0]
  353. str r0, [r1, #SDRAMC_MR_OFF]
  354. str r3, [r2, #0]
  355. str r0, [r1, #SDRAMC_MR_OFF]
  356. str r3, [r2, #0]
  357. str r0, [r1, #SDRAMC_MR_OFF]
  358. str r3, [r2, #0]
  359. str r0, [r1, #SDRAMC_MR_OFF]
  360. str r3, [r2, #0]
  361. str r0, [r1, #SDRAMC_MR_OFF]
  362. str r3, [r2, #0]
  363. str r0, [r1, #SDRAMC_MR_OFF]
  364. str r3, [r2, #0]
  365. /* Issue 16 bit SDRAM command: Set mode register. */
  366. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_LMR)
  367. str r0, [r1, #SDRAMC_MR_OFF]
  368. ldr r3, =(0xCAFEDEDE)
  369. str r3, [r2, #20]
  370. /* Set refresh rate count. */
  371. mov r3, #384
  372. str r0, [r1, #SDRAMC_TR_OFF]
  373. /* Issue 16 bit SDRAM command: Normal mode. */
  374. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_NORMAL)
  375. str r0, [r1, #SDRAMC_MR_OFF]
  376. mov r0, #0
  377. str r3, [r2, #0]
  378. #endif /* NUTMEM_SDRAM_BASE */
  379. /*
  380. * Enable external reset key.
  381. */
  382. ldr r0, =(RSTC_KEY | RSTC_URSTEN)
  383. ldr r1, =RSTC_MR
  384. str r0, [r1, #0]
  385. b __set_stacks
  386. .ltorg
  387. /*
  388. * Section 2: Set stack pointers.
  389. */
  390. .section .init2,"ax",%progbits
  391. .global __set_stacks
  392. __set_stacks:
  393. /*
  394. * Set exception stack pointers and enable interrupts.
  395. */
  396. ldr r0, =__exp_stack
  397. msr CPSR_c, #ARM_MODE_FIQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  398. mov r13, r0
  399. sub r0, r0, #FIQ_STACK_SIZE
  400. msr CPSR_c, #ARM_MODE_IRQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  401. mov r13, r0
  402. sub r0, r0, #IRQ_STACK_SIZE
  403. msr CPSR_c, #ARM_MODE_ABORT | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  404. mov r13, r0
  405. sub r0, r0, #ABT_STACK_SIZE
  406. msr CPSR_c, #ARM_MODE_UNDEF | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  407. mov r13, r0
  408. sub r0, r0, #UND_STACK_SIZE
  409. msr CPSR_c, #ARM_MODE_SVC | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  410. mov r13, r0
  411. b __enter_mode
  412. .ltorg
  413. /*
  414. * Section 3: Enter system mode.
  415. */
  416. .section .init3,"ax",%progbits
  417. .global __enter_mode
  418. __enter_mode:
  419. msr CPSR_c, #ARM_MODE_SYS | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  420. b __clear_bss
  421. .ltorg
  422. /*
  423. * Section 4: Clear bss and copy data.
  424. */
  425. .section .init4,"ax",%progbits
  426. .global __clear_bss
  427. __clear_bss:
  428. ldr r1, =__bss_start
  429. ldr r2, =__bss_end
  430. ldr r3, =0
  431. _40:
  432. cmp r1, r2
  433. strne r3, [r1], #+4
  434. bne _40
  435. /*
  436. * Relocate .data section (Copy from ROM to RAM).
  437. */
  438. ldr r1, =__etext
  439. ldr r2, =__data_start
  440. ldr r3, =__data_end
  441. _41:
  442. cmp r2, r3
  443. ldrlo r0, [r1], #4
  444. strlo r0, [r2], #4
  445. blo _41
  446. /*
  447. * Remap SRAM to 0x00000000
  448. */
  449. .global __sram_remap
  450. __sram_remap:
  451. LDR R0, =MC_BASE
  452. MOV R1, #1
  453. STR R1, [R0, #MC_RCR_OFF] /* Remap */
  454. /*
  455. * Initialize user stack pointer.
  456. */
  457. ldr r13, =__stack
  458. b __call_rtos
  459. .ltorg
  460. /*
  461. * Section 5: Call RTOS
  462. */
  463. .section .init5,"ax",%progbits
  464. .global __call_rtos
  465. __call_rtos:
  466. /*
  467. * Jump to Nut/OS initialization.
  468. */
  469. ldr r0, =NutInit
  470. bx r0
  471. End:
  472. b End
  473. .ltorg