From: Jinjie Ruan <[email protected]> Add the priority controls: MPAMF_PRI_IDR advertises a 2-bit INTPRI (0 = low) with no DSPRI, HAS_PRI_PART is set on the cache subtype, and MPAMCFG_PRI is readable and writable per selected internal PARTID, logging writes of DSPRI/INTPRI fields the IDR does not implement.
Signed-off-by: Jinjie Ruan <[email protected]> --- hw/arm/mpam.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/hw/arm/mpam.c b/hw/arm/mpam.c index 7c33ec4..94e517b 100644 --- a/hw/arm/mpam.c +++ b/hw/arm/mpam.c @@ -365,6 +365,13 @@ static uint64_t mpam_msc_read_reg(void *opaque, hwaddr offset, return mpamf->cpor_idr; case A_MPAMF_MBW_IDR: return mpamf->mbw_idr; + case A_MPAMF_PRI_IDR: + if (!FIELD_EX32(mpamf->idr, MPAMF_IDR, HAS_PRI_PART)) { + qemu_log_mask(LOG_UNIMP, + "MPAM: Unexpected read of PRI_IDR with no PRI PART support\n"); + return 0; + } + return mpamf->pri_idr; case A_MPAMF_PARTID_NRW_IDR: { return mpamf->partid_nrw_idr; } @@ -380,6 +387,8 @@ static uint64_t mpam_msc_read_reg(void *opaque, hwaddr offset, return mpamf->per_nrw_id[nrw_part_sel].cfg_mbw_min; case A_MPAMF_MPAMCFG_MBW_MAX: return mpamf->per_nrw_id[nrw_part_sel].cfg_mbw_max; + case A_MPAMF_MPAMCFG_PRI: + return mpamf->per_nrw_id[nrw_part_sel].cfg_pri; case A_MPAMF_MPAMCFG_MBW_PROP: return mpamf->per_nrw_id[nrw_part_sel].cfg_mbw_prop; case A_MPAMF_MPAMCFG_CPBM0... @@ -467,6 +476,24 @@ static void mpam_msc_write_reg(void *opaque, hwaddr offset, uint64_t value, } mpamf->per_nrw_id[nrw_part_sel].cfg_mbw_max = value; return; + case A_MPAMF_MPAMCFG_PRI: + if (!FIELD_EX32(mpamf->idr, MPAMF_IDR, HAS_PRI_PART)) { + qemu_log_mask(LOG_UNIMP, + "MPAM: Unexpected write to CFG_PRI when !HAS_PRI_PART\n"); + } else { + if (!FIELD_EX32(mpamf->pri_idr, MPAMF_PRI_IDR, HAS_DSPRI) && + FIELD_EX32(value, MPAMF_MPAMCFG_PRI, DSPRI)) { + qemu_log_mask(LOG_UNIMP, + "MPAM: Unexpected write to CFGP_PRI DSPRI when !HAS_DSPRI\n"); + } + if (!FIELD_EX32(mpamf->pri_idr, MPAMF_PRI_IDR, HAS_INTPRI) && + FIELD_EX32(value, MPAMF_MPAMCFG_PRI, INTPRI)) { + qemu_log_mask(LOG_UNIMP, + "MPAM: Unexpected write to CFGP_PRI INTPRI when !HAS_INTPRI\n"); + } + } + mpamf->per_nrw_id[nrw_part_sel].cfg_pri = value; + return; case A_MPAMF_MPAMCFG_MBW_PROP: if (value & ~MPAMF_MPAMCFG_MBW_PROP_WRITE_MASK) { qemu_log_mask(LOG_UNIMP, @@ -648,6 +675,7 @@ static void mpam_msc_cache_realize(DeviceState *dev, Error **errp) /* Cache specific bit */ mpamf->idr = FIELD_DP64(mpamf->idr, MPAMF_IDR, HAS_CPOR_PART, 1); + mpamf->idr = FIELD_DP64(mpamf->idr, MPAMF_IDR, HAS_PRI_PART, 1); mpamf->idr = FIELD_DP64(mpamf->idr, MPAMF_IDR, HAS_PARTID_NRW, s->num_int_partid < s->num_partid); @@ -665,6 +693,14 @@ static void mpam_msc_cache_realize(DeviceState *dev, Error **errp) mpamf->cpor_idr = FIELD_DP32(mpamf->cpor_idr, MPAMF_CPOR_IDR, CPBM_WD, MPAM_CACHE_PART); + /* Priority */ + mpamf->pri_idr = FIELD_DP32(mpamf->pri_idr, MPAMF_PRI_IDR, + HAS_INTPRI, 1); + mpamf->pri_idr = FIELD_DP32(mpamf->pri_idr, MPAMF_PRI_IDR, + INTPRI_0_IS_LOW, 1); + mpamf->pri_idr = FIELD_DP32(mpamf->pri_idr, MPAMF_PRI_IDR, + INTPRI_WD, 2); + if (s->num_int_partid < s->num_partid) { mpamf->partid_nrw_idr = FIELD_DP32(mpamf->partid_nrw_idr, MPAMF_PARTID_NRW_IDR, -- 2.43.0
