在 2026/11/3 9:26, Jonathan Cameron 写道:
> On Fri, 16 Oct 2026 17:47:05 +0800
> Jinjie Ruan <[email protected]> wrote:
>
>> 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]>
> Comment in here is fix the fixme ;)
>
> Otherwise looks fine to me and I think it is a wise
> decision to always allocate backing for the max sized bitmap
> rather than trying to do it dependent on what the width is
> for a particular instance.
>
>> ---
>> 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;
>
> Sanity check for whether the width is large enough would just be informational
> here but it would I think be nice to have.
Will add a Sanity check for the width.
>
>> + }
>> + 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 */
>
> Ah. Indeed, this is the thing the LLM was complaining about earlier. The
> width depends on how many partitions there are.
> Definitely need that enforced (and a log on going over it).
>
> Roughly speaking n such that (from the spec)
> When ((n * 32) + x) >= UInt(MPAMF_CPOR_IDR().CPBM_WD)
> is bad so either register out of range where n is the
> register offset and x is the bit in it. So shouldn't be too tricky to
> fix this.
Yes, the spec requires this, we should fix it.
>
>
>> + 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;
>> + }
>
--
Best regards,
Jinjie