Atmosphere/thermosphere/src/exceptions.h
2018-04-20 04:10:44 -06:00

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