crtat91sam7sex_rom.S 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  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. * $Id: crtat91sam7sex_rom.S 4937 2013-01-22 11:38:42Z haraldkipp $
  37. */
  38. #include <cfg/clock.h>
  39. #include <cfg/memory.h>
  40. #include <arch/arm.h>
  41. #ifndef NUTMEM_FLASH_RWS
  42. /* By default use 1 wait state for flash read access. */
  43. #define NUTMEM_FLASH_RWS 1
  44. #endif
  45. #if NUTMEM_FLASH_RWS == 0
  46. #define MC_FWS_VAL MC_FWS_1R2W /* 1 cycle for read, 2 for write ops. */
  47. #elif NUTMEM_FLASH_RWS == 1
  48. #define MC_FWS_VAL MC_FWS_2R3W /* 2 cycles for read, 3 for write ops. */
  49. #elif NUTMEM_FLASH_RWS == 2
  50. #define MC_FWS_VAL MC_FWS_3R4W /* 3 cycles for read, 4 for write ops. */
  51. #else
  52. #define MC_FWS_VAL MC_FWS_4R4W /* 4 cycles for read and write ops. */
  53. #endif
  54. #ifndef PLL_MUL_VAL
  55. #define PLL_MUL_VAL 72
  56. #endif
  57. #ifndef PLL_DIV_VAL
  58. #define PLL_DIV_VAL 14
  59. #endif
  60. #if MASTER_CLOCK_PRES == 1
  61. #define AT91MCK_PRES PMC_PRES_CLK
  62. #elif MASTER_CLOCK_PRES == 4
  63. #define AT91MCK_PRES PMC_PRES_CLK_4
  64. #elif MASTER_CLOCK_PRES == 8
  65. #define AT91MCK_PRES PMC_PRES_CLK_8
  66. #elif MASTER_CLOCK_PRES == 16
  67. #define AT91MCK_PRES PMC_PRES_CLK_16
  68. #elif MASTER_CLOCK_PRES == 32
  69. #define AT91MCK_PRES PMC_PRES_CLK_32
  70. #elif MASTER_CLOCK_PRES == 64
  71. #define AT91MCK_PRES PMC_PRES_CLK_64
  72. #else
  73. #define AT91MCK_PRES PMC_PRES_CLK_2
  74. #endif
  75. #ifndef IRQ_STACK_SIZE
  76. #define IRQ_STACK_SIZE 512
  77. #endif
  78. #ifndef FIQ_STACK_SIZE
  79. #define FIQ_STACK_SIZE 256
  80. #endif
  81. #ifndef ABT_STACK_SIZE
  82. #define ABT_STACK_SIZE 128
  83. #endif
  84. #ifndef UND_STACK_SIZE
  85. #define UND_STACK_SIZE 128
  86. #endif
  87. #ifdef NUTMEM_SDRAM_BASE
  88. #if NUTMEM_SDRAM_BANKS == 2
  89. #define SDRAMC_CFG_NB 0
  90. #else
  91. #define SDRAMC_CFG_NB SDRAMC_NB
  92. #endif
  93. #if NUTMEM_SDRAM_COLBITS == 8
  94. #define SDRAMC_CFG_NC SDRAMC_NC_8
  95. #elif NUTMEM_SDRAM_COLBITS == 9
  96. #define SDRAMC_CFG_NC SDRAMC_NC_9
  97. #elif NUTMEM_SDRAM_COLBITS == 10
  98. #define SDRAMC_CFG_NC SDRAMC_NC_10
  99. #else
  100. #define SDRAMC_CFG_NC SDRAMC_NC_11
  101. #endif
  102. #if NUTMEM_SDRAM_ROWBITS == 11
  103. #define SDRAMC_CFG_NR SDRAMC_NR_11
  104. #elif NUTMEM_SDRAM_ROWBITS == 12
  105. #define SDRAMC_CFG_NR SDRAMC_NR_12
  106. #else
  107. #define SDRAMC_CFG_NR SDRAMC_NR_13
  108. #endif
  109. #if NUTMEM_SDRAM_CASLAT == 1
  110. #define SDRAMC_CFG_CAS SDRAMC_CAS_1
  111. #elif NUTMEM_SDRAM_CASLAT == 2
  112. #define SDRAMC_CFG_CAS SDRAMC_CAS_2
  113. #else
  114. #define SDRAMC_CFG_CAS SDRAMC_CAS_3
  115. #endif
  116. #endif /* NUTMEM_SDRAM_BASE */
  117. #ifndef _BV
  118. #define _BV(n) (1 << (n))
  119. #endif
  120. /*
  121. * Section 0: Vector table and reset entry.
  122. */
  123. .section .init0,"ax",%progbits
  124. .global __vectors
  125. __vectors:
  126. ldr pc, [pc, #24] /* Reset */
  127. ldr pc, [pc, #24] /* Undefined instruction */
  128. ldr pc, [pc, #24] /* Software interrupt */
  129. ldr pc, [pc, #24] /* Prefetch abort */
  130. ldr pc, [pc, #24] /* Data abort */
  131. ldr pc, [pc, #24] /* Reserved */
  132. /*
  133. * On IRQ the PC will be loaded from AIC_IVR, which
  134. * provides the address previously set in AIC_SVR.
  135. * The interrupt routine will be called in ARM_MODE_IRQ
  136. * with IRQ disabled and FIQ unchanged.
  137. */
  138. ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */
  139. ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */
  140. .word _start
  141. .word __undef
  142. .word __swi
  143. .word __prefetch_abort
  144. .word __data_abort
  145. .weak __undef
  146. .set __undef, __xcpt_dummy
  147. .weak __swi
  148. .set __swi, __xcpt_dummy
  149. .weak __prefetch_abort
  150. .set __prefetch_abort, __xcpt_dummy
  151. .weak __data_abort
  152. .set __data_abort, __xcpt_dummy
  153. .global __xcpt_dummy
  154. __xcpt_dummy:
  155. b __xcpt_dummy
  156. .ltorg
  157. /*
  158. * Section 1: Hardware initialization.
  159. */
  160. .section .init1, "ax", %progbits
  161. .globl _start
  162. _start:
  163. /*
  164. * Set cycles for flash access.
  165. */
  166. ldr r1, =MC_BASE
  167. mov r0, #MC_FWS_VAL
  168. str r0, [r1, #MC_FMR_EFC0_OFF]
  169. str r0, [r1, #MC_FMR_EFC1_OFF]
  170. /*
  171. * Disable all interrupts. Useful for debugging w/o target reset.
  172. */
  173. ldr r1, =AIC_BASE
  174. mvn r0, #0
  175. str r0, [r1, #AIC_EOICR_OFF]
  176. str r0, [r1, #AIC_IDCR_OFF]
  177. /*
  178. * The watchdog is enabled after processor reset.
  179. */
  180. #ifdef NUT_WDT_START
  181. #if NUT_WDT_START
  182. /* Configure the watchdog. */
  183. ldr r1, =WDT_BASE
  184. ldr r0, =NUT_WDT_START
  185. str r0, [r1, #WDT_MR_OFF]
  186. #endif
  187. #else
  188. /* Disable the watchdog. */
  189. ldr r1, =WDT_BASE
  190. ldr r0, =WDT_WDDIS
  191. str r0, [r1, #WDT_MR_OFF]
  192. #endif
  193. /*
  194. * Enable the main oscillator. Set startup time of 6 * 8 slow
  195. * clock cycles and wait until oscillator is stabilized.
  196. */
  197. ldr r1, =PMC_BASE
  198. mov r0, #(6 << 8)
  199. orr r0, r0, #CKGR_MOSCEN
  200. str r0, [r1, #CKGR_MOR_OFF]
  201. wait_moscs:
  202. ldr r0, [r1, #PMC_SR_OFF]
  203. tst r0, #PMC_MOSCS
  204. beq wait_moscs
  205. /*
  206. * Switch to Slow clock in case PLL was already set up.
  207. */
  208. ldr r0, [r1, #PMC_MCKR_OFF]
  209. and r0, r0, #~PMC_CSS
  210. /* Slow Clock. The next statement really isn't needed.
  211. ** It is included for code clarity */
  212. orr r0, r0, #PMC_CSS_SLOW_CLK
  213. str r0, [r1, #PMC_MCKR_OFF]
  214. wait_slowsel:
  215. ldr r0, [r1, #PMC_SR_OFF]
  216. tst r0, #PMC_MCKRDY
  217. beq wait_slowsel
  218. /*
  219. * Set PLL:
  220. * PLLfreq = crystal / divider * (multiplier + 1)
  221. * Wait 28 clock cycles until PLL is locked.
  222. */
  223. ldr r0, =((PLL_MUL_VAL << CKGR_MUL_LSB) | (28 << CKGR_PLLCOUNT_LSB) | (PLL_DIV_VAL << CKGR_DIV_LSB))
  224. str r0, [r1, #CKGR_PLLR_OFF]
  225. wait_lock:
  226. ldr r0, [r1, #PMC_SR_OFF]
  227. tst r0, #PMC_LOCK
  228. beq wait_lock
  229. /*
  230. * Set master clock prescaler.
  231. */
  232. mov r0, #AT91MCK_PRES
  233. str r0, [r1, #PMC_MCKR_OFF]
  234. wait_presrdy:
  235. ldr r0, [r1, #PMC_SR_OFF]
  236. tst r0, #PMC_MCKRDY
  237. beq wait_presrdy
  238. /*
  239. * Switch to PLL clock.
  240. */
  241. ldr r0, [r1, #PMC_MCKR_OFF]
  242. orr r0, r0, #PMC_CSS_PLL_CLK
  243. str r0, [r1, #PMC_MCKR_OFF]
  244. wait_pllsel:
  245. ldr r0, [r1, #PMC_SR_OFF]
  246. tst r0, #PMC_MCKRDY
  247. beq wait_pllsel
  248. /*
  249. * Enable SDRAM interface, if configured.
  250. */
  251. #ifdef NUTMEM_SDRAM_BASE
  252. /* Enable SDRAM control at PIO A. */
  253. ldr r1, =PIOA_BASE
  254. ldr r0, =(_BV(PA23_NWR1_B) \
  255. | _BV(PA24_SDA10_B) \
  256. | _BV(PA25_SDCKE_B) \
  257. | _BV(PA26_NCS1_B) \
  258. | _BV(PA27_SDWE_B) \
  259. | _BV(PA28_CAS_B) \
  260. | _BV(PA29_RAS_B))
  261. str r0, [r1, #PIO_BSR_OFF]
  262. str r0, [r1, #PIO_PDR_OFF]
  263. /* Enable address bus (A0, A2-A11, A13-A17) at PIO B. */
  264. ldr r1, =PIOB_BASE
  265. ldr r0, =(_BV(PB0_A0_B) \
  266. | _BV(PB2_A2_B) \
  267. | _BV(PB3_A3_B) \
  268. | _BV(PB4_A4_B) \
  269. | _BV(PB5_A5_B) \
  270. | _BV(PB6_A6_B) \
  271. | _BV(PB7_A7_B) \
  272. | _BV(PB8_A8_B) \
  273. | _BV(PB9_A9_B) \
  274. | _BV(PB10_A10_B) \
  275. | _BV(PB11_A11_B) \
  276. | _BV(PB13_A13_B) \
  277. | _BV(PB14_A14_B) \
  278. | _BV(PB15_A15_B) \
  279. | _BV(PB16_A16_B) \
  280. | _BV(PB17_A17_B))
  281. str r0, [r1, #PIO_BSR_OFF]
  282. str r0, [r1, #PIO_PDR_OFF]
  283. /* Enable 16 bit data bus at PIO C. */
  284. ldr r1, =PIOC_BASE
  285. ldr r0, =(_BV(PC0_D0_A) \
  286. | _BV(PC1_D1_A) \
  287. | _BV(PC2_D2_A) \
  288. | _BV(PC3_D3_A) \
  289. | _BV(PC4_D4_A) \
  290. | _BV(PC5_D5_A) \
  291. | _BV(PC6_D6_A) \
  292. | _BV(PC7_D7_A) \
  293. | _BV(PC8_D8_A) \
  294. | _BV(PC9_D9_A) \
  295. | _BV(PC10_D10_A) \
  296. | _BV(PC11_D11_A) \
  297. | _BV(PC12_D12_A) \
  298. | _BV(PC13_D13_A) \
  299. | _BV(PC14_D14_A) \
  300. | _BV(PC15_D15_A))
  301. str r0, [r1, #PIO_ASR_OFF]
  302. str r0, [r1, #PIO_PDR_OFF]
  303. /* Enable SDRAM chip select. */
  304. ldr r1, =EBI_BASE
  305. ldr r0, =EBI_CS1A
  306. str r0, [r1, #EBI_CSA_OFF]
  307. /* Load SDRAM controller base address. */
  308. ldr r1, =SDRAMC_BASE
  309. /* Set SDRAM characteristics in configuration register. */
  310. /* Hard coded values for MT48LC32M16A2 with 48MHz CPU. */
  311. ldr r0, =(SDRAMC_CFG_NC | SDRAMC_CFG_NR \
  312. | SDRAMC_CFG_NB | SDRAMC_CFG_CAS \
  313. | (NUTMEM_SDRAM_TWR << SDRAMC_TWR_LSB) \
  314. | (NUTMEM_SDRAM_TRC << SDRAMC_TRC_LSB) \
  315. | (NUTMEM_SDRAM_TRP << SDRAMC_TRP_LSB) \
  316. | (NUTMEM_SDRAM_TRCD << SDRAMC_TRCD_LSB) \
  317. | (NUTMEM_SDRAM_TRAS << SDRAMC_TRAS_LSB) \
  318. | (NUTMEM_SDRAM_TXSR << SDRAMC_TXSR_LSB))
  319. str r0, [r1, #SDRAMC_CR_OFF]
  320. /* 200us delay minimum. */
  321. mov r3, #0x2000
  322. 1:
  323. subs r3, r3, #1
  324. bne 1b
  325. /* Load SDRAM base address. */
  326. mov r2, #NUTMEM_SDRAM_BASE
  327. /* Issue 16 bit SDRAM command: NOP. */
  328. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_NOP)
  329. str r0, [r1, #SDRAMC_MR_OFF]
  330. mov r3, #0
  331. str r3, [r2, #0]
  332. /* Issue 16 bit SDRAM command: Precharge all. */
  333. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_PRCGALL)
  334. str r0, [r1, #SDRAMC_MR_OFF]
  335. str r3, [r2, #0]
  336. /* Issue 8 auto-refresh cycles. */
  337. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_RFSH)
  338. str r0, [r1, #SDRAMC_MR_OFF]
  339. str r3, [r2, #0]
  340. str r0, [r1, #SDRAMC_MR_OFF]
  341. str r3, [r2, #0]
  342. str r0, [r1, #SDRAMC_MR_OFF]
  343. str r3, [r2, #0]
  344. str r0, [r1, #SDRAMC_MR_OFF]
  345. str r3, [r2, #0]
  346. str r0, [r1, #SDRAMC_MR_OFF]
  347. str r3, [r2, #0]
  348. str r0, [r1, #SDRAMC_MR_OFF]
  349. str r3, [r2, #0]
  350. str r0, [r1, #SDRAMC_MR_OFF]
  351. str r3, [r2, #0]
  352. str r0, [r1, #SDRAMC_MR_OFF]
  353. str r3, [r2, #0]
  354. /* Issue 16 bit SDRAM command: Set mode register. */
  355. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_LMR)
  356. str r0, [r1, #SDRAMC_MR_OFF]
  357. ldr r3, =(0xCAFEDEDE)
  358. str r3, [r2, #20]
  359. /* Set refresh rate count. */
  360. mov r0, #384
  361. str r0, [r1, #SDRAMC_TR_OFF]
  362. /* Issue 16 bit SDRAM command: Normal mode. */
  363. ldr r0, =(SDRAMC_DBW | SDRAMC_MODE_NORMAL)
  364. str r0, [r1, #SDRAMC_MR_OFF]
  365. mov r0, #0
  366. str r0, [r2, #0]
  367. #endif /* NUTMEM_SDRAM_BASE */
  368. /*
  369. * Enable external reset key.
  370. */
  371. ldr r0, =(RSTC_KEY | RSTC_URSTEN)
  372. ldr r1, =RSTC_MR
  373. str r0, [r1, #0]
  374. b __set_stacks
  375. .ltorg
  376. /*
  377. * Section 2: Set stack pointers.
  378. */
  379. .section .init2,"ax",%progbits
  380. .global __set_stacks
  381. __set_stacks:
  382. /*
  383. * Set exception stack pointers and enable interrupts.
  384. */
  385. ldr r0, =__exp_stack
  386. msr CPSR_c, #ARM_MODE_FIQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  387. mov r13, r0
  388. sub r0, r0, #FIQ_STACK_SIZE
  389. msr CPSR_c, #ARM_MODE_IRQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  390. mov r13, r0
  391. sub r0, r0, #IRQ_STACK_SIZE
  392. msr CPSR_c, #ARM_MODE_ABORT | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  393. mov r13, r0
  394. sub r0, r0, #ABT_STACK_SIZE
  395. msr CPSR_c, #ARM_MODE_UNDEF | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  396. mov r13, r0
  397. sub r0, r0, #UND_STACK_SIZE
  398. msr CPSR_c, #ARM_MODE_SVC | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  399. mov r13, r0
  400. b __enter_mode
  401. .ltorg
  402. /*
  403. * Section 3: Enter system mode.
  404. */
  405. .section .init3,"ax",%progbits
  406. .global __enter_mode
  407. __enter_mode:
  408. msr CPSR_c, #ARM_MODE_SYS | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  409. b __clear_bss
  410. .ltorg
  411. /*
  412. * Section 4: Clear bss and copy data.
  413. */
  414. .section .init4,"ax",%progbits
  415. .global __clear_bss
  416. __clear_bss:
  417. ldr r1, =__bss_start
  418. ldr r2, =__bss_end
  419. ldr r3, =0
  420. _40:
  421. cmp r1, r2
  422. strne r3, [r1], #+4
  423. bne _40
  424. #if defined(MCU_AT91SAM7SE)
  425. /*
  426. * Clear .bss_iram section
  427. */
  428. ldr r1, =__bss_iram_start
  429. ldr r2, =__bss_iram_end
  430. ldr r3, =0
  431. 1: cmp r1, r2
  432. strne r3, [r1], #+4
  433. bne 1b
  434. #endif
  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. #if defined(MCU_AT91SAM7SE)
  447. /*
  448. * Relocate .data_iram section (Copy from ROM to internal RAM).
  449. */
  450. ldr r1, =__etext
  451. ldr r2, =__data_iram_start
  452. ldr r3, =__data_iram_end
  453. 1: cmp r2, r3
  454. ldrlo r0, [r1], #4
  455. strlo r0, [r2], #4
  456. blo 1b
  457. #endif
  458. /*
  459. * Initialize user stack pointer.
  460. */
  461. ldr r13, =__stack
  462. b __call_rtos
  463. .ltorg
  464. /*
  465. * Section 5: Call RTOS
  466. */
  467. .section .init5,"ax",%progbits
  468. .global __call_rtos
  469. __call_rtos:
  470. /*
  471. * Jump to Nut/OS initialization.
  472. */
  473. ldr r0, =NutInit
  474. bx r0
  475. End:
  476. b End
  477. .ltorg