mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
target-arm: Provide correct syndrome information for cpreg access traps
For exceptions taken to AArch64, if a coprocessor/system register access fails due to a trap or enable bit then the syndrome information must include details of the failing instruction (crn/crm/opc1/opc2 fields, etc). Make the decoder construct the syndrome information at translate time so it can be passed at runtime to the access-check helper function and used as required. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
This commit is contained in:
parent
abf1172fc6
commit
8bcbf37caa
5 changed files with 184 additions and 7 deletions
|
@ -46,4 +46,132 @@ enum arm_fprounding {
|
|||
|
||||
int arm_rmode_to_sf(int rmode);
|
||||
|
||||
/* Valid Syndrome Register EC field values */
|
||||
enum arm_exception_class {
|
||||
EC_UNCATEGORIZED = 0x00,
|
||||
EC_WFX_TRAP = 0x01,
|
||||
EC_CP15RTTRAP = 0x03,
|
||||
EC_CP15RRTTRAP = 0x04,
|
||||
EC_CP14RTTRAP = 0x05,
|
||||
EC_CP14DTTRAP = 0x06,
|
||||
EC_ADVSIMDFPACCESSTRAP = 0x07,
|
||||
EC_FPIDTRAP = 0x08,
|
||||
EC_CP14RRTTRAP = 0x0c,
|
||||
EC_ILLEGALSTATE = 0x0e,
|
||||
EC_AA32_SVC = 0x11,
|
||||
EC_AA32_HVC = 0x12,
|
||||
EC_AA32_SMC = 0x13,
|
||||
EC_AA64_SVC = 0x15,
|
||||
EC_AA64_HVC = 0x16,
|
||||
EC_AA64_SMC = 0x17,
|
||||
EC_SYSTEMREGISTERTRAP = 0x18,
|
||||
EC_INSNABORT = 0x20,
|
||||
EC_INSNABORT_SAME_EL = 0x21,
|
||||
EC_PCALIGNMENT = 0x22,
|
||||
EC_DATAABORT = 0x24,
|
||||
EC_DATAABORT_SAME_EL = 0x25,
|
||||
EC_SPALIGNMENT = 0x26,
|
||||
EC_AA32_FPTRAP = 0x28,
|
||||
EC_AA64_FPTRAP = 0x2c,
|
||||
EC_SERROR = 0x2f,
|
||||
EC_BREAKPOINT = 0x30,
|
||||
EC_BREAKPOINT_SAME_EL = 0x31,
|
||||
EC_SOFTWARESTEP = 0x32,
|
||||
EC_SOFTWARESTEP_SAME_EL = 0x33,
|
||||
EC_WATCHPOINT = 0x34,
|
||||
EC_WATCHPOINT_SAME_EL = 0x35,
|
||||
EC_AA32_BKPT = 0x38,
|
||||
EC_VECTORCATCH = 0x3a,
|
||||
EC_AA64_BKPT = 0x3c,
|
||||
};
|
||||
|
||||
#define ARM_EL_EC_SHIFT 26
|
||||
#define ARM_EL_IL_SHIFT 25
|
||||
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
|
||||
|
||||
/* Utility functions for constructing various kinds of syndrome value.
|
||||
* Note that in general we follow the AArch64 syndrome values; in a
|
||||
* few cases the value in HSR for exceptions taken to AArch32 Hyp
|
||||
* mode differs slightly, so if we ever implemented Hyp mode then the
|
||||
* syndrome value would need some massaging on exception entry.
|
||||
* (One example of this is that AArch64 defaults to IL bit set for
|
||||
* exceptions which don't specifically indicate information about the
|
||||
* trapping instruction, whereas AArch32 defaults to IL bit clear.)
|
||||
*/
|
||||
static inline uint32_t syn_uncategorized(void)
|
||||
{
|
||||
return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
|
||||
}
|
||||
|
||||
static inline uint32_t syn_aa64_svc(uint32_t imm16)
|
||||
{
|
||||
return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
|
||||
}
|
||||
|
||||
static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
|
||||
{
|
||||
return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
|
||||
| (is_thumb ? 0 : ARM_EL_IL);
|
||||
}
|
||||
|
||||
static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
|
||||
{
|
||||
return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
|
||||
}
|
||||
|
||||
static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_thumb)
|
||||
{
|
||||
return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
|
||||
| (is_thumb ? 0 : ARM_EL_IL);
|
||||
}
|
||||
|
||||
static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
|
||||
int crn, int crm, int rt,
|
||||
int isread)
|
||||
{
|
||||
return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
|
||||
| (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
|
||||
| (crm << 1) | isread;
|
||||
}
|
||||
|
||||
static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
|
||||
int crn, int crm, int rt, int isread,
|
||||
bool is_thumb)
|
||||
{
|
||||
return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
|
||||
| (is_thumb ? 0 : ARM_EL_IL)
|
||||
| (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
|
||||
| (crn << 10) | (rt << 5) | (crm << 1) | isread;
|
||||
}
|
||||
|
||||
static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
|
||||
int crn, int crm, int rt, int isread,
|
||||
bool is_thumb)
|
||||
{
|
||||
return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
|
||||
| (is_thumb ? 0 : ARM_EL_IL)
|
||||
| (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
|
||||
| (crn << 10) | (rt << 5) | (crm << 1) | isread;
|
||||
}
|
||||
|
||||
static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
|
||||
int rt, int rt2, int isread,
|
||||
bool is_thumb)
|
||||
{
|
||||
return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
|
||||
| (is_thumb ? 0 : ARM_EL_IL)
|
||||
| (cv << 24) | (cond << 20) | (opc1 << 16)
|
||||
| (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
|
||||
}
|
||||
|
||||
static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
|
||||
int rt, int rt2, int isread,
|
||||
bool is_thumb)
|
||||
{
|
||||
return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
|
||||
| (is_thumb ? 0 : ARM_EL_IL)
|
||||
| (cv << 24) | (cond << 20) | (opc1 << 16)
|
||||
| (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue