Loongarch ipi is added herei, it inherits from class TYPE_LOONGSON_IPI_COMMON, and two interfaces get_iocsr_as() and cpu_by_arch_id() are added for Loongarch 3A5000 machine. It can be used when ipi is emulated in userspace with kvm mode.
Signed-off-by: Bibo Mao <maob...@loongson.cn> --- hw/intc/loongarch_ipi.c | 80 +++++++++++++++++++++++++++++++++ include/hw/intc/loongarch_ipi.h | 33 ++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 hw/intc/loongarch_ipi.c create mode 100644 include/hw/intc/loongarch_ipi.h diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c new file mode 100644 index 0000000000..91689c35c0 --- /dev/null +++ b/hw/intc/loongarch_ipi.c @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Loongarch ipi interrupt support + * + * Copyright (C) 2024 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "hw/boards.h" +#include "hw/sysbus.h" +#include "hw/intc/loongarch_ipi.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "exec/address-spaces.h" +#include "migration/vmstate.h" +#include "target/loongarch/cpu.h" +#include "trace.h" + +static AddressSpace *get_iocsr_as(CPUState *cpu) +{ + return LOONGARCH_CPU(cpu)->env.address_space_iocsr; +} + +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 *get_cpu_by_archid(int64_t arch_id) +{ + MachineState *machine = MACHINE(qdev_get_machine()); + CPUArchId *archid; + + archid = find_cpu_by_archid(machine, arch_id); + if (archid) { + return CPU(archid->cpu); + } + + return NULL; +} + +static void loongarch_ipi_class_init(ObjectClass *klass, void *data) +{ + LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass); + + licc->get_iocsr_as = get_iocsr_as; + licc->cpu_by_arch_id = get_cpu_by_archid; +} + +static const TypeInfo loongarch_ipi_info = { + .name = TYPE_LOONGARCH_IPI, + .parent = TYPE_LOONGSON_IPI_COMMON, + .instance_size = sizeof(LoongarchIPIState), + .class_size = sizeof(LoongarchIPIClass), + .class_init = loongarch_ipi_class_init, +}; + +static void loongarch_ipi_register_types(void) +{ + type_register_static(&loongarch_ipi_info); +} + +type_init(loongarch_ipi_register_types) diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h new file mode 100644 index 0000000000..451bbcff5c --- /dev/null +++ b/include/hw/intc/loongarch_ipi.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Loongarch ipi interrupt header files + * + * Copyright (C) 2024 Loongson Technology Corporation Limited + */ + +#ifndef HW_LOONGARCH_IPI_H +#define HW_LOONGARCH_IPI_H + +#include "qom/object.h" +#include "hw/intc/loongson_ipi_common.h" +#include "hw/sysbus.h" + +#define TYPE_LOONGARCH_IPI "loongarch_ipi" +typedef struct LoongarchIPIClass LoongarchIPIClass; +typedef struct LoongarchIPIState LoongarchIPIState; +DECLARE_OBJ_CHECKERS(LoongarchIPIState, LoongarchIPIClass, + LOONGARCH_IPI, TYPE_LOONGARCH_IPI) + +struct LoongarchIPIState { + LoongsonIPICommonState parent_obj; +}; + +struct LoongarchIPIClass { + /*< private >*/ + LoongsonIPICommonClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; +}; + +#endif -- 2.39.3