hw/loongarch: DINTC add a MemoryRegion

the DINTC use [2fe00000-2ff00000) Memory.

Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-7-gaosong@loongson.cn>
This commit is contained in:
Song Gao 2025-09-16 20:21:04 +08:00
parent 3ff989d566
commit 07f3e5203a
5 changed files with 65 additions and 1 deletions

View file

@ -17,6 +17,24 @@
#include "trace.h"
#include "hw/qdev-properties.h"
static uint64_t loongarch_dintc_mem_read(void *opaque,
hwaddr addr, unsigned size)
{
return 0;
}
static void loongarch_dintc_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
return;
}
static const MemoryRegionOps loongarch_dintc_ops = {
.read = loongarch_dintc_mem_read,
.write = loongarch_dintc_mem_write,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void loongarch_dintc_realize(DeviceState *dev, Error **errp)
{
@ -39,6 +57,12 @@ static void loongarch_dintc_unrealize(DeviceState *dev)
static void loongarch_dintc_init(Object *obj)
{
LoongArchDINTCState *s = LOONGARCH_DINTC(obj);
SysBusDevice *shd = SYS_BUS_DEVICE(obj);
memory_region_init_io(&s->dintc_mmio, OBJECT(s), &loongarch_dintc_ops,
s, TYPE_LOONGARCH_DINTC, VIRT_DINTC_SIZE);
sysbus_init_mmio(shd, &s->dintc_mmio);
msi_nonbroken = true;
return;
}

View file

@ -28,6 +28,7 @@
#include "hw/intc/loongarch_extioi.h"
#include "hw/intc/loongarch_pch_pic.h"
#include "hw/intc/loongarch_pch_msi.h"
#include "hw/intc/loongarch_dintc.h"
#include "hw/pci-host/ls7a.h"
#include "hw/pci-host/gpex.h"
#include "hw/misc/unimp.h"
@ -386,7 +387,7 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
static void virt_irq_init(LoongArchVirtMachineState *lvms)
{
DeviceState *pch_pic, *pch_msi;
DeviceState *ipi, *extioi;
DeviceState *ipi, *extioi, *dintc;
SysBusDevice *d;
int i, start, num;
@ -432,6 +433,33 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
* +--------+ +---------+ +---------+
* | UARTs | | Devices | | Devices |
* +--------+ +---------+ +---------+
*
*
* Advanced Extended IRQ model
*
* +-----+ +---------------------------------+ +-------+
* | IPI | --> | CPUINTC | <-- | Timer |
* +-----+ +---------------------------------+ +-------+
* ^ ^ ^
* | | |
* +-------------+ +----------+ +---------+ +-------+
* | EIOINTC | | DINTC | | LIOINTC | <-- | UARTs |
* +-------------+ +----------+ +---------+ +-------+
* ^ ^ ^
* | | |
* +---------+ +---------+ |
* | PCH-PIC | | PCH-MSI | |
* +---------+ +---------+ |
* ^ ^ ^ |
* | | | |
* +---------+ +---------+ +---------+
* | Devices | | PCH-LPC | | Devices |
* +---------+ +---------+ +---------+
* ^
* |
* +---------+
* | Devices |
* +---------+
*/
/* Create IPI device */
@ -439,6 +467,14 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
lvms->ipi = ipi;
sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
/* Create DINTC device*/
if (virt_has_dmsi(lvms)) {
dintc = qdev_new(TYPE_LOONGARCH_DINTC);
lvms->dintc = dintc;
sysbus_realize_and_unref(SYS_BUS_DEVICE(dintc), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dintc), 0, VIRT_DINTC_BASE);
}
/* Create EXTIOI device */
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
lvms->extioi = extioi;

View file

@ -23,6 +23,7 @@ typedef struct DINTCCore {
struct LoongArchDINTCState {
SysBusDevice parent_obj;
MemoryRegion dintc_mmio;
DINTCCore *cpu;
uint32_t num_cpu;
};

View file

@ -89,6 +89,7 @@ struct LoongArchVirtMachineState {
unsigned int memmap_entries;
uint64_t misc_feature;
uint64_t misc_status;
DeviceState *dintc;
};
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")

View file

@ -24,6 +24,8 @@
#define VIRT_PCH_REG_BASE 0x10000000UL
#define VIRT_IOAPIC_REG_BASE (VIRT_PCH_REG_BASE)
#define VIRT_PCH_MSI_ADDR_LOW 0x2FF00000UL
#define VIRT_DINTC_SIZE 0x100000UL
#define VIRT_DINTC_BASE 0x2FE00000UL
#define VIRT_PCH_REG_SIZE 0x400
#define VIRT_PCH_MSI_SIZE 0x8