dev-arm: Implement GIC-400 model from GicV2
Implementation registers for the GICv2 model currently hold values referring to a GIC-400 implementation. This patch is making them parametrizable so that it is possible to instantiate a GIC-400 model. The patch is also modifying Realview platform to use new GIC-400 model in lieau of GICv2. Change-Id: I446db8c796ee3c2708af91e9139f0a6e7947321b 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/15277 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -49,6 +49,15 @@ class BaseGic(PioDevice):
|
||||
|
||||
platform = Param.Platform(Parent.any, "Platform this device is part of.")
|
||||
|
||||
gicd_iidr = Param.UInt32(0,
|
||||
"Distributor Implementer Identification Register")
|
||||
gicd_pidr = Param.UInt32(0,
|
||||
"Peripheral Identification Register")
|
||||
gicc_iidr = Param.UInt32(0,
|
||||
"CPU Interface Identification Register")
|
||||
gicv_iidr = Param.UInt32(0,
|
||||
"VM CPU Interface Identification Register")
|
||||
|
||||
class ArmInterruptPin(SimObject):
|
||||
type = 'ArmInterruptPin'
|
||||
cxx_header = "dev/arm/base_gic.hh"
|
||||
@@ -81,6 +90,19 @@ class GicV2(BaseGic):
|
||||
it_lines = Param.UInt32(128, "Number of interrupt lines supported (max = 1020)")
|
||||
gem5_extensions = Param.Bool(False, "Enable gem5 extensions")
|
||||
|
||||
class Gic400(GicV2):
|
||||
"""
|
||||
As defined in:
|
||||
"ARM Generic Interrupt Controller Architecture" version 2.0
|
||||
"CoreLink GIC-400 Generic Interrupt Controller" revision r0p1
|
||||
"""
|
||||
gicd_pidr = 0x002bb490
|
||||
gicd_iidr = 0x0200143B
|
||||
gicc_iidr = 0x0202143B
|
||||
|
||||
# gicv_iidr same as gicc_idr
|
||||
gicv_iidr = gicc_iidr
|
||||
|
||||
class Gicv2mFrame(SimObject):
|
||||
type = 'Gicv2mFrame'
|
||||
cxx_header = "dev/arm/gic_v2m.hh"
|
||||
@@ -107,6 +129,10 @@ class VGic(PioDevice):
|
||||
# The number of list registers is not currently configurable at runtime.
|
||||
ppint = Param.UInt32("HV maintenance interrupt number")
|
||||
|
||||
# gicv_iidr same as gicc_idr
|
||||
gicv_iidr = Param.UInt32(Self.gic.gicc_iidr,
|
||||
"VM CPU Interface Identification Register")
|
||||
|
||||
def generateDeviceTree(self, state):
|
||||
gic = self.gic.unproxy(self)
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ try:
|
||||
except ImportError:
|
||||
# KVM support wasn't compiled into gem5. Fallback to a
|
||||
# software-only GIC.
|
||||
kvm_gicv2_class = GicV2
|
||||
kvm_gicv2_class = Gic400
|
||||
pass
|
||||
|
||||
class AmbaPioDevice(BasicPioDevice):
|
||||
@@ -574,7 +574,7 @@ class RealViewPBX(RealView):
|
||||
realview_io = RealViewCtrl(pio_addr=0x10000000)
|
||||
mcc = VExpressMCC()
|
||||
dcc = CoreTile2A15DCC()
|
||||
gic = GicV2(cpu_addr=0x1f000100, dist_addr=0x1f001000, cpu_size=0x100)
|
||||
gic = Gic400(cpu_addr=0x1f000100, dist_addr=0x1f001000, cpu_size=0x100)
|
||||
pci_host = GenericPciHost(
|
||||
conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
|
||||
pci_pio_base=0)
|
||||
@@ -721,7 +721,7 @@ class VExpress_EMM(RealView):
|
||||
dcc = CoreTile2A15DCC()
|
||||
|
||||
### On-chip devices ###
|
||||
gic = GicV2(dist_addr=0x2C001000, cpu_addr=0x2C002000)
|
||||
gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
|
||||
vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
|
||||
|
||||
local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
|
||||
@@ -820,7 +820,8 @@ class VExpress_EMM(RealView):
|
||||
InterruptLine=2, InterruptPin=2)
|
||||
|
||||
def enableMSIX(self):
|
||||
self.gic = GicV2(dist_addr=0x2C001000, cpu_addr=0x2C002000, it_lines=512)
|
||||
self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
|
||||
it_lines=512)
|
||||
self.gicv2m = Gicv2m()
|
||||
self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
|
||||
|
||||
|
||||
@@ -64,6 +64,9 @@ const AddrRange GicV2::GICD_ICFGR (0xc00, 0xcff);
|
||||
|
||||
GicV2::GicV2(const Params *p)
|
||||
: BaseGic(p),
|
||||
gicdPIDR(p->gicd_pidr),
|
||||
gicdIIDR(p->gicd_iidr),
|
||||
giccIIDR(p->gicc_iidr),
|
||||
distRange(RangeSize(p->dist_addr, DIST_SIZE)),
|
||||
cpuRange(RangeSize(p->cpu_addr, p->cpu_size)),
|
||||
addrRanges{distRange, cpuRange},
|
||||
@@ -268,16 +271,16 @@ GicV2::readDistributor(ContextID ctx, Addr daddr, size_t resp_sz)
|
||||
(haveGem5Extensions ? 0x100 : 0x0));
|
||||
case GICD_PIDR0:
|
||||
//ARM defined DevID
|
||||
return (GICD_400_PIDR_VALUE & 0xFF);
|
||||
return (gicdPIDR & 0xFF);
|
||||
case GICD_PIDR1:
|
||||
return ((GICD_400_PIDR_VALUE >> 8) & 0xFF);
|
||||
return ((gicdPIDR >> 8) & 0xFF);
|
||||
case GICD_PIDR2:
|
||||
return ((GICD_400_PIDR_VALUE >> 16) & 0xFF);
|
||||
return ((gicdPIDR >> 16) & 0xFF);
|
||||
case GICD_PIDR3:
|
||||
return ((GICD_400_PIDR_VALUE >> 24) & 0xFF);
|
||||
return ((gicdPIDR >> 24) & 0xFF);
|
||||
case GICD_IIDR:
|
||||
/* revision id is resorted to 1 and variant to 0*/
|
||||
return GICD_400_IIDR_VALUE;
|
||||
return gicdIIDR;
|
||||
default:
|
||||
panic("Tried to read Gic distributor at offset %#x\n", daddr);
|
||||
break;
|
||||
@@ -307,7 +310,7 @@ GicV2::readCpu(ContextID ctx, Addr daddr)
|
||||
{
|
||||
switch(daddr) {
|
||||
case GICC_IIDR:
|
||||
return GICC_400_IIDR_VALUE;
|
||||
return giccIIDR;
|
||||
case GICC_CTLR:
|
||||
return cpuControl[ctx];
|
||||
case GICC_PMR:
|
||||
|
||||
@@ -75,14 +75,9 @@ class GicV2 : public BaseGic, public BaseGicRegisters
|
||||
DIST_SIZE = 0x1000,
|
||||
};
|
||||
|
||||
/**
|
||||
* As defined in:
|
||||
* "ARM Generic Interrupt Controller Architecture" version 2.0
|
||||
* "CoreLink GIC-400 Generic Interrupt Controller" revision r0p1
|
||||
*/
|
||||
static constexpr uint32_t GICD_400_PIDR_VALUE = 0x002bb490;
|
||||
static constexpr uint32_t GICD_400_IIDR_VALUE = 0x200143B;
|
||||
static constexpr uint32_t GICC_400_IIDR_VALUE = 0x202143B;
|
||||
const uint32_t gicdPIDR;
|
||||
const uint32_t gicdIIDR;
|
||||
const uint32_t giccIIDR;
|
||||
|
||||
static const AddrRange GICD_IGROUPR; // interrupt group (unimplemented)
|
||||
static const AddrRange GICD_ISENABLER; // interrupt set enable
|
||||
|
||||
Reference in New Issue
Block a user