aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorTianrui Zhao <zhaotianrui@loongson.cn>2023-05-17 09:22:00 +0800
committerSong Gao <gaosong@loongson.cn>2023-06-16 17:58:46 +0800
commit758a7475663f36d0d411e9cb4199b6c543152f8a (patch)
tree624830723d62a446c81099fa3f53173c5d7c9a21 /hw/intc
parent8f30771ce61b0290fdb00b4cdbbc514723008a12 (diff)
hw/intc: Set physical cpuid route for LoongArch ipi device
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. Reviewed-by: Song Gao <gaosong@loongson.cn> Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20230613120552.2471420-3-zhaotianrui@loongson.cn>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/loongarch_ipi.c44
1 files changed, 37 insertions, 7 deletions
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);