mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 01:03:55 -06:00
hw/loongarch/virt: CPU irq line connection improvement
Interrupt controller extioi and ipi connect to CPU with irq line method. With command -smp x, -device la464-loongarch-cpu, smp.cpus is not accurate for all possible CPU objects, possible_cpu_arch_ids() is used. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Bibo Mao <maobibo@loongson.cn>
This commit is contained in:
parent
2d2c37c492
commit
456739ce43
2 changed files with 38 additions and 24 deletions
|
@ -318,14 +318,43 @@ static void virt_devices_init(DeviceState *pch_pic,
|
||||||
lvms->platform_bus_dev = create_platform_bus(pch_pic);
|
lvms->platform_bus_dev = create_platform_bus(pch_pic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
|
||||||
|
{
|
||||||
|
int num, pin;
|
||||||
|
MachineState *ms = MACHINE(lvms);
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||||
|
const CPUArchIdList *possible_cpus;
|
||||||
|
CPUState *cs;
|
||||||
|
|
||||||
|
/* cpu nodes */
|
||||||
|
possible_cpus = mc->possible_cpu_arch_ids(ms);
|
||||||
|
for (num = 0; num < possible_cpus->len; num++) {
|
||||||
|
cs = possible_cpus->cpus[num].cpu;
|
||||||
|
if (cs == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* connect ipi irq to cpu irq */
|
||||||
|
qdev_connect_gpio_out(lvms->ipi, num,
|
||||||
|
qdev_get_gpio_in(DEVICE(cs), IRQ_IPI));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* connect ext irq to the cpu irq
|
||||||
|
* cpu_pin[9:2] <= intc_pin[7:0]
|
||||||
|
*/
|
||||||
|
for (pin = 0; pin < LS3A_INTC_IP; pin++) {
|
||||||
|
qdev_connect_gpio_out(lvms->extioi, (num * LS3A_INTC_IP + pin),
|
||||||
|
qdev_get_gpio_in(DEVICE(cs), pin + 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||||
{
|
{
|
||||||
MachineState *ms = MACHINE(lvms);
|
DeviceState *pch_pic, *pch_msi;
|
||||||
DeviceState *pch_pic, *pch_msi, *cpudev;
|
|
||||||
DeviceState *ipi, *extioi;
|
DeviceState *ipi, *extioi;
|
||||||
SysBusDevice *d;
|
SysBusDevice *d;
|
||||||
CPUState *cpu_state;
|
int i, start, num;
|
||||||
int cpu, pin, i, start, num;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extended IRQ model.
|
* Extended IRQ model.
|
||||||
|
@ -373,6 +402,7 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||||
|
|
||||||
/* Create IPI device */
|
/* Create IPI device */
|
||||||
ipi = qdev_new(TYPE_LOONGARCH_IPI);
|
ipi = qdev_new(TYPE_LOONGARCH_IPI);
|
||||||
|
lvms->ipi = ipi;
|
||||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
||||||
|
|
||||||
/* IPI iocsr memory region */
|
/* IPI iocsr memory region */
|
||||||
|
@ -381,16 +411,9 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||||
memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
|
memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
|
||||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
|
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
|
||||||
|
|
||||||
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
|
||||||
cpu_state = qemu_get_cpu(cpu);
|
|
||||||
cpudev = DEVICE(cpu_state);
|
|
||||||
|
|
||||||
/* connect ipi irq to cpu irq */
|
|
||||||
qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create EXTIOI device */
|
/* Create EXTIOI device */
|
||||||
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
|
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
|
||||||
|
lvms->extioi = extioi;
|
||||||
if (virt_is_veiointc_enabled(lvms)) {
|
if (virt_is_veiointc_enabled(lvms)) {
|
||||||
qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
|
qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
|
||||||
}
|
}
|
||||||
|
@ -402,18 +425,7 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
|
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
virt_cpu_irq_init(lvms);
|
||||||
* connect ext irq to the cpu irq
|
|
||||||
* cpu_pin[9:2] <= intc_pin[7:0]
|
|
||||||
*/
|
|
||||||
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
|
||||||
cpudev = DEVICE(qemu_get_cpu(cpu));
|
|
||||||
for (pin = 0; pin < LS3A_INTC_IP; pin++) {
|
|
||||||
qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
|
|
||||||
qdev_get_gpio_in(cpudev, pin + 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pch_pic = qdev_new(TYPE_LOONGARCH_PIC);
|
pch_pic = qdev_new(TYPE_LOONGARCH_PIC);
|
||||||
num = VIRT_PCH_PIC_IRQ_NUM;
|
num = VIRT_PCH_PIC_IRQ_NUM;
|
||||||
qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
|
qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
|
||||||
|
|
|
@ -60,6 +60,8 @@ struct LoongArchVirtMachineState {
|
||||||
MemoryRegion iocsr_mem;
|
MemoryRegion iocsr_mem;
|
||||||
AddressSpace as_iocsr;
|
AddressSpace as_iocsr;
|
||||||
struct loongarch_boot_info bootinfo;
|
struct loongarch_boot_info bootinfo;
|
||||||
|
DeviceState *ipi;
|
||||||
|
DeviceState *extioi;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue