1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * QEMU Loongson 7A1000 msi interrupt controller.
5 * Copyright (C) 2021 Loongson Technology Corporation Limited
8 #include "qemu/osdep.h"
11 #include "hw/intc/loongarch_pch_msi.h"
12 #include "hw/intc/loongarch_pch_pic.h"
13 #include "hw/pci/msi.h"
14 #include "hw/misc/unimp.h"
15 #include "migration/vmstate.h"
18 static uint64_t loongarch_msi_mem_read(void *opaque
, hwaddr addr
, unsigned size
)
23 static void loongarch_msi_mem_write(void *opaque
, hwaddr addr
,
24 uint64_t val
, unsigned size
)
26 LoongArchPCHMSI
*s
= LOONGARCH_PCH_MSI(opaque
);
27 int irq_num
= val
& 0xff;
29 trace_loongarch_msi_set_irq(irq_num
);
30 assert(irq_num
< PCH_MSI_IRQ_NUM
);
31 qemu_set_irq(s
->pch_msi_irq
[irq_num
], 1);
34 static const MemoryRegionOps loongarch_pch_msi_ops
= {
35 .read
= loongarch_msi_mem_read
,
36 .write
= loongarch_msi_mem_write
,
37 .endianness
= DEVICE_LITTLE_ENDIAN
,
40 static void pch_msi_irq_handler(void *opaque
, int irq
, int level
)
42 LoongArchPCHMSI
*s
= LOONGARCH_PCH_MSI(opaque
);
44 qemu_set_irq(s
->pch_msi_irq
[irq
], level
);
47 static void loongarch_pch_msi_init(Object
*obj
)
49 LoongArchPCHMSI
*s
= LOONGARCH_PCH_MSI(obj
);
50 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
52 memory_region_init_io(&s
->msi_mmio
, obj
, &loongarch_pch_msi_ops
,
53 s
, TYPE_LOONGARCH_PCH_MSI
, 0x8);
54 sysbus_init_mmio(sbd
, &s
->msi_mmio
);
57 qdev_init_gpio_out(DEVICE(obj
), s
->pch_msi_irq
, PCH_MSI_IRQ_NUM
);
58 qdev_init_gpio_in(DEVICE(obj
), pch_msi_irq_handler
, PCH_MSI_IRQ_NUM
);
61 static const TypeInfo loongarch_pch_msi_info
= {
62 .name
= TYPE_LOONGARCH_PCH_MSI
,
63 .parent
= TYPE_SYS_BUS_DEVICE
,
64 .instance_size
= sizeof(LoongArchPCHMSI
),
65 .instance_init
= loongarch_pch_msi_init
,
68 static void loongarch_pch_msi_register_types(void)
70 type_register_static(&loongarch_pch_msi_info
);
73 type_init(loongarch_pch_msi_register_types
)