summaryrefslogtreecommitdiff
path: root/payloads/libpayload/include/arm64/arch
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload/include/arm64/arch')
-rw-r--r--payloads/libpayload/include/arm64/arch/exception.h90
1 files changed, 86 insertions, 4 deletions
diff --git a/payloads/libpayload/include/arm64/arch/exception.h b/payloads/libpayload/include/arm64/arch/exception.h
index 8afe39103b..f699d3d6ed 100644
--- a/payloads/libpayload/include/arm64/arch/exception.h
+++ b/payloads/libpayload/include/arm64/arch/exception.h
@@ -30,18 +30,98 @@
#ifndef _ARCH_EXCEPTION_H
#define _ARCH_EXCEPTION_H
-#include <stdint.h>
+#define EXCEPTION_STATE_ELR 0x0
+#define EXCEPTION_STATE_ESR 0x8
+#define EXCEPTION_STATE_SPSR 0x10
+#define EXCEPTION_STATE_SP 0x18
+#define EXCEPTION_STATE_REG(r) (0x20 + r * 0x8)
+
+#define ESR_EC_UNKNOWN 0b000000
+#define ESR_EC_SVC_64 0b010101
+#define ESR_EC_INSN_ABT_LOWER 0b100000
+#define ESR_EC_INSN_ABT_SAME 0b100001
+#define ESR_EC_DATA_ABT_LOWER 0b100100
+#define ESR_EC_DATA_ABT_SAME 0b100101
+#define ESR_EC_SERROR 0b101111
+#define ESR_EC_SS_SAME 0b110011
+#define ESR_EC_BKPT_64 0b111100
+
+#define MDCR_TDE (1 << 8)
-void set_vbar(void* vbar);
+#define MDSCR_SS (1 << 0)
+#define MDSCR_KDE (1 << 13)
+#define MDSCR_MDE (1 << 15)
+
+#ifndef __ASSEMBLER__
+
+#include <stddef.h>
+#include <stdint.h>
struct exception_state
{
uint64_t elr;
- uint64_t esr;
+ union {
+ uint64_t esr;
+ union {
+ struct {
+ uint64_t iss : 25;
+ uint64_t il : 1;
+ uint64_t ec : 6;
+ uint64_t _res0 : 32;
+ };
+ struct {
+ uint64_t isfc : 6;
+ uint64_t _res0 : 1;
+ uint64_t s1ptw : 1;
+ uint64_t _res1 : 1;
+ uint64_t ea : 1;
+ uint64_t fnv : 1;
+ uint64_t _res2 : 53;
+ } insn_abt;
+ };
+ };
+ union {
+ uint32_t spsr;
+ struct {
+ uint32_t sp : 1; /* M[0] */
+ uint32_t _res0 : 1; /* M[1] */
+ uint32_t el : 2; /* M[3:2] */
+ uint32_t arch : 1; /* M[4] */
+ uint32_t _res1 : 1;
+ uint32_t f : 1;
+ uint32_t i : 1;
+ uint32_t a : 1;
+ uint32_t d : 1;
+ uint32_t _res2 : 10;
+ uint32_t il : 1;
+ uint32_t ss : 1;
+ uint32_t _res3 : 6;
+ uint32_t v : 1;
+ uint32_t c : 1;
+ uint32_t z : 1;
+ uint32_t n : 1;
+ } pstate;
+ };
+ uint32_t spsr_high_unused;
+ uint64_t sp;
uint64_t regs[31];
} __packed;
-extern struct exception_state *exception_state;
+#define CHECK_ES(field, constant) \
+ _Static_assert(offsetof(struct exception_state, field) == constant, \
+ "(struct exception_state)." #field " doesn't match constant " #constant)
+CHECK_ES(elr, EXCEPTION_STATE_ELR);
+CHECK_ES(esr, EXCEPTION_STATE_ESR);
+CHECK_ES(spsr, EXCEPTION_STATE_SPSR);
+CHECK_ES(sp, EXCEPTION_STATE_SP);
+CHECK_ES(regs[0], EXCEPTION_STATE_REG(0));
+CHECK_ES(regs[30], EXCEPTION_STATE_REG(30));
+
+extern struct exception_state exception_state;
+extern u64 exception_stack[];
+extern u64 *exception_stack_end;
+
+void exception_set_state_ptr(struct exception_state *exception_state_ptr);
enum {
EXC_SYNC_SP0 = 0,
@@ -63,4 +143,6 @@ enum {
EXC_COUNT
};
+#endif /* !__ASSEMBLER__ */
+
#endif