Reviewed-by: Clément Chigot <chi...@adacore.com>

On Tue, Mar 25, 2025 at 1:39 PM Philippe Mathieu-Daudé
<phi...@linaro.org> wrote:
>
> Keep CPUSPARCState for architectural fields, move Leon3
> hardware specific fields to SPARCCPU.
>
> Reset the Leon3 specific 'cache_control' field in
> leon3_cpu_reset() instead of sparc_cpu_reset_hold().
>
> Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org>
> ---
>  target/sparc/cpu.h          | 10 +++++-----
>  hw/sparc/leon3.c            | 35 ++++++++++++++++++-----------------
>  target/sparc/cpu.c          |  1 -
>  target/sparc/int32_helper.c |  8 ++++++--
>  target/sparc/ldst_helper.c  | 12 ++++++------
>  5 files changed, 35 insertions(+), 31 deletions(-)
>
> diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
> index 462bcb6c0e6..abb71c314dc 100644
> --- a/target/sparc/cpu.h
> +++ b/target/sparc/cpu.h
> @@ -543,11 +543,6 @@ struct CPUArchState {
>  #define SOFTINT_REG_MASK (SOFTINT_STIMER|SOFTINT_INTRMASK|SOFTINT_TIMER)
>  #endif
>      sparc_def_t def;
> -
> -    /* Leon3 */
> -    DeviceState *irq_manager;
> -    void (*qemu_irq_ack)(CPUSPARCState *env, int intno);
> -    uint32_t cache_control;
>  };
>
>  /**
> @@ -560,6 +555,11 @@ struct ArchCPU {
>      CPUState parent_obj;
>
>      CPUSPARCState env;
> +
> +    /* Leon3 */
> +    DeviceState *irq_manager;
> +    void (*qemu_irq_ack)(SPARCCPU *cpu, int intno);
> +    uint32_t cache_control;
>  };
>
>  /**
> diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
> index 0aeaad3becc..06966861744 100644
> --- a/hw/sparc/leon3.c
> +++ b/hw/sparc/leon3.c
> @@ -152,6 +152,7 @@ static void leon3_cpu_reset(void *opaque)
>      int id = info->id;
>      ResetData *s = container_of(info, ResetData, info[id]);
>      CPUState *cpu = CPU(s->info[id].cpu);
> +    SPARCCPU *scpu = SPARC_CPU(cpu);
>      CPUSPARCState *env = cpu_env(cpu);
>
>      cpu_reset(cpu);
> @@ -159,41 +160,41 @@ static void leon3_cpu_reset(void *opaque)
>      cpu->halted = cpu->cpu_index != 0;
>      env->pc = s->entry;
>      env->npc = s->entry + 4;
> +    scpu->cache_control = 0;
>  }
>
> -static void leon3_cache_control_int(CPUSPARCState *env)
> +static void leon3_cache_control_int(SPARCCPU *cpu)
>  {
>      uint32_t state = 0;
>
> -    if (env->cache_control & CACHE_CTRL_IF) {
> +    if (cpu->cache_control & CACHE_CTRL_IF) {
>          /* Instruction cache state */
> -        state = env->cache_control & CACHE_STATE_MASK;
> +        state = cpu->cache_control & CACHE_STATE_MASK;
>          if (state == CACHE_ENABLED) {
>              state = CACHE_FROZEN;
>              trace_int_helper_icache_freeze();
>          }
>
> -        env->cache_control &= ~CACHE_STATE_MASK;
> -        env->cache_control |= state;
> +        cpu->cache_control &= ~CACHE_STATE_MASK;
> +        cpu->cache_control |= state;
>      }
>
> -    if (env->cache_control & CACHE_CTRL_DF) {
> +    if (cpu->cache_control & CACHE_CTRL_DF) {
>          /* Data cache state */
> -        state = (env->cache_control >> 2) & CACHE_STATE_MASK;
> +        state = (cpu->cache_control >> 2) & CACHE_STATE_MASK;
>          if (state == CACHE_ENABLED) {
>              state = CACHE_FROZEN;
>              trace_int_helper_dcache_freeze();
>          }
>
> -        env->cache_control &= ~(CACHE_STATE_MASK << 2);
> -        env->cache_control |= (state << 2);
> +        cpu->cache_control &= ~(CACHE_STATE_MASK << 2);
> +        cpu->cache_control |= (state << 2);
>      }
>  }
>
> -static void leon3_irq_ack(CPUSPARCState *env, int intno)
> +static void leon3_irq_ack(SPARCCPU *cpu, int intno)
>  {
> -    CPUState *cpu = CPU(env_cpu(env));
> -    grlib_irqmp_ack(env->irq_manager, cpu->cpu_index, intno);
> +    grlib_irqmp_ack(cpu->irq_manager, CPU(cpu)->cpu_index, intno);
>  }
>
>  /*
> @@ -248,10 +249,10 @@ static void leon3_start_cpu(void *opaque, int n, int 
> level)
>      async_run_on_cpu(cs, leon3_start_cpu_async_work, RUN_ON_CPU_NULL);
>  }
>
> -static void leon3_irq_manager(CPUSPARCState *env, int intno)
> +static void leon3_irq_manager(SPARCCPU *cpu, int intno)
>  {
> -    leon3_irq_ack(env, intno);
> -    leon3_cache_control_int(env);
> +    leon3_irq_ack(cpu, intno);
> +    leon3_cache_control_int(cpu);
>  }
>
>  static void leon3_generic_hw_init(MachineState *machine)
> @@ -320,8 +321,8 @@ static void leon3_generic_hw_init(MachineState *machine)
>          qdev_connect_gpio_out_named(irqmpdev, "grlib-irq", i,
>                                      qdev_get_gpio_in_named(DEVICE(cpu),
>                                                             "pil", 0));
> -        env->irq_manager = irqmpdev;
> -        env->qemu_irq_ack = leon3_irq_manager;
> +        cpu->irq_manager = irqmpdev;
> +        cpu->qemu_irq_ack = leon3_irq_manager;
>      }
>
>      sysbus_mmio_map(SYS_BUS_DEVICE(irqmpdev), 0, LEON3_IRQMP_OFFSET);
> diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
> index 37406227cb7..d62ad6c4db2 100644
> --- a/target/sparc/cpu.c
> +++ b/target/sparc/cpu.c
> @@ -78,7 +78,6 @@ static void sparc_cpu_reset_hold(Object *obj, ResetType 
> type)
>      env->pc = 0;
>      env->npc = env->pc + 4;
>  #endif
> -    env->cache_control = 0;
>      cpu_put_fsr(env, 0);
>  }
>
> diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
> index f0266061023..a902702559d 100644
> --- a/target/sparc/int32_helper.c
> +++ b/target/sparc/int32_helper.c
> @@ -168,8 +168,12 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>
>  #if !defined(CONFIG_USER_ONLY)
>      /* IRQ acknowledgment */
> -    if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
> -        env->qemu_irq_ack(env, intno);
> +    if ((intno & ~15) == TT_EXTINT) {
> +        SPARCCPU *cpu = env_archcpu(env);
> +
> +        if (cpu->qemu_irq_ack != NULL) {
> +            cpu->qemu_irq_ack(cpu, intno);
> +        }
>      }
>  #endif
>  }
> diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
> index d4de32d3c48..0a11360ccaf 100644
> --- a/target/sparc/ldst_helper.c
> +++ b/target/sparc/ldst_helper.c
> @@ -513,7 +513,7 @@ static void sparc_raise_mmu_fault(CPUState *cs, hwaddr 
> addr,
>
>  /* Leon3 cache control */
>
> -static void leon3_cache_control_st(CPUSPARCState *env, target_ulong addr,
> +static void leon3_cache_control_st(SPARCCPU *cpu, target_ulong addr,
>                                     uint64_t val, int size)
>  {
>      DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64 ", size:%d\n",
> @@ -534,7 +534,7 @@ static void leon3_cache_control_st(CPUSPARCState *env, 
> target_ulong addr,
>          val &= ~CACHE_CTRL_IP;
>          val &= ~CACHE_CTRL_DP;
>
> -        env->cache_control = val;
> +        cpu->cache_control = val;
>          break;
>      case 0x04:              /* Instruction cache configuration */
>      case 0x08:              /* Data cache configuration */
> @@ -546,7 +546,7 @@ static void leon3_cache_control_st(CPUSPARCState *env, 
> target_ulong addr,
>      };
>  }
>
> -static uint64_t leon3_cache_control_ld(CPUSPARCState *env, target_ulong addr,
> +static uint64_t leon3_cache_control_ld(SPARCCPU *cpu, target_ulong addr,
>                                         int size)
>  {
>      uint64_t ret = 0;
> @@ -558,7 +558,7 @@ static uint64_t leon3_cache_control_ld(CPUSPARCState 
> *env, target_ulong addr,
>
>      switch (addr) {
>      case 0x00:              /* Cache control */
> -        ret = env->cache_control;
> +        ret = cpu->cache_control;
>          break;
>
>          /* Configuration registers are read and only always keep those
> @@ -599,7 +599,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
> addr,
>          case 0x08:          /* Leon3 Instruction Cache config */
>          case 0x0C:          /* Leon3 Date Cache config */
>              if (env->def.features & CPU_FEATURE_CACHE_CTRL) {
> -                ret = leon3_cache_control_ld(env, addr, size);
> +                ret = leon3_cache_control_ld(env_archcpu(env), addr, size);
>              } else {
>                  qemu_log_mask(LOG_UNIMP,
>                                "%08x: unimplemented access size: %d\n", addr,
> @@ -819,7 +819,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, 
> uint64_t val,
>          case 0x08:          /* Leon3 Instruction Cache config */
>          case 0x0C:          /* Leon3 Date Cache config */
>              if (env->def.features & CPU_FEATURE_CACHE_CTRL) {
> -                leon3_cache_control_st(env, addr, val, size);
> +                leon3_cache_control_st(env_archcpu(env), addr, val, size);
>              } else {
>                  qemu_log_mask(LOG_UNIMP,
>                                "%08x: unimplemented access size: %d\n", addr,
> --
> 2.47.1
>

Reply via email to