summaryrefslogtreecommitdiff
path: root/src/dev/arm/gic_v3_cpu_interface.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/arm/gic_v3_cpu_interface.hh')
-rw-r--r--src/dev/arm/gic_v3_cpu_interface.hh301
1 files changed, 301 insertions, 0 deletions
diff --git a/src/dev/arm/gic_v3_cpu_interface.hh b/src/dev/arm/gic_v3_cpu_interface.hh
new file mode 100644
index 000000000..63d3b5327
--- /dev/null
+++ b/src/dev/arm/gic_v3_cpu_interface.hh
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2018 Metempsy Technology Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Jairo Balart
+ */
+
+#ifndef __DEV_ARM_GICV3_CPU_INTERFACE_H__
+#define __DEV_ARM_GICV3_CPU_INTERFACE_H__
+
+#include "arch/arm/isa_device.hh"
+#include "dev/arm/gic_v3.hh"
+
+class Gicv3Redistributor;
+class Gicv3Distributor;
+
+class Gicv3CPUInterface : public ArmISA::BaseISADevice, public Serializable
+{
+ private:
+
+ friend class Gicv3Redistributor;
+ friend class Gicv3Distributor;
+
+ protected:
+
+ Gicv3 * gic;
+ Gicv3Redistributor * redistributor;
+ Gicv3Distributor * distributor;
+ uint32_t cpuId;
+
+ static const uint32_t ICC_SRE_EL1_SRE = 1 << 0;
+ static const uint32_t ICC_SRE_EL1_DFB = 1 << 1;
+ static const uint32_t ICC_SRE_EL1_DIB = 1 << 2;
+
+ static const uint32_t ICC_SRE_EL2_SRE = 1 << 0;
+ static const uint32_t ICC_SRE_EL2_DFB = 1 << 1;
+ static const uint32_t ICC_SRE_EL2_DIB = 1 << 2;
+ static const uint32_t ICC_SRE_EL2_ENABLE = 1 << 3;
+
+ static const uint32_t ICC_SRE_EL3_SRE = 1 << 0;
+ static const uint32_t ICC_SRE_EL3_DFB = 1 << 1;
+ static const uint32_t ICC_SRE_EL3_DIB = 1 << 2;
+ static const uint32_t ICC_SRE_EL3_ENABLE = 1 << 3;
+
+ static const uint32_t ICC_CTLR_EL3_CBPR_EL1S = 1 << 0;
+ static const uint32_t ICC_CTLR_EL3_CBPR_EL1NS = 1 << 1;
+ static const uint32_t ICC_CTLR_EL3_EOIMODE_EL3 = 1 << 2;
+ static const uint32_t ICC_CTLR_EL3_EOIMODE_EL1S = 1 << 3;
+ static const uint32_t ICC_CTLR_EL3_EOIMODE_EL1NS = 1 << 4;
+ static const uint32_t ICC_CTLR_EL3_RM = 1 << 5;
+ static const uint32_t ICC_CTLR_EL3_PMHE = 1 << 6;
+ static const uint32_t ICC_CTLR_EL3_PRIBITS_SHIFT = 8;
+ static const uint32_t ICC_CTLR_EL3_IDBITS_SHIFT = 11;
+ static const uint32_t ICC_CTLR_EL3_SEIS = 1 << 14;
+ static const uint32_t ICC_CTLR_EL3_A3V = 1 << 15;
+ static const uint32_t ICC_CTLR_EL3_nDS = 1 << 17;
+ static const uint32_t ICC_CTLR_EL3_RSS = 1 << 18;
+
+ static const uint32_t ICC_CTLR_EL1_CBPR = 1 << 0;
+ static const uint32_t ICC_CTLR_EL1_EOIMODE = 1 << 1;
+ static const uint32_t ICC_CTLR_EL1_PMHE = 1 << 6;
+ static const uint32_t ICC_CTLR_EL1_SEIS = 1 << 14;
+ static const uint32_t ICC_CTLR_EL1_A3V = 1 << 15;
+ static const uint32_t ICC_CTLR_EL1_RSS = 1 << 18;
+ static const uint32_t ICC_CTLR_EL1_PRIBITS_SHIFT = 8;
+ static const uint32_t ICC_CTLR_EL1_PRIBITS_MASK =
+ 7U << ICC_CTLR_EL1_PRIBITS_SHIFT;
+ static const uint32_t ICC_CTLR_EL1_IDBITS_SHIFT = 11;
+
+ static const uint32_t ICC_IGRPEN0_EL1_ENABLE = 1 << 0;
+ static const uint32_t ICC_IGRPEN1_EL1_ENABLE = 1 << 0;
+
+ static const uint32_t ICC_IGRPEN1_EL3_ENABLEGRP1NS = 1 << 0;
+ static const uint32_t ICC_IGRPEN1_EL3_ENABLEGRP1S = 1 << 1;
+
+ static const uint8_t PRIORITY_BITS = 5;
+
+ /* Minimum BPR for Secure, or when security not enabled */
+ static const uint8_t GIC_MIN_BPR = 2;
+ /* Minimum BPR for Nonsecure when security is enabled */
+ static const uint8_t GIC_MIN_BPR_NS = GIC_MIN_BPR + 1;
+
+ static const uint8_t VIRTUAL_PRIORITY_BITS = 5;
+ static const uint8_t VIRTUAL_PREEMPTION_BITS = 5;
+ static const uint8_t VIRTUAL_NUM_LIST_REGS = 16;
+
+ static const uint8_t GIC_MIN_VBPR = 7 - VIRTUAL_PREEMPTION_BITS;
+
+ typedef struct {
+ uint32_t intid;
+ uint8_t prio;
+ Gicv3::GroupId group;
+ } hppi_t;
+
+ hppi_t hppi;
+
+ // GIC CPU interface memory mapped control registers (legacy)
+ enum {
+ GICC_CTLR = 0x0000,
+ GICC_PMR = 0x0004,
+ GICC_BPR = 0x0008,
+ GICC_IAR = 0x000C,
+ GICC_EOIR = 0x0010,
+ GICC_RPR = 0x0014,
+ GICC_HPPI = 0x0018,
+ GICC_ABPR = 0x001C,
+ GICC_AIAR = 0x0020,
+ GICC_AEOIR = 0x0024,
+ GICC_AHPPIR = 0x0028,
+ GICC_STATUSR = 0x002C,
+ GICC_IIDR = 0x00FC,
+ };
+
+ static const AddrRange GICC_APR;
+ static const AddrRange GICC_NSAPR;
+
+ // GIC CPU virtual interface memory mapped control registers (legacy)
+ enum {
+ GICH_HCR = 0x0000,
+ GICH_VTR = 0x0004,
+ GICH_VMCR = 0x0008,
+ GICH_MISR = 0x0010,
+ GICH_EISR = 0x0020,
+ GICH_ELRSR = 0x0030,
+ };
+
+ static const AddrRange GICH_APR;
+ static const AddrRange GICH_LR;
+
+ static const uint32_t ICH_HCR_EL2_EN = 1 << 0;
+ static const uint32_t ICH_HCR_EL2_UIE = 1 << 1;
+ static const uint32_t ICH_HCR_EL2_LRENPIE = 1 << 2;
+ static const uint32_t ICH_HCR_EL2_NPIE = 1 << 3;
+ static const uint32_t ICH_HCR_EL2_VGRP0EIE = 1 << 4;
+ static const uint32_t ICH_HCR_EL2_VGRP0DIE = 1 << 5;
+ static const uint32_t ICH_HCR_EL2_VGRP1EIE = 1 << 6;
+ static const uint32_t ICH_HCR_EL2_VGRP1DIE = 1 << 7;
+ static const uint32_t ICH_HCR_EL2_TC = 1 << 10;
+ static const uint32_t ICH_HCR_EL2_TALL0 = 1 << 11;
+ static const uint32_t ICH_HCR_EL2_TALL1 = 1 << 12;
+ static const uint32_t ICH_HCR_EL2_TSEI = 1 << 13;
+ static const uint32_t ICH_HCR_EL2_TDIR = 1 << 14;
+ static const uint32_t ICH_HCR_EL2_EOICOUNT_MASK = 0x1fU << 27;
+
+ static const uint64_t ICH_LR_EL2_VINTID_SHIFT = 0;
+ static const uint64_t ICH_LR_EL2_VINTID_LENGTH = 32;
+ static const uint64_t ICH_LR_EL2_VINTID_MASK =
+ (0xffffffffULL << ICH_LR_EL2_VINTID_SHIFT);
+ static const uint64_t ICH_LR_EL2_PINTID_SHIFT = 32;
+ static const uint64_t ICH_LR_EL2_PINTID_LENGTH = 10;
+ static const uint64_t ICH_LR_EL2_PINTID_MASK =
+ (0x3ffULL << ICH_LR_EL2_PINTID_SHIFT);
+ /* Note that EOI shares with the top bit of the pINTID field */
+ static const uint64_t ICH_LR_EL2_EOI = (1ULL << 41);
+ static const uint64_t ICH_LR_EL2_PRIORITY_SHIFT = 48;
+ static const uint64_t ICH_LR_EL2_PRIORITY_LENGTH = 8;
+ static const uint64_t ICH_LR_EL2_PRIORITY_MASK =
+ (0xffULL << ICH_LR_EL2_PRIORITY_SHIFT);
+ static const uint64_t ICH_LR_EL2_GROUP = (1ULL << 60);
+ static const uint64_t ICH_LR_EL2_HW = (1ULL << 61);
+ static const uint64_t ICH_LR_EL2_STATE_SHIFT = 62;
+ static const uint64_t ICH_LR_EL2_STATE_LENGTH = 2;
+ static const uint64_t ICH_LR_EL2_STATE_MASK =
+ (3ULL << ICH_LR_EL2_STATE_SHIFT);
+ /* values for the state field: */
+ static const uint64_t ICH_LR_EL2_STATE_INVALID = 0;
+ static const uint64_t ICH_LR_EL2_STATE_PENDING = 1;
+ static const uint64_t ICH_LR_EL2_STATE_ACTIVE = 2;
+ static const uint64_t ICH_LR_EL2_STATE_ACTIVE_PENDING = 3;
+ static const uint64_t ICH_LR_EL2_STATE_PENDING_BIT =
+ (1ULL << ICH_LR_EL2_STATE_SHIFT);
+ static const uint64_t ICH_LR_EL2_STATE_ACTIVE_BIT =
+ (2ULL << ICH_LR_EL2_STATE_SHIFT);
+
+ static const uint64_t ICH_LRC_PRIORITY_SHIFT =
+ ICH_LR_EL2_PRIORITY_SHIFT - 32;
+ static const uint64_t ICH_LRC_PRIORITY_LENGTH =
+ ICH_LR_EL2_PRIORITY_LENGTH;
+
+ static const uint32_t ICH_MISR_EL2_EOI = (1 << 0);
+ static const uint32_t ICH_MISR_EL2_U = (1 << 1);
+ static const uint32_t ICH_MISR_EL2_LRENP = (1 << 2);
+ static const uint32_t ICH_MISR_EL2_NP = (1 << 3);
+ static const uint32_t ICH_MISR_EL2_VGRP0E = (1 << 4);
+ static const uint32_t ICH_MISR_EL2_VGRP0D = (1 << 5);
+ static const uint32_t ICH_MISR_EL2_VGRP1E = (1 << 6);
+ static const uint32_t ICH_MISR_EL2_VGRP1D = (1 << 7);
+
+ static const uint32_t ICH_VMCR_EL2_VENG0_SHIFT = 0;
+ static const uint32_t ICH_VMCR_EL2_VENG0 =
+ (1 << ICH_VMCR_EL2_VENG0_SHIFT);
+ static const uint32_t ICH_VMCR_EL2_VENG1_SHIFT = 1;
+ static const uint32_t ICH_VMCR_EL2_VENG1 =
+ (1 << ICH_VMCR_EL2_VENG1_SHIFT);
+ static const uint32_t ICH_VMCR_EL2_VACKCTL = (1 << 2);
+ static const uint32_t ICH_VMCR_EL2_VFIQEN = (1 << 3);
+ static const uint32_t ICH_VMCR_EL2_VCBPR_SHIFT = 4;
+ static const uint32_t ICH_VMCR_EL2_VCBPR =
+ (1 << ICH_VMCR_EL2_VCBPR_SHIFT);
+ static const uint32_t ICH_VMCR_EL2_VEOIM_SHIFT = 9;
+ static const uint32_t ICH_VMCR_EL2_VEOIM =
+ (1 << ICH_VMCR_EL2_VEOIM_SHIFT);
+ static const uint32_t ICH_VMCR_EL2_VBPR1_SHIFT = 18;
+ static const uint32_t ICH_VMCR_EL2_VBPR1_LENGTH = 3;
+ static const uint32_t ICH_VMCR_EL2_VBPR1_MASK =
+ (0x7U << ICH_VMCR_EL2_VBPR1_SHIFT);
+ static const uint32_t ICH_VMCR_EL2_VBPR0_SHIFT = 21;
+ static const uint32_t ICH_VMCR_EL2_VBPR0_LENGTH = 3;
+ static const uint32_t ICH_VMCR_EL2_VBPR0_MASK =
+ (0x7U << ICH_VMCR_EL2_VBPR0_SHIFT);
+ static const uint32_t ICH_VMCR_EL2_VPMR_SHIFT = 24;
+ static const uint32_t ICH_VMCR_EL2_VPMR_LENGTH = 8;
+ static const uint32_t ICH_VMCR_EL2_VPMR_MASK =
+ (0xffU << ICH_VMCR_EL2_VPMR_SHIFT);
+
+ static const uint32_t ICH_VTR_EL2_LISTREGS_SHIFT = 0;
+ static const uint32_t ICH_VTR_EL2_TDS = 1 << 19;
+ static const uint32_t ICH_VTR_EL2_NV4 = 1 << 20;
+ static const uint32_t ICH_VTR_EL2_A3V = 1 << 21;
+ static const uint32_t ICH_VTR_EL2_SEIS = 1 << 22;
+ static const uint32_t ICH_VTR_EL2_IDBITS_SHIFT = 23;
+ static const uint32_t ICH_VTR_EL2_PREBITS_SHIFT = 26;
+ static const uint32_t ICH_VTR_EL2_PRIBITS_SHIFT = 29;
+
+ public:
+
+ Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id);
+ ~Gicv3CPUInterface();
+ void init();
+ void initState();
+
+ ArmISA::MiscReg readMiscReg(int misc_reg) override;
+ void setMiscReg(int misc_reg, ArmISA::MiscReg val) override;
+ void update();
+ void virtualUpdate();
+
+ void serialize(CheckpointOut & cp) const override;
+ void unserialize(CheckpointIn & cp) override;
+
+ protected:
+
+ void reset();
+ bool hppiCanPreempt();
+ bool hppviCanPreempt(int lrIdx);
+ bool groupEnabled(Gicv3::GroupId group);
+ uint8_t highestActivePriority();
+ uint8_t virtualHighestActivePriority();
+ bool inSecureState();
+ int currEL();
+ bool haveEL(ArmISA::ExceptionLevel el);
+ void activateIRQ(uint32_t intid, Gicv3::GroupId group);
+ void virtualActivateIRQ(uint32_t lrIdx);
+ void deactivateIRQ(uint32_t intid, Gicv3::GroupId group);
+ void virtualDeactivateIRQ(int lrIdx);
+ uint32_t groupPriorityMask(Gicv3::GroupId group);
+ uint32_t virtualGroupPriorityMask(Gicv3::GroupId group);
+ void dropPriority(Gicv3::GroupId group);
+ uint8_t virtualDropPriority();
+ ArmISA::InterruptTypes intSignalType(Gicv3::GroupId group);
+ bool isEOISplitMode();
+ bool virtualIsEOISplitMode();
+ bool isSecureBelowEL3();
+ bool inSecureState2();
+ uint32_t eoiMaintenanceInterruptStatus(uint32_t * misr);
+ uint32_t maintenanceInterruptStatus();
+ int highestActiveGroup();
+ bool getHCREL2FMO();
+ bool getHCREL2IMO();
+ uint32_t getHPPIR1();
+ uint32_t getHPPIR0();
+ int getHPPVILR();
+ int virtualFindActive(uint32_t intid);
+ void virtualIncrementEOICount();
+ bool isEL3OrMon();
+ bool isAA64();
+};
+
+#endif //__DEV_ARM_GICV3_CPU_INTERFACE_H__