1 Star 0 Fork 109

Chuan / qemu

forked from src-openEuler / qemu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
target-arm-register-CPU-features-for-property.patch 18.47 KB
一键复制 编辑 原始数据 按行查看 历史
From f169b1f76cad9f727c701df853b05ad5e8d7f927 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Thu, 6 Aug 2020 16:14:37 +0800
Subject: [PATCH 3/9] target/arm: register CPU features for property
The Arm architecture specifies a number of ID registers that are
characterized as comprising a set of 4-bit ID fields. Each ID field
identifies the presence, and possibly the level of support for, a
particular feature in an implementation of the architecture. [1]
For most of the ID fields, there is a minimum presence value, equal to
or higher than which means the corresponding CPU feature is implemented.
Hence, we can use the minimum presence value to determine whether a CPU
feature is enabled and enable a CPU feature.
To disable a CPU feature, setting the corresponding ID field to 0x0/0xf
(for unsigned/signed field) seems as a good idea. However, it maybe
lead to some problems. For example, ID_AA64PFR0_EL1.FP is a signed ID
field. ID_AA64PFR0_EL1.FP == 0x0 represents the implementation of FP
(floating-point) and ID_AA64PFR0_EL1.FP == 0x1 represents the
implementation of FPHP (half-precision floating-point). If
ID_AA64PFR0_EL1.FP is set to 0xf when FPHP is disabled (which is also
disable FP), guest kernel maybe stuck. Hence, we add a ni_value (means
not-implemented value) to disable a CPU feature safely.
[1] D13.1.3 Principles of the ID scheme for fields in ID registers in
DDI.0487
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
target/arm/cpu.c | 343 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 343 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5bcdad0c..3f63312c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1034,6 +1034,347 @@ static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name,
visit_type_uint32(v, name, &cpu->init_svtor, errp);
}
+/**
+ * CPUFeatureInfo:
+ * @reg: The ID register where the ID field is in.
+ * @name: The name of the CPU feature.
+ * @length: The bit length of the ID field.
+ * @shift: The bit shift of the ID field in the ID register.
+ * @min_value: The minimum value equal to or larger than which means the CPU
+ * feature is implemented.
+ * @ni_value: Not-implemented value. It will be set to the ID field when
+ * disabling the CPU feature. Usually, it's min_value - 1.
+ * @sign: Whether the ID field is signed.
+ * @is_32bit: Whether the CPU feature is for 32-bit.
+ *
+ * In ARM, a CPU feature is described by an ID field, which is a 4-bit field in
+ * an ID register.
+ */
+typedef struct CPUFeatureInfo {
+ CPUIDReg reg;
+ const char *name;
+ int length;
+ int shift;
+ int min_value;
+ int ni_value;
+ bool sign;
+ bool is_32bit;
+} CPUFeatureInfo;
+
+#define FIELD_INFO(feature_name, id_reg, field, s, min_val, ni_val, is32bit) { \
+ .reg = id_reg, \
+ .length = R_ ## id_reg ## _ ## field ## _LENGTH, \
+ .shift = R_ ## id_reg ## _ ## field ## _SHIFT, \
+ .sign = s, \
+ .min_value = min_val, \
+ .ni_value = ni_val, \
+ .name = feature_name, \
+ .is_32bit = is32bit, \
+}
+
+static struct CPUFeatureInfo cpu_features[] = {
+ FIELD_INFO("swap", ID_ISAR0, SWAP, false, 1, 0, true),
+ FIELD_INFO("bitcount", ID_ISAR0, BITCOUNT, false, 1, 0, true),
+ FIELD_INFO("bitfield", ID_ISAR0, BITFIELD, false, 1, 0, true),
+ FIELD_INFO("cmpbranch", ID_ISAR0, CMPBRANCH, false, 1, 0, true),
+ FIELD_INFO("coproc", ID_ISAR0, COPROC, false, 1, 0, true),
+ FIELD_INFO("debug", ID_ISAR0, DEBUG, false, 1, 0, true),
+ FIELD_INFO("device", ID_ISAR0, DIVIDE, false, 1, 0, true),
+
+ FIELD_INFO("endian", ID_ISAR1, ENDIAN, false, 1, 0, true),
+ FIELD_INFO("except", ID_ISAR1, EXCEPT, false, 1, 0, true),
+ FIELD_INFO("except_ar", ID_ISAR1, EXCEPT_AR, false, 1, 0, true),
+ FIELD_INFO("extend", ID_ISAR1, EXTEND, false, 1, 0, true),
+ FIELD_INFO("ifthen", ID_ISAR1, IFTHEN, false, 1, 0, true),
+ FIELD_INFO("immediate", ID_ISAR1, IMMEDIATE, false, 1, 0, true),
+ FIELD_INFO("interwork", ID_ISAR1, INTERWORK, false, 1, 0, true),
+ FIELD_INFO("jazelle", ID_ISAR1, JAZELLE, false, 1, 0, true),
+
+ FIELD_INFO("loadstore", ID_ISAR2, LOADSTORE, false, 1, 0, true),
+ FIELD_INFO("memhint", ID_ISAR2, MEMHINT, false, 1, 0, true),
+ FIELD_INFO("multiaccessint", ID_ISAR2, MULTIACCESSINT, false, 1, 0, true),
+ FIELD_INFO("mult", ID_ISAR2, MULT, false, 1, 0, true),
+ FIELD_INFO("mults", ID_ISAR2, MULTS, false, 1, 0, true),
+ FIELD_INFO("multu", ID_ISAR2, MULTU, false, 1, 0, true),
+ FIELD_INFO("psr_ar", ID_ISAR2, PSR_AR, false, 1, 0, true),
+ FIELD_INFO("reversal", ID_ISAR2, REVERSAL, false, 1, 0, true),
+
+ FIELD_INFO("saturate", ID_ISAR3, SATURATE, false, 1, 0, true),
+ FIELD_INFO("simd", ID_ISAR3, SIMD, false, 1, 0, true),
+ FIELD_INFO("svc", ID_ISAR3, SVC, false, 1, 0, true),
+ FIELD_INFO("synchprim", ID_ISAR3, SYNCHPRIM, false, 1, 0, true),
+ FIELD_INFO("tabbranch", ID_ISAR3, TABBRANCH, false, 1, 0, true),
+ FIELD_INFO("t32copy", ID_ISAR3, T32COPY, false, 1, 0, true),
+ FIELD_INFO("truenop", ID_ISAR3, TRUENOP, false, 1, 0, true),
+ FIELD_INFO("t32ee", ID_ISAR3, T32EE, false, 1, 0, true),
+
+ FIELD_INFO("unpriv", ID_ISAR4, UNPRIV, false, 1, 0, true),
+ FIELD_INFO("withshifts", ID_ISAR4, WITHSHIFTS, false, 1, 0, true),
+ FIELD_INFO("writeback", ID_ISAR4, WRITEBACK, false, 1, 0, true),
+ FIELD_INFO("smc", ID_ISAR4, SMC, false, 1, 0, true),
+ FIELD_INFO("barrier", ID_ISAR4, BARRIER, false, 1, 0, true),
+ FIELD_INFO("synchprim_frac", ID_ISAR4, SYNCHPRIM_FRAC, false, 1, 0, true),
+ FIELD_INFO("psr_m", ID_ISAR4, PSR_M, false, 1, 0, true),
+ FIELD_INFO("swp_frac", ID_ISAR4, SWP_FRAC, false, 1, 0, true),
+
+ FIELD_INFO("sevl", ID_ISAR5, SEVL, false, 1, 0, true),
+ FIELD_INFO("aes", ID_ISAR5, AES, false, 1, 0, true),
+ FIELD_INFO("sha1", ID_ISAR5, SHA1, false, 1, 0, true),
+ FIELD_INFO("sha2", ID_ISAR5, SHA2, false, 1, 0, true),
+ FIELD_INFO("crc32", ID_ISAR5, CRC32, false, 1, 0, true),
+ FIELD_INFO("rdm", ID_ISAR5, RDM, false, 1, 0, true),
+ FIELD_INFO("vcma", ID_ISAR5, VCMA, false, 1, 0, true),
+
+ FIELD_INFO("jscvt", ID_ISAR6, JSCVT, false, 1, 0, true),
+ FIELD_INFO("dp", ID_ISAR6, DP, false, 1, 0, true),
+ FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true),
+ FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true),
+ FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true),
+
+ FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true),
+ FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true),
+ FIELD_INFO("bpmaint", ID_MMFR3, BPMAINT, false, 1, 0, true),
+ FIELD_INFO("maintbcst", ID_MMFR3, MAINTBCST, false, 1, 0, true),
+ FIELD_INFO("pan", ID_MMFR3, PAN, false, 1, 0, true),
+ FIELD_INFO("cohwalk", ID_MMFR3, COHWALK, false, 1, 0, true),
+ FIELD_INFO("cmemsz", ID_MMFR3, CMEMSZ, false, 1, 0, true),
+ FIELD_INFO("supersec", ID_MMFR3, SUPERSEC, false, 1, 0, true),
+
+ FIELD_INFO("specsei", ID_MMFR4, SPECSEI, false, 1, 0, true),
+ FIELD_INFO("ac2", ID_MMFR4, AC2, false, 1, 0, true),
+ FIELD_INFO("xnx", ID_MMFR4, XNX, false, 1, 0, true),
+ FIELD_INFO("cnp", ID_MMFR4, CNP, false, 1, 0, true),
+ FIELD_INFO("hpds", ID_MMFR4, HPDS, false, 1, 0, true),
+ FIELD_INFO("lsm", ID_MMFR4, LSM, false, 1, 0, true),
+ FIELD_INFO("ccidx", ID_MMFR4, CCIDX, false, 1, 0, true),
+ FIELD_INFO("evt", ID_MMFR4, EVT, false, 1, 0, true),
+
+ FIELD_INFO("simdreg", MVFR0, SIMDREG, false, 1, 0, true),
+ FIELD_INFO("fpsp", MVFR0, FPSP, false, 1, 0, true),
+ FIELD_INFO("fpdp", MVFR0, FPDP, false, 1, 0, true),
+ FIELD_INFO("fptrap", MVFR0, FPTRAP, false, 1, 0, true),
+ FIELD_INFO("fpdivide", MVFR0, FPDIVIDE, false, 1, 0, true),
+ FIELD_INFO("fpsqrt", MVFR0, FPSQRT, false, 1, 0, true),
+ FIELD_INFO("fpshvec", MVFR0, FPSHVEC, false, 1, 0, true),
+ FIELD_INFO("fpround", MVFR0, FPROUND, false, 1, 0, true),
+
+ FIELD_INFO("fpftz", MVFR1, FPFTZ, false, 1, 0, true),
+ FIELD_INFO("fpdnan", MVFR1, FPDNAN, false, 1, 0, true),
+ FIELD_INFO("simdls", MVFR1, SIMDLS, false, 1, 0, true),
+ FIELD_INFO("simdint", MVFR1, SIMDINT, false, 1, 0, true),
+ FIELD_INFO("simdsp", MVFR1, SIMDSP, false, 1, 0, true),
+ FIELD_INFO("simdhp", MVFR1, SIMDHP, false, 1, 0, true),
+ FIELD_INFO("fphp", MVFR1, FPHP, false, 1, 0, true),
+ FIELD_INFO("simdfmac", MVFR1, SIMDFMAC, false, 1, 0, true),
+
+ FIELD_INFO("simdmisc", MVFR2, SIMDMISC, false, 1, 0, true),
+ FIELD_INFO("fpmisc", MVFR2, FPMISC, false, 1, 0, true),
+
+ FIELD_INFO("debugver", ID_AA64DFR0, DEBUGVER, false, 1, 0, false),
+ FIELD_INFO("tracever", ID_AA64DFR0, TRACEVER, false, 1, 0, false),
+ FIELD_INFO("pmuver", ID_AA64DFR0, PMUVER, false, 1, 0, false),
+ FIELD_INFO("brps", ID_AA64DFR0, BRPS, false, 1, 0, false),
+ FIELD_INFO("wrps", ID_AA64DFR0, WRPS, false, 1, 0, false),
+ FIELD_INFO("ctx_cmps", ID_AA64DFR0, CTX_CMPS, false, 1, 0, false),
+ FIELD_INFO("pmsver", ID_AA64DFR0, PMSVER, false, 1, 0, false),
+ FIELD_INFO("doublelock", ID_AA64DFR0, DOUBLELOCK, false, 1, 0, false),
+ FIELD_INFO("tracefilt", ID_AA64DFR0, TRACEFILT, false, 1, 0, false),
+
+ FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false),
+ FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
+ FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
+ FIELD_INFO("crc32", ID_AA64ISAR0, CRC32, false, 1, 0, false),
+ FIELD_INFO("atomics", ID_AA64ISAR0, ATOMIC, false, 1, 0, false),
+ FIELD_INFO("asimdrdm", ID_AA64ISAR0, RDM, false, 1, 0, false),
+ FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
+ FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
+ FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
+ FIELD_INFO("asimddp", ID_AA64ISAR0, DP, false, 1, 0, false),
+ FIELD_INFO("asimdfhm", ID_AA64ISAR0, FHM, false, 1, 0, false),
+ FIELD_INFO("flagm", ID_AA64ISAR0, TS, false, 1, 0, false),
+ FIELD_INFO("tlb", ID_AA64ISAR0, TLB, false, 1, 0, false),
+ FIELD_INFO("rng", ID_AA64ISAR0, RNDR, false, 1, 0, false),
+
+ FIELD_INFO("dcpop", ID_AA64ISAR1, DPB, false, 1, 0, false),
+ FIELD_INFO("papa", ID_AA64ISAR1, APA, false, 1, 0, false),
+ FIELD_INFO("api", ID_AA64ISAR1, API, false, 1, 0, false),
+ FIELD_INFO("jscvt", ID_AA64ISAR1, JSCVT, false, 1, 0, false),
+ FIELD_INFO("fcma", ID_AA64ISAR1, FCMA, false, 1, 0, false),
+ FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false),
+ FIELD_INFO("pacg", ID_AA64ISAR1, GPA, false, 1, 0, false),
+ FIELD_INFO("gpi", ID_AA64ISAR1, GPI, false, 1, 0, false),
+ FIELD_INFO("frint", ID_AA64ISAR1, FRINTTS, false, 1, 0, false),
+ FIELD_INFO("sb", ID_AA64ISAR1, SB, false, 1, 0, false),
+ FIELD_INFO("specres", ID_AA64ISAR1, SPECRES, false, 1, 0, false),
+
+ FIELD_INFO("el0", ID_AA64PFR0, EL0, false, 1, 0, false),
+ FIELD_INFO("el1", ID_AA64PFR0, EL1, false, 1, 0, false),
+ FIELD_INFO("el2", ID_AA64PFR0, EL2, false, 1, 0, false),
+ FIELD_INFO("el3", ID_AA64PFR0, EL3, false, 1, 0, false),
+ FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
+ FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
+ FIELD_INFO("gic", ID_AA64PFR0, GIC, false, 1, 0, false),
+ FIELD_INFO("ras", ID_AA64PFR0, RAS, false, 1, 0, false),
+ FIELD_INFO("sve", ID_AA64PFR0, SVE, false, 1, 0, false),
+
+ FIELD_INFO("bti", ID_AA64PFR1, BT, false, 1, 0, false),
+ FIELD_INFO("sbss", ID_AA64PFR1, SBSS, false, 1, 0, false),
+ FIELD_INFO("mte", ID_AA64PFR1, MTE, false, 1, 0, false),
+ FIELD_INFO("ras_frac", ID_AA64PFR1, RAS_FRAC, false, 1, 0, false),
+
+ FIELD_INFO("parange", ID_AA64MMFR0, PARANGE, false, 1, 0, false),
+ FIELD_INFO("asidbits", ID_AA64MMFR0, ASIDBITS, false, 1, 0, false),
+ FIELD_INFO("bigend", ID_AA64MMFR0, BIGEND, false, 1, 0, false),
+ FIELD_INFO("snsmem", ID_AA64MMFR0, SNSMEM, false, 1, 0, false),
+ FIELD_INFO("bigendel0", ID_AA64MMFR0, BIGENDEL0, false, 1, 0, false),
+ FIELD_INFO("tgran16", ID_AA64MMFR0, TGRAN16, false, 1, 0, false),
+ FIELD_INFO("tgran64", ID_AA64MMFR0, TGRAN64, false, 1, 0, false),
+ FIELD_INFO("tgran4", ID_AA64MMFR0, TGRAN4, false, 1, 0, false),
+ FIELD_INFO("tgran16_2", ID_AA64MMFR0, TGRAN16_2, false, 1, 0, false),
+ FIELD_INFO("tgran64_2", ID_AA64MMFR0, TGRAN64_2, false, 1, 0, false),
+ FIELD_INFO("tgran4_2", ID_AA64MMFR0, TGRAN4_2, false, 1, 0, false),
+ FIELD_INFO("exs", ID_AA64MMFR0, EXS, false, 1, 0, false),
+
+ FIELD_INFO("hafdbs", ID_AA64MMFR1, HAFDBS, false, 1, 0, false),
+ FIELD_INFO("vmidbits", ID_AA64MMFR1, VMIDBITS, false, 1, 0, false),
+ FIELD_INFO("vh", ID_AA64MMFR1, VH, false, 1, 0, false),
+ FIELD_INFO("hpds", ID_AA64MMFR1, HPDS, false, 1, 0, false),
+ FIELD_INFO("lo", ID_AA64MMFR1, LO, false, 1, 0, false),
+ FIELD_INFO("pan", ID_AA64MMFR1, PAN, false, 1, 0, false),
+ FIELD_INFO("specsei", ID_AA64MMFR1, SPECSEI, false, 1, 0, false),
+ FIELD_INFO("xnx", ID_AA64MMFR1, XNX, false, 1, 0, false),
+
+ FIELD_INFO("cnp", ID_AA64MMFR2, CNP, false, 1, 0, false),
+ FIELD_INFO("uao", ID_AA64MMFR2, UAO, false, 1, 0, false),
+ FIELD_INFO("lsm", ID_AA64MMFR2, LSM, false, 1, 0, false),
+ FIELD_INFO("iesb", ID_AA64MMFR2, IESB, false, 1, 0, false),
+ FIELD_INFO("varange", ID_AA64MMFR2, VARANGE, false, 1, 0, false),
+ FIELD_INFO("ccidx", ID_AA64MMFR2, CCIDX, false, 1, 0, false),
+ FIELD_INFO("nv", ID_AA64MMFR2, NV, false, 1, 0, false),
+ FIELD_INFO("st", ID_AA64MMFR2, ST, false, 1, 0, false),
+ FIELD_INFO("uscat", ID_AA64MMFR2, AT, false, 1, 0, false),
+ FIELD_INFO("ids", ID_AA64MMFR2, IDS, false, 1, 0, false),
+ FIELD_INFO("fwb", ID_AA64MMFR2, FWB, false, 1, 0, false),
+ FIELD_INFO("ttl", ID_AA64MMFR2, TTL, false, 1, 0, false),
+ FIELD_INFO("bbm", ID_AA64MMFR2, BBM, false, 1, 0, false),
+ FIELD_INFO("evt", ID_AA64MMFR2, EVT, false, 1, 0, false),
+ FIELD_INFO("e0pd", ID_AA64MMFR2, E0PD, false, 1, 0, false),
+
+ FIELD_INFO("copdbg", ID_DFR0, COPDBG, false, 1, 0, false),
+ FIELD_INFO("copsdbg", ID_DFR0, COPSDBG, false, 1, 0, false),
+ FIELD_INFO("mmapdbg", ID_DFR0, MMAPDBG, false, 1, 0, false),
+ FIELD_INFO("coptrc", ID_DFR0, COPTRC, false, 1, 0, false),
+ FIELD_INFO("mmaptrc", ID_DFR0, MMAPTRC, false, 1, 0, false),
+ FIELD_INFO("mprofdbg", ID_DFR0, MPROFDBG, false, 1, 0, false),
+ FIELD_INFO("perfmon", ID_DFR0, PERFMON, false, 1, 0, false),
+ FIELD_INFO("tracefilt", ID_DFR0, TRACEFILT, false, 1, 0, false),
+
+ {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH,
+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "pmull", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_TS_LENGTH,
+ .shift = R_ID_AA64ISAR0_TS_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "flagm2", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_DPB_LENGTH,
+ .shift = R_ID_AA64ISAR1_DPB_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "dcpodp", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH,
+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false,
+ },
+};
+
+static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+ CPUFeatureInfo *feat = opaque;
+ int field_value = feat->sign ? sextract64(cpu->isar.regs[feat->reg],
+ feat->shift, feat->length) :
+ extract64(cpu->isar.regs[feat->reg],
+ feat->shift, feat->length);
+ bool value = field_value >= feat->min_value;
+
+ visit_type_bool(v, name, &value, errp);
+}
+
+static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
+ CPUFeatureInfo *feat = opaque;
+ Error *local_err = NULL;
+ bool value;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_bool(v, name, &value, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (value) {
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
+ feat->shift, feat->length,
+ feat->min_value);
+ } else {
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
+ feat->shift, feat->length,
+ feat->ni_value);
+ }
+}
+
+static void arm_cpu_register_feature_props(ARMCPU *cpu)
+{
+ int i;
+ int num = ARRAY_SIZE(cpu_features);
+ ObjectProperty *op;
+ CPUARMState *env = &cpu->env;
+
+ for (i = 0; i < num; i++) {
+ if ((arm_feature(env, ARM_FEATURE_AARCH64) && cpu_features[i].is_32bit)
+ || (!arm_feature(env, ARM_FEATURE_AARCH64) &&
+ cpu_features[i].is_32bit)) {
+ continue;
+ }
+ op = object_property_find(OBJECT(cpu), cpu_features[i].name, NULL);
+ if (!op) {
+ object_property_add(OBJECT(cpu), cpu_features[i].name, "bool",
+ arm_cpu_get_bit_prop,
+ arm_cpu_set_bit_prop,
+ NULL, &cpu_features[i], &error_abort);
+ }
+ }
+}
+
void arm_cpu_post_init(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -1150,6 +1491,8 @@ void arm_cpu_post_init(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
&error_abort);
+
+ arm_cpu_register_feature_props(cpu);
}
static void arm_cpu_finalizefn(Object *obj)
--
2.25.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/Chuan-Zheng/qemu.git
git@gitee.com:Chuan-Zheng/qemu.git
Chuan-Zheng
qemu
qemu
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891