powerpc: More work to support HV exceptions

Rework exception macros a bit to split offset from vector and add
some basic support for HDEC, HDSI, HISI and a few more.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent a5d4f3ad
......@@ -150,28 +150,27 @@
/*
* Exception vectors.
*/
#define STD_EXCEPTION_PSERIES(n, label) \
. = n; \
#define STD_EXCEPTION_PSERIES(loc, vec, label) \
. = loc; \
.globl label##_pSeries; \
label##_pSeries: \
HMT_MEDIUM; \
DO_KVM n; \
DO_KVM vec; \
mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
#define HSTD_EXCEPTION_PSERIES(n, label) \
. = n; \
.globl label##_pSeries; \
label##_pSeries: \
#define STD_EXCEPTION_HV(loc, vec, label) \
. = loc; \
.globl label##_hv; \
label##_hv: \
HMT_MEDIUM; \
DO_KVM n; \
DO_KVM vec; \
mtspr SPRN_SPRG_HSCRATCH0,r13;/* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
#define __MASKABLE_EXCEPTION_PSERIES(n, label, h) \
#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h) \
HMT_MEDIUM; \
DO_KVM n; \
DO_KVM vec; \
mtspr SPRN_SPRG_##h##SCRATCH0,r13; /* save r13 */ \
GET_PACA(r13); \
std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
......@@ -193,8 +192,20 @@ label##_pSeries: \
mtspr SPRN_##h##SRR1,r10; \
h##rfid; \
b . /* prevent speculative execution */
#define MASKABLE_EXCEPTION_PSERIES(n, label, h) \
__MASKABLE_EXCEPTION_PSERIES(n, label, h)
#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h) \
__MASKABLE_EXCEPTION_PSERIES(vec, label, h)
#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label) \
. = loc; \
.globl label##_pSeries; \
label##_pSeries: \
_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD)
#define MASKABLE_EXCEPTION_HV(loc, vec, label) \
. = loc; \
.globl label##_hv; \
label##_hv: \
_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_HV)
#ifdef CONFIG_PPC_ISERIES
#define DISABLE_INTS \
......
......@@ -49,7 +49,7 @@ label##5: \
FTR_ENTRY_OFFSET label##2b-label##5b; \
FTR_ENTRY_OFFSET label##3b-label##5b; \
FTR_ENTRY_OFFSET label##4b-label##5b; \
.ifgt (label##4b-label##3b)-(label##2b-label##1b); \
.ifgt (label##4b- label##3b)-(label##2b- label##1b); \
.error "Feature section else case larger than body"; \
.endif; \
.popsection;
......
......@@ -37,7 +37,7 @@
.globl __start_interrupts
__start_interrupts:
STD_EXCEPTION_PSERIES(0x100, system_reset)
STD_EXCEPTION_PSERIES(0x100, 0x100, system_reset)
. = 0x200
_machine_check_pSeries:
......@@ -113,7 +113,7 @@ data_access_slb_pSeries:
bctr
#endif
STD_EXCEPTION_PSERIES(0x400, instruction_access)
STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access)
. = 0x480
.globl instruction_access_slb_pSeries
......@@ -147,26 +147,29 @@ instruction_access_slb_pSeries:
bctr
#endif
/* We open code these as we can't have a ". = x" (even with
* x = "." within a feature section
*/
. = 0x500;
.globl hardware_interrupt_pSeries
.globl hardware_interrupt_pSeries;
.globl hardware_interrupt_hv;
hardware_interrupt_pSeries:
hardware_interrupt_hv:
BEGIN_FTR_SECTION
MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD)
_MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD)
FTR_SECTION_ELSE
MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV)
_MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV)
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206)
STD_EXCEPTION_PSERIES(0x600, alignment)
STD_EXCEPTION_PSERIES(0x700, program_check)
STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
STD_EXCEPTION_PSERIES(0x600, 0x600, alignment)
STD_EXCEPTION_PSERIES(0x700, 0x700, program_check)
STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable)
. = 0x900;
.globl decrementer_pSeries
decrementer_pSeries:
MASKABLE_EXCEPTION_PSERIES(0x900, decrementer, EXC_STD)
MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer)
MASKABLE_EXCEPTION_HV(0x980, 0x980, decrementer)
STD_EXCEPTION_PSERIES(0xa00, trap_0a)
STD_EXCEPTION_PSERIES(0xb00, trap_0b)
STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a)
STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b)
. = 0xc00
.globl system_call_pSeries
......@@ -196,8 +199,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
rfid /* return to userspace */
b .
STD_EXCEPTION_PSERIES(0xd00, single_step)
STD_EXCEPTION_PSERIES(0xe00, trap_0e)
STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
/* At 0xe??? we have a bunch of hypervisor exceptions, we branch
* out of line to handle them
*/
. = 0xe00
b h_data_storage_hv
. = 0xe20
b h_instr_storage_hv
. = 0xe40
b emulation_assist_hv
. = 0xe50
b hmi_exception_hv
. = 0xe60
b hmi_exception_hv
/* We need to deal with the Altivec unavailable exception
* here which is at 0xf20, thus in the middle of the
......@@ -206,39 +222,42 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
*/
performance_monitor_pSeries_1:
. = 0xf00
DO_KVM 0xf00
b performance_monitor_pSeries
altivec_unavailable_pSeries_1:
. = 0xf20
DO_KVM 0xf20
b altivec_unavailable_pSeries
vsx_unavailable_pSeries_1:
. = 0xf40
DO_KVM 0xf40
b vsx_unavailable_pSeries
#ifdef CONFIG_CBE_RAS
HSTD_EXCEPTION_PSERIES(0x1202, cbe_system_error)
STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
#endif /* CONFIG_CBE_RAS */
STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
#ifdef CONFIG_CBE_RAS
HSTD_EXCEPTION_PSERIES(0x1602, cbe_maintenance)
STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
#endif /* CONFIG_CBE_RAS */
STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
#ifdef CONFIG_CBE_RAS
HSTD_EXCEPTION_PSERIES(0x1802, cbe_thermal)
STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
#endif /* CONFIG_CBE_RAS */
. = 0x3000
/*** pSeries interrupt support ***/
/*** Out of line interrupts support ***/
/* moved from 0xe00 */
STD_EXCEPTION_HV(., 0xe00, h_data_storage)
STD_EXCEPTION_HV(., 0xe20, h_instr_storage)
STD_EXCEPTION_HV(., 0xe40, emulation_assist)
STD_EXCEPTION_HV(., 0xe60, hmi_exception) /* need to flush cache ? */
/* moved from 0xf00 */
STD_EXCEPTION_PSERIES(., performance_monitor)
STD_EXCEPTION_PSERIES(., altivec_unavailable)
STD_EXCEPTION_PSERIES(., vsx_unavailable)
STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable)
STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable)
/*
* An interrupt came in while soft-disabled; clear EE in SRR1,
......@@ -368,6 +387,8 @@ machine_check_common:
STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
#ifdef CONFIG_ALTIVEC
......@@ -445,6 +466,19 @@ data_access_common:
li r5,0x300
b .do_hash_page /* Try to handle as hpte fault */
.align 7
.globl h_data_storage_common
h_data_storage_common:
mfspr r10,SPRN_HDAR
std r10,PACA_EXGEN+EX_DAR(r13)
mfspr r10,SPRN_HDSISR
stw r10,PACA_EXGEN+EX_DSISR(r13)
EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
bl .unknown_exception
b .ret_from_except
.align 7
.globl instruction_access_common
instruction_access_common:
......@@ -454,6 +488,8 @@ instruction_access_common:
li r5,0x400
b .do_hash_page /* Try to handle as hpte fault */
STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception)
/*
* Here is the common SLB miss user that is used when going to virtual
* mode for SLB misses, that is currently not used
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment