start.S 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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. bl board_init_f
  229. sync
  230. /* NOTREACHED - board_init_f() does not return */
  231. .globl invalidate_bats
  232. invalidate_bats:
  233. li r0, 0
  234. /* invalidate BATs */
  235. mtspr IBAT0U, r0
  236. mtspr IBAT1U, r0
  237. mtspr IBAT2U, r0
  238. mtspr IBAT3U, r0
  239. mtspr IBAT4U, r0
  240. mtspr IBAT5U, r0
  241. mtspr IBAT6U, r0
  242. mtspr IBAT7U, r0
  243. isync
  244. mtspr DBAT0U, r0
  245. mtspr DBAT1U, r0
  246. mtspr DBAT2U, r0
  247. mtspr DBAT3U, r0
  248. mtspr DBAT4U, r0
  249. mtspr DBAT5U, r0
  250. mtspr DBAT6U, r0
  251. mtspr DBAT7U, r0
  252. isync
  253. sync
  254. blr
  255. #define CONFIG_BAT_PAIR(n) \
  256. lis r4, CONFIG_SYS_IBAT##n##L@h; \
  257. ori r4, r4, CONFIG_SYS_IBAT##n##L@l; \
  258. lis r3, CONFIG_SYS_IBAT##n##U@h; \
  259. ori r3, r3, CONFIG_SYS_IBAT##n##U@l; \
  260. mtspr IBAT##n##L, r4; \
  261. mtspr IBAT##n##U, r3; \
  262. lis r4, CONFIG_SYS_DBAT##n##L@h; \
  263. ori r4, r4, CONFIG_SYS_DBAT##n##L@l; \
  264. lis r3, CONFIG_SYS_DBAT##n##U@h; \
  265. ori r3, r3, CONFIG_SYS_DBAT##n##U@l; \
  266. mtspr DBAT##n##L, r4; \
  267. mtspr DBAT##n##U, r3;
  268. /*
  269. * setup_bats:
  270. *
  271. * Set up the final BAT registers now that setup is done.
  272. *
  273. * Assumes that:
  274. * 1) Address translation is enabled upon entry
  275. * 2) The boot rom is still accessible via 1:1 translation
  276. */
  277. .globl setup_bats
  278. setup_bats:
  279. mflr r5
  280. sync
  281. /*
  282. * When we disable address translation, we will get 1:1 (VA==PA)
  283. * translation. The only place we know for sure is safe for that is
  284. * the bootrom where we originally started out. Pop back into there.
  285. */
  286. lis r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
  287. ori r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
  288. addi r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
  289. /* disable address translation */
  290. mfmsr r3
  291. rlwinm r3, r3, 0, 28, 25
  292. mtspr SRR0, r4
  293. mtspr SRR1, r3
  294. rfi
  295. trans_disabled:
  296. #if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
  297. && defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
  298. CONFIG_BAT_PAIR(0)
  299. #endif
  300. CONFIG_BAT_PAIR(1)
  301. CONFIG_BAT_PAIR(2)
  302. CONFIG_BAT_PAIR(3)
  303. CONFIG_BAT_PAIR(4)
  304. CONFIG_BAT_PAIR(5)
  305. CONFIG_BAT_PAIR(6)
  306. CONFIG_BAT_PAIR(7)
  307. sync
  308. isync
  309. /* Turn translation back on and return */
  310. mfmsr r3
  311. ori r3, r3, (MSR_IR | MSR_DR)
  312. mtspr SPRN_SRR0,r5
  313. mtspr SPRN_SRR1,r3
  314. rfi
  315. /*
  316. * early_bats:
  317. *
  318. * Set up bats needed early on - this is usually the BAT for the
  319. * stack-in-cache, the Flash, and CCSR space
  320. */
  321. .globl early_bats
  322. early_bats:
  323. /* IBAT 3 */
  324. lis r4, CONFIG_SYS_IBAT3L@h
  325. ori r4, r4, CONFIG_SYS_IBAT3L@l
  326. lis r3, CONFIG_SYS_IBAT3U@h
  327. ori r3, r3, CONFIG_SYS_IBAT3U@l
  328. mtspr IBAT3L, r4
  329. mtspr IBAT3U, r3
  330. isync
  331. /* DBAT 3 */
  332. lis r4, CONFIG_SYS_DBAT3L@h
  333. ori r4, r4, CONFIG_SYS_DBAT3L@l
  334. lis r3, CONFIG_SYS_DBAT3U@h
  335. ori r3, r3, CONFIG_SYS_DBAT3U@l
  336. mtspr DBAT3L, r4
  337. mtspr DBAT3U, r3
  338. isync
  339. /* IBAT 5 */
  340. lis r4, CONFIG_SYS_IBAT5L@h
  341. ori r4, r4, CONFIG_SYS_IBAT5L@l
  342. lis r3, CONFIG_SYS_IBAT5U@h
  343. ori r3, r3, CONFIG_SYS_IBAT5U@l
  344. mtspr IBAT5L, r4
  345. mtspr IBAT5U, r3
  346. isync
  347. /* DBAT 5 */
  348. lis r4, CONFIG_SYS_DBAT5L@h
  349. ori r4, r4, CONFIG_SYS_DBAT5L@l
  350. lis r3, CONFIG_SYS_DBAT5U@h
  351. ori r3, r3, CONFIG_SYS_DBAT5U@l
  352. mtspr DBAT5L, r4
  353. mtspr DBAT5U, r3
  354. isync
  355. /* IBAT 6 */
  356. lis r4, CONFIG_SYS_IBAT6L_EARLY@h
  357. ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
  358. lis r3, CONFIG_SYS_IBAT6U_EARLY@h
  359. ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
  360. mtspr IBAT6L, r4
  361. mtspr IBAT6U, r3
  362. isync
  363. /* DBAT 6 */
  364. lis r4, CONFIG_SYS_DBAT6L_EARLY@h
  365. ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
  366. lis r3, CONFIG_SYS_DBAT6U_EARLY@h
  367. ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
  368. mtspr DBAT6L, r4
  369. mtspr DBAT6U, r3
  370. isync
  371. #if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
  372. /* IBAT 7 */
  373. lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
  374. ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
  375. lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
  376. ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
  377. mtspr IBAT7L, r4
  378. mtspr IBAT7U, r3
  379. isync
  380. /* DBAT 7 */
  381. lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
  382. ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
  383. lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
  384. ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
  385. mtspr DBAT7L, r4
  386. mtspr DBAT7U, r3
  387. isync
  388. #endif
  389. blr
  390. .globl clear_tlbs
  391. clear_tlbs:
  392. addis r3, 0, 0x0000
  393. addis r5, 0, 0x4
  394. isync
  395. tlblp:
  396. tlbie r3
  397. sync
  398. addi r3, r3, 0x1000
  399. cmp 0, 0, r3, r5
  400. blt tlblp
  401. blr
  402. .globl disable_addr_trans
  403. disable_addr_trans:
  404. /* disable address translation */
  405. mflr r4
  406. mfmsr r3
  407. andi. r0, r3, (MSR_IR | MSR_DR)
  408. beqlr
  409. andc r3, r3, r0
  410. mtspr SRR0, r4
  411. mtspr SRR1, r3
  412. rfi
  413. /*
  414. * This code finishes saving the registers to the exception frame
  415. * and jumps to the appropriate handler for the exception.
  416. * Register r21 is pointer into trap frame, r1 has new stack pointer.
  417. */
  418. .globl transfer_to_handler
  419. transfer_to_handler:
  420. stw r22,_NIP(r21)
  421. lis r22,MSR_POW@h
  422. andc r23,r23,r22
  423. stw r23,_MSR(r21)
  424. SAVE_GPR(7, r21)
  425. SAVE_4GPRS(8, r21)
  426. SAVE_8GPRS(12, r21)
  427. SAVE_8GPRS(24, r21)
  428. mflr r23
  429. andi. r24,r23,0x3f00 /* get vector offset */
  430. stw r24,TRAP(r21)
  431. li r22,0
  432. stw r22,RESULT(r21)
  433. mtspr SPRG2,r22 /* r1 is now kernel sp */
  434. lwz r24,0(r23) /* virtual address of handler */
  435. lwz r23,4(r23) /* where to go when done */
  436. mtspr SRR0,r24
  437. mtspr SRR1,r20
  438. mtlr r23
  439. SYNC
  440. rfi /* jump to handler, enable MMU */
  441. int_return:
  442. mfmsr r28 /* Disable interrupts */
  443. li r4,0
  444. ori r4,r4,MSR_EE
  445. andc r28,r28,r4
  446. SYNC /* Some chip revs need this... */
  447. mtmsr r28
  448. SYNC
  449. lwz r2,_CTR(r1)
  450. lwz r0,_LINK(r1)
  451. mtctr r2
  452. mtlr r0
  453. lwz r2,_XER(r1)
  454. lwz r0,_CCR(r1)
  455. mtspr XER,r2
  456. mtcrf 0xFF,r0
  457. REST_10GPRS(3, r1)
  458. REST_10GPRS(13, r1)
  459. REST_8GPRS(23, r1)
  460. REST_GPR(31, r1)
  461. lwz r2,_NIP(r1) /* Restore environment */
  462. lwz r0,_MSR(r1)
  463. mtspr SRR0,r2
  464. mtspr SRR1,r0
  465. lwz r0,GPR0(r1)
  466. lwz r2,GPR2(r1)
  467. lwz r1,GPR1(r1)
  468. SYNC
  469. rfi
  470. .globl dc_read
  471. dc_read:
  472. blr
  473. .globl get_pvr
  474. get_pvr:
  475. mfspr r3, PVR
  476. blr
  477. .globl get_svr
  478. get_svr:
  479. mfspr r3, SVR
  480. blr
  481. /*
  482. * Function: in8
  483. * Description: Input 8 bits
  484. */
  485. .globl in8
  486. in8:
  487. lbz r3,0x0000(r3)
  488. blr
  489. /*
  490. * Function: out8
  491. * Description: Output 8 bits
  492. */
  493. .globl out8
  494. out8:
  495. stb r4,0x0000(r3)
  496. blr
  497. /*
  498. * Function: out16
  499. * Description: Output 16 bits
  500. */
  501. .globl out16
  502. out16:
  503. sth r4,0x0000(r3)
  504. blr
  505. /*
  506. * Function: out16r
  507. * Description: Byte reverse and output 16 bits
  508. */
  509. .globl out16r
  510. out16r:
  511. sthbrx r4,r0,r3
  512. blr
  513. /*
  514. * Function: out32
  515. * Description: Output 32 bits
  516. */
  517. .globl out32
  518. out32:
  519. stw r4,0x0000(r3)
  520. blr
  521. /*
  522. * Function: out32r
  523. * Description: Byte reverse and output 32 bits
  524. */
  525. .globl out32r
  526. out32r:
  527. stwbrx r4,r0,r3
  528. blr
  529. /*
  530. * Function: in16
  531. * Description: Input 16 bits
  532. */
  533. .globl in16
  534. in16:
  535. lhz r3,0x0000(r3)
  536. blr
  537. /*
  538. * Function: in16r
  539. * Description: Input 16 bits and byte reverse
  540. */
  541. .globl in16r
  542. in16r:
  543. lhbrx r3,r0,r3
  544. blr
  545. /*
  546. * Function: in32
  547. * Description: Input 32 bits
  548. */
  549. .globl in32
  550. in32:
  551. lwz 3,0x0000(3)
  552. blr
  553. /*
  554. * Function: in32r
  555. * Description: Input 32 bits and byte reverse
  556. */
  557. .globl in32r
  558. in32r:
  559. lwbrx r3,r0,r3
  560. blr
  561. /*
  562. * void relocate_code (addr_sp, gd, addr_moni)
  563. *
  564. * This "function" does not return, instead it continues in RAM
  565. * after relocating the monitor code.
  566. *
  567. * r3 = dest
  568. * r4 = src
  569. * r5 = length in bytes
  570. * r6 = cachelinesize
  571. */
  572. .globl relocate_code
  573. relocate_code:
  574. mr r1, r3 /* Set new stack pointer */
  575. mr r9, r4 /* Save copy of Global Data pointer */
  576. mr r10, r5 /* Save copy of Destination Address */
  577. GET_GOT
  578. mr r3, r5 /* Destination Address */
  579. lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
  580. ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
  581. lwz r5, GOT(__init_end)
  582. sub r5, r5, r4
  583. li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
  584. /*
  585. * Fix GOT pointer:
  586. *
  587. * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
  588. *
  589. * Offset:
  590. */
  591. sub r15, r10, r4
  592. /* First our own GOT */
  593. add r12, r12, r15
  594. /* then the one used by the C code */
  595. add r30, r30, r15
  596. /*
  597. * Now relocate code
  598. */
  599. cmplw cr1,r3,r4
  600. addi r0,r5,3
  601. srwi. r0,r0,2
  602. beq cr1,4f /* In place copy is not necessary */
  603. beq 7f /* Protect against 0 count */
  604. mtctr r0
  605. bge cr1,2f
  606. la r8,-4(r4)
  607. la r7,-4(r3)
  608. 1: lwzu r0,4(r8)
  609. stwu r0,4(r7)
  610. bdnz 1b
  611. b 4f
  612. 2: slwi r0,r0,2
  613. add r8,r4,r0
  614. add r7,r3,r0
  615. 3: lwzu r0,-4(r8)
  616. stwu r0,-4(r7)
  617. bdnz 3b
  618. /*
  619. * Now flush the cache: note that we must start from a cache aligned
  620. * address. Otherwise we might miss one cache line.
  621. */
  622. 4: cmpwi r6,0
  623. add r5,r3,r5
  624. beq 7f /* Always flush prefetch queue in any case */
  625. subi r0,r6,1
  626. andc r3,r3,r0
  627. mr r4,r3
  628. 5: dcbst 0,r4
  629. add r4,r4,r6
  630. cmplw r4,r5
  631. blt 5b
  632. sync /* Wait for all dcbst to complete on bus */
  633. mr r4,r3
  634. 6: icbi 0,r4
  635. add r4,r4,r6
  636. cmplw r4,r5
  637. blt 6b
  638. 7: sync /* Wait for all icbi to complete on bus */
  639. isync
  640. /*
  641. * We are done. Do not return, instead branch to second part of board
  642. * initialization, now running from RAM.
  643. */
  644. addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
  645. mtlr r0
  646. blr
  647. in_ram:
  648. /*
  649. * Relocation Function, r12 point to got2+0x8000
  650. *
  651. * Adjust got2 pointers, no need to check for 0, this code
  652. * already puts a few entries in the table.
  653. */
  654. li r0,__got2_entries@sectoff@l
  655. la r3,GOT(_GOT2_TABLE_)
  656. lwz r11,GOT(_GOT2_TABLE_)
  657. mtctr r0
  658. sub r11,r3,r11
  659. addi r3,r3,-4
  660. 1: lwzu r0,4(r3)
  661. cmpwi r0,0
  662. beq- 2f
  663. add r0,r0,r11
  664. stw r0,0(r3)
  665. 2: bdnz 1b
  666. /*
  667. * Now adjust the fixups and the pointers to the fixups
  668. * in case we need to move ourselves again.
  669. */
  670. li r0,__fixup_entries@sectoff@l
  671. lwz r3,GOT(_FIXUP_TABLE_)
  672. cmpwi r0,0
  673. mtctr r0
  674. addi r3,r3,-4
  675. beq 4f
  676. 3: lwzu r4,4(r3)
  677. lwzux r0,r4,r11
  678. cmpwi r0,0
  679. add r0,r0,r11
  680. stw r4,0(r3)
  681. beq- 5f
  682. stw r0,0(r4)
  683. 5: bdnz 3b
  684. 4:
  685. /* clear_bss: */
  686. /*
  687. * Now clear BSS segment
  688. */
  689. lwz r3,GOT(__bss_start)
  690. lwz r4,GOT(__bss_end)
  691. cmplw 0, r3, r4
  692. beq 6f
  693. li r0, 0
  694. 5:
  695. stw r0, 0(r3)
  696. addi r3, r3, 4
  697. cmplw 0, r3, r4
  698. bne 5b
  699. 6:
  700. mr r3, r9 /* Init Date pointer */
  701. mr r4, r10 /* Destination Address */
  702. bl board_init_r
  703. /* not reached - end relocate_code */
  704. /*-----------------------------------------------------------------------*/
  705. /*
  706. * Copy exception vector code to low memory
  707. *
  708. * r3: dest_addr
  709. * r7: source address, r8: end address, r9: target address
  710. */
  711. .globl trap_init
  712. trap_init:
  713. mflr r4 /* save link register */
  714. GET_GOT
  715. lwz r7, GOT(_start)
  716. lwz r8, GOT(_end_of_vectors)
  717. li r9, 0x100 /* reset vector always at 0x100 */
  718. cmplw 0, r7, r8
  719. bgelr /* return if r7>=r8 - just in case */
  720. 1:
  721. lwz r0, 0(r7)
  722. stw r0, 0(r9)
  723. addi r7, r7, 4
  724. addi r9, r9, 4
  725. cmplw 0, r7, r8
  726. bne 1b
  727. /*
  728. * relocate `hdlr' and `int_return' entries
  729. */
  730. li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
  731. li r8, Alignment - _start + EXC_OFF_SYS_RESET
  732. 2:
  733. bl trap_reloc
  734. addi r7, r7, 0x100 /* next exception vector */
  735. cmplw 0, r7, r8
  736. blt 2b
  737. li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
  738. bl trap_reloc
  739. li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
  740. bl trap_reloc
  741. li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
  742. li r8, SystemCall - _start + EXC_OFF_SYS_RESET
  743. 3:
  744. bl trap_reloc
  745. addi r7, r7, 0x100 /* next exception vector */
  746. cmplw 0, r7, r8
  747. blt 3b
  748. li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
  749. li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
  750. 4:
  751. bl trap_reloc
  752. addi r7, r7, 0x100 /* next exception vector */
  753. cmplw 0, r7, r8
  754. blt 4b
  755. /* enable execptions from RAM vectors */
  756. mfmsr r7
  757. li r8,MSR_IP
  758. andc r7,r7,r8
  759. ori r7,r7,MSR_ME /* Enable Machine Check */
  760. mtmsr r7
  761. mtlr r4 /* restore link register */
  762. blr
  763. .globl enable_ext_addr
  764. enable_ext_addr:
  765. mfspr r0, HID0
  766. lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
  767. ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
  768. mtspr HID0, r0
  769. sync
  770. isync
  771. blr
  772. #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
  773. .globl setup_ccsrbar
  774. setup_ccsrbar:
  775. /* Special sequence needed to update CCSRBAR itself */
  776. lis r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
  777. ori r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
  778. lis r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
  779. ori r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
  780. srwi r5,r5,12
  781. li r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
  782. rlwimi r5,r6,20,8,11
  783. stw r5, 0(r4) /* Store physical value of CCSR */
  784. isync
  785. lis r5, CONFIG_SYS_TEXT_BASE@h
  786. ori r5,r5,CONFIG_SYS_TEXT_BASE@l
  787. lwz r5, 0(r5)
  788. isync
  789. /* Use VA of CCSR to do read */
  790. lis r3, CONFIG_SYS_CCSRBAR@h
  791. lwz r5, CONFIG_SYS_CCSRBAR@l(r3)
  792. isync
  793. blr
  794. #endif
  795. #ifdef CONFIG_SYS_INIT_RAM_LOCK
  796. lock_ram_in_cache:
  797. /* Allocate Initial RAM in data cache.
  798. */
  799. lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
  800. ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
  801. li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
  802. (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
  803. mtctr r4
  804. 1:
  805. dcbz r0, r3
  806. addi r3, r3, 32
  807. bdnz 1b
  808. #if 1
  809. /* Lock the data cache */
  810. mfspr r0, HID0
  811. ori r0, r0, 0x1000
  812. sync
  813. mtspr HID0, r0
  814. sync
  815. blr
  816. #endif
  817. #if 0
  818. /* Lock the first way of the data cache */
  819. mfspr r0, LDSTCR
  820. ori r0, r0, 0x0080
  821. #if defined(CONFIG_ALTIVEC)
  822. dssall
  823. #endif
  824. sync
  825. mtspr LDSTCR, r0
  826. sync
  827. isync
  828. blr
  829. #endif
  830. .globl unlock_ram_in_cache
  831. unlock_ram_in_cache:
  832. /* invalidate the INIT_RAM section */
  833. lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
  834. ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
  835. li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
  836. (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
  837. mtctr r4
  838. 1: icbi r0, r3
  839. addi r3, r3, 32
  840. bdnz 1b
  841. sync /* Wait for all icbi to complete on bus */
  842. isync
  843. #if 1
  844. /* Unlock the data cache and invalidate it */
  845. mfspr r0, HID0
  846. li r3,0x1000
  847. andc r0,r0,r3
  848. li r3,0x0400
  849. or r0,r0,r3
  850. sync
  851. mtspr HID0, r0
  852. sync
  853. blr
  854. #endif
  855. #if 0
  856. /* Unlock the first way of the data cache */
  857. mfspr r0, LDSTCR
  858. li r3,0x0080
  859. andc r0,r0,r3
  860. #ifdef CONFIG_ALTIVEC
  861. dssall
  862. #endif
  863. sync
  864. mtspr LDSTCR, r0
  865. sync
  866. isync
  867. li r3,0x0400
  868. or r0,r0,r3
  869. sync
  870. mtspr HID0, r0
  871. sync
  872. blr
  873. #endif
  874. #endif