Files
gem5/src/dev/arm/gic_v3_cpu_interface.hh
Giacomo Travaglini 5c891178b9 dev-arm: Read correct version of ICC_BPR register
Some methods like groupPriorityMask check for the value of binary point
registers. Those registers have a minimum value.  Writing to those
register is taking this into account, but the problem with the minimum
value arises when the value is checked before sw is writing to them.
In this case the minimum value won't be considered if the read is
directly forwarded to the ISA class.

Change-Id: Id432a37f1634b02bc478d65c52ffb88323d4bb77
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18598
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
2019-05-02 14:42:42 +00:00

340 lines
10 KiB
C++

/*
* 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 Gicv3Distributor;
class Gicv3Redistributor;
class Gicv3CPUInterface : public ArmISA::BaseISADevice, public Serializable
{
private:
friend class Gicv3Distributor;
friend class Gicv3Redistributor;
protected:
Gicv3 * gic;
Gicv3Redistributor * redistributor;
Gicv3Distributor * distributor;
uint32_t cpuId;
ArmInterruptPin *maintenanceInterrupt;
BitUnion64(ICC_CTLR_EL1)
Bitfield<63, 20> res0_3;
Bitfield<19> ExtRange;
Bitfield<18> RSS;
Bitfield<17, 16> res0_2;
Bitfield<15> A3V;
Bitfield<14> SEIS;
Bitfield<13, 11> IDbits;
Bitfield<10, 8> PRIbits;
Bitfield<7> res0_1;
Bitfield<6> PMHE;
Bitfield<5, 2> res0_0;
Bitfield<1> EOImode;
Bitfield<0> CBPR;
EndBitUnion(ICC_CTLR_EL1)
BitUnion64(ICC_CTLR_EL3)
Bitfield<63, 20> res0_2;
Bitfield<19> ExtRange;
Bitfield<18> RSS;
Bitfield<17> nDS;
Bitfield<16> res0_1;
Bitfield<15> A3V;
Bitfield<14> SEIS;
Bitfield<13, 11> IDbits;
Bitfield<10, 8> PRIbits;
Bitfield<7> res0_0;
Bitfield<6> PMHE;
Bitfield<5> RM;
Bitfield<4> EOImode_EL1NS;
Bitfield<3> EOImode_EL1S;
Bitfield<2> EOImode_EL3;
Bitfield<1> CBPR_EL1NS;
Bitfield<0> CBPR_EL1S;
EndBitUnion(ICC_CTLR_EL3)
BitUnion64(ICC_IGRPEN0_EL1)
Bitfield<63, 1> res0;
Bitfield<0> Enable;
EndBitUnion(ICC_IGRPEN0_EL1)
BitUnion64(ICC_IGRPEN1_EL1)
Bitfield<63, 1> res0;
Bitfield<0> Enable;
EndBitUnion(ICC_IGRPEN1_EL1)
BitUnion64(ICC_IGRPEN1_EL3)
Bitfield<63, 2> res0;
Bitfield<1> EnableGrp1S;
Bitfield<0> EnableGrp1NS;
EndBitUnion(ICC_IGRPEN1_EL3)
BitUnion64(ICC_SRE_EL1)
Bitfield<63, 3> res0;
Bitfield<2> DIB;
Bitfield<1> DFB;
Bitfield<0> SRE;
EndBitUnion(ICC_SRE_EL1)
BitUnion64(ICC_SRE_EL2)
Bitfield<63, 4> res0;
Bitfield<3> Enable;
Bitfield<2> DIB;
Bitfield<1> DFB;
Bitfield<0> SRE;
EndBitUnion(ICC_SRE_EL2)
BitUnion64(ICC_SRE_EL3)
Bitfield<63, 4> res0;
Bitfield<3> Enable;
Bitfield<2> DIB;
Bitfield<1> DFB;
Bitfield<0> SRE;
EndBitUnion(ICC_SRE_EL3)
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;
BitUnion64(ICH_HCR_EL2)
Bitfield<63, 32> res0_2;
Bitfield<31, 27> EOIcount;
Bitfield<26, 15> res0_1;
Bitfield<14> TDIR;
Bitfield<13> TSEI;
Bitfield<12> TALL1;
Bitfield<11> TALL0;
Bitfield<10> TC;
Bitfield<9, 8> res0_0;
Bitfield<7> VGrp1DIE;
Bitfield<6> VGrp1EIE;
Bitfield<5> VGrp0DIE;
Bitfield<4> VGrp0EIE;
Bitfield<3> NPIE;
Bitfield<2> LRENPIE;
Bitfield<1> UIE;
Bitfield<0> En;
EndBitUnion(ICH_HCR_EL2)
BitUnion64(ICH_LR_EL2)
Bitfield<63, 62> State;
Bitfield<61> HW;
Bitfield<60> Group;
Bitfield<59, 56> res0_1;
Bitfield<55, 48> Priority;
Bitfield<47, 45> res0_0;
Bitfield<44, 32> pINTID;
Bitfield<41> EOI;
Bitfield<31, 0> vINTID;
EndBitUnion(ICH_LR_EL2)
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;
BitUnion32(ICH_LRC)
Bitfield<31, 30> State;
Bitfield<29> HW;
Bitfield<28> Group;
Bitfield<27, 24> res0_1;
Bitfield<23, 16> Priority;
Bitfield<15, 13> res0_0;
Bitfield<12, 0> pINTID;
Bitfield<9> EOI;
EndBitUnion(ICH_LRC)
BitUnion64(ICH_MISR_EL2)
Bitfield<63, 8> res0;
Bitfield<7> VGrp1D;
Bitfield<6> VGrp1E;
Bitfield<5> VGrp0D;
Bitfield<4> VGrp0E;
Bitfield<3> NP;
Bitfield<2> LRENP;
Bitfield<1> U;
Bitfield<0> EOI;
EndBitUnion(ICH_MISR_EL2)
BitUnion64(ICH_VMCR_EL2)
Bitfield<63, 32> res0_2;
Bitfield<31, 24> VPMR;
Bitfield<23, 21> VBPR0;
Bitfield<20, 18> VBPR1;
Bitfield<17, 10> res0_1;
Bitfield<9> VEOIM;
Bitfield<8, 5> res0_0;
Bitfield<4> VCBPR;
Bitfield<3> VFIQEn;
Bitfield<2> VAckCtl;
Bitfield<1> VENG1;
Bitfield<0> VENG0;
EndBitUnion(ICH_VMCR_EL2)
BitUnion64(ICH_VTR_EL2)
Bitfield<63, 32> res0_1;
Bitfield<31, 29> PRIbits;
Bitfield<28, 26> PREbits;
Bitfield<25, 23> IDbits;
Bitfield<22> SEIS;
Bitfield<21> A3V;
Bitfield<20> res1;
Bitfield<19> TDS;
Bitfield<18, 5> res0_0;
Bitfield<4, 0> ListRegs;
EndBitUnion(ICH_VTR_EL2)
BitUnion64(ICV_CTLR_EL1)
Bitfield<63, 19> res0_2;
Bitfield<18> RSS;
Bitfield<17, 16> res0_1;
Bitfield<15> A3V;
Bitfield<14> SEIS;
Bitfield<13, 11> IDbits;
Bitfield<10, 8> PRIbits;
Bitfield<7, 2> res0_0;
Bitfield<1> EOImode;
Bitfield<0> CBPR;
EndBitUnion(ICV_CTLR_EL1)
protected:
void activateIRQ(uint32_t intid, Gicv3::GroupId group);
int currEL() const;
void deactivateIRQ(uint32_t intid, Gicv3::GroupId group);
void dropPriority(Gicv3::GroupId group);
uint64_t eoiMaintenanceInterruptStatus() const;
bool getHCREL2FMO() const;
bool getHCREL2IMO() const;
uint32_t getHPPIR0() const;
uint32_t getHPPIR1() const;
int getHPPVILR() const;
bool groupEnabled(Gicv3::GroupId group) const;
uint32_t groupPriorityMask(Gicv3::GroupId group);
bool haveEL(ArmISA::ExceptionLevel el) const;
int highestActiveGroup() const;
uint8_t highestActivePriority() const;
bool hppiCanPreempt();
bool hppviCanPreempt(int lrIdx) const;
bool inSecureState() const;
ArmISA::InterruptTypes intSignalType(Gicv3::GroupId group) const;
bool isAA64() const;
bool isEL3OrMon() const;
bool isEOISplitMode() const;
bool isSecureBelowEL3() const;
ICH_MISR_EL2 maintenanceInterruptStatus() const;
void reset();
void serialize(CheckpointOut & cp) const override;
void unserialize(CheckpointIn & cp) override;
void update();
void virtualActivateIRQ(uint32_t lrIdx);
void virtualDeactivateIRQ(int lrIdx);
uint8_t virtualDropPriority();
int virtualFindActive(uint32_t intid) const;
uint32_t virtualGroupPriorityMask(Gicv3::GroupId group) const;
uint8_t virtualHighestActivePriority() const;
void virtualIncrementEOICount();
bool virtualIsEOISplitMode() const;
void virtualUpdate();
public:
Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id);
void init();
void initState();
public: // BaseISADevice
RegVal readMiscReg(int misc_reg) override;
void setMiscReg(int misc_reg, RegVal val) override;
void setThreadContext(ThreadContext *tc) override;
};
#endif //__DEV_ARM_GICV3_CPU_INTERFACE_H__