Skip to content

Commit 249ad85

Browse files
yangxiaojuan-loongsonrth7680
authored andcommitted
hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI)
This patch realize PCH-MSI interrupt controller. Signed-off-by: Xiaojuan Yang <[email protected]> Signed-off-by: Song Gao <[email protected]> Reviewed-by: Richard Henderson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Richard Henderson <[email protected]>
1 parent 0f4fcf1 commit 249ad85

File tree

7 files changed

+106
-0
lines changed

7 files changed

+106
-0
lines changed

hw/intc/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,8 @@ config LOONGARCH_IPI
9494
config LOONGARCH_PCH_PIC
9595
bool
9696
select UNIMP
97+
98+
config LOONGARCH_PCH_MSI
99+
select MSI_NONBROKEN
100+
bool
101+
select UNIMP

hw/intc/loongarch_pch_msi.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* QEMU Loongson 7A1000 msi interrupt controller.
4+
*
5+
* Copyright (C) 2021 Loongson Technology Corporation Limited
6+
*/
7+
8+
#include "qemu/osdep.h"
9+
#include "hw/sysbus.h"
10+
#include "hw/irq.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"
16+
#include "trace.h"
17+
18+
static uint64_t loongarch_msi_mem_read(void *opaque, hwaddr addr, unsigned size)
19+
{
20+
return 0;
21+
}
22+
23+
static void loongarch_msi_mem_write(void *opaque, hwaddr addr,
24+
uint64_t val, unsigned size)
25+
{
26+
LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque);
27+
int irq_num = val & 0xff;
28+
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);
32+
}
33+
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,
38+
};
39+
40+
static void pch_msi_irq_handler(void *opaque, int irq, int level)
41+
{
42+
LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque);
43+
44+
qemu_set_irq(s->pch_msi_irq[irq], level);
45+
}
46+
47+
static void loongarch_pch_msi_init(Object *obj)
48+
{
49+
LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(obj);
50+
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
51+
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);
55+
msi_nonbroken = true;
56+
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);
59+
}
60+
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,
66+
};
67+
68+
static void loongarch_pch_msi_register_types(void)
69+
{
70+
type_register_static(&loongarch_pch_msi_info);
71+
}
72+
73+
type_init(loongarch_pch_msi_register_types)

hw/intc/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
6565
specific_ss.add(when: 'CONFIG_NIOS2_VIC', if_true: files('nios2_vic.c'))
6666
specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c'))
6767
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c'))
68+
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c'))

hw/intc/trace-events

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,6 @@ loongarch_pch_pic_high_readw(unsigned size, uint64_t addr, uint64_t val) "size:
300300
loongarch_pch_pic_high_writew(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64
301301
loongarch_pch_pic_readb(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64
302302
loongarch_pch_pic_writeb(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64
303+
304+
# loongarch_pch_msi.c
305+
loongarch_msi_set_irq(int irq_num) "set msi irq %d"

hw/loongarch/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ config LOONGARCH_VIRT
44
select PCI_EXPRESS_GENERIC_BRIDGE
55
select LOONGARCH_IPI
66
select LOONGARCH_PCH_PIC
7+
select LOONGARCH_PCH_MSI

include/hw/intc/loongarch_pch_msi.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* LoongArch 7A1000 I/O interrupt controller definitions
4+
*
5+
* Copyright (C) 2021 Loongson Technology Corporation Limited
6+
*/
7+
8+
#define TYPE_LOONGARCH_PCH_MSI "loongarch_pch_msi"
9+
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHMSI, LOONGARCH_PCH_MSI)
10+
11+
/* Msi irq start start from 64 to 255 */
12+
#define PCH_MSI_IRQ_START 64
13+
#define PCH_MSI_IRQ_END 255
14+
#define PCH_MSI_IRQ_NUM 192
15+
16+
struct LoongArchPCHMSI {
17+
SysBusDevice parent_obj;
18+
qemu_irq pch_msi_irq[PCH_MSI_IRQ_NUM];
19+
MemoryRegion msi_mmio;
20+
};

include/hw/pci-host/ls7a.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#include "qemu/range.h"
1616
#include "qom/object.h"
1717

18+
#define LS7A_PCI_MEM_BASE 0x40000000UL
19+
#define LS7A_PCI_MEM_SIZE 0x40000000UL
20+
1821
#define LS7A_PCH_REG_BASE 0x10000000UL
1922
#define LS7A_IOAPIC_REG_BASE (LS7A_PCH_REG_BASE)
2023
#define LS7A_PCH_MSI_ADDR_LOW 0x2FF00000UL

0 commit comments

Comments
 (0)