diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index b6f7e53b7c..3dac5766ca 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -595,13 +595,6 @@ static inline int pa_range(STE *ste) #define CD_A(x) extract32((x)->word[1], 14, 1) #define CD_AARCH64(x) extract32((x)->word[1], 9 , 1) -#define CDM_VALID(x) ((x)->word[0] & 0x1) - -static inline int is_cd_valid(SMMUv3State *s, STE *ste, CD *cd) -{ - return CD_VALID(cd); -} - /** * tg2granule - Decodes the CD translation granule size field according * to the ttbr in use diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index c56e6ec593..4fd6aeb18b 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1260,6 +1260,14 @@ static void xlnx_dp_init(Object *obj) fifo8_create(&s->tx_fifo, 16); } +static void xlnx_dp_finalize(Object *obj) +{ + XlnxDPState *s = XLNX_DP(obj); + + fifo8_destroy(&s->tx_fifo); + fifo8_destroy(&s->rx_fifo); +} + static void xlnx_dp_realize(DeviceState *dev, Error **errp) { XlnxDPState *s = XLNX_DP(dev); @@ -1359,6 +1367,7 @@ static const TypeInfo xlnx_dp_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(XlnxDPState), .instance_init = xlnx_dp_init, + .instance_finalize = xlnx_dp_finalize, .class_init = xlnx_dp_class_init, }; diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c index 714a742ba7..7c892f820f 100644 --- a/hw/net/npcm7xx_emc.c +++ b/hw/net/npcm7xx_emc.c @@ -702,7 +702,9 @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset, !(value & REG_MCMDR_RXON)) { emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA; } - if (!(value & REG_MCMDR_RXON)) { + if (value & REG_MCMDR_RXON) { + emc->rx_active = true; + } else { emc_halt_rx(emc, 0); } break; diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c index eed39917fe..d96002e1ee 100644 --- a/hw/timer/renesas_tmr.c +++ b/hw/timer/renesas_tmr.c @@ -146,6 +146,8 @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch) case CSS_CASCADING: tcnt[1] = tmr->tcnt[1]; break; + default: + g_assert_not_reached(); } switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) { case CSS_INTERNAL: @@ -159,6 +161,8 @@ static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch) case CSS_EXTERNAL: /* QEMU doesn't implement this */ tcnt[0] = tmr->tcnt[0]; break; + default: + g_assert_not_reached(); } } else { tcnt[0] = tmr->tcnt[0]; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 193a49ec7f..fe68f464b3 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -942,6 +942,7 @@ struct ARMCPU { uint64_t id_aa64mmfr2; uint64_t id_aa64dfr0; uint64_t id_aa64dfr1; + uint64_t reset_pmcr_el0; } isar; uint64_t midr; uint32_t revidr; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index f0a9e968c9..5d9d56a33c 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -141,6 +141,7 @@ static void aarch64_a57_initfn(Object *obj) cpu->gic_num_lrs = 4; cpu->gic_vpribits = 5; cpu->gic_vprebits = 5; + cpu->isar.reset_pmcr_el0 = 0x41013000; define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); } @@ -194,6 +195,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->gic_num_lrs = 4; cpu->gic_vpribits = 5; cpu->gic_vprebits = 5; + cpu->isar.reset_pmcr_el0 = 0x41033000; define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); } @@ -245,6 +247,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->gic_num_lrs = 4; cpu->gic_vpribits = 5; cpu->gic_vprebits = 5; + cpu->isar.reset_pmcr_el0 = 0x41023000; define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); } diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index 046e476f65..8252fd29f9 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -301,6 +301,7 @@ static void cortex_a8_initfn(Object *obj) cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */ cpu->reset_auxcr = 2; + cpu->isar.reset_pmcr_el0 = 0x41002000; define_arm_cp_regs(cpu, cortexa8_cp_reginfo); } @@ -373,6 +374,7 @@ static void cortex_a9_initfn(Object *obj) cpu->clidr = (1 << 27) | (1 << 24) | 3; cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */ + cpu->isar.reset_pmcr_el0 = 0x41093000; define_arm_cp_regs(cpu, cortexa9_cp_reginfo); } @@ -443,6 +445,7 @@ static void cortex_a7_initfn(Object *obj) cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ + cpu->isar.reset_pmcr_el0 = 0x41072000; define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */ } @@ -485,6 +488,7 @@ static void cortex_a15_initfn(Object *obj) cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ + cpu->isar.reset_pmcr_el0 = 0x410F3000; define_arm_cp_regs(cpu, cortexa15_cp_reginfo); } @@ -717,6 +721,7 @@ static void cortex_r5_initfn(Object *obj) cpu->isar.id_isar6 = 0x0; cpu->mp_is_up = true; cpu->pmsav7_dregion = 16; + cpu->isar.reset_pmcr_el0 = 0x41151800; define_arm_cp_regs(cpu, cortexr5_cp_reginfo); } diff --git a/target/arm/helper.c b/target/arm/helper.c index d9220be7c5..8fb6cc96e4 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -38,7 +38,6 @@ #endif #define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */ -#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */ #ifndef CONFIG_USER_ONLY @@ -1149,7 +1148,9 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { static inline uint32_t pmu_num_counters(CPUARMState *env) { - return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT; + ARMCPU *cpu = env_archcpu(env); + + return (cpu->isar.reset_pmcr_el0 & PMCRN_MASK) >> PMCRN_SHIFT; } /* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */ @@ -5753,13 +5754,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { .resetvalue = 0, .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write }, #endif - /* The only field of MDCR_EL2 that has a defined architectural reset value - * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N. - */ - { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, - .access = PL2_RW, .resetvalue = PMCR_NUM_COUNTERS, - .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), }, { .name = "HPFAR", .state = ARM_CP_STATE_AA32, .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, .access = PL2_RW, .accessfn = access_el3_aa32ns, @@ -6689,7 +6683,7 @@ static void define_pmu_regs(ARMCPU *cpu) * field as main ID register, and we implement four counters in * addition to the cycle count register. */ - unsigned int i, pmcrn = PMCR_NUM_COUNTERS; + unsigned int i, pmcrn = pmu_num_counters(&cpu->env); ARMCPRegInfo pmcr = { .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, .access = PL0_RW, @@ -6704,10 +6698,10 @@ static void define_pmu_regs(ARMCPU *cpu) .access = PL0_RW, .accessfn = pmreg_access, .type = ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr), - .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) | - PMCRLC, + .resetvalue = cpu->isar.reset_pmcr_el0, .writefn = pmcr_write, .raw_writefn = raw_write, }; + define_one_arm_cp_reg(cpu, &pmcr); define_one_arm_cp_reg(cpu, &pmcr64); for (i = 0; i < pmcrn; i++) { @@ -7825,6 +7819,17 @@ void register_cp_regs_for_features(ARMCPU *cpu) .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) }, REGINFO_SENTINEL }; + /* + * The only field of MDCR_EL2 that has a defined architectural reset + * value is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N. + */ + ARMCPRegInfo mdcr_el2 = { + .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL2_RW, .resetvalue = pmu_num_counters(env), + .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), + }; + define_one_arm_cp_reg(cpu, &mdcr_el2); define_arm_cp_regs(cpu, vpidr_regs); define_arm_cp_regs(cpu, el2_cp_reginfo); if (arm_feature(env, ARM_FEATURE_V8)) { diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index dff85f6db9..581335e49d 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -566,6 +566,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM64_SYS_REG(3, 0, 0, 7, 1)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2, ARM64_SYS_REG(3, 0, 0, 7, 2)); + err |= read_sys_reg64(fdarray[2], &ahcf->isar.reset_pmcr_el0, + ARM64_SYS_REG(3, 3, 9, 12, 0)); /* * Note that if AArch32 support is not present in the host, diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c index 7a28173195..9eec71d87c 100644 --- a/tests/qtest/npcm7xx_emc-test.c +++ b/tests/qtest/npcm7xx_emc-test.c @@ -492,9 +492,6 @@ static void enable_tx(QTestState *qts, const EMCModule *mod, mcmdr |= REG_MCMDR_TXON; emc_write(qts, mod, REG_MCMDR, mcmdr); } - - /* Prod the device to send the packet. */ - emc_write(qts, mod, REG_TSDR, 1); } static void emc_send_verify1(QTestState *qts, const EMCModule *mod, int fd, @@ -558,6 +555,9 @@ static void emc_send_verify(QTestState *qts, const EMCModule *mod, int fd, enable_tx(qts, mod, &desc[0], NUM_TX_DESCRIPTORS, desc_addr, with_irq ? REG_MIEN_ENTXINTR : 0); + /* Prod the device to send the packet. */ + emc_write(qts, mod, REG_TSDR, 1); + /* * It's problematic to observe the interrupt for each packet. * Instead just wait until all the packets go out. @@ -643,13 +643,10 @@ static void enable_rx(QTestState *qts, const EMCModule *mod, mcmdr |= REG_MCMDR_RXON | mcmdr_flags; emc_write(qts, mod, REG_MCMDR, mcmdr); } - - /* Prod the device to accept a packet. */ - emc_write(qts, mod, REG_RSDR, 1); } static void emc_recv_verify(QTestState *qts, const EMCModule *mod, int fd, - bool with_irq) + bool with_irq, bool pump_rsdr) { NPCM7xxEMCRxDesc desc[NUM_RX_DESCRIPTORS]; uint32_t desc_addr = DESC_ADDR; @@ -679,6 +676,15 @@ static void emc_recv_verify(QTestState *qts, const EMCModule *mod, int fd, enable_rx(qts, mod, &desc[0], NUM_RX_DESCRIPTORS, desc_addr, with_irq ? REG_MIEN_ENRXINTR : 0, 0); + /* + * If requested, prod the device to accept a packet. + * This isn't necessary, the linux driver doesn't do this. + * Test doing/not-doing this for robustness. + */ + if (pump_rsdr) { + emc_write(qts, mod, REG_RSDR, 1); + } + /* Send test packet to device's socket. */ ret = iov_send(fd, iov, 2, 0, sizeof(len) + sizeof(test)); g_assert_cmpint(ret, == , sizeof(test) + sizeof(len)); @@ -826,8 +832,14 @@ static void test_rx(gconstpointer test_data) qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic"); - emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/false); - emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/true); + emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/false, + /*pump_rsdr=*/false); + emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/false, + /*pump_rsdr=*/true); + emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/true, + /*pump_rsdr=*/false); + emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/true, + /*pump_rsdr=*/true); emc_test_ptle(qts, td->module, test_sockets[0]); qtest_quit(qts);