diff mbox series

[v2,2/2] hw/intc: Set physical cpuid route for LoongArch ipi device

Message ID 20230613120552.2471420-3-zhaotianrui@loongson.cn (mailing list archive)
State New, archived
Headers show
Series Add LoongArch cpu arch_id support | expand

Commit Message

zhaotianrui June 13, 2023, 12:05 p.m. UTC
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(-)

Comments

gaosong June 16, 2023, 7:10 a.m. UTC | #1
在 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 mbox series

Patch

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;