#ifndef HV_SYSREG_H #define HV_SYSREG_H #include "hv/types.h" #define ESR_EC_SHIFT 26u #define ESR_EC_MASK 0x3fu #define ESR_EC_UNKNOWN 0x00u #define ESR_EC_WFI_WFE 0x01u #define ESR_EC_SMC64 0x17u #define ESR_EC_HVC64 0x16u #define ESR_EC_SYSREG 0x18u #define ESR_EC_IABT_LOWER 0x20u #define ESR_EC_DABT_LOWER 0x24u #define ESR_EC_BRK64 0x3cu #define ESR_SYSREG_DIR_READ 1u #define ESR_SYSREG_DIR_WRITE 0u struct sysreg_access { uint32_t op0; uint32_t op1; uint32_t crn; uint32_t crm; uint32_t op2; uint32_t rt; bool is_read; uint64_t key; }; #define SYSREG_KEY_CONST(op0, op1, crn, crm, op2) \ ((((uint64_t)((op0) & 0x3u)) << 14u) | \ (((uint64_t)((op1) & 0x7u)) << 11u) | \ (((uint64_t)((crn) & 0xfu)) << 7u) | \ (((uint64_t)((crm) & 0xfu)) << 3u) | \ ((uint64_t)((op2) & 0x7u))) static inline uint32_t esr_ec(uint64_t esr) { return (uint32_t)((esr >> ESR_EC_SHIFT) & ESR_EC_MASK); } uint64_t sysreg_key_make(uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2); bool sysreg_decode_from_esr_iss(uint64_t iss, struct sysreg_access *out); const char *sysreg_key_name(uint64_t key); const char *esr_ec_name(uint32_t ec); bool sysreg_selftest(void); #endif