On Fri, May 15, 2020 at 11:39 PM Anup Patel <anup.pa...@wdc.com> wrote: > > We extend CLINT emulation to allow multiple instances of CLINT in > a QEMU RISC-V machine. To achieve this, we remove first HART id > zero assumption from CLINT emulation. > > Signed-off-by: Anup Patel <anup.pa...@wdc.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > hw/riscv/sifive_clint.c | 20 ++++++++++++-------- > hw/riscv/sifive_e.c | 2 +- > hw/riscv/sifive_u.c | 2 +- > hw/riscv/spike.c | 6 +++--- > hw/riscv/virt.c | 2 +- > include/hw/riscv/sifive_clint.h | 7 ++++--- > 6 files changed, 22 insertions(+), 17 deletions(-) > > diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c > index e933d35092..7d713fd743 100644 > --- a/hw/riscv/sifive_clint.c > +++ b/hw/riscv/sifive_clint.c > @@ -78,7 +78,7 @@ static uint64_t sifive_clint_read(void *opaque, hwaddr > addr, unsigned size) > SiFiveCLINTState *clint = opaque; > if (addr >= clint->sip_base && > addr < clint->sip_base + (clint->num_harts << 2)) { > - size_t hartid = (addr - clint->sip_base) >> 2; > + size_t hartid = clint->hartid_base + ((addr - clint->sip_base) >> 2); > CPUState *cpu = qemu_get_cpu(hartid); > CPURISCVState *env = cpu ? cpu->env_ptr : NULL; > if (!env) { > @@ -91,7 +91,8 @@ static uint64_t sifive_clint_read(void *opaque, hwaddr > addr, unsigned size) > } > } else if (addr >= clint->timecmp_base && > addr < clint->timecmp_base + (clint->num_harts << 3)) { > - size_t hartid = (addr - clint->timecmp_base) >> 3; > + size_t hartid = clint->hartid_base + > + ((addr - clint->timecmp_base) >> 3); > CPUState *cpu = qemu_get_cpu(hartid); > CPURISCVState *env = cpu ? cpu->env_ptr : NULL; > if (!env) { > @@ -128,7 +129,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, > uint64_t value, > > if (addr >= clint->sip_base && > addr < clint->sip_base + (clint->num_harts << 2)) { > - size_t hartid = (addr - clint->sip_base) >> 2; > + size_t hartid = clint->hartid_base + ((addr - clint->sip_base) >> 2); > CPUState *cpu = qemu_get_cpu(hartid); > CPURISCVState *env = cpu ? cpu->env_ptr : NULL; > if (!env) { > @@ -141,7 +142,8 @@ static void sifive_clint_write(void *opaque, hwaddr addr, > uint64_t value, > return; > } else if (addr >= clint->timecmp_base && > addr < clint->timecmp_base + (clint->num_harts << 3)) { > - size_t hartid = (addr - clint->timecmp_base) >> 3; > + size_t hartid = clint->hartid_base + > + ((addr - clint->timecmp_base) >> 3); > CPUState *cpu = qemu_get_cpu(hartid); > CPURISCVState *env = cpu ? cpu->env_ptr : NULL; > if (!env) { > @@ -185,6 +187,7 @@ static const MemoryRegionOps sifive_clint_ops = { > }; > > static Property sifive_clint_properties[] = { > + DEFINE_PROP_UINT32("hartid-base", SiFiveCLINTState, hartid_base, 0), > DEFINE_PROP_UINT32("num-harts", SiFiveCLINTState, num_harts, 0), > DEFINE_PROP_UINT32("sip-base", SiFiveCLINTState, sip_base, 0), > DEFINE_PROP_UINT32("timecmp-base", SiFiveCLINTState, timecmp_base, 0), > @@ -226,13 +229,13 @@ type_init(sifive_clint_register_types) > /* > * Create CLINT device. > */ > -DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t > num_harts, > - uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base, > - bool provide_rdtime) > +DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, > + uint32_t hartid_base, uint32_t num_harts, uint32_t sip_base, > + uint32_t timecmp_base, uint32_t time_base, bool provide_rdtime) > { > int i; > for (i = 0; i < num_harts; i++) { > - CPUState *cpu = qemu_get_cpu(i); > + CPUState *cpu = qemu_get_cpu(hartid_base + i); > CPURISCVState *env = cpu ? cpu->env_ptr : NULL; > if (!env) { > continue; > @@ -246,6 +249,7 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr > size, uint32_t num_harts, > } > > DeviceState *dev = qdev_create(NULL, TYPE_SIFIVE_CLINT); > + qdev_prop_set_uint32(dev, "hartid-base", hartid_base); > qdev_prop_set_uint32(dev, "num-harts", num_harts); > qdev_prop_set_uint32(dev, "sip-base", sip_base); > qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base); > diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c > index b53109521e..1c3b37d0ba 100644 > --- a/hw/riscv/sifive_e.c > +++ b/hw/riscv/sifive_e.c > @@ -163,7 +163,7 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, > Error **errp) > SIFIVE_E_PLIC_CONTEXT_STRIDE, > memmap[SIFIVE_E_PLIC].size); > sifive_clint_create(memmap[SIFIVE_E_CLINT].base, > - memmap[SIFIVE_E_CLINT].size, ms->smp.cpus, > + memmap[SIFIVE_E_CLINT].size, 0, ms->smp.cpus, > SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false); > create_unimplemented_device("riscv.sifive.e.aon", > memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size); > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c > index bed10fcfa8..22997fbf13 100644 > --- a/hw/riscv/sifive_u.c > +++ b/hw/riscv/sifive_u.c > @@ -601,7 +601,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, > Error **errp) > sifive_uart_create(system_memory, memmap[SIFIVE_U_UART1].base, > serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ)); > sifive_clint_create(memmap[SIFIVE_U_CLINT].base, > - memmap[SIFIVE_U_CLINT].size, ms->smp.cpus, > + memmap[SIFIVE_U_CLINT].size, 0, ms->smp.cpus, > SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false); > > object_property_set_bool(OBJECT(&s->prci), true, "realized", &err); > diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c > index d0c4843712..d5e0103d89 100644 > --- a/hw/riscv/spike.c > +++ b/hw/riscv/spike.c > @@ -253,7 +253,7 @@ static void spike_board_init(MachineState *machine) > > /* Core Local Interruptor (timer and IPI) */ > sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, > - smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, > + 0, smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, > false); > } > > @@ -343,7 +343,7 @@ static void spike_v1_10_0_board_init(MachineState > *machine) > > /* Core Local Interruptor (timer and IPI) */ > sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, > - smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, > + 0, smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, > false); > } > > @@ -452,7 +452,7 @@ static void spike_v1_09_1_board_init(MachineState > *machine) > > /* Core Local Interruptor (timer and IPI) */ > sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, > - smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, > + 0, smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, > false); > > g_free(config_string); > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c > index daae3ebdbb..dcb8a83b35 100644 > --- a/hw/riscv/virt.c > +++ b/hw/riscv/virt.c > @@ -596,7 +596,7 @@ static void riscv_virt_board_init(MachineState *machine) > VIRT_PLIC_CONTEXT_STRIDE, > memmap[VIRT_PLIC].size); > sifive_clint_create(memmap[VIRT_CLINT].base, > - memmap[VIRT_CLINT].size, smp_cpus, > + memmap[VIRT_CLINT].size, 0, smp_cpus, > SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, true); > sifive_test_create(memmap[VIRT_TEST].base); > > diff --git a/include/hw/riscv/sifive_clint.h b/include/hw/riscv/sifive_clint.h > index 4a720bfece..9f5fb3d31d 100644 > --- a/include/hw/riscv/sifive_clint.h > +++ b/include/hw/riscv/sifive_clint.h > @@ -33,6 +33,7 @@ typedef struct SiFiveCLINTState { > > /*< public >*/ > MemoryRegion mmio; > + uint32_t hartid_base; > uint32_t num_harts; > uint32_t sip_base; > uint32_t timecmp_base; > @@ -40,9 +41,9 @@ typedef struct SiFiveCLINTState { > uint32_t aperture_size; > } SiFiveCLINTState; > > -DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t > num_harts, > - uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base, > - bool provide_rdtime); > +DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, > + uint32_t hartid_base, uint32_t num_harts, uint32_t sip_base, > + uint32_t timecmp_base, uint32_t time_base, bool provide_rdtime); > > enum { > SIFIVE_SIP_BASE = 0x0, > -- > 2.25.1 > >