target/arm: Move cpregs code out of cpu.h

Since commit cf7c6d1004 ("target/arm: Split out cpregs.h") we now have
a cpregs.h header which is more suitable for this code.

Code moved verbatim.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Fabiano Rosas 2023-02-13 17:29:04 -03:00 committed by Peter Maydell
parent 501e6d1f6c
commit 9200d5cc74
2 changed files with 98 additions and 91 deletions

View File

@ -120,6 +120,104 @@ enum {
ARM_CP_SME = 1 << 19,
};
/*
* Interface for defining coprocessor registers.
* Registers are defined in tables of arm_cp_reginfo structs
* which are passed to define_arm_cp_regs().
*/
/*
* When looking up a coprocessor register we look for it
* via an integer which encodes all of:
* coprocessor number
* Crn, Crm, opc1, opc2 fields
* 32 or 64 bit register (ie is it accessed via MRC/MCR
* or via MRRC/MCRR?)
* non-secure/secure bank (AArch32 only)
* We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
* (In this case crn and opc2 should be zero.)
* For AArch64, there is no 32/64 bit size distinction;
* instead all registers have a 2 bit op0, 3 bit op1 and op2,
* and 4 bit CRn and CRm. The encoding patterns are chosen
* to be easy to convert to and from the KVM encodings, and also
* so that the hashtable can contain both AArch32 and AArch64
* registers (to allow for interprocessing where we might run
* 32 bit code on a 64 bit core).
*/
/*
* This bit is private to our hashtable cpreg; in KVM register
* IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
* in the upper bits of the 64 bit ID.
*/
#define CP_REG_AA64_SHIFT 28
#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
/*
* To enable banking of coprocessor registers depending on ns-bit we
* add a bit to distinguish between secure and non-secure cpregs in the
* hashtable.
*/
#define CP_REG_NS_SHIFT 29
#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
(CP_REG_AA64_MASK | \
((cp) << CP_REG_ARM_COPROC_SHIFT) | \
((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
/*
* Convert a full 64 bit KVM register ID to the truncated 32 bit
* version used as a key for the coprocessor register hashtable
*/
static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
{
uint32_t cpregid = kvmid;
if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
cpregid |= CP_REG_AA64_MASK;
} else {
if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
cpregid |= (1 << 15);
}
/*
* KVM is always non-secure so add the NS flag on AArch32 register
* entries.
*/
cpregid |= 1 << CP_REG_NS_SHIFT;
}
return cpregid;
}
/*
* Convert a truncated 32 bit hashtable key into the full
* 64 bit KVM register ID.
*/
static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
{
uint64_t kvmid;
if (cpregid & CP_REG_AA64_MASK) {
kvmid = cpregid & ~CP_REG_AA64_MASK;
kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
} else {
kvmid = cpregid & ~(1 << 15);
if (cpregid & (1 << 15)) {
kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
} else {
kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
}
}
return kvmid;
}
/*
* Valid values for ARMCPRegInfo state field, indicating which of
* the AArch32 and AArch64 execution states this register is visible in.

View File

@ -2559,97 +2559,6 @@ void arm_cpu_list(void);
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
uint32_t cur_el, bool secure);
/* Interface for defining coprocessor registers.
* Registers are defined in tables of arm_cp_reginfo structs
* which are passed to define_arm_cp_regs().
*/
/* When looking up a coprocessor register we look for it
* via an integer which encodes all of:
* coprocessor number
* Crn, Crm, opc1, opc2 fields
* 32 or 64 bit register (ie is it accessed via MRC/MCR
* or via MRRC/MCRR?)
* non-secure/secure bank (AArch32 only)
* We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
* (In this case crn and opc2 should be zero.)
* For AArch64, there is no 32/64 bit size distinction;
* instead all registers have a 2 bit op0, 3 bit op1 and op2,
* and 4 bit CRn and CRm. The encoding patterns are chosen
* to be easy to convert to and from the KVM encodings, and also
* so that the hashtable can contain both AArch32 and AArch64
* registers (to allow for interprocessing where we might run
* 32 bit code on a 64 bit core).
*/
/* This bit is private to our hashtable cpreg; in KVM register
* IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
* in the upper bits of the 64 bit ID.
*/
#define CP_REG_AA64_SHIFT 28
#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
/* To enable banking of coprocessor registers depending on ns-bit we
* add a bit to distinguish between secure and non-secure cpregs in the
* hashtable.
*/
#define CP_REG_NS_SHIFT 29
#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
(CP_REG_AA64_MASK | \
((cp) << CP_REG_ARM_COPROC_SHIFT) | \
((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
/* Convert a full 64 bit KVM register ID to the truncated 32 bit
* version used as a key for the coprocessor register hashtable
*/
static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
{
uint32_t cpregid = kvmid;
if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
cpregid |= CP_REG_AA64_MASK;
} else {
if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
cpregid |= (1 << 15);
}
/* KVM is always non-secure so add the NS flag on AArch32 register
* entries.
*/
cpregid |= 1 << CP_REG_NS_SHIFT;
}
return cpregid;
}
/* Convert a truncated 32 bit hashtable key into the full
* 64 bit KVM register ID.
*/
static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
{
uint64_t kvmid;
if (cpregid & CP_REG_AA64_MASK) {
kvmid = cpregid & ~CP_REG_AA64_MASK;
kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
} else {
kvmid = cpregid & ~(1 << 15);
if (cpregid & (1 << 15)) {
kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
} else {
kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
}
}
return kvmid;
}
/* Return the highest implemented Exception Level */
static inline int arm_highest_el(CPUARMState *env)
{