arm: Clean up the GIC implementation
Lots of minor cleaups: * Make cached params const * Don't serialize params * Use AddrRange to represent the distributor and CPU address spaces * Store a const AddrRangeList of all PIO ranges Change-Id: I40a17bc3a38868fb3b8af247790e852cf99ddf1d Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Curtis Dunham <curtis.dunham@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2330 Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
parent
011ddf96fa
commit
35cb11f14e
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2013, 2015-2016 ARM Limited
|
* Copyright (c) 2010, 2013, 2015-2017 ARM Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
|
@ -63,8 +63,11 @@ const AddrRange Pl390::GICD_ITARGETSR (0x800, 0xbff);
|
||||||
const AddrRange Pl390::GICD_ICFGR (0xc00, 0xcff);
|
const AddrRange Pl390::GICD_ICFGR (0xc00, 0xcff);
|
||||||
|
|
||||||
Pl390::Pl390(const Params *p)
|
Pl390::Pl390(const Params *p)
|
||||||
: BaseGic(p), distAddr(p->dist_addr),
|
: BaseGic(p),
|
||||||
cpuAddr(p->cpu_addr), distPioDelay(p->dist_pio_delay),
|
distRange(RangeSize(p->dist_addr, DIST_SIZE)),
|
||||||
|
cpuRange(RangeSize(p->cpu_addr, CPU_SIZE)),
|
||||||
|
addrRanges{distRange, cpuRange},
|
||||||
|
distPioDelay(p->dist_pio_delay),
|
||||||
cpuPioDelay(p->cpu_pio_delay), intLatency(p->int_latency),
|
cpuPioDelay(p->cpu_pio_delay), intLatency(p->int_latency),
|
||||||
enabled(false), haveGem5Extensions(p->gem5_extensions),
|
enabled(false), haveGem5Extensions(p->gem5_extensions),
|
||||||
itLines(p->it_lines),
|
itLines(p->it_lines),
|
||||||
|
@ -93,12 +96,11 @@ Pl390::Pl390(const Params *p)
|
||||||
Tick
|
Tick
|
||||||
Pl390::read(PacketPtr pkt)
|
Pl390::read(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
|
const Addr addr = pkt->getAddr();
|
||||||
|
|
||||||
Addr addr = pkt->getAddr();
|
if (distRange.contains(addr))
|
||||||
|
|
||||||
if (addr >= distAddr && addr < distAddr + DIST_SIZE)
|
|
||||||
return readDistributor(pkt);
|
return readDistributor(pkt);
|
||||||
else if (addr >= cpuAddr && addr < cpuAddr + CPU_SIZE)
|
else if (cpuRange.contains(addr))
|
||||||
return readCpu(pkt);
|
return readCpu(pkt);
|
||||||
else
|
else
|
||||||
panic("Read to unknown address %#x\n", pkt->getAddr());
|
panic("Read to unknown address %#x\n", pkt->getAddr());
|
||||||
|
@ -108,12 +110,11 @@ Pl390::read(PacketPtr pkt)
|
||||||
Tick
|
Tick
|
||||||
Pl390::write(PacketPtr pkt)
|
Pl390::write(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
|
const Addr addr = pkt->getAddr();
|
||||||
|
|
||||||
Addr addr = pkt->getAddr();
|
if (distRange.contains(addr))
|
||||||
|
|
||||||
if (addr >= distAddr && addr < distAddr + DIST_SIZE)
|
|
||||||
return writeDistributor(pkt);
|
return writeDistributor(pkt);
|
||||||
else if (addr >= cpuAddr && addr < cpuAddr + CPU_SIZE)
|
else if (cpuRange.contains(addr))
|
||||||
return writeCpu(pkt);
|
return writeCpu(pkt);
|
||||||
else
|
else
|
||||||
panic("Write to unknown address %#x\n", pkt->getAddr());
|
panic("Write to unknown address %#x\n", pkt->getAddr());
|
||||||
|
@ -122,9 +123,8 @@ Pl390::write(PacketPtr pkt)
|
||||||
Tick
|
Tick
|
||||||
Pl390::readDistributor(PacketPtr pkt)
|
Pl390::readDistributor(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
Addr daddr = pkt->getAddr() - distAddr;
|
const Addr daddr = pkt->getAddr() - distRange.start();
|
||||||
|
const ContextID ctx = pkt->req->contextId();
|
||||||
ContextID ctx = pkt->req->contextId();
|
|
||||||
|
|
||||||
DPRINTF(GIC, "gic distributor read register %#x\n", daddr);
|
DPRINTF(GIC, "gic distributor read register %#x\n", daddr);
|
||||||
|
|
||||||
|
@ -267,10 +267,10 @@ done:
|
||||||
Tick
|
Tick
|
||||||
Pl390::readCpu(PacketPtr pkt)
|
Pl390::readCpu(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
Addr daddr = pkt->getAddr() - cpuAddr;
|
const Addr daddr = pkt->getAddr() - cpuRange.start();
|
||||||
|
|
||||||
assert(pkt->req->hasContextId());
|
assert(pkt->req->hasContextId());
|
||||||
ContextID ctx = pkt->req->contextId();
|
const ContextID ctx = pkt->req->contextId();
|
||||||
assert(ctx < sys->numRunningContexts());
|
assert(ctx < sys->numRunningContexts());
|
||||||
|
|
||||||
DPRINTF(GIC, "gic cpu read register %#x cpu context: %d\n", daddr,
|
DPRINTF(GIC, "gic cpu read register %#x cpu context: %d\n", daddr,
|
||||||
|
@ -361,10 +361,10 @@ Pl390::readCpu(PacketPtr pkt)
|
||||||
Tick
|
Tick
|
||||||
Pl390::writeDistributor(PacketPtr pkt)
|
Pl390::writeDistributor(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
Addr daddr = pkt->getAddr() - distAddr;
|
const Addr daddr = pkt->getAddr() - distRange.start();
|
||||||
|
|
||||||
assert(pkt->req->hasContextId());
|
assert(pkt->req->hasContextId());
|
||||||
ContextID ctx = pkt->req->contextId();
|
const ContextID ctx = pkt->req->contextId();
|
||||||
|
|
||||||
uint32_t pkt_data M5_VAR_USED;
|
uint32_t pkt_data M5_VAR_USED;
|
||||||
switch (pkt->getSize())
|
switch (pkt->getSize())
|
||||||
|
@ -520,10 +520,10 @@ done:
|
||||||
Tick
|
Tick
|
||||||
Pl390::writeCpu(PacketPtr pkt)
|
Pl390::writeCpu(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
Addr daddr = pkt->getAddr() - cpuAddr;
|
const Addr daddr = pkt->getAddr() - cpuRange.start();
|
||||||
|
|
||||||
assert(pkt->req->hasContextId());
|
assert(pkt->req->hasContextId());
|
||||||
ContextID ctx = pkt->req->contextId();
|
const ContextID ctx = pkt->req->contextId();
|
||||||
IAR iar;
|
IAR iar;
|
||||||
|
|
||||||
DPRINTF(GIC, "gic cpu write register cpu:%d %#x val: %#x\n",
|
DPRINTF(GIC, "gic cpu write register cpu:%d %#x val: %#x\n",
|
||||||
|
@ -816,25 +816,12 @@ Pl390::postInt(uint32_t cpu, Tick when)
|
||||||
eventq->schedule(postIntEvent[cpu], when);
|
eventq->schedule(postIntEvent[cpu], when);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddrRangeList
|
|
||||||
Pl390::getAddrRanges() const
|
|
||||||
{
|
|
||||||
AddrRangeList ranges;
|
|
||||||
ranges.push_back(RangeSize(distAddr, DIST_SIZE));
|
|
||||||
ranges.push_back(RangeSize(cpuAddr, CPU_SIZE));
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Pl390::serialize(CheckpointOut &cp) const
|
Pl390::serialize(CheckpointOut &cp) const
|
||||||
{
|
{
|
||||||
DPRINTF(Checkpoint, "Serializing Arm GIC\n");
|
DPRINTF(Checkpoint, "Serializing Arm GIC\n");
|
||||||
|
|
||||||
SERIALIZE_SCALAR(distAddr);
|
|
||||||
SERIALIZE_SCALAR(cpuAddr);
|
|
||||||
SERIALIZE_SCALAR(distPioDelay);
|
|
||||||
SERIALIZE_SCALAR(cpuPioDelay);
|
|
||||||
SERIALIZE_SCALAR(enabled);
|
SERIALIZE_SCALAR(enabled);
|
||||||
SERIALIZE_SCALAR(itLines);
|
SERIALIZE_SCALAR(itLines);
|
||||||
SERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
|
SERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
|
||||||
|
@ -887,10 +874,6 @@ Pl390::unserialize(CheckpointIn &cp)
|
||||||
{
|
{
|
||||||
DPRINTF(Checkpoint, "Unserializing Arm GIC\n");
|
DPRINTF(Checkpoint, "Unserializing Arm GIC\n");
|
||||||
|
|
||||||
UNSERIALIZE_SCALAR(distAddr);
|
|
||||||
UNSERIALIZE_SCALAR(cpuAddr);
|
|
||||||
UNSERIALIZE_SCALAR(distPioDelay);
|
|
||||||
UNSERIALIZE_SCALAR(cpuPioDelay);
|
|
||||||
UNSERIALIZE_SCALAR(enabled);
|
UNSERIALIZE_SCALAR(enabled);
|
||||||
UNSERIALIZE_SCALAR(itLines);
|
UNSERIALIZE_SCALAR(itLines);
|
||||||
UNSERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
|
UNSERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2013, 2015-2016 ARM Limited
|
* Copyright (c) 2010, 2013, 2015-2017 ARM Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
|
@ -122,22 +122,26 @@ class Pl390 : public BaseGic
|
||||||
Bitfield<12,10> cpu_id;
|
Bitfield<12,10> cpu_id;
|
||||||
EndBitUnion(IAR)
|
EndBitUnion(IAR)
|
||||||
|
|
||||||
/** Distributor address GIC listens at */
|
protected: /* Params */
|
||||||
Addr distAddr;
|
/** Address range for the distributor interface */
|
||||||
|
const AddrRange distRange;
|
||||||
|
|
||||||
/** CPU address GIC listens at */
|
/** Address range for the CPU interfaces */
|
||||||
/** @todo is this one per cpu? */
|
const AddrRange cpuRange;
|
||||||
Addr cpuAddr;
|
|
||||||
|
/** All address ranges used by this GIC */
|
||||||
|
const AddrRangeList addrRanges;
|
||||||
|
|
||||||
/** Latency for a distributor operation */
|
/** Latency for a distributor operation */
|
||||||
Tick distPioDelay;
|
const Tick distPioDelay;
|
||||||
|
|
||||||
/** Latency for a cpu operation */
|
/** Latency for a cpu operation */
|
||||||
Tick cpuPioDelay;
|
const Tick cpuPioDelay;
|
||||||
|
|
||||||
/** Latency for a interrupt to get to CPU */
|
/** Latency for a interrupt to get to CPU */
|
||||||
Tick intLatency;
|
const Tick intLatency;
|
||||||
|
|
||||||
|
protected:
|
||||||
/** Gic enabled */
|
/** Gic enabled */
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
|
||||||
|
@ -343,11 +347,11 @@ class Pl390 : public BaseGic
|
||||||
}
|
}
|
||||||
Pl390(const Params *p);
|
Pl390(const Params *p);
|
||||||
|
|
||||||
/** @{ */
|
void serialize(CheckpointOut &cp) const override;
|
||||||
/** Return the address ranges used by the Gic
|
void unserialize(CheckpointIn &cp) override;
|
||||||
* This is the distributor address + all cpu addresses
|
|
||||||
*/
|
public: /* PioDevice */
|
||||||
AddrRangeList getAddrRanges() const override;
|
AddrRangeList getAddrRanges() const { return addrRanges; }
|
||||||
|
|
||||||
/** A PIO read to the device, immediately split up into
|
/** A PIO read to the device, immediately split up into
|
||||||
* readDistributor() or readCpu()
|
* readDistributor() or readCpu()
|
||||||
|
@ -358,27 +362,15 @@ class Pl390 : public BaseGic
|
||||||
* writeDistributor() or writeCpu()
|
* writeDistributor() or writeCpu()
|
||||||
*/
|
*/
|
||||||
Tick write(PacketPtr pkt) override;
|
Tick write(PacketPtr pkt) override;
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** @{ */
|
public: /* BaseGic */
|
||||||
/** Post an interrupt from a device that is connected to the Gic.
|
|
||||||
* Depending on the configuration, the gic will pass this interrupt
|
|
||||||
* on through to a CPU.
|
|
||||||
* @param number number of interrupt to send */
|
|
||||||
void sendInt(uint32_t number) override;
|
void sendInt(uint32_t number) override;
|
||||||
|
|
||||||
/** Interface call for private peripheral interrupts */
|
|
||||||
void sendPPInt(uint32_t num, uint32_t cpu) override;
|
|
||||||
|
|
||||||
/** Clear an interrupt from a device that is connected to the Gic
|
|
||||||
* Depending on the configuration, the gic may de-assert it's cpu line
|
|
||||||
* @param number number of interrupt to send */
|
|
||||||
void clearInt(uint32_t number) override;
|
void clearInt(uint32_t number) override;
|
||||||
|
|
||||||
/** Clear a (level-sensitive) PPI */
|
void sendPPInt(uint32_t num, uint32_t cpu) override;
|
||||||
void clearPPInt(uint32_t num, uint32_t cpu) override;
|
void clearPPInt(uint32_t num, uint32_t cpu) override;
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
public: // Test & debug intefaces
|
||||||
/** @{ */
|
/** @{ */
|
||||||
/* Various functions fer testing and debugging */
|
/* Various functions fer testing and debugging */
|
||||||
void driveSPI(uint32_t spi);
|
void driveSPI(uint32_t spi);
|
||||||
|
@ -387,9 +379,6 @@ class Pl390 : public BaseGic
|
||||||
void driveIrqEn(bool state);
|
void driveIrqEn(bool state);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
void serialize(CheckpointOut &cp) const override;
|
|
||||||
void unserialize(CheckpointIn &cp) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Handle a read to the distributor portion of the GIC
|
/** Handle a read to the distributor portion of the GIC
|
||||||
* @param pkt packet to respond to
|
* @param pkt packet to respond to
|
||||||
|
|
Loading…
Reference in a new issue