mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-26 05:42:17 +00:00
176 lines
6.2 KiB
C
176 lines
6.2 KiB
C
/**
|
|
* Thermosphère: exception handler
|
|
* Handles all exceptions, including a return to EL2.
|
|
*
|
|
* Copyright (c) 2018 Kate J. Temkin <k@ktemkin.com>
|
|
*/
|
|
|
|
#ifndef __EXCEPTION_H__
|
|
#define __EXCEPTION_H__
|
|
|
|
/**
|
|
* Borrowed fom Xen (not copyrightable as these are facts).
|
|
* Description of the EL2 exception syndrome register.
|
|
*/
|
|
#define HSR_EC_UNKNOWN 0x00
|
|
#define HSR_EC_WFI_WFE 0x01
|
|
#define HSR_EC_CP15_32 0x03
|
|
#define HSR_EC_CP15_64 0x04
|
|
#define HSR_EC_CP14_32 0x05 /* Trapped MCR or MRC access to CP14 */
|
|
#define HSR_EC_CP14_DBG 0x06 /* Trapped LDC/STC access to CP14 (only for debug registers) */
|
|
#define HSR_EC_CP 0x07 /* HCPTR-trapped access to CP0-CP13 */
|
|
#define HSR_EC_CP10 0x08
|
|
#define HSR_EC_JAZELLE 0x09
|
|
#define HSR_EC_BXJ 0x0a
|
|
#define HSR_EC_CP14_64 0x0c
|
|
#define HSR_EC_SVC32 0x11
|
|
#define HSR_EC_HVC32 0x12
|
|
#define HSR_EC_SMC32 0x13
|
|
#define HSR_EC_HVC64 0x16
|
|
#define HSR_EC_SMC64 0x17
|
|
#define HSR_EC_SYSREG 0x18
|
|
#define HSR_EC_INSTR_ABORT_LOWER_EL 0x20
|
|
#define HSR_EC_INSTR_ABORT_CURR_EL 0x21
|
|
#define HSR_EC_DATA_ABORT_LOWER_EL 0x24
|
|
#define HSR_EC_DATA_ABORT_CURR_EL 0x25
|
|
#define HSR_EC_BRK 0x3c
|
|
|
|
/**
|
|
* Borrowed fom Xen (not copyrightable as these are facts).
|
|
* Description of the EL2 exception syndrome register.
|
|
*/
|
|
union esr {
|
|
uint32_t bits;
|
|
struct {
|
|
unsigned long iss:25; /* Instruction Specific Syndrome */
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
};
|
|
|
|
/* Common to all conditional exception classes (0x0N, except 0x00). */
|
|
struct hsr_cond {
|
|
unsigned long iss:20; /* Instruction Specific Syndrome */
|
|
unsigned long cc:4; /* Condition Code */
|
|
unsigned long ccvalid:1;/* CC Valid */
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} cond;
|
|
|
|
struct hsr_wfi_wfe {
|
|
unsigned long ti:1; /* Trapped instruction */
|
|
unsigned long sbzp:19;
|
|
unsigned long cc:4; /* Condition Code */
|
|
unsigned long ccvalid:1;/* CC Valid */
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} wfi_wfe;
|
|
|
|
/* reg, reg0, reg1 are 4 bits on AArch32, the fifth bit is sbzp. */
|
|
struct hsr_cp32 {
|
|
unsigned long read:1; /* Direction */
|
|
unsigned long crm:4; /* CRm */
|
|
unsigned long reg:5; /* Rt */
|
|
unsigned long crn:4; /* CRn */
|
|
unsigned long op1:3; /* Op1 */
|
|
unsigned long op2:3; /* Op2 */
|
|
unsigned long cc:4; /* Condition Code */
|
|
unsigned long ccvalid:1;/* CC Valid */
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} cp32; /* HSR_EC_CP15_32, CP14_32, CP10 */
|
|
|
|
struct hsr_cp64 {
|
|
unsigned long read:1; /* Direction */
|
|
unsigned long crm:4; /* CRm */
|
|
unsigned long reg1:5; /* Rt1 */
|
|
unsigned long reg2:5; /* Rt2 */
|
|
unsigned long sbzp2:1;
|
|
unsigned long op1:4; /* Op1 */
|
|
unsigned long cc:4; /* Condition Code */
|
|
unsigned long ccvalid:1;/* CC Valid */
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} cp64; /* HSR_EC_CP15_64, HSR_EC_CP14_64 */
|
|
|
|
struct hsr_cp {
|
|
unsigned long coproc:4; /* Number of coproc accessed */
|
|
unsigned long sbz0p:1;
|
|
unsigned long tas:1; /* Trapped Advanced SIMD */
|
|
unsigned long res0:14;
|
|
unsigned long cc:4; /* Condition Code */
|
|
unsigned long ccvalid:1;/* CC Valid */
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} cp; /* HSR_EC_CP */
|
|
|
|
struct hsr_sysreg {
|
|
unsigned long read:1; /* Direction */
|
|
unsigned long crm:4; /* CRm */
|
|
unsigned long reg:5; /* Rt */
|
|
unsigned long crn:4; /* CRn */
|
|
unsigned long op1:3; /* Op1 */
|
|
unsigned long op2:3; /* Op2 */
|
|
unsigned long op0:2; /* Op0 */
|
|
unsigned long res0:3;
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6;
|
|
} sysreg; /* HSR_EC_SYSREG */
|
|
|
|
struct hsr_iabt {
|
|
unsigned long ifsc:6; /* Instruction fault status code */
|
|
unsigned long res0:1;
|
|
unsigned long s1ptw:1; /* Stage 2 fault during stage 1 translation */
|
|
unsigned long res1:1;
|
|
unsigned long eat:1; /* External abort type */
|
|
unsigned long res2:15;
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} iabt; /* HSR_EC_INSTR_ABORT_* */
|
|
|
|
struct hsr_dabt {
|
|
unsigned long dfsc:6; /* Data Fault Status Code */
|
|
unsigned long write:1; /* Write / not Read */
|
|
unsigned long s1ptw:1; /* Stage 2 fault during stage 1 translation */
|
|
unsigned long cache:1; /* Cache Maintenance */
|
|
unsigned long eat:1; /* External Abort Type */
|
|
unsigned long sbzp0:4;
|
|
unsigned long ar:1; /* Acquire Release */
|
|
unsigned long sf:1; /* Sixty Four bit register */
|
|
unsigned long reg:5; /* Register */
|
|
unsigned long sign:1; /* Sign extend */
|
|
unsigned long size:2; /* Access Size */
|
|
unsigned long valid:1; /* Syndrome Valid */
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} dabt; /* HSR_EC_DATA_ABORT_* */
|
|
|
|
struct hsr_brk {
|
|
unsigned long comment:16; /* Comment */
|
|
unsigned long res0:9;
|
|
unsigned long len:1; /* Instruction length */
|
|
unsigned long ec:6; /* Exception Class */
|
|
} brk;
|
|
|
|
};
|
|
|
|
/**
|
|
* Structure that stores the saved register values on a hypercall.
|
|
*/
|
|
struct guest_state {
|
|
uint64_t pc;
|
|
uint64_t cpsr;
|
|
|
|
uint64_t elr_el1;
|
|
uint64_t spsr_el1;
|
|
|
|
uint64_t sp_el0;
|
|
uint64_t sp_el1;
|
|
|
|
union esr esr_el2;
|
|
uint64_t x[31];
|
|
}
|
|
__attribute__((packed));
|
|
|
|
|
|
|
|
#endif
|