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:
Giacomo Travaglini
2018-12-21 10:26:55 +00:00
parent 75831ce5b7
commit 90ed58bcb1
4 changed files with 43 additions and 18 deletions

View File

@@ -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)

View File

@@ -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)]

View File

@@ -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:

View File

@@ -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