.. | .. |
---|
6 | 6 | #include <asm/kvm_asm.h> |
---|
7 | 7 | #include <asm/kvm_booke_hv_asm.h> |
---|
8 | 8 | |
---|
| 9 | +#ifdef __ASSEMBLY__ |
---|
| 10 | + |
---|
9 | 11 | /* |
---|
10 | 12 | * Macros used for common Book-e exception handling |
---|
11 | 13 | */ |
---|
.. | .. |
---|
55 | 57 | beq 1f; \ |
---|
56 | 58 | BOOKE_CLEAR_BTB(r11) \ |
---|
57 | 59 | /* if from user, start at top of this thread's kernel stack */ \ |
---|
58 | | - lwz r11, THREAD_INFO-THREAD(r10); \ |
---|
| 60 | + lwz r11, TASK_STACK - THREAD(r10); \ |
---|
59 | 61 | ALLOC_STACK_FRAME(r11, THREAD_SIZE); \ |
---|
60 | 62 | 1 : subi r11, r11, INT_FRAME_SIZE; /* Allocate exception frame */ \ |
---|
61 | 63 | stw r13, _CCR(r11); /* save various registers */ \ |
---|
.. | .. |
---|
80 | 82 | stw r10, 8(r11); \ |
---|
81 | 83 | SAVE_4GPRS(3, r11); \ |
---|
82 | 84 | SAVE_2GPRS(7, r11) |
---|
| 85 | + |
---|
| 86 | +.macro SYSCALL_ENTRY trapno intno srr1 |
---|
| 87 | + mfspr r10, SPRN_SPRG_THREAD |
---|
| 88 | +#ifdef CONFIG_KVM_BOOKE_HV |
---|
| 89 | +BEGIN_FTR_SECTION |
---|
| 90 | + mtspr SPRN_SPRG_WSCRATCH0, r10 |
---|
| 91 | + stw r11, THREAD_NORMSAVE(0)(r10) |
---|
| 92 | + stw r13, THREAD_NORMSAVE(2)(r10) |
---|
| 93 | + mfcr r13 /* save CR in r13 for now */ |
---|
| 94 | + mfspr r11, SPRN_SRR1 |
---|
| 95 | + mtocrf 0x80, r11 /* check MSR[GS] without clobbering reg */ |
---|
| 96 | + bf 3, 1975f |
---|
| 97 | + b kvmppc_handler_\intno\()_\srr1 |
---|
| 98 | +1975: |
---|
| 99 | + mr r12, r13 |
---|
| 100 | + lwz r13, THREAD_NORMSAVE(2)(r10) |
---|
| 101 | +FTR_SECTION_ELSE |
---|
| 102 | +#endif |
---|
| 103 | + mfcr r12 |
---|
| 104 | +#ifdef CONFIG_KVM_BOOKE_HV |
---|
| 105 | +ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) |
---|
| 106 | +#endif |
---|
| 107 | + mfspr r9, SPRN_SRR1 |
---|
| 108 | + BOOKE_CLEAR_BTB(r11) |
---|
| 109 | + andi. r11, r9, MSR_PR |
---|
| 110 | + lwz r11, TASK_STACK - THREAD(r10) |
---|
| 111 | + rlwinm r12,r12,0,4,2 /* Clear SO bit in CR */ |
---|
| 112 | + beq- 99f |
---|
| 113 | + ALLOC_STACK_FRAME(r11, THREAD_SIZE - INT_FRAME_SIZE) |
---|
| 114 | + stw r12, _CCR(r11) /* save various registers */ |
---|
| 115 | + mflr r12 |
---|
| 116 | + stw r12,_LINK(r11) |
---|
| 117 | + mfspr r12,SPRN_SRR0 |
---|
| 118 | + stw r1, GPR1(r11) |
---|
| 119 | + stw r1, 0(r11) |
---|
| 120 | + mr r1, r11 |
---|
| 121 | + stw r12,_NIP(r11) |
---|
| 122 | + rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ |
---|
| 123 | + lis r12, STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ |
---|
| 124 | + stw r2,GPR2(r11) |
---|
| 125 | + addi r12, r12, STACK_FRAME_REGS_MARKER@l |
---|
| 126 | + stw r9,_MSR(r11) |
---|
| 127 | + li r2, \trapno + 1 |
---|
| 128 | + stw r12, 8(r11) |
---|
| 129 | + stw r2,_TRAP(r11) |
---|
| 130 | + SAVE_GPR(0, r11) |
---|
| 131 | + SAVE_4GPRS(3, r11) |
---|
| 132 | + SAVE_2GPRS(7, r11) |
---|
| 133 | + |
---|
| 134 | + addi r11,r1,STACK_FRAME_OVERHEAD |
---|
| 135 | + addi r2,r10,-THREAD |
---|
| 136 | + stw r11,PT_REGS(r10) |
---|
| 137 | + /* Check to see if the dbcr0 register is set up to debug. Use the |
---|
| 138 | + internal debug mode bit to do this. */ |
---|
| 139 | + lwz r12,THREAD_DBCR0(r10) |
---|
| 140 | + andis. r12,r12,DBCR0_IDM@h |
---|
| 141 | + ACCOUNT_CPU_USER_ENTRY(r2, r11, r12) |
---|
| 142 | + beq+ 3f |
---|
| 143 | + /* From user and task is ptraced - load up global dbcr0 */ |
---|
| 144 | + li r12,-1 /* clear all pending debug events */ |
---|
| 145 | + mtspr SPRN_DBSR,r12 |
---|
| 146 | + lis r11,global_dbcr0@ha |
---|
| 147 | + tophys(r11,r11) |
---|
| 148 | + addi r11,r11,global_dbcr0@l |
---|
| 149 | +#ifdef CONFIG_SMP |
---|
| 150 | + lwz r10, TASK_CPU(r2) |
---|
| 151 | + slwi r10, r10, 3 |
---|
| 152 | + add r11, r11, r10 |
---|
| 153 | +#endif |
---|
| 154 | + lwz r12,0(r11) |
---|
| 155 | + mtspr SPRN_DBCR0,r12 |
---|
| 156 | + lwz r12,4(r11) |
---|
| 157 | + addi r12,r12,-1 |
---|
| 158 | + stw r12,4(r11) |
---|
| 159 | + |
---|
| 160 | +3: |
---|
| 161 | + tovirt(r2, r2) /* set r2 to current */ |
---|
| 162 | + lis r11, transfer_to_syscall@h |
---|
| 163 | + ori r11, r11, transfer_to_syscall@l |
---|
| 164 | +#ifdef CONFIG_TRACE_IRQFLAGS |
---|
| 165 | + /* |
---|
| 166 | + * If MSR is changing we need to keep interrupts disabled at this point |
---|
| 167 | + * otherwise we might risk taking an interrupt before we tell lockdep |
---|
| 168 | + * they are enabled. |
---|
| 169 | + */ |
---|
| 170 | + lis r10, MSR_KERNEL@h |
---|
| 171 | + ori r10, r10, MSR_KERNEL@l |
---|
| 172 | + rlwimi r10, r9, 0, MSR_EE |
---|
| 173 | +#else |
---|
| 174 | + lis r10, (MSR_KERNEL | MSR_EE)@h |
---|
| 175 | + ori r10, r10, (MSR_KERNEL | MSR_EE)@l |
---|
| 176 | +#endif |
---|
| 177 | + mtspr SPRN_SRR1,r10 |
---|
| 178 | + mtspr SPRN_SRR0,r11 |
---|
| 179 | + RFI /* jump to handler, enable MMU */ |
---|
| 180 | +99: b ret_from_kernel_syscall |
---|
| 181 | +.endm |
---|
83 | 182 | |
---|
84 | 183 | /* To handle the additional exception priority levels on 40x and Book-E |
---|
85 | 184 | * processors we allocate a stack per additional priority level. |
---|
.. | .. |
---|
142 | 241 | BOOKE_CLEAR_BTB(r10) \ |
---|
143 | 242 | andi. r11,r11,MSR_PR; \ |
---|
144 | 243 | mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\ |
---|
145 | | - lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ |
---|
| 244 | + lwz r11, TASK_STACK - THREAD(r11); /* this thread's kernel stack */\ |
---|
146 | 245 | addi r11,r11,EXC_LVL_FRAME_OVERHEAD; /* allocate stack frame */\ |
---|
147 | 246 | beq 1f; \ |
---|
148 | 247 | /* COMING FROM USER MODE */ \ |
---|
.. | .. |
---|
155 | 254 | stw r10,GPR11(r11); \ |
---|
156 | 255 | b 2f; \ |
---|
157 | 256 | /* COMING FROM PRIV MODE */ \ |
---|
158 | | -1: lwz r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r11); \ |
---|
159 | | - lwz r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r11); \ |
---|
160 | | - stw r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r8); \ |
---|
161 | | - stw r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r8); \ |
---|
162 | | - lwz r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r11); \ |
---|
163 | | - stw r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r8); \ |
---|
164 | | - mr r11,r8; \ |
---|
| 257 | +1: mr r11, r8; \ |
---|
165 | 258 | 2: mfspr r8,SPRN_SPRG_RSCRATCH_##exc_level; \ |
---|
166 | 259 | stw r12,GPR12(r11); /* save various registers */\ |
---|
167 | 260 | mflr r10; \ |
---|
.. | .. |
---|
223 | 316 | CRITICAL_EXCEPTION_PROLOG(intno); \ |
---|
224 | 317 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
---|
225 | 318 | EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ |
---|
226 | | - NOCOPY, crit_transfer_to_handler, \ |
---|
227 | | - ret_from_crit_exc) |
---|
| 319 | + crit_transfer_to_handler, ret_from_crit_exc) |
---|
228 | 320 | |
---|
229 | 321 | #define MCHECK_EXCEPTION(n, label, hdlr) \ |
---|
230 | 322 | START_EXCEPTION(label); \ |
---|
.. | .. |
---|
233 | 325 | stw r5,_ESR(r11); \ |
---|
234 | 326 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
---|
235 | 327 | EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ |
---|
236 | | - NOCOPY, mcheck_transfer_to_handler, \ |
---|
237 | | - ret_from_mcheck_exc) |
---|
| 328 | + mcheck_transfer_to_handler, ret_from_mcheck_exc) |
---|
238 | 329 | |
---|
239 | | -#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \ |
---|
| 330 | +#define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \ |
---|
240 | 331 | li r10,trap; \ |
---|
241 | 332 | stw r10,_TRAP(r11); \ |
---|
242 | 333 | lis r10,msr@h; \ |
---|
243 | 334 | ori r10,r10,msr@l; \ |
---|
244 | | - copyee(r10, r9); \ |
---|
245 | 335 | bl tfer; \ |
---|
246 | 336 | .long hdlr; \ |
---|
247 | 337 | .long ret |
---|
248 | 338 | |
---|
249 | | -#define COPY_EE(d, s) rlwimi d,s,0,16,16 |
---|
250 | | -#define NOCOPY(d, s) |
---|
251 | | - |
---|
252 | 339 | #define EXC_XFER_STD(n, hdlr) \ |
---|
253 | | - EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \ |
---|
| 340 | + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \ |
---|
254 | 341 | ret_from_except_full) |
---|
255 | 342 | |
---|
256 | 343 | #define EXC_XFER_LITE(n, hdlr) \ |
---|
257 | | - EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ |
---|
258 | | - ret_from_except) |
---|
259 | | - |
---|
260 | | -#define EXC_XFER_EE(n, hdlr) \ |
---|
261 | | - EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \ |
---|
262 | | - ret_from_except_full) |
---|
263 | | - |
---|
264 | | -#define EXC_XFER_EE_LITE(n, hdlr) \ |
---|
265 | | - EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ |
---|
| 344 | + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, transfer_to_handler, \ |
---|
266 | 345 | ret_from_except) |
---|
267 | 346 | |
---|
268 | 347 | /* Check for a single step debug exception while in an exception |
---|
.. | .. |
---|
329 | 408 | /* continue normal handling for a debug exception... */ \ |
---|
330 | 409 | 2: mfspr r4,SPRN_DBSR; \ |
---|
331 | 410 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
---|
332 | | - EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc) |
---|
| 411 | + EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), debug_transfer_to_handler, ret_from_debug_exc) |
---|
333 | 412 | |
---|
334 | 413 | #define DEBUG_CRIT_EXCEPTION \ |
---|
335 | 414 | START_EXCEPTION(DebugCrit); \ |
---|
.. | .. |
---|
382 | 461 | /* continue normal handling for a critical exception... */ \ |
---|
383 | 462 | 2: mfspr r4,SPRN_DBSR; \ |
---|
384 | 463 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
---|
385 | | - EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) |
---|
| 464 | + EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), crit_transfer_to_handler, ret_from_crit_exc) |
---|
386 | 465 | |
---|
387 | 466 | #define DATA_STORAGE_EXCEPTION \ |
---|
388 | 467 | START_EXCEPTION(DataStorage) \ |
---|
.. | .. |
---|
390 | 469 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ |
---|
391 | 470 | stw r5,_ESR(r11); \ |
---|
392 | 471 | mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ |
---|
| 472 | + stw r4, _DEAR(r11); \ |
---|
393 | 473 | EXC_XFER_LITE(0x0300, handle_page_fault) |
---|
394 | 474 | |
---|
395 | 475 | #define INSTRUCTION_STORAGE_EXCEPTION \ |
---|
.. | .. |
---|
398 | 478 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ |
---|
399 | 479 | stw r5,_ESR(r11); \ |
---|
400 | 480 | mr r4,r12; /* Pass SRR0 as arg2 */ \ |
---|
| 481 | + stw r4, _DEAR(r11); \ |
---|
401 | 482 | li r5,0; /* Pass zero as arg3 */ \ |
---|
402 | 483 | EXC_XFER_LITE(0x0400, handle_page_fault) |
---|
403 | 484 | |
---|
.. | .. |
---|
407 | 488 | mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \ |
---|
408 | 489 | stw r4,_DEAR(r11); \ |
---|
409 | 490 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
---|
410 | | - EXC_XFER_EE(0x0600, alignment_exception) |
---|
| 491 | + EXC_XFER_STD(0x0600, alignment_exception) |
---|
411 | 492 | |
---|
412 | 493 | #define PROGRAM_EXCEPTION \ |
---|
413 | 494 | START_EXCEPTION(Program) \ |
---|
.. | .. |
---|
432 | 513 | bl load_up_fpu; /* if from user, just load it up */ \ |
---|
433 | 514 | b fast_exception_return; \ |
---|
434 | 515 | 1: addi r3,r1,STACK_FRAME_OVERHEAD; \ |
---|
435 | | - EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception) |
---|
| 516 | + EXC_XFER_STD(0x800, kernel_fp_unavailable_exception) |
---|
436 | 517 | |
---|
437 | | -#ifndef __ASSEMBLY__ |
---|
| 518 | +#else /* __ASSEMBLY__ */ |
---|
438 | 519 | struct exception_regs { |
---|
439 | 520 | unsigned long mas0; |
---|
440 | 521 | unsigned long mas1; |
---|
.. | .. |
---|
452 | 533 | }; |
---|
453 | 534 | |
---|
454 | 535 | /* ensure this structure is always sized to a multiple of the stack alignment */ |
---|
455 | | -#define STACK_EXC_LVL_FRAME_SIZE _ALIGN_UP(sizeof (struct exception_regs), 16) |
---|
| 536 | +#define STACK_EXC_LVL_FRAME_SIZE ALIGN(sizeof (struct exception_regs), 16) |
---|
456 | 537 | |
---|
457 | 538 | #endif /* __ASSEMBLY__ */ |
---|
458 | 539 | #endif /* __HEAD_BOOKE_H__ */ |
---|