On Mon, 19 Jan 2026 18:27:30 +0100
Cornelia Huck <[email protected]> wrote:

> For some registers, we do not have a single ID register, but actually
> an array of values (e.g. CCSIDR_EL1, where the actual value is
> determined by whatever CSSELR_EL1 points to.) If we want to avoid
> using a different way to handle registers like that for every
> instance, we should provide some kind of infrastructure. Therefore,
> add accessors {GET,SET}_IDREG_DEMUX that are similar to the accessors
> we already use for regular ID registers.
> 
> Signed-off-by: Cornelia Huck <[email protected]>
> ---
>  target/arm/cpu-sysregs.h |  5 +++++
>  target/arm/cpu.h         | 20 ++++++++++++++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
> index 7877a3b06a8e..31f82c6a0afc 100644
> --- a/target/arm/cpu-sysregs.h
> +++ b/target/arm/cpu-sysregs.h
> @@ -35,6 +35,11 @@ typedef enum ARMSysRegs {
>  
>  #undef DEF
>  
> +/* ID registers that vary based upon another register */
> +typedef enum ARMIDRegisterDemuxIdx {
> +    NUM_ID_DEMUX_IDX,
> +} ARMIDRegisterDemuxIdx;
> +
>  extern const uint32_t id_register_sysreg[NUM_ID_IDX];
>  
>  int get_sysreg_idx(ARMSysRegs sysreg);
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 08b7d3fb936a..f7bd19f26fbd 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -905,6 +905,25 @@ typedef struct {
>          i_->idregs[REG ## _EL1_IDX];                                    \
>      })
>  
> +#define SET_IDREG_DEMUX(ISAR, REG, INDEX, VALUE)                        \
> +    ({                                                                  \
> +        ARMISARegisters *i_ = (ISAR);                                   \
> +        i_->idregs_demux[REG ## _EL1_DEMUX_IDX][INDEX] = VALUE;         \
> +    })
> +
> +#define GET_IDREG_DEMUX(ISAR, REG, INDEX)                               \
> +    ({                                                                  \
> +        ARMISARegisters *i_ = (ISAR);                                   \
> +        i_->idregs_demux[REG ## _EL1_DEMUX_IDX][INDEX];                 \
> +    })
> +
> +#define COPY_IDREG_DEMUX(ISAR, REG, FROM_INDEX, TO_INDEX)               \
> +    ({                                                                  \
> +        ARMISARegisters *i_ = (ISAR);                                   \
> +        i_->idregs_demux[REG ## _EL1_DEMUX_IDX][TO_INDEX] =             \
> +            i_->idregs_demux[REG ## _EL1_DEMUX_IDX][FROM_INDEX];        \
> +    })
> +
>  /**
>   * ARMCPU:
>   * @env: #CPUARMState
> @@ -1083,6 +1102,7 @@ struct ArchCPU {
>          uint32_t dbgdevid1;
>          uint64_t reset_pmcr_el0;
>          uint64_t idregs[NUM_ID_IDX];
> +        uint64_t idregs_demux[NUM_ID_DEMUX_IDX][16];
Hi,

Trivial, but I'd like a comment on why 16. I assume because that's
the biggest you've seen so far (8 levels, 2 types for CCSIDR)
Just good to have a bread crumb here for future readers.

Otherwise seems reasonable to me.
>      } isar;
>      uint64_t midr;
>      uint32_t revidr;


Reply via email to