diff options
author | Bibo Mao <maobibo@loongson.cn> | 2025-01-20 12:02:30 +0800 |
---|---|---|
committer | Bibo Mao <maobibo@loongson.cn> | 2025-03-05 09:39:17 +0800 |
commit | 54492213e6a2be203afff03098a188a0a2413fc9 (patch) | |
tree | 94a07da17f381bbefdccf09bdb98b322f2ca7f4a /hw/intc | |
parent | 9d71149a64f0ab051575a3f534e80918a3ca8610 (diff) | |
download | qemu-54492213e6a2be203afff03098a188a0a2413fc9.zip qemu-54492213e6a2be203afff03098a188a0a2413fc9.tar.gz qemu-54492213e6a2be203afff03098a188a0a2413fc9.tar.bz2 |
hw/intc/loongarch_ipi: Implment cpu hotplug interface
Add logic cpu allocation and cpu mapping with cpu hotplug interface.
When cpu is added, connect ipi gpio irq to CPU IRQ_IPI irq pin.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/loongarch_ipi.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 90bbb7a..b10641d 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -49,6 +49,22 @@ static int loongarch_cpu_by_arch_id(LoongsonIPICommonState *lics, return MEMTX_ERROR; } +static IPICore *loongarch_ipi_get_cpu(LoongsonIPICommonState *lics, + DeviceState *dev) +{ + CPUClass *k = CPU_GET_CLASS(dev); + uint64_t arch_id = k->get_arch_id(CPU(dev)); + int i; + + for (i = 0; i < lics->num_cpu; i++) { + if (lics->cpu[i].arch_id == arch_id) { + return &lics->cpu[i]; + } + } + + return NULL; +} + static void loongarch_ipi_realize(DeviceState *dev, Error **errp) { LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(dev); @@ -80,25 +96,48 @@ static void loongarch_ipi_realize(DeviceState *dev, Error **errp) static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { + LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(hotplug_dev); Object *obj = OBJECT(dev); + IPICore *core; + int index; if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) { warn_report("LoongArch extioi: Invalid %s device type", object_get_typename(obj)); return; } + + core = loongarch_ipi_get_cpu(lics, dev); + if (!core) { + return; + } + + core->cpu = CPU(dev); + index = core - lics->cpu; + + /* connect ipi irq to cpu irq */ + qdev_connect_gpio_out(DEVICE(lics), index, qdev_get_gpio_in(dev, IRQ_IPI)); } static void loongarch_ipi_cpu_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { + LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(hotplug_dev); Object *obj = OBJECT(dev); + IPICore *core; if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) { warn_report("LoongArch extioi: Invalid %s device type", object_get_typename(obj)); return; } + + core = loongarch_ipi_get_cpu(lics, dev); + if (!core) { + return; + } + + core->cpu = NULL; } static void loongarch_ipi_class_init(ObjectClass *klass, void *data) |