loongarch: add a direct interrupt controller device

Add Loongarch direct interrupt controller device base Definition.

Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-5-gaosong@loongson.cn>
This commit is contained in:
Song Gao 2025-09-16 20:21:02 +08:00
parent 86f4c80ab4
commit 4d4baab241
5 changed files with 108 additions and 0 deletions

View file

@ -109,3 +109,6 @@ config LOONGARCH_PCH_MSI
config LOONGARCH_EXTIOI
bool
config LOONGARCH_DINTC
bool

68
hw/intc/loongarch_dintc.c Normal file
View file

@ -0,0 +1,68 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* QEMU LoongArch direct interrupt controller.
*
* Copyright (C) 2025 Loongson Technology Corporation Limited
*/
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/intc/loongarch_pch_msi.h"
#include "hw/intc/loongarch_pch_pic.h"
#include "hw/intc/loongarch_dintc.h"
#include "hw/pci/msi.h"
#include "hw/misc/unimp.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "hw/qdev-properties.h"
static void loongarch_dintc_realize(DeviceState *dev, Error **errp)
{
LoongArchDINTCClass *lac = LOONGARCH_DINTC_GET_CLASS(dev);
Error *local_err = NULL;
lac->parent_realize(dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
return;
}
static void loongarch_dintc_unrealize(DeviceState *dev)
{
return;
}
static void loongarch_dintc_init(Object *obj)
{
return;
}
static void loongarch_dintc_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
LoongArchDINTCClass *lac = LOONGARCH_DINTC_CLASS(klass);
dc->unrealize = loongarch_dintc_unrealize;
device_class_set_parent_realize(dc, loongarch_dintc_realize,
&lac->parent_realize);
}
static const TypeInfo loongarch_dintc_info = {
.name = TYPE_LOONGARCH_DINTC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LoongArchDINTCState),
.instance_init = loongarch_dintc_init,
.class_init = loongarch_dintc_class_init,
};
static void loongarch_dintc_register_types(void)
{
type_register_static(&loongarch_dintc_info);
}
type_init(loongarch_dintc_register_types)

View file

@ -80,3 +80,4 @@ specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_
specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c', 'loongarch_extioi_common.c'))
specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_LOONGARCH_EXTIOI'],
if_true: files('loongarch_extioi_kvm.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_DINTC', if_true: files('loongarch_dintc.c'))

View file

@ -15,6 +15,7 @@ config LOONGARCH_VIRT
select LOONGARCH_PCH_PIC
select LOONGARCH_PCH_MSI
select LOONGARCH_EXTIOI
select LOONGARCH_DINTC
select LS7A_RTC
select SMBIOS
select ACPI_CPU_HOTPLUG

View file

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* LoongArch direct interrupt controller definitions
*
* Copyright (C) 2025 Loongson Technology Corporation Limited
*/
#include "qom/object.h"
#include "hw/sysbus.h"
#include "hw/loongarch/virt.h"
#define NR_VECTORS 256
#define TYPE_LOONGARCH_DINTC "loongarch_dintc"
OBJECT_DECLARE_TYPE(LoongArchDINTCState, LoongArchDINTCClass, LOONGARCH_DINTC)
typedef struct DINTCCore {
CPUState *cpu;
qemu_irq parent_irq;
uint64_t arch_id;
} DINTCCore;
struct LoongArchDINTCState {
SysBusDevice parent_obj;
DINTCCore *cpu;
uint32_t num_cpu;
};
struct LoongArchDINTCClass {
SysBusDeviceClass parent_class;
DeviceRealize parent_realize;
DeviceUnrealize parent_unrealize;
};