C-sparse
view release on metacpan or search on metacpan
src/sparse-0.4.4/perl/t/target-arm/cpu.h view on Meta::CPAN
* defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
* PL2 (hyp). The other level which has Read and Write bits is Secure PL1
* (ie any of the privileged modes in Secure state, or Monitor mode).
* If a register is accessible in one privilege level it's always accessible
* in higher privilege levels too. Since "Secure PL1" also follows this rule
* (ie anything visible in PL2 is visible in S-PL1, some things are only
* visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
* terminology a little and call this PL3.
*
* If access permissions for a register are more complex than can be
* described with these bits, then use a laxer set of restrictions, and
* do the more restrictive/complex check inside a helper function.
*/
#define PL3_R 0x80
#define PL3_W 0x40
#define PL2_R (0x20 | PL3_R)
#define PL2_W (0x10 | PL3_W)
#define PL1_R (0x08 | PL2_R)
#define PL1_W (0x04 | PL2_W)
#define PL0_R (0x02 | PL1_R)
#define PL0_W (0x01 | PL1_W)
#define PL3_RW (PL3_R | PL3_W)
#define PL2_RW (PL2_R | PL2_W)
#define PL1_RW (PL1_R | PL1_W)
#define PL0_RW (PL0_R | PL0_W)
static inline int arm_current_pl(CPUARMState *env)
{
if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
return 0;
}
/* We don't currently implement the Virtualization or TrustZone
* extensions, so PL2 and PL3 don't exist for us.
*/
return 1;
}
typedef struct ARMCPRegInfo ARMCPRegInfo;
/* Access functions for coprocessor registers. These should return
* 0 on success, or one of the EXCP_* constants if access should cause
* an exception (in which case *value is not written).
*/
typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
uint64_t *value);
typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
uint64_t value);
/* Hook function for register reset */
typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
#define CP_ANY 0xff
/* Definition of an ARM coprocessor register */
struct ARMCPRegInfo {
/* Name of register (useful mainly for debugging, need not be unique) */
const char *name;
/* Location of register: coprocessor number and (crn,crm,opc1,opc2)
* tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
* 'wildcard' field -- any value of that field in the MRC/MCR insn
* will be decoded to this register. The register read and write
* callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
* used by the program, so it is possible to register a wildcard and
* then behave differently on read/write if necessary.
* For 64 bit registers, only crm and opc1 are relevant; crn and opc2
* must both be zero.
*/
uint8_t cp;
uint8_t crn;
uint8_t crm;
uint8_t opc1;
uint8_t opc2;
/* Register type: ARM_CP_* bits/values */
int type;
/* Access rights: PL*_[RW] */
int access;
/* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
* this register was defined: can be used to hand data through to the
* register read/write functions, since they are passed the ARMCPRegInfo*.
*/
void *opaque;
/* Value of this register, if it is ARM_CP_CONST. Otherwise, if
* fieldoffset is non-zero, the reset value of the register.
*/
uint64_t resetvalue;
/* Offset of the field in CPUARMState for this register. This is not
* needed if either:
* 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
* 2. both readfn and writefn are specified
*/
ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
/* Function for handling reads of this register. If NULL, then reads
* will be done by loading from the offset into CPUARMState specified
* by fieldoffset.
*/
CPReadFn *readfn;
/* Function for handling writes of this register. If NULL, then writes
* will be done by writing to the offset into CPUARMState specified
* by fieldoffset.
*/
CPWriteFn *writefn;
/* Function for doing a "raw" read; used when we need to copy
* coprocessor state to the kernel for KVM or out for
* migration. This only needs to be provided if there is also a
* readfn and it makes an access permission check.
*/
CPReadFn *raw_readfn;
/* Function for doing a "raw" write; used when we need to copy KVM
* kernel coprocessor state into userspace, or for inbound
* migration. This only needs to be provided if there is also a
* writefn and it makes an access permission check or masks out
* "unwritable" bits or has write-one-to-clear or similar behaviour.
*/
CPWriteFn *raw_writefn;
/* Function for resetting the register. If NULL, then reset will be done
* by writing resetvalue to the field specified in fieldoffset. If
* fieldoffset is 0 then no reset will be done.
*/
CPResetFn *resetfn;
};
( run in 0.453 second using v1.01-cache-2.11-cpan-39bf76dae61 )