exceptions-64e.S 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /*
  2. * Boot code and exception vectors for Book3E processors
  3. *
  4. * Copyright (C) 2007 Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <linux/threads.h>
  12. #include <asm/reg.h>
  13. #include <asm/page.h>
  14. #include <asm/ppc_asm.h>
  15. #include <asm/asm-offsets.h>
  16. #include <asm/cputable.h>
  17. #include <asm/setup.h>
  18. #include <asm/thread_info.h>
  19. #include <asm/reg.h>
  20. #include <asm/exception-64e.h>
  21. #include <asm/bug.h>
  22. #include <asm/irqflags.h>
  23. #include <asm/ptrace.h>
  24. #include <asm/ppc-opcode.h>
  25. #include <asm/mmu.h>
  26. /* XXX This will ultimately add space for a special exception save
  27. * structure used to save things like SRR0/SRR1, SPRGs, MAS, etc...
  28. * when taking special interrupts. For now we don't support that,
  29. * special interrupts from within a non-standard level will probably
  30. * blow you up
  31. */
  32. #define SPECIAL_EXC_FRAME_SIZE INT_FRAME_SIZE
  33. /* Exception prolog code for all exceptions */
  34. #define EXCEPTION_PROLOG(n, type, addition) \
  35. mtspr SPRN_SPRG_##type##_SCRATCH,r13; /* get spare registers */ \
  36. mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \
  37. std r10,PACA_EX##type+EX_R10(r13); \
  38. std r11,PACA_EX##type+EX_R11(r13); \
  39. mfcr r10; /* save CR */ \
  40. addition; /* additional code for that exc. */ \
  41. std r1,PACA_EX##type+EX_R1(r13); /* save old r1 in the PACA */ \
  42. stw r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \
  43. mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \
  44. type##_SET_KSTACK; /* get special stack if necessary */\
  45. andi. r10,r11,MSR_PR; /* save stack pointer */ \
  46. beq 1f; /* branch around if supervisor */ \
  47. ld r1,PACAKSAVE(r13); /* get kernel stack coming from usr */\
  48. 1: cmpdi cr1,r1,0; /* check if SP makes sense */ \
  49. bge- cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \
  50. mfspr r10,SPRN_##type##_SRR0; /* read SRR0 before touching stack */
  51. /* Exception type-specific macros */
  52. #define GEN_SET_KSTACK \
  53. subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */
  54. #define SPRN_GEN_SRR0 SPRN_SRR0
  55. #define SPRN_GEN_SRR1 SPRN_SRR1
  56. #define CRIT_SET_KSTACK \
  57. ld r1,PACA_CRIT_STACK(r13); \
  58. subi r1,r1,SPECIAL_EXC_FRAME_SIZE;
  59. #define SPRN_CRIT_SRR0 SPRN_CSRR0
  60. #define SPRN_CRIT_SRR1 SPRN_CSRR1
  61. #define DBG_SET_KSTACK \
  62. ld r1,PACA_DBG_STACK(r13); \
  63. subi r1,r1,SPECIAL_EXC_FRAME_SIZE;
  64. #define SPRN_DBG_SRR0 SPRN_DSRR0
  65. #define SPRN_DBG_SRR1 SPRN_DSRR1
  66. #define MC_SET_KSTACK \
  67. ld r1,PACA_MC_STACK(r13); \
  68. subi r1,r1,SPECIAL_EXC_FRAME_SIZE;
  69. #define SPRN_MC_SRR0 SPRN_MCSRR0
  70. #define SPRN_MC_SRR1 SPRN_MCSRR1
  71. #define NORMAL_EXCEPTION_PROLOG(n, addition) \
  72. EXCEPTION_PROLOG(n, GEN, addition##_GEN)
  73. #define CRIT_EXCEPTION_PROLOG(n, addition) \
  74. EXCEPTION_PROLOG(n, CRIT, addition##_CRIT)
  75. #define DBG_EXCEPTION_PROLOG(n, addition) \
  76. EXCEPTION_PROLOG(n, DBG, addition##_DBG)
  77. #define MC_EXCEPTION_PROLOG(n, addition) \
  78. EXCEPTION_PROLOG(n, MC, addition##_MC)
  79. /* Variants of the "addition" argument for the prolog
  80. */
  81. #define PROLOG_ADDITION_NONE_GEN
  82. #define PROLOG_ADDITION_NONE_CRIT
  83. #define PROLOG_ADDITION_NONE_DBG
  84. #define PROLOG_ADDITION_NONE_MC
  85. #define PROLOG_ADDITION_MASKABLE_GEN \
  86. lbz r11,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */ \
  87. cmpwi cr0,r11,0; /* yes -> go out of line */ \
  88. beq masked_interrupt_book3e;
  89. #define PROLOG_ADDITION_2REGS_GEN \
  90. std r14,PACA_EXGEN+EX_R14(r13); \
  91. std r15,PACA_EXGEN+EX_R15(r13)
  92. #define PROLOG_ADDITION_1REG_GEN \
  93. std r14,PACA_EXGEN+EX_R14(r13);
  94. #define PROLOG_ADDITION_2REGS_CRIT \
  95. std r14,PACA_EXCRIT+EX_R14(r13); \
  96. std r15,PACA_EXCRIT+EX_R15(r13)
  97. #define PROLOG_ADDITION_2REGS_DBG \
  98. std r14,PACA_EXDBG+EX_R14(r13); \
  99. std r15,PACA_EXDBG+EX_R15(r13)
  100. #define PROLOG_ADDITION_2REGS_MC \
  101. std r14,PACA_EXMC+EX_R14(r13); \
  102. std r15,PACA_EXMC+EX_R15(r13)
  103. /* Core exception code for all exceptions except TLB misses.
  104. * XXX: Needs to make SPRN_SPRG_GEN depend on exception type
  105. */
  106. #define EXCEPTION_COMMON(n, excf, ints) \
  107. std r0,GPR0(r1); /* save r0 in stackframe */ \
  108. std r2,GPR2(r1); /* save r2 in stackframe */ \
  109. SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
  110. SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
  111. std r9,GPR9(r1); /* save r9 in stackframe */ \
  112. std r10,_NIP(r1); /* save SRR0 to stackframe */ \
  113. std r11,_MSR(r1); /* save SRR1 to stackframe */ \
  114. ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */ \
  115. ld r3,excf+EX_R10(r13); /* get back r10 */ \
  116. ld r4,excf+EX_R11(r13); /* get back r11 */ \
  117. mfspr r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 */ \
  118. std r12,GPR12(r1); /* save r12 in stackframe */ \
  119. ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
  120. mflr r6; /* save LR in stackframe */ \
  121. mfctr r7; /* save CTR in stackframe */ \
  122. mfspr r8,SPRN_XER; /* save XER in stackframe */ \
  123. ld r9,excf+EX_R1(r13); /* load orig r1 back from PACA */ \
  124. lwz r10,excf+EX_CR(r13); /* load orig CR back from PACA */ \
  125. lbz r11,PACASOFTIRQEN(r13); /* get current IRQ softe */ \
  126. ld r12,exception_marker@toc(r2); \
  127. li r0,0; \
  128. std r3,GPR10(r1); /* save r10 to stackframe */ \
  129. std r4,GPR11(r1); /* save r11 to stackframe */ \
  130. std r5,GPR13(r1); /* save it to stackframe */ \
  131. std r6,_LINK(r1); \
  132. std r7,_CTR(r1); \
  133. std r8,_XER(r1); \
  134. li r3,(n)+1; /* indicate partial regs in trap */ \
  135. std r9,0(r1); /* store stack frame back link */ \
  136. std r10,_CCR(r1); /* store orig CR in stackframe */ \
  137. std r9,GPR1(r1); /* store stack frame back link */ \
  138. std r11,SOFTE(r1); /* and save it to stackframe */ \
  139. std r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ \
  140. std r3,_TRAP(r1); /* set trap number */ \
  141. std r0,RESULT(r1); /* clear regs->result */ \
  142. ints;
  143. /* Variants for the "ints" argument */
  144. #define INTS_KEEP
  145. #define INTS_DISABLE_SOFT \
  146. stb r0,PACASOFTIRQEN(r13); /* mark interrupts soft-disabled */ \
  147. TRACE_DISABLE_INTS;
  148. #define INTS_DISABLE_HARD \
  149. stb r0,PACAHARDIRQEN(r13); /* and hard disabled */
  150. #define INTS_DISABLE_ALL \
  151. INTS_DISABLE_SOFT \
  152. INTS_DISABLE_HARD
  153. /* This is called by exceptions that used INTS_KEEP (that is did not clear
  154. * neither soft nor hard IRQ indicators in the PACA. This will restore MSR:EE
  155. * to it's previous value
  156. *
  157. * XXX In the long run, we may want to open-code it in order to separate the
  158. * load from the wrtee, thus limiting the latency caused by the dependency
  159. * but at this point, I'll favor code clarity until we have a near to final
  160. * implementation
  161. */
  162. #define INTS_RESTORE_HARD \
  163. ld r11,_MSR(r1); \
  164. wrtee r11;
  165. /* XXX FIXME: Restore r14/r15 when necessary */
  166. #define BAD_STACK_TRAMPOLINE(n) \
  167. exc_##n##_bad_stack: \
  168. li r1,(n); /* get exception number */ \
  169. sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \
  170. b bad_stack_book3e; /* bad stack error */
  171. #define EXCEPTION_STUB(loc, label) \
  172. . = interrupt_base_book3e + loc; \
  173. nop; /* To make debug interrupts happy */ \
  174. b exc_##label##_book3e;
  175. #define ACK_NONE(r)
  176. #define ACK_DEC(r) \
  177. lis r,TSR_DIS@h; \
  178. mtspr SPRN_TSR,r
  179. #define ACK_FIT(r) \
  180. lis r,TSR_FIS@h; \
  181. mtspr SPRN_TSR,r
  182. #define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \
  183. START_EXCEPTION(label); \
  184. NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \
  185. EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \
  186. ack(r8); \
  187. addi r3,r1,STACK_FRAME_OVERHEAD; \
  188. bl hdlr; \
  189. b .ret_from_except_lite;
  190. /* This value is used to mark exception frames on the stack. */
  191. .section ".toc","aw"
  192. exception_marker:
  193. .tc ID_EXC_MARKER[TC],STACK_FRAME_REGS_MARKER
  194. /*
  195. * And here we have the exception vectors !
  196. */
  197. .text
  198. .balign 0x1000
  199. .globl interrupt_base_book3e
  200. interrupt_base_book3e: /* fake trap */
  201. /* Note: If real debug exceptions are supported by the HW, the vector
  202. * below will have to be patched up to point to an appropriate handler
  203. */
  204. EXCEPTION_STUB(0x000, machine_check) /* 0x0200 */
  205. EXCEPTION_STUB(0x020, critical_input) /* 0x0580 */
  206. EXCEPTION_STUB(0x040, debug_crit) /* 0x0d00 */
  207. EXCEPTION_STUB(0x060, data_storage) /* 0x0300 */
  208. EXCEPTION_STUB(0x080, instruction_storage) /* 0x0400 */
  209. EXCEPTION_STUB(0x0a0, external_input) /* 0x0500 */
  210. EXCEPTION_STUB(0x0c0, alignment) /* 0x0600 */
  211. EXCEPTION_STUB(0x0e0, program) /* 0x0700 */
  212. EXCEPTION_STUB(0x100, fp_unavailable) /* 0x0800 */
  213. EXCEPTION_STUB(0x120, system_call) /* 0x0c00 */
  214. EXCEPTION_STUB(0x140, ap_unavailable) /* 0x0f20 */
  215. EXCEPTION_STUB(0x160, decrementer) /* 0x0900 */
  216. EXCEPTION_STUB(0x180, fixed_interval) /* 0x0980 */
  217. EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */
  218. EXCEPTION_STUB(0x1c0, data_tlb_miss)
  219. EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
  220. #if 0
  221. EXCEPTION_STUB(0x280, processor_doorbell)
  222. EXCEPTION_STUB(0x220, processor_doorbell_crit)
  223. #endif
  224. .globl interrupt_end_book3e
  225. interrupt_end_book3e:
  226. /* Critical Input Interrupt */
  227. START_EXCEPTION(critical_input);
  228. CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE)
  229. // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL)
  230. // bl special_reg_save_crit
  231. // addi r3,r1,STACK_FRAME_OVERHEAD
  232. // bl .critical_exception
  233. // b ret_from_crit_except
  234. b .
  235. /* Machine Check Interrupt */
  236. START_EXCEPTION(machine_check);
  237. CRIT_EXCEPTION_PROLOG(0x200, PROLOG_ADDITION_NONE)
  238. // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL)
  239. // bl special_reg_save_mc
  240. // addi r3,r1,STACK_FRAME_OVERHEAD
  241. // bl .machine_check_exception
  242. // b ret_from_mc_except
  243. b .
  244. /* Data Storage Interrupt */
  245. START_EXCEPTION(data_storage)
  246. NORMAL_EXCEPTION_PROLOG(0x300, PROLOG_ADDITION_2REGS)
  247. mfspr r14,SPRN_DEAR
  248. mfspr r15,SPRN_ESR
  249. EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_KEEP)
  250. b storage_fault_common
  251. /* Instruction Storage Interrupt */
  252. START_EXCEPTION(instruction_storage);
  253. NORMAL_EXCEPTION_PROLOG(0x400, PROLOG_ADDITION_2REGS)
  254. li r15,0
  255. mr r14,r10
  256. EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_KEEP)
  257. b storage_fault_common
  258. /* External Input Interrupt */
  259. MASKABLE_EXCEPTION(0x500, external_input, .do_IRQ, ACK_NONE)
  260. /* Alignment */
  261. START_EXCEPTION(alignment);
  262. NORMAL_EXCEPTION_PROLOG(0x600, PROLOG_ADDITION_2REGS)
  263. mfspr r14,SPRN_DEAR
  264. mfspr r15,SPRN_ESR
  265. EXCEPTION_COMMON(0x600, PACA_EXGEN, INTS_KEEP)
  266. b alignment_more /* no room, go out of line */
  267. /* Program Interrupt */
  268. START_EXCEPTION(program);
  269. NORMAL_EXCEPTION_PROLOG(0x700, PROLOG_ADDITION_1REG)
  270. mfspr r14,SPRN_ESR
  271. EXCEPTION_COMMON(0x700, PACA_EXGEN, INTS_DISABLE_SOFT)
  272. std r14,_DSISR(r1)
  273. addi r3,r1,STACK_FRAME_OVERHEAD
  274. ld r14,PACA_EXGEN+EX_R14(r13)
  275. bl .save_nvgprs
  276. INTS_RESTORE_HARD
  277. bl .program_check_exception
  278. b .ret_from_except
  279. /* Floating Point Unavailable Interrupt */
  280. START_EXCEPTION(fp_unavailable);
  281. NORMAL_EXCEPTION_PROLOG(0x800, PROLOG_ADDITION_NONE)
  282. /* we can probably do a shorter exception entry for that one... */
  283. EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP)
  284. bne 1f /* if from user, just load it up */
  285. bl .save_nvgprs
  286. addi r3,r1,STACK_FRAME_OVERHEAD
  287. INTS_RESTORE_HARD
  288. bl .kernel_fp_unavailable_exception
  289. BUG_OPCODE
  290. 1: ld r12,_MSR(r1)
  291. bl .load_up_fpu
  292. b fast_exception_return
  293. /* Decrementer Interrupt */
  294. MASKABLE_EXCEPTION(0x900, decrementer, .timer_interrupt, ACK_DEC)
  295. /* Fixed Interval Timer Interrupt */
  296. MASKABLE_EXCEPTION(0x980, fixed_interval, .unknown_exception, ACK_FIT)
  297. /* Watchdog Timer Interrupt */
  298. START_EXCEPTION(watchdog);
  299. CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE)
  300. // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL)
  301. // bl special_reg_save_crit
  302. // addi r3,r1,STACK_FRAME_OVERHEAD
  303. // bl .unknown_exception
  304. // b ret_from_crit_except
  305. b .
  306. /* System Call Interrupt */
  307. START_EXCEPTION(system_call)
  308. mr r9,r13 /* keep a copy of userland r13 */
  309. mfspr r11,SPRN_SRR0 /* get return address */
  310. mfspr r12,SPRN_SRR1 /* get previous MSR */
  311. mfspr r13,SPRN_SPRG_PACA /* get our PACA */
  312. b system_call_common
  313. /* Auxillary Processor Unavailable Interrupt */
  314. START_EXCEPTION(ap_unavailable);
  315. NORMAL_EXCEPTION_PROLOG(0xf20, PROLOG_ADDITION_NONE)
  316. EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_KEEP)
  317. addi r3,r1,STACK_FRAME_OVERHEAD
  318. bl .save_nvgprs
  319. INTS_RESTORE_HARD
  320. bl .unknown_exception
  321. b .ret_from_except
  322. /* Debug exception as a critical interrupt*/
  323. START_EXCEPTION(debug_crit);
  324. CRIT_EXCEPTION_PROLOG(0xd00, PROLOG_ADDITION_2REGS)
  325. /*
  326. * If there is a single step or branch-taken exception in an
  327. * exception entry sequence, it was probably meant to apply to
  328. * the code where the exception occurred (since exception entry
  329. * doesn't turn off DE automatically). We simulate the effect
  330. * of turning off DE on entry to an exception handler by turning
  331. * off DE in the CSRR1 value and clearing the debug status.
  332. */
  333. mfspr r14,SPRN_DBSR /* check single-step/branch taken */
  334. andis. r15,r14,DBSR_IC@h
  335. beq+ 1f
  336. LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
  337. LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
  338. cmpld cr0,r10,r14
  339. cmpld cr1,r10,r15
  340. blt+ cr0,1f
  341. bge+ cr1,1f
  342. /* here it looks like we got an inappropriate debug exception. */
  343. lis r14,DBSR_IC@h /* clear the IC event */
  344. rlwinm r11,r11,0,~MSR_DE /* clear DE in the CSRR1 value */
  345. mtspr SPRN_DBSR,r14
  346. mtspr SPRN_CSRR1,r11
  347. lwz r10,PACA_EXCRIT+EX_CR(r13) /* restore registers */
  348. ld r1,PACA_EXCRIT+EX_R1(r13)
  349. ld r14,PACA_EXCRIT+EX_R14(r13)
  350. ld r15,PACA_EXCRIT+EX_R15(r13)
  351. mtcr r10
  352. ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */
  353. ld r11,PACA_EXCRIT+EX_R11(r13)
  354. mfspr r13,SPRN_SPRG_CRIT_SCRATCH
  355. rfci
  356. /* Normal debug exception */
  357. /* XXX We only handle coming from userspace for now since we can't
  358. * quite save properly an interrupted kernel state yet
  359. */
  360. 1: andi. r14,r11,MSR_PR; /* check for userspace again */
  361. beq kernel_dbg_exc; /* if from kernel mode */
  362. /* Now we mash up things to make it look like we are coming on a
  363. * normal exception
  364. */
  365. mfspr r15,SPRN_SPRG_CRIT_SCRATCH
  366. mtspr SPRN_SPRG_GEN_SCRATCH,r15
  367. mfspr r14,SPRN_DBSR
  368. EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE_ALL)
  369. std r14,_DSISR(r1)
  370. addi r3,r1,STACK_FRAME_OVERHEAD
  371. mr r4,r14
  372. ld r14,PACA_EXCRIT+EX_R14(r13)
  373. ld r15,PACA_EXCRIT+EX_R15(r13)
  374. bl .save_nvgprs
  375. bl .DebugException
  376. b .ret_from_except
  377. kernel_dbg_exc:
  378. b . /* NYI */
  379. /*
  380. * An interrupt came in while soft-disabled; clear EE in SRR1,
  381. * clear paca->hard_enabled and return.
  382. */
  383. masked_interrupt_book3e:
  384. mtcr r10
  385. stb r11,PACAHARDIRQEN(r13)
  386. mfspr r10,SPRN_SRR1
  387. rldicl r11,r10,48,1 /* clear MSR_EE */
  388. rotldi r10,r11,16
  389. mtspr SPRN_SRR1,r10
  390. ld r10,PACA_EXGEN+EX_R10(r13); /* restore registers */
  391. ld r11,PACA_EXGEN+EX_R11(r13);
  392. mfspr r13,SPRN_SPRG_GEN_SCRATCH;
  393. rfi
  394. b .
  395. /*
  396. * This is called from 0x300 and 0x400 handlers after the prologs with
  397. * r14 and r15 containing the fault address and error code, with the
  398. * original values stashed away in the PACA
  399. */
  400. storage_fault_common:
  401. std r14,_DAR(r1)
  402. std r15,_DSISR(r1)
  403. addi r3,r1,STACK_FRAME_OVERHEAD
  404. mr r4,r14
  405. mr r5,r15
  406. ld r14,PACA_EXGEN+EX_R14(r13)
  407. ld r15,PACA_EXGEN+EX_R15(r13)
  408. INTS_RESTORE_HARD
  409. bl .do_page_fault
  410. cmpdi r3,0
  411. bne- 1f
  412. b .ret_from_except_lite
  413. 1: bl .save_nvgprs
  414. mr r5,r3
  415. addi r3,r1,STACK_FRAME_OVERHEAD
  416. ld r4,_DAR(r1)
  417. bl .bad_page_fault
  418. b .ret_from_except
  419. /*
  420. * Alignment exception doesn't fit entirely in the 0x100 bytes so it
  421. * continues here.
  422. */
  423. alignment_more:
  424. std r14,_DAR(r1)
  425. std r15,_DSISR(r1)
  426. addi r3,r1,STACK_FRAME_OVERHEAD
  427. ld r14,PACA_EXGEN+EX_R14(r13)
  428. ld r15,PACA_EXGEN+EX_R15(r13)
  429. bl .save_nvgprs
  430. INTS_RESTORE_HARD
  431. bl .alignment_exception
  432. b .ret_from_except
  433. /*
  434. * We branch here from entry_64.S for the last stage of the exception
  435. * return code path. MSR:EE is expected to be off at that point
  436. */
  437. _GLOBAL(exception_return_book3e)
  438. b 1f
  439. /* This is the return from load_up_fpu fast path which could do with
  440. * less GPR restores in fact, but for now we have a single return path
  441. */
  442. .globl fast_exception_return
  443. fast_exception_return:
  444. wrteei 0
  445. 1: mr r0,r13
  446. ld r10,_MSR(r1)
  447. REST_4GPRS(2, r1)
  448. andi. r6,r10,MSR_PR
  449. REST_2GPRS(6, r1)
  450. beq 1f
  451. ACCOUNT_CPU_USER_EXIT(r10, r11)
  452. ld r0,GPR13(r1)
  453. 1: stdcx. r0,0,r1 /* to clear the reservation */
  454. ld r8,_CCR(r1)
  455. ld r9,_LINK(r1)
  456. ld r10,_CTR(r1)
  457. ld r11,_XER(r1)
  458. mtcr r8
  459. mtlr r9
  460. mtctr r10
  461. mtxer r11
  462. REST_2GPRS(8, r1)
  463. ld r10,GPR10(r1)
  464. ld r11,GPR11(r1)
  465. ld r12,GPR12(r1)
  466. mtspr SPRN_SPRG_GEN_SCRATCH,r0
  467. std r10,PACA_EXGEN+EX_R10(r13);
  468. std r11,PACA_EXGEN+EX_R11(r13);
  469. ld r10,_NIP(r1)
  470. ld r11,_MSR(r1)
  471. ld r0,GPR0(r1)
  472. ld r1,GPR1(r1)
  473. mtspr SPRN_SRR0,r10
  474. mtspr SPRN_SRR1,r11
  475. ld r10,PACA_EXGEN+EX_R10(r13)
  476. ld r11,PACA_EXGEN+EX_R11(r13)
  477. mfspr r13,SPRN_SPRG_GEN_SCRATCH
  478. rfi
  479. /*
  480. * Trampolines used when spotting a bad kernel stack pointer in
  481. * the exception entry code.
  482. *
  483. * TODO: move some bits like SRR0 read to trampoline, pass PACA
  484. * index around, etc... to handle crit & mcheck
  485. */
  486. BAD_STACK_TRAMPOLINE(0x000)
  487. BAD_STACK_TRAMPOLINE(0x100)
  488. BAD_STACK_TRAMPOLINE(0x200)
  489. BAD_STACK_TRAMPOLINE(0x300)
  490. BAD_STACK_TRAMPOLINE(0x400)
  491. BAD_STACK_TRAMPOLINE(0x500)
  492. BAD_STACK_TRAMPOLINE(0x600)
  493. BAD_STACK_TRAMPOLINE(0x700)
  494. BAD_STACK_TRAMPOLINE(0x800)
  495. BAD_STACK_TRAMPOLINE(0x900)
  496. BAD_STACK_TRAMPOLINE(0x980)
  497. BAD_STACK_TRAMPOLINE(0x9f0)
  498. BAD_STACK_TRAMPOLINE(0xa00)
  499. BAD_STACK_TRAMPOLINE(0xb00)
  500. BAD_STACK_TRAMPOLINE(0xc00)
  501. BAD_STACK_TRAMPOLINE(0xd00)
  502. BAD_STACK_TRAMPOLINE(0xe00)
  503. BAD_STACK_TRAMPOLINE(0xf00)
  504. BAD_STACK_TRAMPOLINE(0xf20)
  505. .globl bad_stack_book3e
  506. bad_stack_book3e:
  507. /* XXX: Needs to make SPRN_SPRG_GEN depend on exception type */
  508. mfspr r10,SPRN_SRR0; /* read SRR0 before touching stack */
  509. ld r1,PACAEMERGSP(r13)
  510. subi r1,r1,64+INT_FRAME_SIZE
  511. std r10,_NIP(r1)
  512. std r11,_MSR(r1)
  513. ld r10,PACA_EXGEN+EX_R1(r13) /* FIXME for crit & mcheck */
  514. lwz r11,PACA_EXGEN+EX_CR(r13) /* FIXME for crit & mcheck */
  515. std r10,GPR1(r1)
  516. std r11,_CCR(r1)
  517. mfspr r10,SPRN_DEAR
  518. mfspr r11,SPRN_ESR
  519. std r10,_DAR(r1)
  520. std r11,_DSISR(r1)
  521. std r0,GPR0(r1); /* save r0 in stackframe */ \
  522. std r2,GPR2(r1); /* save r2 in stackframe */ \
  523. SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
  524. SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
  525. std r9,GPR9(r1); /* save r9 in stackframe */ \
  526. ld r3,PACA_EXGEN+EX_R10(r13);/* get back r10 */ \
  527. ld r4,PACA_EXGEN+EX_R11(r13);/* get back r11 */ \
  528. mfspr r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 XXX can be wrong */ \
  529. std r3,GPR10(r1); /* save r10 to stackframe */ \
  530. std r4,GPR11(r1); /* save r11 to stackframe */ \
  531. std r12,GPR12(r1); /* save r12 in stackframe */ \
  532. std r5,GPR13(r1); /* save it to stackframe */ \
  533. mflr r10
  534. mfctr r11
  535. mfxer r12
  536. std r10,_LINK(r1)
  537. std r11,_CTR(r1)
  538. std r12,_XER(r1)
  539. SAVE_10GPRS(14,r1)
  540. SAVE_8GPRS(24,r1)
  541. lhz r12,PACA_TRAP_SAVE(r13)
  542. std r12,_TRAP(r1)
  543. addi r11,r1,INT_FRAME_SIZE
  544. std r11,0(r1)
  545. li r12,0
  546. std r12,0(r11)
  547. ld r2,PACATOC(r13)
  548. 1: addi r3,r1,STACK_FRAME_OVERHEAD
  549. bl .kernel_bad_stack
  550. b 1b
  551. /*
  552. * Setup the initial TLB for a core. This current implementation
  553. * assume that whatever we are running off will not conflict with
  554. * the new mapping at PAGE_OFFSET.
  555. * We also make various assumptions about the processor we run on,
  556. * this might have to be made more flexible based on the content
  557. * of MMUCFG and friends.
  558. */
  559. _GLOBAL(initial_tlb_book3e)
  560. /* Setup MAS 0,1,2,3 and 7 for tlbwe of a 1G entry that maps the
  561. * kernel linear mapping. We also set MAS8 once for all here though
  562. * that will have to be made dependent on whether we are running under
  563. * a hypervisor I suppose.
  564. */
  565. li r3,MAS0_HES | MAS0_WQ_ALLWAYS
  566. mtspr SPRN_MAS0,r3
  567. lis r3,(MAS1_VALID | MAS1_IPROT)@h
  568. ori r3,r3,BOOK3E_PAGESZ_1GB << MAS1_TSIZE_SHIFT
  569. mtspr SPRN_MAS1,r3
  570. LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET | MAS2_M)
  571. mtspr SPRN_MAS2,r3
  572. li r3,MAS3_SR | MAS3_SW | MAS3_SX
  573. mtspr SPRN_MAS7_MAS3,r3
  574. li r3,0
  575. mtspr SPRN_MAS8,r3
  576. /* Write the TLB entry */
  577. tlbwe
  578. /* Now we branch the new virtual address mapped by this entry */
  579. LOAD_REG_IMMEDIATE(r3,1f)
  580. mtctr r3
  581. bctr
  582. 1: /* We are now running at PAGE_OFFSET, clean the TLB of everything
  583. * else (XXX we should scan for bolted crap from the firmware too)
  584. */
  585. PPC_TLBILX(0,0,0)
  586. sync
  587. isync
  588. /* We translate LR and return */
  589. mflr r3
  590. tovirt(r3,r3)
  591. mtlr r3
  592. blr
  593. /*
  594. * Main entry (boot CPU, thread 0)
  595. *
  596. * We enter here from head_64.S, possibly after the prom_init trampoline
  597. * with r3 and r4 already saved to r31 and 30 respectively and in 64 bits
  598. * mode. Anything else is as it was left by the bootloader
  599. *
  600. * Initial requirements of this port:
  601. *
  602. * - Kernel loaded at 0 physical
  603. * - A good lump of memory mapped 0:0 by UTLB entry 0
  604. * - MSR:IS & MSR:DS set to 0
  605. *
  606. * Note that some of the above requirements will be relaxed in the future
  607. * as the kernel becomes smarter at dealing with different initial conditions
  608. * but for now you have to be careful
  609. */
  610. _GLOBAL(start_initialization_book3e)
  611. mflr r28
  612. /* First, we need to setup some initial TLBs to map the kernel
  613. * text, data and bss at PAGE_OFFSET. We don't have a real mode
  614. * and always use AS 0, so we just set it up to match our link
  615. * address and never use 0 based addresses.
  616. */
  617. bl .initial_tlb_book3e
  618. /* Init global core bits */
  619. bl .init_core_book3e
  620. /* Init per-thread bits */
  621. bl .init_thread_book3e
  622. /* Return to common init code */
  623. tovirt(r28,r28)
  624. mtlr r28
  625. blr
  626. /*
  627. * Secondary core/processor entry
  628. *
  629. * This is entered for thread 0 of a secondary core, all other threads
  630. * are expected to be stopped. It's similar to start_initialization_book3e
  631. * except that it's generally entered from the holding loop in head_64.S
  632. * after CPUs have been gathered by Open Firmware.
  633. *
  634. * We assume we are in 32 bits mode running with whatever TLB entry was
  635. * set for us by the firmware or POR engine.
  636. */
  637. _GLOBAL(book3e_secondary_core_init_tlb_set)
  638. li r4,1
  639. b .generic_secondary_smp_init
  640. _GLOBAL(book3e_secondary_core_init)
  641. mflr r28
  642. /* Do we need to setup initial TLB entry ? */
  643. cmplwi r4,0
  644. bne 2f
  645. /* Setup TLB for this core */
  646. bl .initial_tlb_book3e
  647. /* We can return from the above running at a different
  648. * address, so recalculate r2 (TOC)
  649. */
  650. bl .relative_toc
  651. /* Init global core bits */
  652. 2: bl .init_core_book3e
  653. /* Init per-thread bits */
  654. 3: bl .init_thread_book3e
  655. /* Return to common init code at proper virtual address.
  656. *
  657. * Due to various previous assumptions, we know we entered this
  658. * function at either the final PAGE_OFFSET mapping or using a
  659. * 1:1 mapping at 0, so we don't bother doing a complicated check
  660. * here, we just ensure the return address has the right top bits.
  661. *
  662. * Note that if we ever want to be smarter about where we can be
  663. * started from, we have to be careful that by the time we reach
  664. * the code below we may already be running at a different location
  665. * than the one we were called from since initial_tlb_book3e can
  666. * have moved us already.
  667. */
  668. cmpdi cr0,r28,0
  669. blt 1f
  670. lis r3,PAGE_OFFSET@highest
  671. sldi r3,r3,32
  672. or r28,r28,r3
  673. 1: mtlr r28
  674. blr
  675. _GLOBAL(book3e_secondary_thread_init)
  676. mflr r28
  677. b 3b
  678. _STATIC(init_core_book3e)
  679. /* Establish the interrupt vector base */
  680. LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e)
  681. mtspr SPRN_IVPR,r3
  682. sync
  683. blr
  684. _STATIC(init_thread_book3e)
  685. lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h
  686. mtspr SPRN_EPCR,r3
  687. /* Make sure interrupts are off */
  688. wrteei 0
  689. /* disable watchdog and FIT and enable DEC interrupts */
  690. lis r3,TCR_DIE@h
  691. mtspr SPRN_TCR,r3
  692. blr