Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
zhaotianrui-loongson authored and gaosong-loongson committed Jun 16, 2023
1 parent 8f30771 commit 758a747
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
44 changes: 37 additions & 7 deletions hw/intc/loongarch_ipi.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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)
Expand All @@ -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);
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions hw/loongarch/virt.c
Expand Up @@ -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;
}

/*
Expand Down
2 changes: 2 additions & 0 deletions target/loongarch/cpu.h
Expand Up @@ -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;

Expand Down

0 comments on commit 758a747

Please sign in to comment.