mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-target-arm-20220519' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue: * Implement FEAT_S2FWB * Implement FEAT_IDST * Drop unsupported_encoding() macro * hw/intc/arm_gicv3: Use correct number of priority bits for the CPU * Fix aarch64 debug register names * hw/adc/zynq-xadc: Use qemu_irq typedef * target/arm/helper.c: Delete stray obsolete comment * Make number of counters in PMCR follow the CPU * hw/arm/virt: Fix dtb nits * ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY * target/arm: Fix PAuth keys access checks for disabled SEL2 * Enable FEAT_HCX for -cpu max * Use FIELD definitions for CPACR, CPTR_ELx # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmKGf/kZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3h5fD/9+2ymBkwX9jIaaOooejZrJ # CUVCPL2w206eZbPihgE4snZcZdkGjteDhS30kipyJxFNaCE0d2qQLTMrPXQMKyGz # aqCcvSSdb+VraVOP7RpfqYrkzFsj/+K/F5NHn3Vf/T7ULLQJFk0JZ4UWnt7/rkhL # oaXGDm79JrFfMTWUu2AKtCGj132YXyH2YP7GmvYyIty3l+hR9a8mwx3EcFTewuEn # U7AZGZL2GfixGLZU/nNRcTu/BOlkdU6PM1BZoprs7HwbMXR1+pBCX6bwIXK35Q6/ # vCu8e/4+Hi4cd7nxRXqQ7+KuIdcEB+LwupN61othVUl2lnfQgNcvj2hhiWJkxdRI # gpRktnnf6QNWsQ7HWShB5o8HhDN9v82wMf8VSiN1XncN6oYWZSEAMa4NbV/1ditY # yolJww/onnre8A07xTzBqIXqKRViwUMltXSamUpuWx4UsSMOql/ktJYsXqSnJWP+ # cpTqQ+VQKj8cTotvDTnxKsOiI/RraSAzW1amle0x2Ff8I6AN45j1S3GuT9EyJJ3w # CabegyYloJChI2Gnqf5Pc+B108E/GwHlcsmgaN5FEjlGzluKa7Ii0D2f1Cey1tAl # iTqJ3dRFjhkll6a88TN47QRtDJadXp+PjQzzQxtEM1wXhJLWXTxocvBn0cGg2OnY # 4eMY1YLtD9neCnKvdZdw9g== # =F3ow # -----END PGP SIGNATURE----- # gpg: Signature made Thu 19 May 2022 10:35:53 AM PDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] * tag 'pull-target-arm-20220519' of https://git.linaro.org/people/pmaydell/qemu-arm: (22 commits) target/arm: Use FIELD definitions for CPACR, CPTR_ELx target/arm: Enable FEAT_HCX for -cpu max target/arm: Fix PAuth keys access checks for disabled SEL2 ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY hw/arm/virt: Drop #size-cells and #address-cells from gpio-keys dtb node hw/arm/virt: Fix incorrect non-secure flash dtb node name target/arm: Make number of counters in PMCR follow the CPU target/arm/helper.c: Delete stray obsolete comment hw/adc/zynq-xadc: Use qemu_irq typedef Fix aarch64 debug register names. hw/intc/arm_gicv3: Provide ich_num_aprs() hw/intc/arm_gicv3: Use correct number of priority bits for the CPU hw/intc/arm_gicv3: Support configurable number of physical priority bits hw/intc/arm_gicv3_kvm.c: Stop using GIC_MIN_BPR constant hw/intc/arm_gicv3: report correct PRIbits field in ICV_CTLR_EL1 hw/intc/arm_gicv3_cpuif: Handle CPUs that don't specify GICv3 parameters target/arm: Drop unsupported_encoding() macro target/arm: Implement FEAT_IDST target/arm: Enable FEAT_S2FWB for -cpu max target/arm: Implement FEAT_S2FWB ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
@@ -31,6 +31,7 @@ the following architecture extensions:
|
||||
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
|
||||
- FEAT_HPDS (Hierarchical permission disables)
|
||||
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
|
||||
- FEAT_IDST (ID space trap handling)
|
||||
- FEAT_IESB (Implicit error synchronization event)
|
||||
- FEAT_JSCVT (JavaScript conversion instructions)
|
||||
- FEAT_LOR (Limited ordering regions)
|
||||
@@ -52,6 +53,7 @@ the following architecture extensions:
|
||||
- FEAT_RAS (Reliability, availability, and serviceability)
|
||||
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
|
||||
- FEAT_RNG (Random number generator)
|
||||
- FEAT_S2FWB (Stage 2 forced Write-Back)
|
||||
- FEAT_SB (Speculation Barrier)
|
||||
- FEAT_SEL2 (Secure EL2)
|
||||
- FEAT_SHA1 (SHA1 instructions)
|
||||
|
||||
+2
-2
@@ -86,7 +86,7 @@ static void zynq_xadc_update_ints(ZynqXADCState *s)
|
||||
s->regs[INT_STS] |= INT_DFIFO_GTH;
|
||||
}
|
||||
|
||||
qemu_set_irq(s->qemu_irq, !!(s->regs[INT_STS] & ~s->regs[INT_MASK]));
|
||||
qemu_set_irq(s->irq, !!(s->regs[INT_STS] & ~s->regs[INT_MASK]));
|
||||
}
|
||||
|
||||
static void zynq_xadc_reset(DeviceState *d)
|
||||
@@ -262,7 +262,7 @@ static void zynq_xadc_init(Object *obj)
|
||||
memory_region_init_io(&s->iomem, obj, &xadc_ops, s, "zynq-xadc",
|
||||
ZYNQ_XADC_MMIO_SIZE);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
sysbus_init_irq(sbd, &s->qemu_irq);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_zynq_xadc = {
|
||||
|
||||
+1
-1
@@ -761,7 +761,7 @@ static void do_cpu_reset(void *opaque)
|
||||
env->cp15.scr_el3 |= SCR_ATA;
|
||||
}
|
||||
if (cpu_isar_feature(aa64_sve, cpu)) {
|
||||
env->cp15.cptr_el[3] |= CPTR_EZ;
|
||||
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
|
||||
}
|
||||
/* AArch64 kernels never boot in secure mode */
|
||||
assert(!info->secure_boot);
|
||||
|
||||
+1
-1
@@ -464,7 +464,7 @@ static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
s->freq = freq;
|
||||
|
||||
s->ptimer = ptimer_init(mv88w8618_timer_tick, s, PTIMER_POLICY_DEFAULT);
|
||||
s->ptimer = ptimer_init(mv88w8618_timer_tick, s, PTIMER_POLICY_LEGACY);
|
||||
}
|
||||
|
||||
static uint64_t mv88w8618_pit_read(void *opaque, hwaddr offset,
|
||||
|
||||
+1
-3
@@ -925,8 +925,6 @@ static void create_gpio_keys(char *fdt, DeviceState *pl061_dev,
|
||||
|
||||
qemu_fdt_add_subnode(fdt, "/gpio-keys");
|
||||
qemu_fdt_setprop_string(fdt, "/gpio-keys", "compatible", "gpio-keys");
|
||||
qemu_fdt_setprop_cell(fdt, "/gpio-keys", "#size-cells", 0);
|
||||
qemu_fdt_setprop_cell(fdt, "/gpio-keys", "#address-cells", 1);
|
||||
|
||||
qemu_fdt_add_subnode(fdt, "/gpio-keys/poweroff");
|
||||
qemu_fdt_setprop_string(fdt, "/gpio-keys/poweroff",
|
||||
@@ -1195,7 +1193,7 @@ static void virt_flash_fdt(VirtMachineState *vms,
|
||||
qemu_fdt_setprop_string(ms->fdt, nodename, "secure-status", "okay");
|
||||
g_free(nodename);
|
||||
|
||||
nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
|
||||
nodename = g_strdup_printf("/flash@%" PRIx64, flashbase + flashsize);
|
||||
qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash");
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
|
||||
|
||||
+3
-1
@@ -41,7 +41,9 @@
|
||||
#include "hw/virtio/virtio-pci.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
|
||||
GlobalProperty hw_compat_7_0[] = {};
|
||||
GlobalProperty hw_compat_7_0[] = {
|
||||
{ "arm-gicv3-common", "force-8-bit-prio", "on" },
|
||||
};
|
||||
const size_t hw_compat_7_0_len = G_N_ELEMENTS(hw_compat_7_0);
|
||||
|
||||
GlobalProperty hw_compat_6_2[] = {
|
||||
|
||||
@@ -552,7 +552,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
st->dma = s;
|
||||
st->nr = i;
|
||||
st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
|
||||
st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_LEGACY);
|
||||
ptimer_transaction_begin(st->ptimer);
|
||||
ptimer_set_freq(st->ptimer, s->freqhz);
|
||||
ptimer_transaction_commit(st->ptimer);
|
||||
|
||||
@@ -666,7 +666,7 @@ static void xlnx_csu_dma_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
|
||||
|
||||
s->src_timer = ptimer_init(xlnx_csu_dma_src_timeout_hit,
|
||||
s, PTIMER_POLICY_DEFAULT);
|
||||
s, PTIMER_POLICY_LEGACY);
|
||||
|
||||
s->attr = MEMTXATTRS_UNSPECIFIED;
|
||||
|
||||
|
||||
@@ -563,6 +563,11 @@ static Property arm_gicv3_common_properties[] = {
|
||||
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
|
||||
DEFINE_PROP_BOOL("has-lpi", GICv3State, lpi_enable, 0),
|
||||
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
|
||||
/*
|
||||
* Compatibility property: force 8 bits of physical priority, even
|
||||
* if the CPU being emulated should have fewer.
|
||||
*/
|
||||
DEFINE_PROP_BOOL("force-8-bit-prio", GICv3State, force_8bit_prio, 0),
|
||||
DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
|
||||
redist_region_count, qdev_prop_uint32, uint32_t),
|
||||
DEFINE_PROP_LINK("sysmem", GICv3State, dma, TYPE_MEMORY_REGION,
|
||||
|
||||
+159
-66
@@ -49,6 +49,14 @@ static inline int icv_min_vbpr(GICv3CPUState *cs)
|
||||
return 7 - cs->vprebits;
|
||||
}
|
||||
|
||||
static inline int ich_num_aprs(GICv3CPUState *cs)
|
||||
{
|
||||
/* Return the number of virtual APR registers (1, 2, or 4) */
|
||||
int aprmax = 1 << (cs->vprebits - 5);
|
||||
assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
|
||||
return aprmax;
|
||||
}
|
||||
|
||||
/* Simple accessor functions for LR fields */
|
||||
static uint32_t ich_lr_vintid(uint64_t lr)
|
||||
{
|
||||
@@ -145,9 +153,7 @@ static int ich_highest_active_virt_prio(GICv3CPUState *cs)
|
||||
* in the ICH Active Priority Registers.
|
||||
*/
|
||||
int i;
|
||||
int aprmax = 1 << (cs->vprebits - 5);
|
||||
|
||||
assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
|
||||
int aprmax = ich_num_aprs(cs);
|
||||
|
||||
for (i = 0; i < aprmax; i++) {
|
||||
uint32_t apr = cs->ich_apr[GICV3_G0][i] |
|
||||
@@ -657,7 +663,7 @@ static uint64_t icv_ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
* should match the ones reported in ich_vtr_read().
|
||||
*/
|
||||
value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
|
||||
(7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
|
||||
((cs->vpribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
|
||||
|
||||
if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM) {
|
||||
value |= ICC_CTLR_EL1_EOIMODE;
|
||||
@@ -787,6 +793,36 @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
return intid;
|
||||
}
|
||||
|
||||
static uint32_t icc_fullprio_mask(GICv3CPUState *cs)
|
||||
{
|
||||
/*
|
||||
* Return a mask word which clears the unimplemented priority bits
|
||||
* from a priority value for a physical interrupt. (Not to be confused
|
||||
* with the group priority, whose mask depends on the value of BPR
|
||||
* for the interrupt group.)
|
||||
*/
|
||||
return ~0U << (8 - cs->pribits);
|
||||
}
|
||||
|
||||
static inline int icc_min_bpr(GICv3CPUState *cs)
|
||||
{
|
||||
/* The minimum BPR for the physical interface. */
|
||||
return 7 - cs->prebits;
|
||||
}
|
||||
|
||||
static inline int icc_min_bpr_ns(GICv3CPUState *cs)
|
||||
{
|
||||
return icc_min_bpr(cs) + 1;
|
||||
}
|
||||
|
||||
static inline int icc_num_aprs(GICv3CPUState *cs)
|
||||
{
|
||||
/* Return the number of APR registers (1, 2, or 4) */
|
||||
int aprmax = 1 << MAX(cs->prebits - 5, 0);
|
||||
assert(aprmax <= ARRAY_SIZE(cs->icc_apr[0]));
|
||||
return aprmax;
|
||||
}
|
||||
|
||||
static int icc_highest_active_prio(GICv3CPUState *cs)
|
||||
{
|
||||
/* Calculate the current running priority based on the set bits
|
||||
@@ -794,14 +830,14 @@ static int icc_highest_active_prio(GICv3CPUState *cs)
|
||||
*/
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs->icc_apr[0]); i++) {
|
||||
for (i = 0; i < icc_num_aprs(cs); i++) {
|
||||
uint32_t apr = cs->icc_apr[GICV3_G0][i] |
|
||||
cs->icc_apr[GICV3_G1][i] | cs->icc_apr[GICV3_G1NS][i];
|
||||
|
||||
if (!apr) {
|
||||
continue;
|
||||
}
|
||||
return (i * 32 + ctz32(apr)) << (GIC_MIN_BPR + 1);
|
||||
return (i * 32 + ctz32(apr)) << (icc_min_bpr(cs) + 1);
|
||||
}
|
||||
/* No current active interrupts: return idle priority */
|
||||
return 0xff;
|
||||
@@ -980,7 +1016,7 @@ static void icc_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
|
||||
trace_gicv3_icc_pmr_write(gicv3_redist_affid(cs), value);
|
||||
|
||||
value &= 0xff;
|
||||
value &= icc_fullprio_mask(cs);
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env) &&
|
||||
(env->cp15.scr_el3 & SCR_FIQ)) {
|
||||
@@ -1004,7 +1040,7 @@ static void icc_activate_irq(GICv3CPUState *cs, int irq)
|
||||
*/
|
||||
uint32_t mask = icc_gprio_mask(cs, cs->hppi.grp);
|
||||
int prio = cs->hppi.prio & mask;
|
||||
int aprbit = prio >> 1;
|
||||
int aprbit = prio >> (8 - cs->prebits);
|
||||
int regno = aprbit / 32;
|
||||
int regbit = aprbit % 32;
|
||||
|
||||
@@ -1162,7 +1198,7 @@ static void icc_drop_prio(GICv3CPUState *cs, int grp)
|
||||
*/
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs->icc_apr[grp]); i++) {
|
||||
for (i = 0; i < icc_num_aprs(cs); i++) {
|
||||
uint64_t *papr = &cs->icc_apr[grp][i];
|
||||
|
||||
if (!*papr) {
|
||||
@@ -1303,9 +1339,7 @@ static int icv_drop_prio(GICv3CPUState *cs)
|
||||
* 32 bits are actually relevant.
|
||||
*/
|
||||
int i;
|
||||
int aprmax = 1 << (cs->vprebits - 5);
|
||||
|
||||
assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
|
||||
int aprmax = ich_num_aprs(cs);
|
||||
|
||||
for (i = 0; i < aprmax; i++) {
|
||||
uint64_t *papr0 = &cs->ich_apr[GICV3_G0][i];
|
||||
@@ -1590,7 +1624,7 @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
return;
|
||||
}
|
||||
|
||||
minval = (grp == GICV3_G1NS) ? GIC_MIN_BPR_NS : GIC_MIN_BPR;
|
||||
minval = (grp == GICV3_G1NS) ? icc_min_bpr_ns(cs) : icc_min_bpr(cs);
|
||||
if (value < minval) {
|
||||
value = minval;
|
||||
}
|
||||
@@ -2171,19 +2205,19 @@ static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
|
||||
cs->icc_ctlr_el1[GICV3_S] = ICC_CTLR_EL1_A3V |
|
||||
(1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
|
||||
(7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
|
||||
((cs->pribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
|
||||
cs->icc_ctlr_el1[GICV3_NS] = ICC_CTLR_EL1_A3V |
|
||||
(1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
|
||||
(7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
|
||||
((cs->pribits - 1) << ICC_CTLR_EL1_PRIBITS_SHIFT);
|
||||
cs->icc_pmr_el1 = 0;
|
||||
cs->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
|
||||
cs->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
|
||||
cs->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR_NS;
|
||||
cs->icc_bpr[GICV3_G0] = icc_min_bpr(cs);
|
||||
cs->icc_bpr[GICV3_G1] = icc_min_bpr(cs);
|
||||
cs->icc_bpr[GICV3_G1NS] = icc_min_bpr_ns(cs);
|
||||
memset(cs->icc_apr, 0, sizeof(cs->icc_apr));
|
||||
memset(cs->icc_igrpen, 0, sizeof(cs->icc_igrpen));
|
||||
cs->icc_ctlr_el3 = ICC_CTLR_EL3_NDS | ICC_CTLR_EL3_A3V |
|
||||
(1 << ICC_CTLR_EL3_IDBITS_SHIFT) |
|
||||
(7 << ICC_CTLR_EL3_PRIBITS_SHIFT);
|
||||
((cs->pribits - 1) << ICC_CTLR_EL3_PRIBITS_SHIFT);
|
||||
|
||||
memset(cs->ich_apr, 0, sizeof(cs->ich_apr));
|
||||
cs->ich_hcr_el2 = 0;
|
||||
@@ -2238,27 +2272,6 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_fiq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_fiq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_fiq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
/* All the ICC_AP1R*_EL1 registers are banked */
|
||||
{ .name = "ICC_AP1R0_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 0,
|
||||
@@ -2267,27 +2280,6 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP1R1_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 1,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_irq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP1R2_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 2,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_irq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP1R3_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 3,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_irq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_DIR_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 1,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
@@ -2430,6 +2422,54 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const ARMCPRegInfo gicv3_cpuif_icc_apxr1_reginfo[] = {
|
||||
{ .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_fiq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP1R1_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 1,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_irq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
};
|
||||
|
||||
static const ARMCPRegInfo gicv3_cpuif_icc_apxr23_reginfo[] = {
|
||||
{ .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_fiq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_fiq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP1R2_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 2,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_irq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
{ .name = "ICC_AP1R3_EL1", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 3,
|
||||
.type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
.access = PL1_RW, .accessfn = gicv3_irq_access,
|
||||
.readfn = icc_ap_read,
|
||||
.writefn = icc_ap_write,
|
||||
},
|
||||
};
|
||||
|
||||
static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
@@ -2755,6 +2795,16 @@ void gicv3_init_cpuif(GICv3State *s)
|
||||
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
|
||||
GICv3CPUState *cs = &s->cpu[i];
|
||||
|
||||
/*
|
||||
* If the CPU doesn't define a GICv3 configuration, probably because
|
||||
* in real hardware it doesn't have one, then we use default values
|
||||
* matching the one used by most Arm CPUs. This applies to:
|
||||
* cpu->gic_num_lrs
|
||||
* cpu->gic_vpribits
|
||||
* cpu->gic_vprebits
|
||||
* cpu->gic_pribits
|
||||
*/
|
||||
|
||||
/* Note that we can't just use the GICv3CPUState as an opaque pointer
|
||||
* in define_arm_cp_regs_with_opaque(), because when we're called back
|
||||
* it might be with code translated by CPU 0 but run by CPU 1, in
|
||||
@@ -2763,13 +2813,56 @@ void gicv3_init_cpuif(GICv3State *s)
|
||||
* get back to the GICv3CPUState from the CPUARMState.
|
||||
*/
|
||||
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||||
if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
|
||||
&& cpu->gic_num_lrs) {
|
||||
|
||||
/*
|
||||
* The CPU implementation specifies the number of supported
|
||||
* bits of physical priority. For backwards compatibility
|
||||
* of migration, we have a compat property that forces use
|
||||
* of 8 priority bits regardless of what the CPU really has.
|
||||
*/
|
||||
if (s->force_8bit_prio) {
|
||||
cs->pribits = 8;
|
||||
} else {
|
||||
cs->pribits = cpu->gic_pribits ?: 5;
|
||||
}
|
||||
|
||||
/*
|
||||
* The GICv3 has separate ID register fields for virtual priority
|
||||
* and preemption bit values, but only a single ID register field
|
||||
* for the physical priority bits. The preemption bit count is
|
||||
* always the same as the priority bit count, except that 8 bits
|
||||
* of priority means 7 preemption bits. We precalculate the
|
||||
* preemption bits because it simplifies the code and makes the
|
||||
* parallels between the virtual and physical bits of the GIC
|
||||
* a bit clearer.
|
||||
*/
|
||||
cs->prebits = cs->pribits;
|
||||
if (cs->prebits == 8) {
|
||||
cs->prebits--;
|
||||
}
|
||||
/*
|
||||
* Check that CPU code defining pribits didn't violate
|
||||
* architectural constraints our implementation relies on.
|
||||
*/
|
||||
g_assert(cs->pribits >= 4 && cs->pribits <= 8);
|
||||
|
||||
/*
|
||||
* gicv3_cpuif_reginfo[] defines ICC_AP*R0_EL1; add definitions
|
||||
* for ICC_AP*R{1,2,3}_EL1 if the prebits value requires them.
|
||||
*/
|
||||
if (cs->prebits >= 6) {
|
||||
define_arm_cp_regs(cpu, gicv3_cpuif_icc_apxr1_reginfo);
|
||||
}
|
||||
if (cs->prebits == 7) {
|
||||
define_arm_cp_regs(cpu, gicv3_cpuif_icc_apxr23_reginfo);
|
||||
}
|
||||
|
||||
if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
|
||||
int j;
|
||||
|
||||
cs->num_list_regs = cpu->gic_num_lrs;
|
||||
cs->vpribits = cpu->gic_vpribits;
|
||||
cs->vprebits = cpu->gic_vprebits;
|
||||
cs->num_list_regs = cpu->gic_num_lrs ?: 4;
|
||||
cs->vpribits = cpu->gic_vpribits ?: 5;
|
||||
cs->vprebits = cpu->gic_vprebits ?: 5;
|
||||
|
||||
/* Check against architectural constraints: getting these
|
||||
* wrong would be a bug in the CPU code defining these,
|
||||
|
||||
+13
-3
@@ -673,9 +673,19 @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
s = c->gic;
|
||||
|
||||
c->icc_pmr_el1 = 0;
|
||||
c->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
|
||||
c->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
|
||||
c->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR;
|
||||
/*
|
||||
* Architecturally the reset value of the ICC_BPR registers
|
||||
* is UNKNOWN. We set them all to 0 here; when the kernel
|
||||
* uses these values to program the ICH_VMCR_EL2 fields that
|
||||
* determine the guest-visible ICC_BPR register values, the
|
||||
* hardware's "writing a value less than the minimum sets
|
||||
* the field to the minimum value" behaviour will result in
|
||||
* them effectively resetting to the correct minimum value
|
||||
* for the host GIC.
|
||||
*/
|
||||
c->icc_bpr[GICV3_G0] = 0;
|
||||
c->icc_bpr[GICV3_G1] = 0;
|
||||
c->icc_bpr[GICV3_G1NS] = 0;
|
||||
|
||||
c->icc_sre_el1 = 0x7;
|
||||
memset(c->icc_apr, 0, sizeof(c->icc_apr));
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
|
||||
m5206_timer_state *s;
|
||||
|
||||
s = g_new0(m5206_timer_state, 1);
|
||||
s->timer = ptimer_init(m5206_timer_trigger, s, PTIMER_POLICY_DEFAULT);
|
||||
s->timer = ptimer_init(m5206_timer_trigger, s, PTIMER_POLICY_LEGACY);
|
||||
s->irq = irq;
|
||||
m5206_timer_reset(s);
|
||||
return s;
|
||||
|
||||
+1
-1
@@ -197,7 +197,7 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
|
||||
/* Timers. */
|
||||
for (i = 0; i < 2; i++) {
|
||||
s = g_new0(m5208_timer_state, 1);
|
||||
s->timer = ptimer_init(m5208_timer_trigger, s, PTIMER_POLICY_DEFAULT);
|
||||
s->timer = ptimer_init(m5208_timer_trigger, s, PTIMER_POLICY_LEGACY);
|
||||
memory_region_init_io(&s->iomem, NULL, &m5208_timer_ops, s,
|
||||
"m5208-timer", 0x00004000);
|
||||
memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
|
||||
|
||||
@@ -1079,7 +1079,7 @@ static void xlnx_zynqmp_can_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
/* Allocate a new timer. */
|
||||
s->can_timer = ptimer_init(xlnx_zynqmp_can_ptimer_cb, s,
|
||||
PTIMER_POLICY_DEFAULT);
|
||||
PTIMER_POLICY_LEGACY);
|
||||
|
||||
ptimer_transaction_begin(s->can_timer);
|
||||
|
||||
|
||||
@@ -393,7 +393,7 @@ static void etsec_realize(DeviceState *dev, Error **errp)
|
||||
object_get_typename(OBJECT(dev)), dev->id, etsec);
|
||||
qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
|
||||
|
||||
etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_DEFAULT);
|
||||
etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_LEGACY);
|
||||
ptimer_transaction_begin(etsec->ptimer);
|
||||
ptimer_set_freq(etsec->ptimer, 100);
|
||||
ptimer_transaction_commit(etsec->ptimer);
|
||||
|
||||
+1
-1
@@ -1363,7 +1363,7 @@ static void lan9118_realize(DeviceState *dev, Error **errp)
|
||||
s->pmt_ctrl = 1;
|
||||
s->txp = &s->tx_packet;
|
||||
|
||||
s->timer = ptimer_init(lan9118_tick, s, PTIMER_POLICY_DEFAULT);
|
||||
s->timer = ptimer_init(lan9118_tick, s, PTIMER_POLICY_LEGACY);
|
||||
ptimer_transaction_begin(s->timer);
|
||||
ptimer_set_freq(s->timer, 10000);
|
||||
ptimer_set_limit(s->timer, 0xffff, 1);
|
||||
|
||||
@@ -564,14 +564,14 @@ static void exynos4210_rtc_init(Object *obj)
|
||||
Exynos4210RTCState *s = EXYNOS4210_RTC(obj);
|
||||
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
|
||||
|
||||
s->ptimer = ptimer_init(exynos4210_rtc_tick, s, PTIMER_POLICY_DEFAULT);
|
||||
s->ptimer = ptimer_init(exynos4210_rtc_tick, s, PTIMER_POLICY_LEGACY);
|
||||
ptimer_transaction_begin(s->ptimer);
|
||||
ptimer_set_freq(s->ptimer, RTC_BASE_FREQ);
|
||||
exynos4210_rtc_update_freq(s, 0);
|
||||
ptimer_transaction_commit(s->ptimer);
|
||||
|
||||
s->ptimer_1Hz = ptimer_init(exynos4210_rtc_1Hz_tick,
|
||||
s, PTIMER_POLICY_DEFAULT);
|
||||
s, PTIMER_POLICY_LEGACY);
|
||||
ptimer_transaction_begin(s->ptimer_1Hz);
|
||||
ptimer_set_freq(s->ptimer_1Hz, RTC_BASE_FREQ);
|
||||
ptimer_transaction_commit(s->ptimer_1Hz);
|
||||
|
||||
@@ -275,7 +275,7 @@ static void a10_pit_init(Object *obj)
|
||||
|
||||
tc->container = s;
|
||||
tc->index = i;
|
||||
s->timer[i] = ptimer_init(a10_pit_timer_cb, tc, PTIMER_POLICY_DEFAULT);
|
||||
s->timer[i] = ptimer_init(a10_pit_timer_cb, tc, PTIMER_POLICY_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ static void altera_timer_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
t->ptimer = ptimer_init(timer_hit, t, PTIMER_POLICY_DEFAULT);
|
||||
t->ptimer = ptimer_init(timer_hit, t, PTIMER_POLICY_LEGACY);
|
||||
ptimer_transaction_begin(t->ptimer);
|
||||
ptimer_set_freq(t->ptimer, t->freq_hz);
|
||||
ptimer_transaction_commit(t->ptimer);
|
||||
|
||||
@@ -180,7 +180,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
|
||||
s->freq = freq;
|
||||
s->control = TIMER_CTRL_IE;
|
||||
|
||||
s->timer = ptimer_init(arm_timer_tick, s, PTIMER_POLICY_DEFAULT);
|
||||
s->timer = ptimer_init(arm_timer_tick, s, PTIMER_POLICY_LEGACY);
|
||||
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_arm_timer, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user