Message ID | 20230613120552.2471420-3-zhaotianrui@loongson.cn |
---|---|
State | New |
Headers | show |
Series | Add LoongArch cpu arch_id support | expand |
在 2023/6/13 下午8:05, Tianrui Zhao 写道: > LoongArch ipi device uses physical cpuid to route to different > vcpus rather logical cpuid, and the physical cpuid is the same > with cpuid in acpi dsdt and srat table. > > Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> > Signed-off-by: Song Gao <gaosong@loongson.cn> > --- > hw/intc/loongarch_ipi.c | 44 ++++++++++++++++++++++++++++++++++------- > hw/loongarch/virt.c | 1 + > target/loongarch/cpu.h | 2 ++ > 3 files changed, 40 insertions(+), 7 deletions(-) Reviewed-by: Song Gao <gaosong@loongson.cn> Thanks. Song Gao > diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c > index 3e45381652..67858b521c 100644 > --- a/hw/intc/loongarch_ipi.c > +++ b/hw/intc/loongarch_ipi.c > @@ -17,6 +17,8 @@ > #include "target/loongarch/internals.h" > #include "trace.h" > > +static void loongarch_ipi_writel(void *, hwaddr, uint64_t, unsigned); > + > static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) > { > IPICore *s = opaque; > @@ -75,13 +77,42 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) > data, MEMTXATTRS_UNSPECIFIED, NULL); > } > > +static int archid_cmp(const void *a, const void *b) > +{ > + CPUArchId *archid_a = (CPUArchId *)a; > + CPUArchId *archid_b = (CPUArchId *)b; > + > + return archid_a->arch_id - archid_b->arch_id; > +} > + > +static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id) > +{ > + CPUArchId apic_id, *found_cpu; > + > + apic_id.arch_id = id; > + found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus, > + ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus), > + archid_cmp); > + > + return found_cpu; > +} > + > +static CPUState *ipi_getcpu(int arch_id) > +{ > + MachineState *machine = MACHINE(qdev_get_machine()); > + CPUArchId *archid; > + > + archid = find_cpu_by_archid(machine, arch_id); > + return CPU(archid->cpu); > +} > + > static void ipi_send(uint64_t val) > { > uint32_t cpuid; > uint8_t vector; > - CPULoongArchState *env; > CPUState *cs; > LoongArchCPU *cpu; > + LoongArchIPI *s; > > cpuid = extract32(val, 16, 10); > if (cpuid >= LOONGARCH_MAX_CPUS) { > @@ -92,11 +123,10 @@ static void ipi_send(uint64_t val) > /* IPI status vector */ > vector = extract8(val, 0, 5); > > - cs = qemu_get_cpu(cpuid); > + cs = ipi_getcpu(cpuid); > cpu = LOONGARCH_CPU(cs); > - env = &cpu->env; > - address_space_stl(&env->address_space_iocsr, 0x1008, > - BIT(vector), MEMTXATTRS_UNSPECIFIED, NULL); > + s = LOONGARCH_IPI(cpu->env.ipistate); > + loongarch_ipi_writel(&s->ipi_core, CORE_SET_OFF, BIT(vector), 4); > } > > static void mail_send(uint64_t val) > @@ -114,7 +144,7 @@ static void mail_send(uint64_t val) > } > > addr = 0x1020 + (val & 0x1c); > - cs = qemu_get_cpu(cpuid); > + cs = ipi_getcpu(cpuid); > cpu = LOONGARCH_CPU(cs); > env = &cpu->env; > send_ipi_data(env, val, addr); > @@ -135,7 +165,7 @@ static void any_send(uint64_t val) > } > > addr = val & 0xffff; > - cs = qemu_get_cpu(cpuid); > + cs = ipi_getcpu(cpuid); > cpu = LOONGARCH_CPU(cs); > env = &cpu->env; > send_ipi_data(env, val, addr); > diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c > index ced5a862f8..17bc37bccd 100644 > --- a/hw/loongarch/virt.c > +++ b/hw/loongarch/virt.c > @@ -617,6 +617,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) > memory_region_add_subregion(&env->system_iocsr, APIC_BASE, > sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), > cpu)); > + env->ipistate = ipi; > } > > /* > diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h > index 1f37e36b7c..b23f38c3d5 100644 > --- a/target/loongarch/cpu.h > +++ b/target/loongarch/cpu.h > @@ -351,6 +351,8 @@ typedef struct CPUArchState { > MemoryRegion iocsr_mem; > bool load_elf; > uint64_t elf_address; > + /* Store ipistate to access from this struct */ > + DeviceState *ipistate; > #endif > } CPULoongArchState; >
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 3e45381652..67858b521c 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -17,6 +17,8 @@ #include "target/loongarch/internals.h" #include "trace.h" +static void loongarch_ipi_writel(void *, hwaddr, uint64_t, unsigned); + static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) { IPICore *s = opaque; @@ -75,13 +77,42 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) data, MEMTXATTRS_UNSPECIFIED, NULL); } +static int archid_cmp(const void *a, const void *b) +{ + CPUArchId *archid_a = (CPUArchId *)a; + CPUArchId *archid_b = (CPUArchId *)b; + + return archid_a->arch_id - archid_b->arch_id; +} + +static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id) +{ + CPUArchId apic_id, *found_cpu; + + apic_id.arch_id = id; + found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus, + ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus), + archid_cmp); + + return found_cpu; +} + +static CPUState *ipi_getcpu(int arch_id) +{ + MachineState *machine = MACHINE(qdev_get_machine()); + CPUArchId *archid; + + archid = find_cpu_by_archid(machine, arch_id); + return CPU(archid->cpu); +} + static void ipi_send(uint64_t val) { uint32_t cpuid; uint8_t vector; - CPULoongArchState *env; CPUState *cs; LoongArchCPU *cpu; + LoongArchIPI *s; cpuid = extract32(val, 16, 10); if (cpuid >= LOONGARCH_MAX_CPUS) { @@ -92,11 +123,10 @@ static void ipi_send(uint64_t val) /* IPI status vector */ vector = extract8(val, 0, 5); - cs = qemu_get_cpu(cpuid); + cs = ipi_getcpu(cpuid); cpu = LOONGARCH_CPU(cs); - env = &cpu->env; - address_space_stl(&env->address_space_iocsr, 0x1008, - BIT(vector), MEMTXATTRS_UNSPECIFIED, NULL); + s = LOONGARCH_IPI(cpu->env.ipistate); + loongarch_ipi_writel(&s->ipi_core, CORE_SET_OFF, BIT(vector), 4); } static void mail_send(uint64_t val) @@ -114,7 +144,7 @@ static void mail_send(uint64_t val) } addr = 0x1020 + (val & 0x1c); - cs = qemu_get_cpu(cpuid); + cs = ipi_getcpu(cpuid); cpu = LOONGARCH_CPU(cs); env = &cpu->env; send_ipi_data(env, val, addr); @@ -135,7 +165,7 @@ static void any_send(uint64_t val) } addr = val & 0xffff; - cs = qemu_get_cpu(cpuid); + cs = ipi_getcpu(cpuid); cpu = LOONGARCH_CPU(cs); env = &cpu->env; send_ipi_data(env, val, addr); diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index ced5a862f8..17bc37bccd 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -617,6 +617,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) memory_region_add_subregion(&env->system_iocsr, APIC_BASE, sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), cpu)); + env->ipistate = ipi; } /* diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 1f37e36b7c..b23f38c3d5 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -351,6 +351,8 @@ typedef struct CPUArchState { MemoryRegion iocsr_mem; bool load_elf; uint64_t elf_address; + /* Store ipistate to access from this struct */ + DeviceState *ipistate; #endif } CPULoongArchState;