|
@@ -335,7 +335,7 @@ emulation_assist_trampoline:
|
|
|
hv_exception_trampoline:
|
|
|
SET_SCRATCH0(r13)
|
|
|
EXCEPTION_PROLOG_0(PACA_EXGEN)
|
|
|
- b hmi_exception_hv
|
|
|
+ b hmi_exception_early
|
|
|
|
|
|
. = 0xe80
|
|
|
hv_doorbell_trampoline:
|
|
@@ -589,8 +589,64 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
|
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22)
|
|
|
STD_EXCEPTION_HV_OOL(0xe42, emulation_assist)
|
|
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42)
|
|
|
- STD_EXCEPTION_HV_OOL(0xe62, hmi_exception) /* need to flush cache ? */
|
|
|
+ MASKABLE_EXCEPTION_HV_OOL(0xe62, hmi_exception)
|
|
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62)
|
|
|
+
|
|
|
+ .globl hmi_exception_early
|
|
|
+hmi_exception_early:
|
|
|
+ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0xe60)
|
|
|
+ mr r10,r1 /* Save r1 */
|
|
|
+ ld r1,PACAEMERGSP(r13) /* Use emergency stack */
|
|
|
+ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
|
|
|
+ std r9,_CCR(r1) /* save CR in stackframe */
|
|
|
+ mfspr r11,SPRN_HSRR0 /* Save HSRR0 */
|
|
|
+ std r11,_NIP(r1) /* save HSRR0 in stackframe */
|
|
|
+ mfspr r12,SPRN_HSRR1 /* Save SRR1 */
|
|
|
+ std r12,_MSR(r1) /* save SRR1 in stackframe */
|
|
|
+ std r10,0(r1) /* make stack chain pointer */
|
|
|
+ std r0,GPR0(r1) /* save r0 in stackframe */
|
|
|
+ std r10,GPR1(r1) /* save r1 in stackframe */
|
|
|
+ EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN)
|
|
|
+ EXCEPTION_PROLOG_COMMON_3(0xe60)
|
|
|
+ addi r3,r1,STACK_FRAME_OVERHEAD
|
|
|
+ bl hmi_exception_realmode
|
|
|
+ /* Windup the stack. */
|
|
|
+ /* Clear MSR_RI before setting SRR0 and SRR1. */
|
|
|
+ li r0,MSR_RI
|
|
|
+ mfmsr r9 /* get MSR value */
|
|
|
+ andc r9,r9,r0
|
|
|
+ mtmsrd r9,1 /* Clear MSR_RI */
|
|
|
+ /* Move original HSRR0 and HSRR1 into the respective regs */
|
|
|
+ ld r9,_MSR(r1)
|
|
|
+ mtspr SPRN_HSRR1,r9
|
|
|
+ ld r3,_NIP(r1)
|
|
|
+ mtspr SPRN_HSRR0,r3
|
|
|
+ ld r9,_CTR(r1)
|
|
|
+ mtctr r9
|
|
|
+ ld r9,_XER(r1)
|
|
|
+ mtxer r9
|
|
|
+ ld r9,_LINK(r1)
|
|
|
+ mtlr r9
|
|
|
+ REST_GPR(0, r1)
|
|
|
+ REST_8GPRS(2, r1)
|
|
|
+ REST_GPR(10, r1)
|
|
|
+ ld r11,_CCR(r1)
|
|
|
+ mtcr r11
|
|
|
+ REST_GPR(11, r1)
|
|
|
+ REST_2GPRS(12, r1)
|
|
|
+ /* restore original r1. */
|
|
|
+ ld r1,GPR1(r1)
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Go to virtual mode and pull the HMI event information from
|
|
|
+ * firmware.
|
|
|
+ */
|
|
|
+ .globl hmi_exception_after_realmode
|
|
|
+hmi_exception_after_realmode:
|
|
|
+ SET_SCRATCH0(r13)
|
|
|
+ EXCEPTION_PROLOG_0(PACA_EXGEN)
|
|
|
+ b hmi_exception_hv
|
|
|
+
|
|
|
MASKABLE_EXCEPTION_HV_OOL(0xe82, h_doorbell)
|
|
|
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82)
|
|
|
|
|
@@ -611,6 +667,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
|
|
* - If it was a decrementer interrupt, we bump the dec to max and and return.
|
|
|
* - If it was a doorbell we return immediately since doorbells are edge
|
|
|
* triggered and won't automatically refire.
|
|
|
+ * - If it was a HMI we return immediately since we handled it in realmode
|
|
|
+ * and it won't refire.
|
|
|
* - else we hard disable and return.
|
|
|
* This is called with r10 containing the value to OR to the paca field.
|
|
|
*/
|
|
@@ -627,6 +685,8 @@ masked_##_H##interrupt: \
|
|
|
mtspr SPRN_DEC,r10; \
|
|
|
b 2f; \
|
|
|
1: cmpwi r10,PACA_IRQ_DBELL; \
|
|
|
+ beq 2f; \
|
|
|
+ cmpwi r10,PACA_IRQ_HMI; \
|
|
|
beq 2f; \
|
|
|
mfspr r10,SPRN_##_H##SRR1; \
|
|
|
rldicl r10,r10,48,1; /* clear MSR_EE */ \
|
|
@@ -767,7 +827,7 @@ kvmppc_skip_Hinterrupt:
|
|
|
STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception)
|
|
|
STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception)
|
|
|
STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt)
|
|
|
- STD_EXCEPTION_COMMON(0xe60, hmi_exception, unknown_exception)
|
|
|
+ STD_EXCEPTION_COMMON_ASYNC(0xe60, hmi_exception, handle_hmi_exception)
|
|
|
#ifdef CONFIG_PPC_DOORBELL
|
|
|
STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception)
|
|
|
#else
|