summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-07-12 12:34:41 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-07-12 12:34:41 +0100
commit74e1b782b34e280b06a90f61fdbac5a046cbe491 (patch)
tree4e707525686a8c338ec5b013189a5f0d586e89a3 /include
parentc1ac514a0444cae0a822dd9a0e60ac77918c102c (diff)
parentcdc46fab07a122dfcc8a1054510a68d936ae3440 (diff)
downloadqemu-74e1b782b34e280b06a90f61fdbac5a046cbe491.zip
Merge remote-tracking branch 'remotes/lalrae/tags/mips-20160712' into staging
MIPS patches 2016-07-12 Changes: * support 10-bit ASIDs * MIPS64R6-generic renamed to I6400 * initial GIC support * implement RESET_BASE register in CM GCR # gpg: Signature made Tue 12 Jul 2016 11:49:50 BST # gpg: using RSA key 0x52118E3C0B29DA6B # gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.com>" # Primary key fingerprint: 8DD3 2F98 5495 9D66 35D4 4FC0 5211 8E3C 0B29 DA6B * remotes/lalrae/tags/mips-20160712: target-mips: enable 10-bit ASIDs in I6400 CPU target-mips: support CP0.Config4.AE bit target-mips: change ASID type to hold more than 8 bits target-mips: add ASID mask field and replace magic values target-mips: replace MIPS64R6-generic with the real I6400 CPU model hw/mips_cmgcr: implement RESET_BASE register in CM GCR hw/mips_cpc: make VP correctly start from the reset vector target-mips: add exception base to MIPS CPU hw/mips/cps: create GIC block inside CPS hw/mips: implement Global Interrupt Controller hw/mips: implement GIC Interval Timer Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r--include/hw/intc/mips_gic.h216
-rw-r--r--include/hw/mips/cps.h2
-rw-r--r--include/hw/misc/mips_cmgcr.h27
-rw-r--r--include/hw/timer/mips_gictimer.h46
4 files changed, 291 insertions, 0 deletions
diff --git a/include/hw/intc/mips_gic.h b/include/hw/intc/mips_gic.h
new file mode 100644
index 0000000000..dd6d44d731
--- /dev/null
+++ b/include/hw/intc/mips_gic.h
@@ -0,0 +1,216 @@
+/*
+ * 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 "hw/timer/mips_gictimer.h"
+#include "cpu.h"
+/*
+ * GIC Specific definitions
+ */
+
+/* The MIPS default location */
+#define GIC_BASE_ADDR 0x1bdc0000ULL
+#define GIC_ADDRSPACE_SZ (128 * 1024)
+
+/* 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"
+#define MIPS_GIC(obj) OBJECT_CHECK(MIPSGICState, (obj), TYPE_MIPS_GIC)
+
+/* Support up to 32 VPs and 256 IRQs */
+#define GIC_MAX_VPS 32
+#define GIC_MAX_INTRS 256
+
+typedef struct MIPSGICState MIPSGICState;
+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/mips/cps.h b/include/hw/mips/cps.h
index 4dbae9c8c9..526b8d0b11 100644
--- a/include/hw/mips/cps.h
+++ b/include/hw/mips/cps.h
@@ -22,6 +22,7 @@
#include "hw/sysbus.h"
#include "hw/misc/mips_cmgcr.h"
+#include "hw/intc/mips_gic.h"
#include "hw/misc/mips_cpc.h"
#include "hw/misc/mips_itu.h"
@@ -37,6 +38,7 @@ typedef struct MIPSCPSState {
MemoryRegion container;
MIPSGCRState gcr;
+ MIPSGICState gic;
MIPSCPCState cpc;
MIPSITUState itu;
} MIPSCPSState;
diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h
index cc60eefa53..690e1d6221 100644
--- a/include/hw/misc/mips_cmgcr.h
+++ b/include/hw/misc/mips_cmgcr.h
@@ -26,23 +26,45 @@
#define GCR_CONFIG_OFS 0x0000
#define GCR_BASE_OFS 0x0008
#define GCR_REV_OFS 0x0030
+#define GCR_GIC_BASE_OFS 0x0080
#define GCR_CPC_BASE_OFS 0x0088
+#define GCR_GIC_STATUS_OFS 0x00D0
#define GCR_CPC_STATUS_OFS 0x00F0
#define GCR_L2_CONFIG_OFS 0x0130
/* Core Local and Core Other Block Register Map */
#define GCR_CL_CONFIG_OFS 0x0010
#define GCR_CL_OTHER_OFS 0x0018
+#define GCR_CL_RESETBASE_OFS 0x0020
/* GCR_L2_CONFIG register fields */
#define GCR_L2_CONFIG_BYPASS_SHF 20
#define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF)
+/* GCR_GIC_BASE register fields */
+#define GCR_GIC_BASE_GICEN_MSK 1
+#define GCR_GIC_BASE_GICBASE_MSK 0xFFFFFFFE0000ULL
+#define GCR_GIC_BASE_MSK (GCR_GIC_BASE_GICEN_MSK | GCR_GIC_BASE_GICBASE_MSK)
+
/* GCR_CPC_BASE register fields */
#define GCR_CPC_BASE_CPCEN_MSK 1
#define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL
#define GCR_CPC_BASE_MSK (GCR_CPC_BASE_CPCEN_MSK | GCR_CPC_BASE_CPCBASE_MSK)
+/* GCR_CL_OTHER_OFS register fields */
+#define GCR_CL_OTHER_VPOTHER_MSK 0x7
+#define GCR_CL_OTHER_MSK GCR_CL_OTHER_VPOTHER_MSK
+
+/* GCR_CL_RESETBASE_OFS register fields */
+#define GCR_CL_RESET_BASE_RESETBASE_MSK 0xFFFFF000U
+#define GCR_CL_RESET_BASE_MSK GCR_CL_RESET_BASE_RESETBASE_MSK
+
+typedef struct MIPSGCRVPState MIPSGCRVPState;
+struct MIPSGCRVPState {
+ uint32_t other;
+ uint64_t reset_base;
+};
+
typedef struct MIPSGCRState MIPSGCRState;
struct MIPSGCRState {
SysBusDevice parent_obj;
@@ -52,8 +74,13 @@ struct MIPSGCRState {
hwaddr gcr_base;
MemoryRegion iomem;
MemoryRegion *cpc_mr;
+ MemoryRegion *gic_mr;
uint64_t cpc_base;
+ uint64_t gic_base;
+
+ /* VP Local/Other Registers */
+ MIPSGCRVPState *vps;
};
#endif /* _MIPS_GCR_H */
diff --git a/include/hw/timer/mips_gictimer.h b/include/hw/timer/mips_gictimer.h
new file mode 100644
index 0000000000..e3ca45c533
--- /dev/null
+++ b/include/hw/timer/mips_gictimer.h
@@ -0,0 +1,46 @@
+/*
+ * 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) 2016 Imagination Technologies
+ *
+ */
+
+#ifndef _MIPS_GICTIMER_H_
+#define _MIPS_GICTIMER_H_
+
+typedef struct MIPSGICTimerVPState MIPSGICTimerVPState;
+typedef struct MIPSGICTimerState MIPSGICTimerState;
+
+typedef void MIPSGICTimerCB(void *opaque, uint32_t vp_index);
+
+struct MIPSGICTimerVPState {
+ QEMUTimer *qtimer;
+ uint32_t vp_index;
+ uint32_t comparelo;
+ MIPSGICTimerState *gictimer;
+};
+
+struct MIPSGICTimerState {
+ void *opaque;
+ uint8_t countstop;
+ uint32_t sh_counterlo;
+ int32_t num_vps;
+ MIPSGICTimerVPState *vptimers;
+ MIPSGICTimerCB *cb;
+};
+
+uint32_t mips_gictimer_get_sh_count(MIPSGICTimerState *gic);
+void mips_gictimer_store_sh_count(MIPSGICTimerState *gic, uint64_t count);
+uint32_t mips_gictimer_get_vp_compare(MIPSGICTimerState *gictimer,
+ uint32_t vp_index);
+void mips_gictimer_store_vp_compare(MIPSGICTimerState *gic, uint32_t vp_index,
+ uint64_t compare);
+uint8_t mips_gictimer_get_countstop(MIPSGICTimerState *gic);
+void mips_gictimer_start_count(MIPSGICTimerState *gic);
+void mips_gictimer_stop_count(MIPSGICTimerState *gic);
+MIPSGICTimerState *mips_gictimer_init(void *opaque, uint32_t nvps,
+ MIPSGICTimerCB *cb);
+
+#endif /* _MIPS_GICTIMER_H_ */