start.S 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. /*
  2. * Copyright 2004, 2007, 2011 Freescale Semiconductor.
  3. * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. /* U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
  8. *
  9. *
  10. * The processor starts at 0xfff00100 and the code is executed
  11. * from flash. The code is organized to be at an other address
  12. * in memory, but as long we don't jump around before relocating.
  13. * board_init lies at a quite high address and when the cpu has
  14. * jumped there, everything is ok.
  15. */
  16. #include <asm-offsets.h>
  17. #include <config.h>
  18. #include <mpc86xx.h>
  19. #include <version.h>
  20. #include <ppc_asm.tmpl>
  21. #include <ppc_defs.h>
  22. #include <asm/cache.h>
  23. #include <asm/mmu.h>
  24. #include <asm/u-boot.h>
  25. /*
  26. * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions
  27. */
  28. /*
  29. * Set up GOT: Global Offset Table
  30. *
  31. * Use r12 to access the GOT
  32. */
  33. START_GOT
  34. GOT_ENTRY(_GOT2_TABLE_)
  35. GOT_ENTRY(_FIXUP_TABLE_)
  36. GOT_ENTRY(_start)
  37. GOT_ENTRY(_start_of_vectors)
  38. GOT_ENTRY(_end_of_vectors)
  39. GOT_ENTRY(transfer_to_handler)
  40. GOT_ENTRY(__init_end)
  41. GOT_ENTRY(__bss_end)
  42. GOT_ENTRY(__bss_start)
  43. END_GOT
  44. /*
  45. * r3 - 1st arg to board_init(): IMMP pointer
  46. * r4 - 2nd arg to board_init(): boot flag
  47. */
  48. .text
  49. .long 0x27051956 /* U-Boot Magic Number */
  50. .globl version_string
  51. version_string:
  52. .ascii U_BOOT_VERSION_STRING, "\0"
  53. . = EXC_OFF_SYS_RESET
  54. .globl _start
  55. _start:
  56. b boot_cold
  57. /* the boot code is located below the exception table */
  58. .globl _start_of_vectors
  59. _start_of_vectors:
  60. /* Machine check */
  61. STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
  62. /* Data Storage exception. */
  63. STD_EXCEPTION(0x300, DataStorage, UnknownException)
  64. /* Instruction Storage exception. */
  65. STD_EXCEPTION(0x400, InstStorage, UnknownException)
  66. /* External Interrupt exception. */
  67. STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
  68. /* Alignment exception. */
  69. . = 0x600
  70. Alignment:
  71. EXCEPTION_PROLOG(SRR0, SRR1)
  72. mfspr r4,DAR
  73. stw r4,_DAR(r21)
  74. mfspr r5,DSISR
  75. stw r5,_DSISR(r21)
  76. addi r3,r1,STACK_FRAME_OVERHEAD
  77. EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
  78. /* Program check exception */
  79. . = 0x700
  80. ProgramCheck:
  81. EXCEPTION_PROLOG(SRR0, SRR1)
  82. addi r3,r1,STACK_FRAME_OVERHEAD
  83. EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
  84. MSR_KERNEL, COPY_EE)
  85. STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
  86. /* I guess we could implement decrementer, and may have
  87. * to someday for timekeeping.
  88. */
  89. STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
  90. STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
  91. STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
  92. STD_EXCEPTION(0xc00, SystemCall, UnknownException)
  93. STD_EXCEPTION(0xd00, SingleStep, UnknownException)
  94. STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
  95. STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
  96. STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
  97. STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
  98. STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
  99. STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
  100. STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
  101. STD_EXCEPTION(0x1500, Reserved5, UnknownException)
  102. STD_EXCEPTION(0x1600, Reserved6, UnknownException)
  103. STD_EXCEPTION(0x1700, Reserved7, UnknownException)
  104. STD_EXCEPTION(0x1800, Reserved8, UnknownException)
  105. STD_EXCEPTION(0x1900, Reserved9, UnknownException)
  106. STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
  107. STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
  108. STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
  109. STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
  110. STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
  111. STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
  112. .globl _end_of_vectors
  113. _end_of_vectors:
  114. . = 0x2000
  115. boot_cold:
  116. /*
  117. * NOTE: Only Cpu 0 will ever come here. Other cores go to an
  118. * address specified by the BPTR
  119. */
  120. 1:
  121. #ifdef CONFIG_SYS_RAMBOOT
  122. /* disable everything */
  123. li r0, 0
  124. mtspr HID0, r0
  125. sync
  126. mtmsr 0
  127. #endif
  128. /* Invalidate BATs */
  129. bl invalidate_bats
  130. sync
  131. /* Invalidate all of TLB before MMU turn on */
  132. bl clear_tlbs
  133. sync
  134. #ifdef CONFIG_SYS_L2
  135. /* init the L2 cache */
  136. lis r3, L2_INIT@h
  137. ori r3, r3, L2_INIT@l
  138. mtspr l2cr, r3
  139. /* invalidate the L2 cache */
  140. bl l2cache_invalidate
  141. sync
  142. #endif
  143. /*
  144. * Calculate absolute address in FLASH and jump there
  145. *------------------------------------------------------*/
  146. lis r3, CONFIG_SYS_MONITOR_BASE_EARLY@h
  147. ori r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l
  148. addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
  149. mtlr r3
  150. blr
  151. in_flash:
  152. /* let the C-code set up the rest */
  153. /* */
  154. /* Be careful to keep code relocatable ! */
  155. /*------------------------------------------------------*/
  156. /* perform low-level init */
  157. /* enable extended addressing */
  158. bl enable_ext_addr
  159. /* setup the bats */
  160. bl early_bats
  161. /*
  162. * Cache must be enabled here for stack-in-cache trick.
  163. * This means we need to enable the BATS.
  164. * Cache should be turned on after BATs, since by default
  165. * everything is write-through.
  166. */
  167. /* enable address translation */
  168. mfmsr r5
  169. ori r5, r5, (MSR_IR | MSR_DR)
  170. lis r3,addr_trans_enabled@h
  171. ori r3, r3, addr_trans_enabled@l
  172. mtspr SPRN_SRR0,r3
  173. mtspr SPRN_SRR1,r5
  174. rfi
  175. addr_trans_enabled:
  176. /* enable and invalidate the data cache */
  177. /* bl l1dcache_enable */
  178. bl dcache_enable
  179. sync
  180. #if 1
  181. bl icache_enable
  182. #endif
  183. #ifdef CONFIG_SYS_INIT_RAM_LOCK
  184. bl lock_ram_in_cache
  185. sync
  186. #endif
  187. #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
  188. bl setup_ccsrbar
  189. #endif
  190. /* set up the stack pointer in our newly created
  191. * cache-ram (r1) */
  192. lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
  193. ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
  194. li r0, 0 /* Make room for stack frame header and */
  195. stwu r0, -4(r1) /* clear final stack frame so that */
  196. stwu r0, -4(r1) /* stack backtraces terminate cleanly */
  197. GET_GOT /* initialize GOT access */
  198. /* run low-level CPU init code (from Flash) */
  199. bl cpu_init_f
  200. sync
  201. #ifdef RUN_DIAG
  202. /* Load PX_AUX register address in r4 */
  203. lis r4, PIXIS_BASE@h
  204. ori r4, r4, 0x6
  205. /* Load contents of PX_AUX in r3 bits 24 to 31*/
  206. lbz r3, 0(r4)
  207. /* Mask and obtain the bit in r3 */
  208. rlwinm. r3, r3, 0, 24, 24
  209. /* If not zero, jump and continue with u-boot */
  210. bne diag_done
  211. /* Load back contents of PX_AUX in r3 bits 24 to 31 */
  212. lbz r3, 0(r4)
  213. /* Set the MSB of the register value */
  214. ori r3, r3, 0x80
  215. /* Write value in r3 back to PX_AUX */
  216. stb r3, 0(r4)
  217. /* Get the address to jump to in r3*/
  218. lis r3, CONFIG_SYS_DIAG_ADDR@h
  219. ori r3, r3, CONFIG_SYS_DIAG_ADDR@l
  220. /* Load the LR with the branch address */
  221. mtlr r3
  222. /* Branch to diagnostic */
  223. blr
  224. diag_done:
  225. #endif
  226. /* bl l2cache_enable */
  227. /* run 1st part of board init code (from Flash) */
  228. li r3, 0 /* clear boot_flag for calling board_init_f */
  229. bl board_init_f
  230. sync
  231. /* NOTREACHED - board_init_f() does not return */
  232. .globl invalidate_bats
  233. invalidate_bats:
  234. li r0, 0
  235. /* invalidate BATs */
  236. mtspr IBAT0U, r0
  237. mtspr IBAT1U, r0
  238. mtspr IBAT2U, r0
  239. mtspr IBAT3U, r0
  240. mtspr IBAT4U, r0
  241. mtspr IBAT5U, r0
  242. mtspr IBAT6U, r0
  243. mtspr IBAT7U, r0
  244. isync
  245. mtspr DBAT0U, r0
  246. mtspr DBAT1U, r0
  247. mtspr DBAT2U, r0
  248. mtspr DBAT3U, r0
  249. mtspr DBAT4U, r0
  250. mtspr DBAT5U, r0
  251. mtspr DBAT6U, r0
  252. mtspr DBAT7U, r0
  253. isync
  254. sync
  255. blr
  256. #define CONFIG_BAT_PAIR(n) \
  257. lis r4, CONFIG_SYS_IBAT##n##L@h; \
  258. ori r4, r4, CONFIG_SYS_IBAT##n##L@l; \
  259. lis r3, CONFIG_SYS_IBAT##n##U@h; \
  260. ori r3, r3, CONFIG_SYS_IBAT##n##U@l; \
  261. mtspr IBAT##n##L, r4; \
  262. mtspr IBAT##n##U, r3; \
  263. lis r4, CONFIG_SYS_DBAT##n##L@h; \
  264. ori r4, r4, CONFIG_SYS_DBAT##n##L@l; \
  265. lis r3, CONFIG_SYS_DBAT##n##U@h; \
  266. ori r3, r3, CONFIG_SYS_DBAT##n##U@l; \
  267. mtspr DBAT##n##L, r4; \
  268. mtspr DBAT##n##U, r3;
  269. /*
  270. * setup_bats:
  271. *
  272. * Set up the final BAT registers now that setup is done.
  273. *
  274. * Assumes that:
  275. * 1) Address translation is enabled upon entry
  276. * 2) The boot rom is still accessible via 1:1 translation
  277. */
  278. .globl setup_bats
  279. setup_bats:
  280. mflr r5
  281. sync
  282. /*
  283. * When we disable address translation, we will get 1:1 (VA==PA)
  284. * translation. The only place we know for sure is safe for that is
  285. * the bootrom where we originally started out. Pop back into there.
  286. */
  287. lis r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
  288. ori r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
  289. addi r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
  290. /* disable address translation */
  291. mfmsr r3
  292. rlwinm r3, r3, 0, 28, 25
  293. mtspr SRR0, r4
  294. mtspr SRR1, r3
  295. rfi
  296. trans_disabled:
  297. #if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
  298. && defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
  299. CONFIG_BAT_PAIR(0)
  300. #endif
  301. CONFIG_BAT_PAIR(1)
  302. CONFIG_BAT_PAIR(2)
  303. CONFIG_BAT_PAIR(3)
  304. CONFIG_BAT_PAIR(4)
  305. CONFIG_BAT_PAIR(5)
  306. CONFIG_BAT_PAIR(6)
  307. CONFIG_BAT_PAIR(7)
  308. sync
  309. isync
  310. /* Turn translation back on and return */
  311. mfmsr r3
  312. ori r3, r3, (MSR_IR | MSR_DR)
  313. mtspr SPRN_SRR0,r5
  314. mtspr SPRN_SRR1,r3
  315. rfi
  316. /*
  317. * early_bats:
  318. *
  319. * Set up bats needed early on - this is usually the BAT for the
  320. * stack-in-cache, the Flash, and CCSR space
  321. */
  322. .globl early_bats
  323. early_bats:
  324. /* IBAT 3 */
  325. lis r4, CONFIG_SYS_IBAT3L@h
  326. ori r4, r4, CONFIG_SYS_IBAT3L@l
  327. lis r3, CONFIG_SYS_IBAT3U@h
  328. ori r3, r3, CONFIG_SYS_IBAT3U@l
  329. mtspr IBAT3L, r4
  330. mtspr IBAT3U, r3
  331. isync
  332. /* DBAT 3 */
  333. lis r4, CONFIG_SYS_DBAT3L@h
  334. ori r4, r4, CONFIG_SYS_DBAT3L@l
  335. lis r3, CONFIG_SYS_DBAT3U@h
  336. ori r3, r3, CONFIG_SYS_DBAT3U@l
  337. mtspr DBAT3L, r4
  338. mtspr DBAT3U, r3
  339. isync
  340. /* IBAT 5 */
  341. lis r4, CONFIG_SYS_IBAT5L@h
  342. ori r4, r4, CONFIG_SYS_IBAT5L@l
  343. lis r3, CONFIG_SYS_IBAT5U@h
  344. ori r3, r3, CONFIG_SYS_IBAT5U@l
  345. mtspr IBAT5L, r4
  346. mtspr IBAT5U, r3
  347. isync
  348. /* DBAT 5 */
  349. lis r4, CONFIG_SYS_DBAT5L@h
  350. ori r4, r4, CONFIG_SYS_DBAT5L@l
  351. lis r3, CONFIG_SYS_DBAT5U@h
  352. ori r3, r3, CONFIG_SYS_DBAT5U@l
  353. mtspr DBAT5L, r4
  354. mtspr DBAT5U, r3
  355. isync
  356. /* IBAT 6 */
  357. lis r4, CONFIG_SYS_IBAT6L_EARLY@h
  358. ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
  359. lis r3, CONFIG_SYS_IBAT6U_EARLY@h
  360. ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
  361. mtspr IBAT6L, r4
  362. mtspr IBAT6U, r3
  363. isync
  364. /* DBAT 6 */
  365. lis r4, CONFIG_SYS_DBAT6L_EARLY@h
  366. ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
  367. lis r3, CONFIG_SYS_DBAT6U_EARLY@h
  368. ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
  369. mtspr DBAT6L, r4
  370. mtspr DBAT6U, r3
  371. isync
  372. #if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
  373. /* IBAT 7 */
  374. lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
  375. ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
  376. lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
  377. ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
  378. mtspr IBAT7L, r4
  379. mtspr IBAT7U, r3
  380. isync
  381. /* DBAT 7 */
  382. lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
  383. ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
  384. lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
  385. ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
  386. mtspr DBAT7L, r4
  387. mtspr DBAT7U, r3
  388. isync
  389. #endif
  390. blr
  391. .globl clear_tlbs
  392. clear_tlbs:
  393. addis r3, 0, 0x0000
  394. addis r5, 0, 0x4
  395. isync
  396. tlblp:
  397. tlbie r3
  398. sync
  399. addi r3, r3, 0x1000
  400. cmp 0, 0, r3, r5
  401. blt tlblp
  402. blr
  403. .globl disable_addr_trans
  404. disable_addr_trans:
  405. /* disable address translation */
  406. mflr r4
  407. mfmsr r3
  408. andi. r0, r3, (MSR_IR | MSR_DR)
  409. beqlr
  410. andc r3, r3, r0
  411. mtspr SRR0, r4
  412. mtspr SRR1, r3
  413. rfi
  414. /*
  415. * This code finishes saving the registers to the exception frame
  416. * and jumps to the appropriate handler for the exception.
  417. * Register r21 is pointer into trap frame, r1 has new stack pointer.
  418. */
  419. .globl transfer_to_handler
  420. transfer_to_handler:
  421. stw r22,_NIP(r21)
  422. lis r22,MSR_POW@h
  423. andc r23,r23,r22
  424. stw r23,_MSR(r21)
  425. SAVE_GPR(7, r21)
  426. SAVE_4GPRS(8, r21)
  427. SAVE_8GPRS(12, r21)
  428. SAVE_8GPRS(24, r21)
  429. mflr r23
  430. andi. r24,r23,0x3f00 /* get vector offset */
  431. stw r24,TRAP(r21)
  432. li r22,0
  433. stw r22,RESULT(r21)
  434. mtspr SPRG2,r22 /* r1 is now kernel sp */
  435. lwz r24,0(r23) /* virtual address of handler */
  436. lwz r23,4(r23) /* where to go when done */
  437. mtspr SRR0,r24
  438. mtspr SRR1,r20
  439. mtlr r23
  440. SYNC
  441. rfi /* jump to handler, enable MMU */
  442. int_return:
  443. mfmsr r28 /* Disable interrupts */
  444. li r4,0
  445. ori r4,r4,MSR_EE
  446. andc r28,r28,r4
  447. SYNC /* Some chip revs need this... */
  448. mtmsr r28
  449. SYNC
  450. lwz r2,_CTR(r1)
  451. lwz r0,_LINK(r1)
  452. mtctr r2
  453. mtlr r0
  454. lwz r2,_XER(r1)
  455. lwz r0,_CCR(r1)
  456. mtspr XER,r2
  457. mtcrf 0xFF,r0
  458. REST_10GPRS(3, r1)
  459. REST_10GPRS(13, r1)
  460. REST_8GPRS(23, r1)
  461. REST_GPR(31, r1)
  462. lwz r2,_NIP(r1) /* Restore environment */
  463. lwz r0,_MSR(r1)
  464. mtspr SRR0,r2
  465. mtspr SRR1,r0
  466. lwz r0,GPR0(r1)
  467. lwz r2,GPR2(r1)
  468. lwz r1,GPR1(r1)
  469. SYNC
  470. rfi
  471. .globl dc_read
  472. dc_read:
  473. blr
  474. .globl get_pvr
  475. get_pvr:
  476. mfspr r3, PVR
  477. blr
  478. .globl get_svr
  479. get_svr:
  480. mfspr r3, SVR
  481. blr
  482. /*
  483. * Function: in8
  484. * Description: Input 8 bits
  485. */
  486. .globl in8
  487. in8:
  488. lbz r3,0x0000(r3)
  489. blr
  490. /*
  491. * Function: out8
  492. * Description: Output 8 bits
  493. */
  494. .globl out8
  495. out8:
  496. stb r4,0x0000(r3)
  497. blr
  498. /*
  499. * Function: out16
  500. * Description: Output 16 bits
  501. */
  502. .globl out16
  503. out16:
  504. sth r4,0x0000(r3)
  505. blr
  506. /*
  507. * Function: out16r
  508. * Description: Byte reverse and output 16 bits
  509. */
  510. .globl out16r
  511. out16r:
  512. sthbrx r4,r0,r3
  513. blr
  514. /*
  515. * Function: out32
  516. * Description: Output 32 bits
  517. */
  518. .globl out32
  519. out32:
  520. stw r4,0x0000(r3)
  521. blr
  522. /*
  523. * Function: out32r
  524. * Description: Byte reverse and output 32 bits
  525. */
  526. .globl out32r
  527. out32r:
  528. stwbrx r4,r0,r3
  529. blr
  530. /*
  531. * Function: in16
  532. * Description: Input 16 bits
  533. */
  534. .globl in16
  535. in16:
  536. lhz r3,0x0000(r3)
  537. blr
  538. /*
  539. * Function: in16r
  540. * Description: Input 16 bits and byte reverse
  541. */
  542. .globl in16r
  543. in16r:
  544. lhbrx r3,r0,r3
  545. blr
  546. /*
  547. * Function: in32
  548. * Description: Input 32 bits
  549. */
  550. .globl in32
  551. in32:
  552. lwz 3,0x0000(3)
  553. blr
  554. /*
  555. * Function: in32r
  556. * Description: Input 32 bits and byte reverse
  557. */
  558. .globl in32r
  559. in32r:
  560. lwbrx r3,r0,r3
  561. blr
  562. /*
  563. * void relocate_code (addr_sp, gd, addr_moni)
  564. *
  565. * This "function" does not return, instead it continues in RAM
  566. * after relocating the monitor code.
  567. *
  568. * r3 = dest
  569. * r4 = src
  570. * r5 = length in bytes
  571. * r6 = cachelinesize
  572. */
  573. .globl relocate_code
  574. relocate_code:
  575. mr r1, r3 /* Set new stack pointer */
  576. mr r9, r4 /* Save copy of Global Data pointer */
  577. mr r10, r5 /* Save copy of Destination Address */
  578. GET_GOT
  579. mr r3, r5 /* Destination Address */
  580. lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
  581. ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
  582. lwz r5, GOT(__init_end)
  583. sub r5, r5, r4
  584. li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
  585. /*
  586. * Fix GOT pointer:
  587. *
  588. * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
  589. *
  590. * Offset:
  591. */
  592. sub r15, r10, r4
  593. /* First our own GOT */
  594. add r12, r12, r15
  595. /* then the one used by the C code */
  596. add r30, r30, r15
  597. /*
  598. * Now relocate code
  599. */
  600. cmplw cr1,r3,r4
  601. addi r0,r5,3
  602. srwi. r0,r0,2
  603. beq cr1,4f /* In place copy is not necessary */
  604. beq 7f /* Protect against 0 count */
  605. mtctr r0
  606. bge cr1,2f
  607. la r8,-4(r4)
  608. la r7,-4(r3)
  609. 1: lwzu r0,4(r8)
  610. stwu r0,4(r7)
  611. bdnz 1b
  612. b 4f
  613. 2: slwi r0,r0,2
  614. add r8,r4,r0
  615. add r7,r3,r0
  616. 3: lwzu r0,-4(r8)
  617. stwu r0,-4(r7)
  618. bdnz 3b
  619. /*
  620. * Now flush the cache: note that we must start from a cache aligned
  621. * address. Otherwise we might miss one cache line.
  622. */
  623. 4: cmpwi r6,0
  624. add r5,r3,r5
  625. beq 7f /* Always flush prefetch queue in any case */
  626. subi r0,r6,1
  627. andc r3,r3,r0
  628. mr r4,r3
  629. 5: dcbst 0,r4
  630. add r4,r4,r6
  631. cmplw r4,r5
  632. blt 5b
  633. sync /* Wait for all dcbst to complete on bus */
  634. mr r4,r3
  635. 6: icbi 0,r4
  636. add r4,r4,r6
  637. cmplw r4,r5
  638. blt 6b
  639. 7: sync /* Wait for all icbi to complete on bus */
  640. isync
  641. /*
  642. * We are done. Do not return, instead branch to second part of board
  643. * initialization, now running from RAM.
  644. */
  645. addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
  646. mtlr r0
  647. blr
  648. in_ram:
  649. /*
  650. * Relocation Function, r12 point to got2+0x8000
  651. *
  652. * Adjust got2 pointers, no need to check for 0, this code
  653. * already puts a few entries in the table.
  654. */
  655. li r0,__got2_entries@sectoff@l
  656. la r3,GOT(_GOT2_TABLE_)
  657. lwz r11,GOT(_GOT2_TABLE_)
  658. mtctr r0
  659. sub r11,r3,r11
  660. addi r3,r3,-4
  661. 1: lwzu r0,4(r3)
  662. cmpwi r0,0
  663. beq- 2f
  664. add r0,r0,r11
  665. stw r0,0(r3)
  666. 2: bdnz 1b
  667. /*
  668. * Now adjust the fixups and the pointers to the fixups
  669. * in case we need to move ourselves again.
  670. */
  671. li r0,__fixup_entries@sectoff@l
  672. lwz r3,GOT(_FIXUP_TABLE_)
  673. cmpwi r0,0
  674. mtctr r0
  675. addi r3,r3,-4
  676. beq 4f
  677. 3: lwzu r4,4(r3)
  678. lwzux r0,r4,r11
  679. cmpwi r0,0
  680. add r0,r0,r11
  681. stw r4,0(r3)
  682. beq- 5f
  683. stw r0,0(r4)
  684. 5: bdnz 3b
  685. 4:
  686. /* clear_bss: */
  687. /*
  688. * Now clear BSS segment
  689. */
  690. lwz r3,GOT(__bss_start)
  691. lwz r4,GOT(__bss_end)
  692. cmplw 0, r3, r4
  693. beq 6f
  694. li r0, 0
  695. 5:
  696. stw r0, 0(r3)
  697. addi r3, r3, 4
  698. cmplw 0, r3, r4
  699. bne 5b
  700. 6:
  701. mr r3, r9 /* Init Date pointer */
  702. mr r4, r10 /* Destination Address */
  703. bl board_init_r
  704. /* not reached - end relocate_code */
  705. /*-----------------------------------------------------------------------*/
  706. /*
  707. * Copy exception vector code to low memory
  708. *
  709. * r3: dest_addr
  710. * r7: source address, r8: end address, r9: target address
  711. */
  712. .globl trap_init
  713. trap_init:
  714. mflr r4 /* save link register */
  715. GET_GOT
  716. lwz r7, GOT(_start)
  717. lwz r8, GOT(_end_of_vectors)
  718. li r9, 0x100 /* reset vector always at 0x100 */
  719. cmplw 0, r7, r8
  720. bgelr /* return if r7>=r8 - just in case */
  721. 1:
  722. lwz r0, 0(r7)
  723. stw r0, 0(r9)
  724. addi r7, r7, 4
  725. addi r9, r9, 4
  726. cmplw 0, r7, r8
  727. bne 1b
  728. /*
  729. * relocate `hdlr' and `int_return' entries
  730. */
  731. li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
  732. li r8, Alignment - _start + EXC_OFF_SYS_RESET
  733. 2:
  734. bl trap_reloc
  735. addi r7, r7, 0x100 /* next exception vector */
  736. cmplw 0, r7, r8
  737. blt 2b
  738. li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
  739. bl trap_reloc
  740. li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
  741. bl trap_reloc
  742. li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
  743. li r8, SystemCall - _start + EXC_OFF_SYS_RESET
  744. 3:
  745. bl trap_reloc
  746. addi r7, r7, 0x100 /* next exception vector */
  747. cmplw 0, r7, r8
  748. blt 3b
  749. li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
  750. li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
  751. 4:
  752. bl trap_reloc
  753. addi r7, r7, 0x100 /* next exception vector */
  754. cmplw 0, r7, r8
  755. blt 4b
  756. /* enable execptions from RAM vectors */
  757. mfmsr r7
  758. li r8,MSR_IP
  759. andc r7,r7,r8
  760. ori r7,r7,MSR_ME /* Enable Machine Check */
  761. mtmsr r7
  762. mtlr r4 /* restore link register */
  763. blr
  764. .globl enable_ext_addr
  765. enable_ext_addr:
  766. mfspr r0, HID0
  767. lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
  768. ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
  769. mtspr HID0, r0
  770. sync
  771. isync
  772. blr
  773. #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
  774. .globl setup_ccsrbar
  775. setup_ccsrbar:
  776. /* Special sequence needed to update CCSRBAR itself */
  777. lis r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
  778. ori r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
  779. lis r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
  780. ori r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
  781. srwi r5,r5,12
  782. li r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
  783. rlwimi r5,r6,20,8,11
  784. stw r5, 0(r4) /* Store physical value of CCSR */
  785. isync
  786. lis r5, CONFIG_SYS_TEXT_BASE@h
  787. ori r5,r5,CONFIG_SYS_TEXT_BASE@l
  788. lwz r5, 0(r5)
  789. isync
  790. /* Use VA of CCSR to do read */
  791. lis r3, CONFIG_SYS_CCSRBAR@h
  792. lwz r5, CONFIG_SYS_CCSRBAR@l(r3)
  793. isync
  794. blr
  795. #endif
  796. #ifdef CONFIG_SYS_INIT_RAM_LOCK
  797. lock_ram_in_cache:
  798. /* Allocate Initial RAM in data cache.
  799. */
  800. lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
  801. ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
  802. li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
  803. (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
  804. mtctr r4
  805. 1:
  806. dcbz r0, r3
  807. addi r3, r3, 32
  808. bdnz 1b
  809. #if 1
  810. /* Lock the data cache */
  811. mfspr r0, HID0
  812. ori r0, r0, 0x1000
  813. sync
  814. mtspr HID0, r0
  815. sync
  816. blr
  817. #endif
  818. #if 0
  819. /* Lock the first way of the data cache */
  820. mfspr r0, LDSTCR
  821. ori r0, r0, 0x0080
  822. #if defined(CONFIG_ALTIVEC)
  823. dssall
  824. #endif
  825. sync
  826. mtspr LDSTCR, r0
  827. sync
  828. isync
  829. blr
  830. #endif
  831. .globl unlock_ram_in_cache
  832. unlock_ram_in_cache:
  833. /* invalidate the INIT_RAM section */
  834. lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
  835. ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
  836. li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
  837. (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
  838. mtctr r4
  839. 1: icbi r0, r3
  840. addi r3, r3, 32
  841. bdnz 1b
  842. sync /* Wait for all icbi to complete on bus */
  843. isync
  844. #if 1
  845. /* Unlock the data cache and invalidate it */
  846. mfspr r0, HID0
  847. li r3,0x1000
  848. andc r0,r0,r3
  849. li r3,0x0400
  850. or r0,r0,r3
  851. sync
  852. mtspr HID0, r0
  853. sync
  854. blr
  855. #endif
  856. #if 0
  857. /* Unlock the first way of the data cache */
  858. mfspr r0, LDSTCR
  859. li r3,0x0080
  860. andc r0,r0,r3
  861. #ifdef CONFIG_ALTIVEC
  862. dssall
  863. #endif
  864. sync
  865. mtspr LDSTCR, r0
  866. sync
  867. isync
  868. li r3,0x0400
  869. or r0,r0,r3
  870. sync
  871. mtspr HID0, r0
  872. sync
  873. blr
  874. #endif
  875. #endif