| .. | .. |
|---|
| 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__ */ |
|---|