aboutsummaryrefslogtreecommitdiffstats
path: root/include/hw/intc
diff options
context:
space:
mode:
authorTimos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>2023-10-10 11:40:56 +0000
committerTimos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>2023-10-10 11:40:56 +0000
commite02cda008591317b1625707ff8e115a4841aa889 (patch)
treeaee302e3cf8b59ec2d32ec481be3d1afddfc8968 /include/hw/intc
parentcc668e6b7e0ffd8c9d130513d12053cf5eda1d3b (diff)
Introduce Virtio-loopback epsilon release:
Epsilon release introduces a new compatibility layer which make virtio-loopback design to work with QEMU and rust-vmm vhost-user backend without require any changes. Signed-off-by: Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com> Change-Id: I52e57563e08a7d0bdc002f8e928ee61ba0c53dd9
Diffstat (limited to 'include/hw/intc')
-rw-r--r--include/hw/intc/allwinner-a10-pic.h43
-rw-r--r--include/hw/intc/arm_gic.h89
-rw-r--r--include/hw/intc/arm_gic_common.h168
-rw-r--r--include/hw/intc/arm_gicv3.h32
-rw-r--r--include/hw/intc/arm_gicv3_common.h321
-rw-r--r--include/hw/intc/arm_gicv3_its_common.h113
-rw-r--r--include/hw/intc/armv7m_nvic.h89
-rw-r--r--include/hw/intc/aspeed_vic.h49
-rw-r--r--include/hw/intc/bcm2835_ic.h36
-rw-r--r--include/hw/intc/bcm2836_control.h61
-rw-r--r--include/hw/intc/goldfish_pic.h33
-rw-r--r--include/hw/intc/heathrow_pic.h52
-rw-r--r--include/hw/intc/i8259.h12
-rw-r--r--include/hw/intc/ibex_plic.h67
-rw-r--r--include/hw/intc/imx_avic.h56
-rw-r--r--include/hw/intc/imx_gpcv2.h23
-rw-r--r--include/hw/intc/intc.h28
-rw-r--r--include/hw/intc/loongson_liointc.h22
-rw-r--r--include/hw/intc/m68k_irqc.h41
-rw-r--r--include/hw/intc/mips_gic.h218
-rw-r--r--include/hw/intc/ppc-uic.h80
-rw-r--r--include/hw/intc/realview_gic.h28
-rw-r--r--include/hw/intc/riscv_aclint.h80
-rw-r--r--include/hw/intc/rx_icu.h76
-rw-r--r--include/hw/intc/sifive_plic.h88
-rw-r--r--include/hw/intc/xlnx-pmu-iomod-intc.h57
-rw-r--r--include/hw/intc/xlnx-zynqmp-ipi.h56
27 files changed, 2018 insertions, 0 deletions
diff --git a/include/hw/intc/allwinner-a10-pic.h b/include/hw/intc/allwinner-a10-pic.h
new file mode 100644
index 000000000..b8364d3ed
--- /dev/null
+++ b/include/hw/intc/allwinner-a10-pic.h
@@ -0,0 +1,43 @@
+#ifndef ALLWINNER_A10_PIC_H
+#define ALLWINNER_A10_PIC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_AW_A10_PIC "allwinner-a10-pic"
+OBJECT_DECLARE_SIMPLE_TYPE(AwA10PICState, AW_A10_PIC)
+
+#define AW_A10_PIC_VECTOR 0
+#define AW_A10_PIC_BASE_ADDR 4
+#define AW_A10_PIC_PROTECT 8
+#define AW_A10_PIC_NMI 0xc
+#define AW_A10_PIC_IRQ_PENDING 0x10
+#define AW_A10_PIC_FIQ_PENDING 0x20
+#define AW_A10_PIC_SELECT 0x30
+#define AW_A10_PIC_ENABLE 0x40
+#define AW_A10_PIC_MASK 0x50
+
+#define AW_A10_PIC_INT_NR 95
+#define AW_A10_PIC_REG_NUM DIV_ROUND_UP(AW_A10_PIC_INT_NR, 32)
+
+struct AwA10PICState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+ MemoryRegion iomem;
+ qemu_irq parent_fiq;
+ qemu_irq parent_irq;
+
+ uint32_t vector;
+ uint32_t base_addr;
+ uint32_t protect;
+ uint32_t nmi;
+ uint32_t irq_pending[AW_A10_PIC_REG_NUM];
+ uint32_t fiq_pending[AW_A10_PIC_REG_NUM];
+ uint32_t select[AW_A10_PIC_REG_NUM];
+ uint32_t enable[AW_A10_PIC_REG_NUM];
+ uint32_t mask[AW_A10_PIC_REG_NUM];
+ /*priority setting here*/
+};
+
+#endif
diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h
new file mode 100644
index 000000000..116ccbb5a
--- /dev/null
+++ b/include/hw/intc/arm_gic.h
@@ -0,0 +1,89 @@
+/*
+ * ARM GIC support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * QEMU interface:
+ * + QOM property "num-cpu": number of CPUs to support
+ * + QOM property "num-irq": number of IRQs (including both SPIs and PPIs)
+ * + QOM property "revision": GIC version (1 or 2), or 0 for the 11MPCore GIC
+ * + QOM property "has-security-extensions": set true if the GIC should
+ * implement the security extensions
+ * + QOM property "has-virtualization-extensions": set true if the GIC should
+ * implement the virtualization extensions
+ * + unnamed GPIO inputs: (where P is number of SPIs, i.e. num-irq - 32)
+ * [0..P-1] SPIs
+ * [P..P+31] PPIs for CPU 0
+ * [P+32..P+63] PPIs for CPU 1
+ * ...
+ * + sysbus IRQs: (in order; number will vary depending on number of cores)
+ * - IRQ for CPU 0
+ * - IRQ for CPU 1
+ * ...
+ * - FIQ for CPU 0
+ * - FIQ for CPU 1
+ * ...
+ * - VIRQ for CPU 0 (exists even if virt extensions not present)
+ * - VIRQ for CPU 1 (exists even if virt extensions not present)
+ * ...
+ * - VFIQ for CPU 0 (exists even if virt extensions not present)
+ * - VFIQ for CPU 1 (exists even if virt extensions not present)
+ * ...
+ * - maintenance IRQ for CPU i/f 0 (only if virt extensions present)
+ * - maintenance IRQ for CPU i/f 1 (only if virt extensions present)
+ * + sysbus MMIO regions: (in order; numbers will vary depending on
+ * whether virtualization extensions are present and on number of cores)
+ * - distributor registers (GICD*)
+ * - CPU interface for the accessing core (GICC*)
+ * - virtual interface control registers (GICH*) (only if virt extns present)
+ * - virtual CPU interface for the accessing core (GICV*) (only if virt)
+ * - CPU 0 CPU interface registers
+ * - CPU 1 CPU interface registers
+ * ...
+ * - CPU 0 virtual interface control registers (only if virt extns present)
+ * - CPU 1 virtual interface control registers (only if virt extns present)
+ * ...
+ */
+
+#ifndef HW_ARM_GIC_H
+#define HW_ARM_GIC_H
+
+#include "arm_gic_common.h"
+#include "qom/object.h"
+
+/* Number of SGI target-list bits */
+#define GIC_TARGETLIST_BITS 8
+#define GIC_MAX_PRIORITY_BITS 8
+#define GIC_MIN_PRIORITY_BITS 4
+
+#define TYPE_ARM_GIC "arm_gic"
+typedef struct ARMGICClass ARMGICClass;
+/* This is reusing the GICState typedef from TYPE_ARM_GIC_COMMON */
+DECLARE_OBJ_CHECKERS(GICState, ARMGICClass,
+ ARM_GIC, TYPE_ARM_GIC)
+
+struct ARMGICClass {
+ /*< private >*/
+ ARMGICCommonClass parent_class;
+ /*< public >*/
+
+ DeviceRealize parent_realize;
+};
+
+#endif
diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h
new file mode 100644
index 000000000..708037500
--- /dev/null
+++ b/include/hw/intc/arm_gic_common.h
@@ -0,0 +1,168 @@
+/*
+ * ARM GIC support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_ARM_GIC_COMMON_H
+#define HW_ARM_GIC_COMMON_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+/* Maximum number of possible interrupts, determined by the GIC architecture */
+#define GIC_MAXIRQ 1020
+/* First 32 are private to each CPU (SGIs and PPIs). */
+#define GIC_INTERNAL 32
+#define GIC_NR_SGIS 16
+/* Maximum number of possible CPU interfaces, determined by GIC architecture */
+#define GIC_NCPU 8
+/* Maximum number of possible CPU interfaces with their respective vCPU */
+#define GIC_NCPU_VCPU (GIC_NCPU * 2)
+
+#define MAX_NR_GROUP_PRIO 128
+#define GIC_NR_APRS (MAX_NR_GROUP_PRIO / 32)
+
+#define GIC_MIN_BPR 0
+#define GIC_MIN_ABPR (GIC_MIN_BPR + 1)
+
+/* Architectural maximum number of list registers in the virtual interface */
+#define GIC_MAX_LR 64
+
+/* Only 32 priority levels and 32 preemption levels in the vCPU interfaces */
+#define GIC_VIRT_MAX_GROUP_PRIO_BITS 5
+#define GIC_VIRT_MAX_NR_GROUP_PRIO (1 << GIC_VIRT_MAX_GROUP_PRIO_BITS)
+#define GIC_VIRT_NR_APRS (GIC_VIRT_MAX_NR_GROUP_PRIO / 32)
+
+#define GIC_VIRT_MIN_BPR 2
+#define GIC_VIRT_MIN_ABPR (GIC_VIRT_MIN_BPR + 1)
+
+typedef struct gic_irq_state {
+ /* The enable bits are only banked for per-cpu interrupts. */
+ uint8_t enabled;
+ uint8_t pending;
+ uint8_t active;
+ uint8_t level;
+ bool model; /* 0 = N:N, 1 = 1:N */
+ bool edge_trigger; /* true: edge-triggered, false: level-triggered */
+ uint8_t group;
+} gic_irq_state;
+
+struct GICState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ qemu_irq parent_irq[GIC_NCPU];
+ qemu_irq parent_fiq[GIC_NCPU];
+ qemu_irq parent_virq[GIC_NCPU];
+ qemu_irq parent_vfiq[GIC_NCPU];
+ qemu_irq maintenance_irq[GIC_NCPU];
+
+ /* GICD_CTLR; for a GIC with the security extensions the NS banked version
+ * of this register is just an alias of bit 1 of the S banked version.
+ */
+ uint32_t ctlr;
+ /* GICC_CTLR; again, the NS banked version is just aliases of bits of
+ * the S banked register, so our state only needs to store the S version.
+ */
+ uint32_t cpu_ctlr[GIC_NCPU_VCPU];
+
+ gic_irq_state irq_state[GIC_MAXIRQ];
+ uint8_t irq_target[GIC_MAXIRQ];
+ uint8_t priority1[GIC_INTERNAL][GIC_NCPU];
+ uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL];
+ /* For each SGI on the target CPU, we store 8 bits
+ * indicating which source CPUs have made this SGI
+ * pending on the target CPU. These correspond to
+ * the bytes in the GIC_SPENDSGIR* registers as
+ * read by the target CPU.
+ */
+ uint8_t sgi_pending[GIC_NR_SGIS][GIC_NCPU];
+
+ uint16_t priority_mask[GIC_NCPU_VCPU];
+ uint16_t running_priority[GIC_NCPU_VCPU];
+ uint16_t current_pending[GIC_NCPU_VCPU];
+ uint32_t n_prio_bits;
+
+ /* If we present the GICv2 without security extensions to a guest,
+ * the guest can configure the GICC_CTLR to configure group 1 binary point
+ * in the abpr.
+ * For a GIC with Security Extensions we use use bpr for the
+ * secure copy and abpr as storage for the non-secure copy of the register.
+ */
+ uint8_t bpr[GIC_NCPU_VCPU];
+ uint8_t abpr[GIC_NCPU_VCPU];
+
+ /* The APR is implementation defined, so we choose a layout identical to
+ * the KVM ABI layout for QEMU's implementation of the gic:
+ * If an interrupt for preemption level X is active, then
+ * APRn[X mod 32] == 0b1, where n = X / 32
+ * otherwise the bit is clear.
+ */
+ uint32_t apr[GIC_NR_APRS][GIC_NCPU];
+ uint32_t nsapr[GIC_NR_APRS][GIC_NCPU];
+
+ /* Virtual interface control registers */
+ uint32_t h_hcr[GIC_NCPU];
+ uint32_t h_misr[GIC_NCPU];
+ uint32_t h_lr[GIC_MAX_LR][GIC_NCPU];
+ uint32_t h_apr[GIC_NCPU];
+
+ /* Number of LRs implemented in this GIC instance */
+ uint32_t num_lrs;
+
+ uint32_t num_cpu;
+
+ MemoryRegion iomem; /* Distributor */
+ /* This is just so we can have an opaque pointer which identifies
+ * both this GIC and which CPU interface we should be accessing.
+ */
+ struct GICState *backref[GIC_NCPU];
+ MemoryRegion cpuiomem[GIC_NCPU + 1]; /* CPU interfaces */
+ MemoryRegion vifaceiomem[GIC_NCPU + 1]; /* Virtual interfaces */
+ MemoryRegion vcpuiomem; /* vCPU interface */
+
+ uint32_t num_irq;
+ uint32_t revision;
+ bool security_extn;
+ bool virt_extn;
+ bool irq_reset_nonsecure; /* configure IRQs as group 1 (NS) on reset? */
+ int dev_fd; /* kvm device fd if backed by kvm vgic support */
+ Error *migration_blocker;
+};
+typedef struct GICState GICState;
+
+#define TYPE_ARM_GIC_COMMON "arm_gic_common"
+typedef struct ARMGICCommonClass ARMGICCommonClass;
+DECLARE_OBJ_CHECKERS(GICState, ARMGICCommonClass,
+ ARM_GIC_COMMON, TYPE_ARM_GIC_COMMON)
+
+struct ARMGICCommonClass {
+ /*< private >*/
+ SysBusDeviceClass parent_class;
+ /*< public >*/
+
+ void (*pre_save)(GICState *s);
+ void (*post_load)(GICState *s);
+};
+
+void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler,
+ const MemoryRegionOps *ops,
+ const MemoryRegionOps *virt_ops);
+
+#endif
diff --git a/include/hw/intc/arm_gicv3.h b/include/hw/intc/arm_gicv3.h
new file mode 100644
index 000000000..a81a6ae7e
--- /dev/null
+++ b/include/hw/intc/arm_gicv3.h
@@ -0,0 +1,32 @@
+/*
+ * ARM Generic Interrupt Controller v3
+ *
+ * Copyright (c) 2015 Huawei.
+ * Copyright (c) 2016 Linaro Limited
+ * Written by Shlomo Pongratz, Peter Maydell
+ *
+ * This code is licensed under the GPL, version 2 or (at your option)
+ * any later version.
+ */
+
+#ifndef HW_ARM_GICV3_H
+#define HW_ARM_GICV3_H
+
+#include "arm_gicv3_common.h"
+#include "qom/object.h"
+
+#define TYPE_ARM_GICV3 "arm-gicv3"
+typedef struct ARMGICv3Class ARMGICv3Class;
+/* This is reusing the GICState typedef from TYPE_ARM_GICV3_COMMON */
+DECLARE_OBJ_CHECKERS(GICv3State, ARMGICv3Class,
+ ARM_GICV3, TYPE_ARM_GICV3)
+
+struct ARMGICv3Class {
+ /*< private >*/
+ ARMGICv3CommonClass parent_class;
+ /*< public >*/
+
+ DeviceRealize parent_realize;
+};
+
+#endif
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
new file mode 100644
index 000000000..fc38e4b7d
--- /dev/null
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -0,0 +1,321 @@
+/*
+ * ARM GIC support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Copyright (c) 2015 Huawei.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Written by Peter Maydell
+ * Reworked for GICv3 by Shlomo Pongratz and Pavel Fedin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_ARM_GICV3_COMMON_H
+#define HW_ARM_GICV3_COMMON_H
+
+#include "hw/sysbus.h"
+#include "hw/intc/arm_gic_common.h"
+#include "qom/object.h"
+
+/*
+ * Maximum number of possible interrupts, determined by the GIC architecture.
+ * Note that this does not include LPIs. When implemented, these should be
+ * dealt with separately.
+ */
+#define GICV3_MAXIRQ 1020
+#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)
+
+#define GICV3_LPI_INTID_START 8192
+
+#define GICV3_REDIST_SIZE 0x20000
+
+/* Number of SGI target-list bits */
+#define GICV3_TARGETLIST_BITS 16
+
+/* Maximum number of list registers (architectural limit) */
+#define GICV3_LR_MAX 16
+
+/* Minimum BPR for Secure, or when security not enabled */
+#define GIC_MIN_BPR 0
+/* Minimum BPR for Nonsecure when security is enabled */
+#define GIC_MIN_BPR_NS (GIC_MIN_BPR + 1)
+
+/* For some distributor fields we want to model the array of 32-bit
+ * register values which hold various bitmaps corresponding to enabled,
+ * pending, etc bits. These macros and functions facilitate that; the
+ * APIs are generally modelled on the generic bitmap.h functions
+ * (which are unsuitable here because they use 'unsigned long' as the
+ * underlying storage type, which is very awkward when you need to
+ * access the data as 32-bit values.)
+ * Each bitmap contains a bit for each interrupt. Although there is
+ * space for the PPIs and SGIs, those bits (the first 32) are never
+ * used as that state lives in the redistributor. The unused bits are
+ * provided purely so that interrupt X's state is always in bit X; this
+ * avoids bugs where we forget to subtract GIC_INTERNAL from an
+ * interrupt number.
+ */
+#define GICV3_BMP_SIZE DIV_ROUND_UP(GICV3_MAXIRQ, 32)
+
+#define GIC_DECLARE_BITMAP(name) \
+ uint32_t name[GICV3_BMP_SIZE]
+
+#define GIC_BIT_MASK(nr) (1U << ((nr) % 32))
+#define GIC_BIT_WORD(nr) ((nr) / 32)
+
+static inline void gic_bmp_set_bit(int nr, uint32_t *addr)
+{
+ uint32_t mask = GIC_BIT_MASK(nr);
+ uint32_t *p = addr + GIC_BIT_WORD(nr);
+
+ *p |= mask;
+}
+
+static inline void gic_bmp_clear_bit(int nr, uint32_t *addr)
+{
+ uint32_t mask = GIC_BIT_MASK(nr);
+ uint32_t *p = addr + GIC_BIT_WORD(nr);
+
+ *p &= ~mask;
+}
+
+static inline int gic_bmp_test_bit(int nr, const uint32_t *addr)
+{
+ return 1U & (addr[GIC_BIT_WORD(nr)] >> (nr & 31));
+}
+
+static inline void gic_bmp_replace_bit(int nr, uint32_t *addr, int val)
+{
+ uint32_t mask = GIC_BIT_MASK(nr);
+ uint32_t *p = addr + GIC_BIT_WORD(nr);
+
+ *p &= ~mask;
+ *p |= (val & 1U) << (nr % 32);
+}
+
+/* Return a pointer to the 32-bit word containing the specified bit. */
+static inline uint32_t *gic_bmp_ptr32(uint32_t *addr, int nr)
+{
+ return addr + GIC_BIT_WORD(nr);
+}
+
+typedef struct GICv3State GICv3State;
+typedef struct GICv3CPUState GICv3CPUState;
+
+/* Some CPU interface registers come in three flavours:
+ * Group0, Group1 (Secure) and Group1 (NonSecure)
+ * (where the latter two are exposed as a single banked system register).
+ * In the state struct they are implemented as a 3-element array which
+ * can be indexed into by the GICV3_G0, GICV3_G1 and GICV3_G1NS constants.
+ * If the CPU doesn't support EL3 then the G1 element is unused.
+ *
+ * These constants are also used to communicate the group to use for
+ * an interrupt or SGI when it is passed between the cpu interface and
+ * the redistributor or distributor. For those purposes the receiving end
+ * must be prepared to cope with a Group 1 Secure interrupt even if it does
+ * not have security support enabled, because security can be disabled
+ * independently in the CPU and in the GIC. In that case the receiver should
+ * treat an incoming Group 1 Secure interrupt as if it were Group 0.
+ * (This architectural requirement is why the _G1 element is the unused one
+ * in a no-EL3 CPU: we would otherwise have to translate back and forth
+ * between (G0, G1NS) from the distributor and (G0, G1) in the CPU i/f.)
+ */
+#define GICV3_G0 0
+#define GICV3_G1 1
+#define GICV3_G1NS 2
+
+/* ICC_CTLR_EL1, GICD_STATUSR and GICR_STATUSR are banked but not
+ * group-related, so those indices are just 0 for S and 1 for NS.
+ * (If the CPU or the GIC, respectively, don't support the Security
+ * extensions then the S element is unused.)
+ */
+#define GICV3_S 0
+#define GICV3_NS 1
+
+typedef struct {
+ int irq;
+ uint8_t prio;
+ int grp;
+} PendingIrq;
+
+struct GICv3CPUState {
+ GICv3State *gic;
+ CPUState *cpu;
+ qemu_irq parent_irq;
+ qemu_irq parent_fiq;
+ qemu_irq parent_virq;
+ qemu_irq parent_vfiq;
+
+ /* Redistributor */
+ uint32_t level; /* Current IRQ level */
+ /* RD_base page registers */
+ uint32_t gicr_ctlr;
+ uint64_t gicr_typer;
+ uint32_t gicr_statusr[2];
+ uint32_t gicr_waker;
+ uint64_t gicr_propbaser;
+ uint64_t gicr_pendbaser;
+ /* SGI_base page registers */
+ uint32_t gicr_igroupr0;
+ uint32_t gicr_ienabler0;
+ uint32_t gicr_ipendr0;
+ uint32_t gicr_iactiver0;
+ uint32_t edge_trigger; /* ICFGR0 and ICFGR1 even bits */
+ uint32_t gicr_igrpmodr0;
+ uint32_t gicr_nsacr;
+ uint8_t gicr_ipriorityr[GIC_INTERNAL];
+
+ /* CPU interface */
+ uint64_t icc_sre_el1;
+ uint64_t icc_ctlr_el1[2];
+ uint64_t icc_pmr_el1;
+ uint64_t icc_bpr[3];
+ uint64_t icc_apr[3][4];
+ uint64_t icc_igrpen[3];
+ uint64_t icc_ctlr_el3;
+
+ /* Virtualization control interface */
+ uint64_t ich_apr[3][4]; /* ich_apr[GICV3_G1][x] never used */
+ uint64_t ich_hcr_el2;
+ uint64_t ich_lr_el2[GICV3_LR_MAX];
+ uint64_t ich_vmcr_el2;
+
+ /* Properties of the CPU interface. These are initialized from
+ * the settings in the CPU proper.
+ * If the number of implemented list registers is 0 then the
+ * virtualization support is not implemented.
+ */
+ int num_list_regs;
+ int vpribits; /* number of virtual priority bits */
+ int vprebits; /* number of virtual preemption bits */
+
+ /* Current highest priority pending interrupt for this CPU.
+ * This is cached information that can be recalculated from the
+ * real state above; it doesn't need to be migrated.
+ */
+ PendingIrq hppi;
+
+ /*
+ * Cached information recalculated from LPI tables
+ * in guest memory
+ */
+ PendingIrq hpplpi;
+
+ /* This is temporary working state, to avoid a malloc in gicv3_update() */
+ bool seenbetter;
+};
+
+/*
+ * The redistributor pages might be split into more than one region
+ * on some machine types if there are many CPUs.
+ */
+typedef struct GICv3RedistRegion {
+ GICv3State *gic;
+ MemoryRegion iomem;
+ uint32_t cpuidx; /* index of first CPU this region covers */
+} GICv3RedistRegion;
+
+struct GICv3State {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ MemoryRegion iomem_dist; /* Distributor */
+ GICv3RedistRegion *redist_regions; /* Redistributor Regions */
+ uint32_t *redist_region_count; /* redistributor count within each region */
+ uint32_t nb_redist_regions; /* number of redist regions */
+
+ uint32_t num_cpu;
+ uint32_t num_irq;
+ uint32_t revision;
+ bool lpi_enable;
+ bool security_extn;
+ bool irq_reset_nonsecure;
+ bool gicd_no_migration_shift_bug;
+
+ int dev_fd; /* kvm device fd if backed by kvm vgic support */
+ Error *migration_blocker;
+
+ MemoryRegion *dma;
+ AddressSpace dma_as;
+
+ /* Distributor */
+
+ /* for a GIC with the security extensions the NS banked version of this
+ * register is just an alias of bit 1 of the S banked version.
+ */
+ uint32_t gicd_ctlr;
+ uint32_t gicd_statusr[2];
+ GIC_DECLARE_BITMAP(group); /* GICD_IGROUPR */
+ GIC_DECLARE_BITMAP(grpmod); /* GICD_IGRPMODR */
+ GIC_DECLARE_BITMAP(enabled); /* GICD_ISENABLER */
+ GIC_DECLARE_BITMAP(pending); /* GICD_ISPENDR */
+ GIC_DECLARE_BITMAP(active); /* GICD_ISACTIVER */
+ GIC_DECLARE_BITMAP(level); /* Current level */
+ GIC_DECLARE_BITMAP(edge_trigger); /* GICD_ICFGR even bits */
+ uint8_t gicd_ipriority[GICV3_MAXIRQ];
+ uint64_t gicd_irouter[GICV3_MAXIRQ];
+ /* Cached information: pointer to the cpu i/f for the CPUs specified
+ * in the IROUTER registers
+ */
+ GICv3CPUState *gicd_irouter_target[GICV3_MAXIRQ];
+ uint32_t gicd_nsacr[DIV_ROUND_UP(GICV3_MAXIRQ, 16)];
+
+ GICv3CPUState *cpu;
+};
+
+#define GICV3_BITMAP_ACCESSORS(BMP) \
+ static inline void gicv3_gicd_##BMP##_set(GICv3State *s, int irq) \
+ { \
+ gic_bmp_set_bit(irq, s->BMP); \
+ } \
+ static inline int gicv3_gicd_##BMP##_test(GICv3State *s, int irq) \
+ { \
+ return gic_bmp_test_bit(irq, s->BMP); \
+ } \
+ static inline void gicv3_gicd_##BMP##_clear(GICv3State *s, int irq) \
+ { \
+ gic_bmp_clear_bit(irq, s->BMP); \
+ } \
+ static inline void gicv3_gicd_##BMP##_replace(GICv3State *s, \
+ int irq, int value) \
+ { \
+ gic_bmp_replace_bit(irq, s->BMP, value); \
+ }
+
+GICV3_BITMAP_ACCESSORS(group)
+GICV3_BITMAP_ACCESSORS(grpmod)
+GICV3_BITMAP_ACCESSORS(enabled)
+GICV3_BITMAP_ACCESSORS(pending)
+GICV3_BITMAP_ACCESSORS(active)
+GICV3_BITMAP_ACCESSORS(level)
+GICV3_BITMAP_ACCESSORS(edge_trigger)
+
+#define TYPE_ARM_GICV3_COMMON "arm-gicv3-common"
+typedef struct ARMGICv3CommonClass ARMGICv3CommonClass;
+DECLARE_OBJ_CHECKERS(GICv3State, ARMGICv3CommonClass,
+ ARM_GICV3_COMMON, TYPE_ARM_GICV3_COMMON)
+
+struct ARMGICv3CommonClass {
+ /*< private >*/
+ SysBusDeviceClass parent_class;
+ /*< public >*/
+
+ void (*pre_save)(GICv3State *s);
+ void (*post_load)(GICv3State *s);
+};
+
+void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
+ const MemoryRegionOps *ops);
+
+#endif
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
new file mode 100644
index 000000000..4e79145dd
--- /dev/null
+++ b/include/hw/intc/arm_gicv3_its_common.h
@@ -0,0 +1,113 @@
+/*
+ * ITS support for ARM GICv3
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Written by Pavel Fedin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_ARM_GICV3_ITS_COMMON_H
+#define QEMU_ARM_GICV3_ITS_COMMON_H
+
+#include "hw/sysbus.h"
+#include "hw/intc/arm_gicv3_common.h"
+#include "qom/object.h"
+
+#define TYPE_ARM_GICV3_ITS "arm-gicv3-its"
+
+#define ITS_CONTROL_SIZE 0x10000
+#define ITS_TRANS_SIZE 0x10000
+#define ITS_SIZE (ITS_CONTROL_SIZE + ITS_TRANS_SIZE)
+
+#define GITS_CTLR 0x0
+#define GITS_IIDR 0x4
+#define GITS_TYPER 0x8
+#define GITS_CBASER 0x80
+#define GITS_CWRITER 0x88
+#define GITS_CREADR 0x90
+#define GITS_BASER 0x100
+
+#define GITS_TRANSLATER 0x0040
+
+typedef struct {
+ bool valid;
+ bool indirect;
+ uint16_t entry_sz;
+ uint32_t page_sz;
+ uint32_t max_entries;
+ union {
+ uint32_t max_devids;
+ uint32_t max_collids;
+ } maxids;
+ uint64_t base_addr;
+} TableDesc;
+
+typedef struct {
+ bool valid;
+ uint32_t max_entries;
+ uint64_t base_addr;
+} CmdQDesc;
+
+struct GICv3ITSState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem_main;
+ MemoryRegion iomem_its_cntrl;
+ MemoryRegion iomem_its_translation;
+
+ GICv3State *gicv3;
+
+ int dev_fd; /* kvm device fd if backed by kvm vgic support */
+ uint64_t gits_translater_gpa;
+ bool translater_gpa_known;
+
+ /* Registers */
+ uint32_t ctlr;
+ uint32_t iidr;
+ uint64_t typer;
+ uint64_t cbaser;
+ uint64_t cwriter;
+ uint64_t creadr;
+ uint64_t baser[8];
+
+ TableDesc dt;
+ TableDesc ct;
+ CmdQDesc cq;
+
+ Error *migration_blocker;
+};
+
+typedef struct GICv3ITSState GICv3ITSState;
+
+void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops,
+ const MemoryRegionOps *tops);
+
+#define TYPE_ARM_GICV3_ITS_COMMON "arm-gicv3-its-common"
+typedef struct GICv3ITSCommonClass GICv3ITSCommonClass;
+DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSCommonClass,
+ ARM_GICV3_ITS_COMMON, TYPE_ARM_GICV3_ITS_COMMON)
+
+struct GICv3ITSCommonClass {
+ /*< private >*/
+ SysBusDeviceClass parent_class;
+ /*< public >*/
+
+ int (*send_msi)(GICv3ITSState *s, uint32_t data, uint16_t devid);
+ void (*pre_save)(GICv3ITSState *s);
+ void (*post_load)(GICv3ITSState *s);
+};
+
+
+#endif
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
new file mode 100644
index 000000000..0180c7b0c
--- /dev/null
+++ b/include/hw/intc/armv7m_nvic.h
@@ -0,0 +1,89 @@
+/*
+ * ARMv7M NVIC object
+ *
+ * Copyright (c) 2017 Linaro Ltd
+ * Written by Peter Maydell <peter.maydell@linaro.org>
+ *
+ * This code is licensed under the GPL version 2 or later.
+ */
+
+#ifndef HW_ARM_ARMV7M_NVIC_H
+#define HW_ARM_ARMV7M_NVIC_H
+
+#include "target/arm/cpu.h"
+#include "hw/sysbus.h"
+#include "hw/timer/armv7m_systick.h"
+#include "qom/object.h"
+
+#define TYPE_NVIC "armv7m_nvic"
+
+typedef struct NVICState NVICState;
+DECLARE_INSTANCE_CHECKER(NVICState, NVIC,
+ TYPE_NVIC)
+
+/* Highest permitted number of exceptions (architectural limit) */
+#define NVIC_MAX_VECTORS 512
+/* Number of internal exceptions */
+#define NVIC_INTERNAL_VECTORS 16
+
+typedef struct VecInfo {
+ /* Exception priorities can range from -3 to 255; only the unmodifiable
+ * priority values for RESET, NMI and HardFault can be negative.
+ */
+ int16_t prio;
+ uint8_t enabled;
+ uint8_t pending;
+ uint8_t active;
+ uint8_t level; /* exceptions <=15 never set level */
+} VecInfo;
+
+struct NVICState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ ARMCPU *cpu;
+
+ VecInfo vectors[NVIC_MAX_VECTORS];
+ /* If the v8M security extension is implemented, some of the internal
+ * exceptions are banked between security states (ie there exists both
+ * a Secure and a NonSecure version of the exception and its state):
+ * HardFault, MemManage, UsageFault, SVCall, PendSV, SysTick (R_PJHV)
+ * The rest (including all the external exceptions) are not banked, though
+ * they may be configurable to target either Secure or NonSecure state.
+ * We store the secure exception state in sec_vectors[] for the banked
+ * exceptions, and otherwise use only vectors[] (including for exceptions
+ * like SecureFault that unconditionally target Secure state).
+ * Entries in sec_vectors[] for non-banked exception numbers are unused.
+ */
+ VecInfo sec_vectors[NVIC_INTERNAL_VECTORS];
+ /* The PRIGROUP field in AIRCR is banked */
+ uint32_t prigroup[M_REG_NUM_BANKS];
+ uint8_t num_prio_bits;
+
+ /* v8M NVIC_ITNS state (stored as a bool per bit) */
+ bool itns[NVIC_MAX_VECTORS];
+
+ /* The following fields are all cached state that can be recalculated
+ * from the vectors[] and sec_vectors[] arrays and the prigroup field:
+ * - vectpending
+ * - vectpending_is_secure
+ * - exception_prio
+ * - vectpending_prio
+ */
+ unsigned int vectpending; /* highest prio pending enabled exception */
+ /* true if vectpending is a banked secure exception, ie it is in
+ * sec_vectors[] rather than vectors[]
+ */
+ bool vectpending_is_s_banked;
+ int exception_prio; /* group prio of the highest prio active exception */
+ int vectpending_prio; /* group prio of the exeception in vectpending */
+
+ MemoryRegion sysregmem;
+
+ uint32_t num_irq;
+ qemu_irq excpout;
+ qemu_irq sysresetreq;
+};
+
+#endif
diff --git a/include/hw/intc/aspeed_vic.h b/include/hw/intc/aspeed_vic.h
new file mode 100644
index 000000000..68d6ab997
--- /dev/null
+++ b/include/hw/intc/aspeed_vic.h
@@ -0,0 +1,49 @@
+/*
+ * ASPEED Interrupt Controller (New)
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ *
+ * Need to add SVIC and CVIC support
+ */
+#ifndef ASPEED_VIC_H
+#define ASPEED_VIC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_ASPEED_VIC "aspeed.vic"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedVICState, ASPEED_VIC)
+
+#define ASPEED_VIC_NR_IRQS 51
+
+struct AspeedVICState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+ qemu_irq irq;
+ qemu_irq fiq;
+
+ uint64_t level;
+ uint64_t raw;
+ uint64_t select;
+ uint64_t enable;
+ uint64_t trigger;
+
+ /* 0=edge, 1=level */
+ uint64_t sense;
+
+ /* 0=single-edge, 1=dual-edge */
+ uint64_t dual_edge;
+
+ /* 0=low-sensitive/falling-edge, 1=high-sensitive/rising-edge */
+ uint64_t event;
+};
+
+#endif /* ASPEED_VIC_H */
diff --git a/include/hw/intc/bcm2835_ic.h b/include/hw/intc/bcm2835_ic.h
new file mode 100644
index 000000000..588eb76c5
--- /dev/null
+++ b/include/hw/intc/bcm2835_ic.h
@@ -0,0 +1,36 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef BCM2835_IC_H
+#define BCM2835_IC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_BCM2835_IC "bcm2835-ic"
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835ICState, BCM2835_IC)
+
+#define BCM2835_IC_GPU_IRQ "gpu-irq"
+#define BCM2835_IC_ARM_IRQ "arm-irq"
+
+struct BCM2835ICState {
+ /*< private >*/
+ SysBusDevice busdev;
+ /*< public >*/
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+ qemu_irq fiq;
+
+ /* 64 GPU IRQs + 8 ARM IRQs = 72 total (GPU first) */
+ uint64_t gpu_irq_level, gpu_irq_enable;
+ uint8_t arm_irq_level, arm_irq_enable;
+ bool fiq_enable;
+ uint8_t fiq_select;
+};
+
+#endif
diff --git a/include/hw/intc/bcm2836_control.h b/include/hw/intc/bcm2836_control.h
new file mode 100644
index 000000000..a410c817e
--- /dev/null
+++ b/include/hw/intc/bcm2836_control.h
@@ -0,0 +1,61 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * ARM Local Timer IRQ Copyright (c) 2019. Zoltán Baldaszti
+ * Added basic IRQ_TIMER interrupt support
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef BCM2836_CONTROL_H
+#define BCM2836_CONTROL_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "qom/object.h"
+
+/* 4 mailboxes per core, for 16 total */
+#define BCM2836_NCORES 4
+#define BCM2836_MBPERCORE 4
+
+#define TYPE_BCM2836_CONTROL "bcm2836-control"
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2836ControlState, BCM2836_CONTROL)
+
+struct BCM2836ControlState {
+ /*< private >*/
+ SysBusDevice busdev;
+ /*< public >*/
+ MemoryRegion iomem;
+
+ /* mailbox state */
+ uint32_t mailboxes[BCM2836_NCORES * BCM2836_MBPERCORE];
+
+ /* interrupt routing/control registers */
+ uint8_t route_gpu_irq, route_gpu_fiq;
+ uint32_t timercontrol[BCM2836_NCORES];
+ uint32_t mailboxcontrol[BCM2836_NCORES];
+
+ /* interrupt status regs (derived from input pins; not visible to user) */
+ bool gpu_irq, gpu_fiq;
+ uint8_t timerirqs[BCM2836_NCORES];
+
+ /* local timer */
+ QEMUTimer timer;
+ uint32_t local_timer_control;
+ uint8_t route_localtimer;
+
+ /* interrupt source registers, post-routing (also input-derived; visible) */
+ uint32_t irqsrc[BCM2836_NCORES];
+ uint32_t fiqsrc[BCM2836_NCORES];
+
+ /* outputs to CPU cores */
+ qemu_irq irq[BCM2836_NCORES];
+ qemu_irq fiq[BCM2836_NCORES];
+};
+
+#endif
diff --git a/include/hw/intc/goldfish_pic.h b/include/hw/intc/goldfish_pic.h
new file mode 100644
index 000000000..e9d552f79
--- /dev/null
+++ b/include/hw/intc/goldfish_pic.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Goldfish PIC
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#ifndef HW_INTC_GOLDFISH_PIC_H
+#define HW_INTC_GOLDFISH_PIC_H
+
+#define TYPE_GOLDFISH_PIC "goldfish_pic"
+OBJECT_DECLARE_SIMPLE_TYPE(GoldfishPICState, GOLDFISH_PIC)
+
+#define GOLDFISH_PIC_IRQ_NB 32
+
+struct GoldfishPICState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+
+ uint32_t pending;
+ uint32_t enabled;
+
+ /* statistics */
+ uint64_t stats_irq_count[32];
+ /* for tracing */
+ uint8_t idx;
+};
+
+#endif
diff --git a/include/hw/intc/heathrow_pic.h b/include/hw/intc/heathrow_pic.h
new file mode 100644
index 000000000..c0a7f6f54
--- /dev/null
+++ b/include/hw/intc/heathrow_pic.h
@@ -0,0 +1,52 @@
+/*
+ * Heathrow PIC support (OldWorld PowerMac)
+ *
+ * Copyright (c) 2005-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_INTC_HEATHROW_PIC_H
+#define HW_INTC_HEATHROW_PIC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_HEATHROW "heathrow"
+OBJECT_DECLARE_SIMPLE_TYPE(HeathrowState, HEATHROW)
+
+typedef struct HeathrowPICState {
+ uint32_t events;
+ uint32_t mask;
+ uint32_t levels;
+ uint32_t level_triggered;
+} HeathrowPICState;
+
+struct HeathrowState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mem;
+ HeathrowPICState pics[2];
+ qemu_irq irqs[1];
+};
+
+#define HEATHROW_NUM_IRQS 64
+
+#endif /* HW_INTC_HEATHROW_PIC_H */
diff --git a/include/hw/intc/i8259.h b/include/hw/intc/i8259.h
new file mode 100644
index 000000000..e2b1e8c59
--- /dev/null
+++ b/include/hw/intc/i8259.h
@@ -0,0 +1,12 @@
+#ifndef HW_I8259_H
+#define HW_I8259_H
+
+/* i8259.c */
+
+extern DeviceState *isa_pic;
+qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq);
+qemu_irq *kvm_i8259_init(ISABus *bus);
+int pic_get_output(DeviceState *d);
+int pic_read_irq(DeviceState *d);
+
+#endif
diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
new file mode 100644
index 000000000..d596436e0
--- /dev/null
+++ b/include/hw/intc/ibex_plic.h
@@ -0,0 +1,67 @@
+/*
+ * QEMU RISC-V lowRISC Ibex PLIC
+ *
+ * Copyright (c) 2020 Western Digital
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_IBEX_PLIC_H
+#define HW_IBEX_PLIC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_IBEX_PLIC "ibex-plic"
+OBJECT_DECLARE_SIMPLE_TYPE(IbexPlicState, IBEX_PLIC)
+
+struct IbexPlicState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion mmio;
+
+ uint32_t *pending;
+ uint32_t *hidden_pending;
+ uint32_t *claimed;
+ uint32_t *source;
+ uint32_t *priority;
+ uint32_t *enable;
+ uint32_t threshold;
+ uint32_t claim;
+
+ /* config */
+ uint32_t num_cpus;
+ uint32_t num_sources;
+
+ uint32_t pending_base;
+ uint32_t pending_num;
+
+ uint32_t source_base;
+ uint32_t source_num;
+
+ uint32_t priority_base;
+ uint32_t priority_num;
+
+ uint32_t enable_base;
+ uint32_t enable_num;
+
+ uint32_t threshold_base;
+
+ uint32_t claim_base;
+
+ qemu_irq *external_irqs;
+};
+
+#endif /* HW_IBEX_PLIC_H */
diff --git a/include/hw/intc/imx_avic.h b/include/hw/intc/imx_avic.h
new file mode 100644
index 000000000..75fbd1a89
--- /dev/null
+++ b/include/hw/intc/imx_avic.h
@@ -0,0 +1,56 @@
+/*
+ * i.MX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by Freescale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally written by Hans Jiang
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+#ifndef IMX_AVIC_H
+#define IMX_AVIC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_IMX_AVIC "imx.avic"
+OBJECT_DECLARE_SIMPLE_TYPE(IMXAVICState, IMX_AVIC)
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM (1<<18) /* Normal interrupt mode */
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+struct IMXAVICState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+ uint64_t pending;
+ uint64_t enabled;
+ uint64_t is_fiq;
+ uint32_t intcntl;
+ uint32_t intmask;
+ qemu_irq irq;
+ qemu_irq fiq;
+ uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+};
+
+#endif /* IMX_AVIC_H */
diff --git a/include/hw/intc/imx_gpcv2.h b/include/hw/intc/imx_gpcv2.h
new file mode 100644
index 000000000..7bdee7e80
--- /dev/null
+++ b/include/hw/intc/imx_gpcv2.h
@@ -0,0 +1,23 @@
+#ifndef IMX_GPCV2_H
+#define IMX_GPCV2_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+enum IMXGPCv2Registers {
+ GPC_NUM = 0xE00 / sizeof(uint32_t),
+};
+
+struct IMXGPCv2State {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+ uint32_t regs[GPC_NUM];
+};
+
+#define TYPE_IMX_GPCV2 "imx-gpcv2"
+OBJECT_DECLARE_SIMPLE_TYPE(IMXGPCv2State, IMX_GPCV2)
+
+#endif /* IMX_GPCV2_H */
diff --git a/include/hw/intc/intc.h b/include/hw/intc/intc.h
new file mode 100644
index 000000000..7018f608c
--- /dev/null
+++ b/include/hw/intc/intc.h
@@ -0,0 +1,28 @@
+#ifndef INTC_H
+#define INTC_H
+
+#include "qom/object.h"
+
+#define TYPE_INTERRUPT_STATS_PROVIDER "intctrl"
+
+typedef struct InterruptStatsProviderClass InterruptStatsProviderClass;
+DECLARE_CLASS_CHECKERS(InterruptStatsProviderClass, INTERRUPT_STATS_PROVIDER,
+ TYPE_INTERRUPT_STATS_PROVIDER)
+#define INTERRUPT_STATS_PROVIDER(obj) \
+ INTERFACE_CHECK(InterruptStatsProvider, (obj), \
+ TYPE_INTERRUPT_STATS_PROVIDER)
+
+typedef struct InterruptStatsProvider InterruptStatsProvider;
+
+struct InterruptStatsProviderClass {
+ InterfaceClass parent;
+
+ /* The returned pointer and statistics must remain valid until
+ * the BQL is next dropped.
+ */
+ bool (*get_statistics)(InterruptStatsProvider *obj, uint64_t **irq_counts,
+ unsigned int *nb_irqs);
+ void (*print_info)(InterruptStatsProvider *obj, Monitor *mon);
+};
+
+#endif
diff --git a/include/hw/intc/loongson_liointc.h b/include/hw/intc/loongson_liointc.h
new file mode 100644
index 000000000..848e65eb3
--- /dev/null
+++ b/include/hw/intc/loongson_liointc.h
@@ -0,0 +1,22 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2020 Huacai Chen <chenhc@lemote.com>
+ * Copyright (c) 2020 Jiaxun Yang <jiaxun.yang@flygoat.com>
+ *
+ */
+
+#ifndef LOONGSON_LIOINTC_H
+#define LOONGSON_LIOINTC_H
+
+#include "qemu/units.h"
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_LOONGSON_LIOINTC "loongson.liointc"
+DECLARE_INSTANCE_CHECKER(struct loongson_liointc, LOONGSON_LIOINTC,
+ TYPE_LOONGSON_LIOINTC)
+
+#endif /* LOONGSON_LIOINTC_H */
diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h
new file mode 100644
index 000000000..ef91f2181
--- /dev/null
+++ b/include/hw/intc/m68k_irqc.h
@@ -0,0 +1,41 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * QEMU Motorola 680x0 IRQ Controller
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#ifndef M68K_IRQC_H
+#define M68K_IRQC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_M68K_IRQC "m68k-irq-controller"
+#define M68K_IRQC(obj) OBJECT_CHECK(M68KIRQCState, (obj), \
+ TYPE_M68K_IRQC)
+
+#define M68K_IRQC_AUTOVECTOR_BASE 25
+
+enum {
+ M68K_IRQC_LEVEL_1 = 0,
+ M68K_IRQC_LEVEL_2,
+ M68K_IRQC_LEVEL_3,
+ M68K_IRQC_LEVEL_4,
+ M68K_IRQC_LEVEL_5,
+ M68K_IRQC_LEVEL_6,
+ M68K_IRQC_LEVEL_7,
+};
+#define M68K_IRQC_LEVEL_NUM (M68K_IRQC_LEVEL_7 - M68K_IRQC_LEVEL_1 + 1)
+
+typedef struct M68KIRQCState {
+ SysBusDevice parent_obj;
+
+ uint8_t ipr;
+
+ /* statistics */
+ uint64_t stats_irq_count[M68K_IRQC_LEVEL_NUM];
+} M68KIRQCState;
+
+#endif
diff --git a/include/hw/intc/mips_gic.h b/include/hw/intc/mips_gic.h
new file mode 100644
index 000000000..eeb136e26
--- /dev/null
+++ b/include/hw/intc/mips_gic.h
@@ -0,0 +1,218 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 07 MIPS Technologies, Inc.
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ */
+
+#ifndef MIPS_GIC_H
+#define MIPS_GIC_H
+
+#include "qemu/units.h"
+#include "hw/timer/mips_gictimer.h"
+#include "hw/sysbus.h"
+#include "cpu.h"
+#include "qom/object.h"
+/*
+ * GIC Specific definitions
+ */
+
+/* The MIPS default location */
+#define GIC_BASE_ADDR 0x1bdc0000ULL
+#define GIC_ADDRSPACE_SZ (128 * KiB)
+
+/* Constants */
+#define GIC_POL_POS 1
+#define GIC_POL_NEG 0
+#define GIC_TRIG_EDGE 1
+#define GIC_TRIG_LEVEL 0
+
+#define MSK(n) ((1ULL << (n)) - 1)
+
+/* GIC Address Space */
+#define SHARED_SECTION_OFS 0x0000
+#define SHARED_SECTION_SIZE 0x8000
+#define VP_LOCAL_SECTION_OFS 0x8000
+#define VP_LOCAL_SECTION_SIZE 0x4000
+#define VP_OTHER_SECTION_OFS 0xc000
+#define VP_OTHER_SECTION_SIZE 0x4000
+#define USM_VISIBLE_SECTION_OFS 0x10000
+#define USM_VISIBLE_SECTION_SIZE 0x10000
+
+/* Register Map for Shared Section */
+
+#define GIC_SH_CONFIG_OFS 0x0000
+
+/* Shared Global Counter */
+#define GIC_SH_COUNTERLO_OFS 0x0010
+#define GIC_SH_COUNTERHI_OFS 0x0014
+#define GIC_SH_REVISIONID_OFS 0x0020
+
+/* Set/Clear corresponding bit in Edge Detect Register */
+#define GIC_SH_WEDGE_OFS 0x0280
+
+/* Reset Mask - Disables Interrupt */
+#define GIC_SH_RMASK_OFS 0x0300
+#define GIC_SH_RMASK_LAST_OFS 0x031c
+
+/* Set Mask (WO) - Enables Interrupt */
+#define GIC_SH_SMASK_OFS 0x0380
+#define GIC_SH_SMASK_LAST_OFS 0x039c
+
+/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
+#define GIC_SH_MASK_OFS 0x0400
+#define GIC_SH_MASK_LAST_OFS 0x041c
+
+/* Pending Global Interrupts (RO) */
+#define GIC_SH_PEND_OFS 0x0480
+#define GIC_SH_PEND_LAST_OFS 0x049c
+
+#define GIC_SH_MAP0_PIN_OFS 0x0500
+#define GIC_SH_MAP255_PIN_OFS 0x08fc
+
+#define GIC_SH_MAP0_VP_OFS 0x2000
+#define GIC_SH_MAP255_VP_LAST_OFS 0x3fe4
+
+/* Register Map for Local Section */
+#define GIC_VP_CTL_OFS 0x0000
+#define GIC_VP_PEND_OFS 0x0004
+#define GIC_VP_MASK_OFS 0x0008
+#define GIC_VP_RMASK_OFS 0x000c
+#define GIC_VP_SMASK_OFS 0x0010
+#define GIC_VP_WD_MAP_OFS 0x0040
+#define GIC_VP_COMPARE_MAP_OFS 0x0044
+#define GIC_VP_TIMER_MAP_OFS 0x0048
+#define GIC_VP_FDC_MAP_OFS 0x004c
+#define GIC_VP_PERFCTR_MAP_OFS 0x0050
+#define GIC_VP_SWINT0_MAP_OFS 0x0054
+#define GIC_VP_SWINT1_MAP_OFS 0x0058
+#define GIC_VP_OTHER_ADDR_OFS 0x0080
+#define GIC_VP_IDENT_OFS 0x0088
+#define GIC_VP_WD_CONFIG0_OFS 0x0090
+#define GIC_VP_WD_COUNT0_OFS 0x0094
+#define GIC_VP_WD_INITIAL0_OFS 0x0098
+#define GIC_VP_COMPARE_LO_OFS 0x00a0
+#define GIC_VP_COMPARE_HI_OFS 0x00a4
+#define GIC_VL_BRK_GROUP 0x3080
+
+/* User-Mode Visible Section Register */
+/* Read-only alias for GIC Shared CounterLo */
+#define GIC_USER_MODE_COUNTERLO 0x0000
+/* Read-only alias for GIC Shared CounterHi */
+#define GIC_USER_MODE_COUNTERHI 0x0004
+
+/* Masks */
+#define GIC_SH_CONFIG_COUNTSTOP_SHF 28
+#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
+#define GIC_SH_CONFIG_COUNTBITS_SHF 24
+#define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
+#define GIC_SH_CONFIG_NUMINTRS_SHF 16
+#define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
+#define GIC_SH_CONFIG_PVPS_SHF 0
+#define GIC_SH_CONFIG_PVPS_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPS_SHF)
+
+#define GIC_SH_WEDGE_RW_SHF 31
+#define GIC_SH_WEDGE_RW_MSK (MSK(1) << GIC_SH_WEDGE_RW_SHF)
+
+#define GIC_MAP_TO_PIN_SHF 31
+#define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF)
+#define GIC_MAP_TO_NMI_SHF 30
+#define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF)
+#define GIC_MAP_TO_YQ_SHF 29
+#define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF)
+#define GIC_MAP_SHF 0
+#define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF)
+#define GIC_MAP_TO_PIN_REG_MSK \
+ (GIC_MAP_TO_PIN_MSK | GIC_MAP_TO_NMI_MSK | GIC_MAP_TO_YQ_MSK | GIC_MAP_MSK)
+
+/* GIC_VP_CTL Masks */
+#define GIC_VP_CTL_FDC_RTBL_SHF 4
+#define GIC_VP_CTL_FDC_RTBL_MSK (MSK(1) << GIC_VP_CTL_FDC_RTBL_SHF)
+#define GIC_VP_CTL_SWINT_RTBL_SHF 3
+#define GIC_VP_CTL_SWINT_RTBL_MSK (MSK(1) << GIC_VP_CTL_SWINT_RTBL_SHF)
+#define GIC_VP_CTL_PERFCNT_RTBL_SHF 2
+#define GIC_VP_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VP_CTL_PERFCNT_RTBL_SHF)
+#define GIC_VP_CTL_TIMER_RTBL_SHF 1
+#define GIC_VP_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VP_CTL_TIMER_RTBL_SHF)
+#define GIC_VP_CTL_EIC_MODE_SHF 0
+#define GIC_VP_CTL_EIC_MODE_MSK (MSK(1) << GIC_VP_CTL_EIC_MODE_SHF)
+
+/* GIC_VP_MASK Masks */
+#define GIC_VP_MASK_FDC_SHF 6
+#define GIC_VP_MASK_FDC_MSK (MSK(1) << GIC_VP_MASK_FDC_SHF)
+#define GIC_VP_MASK_SWINT1_SHF 5
+#define GIC_VP_MASK_SWINT1_MSK (MSK(1) << GIC_VP_MASK_SWINT1_SHF)
+#define GIC_VP_MASK_SWINT0_SHF 4
+#define GIC_VP_MASK_SWINT0_MSK (MSK(1) << GIC_VP_MASK_SWINT0_SHF)
+#define GIC_VP_MASK_PERFCNT_SHF 3
+#define GIC_VP_MASK_PERFCNT_MSK (MSK(1) << GIC_VP_MASK_PERFCNT_SHF)
+#define GIC_VP_MASK_TIMER_SHF 2
+#define GIC_VP_MASK_TIMER_MSK (MSK(1) << GIC_VP_MASK_TIMER_SHF)
+#define GIC_VP_MASK_CMP_SHF 1
+#define GIC_VP_MASK_CMP_MSK (MSK(1) << GIC_VP_MASK_CMP_SHF)
+#define GIC_VP_MASK_WD_SHF 0
+#define GIC_VP_MASK_WD_MSK (MSK(1) << GIC_VP_MASK_WD_SHF)
+#define GIC_VP_SET_RESET_MSK (MSK(7) << GIC_VP_MASK_WD_SHF)
+
+#define GIC_CPU_INT_MAX 5 /* Core Interrupt 7 */
+#define GIC_CPU_PIN_OFFSET 2
+
+/* Local GIC interrupts. */
+#define GIC_NUM_LOCAL_INTRS 7
+#define GIC_LOCAL_INT_FDC 6 /* CPU fast debug channel */
+#define GIC_LOCAL_INT_SWINT1 5 /* CPU software interrupt 1 */
+#define GIC_LOCAL_INT_SWINT0 4 /* CPU software interrupt 0 */
+#define GIC_LOCAL_INT_PERFCTR 3 /* CPU performance counter */
+#define GIC_LOCAL_INT_TIMER 2 /* CPU timer interrupt */
+#define GIC_LOCAL_INT_COMPARE 1 /* GIC count and compare timer */
+#define GIC_LOCAL_INT_WD 0 /* GIC watchdog */
+
+#define TYPE_MIPS_GIC "mips-gic"
+OBJECT_DECLARE_SIMPLE_TYPE(MIPSGICState, MIPS_GIC)
+
+/* Support up to 32 VPs and 256 IRQs */
+#define GIC_MAX_VPS 32
+#define GIC_MAX_INTRS 256
+
+typedef struct MIPSGICIRQState MIPSGICIRQState;
+typedef struct MIPSGICVPState MIPSGICVPState;
+
+struct MIPSGICIRQState {
+ uint8_t enabled;
+ uint8_t pending;
+ uint32_t map_pin;
+ int32_t map_vp;
+ qemu_irq irq;
+};
+
+struct MIPSGICVPState {
+ uint32_t ctl;
+ uint32_t pend;
+ uint32_t mask;
+ uint32_t compare_map;
+ uint32_t other_addr;
+ CPUMIPSState *env;
+};
+
+struct MIPSGICState {
+ SysBusDevice parent_obj;
+ MemoryRegion mr;
+
+ /* Shared Section Registers */
+ uint32_t sh_config;
+ MIPSGICIRQState *irq_state;
+
+ /* VP Local/Other Section Registers */
+ MIPSGICVPState *vps;
+
+ /* GIC VP Timer */
+ MIPSGICTimerState *gic_timer;
+
+ int32_t num_vps;
+ int32_t num_irq;
+};
+
+#endif /* MIPS_GIC_H */
diff --git a/include/hw/intc/ppc-uic.h b/include/hw/intc/ppc-uic.h
new file mode 100644
index 000000000..22dd5e5ac
--- /dev/null
+++ b/include/hw/intc/ppc-uic.h
@@ -0,0 +1,80 @@
+/*
+ * "Universal" Interrupt Controller for PowerPPC 4xx embedded processors
+ *
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_INTC_PPC_UIC_H
+#define HW_INTC_PPC_UIC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_PPC_UIC "ppc-uic"
+OBJECT_DECLARE_SIMPLE_TYPE(PPCUIC, PPC_UIC)
+
+/*
+ * QEMU interface:
+ * QOM property "cpu": link to the PPC CPU
+ * (no default, must be set)
+ * QOM property "dcr-base": base of the bank of DCR registers for the UIC
+ * (default 0x30)
+ * QOM property "use-vectors": true if the UIC has vector registers
+ * (default true)
+ * unnamed GPIO inputs 0..UIC_MAX_IRQ: input IRQ lines
+ * sysbus IRQs:
+ * 0 (PPCUIC_OUTPUT_INT): output INT line to the CPU
+ * 1 (PPCUIC_OUTPUT_CINT): output CINT line to the CPU
+ */
+
+#define UIC_MAX_IRQ 32
+
+/* Symbolic constants for the sysbus IRQ outputs */
+enum {
+ PPCUIC_OUTPUT_INT = 0,
+ PPCUIC_OUTPUT_CINT = 1,
+ PPCUIC_OUTPUT_NB,
+};
+
+struct PPCUIC {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ qemu_irq output_int;
+ qemu_irq output_cint;
+
+ /* properties */
+ CPUState *cpu;
+ uint32_t dcr_base;
+ bool use_vectors;
+
+ uint32_t level; /* Remembers the state of level-triggered interrupts. */
+ uint32_t uicsr; /* Status register */
+ uint32_t uicer; /* Enable register */
+ uint32_t uiccr; /* Critical register */
+ uint32_t uicpr; /* Polarity register */
+ uint32_t uictr; /* Triggering register */
+ uint32_t uicvcr; /* Vector configuration register */
+ uint32_t uicvr;
+};
+
+#endif
diff --git a/include/hw/intc/realview_gic.h b/include/hw/intc/realview_gic.h
new file mode 100644
index 000000000..f37339dc0
--- /dev/null
+++ b/include/hw/intc/realview_gic.h
@@ -0,0 +1,28 @@
+/*
+ * ARM RealView Emulation Baseboard Interrupt Controller
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GPL.
+ */
+
+#ifndef HW_INTC_REALVIEW_GIC_H
+#define HW_INTC_REALVIEW_GIC_H
+
+#include "hw/sysbus.h"
+#include "hw/intc/arm_gic.h"
+#include "qom/object.h"
+
+#define TYPE_REALVIEW_GIC "realview_gic"
+OBJECT_DECLARE_SIMPLE_TYPE(RealViewGICState, REALVIEW_GIC)
+
+struct RealViewGICState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion container;
+
+ GICState gic;
+};
+
+#endif
diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h
new file mode 100644
index 000000000..229bd08d2
--- /dev/null
+++ b/include/hw/intc/riscv_aclint.h
@@ -0,0 +1,80 @@
+/*
+ * RISC-V ACLINT (Advanced Core Local Interruptor) interface
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_RISCV_ACLINT_H
+#define HW_RISCV_ACLINT_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_RISCV_ACLINT_MTIMER "riscv.aclint.mtimer"
+
+#define RISCV_ACLINT_MTIMER(obj) \
+ OBJECT_CHECK(RISCVAclintMTimerState, (obj), TYPE_RISCV_ACLINT_MTIMER)
+
+typedef struct RISCVAclintMTimerState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion mmio;
+ uint32_t hartid_base;
+ uint32_t num_harts;
+ uint32_t timecmp_base;
+ uint32_t time_base;
+ uint32_t aperture_size;
+ uint32_t timebase_freq;
+ qemu_irq *timer_irqs;
+} RISCVAclintMTimerState;
+
+DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
+ uint32_t hartid_base, uint32_t num_harts,
+ uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq,
+ bool provide_rdtime);
+
+#define TYPE_RISCV_ACLINT_SWI "riscv.aclint.swi"
+
+#define RISCV_ACLINT_SWI(obj) \
+ OBJECT_CHECK(RISCVAclintSwiState, (obj), TYPE_RISCV_ACLINT_SWI)
+
+typedef struct RISCVAclintSwiState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion mmio;
+ uint32_t hartid_base;
+ uint32_t num_harts;
+ uint32_t sswi;
+ qemu_irq *soft_irqs;
+} RISCVAclintSwiState;
+
+DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base,
+ uint32_t num_harts, bool sswi);
+
+enum {
+ RISCV_ACLINT_DEFAULT_MTIMECMP = 0x0,
+ RISCV_ACLINT_DEFAULT_MTIME = 0x7ff8,
+ RISCV_ACLINT_DEFAULT_MTIMER_SIZE = 0x8000,
+ RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ = 10000000,
+ RISCV_ACLINT_MAX_HARTS = 4095,
+ RISCV_ACLINT_SWI_SIZE = 0x4000
+};
+
+#endif
diff --git a/include/hw/intc/rx_icu.h b/include/hw/intc/rx_icu.h
new file mode 100644
index 000000000..7f5889b36
--- /dev/null
+++ b/include/hw/intc/rx_icu.h
@@ -0,0 +1,76 @@
+/*
+ * RX Interrupt Control Unit
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_INTC_RX_ICU_H
+#define HW_INTC_RX_ICU_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+enum TRG_MODE {
+ TRG_LEVEL = 0,
+ TRG_NEDGE = 1, /* Falling */
+ TRG_PEDGE = 2, /* Raising */
+ TRG_BEDGE = 3, /* Both */
+};
+
+struct IRQSource {
+ enum TRG_MODE sense;
+ int level;
+};
+
+enum {
+ /* Software interrupt request */
+ SWI = 27,
+ NR_IRQS = 256
+};
+
+struct RXICUState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ MemoryRegion memory;
+ struct IRQSource src[NR_IRQS];
+ uint32_t nr_irqs;
+ uint8_t *map;
+ uint32_t nr_sense;
+ uint8_t *init_sense;
+
+ uint8_t ir[NR_IRQS];
+ uint8_t dtcer[NR_IRQS];
+ uint8_t ier[NR_IRQS / 8];
+ uint8_t ipr[142];
+ uint8_t dmasr[4];
+ uint16_t fir;
+ uint8_t nmisr;
+ uint8_t nmier;
+ uint8_t nmiclr;
+ uint8_t nmicr;
+ int16_t req_irq;
+ qemu_irq _irq;
+ qemu_irq _fir;
+ qemu_irq _swi;
+};
+
+#define TYPE_RX_ICU "rx-icu"
+OBJECT_DECLARE_SIMPLE_TYPE(RXICUState, RX_ICU)
+
+#endif /* RX_ICU_H */
diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
new file mode 100644
index 000000000..134cf39a9
--- /dev/null
+++ b/include/hw/intc/sifive_plic.h
@@ -0,0 +1,88 @@
+/*
+ * SiFive PLIC (Platform Level Interrupt Controller) interface
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * This provides a RISC-V PLIC device
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_SIFIVE_PLIC_H
+#define HW_SIFIVE_PLIC_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_SIFIVE_PLIC "riscv.sifive.plic"
+
+typedef struct SiFivePLICState SiFivePLICState;
+DECLARE_INSTANCE_CHECKER(SiFivePLICState, SIFIVE_PLIC,
+ TYPE_SIFIVE_PLIC)
+
+typedef enum PLICMode {
+ PLICMode_U,
+ PLICMode_S,
+ PLICMode_H,
+ PLICMode_M
+} PLICMode;
+
+typedef struct PLICAddr {
+ uint32_t addrid;
+ uint32_t hartid;
+ PLICMode mode;
+} PLICAddr;
+
+struct SiFivePLICState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion mmio;
+ uint32_t num_addrs;
+ uint32_t num_harts;
+ uint32_t bitfield_words;
+ uint32_t num_enables;
+ PLICAddr *addr_config;
+ uint32_t *source_priority;
+ uint32_t *target_priority;
+ uint32_t *pending;
+ uint32_t *claimed;
+ uint32_t *enable;
+
+ /* config */
+ char *hart_config;
+ uint32_t hartid_base;
+ uint32_t num_sources;
+ uint32_t num_priorities;
+ uint32_t priority_base;
+ uint32_t pending_base;
+ uint32_t enable_base;
+ uint32_t enable_stride;
+ uint32_t context_base;
+ uint32_t context_stride;
+ uint32_t aperture_size;
+
+ qemu_irq *m_external_irqs;
+ qemu_irq *s_external_irqs;
+};
+
+DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
+ uint32_t num_harts,
+ uint32_t hartid_base, uint32_t num_sources,
+ uint32_t num_priorities, uint32_t priority_base,
+ uint32_t pending_base, uint32_t enable_base,
+ uint32_t enable_stride, uint32_t context_base,
+ uint32_t context_stride, uint32_t aperture_size);
+
+#endif
diff --git a/include/hw/intc/xlnx-pmu-iomod-intc.h b/include/hw/intc/xlnx-pmu-iomod-intc.h
new file mode 100644
index 000000000..ccc8bd272
--- /dev/null
+++ b/include/hw/intc/xlnx-pmu-iomod-intc.h
@@ -0,0 +1,57 @@
+/*
+ * QEMU model of Xilinx I/O Module Interrupt Controller
+ *
+ * Copyright (c) 2014 Xilinx Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_INTC_XLNX_PMU_IOMOD_INTC_H
+#define HW_INTC_XLNX_PMU_IOMOD_INTC_H
+
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "qom/object.h"
+
+#define TYPE_XLNX_PMU_IO_INTC "xlnx.pmu_io_intc"
+
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxPMUIOIntc, XLNX_PMU_IO_INTC)
+
+/* This is R_PIT3_CONTROL + 1 */
+#define XLNXPMUIOINTC_R_MAX (0x78 + 1)
+
+struct XlnxPMUIOIntc {
+ SysBusDevice parent_obj;
+ MemoryRegion iomem;
+
+ qemu_irq parent_irq;
+
+ struct {
+ uint32_t intr_size;
+ uint32_t level_edge;
+ uint32_t positive;
+ } cfg;
+
+ uint32_t irq_raw;
+
+ uint32_t regs[XLNXPMUIOINTC_R_MAX];
+ RegisterInfo regs_info[XLNXPMUIOINTC_R_MAX];
+};
+
+#endif /* HW_INTC_XLNX_PMU_IOMOD_INTC_H */
diff --git a/include/hw/intc/xlnx-zynqmp-ipi.h b/include/hw/intc/xlnx-zynqmp-ipi.h
new file mode 100644
index 000000000..33eff1d4f
--- /dev/null
+++ b/include/hw/intc/xlnx-zynqmp-ipi.h
@@ -0,0 +1,56 @@
+/*
+ * QEMU model of the IPI Inter Processor Interrupt block
+ *
+ * Copyright (c) 2014 Xilinx Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef XLNX_ZYNQMP_IPI_H
+#define XLNX_ZYNQMP_IPI_H
+
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "qom/object.h"
+
+#define TYPE_XLNX_ZYNQMP_IPI "xlnx.zynqmp_ipi"
+
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPIPI, XLNX_ZYNQMP_IPI)
+
+/* This is R_IPI_IDR + 1 */
+#define R_XLNX_ZYNQMP_IPI_MAX ((0x1c / 4) + 1)
+
+#define NUM_IPIS 11
+
+struct XlnxZynqMPIPI {
+ /* Private */
+ SysBusDevice parent_obj;
+
+ /* Public */
+ MemoryRegion iomem;
+ qemu_irq irq;
+
+ qemu_irq irq_trig_out[NUM_IPIS];
+ qemu_irq irq_obs_out[NUM_IPIS];
+
+ uint32_t regs[R_XLNX_ZYNQMP_IPI_MAX];
+ RegisterInfo regs_info[R_XLNX_ZYNQMP_IPI_MAX];
+};
+
+#endif /* XLNX_ZYNQMP_IPI_H */