From: Jinjie Ruan <[email protected]> Add the cache-portion controls: MPAMF_CPOR_IDR advertises the CPBM bitmap width (MPAM_CACHE_PART portions) and the cache subtype sets HAS_CPOR_PART, and the CPBM array registers become readable and writable per selected internal PARTID. Reads and writes of CPOR_IDR/CPBM on an MSC without CPOR support are logged and ignored.
Signed-off-by: Jinjie Ruan <[email protected]> --- hw/arm/mpam.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/hw/arm/mpam.c b/hw/arm/mpam.c index cce9355..2b1401e 100644 --- a/hw/arm/mpam.c +++ b/hw/arm/mpam.c @@ -356,6 +356,13 @@ static uint64_t mpam_msc_read_reg(void *opaque, hwaddr offset, return 0; } return mpamf->impl_idr; + case A_MPAMF_CPOR_IDR: + if (!FIELD_EX32(mpamf->idr, MPAMF_IDR, HAS_CPOR_PART)) { + qemu_log_mask(LOG_UNIMP, + "MPAM: Unexpected read of CPOR_IDR with no CPOR support\n"); + return 0; + } + return mpamf->cpor_idr; case A_MPAMF_PARTID_NRW_IDR: { return mpamf->partid_nrw_idr; } @@ -367,6 +374,19 @@ static uint64_t mpam_msc_read_reg(void *opaque, hwaddr offset, return mpamf->mbwumon_idr; case A_MPAMF_CFG_PART_SEL: return mpamf->cfg_part_sel; + case A_MPAMF_MPAMCFG_CPBM0... + (A_MPAMF_MPAMCFG_CPBM0 + ((MPAM_CACHE_PART + 31) / 32 - 1) * 4): + { + uint32_t array_offset; + + if (!FIELD_EX32(mpamf->idr, MPAMF_IDR, HAS_CPOR_PART)) { + qemu_log_mask(LOG_UNIMP, + "MPAM: Unexpected read of CPBM with no CPOR support\n"); + return 0; + } + array_offset = (offset - A_MPAMF_MPAMCFG_CPBM0) / sizeof(uint32_t); + return mpamf->per_nrw_id[nrw_part_sel].cfg_cpbm[array_offset]; + } default: qemu_log_mask(LOG_UNIMP, "MPAM: Unexpected read of %lx\n", offset); @@ -410,6 +430,21 @@ static void mpam_msc_write_reg(void *opaque, hwaddr offset, uint64_t value, mpamf = &s->mpamf[s->ris]; mpamf->cfg_part_sel = value; return; + case A_MPAMF_MPAMCFG_CPBM0... + (A_MPAMF_MPAMCFG_CPBM0 + ((MPAM_CACHE_PART + 31) / 32 - 1) * 4): + { + uint32_t array_offset; + + /* TODO: Figure out write mask to check this stays in write bits */ + if (!FIELD_EX32(mpamf->idr, MPAMF_IDR, HAS_CPOR_PART)) { + qemu_log_mask(LOG_UNIMP, + "MPAM: Unexpected write to CPMB when !HAS_CPORT_PART\n"); + return; + } + array_offset = (offset - A_MPAMF_MPAMCFG_CPBM0) / sizeof(uint32_t); + mpamf->per_nrw_id[nrw_part_sel].cfg_cpbm[array_offset] = value; + return; + } default: qemu_log_mask(LOG_UNIMP, "MPAM: Write to unexpected register Addr %lx Value=%lx\n", @@ -538,6 +573,8 @@ static void mpam_msc_cache_realize(DeviceState *dev, Error **errp) /* Need to implement for RME */ mpamf->idr = FIELD_DP64(mpamf->idr, MPAMF_IDR, SP4, 0); + /* Cache specific bit */ + mpamf->idr = FIELD_DP64(mpamf->idr, MPAMF_IDR, HAS_CPOR_PART, 1); mpamf->idr = FIELD_DP64(mpamf->idr, MPAMF_IDR, HAS_PARTID_NRW, s->num_int_partid < s->num_partid); @@ -551,6 +588,10 @@ static void mpam_msc_cache_realize(DeviceState *dev, Error **errp) mpamf->aidr = FIELD_DP32(mpamf->aidr, MPAMF_AIDR, ARCH_MINOR_REV, 1); mpamf->aidr = FIELD_DP32(mpamf->aidr, MPAMF_AIDR, ARCH_MAJOR_REV, 1); + /* Portion */ + mpamf->cpor_idr = FIELD_DP32(mpamf->cpor_idr, MPAMF_CPOR_IDR, CPBM_WD, + MPAM_CACHE_PART); + 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
