changeset 1a70f8188580 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=1a70f8188580
description:
arm: bank GIC registers per CPU
Updated according to GICv2 documentation.
Change-Id: I5d926d1abf665eecc43ff0f7d6e561e1ee1c390a
Reviewed-by: Andreas Sandberg <[email protected]>
diffstat:
src/dev/arm/gic_pl390.cc | 370 +++++++++++++++------------
src/dev/arm/gic_pl390.hh | 161 ++++++++---
util/cpt_upgraders/arm-gicv2-banked-regs.py | 81 ++++++
3 files changed, 400 insertions(+), 212 deletions(-)
diffs (truncated from 937 to 300 lines):
diff -r af2f7fef4875 -r 1a70f8188580 src/dev/arm/gic_pl390.cc
--- a/src/dev/arm/gic_pl390.cc Tue Aug 02 11:34:32 2016 +0100
+++ b/src/dev/arm/gic_pl390.cc Tue Aug 02 13:35:45 2016 +0100
@@ -51,15 +51,29 @@
#include "mem/packet.hh"
#include "mem/packet_access.hh"
+const AddrRange Pl390::GICD_ISENABLER (0x100, 0x17f);
+const AddrRange Pl390::GICD_ICENABLER (0x180, 0x1ff);
+const AddrRange Pl390::GICD_ISPENDR (0x200, 0x27f);
+const AddrRange Pl390::GICD_ICPENDR (0x280, 0x2ff);
+const AddrRange Pl390::GICD_ISACTIVER (0x300, 0x37f);
+const AddrRange Pl390::GICD_ICACTIVER (0x380, 0x3ff);
+const AddrRange Pl390::GICD_IPRIORITYR(0x400, 0x7ff);
+const AddrRange Pl390::GICD_ITARGETSR (0x800, 0xbff);
+const AddrRange Pl390::GICD_ICFGR (0xc00, 0xcff);
+
Pl390::Pl390(const Params *p)
: BaseGic(p), distAddr(p->dist_addr),
cpuAddr(p->cpu_addr), distPioDelay(p->dist_pio_delay),
cpuPioDelay(p->cpu_pio_delay), intLatency(p->int_latency),
- enabled(false), itLines(p->it_lines),
- haveGem5Extensions(p->gem5_extensions), irqEnable(false)
+ enabled(false), haveGem5Extensions(p->gem5_extensions),
+ itLines(p->it_lines),
+ intEnabled {}, pendingInt {}, activeInt {},
+ intPriority {}, cpuTarget {}, intConfig {},
+ cpuSgiPending {}, cpuSgiActive {},
+ cpuSgiPendingExt {}, cpuSgiActiveExt {},
+ cpuPpiPending {}, cpuPpiActive {},
+ irqEnable(false)
{
- itLinesLog2 = ceilLog2(itLines);
-
for (int x = 0; x < CPU_MAX; x++) {
iccrpr[x] = 0xff;
cpuEnabled[x] = false;
@@ -72,38 +86,6 @@
DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled[0],
cpuEnabled[1]);
- for (int x = 0; x < INT_BITS_MAX; x++) {
- intEnabled[x] = 0;
- pendingInt[x] = 0;
- activeInt[x] = 0;
- }
-
- for (int x = 0; x < INT_LINES_MAX; x++) {
- intPriority[x] = 0;
- cpuTarget[x] = 0;
- }
-
- for (int x = 0; x < INT_BITS_MAX*2; x++) {
- intConfig[x] = 0;
- }
-
- for (int x = 0; x < SGI_MAX; x++) {
- cpuSgiActive[x] = 0;
- cpuSgiPending[x] = 0;
- }
- for (int x = 0; x < CPU_MAX; x++) {
- cpuPpiActive[x] = 0;
- cpuPpiPending[x] = 0;
- cpuSgiActiveExt[x] = 0;
- cpuSgiPendingExt[x] = 0;
- }
-
- for (int i = 0; i < CPU_MAX; i++) {
- for (int j = 0; j < (SGI_MAX + PPI_MAX); j++) {
- bankedIntPriority[i][j] = 0;
- }
- }
-
gem5ExtensionsEnabled = false;
}
@@ -145,63 +127,68 @@
DPRINTF(GIC, "gic distributor read register %#x\n", daddr);
- if (daddr >= GICD_ISENABLER_ST && daddr < GICD_ISENABLER_ED + 4) {
- assert((daddr-GICD_ISENABLER_ST) >> 2 < 32);
- pkt->set<uint32_t>(intEnabled[(daddr-GICD_ISENABLER_ST)>>2]);
+ if (GICD_ISENABLER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ISENABLER.start()) >> 2;
+ assert(ix < 32);
+ pkt->set<uint32_t>(getIntEnabled(ctx_id, ix));
goto done;
}
- if (daddr >= GICD_ICENABLER_ST && daddr < GICD_ICENABLER_ED + 4) {
- assert((daddr-GICD_ICENABLER_ST) >> 2 < 32);
- pkt->set<uint32_t>(intEnabled[(daddr-GICD_ICENABLER_ST)>>2]);
+ if (GICD_ICENABLER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ICENABLER.start()) >> 2;
+ assert(ix < 32);
+ pkt->set<uint32_t>(getIntEnabled(ctx_id, ix));
goto done;
}
- if (daddr >= GICD_ISPENDR_ST && daddr < GICD_ISPENDR_ED + 4) {
- assert((daddr-GICD_ISPENDR_ST) >> 2 < 32);
- pkt->set<uint32_t>(pendingInt[(daddr-GICD_ISPENDR_ST)>>2]);
+ if (GICD_ISPENDR.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ISPENDR.start()) >> 2;
+ assert(ix < 32);
+ pkt->set<uint32_t>(getPendingInt(ctx_id, ix));
goto done;
}
- if (daddr >= GICD_ICPENDR_ST && daddr < GICD_ICPENDR_ED + 4) {
- assert((daddr-GICD_ICPENDR_ST) >> 2 < 32);
- pkt->set<uint32_t>(pendingInt[(daddr-GICD_ICPENDR_ST)>>2]);
+ if (GICD_ICPENDR.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ICPENDR.start()) >> 2;
+ assert(ix < 32);
+ pkt->set<uint32_t>(getPendingInt(ctx_id, ix));
goto done;
}
- if (daddr >= GICD_ISACTIVER_ST && daddr < GICD_ISACTIVER_ED + 4) {
- assert((daddr-GICD_ISACTIVER_ST) >> 2 < 32);
- pkt->set<uint32_t>(activeInt[(daddr-GICD_ISACTIVER_ST)>>2]);
+ if (GICD_ISACTIVER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ISACTIVER.start()) >> 2;
+ assert(ix < 32);
+ pkt->set<uint32_t>(getPendingInt(ctx_id, ix));
goto done;
}
- if (daddr >= GICD_IPRIORITYR_ST && daddr < GICD_IPRIORITYR_ED + 4) {
- Addr int_num;
- int_num = daddr - GICD_IPRIORITYR_ST;
+ if (GICD_ICACTIVER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ICACTIVER.start()) >> 2;
+ assert(ix < 32);
+ pkt->set<uint32_t>(getPendingInt(ctx_id, ix));
+ goto done;
+ }
+
+ if (GICD_IPRIORITYR.contains(daddr)) {
+ Addr int_num = daddr - GICD_IPRIORITYR.start();
assert(int_num < INT_LINES_MAX);
DPRINTF(Interrupt, "Reading interrupt priority at int# %#x
\n",int_num);
- uint8_t* int_p;
- if (int_num < (SGI_MAX + PPI_MAX))
- int_p = bankedIntPriority[ctx_id];
- else
- int_p = intPriority;
-
switch (pkt->getSize()) {
case 1:
- pkt->set<uint8_t>(int_p[int_num]);
+ pkt->set<uint8_t>(getIntPriority(ctx_id, int_num));
break;
case 2:
assert((int_num + 1) < INT_LINES_MAX);
- pkt->set<uint16_t>(int_p[int_num] |
- int_p[int_num+1] << 8);
+ pkt->set<uint16_t>(getIntPriority(ctx_id, int_num) |
+ getIntPriority(ctx_id, int_num+1) << 8);
break;
case 4:
assert((int_num + 3) < INT_LINES_MAX);
- pkt->set<uint32_t>(int_p[int_num] |
- int_p[int_num+1] << 8 |
- int_p[int_num+2] << 16 |
- int_p[int_num+3] << 24);
+ pkt->set<uint32_t>(getIntPriority(ctx_id, int_num) |
+ getIntPriority(ctx_id, int_num+1) << 8 |
+ getIntPriority(ctx_id, int_num+2) << 16 |
+ getIntPriority(ctx_id, int_num+3) << 24);
break;
default:
panic("Invalid size while reading priority regs in GIC: %d\n",
@@ -210,9 +197,8 @@
goto done;
}
- if (daddr >= GICD_ITARGETSR_ST && daddr < GICD_ITARGETSR_ED + 4) {
- Addr int_num;
- int_num = (daddr-GICD_ITARGETSR_ST) ;
+ if (GICD_ITARGETSR.contains(daddr)) {
+ Addr int_num = daddr - GICD_ITARGETSR.start();
DPRINTF(GIC, "Reading processor target register for int# %#x \n",
int_num);
assert(int_num < INT_LINES_MAX);
@@ -246,12 +232,12 @@
goto done;
}
- if (daddr >= GICD_ICFGR_ST && daddr < GICD_ICFGR_ED + 4) {
- assert((daddr-GICD_ICFGR_ST) >> 2 < 64);
- /** @todo software generated interrutps and PPIs
- * can't be configured in some ways
- */
- pkt->set<uint32_t>(intConfig[(daddr-GICD_ICFGR_ST)>>2]);
+ if (GICD_ICFGR.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2;
+ assert(ix < 64);
+ /** @todo software generated interrupts and PPIs
+ * can't be configured in some ways */
+ pkt->set<uint32_t>(intConfig[ix]);
goto done;
}
@@ -262,8 +248,7 @@
case GICD_TYPER: {
/* The 0x100 is a made-up flag to show that gem5 extensions
* are available,
- * write 0x200 to this register to enable it.
- */
+ * write 0x200 to this register to enable it. */
uint32_t tmp = ((sys->numRunningContexts() - 1) << 5) |
(itLines/INT_BITS_MAX -1) |
(haveGem5Extensions ? 0x100 : 0x0);
@@ -342,7 +327,8 @@
uint32_t int_num = 1 << intNumToBit(cpuHighestInt[ctx_id]);
activeInt[intNumToWord(cpuHighestInt[ctx_id])] |= int_num;
updateRunPri();
- pendingInt[intNumToWord(cpuHighestInt[ctx_id])] &= ~int_num;
+ getPendingInt(ctx_id, intNumToWord(cpuHighestInt[ctx_id]))
+ &= ~int_num;
}
DPRINTF(Interrupt,"CPU %d reading IAR.id=%d IAR.cpu=%d,
iar=0x%x\n",
@@ -399,60 +385,70 @@
DPRINTF(GIC, "gic distributor write register %#x size %#x value %#x \n",
daddr, pkt->getSize(), pkt_data);
- if (daddr >= GICD_ISENABLER_ST && daddr < GICD_ISENABLER_ED + 4) {
- assert((daddr-GICD_ISENABLER_ST) >> 2 < 32);
- intEnabled[(daddr-GICD_ISENABLER_ST) >> 2] |= pkt->get<uint32_t>();
+ if (GICD_ISENABLER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ISENABLER.start()) >> 2;
+ assert(ix < 32);
+ getIntEnabled(ctx_id, ix) |= pkt->get<uint32_t>();
goto done;
}
- if (daddr >= GICD_ICENABLER_ST && daddr < GICD_ICENABLER_ED + 4) {
- assert((daddr-GICD_ICENABLER_ST) >> 2 < 32);
- intEnabled[(daddr-GICD_ICENABLER_ST) >> 2] &= ~pkt->get<uint32_t>();
+ if (GICD_ICENABLER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ICENABLER.start()) >> 2;
+ assert(ix < 32);
+ getIntEnabled(ctx_id, ix) &= ~pkt->get<uint32_t>();
goto done;
}
- if (daddr >= GICD_ISPENDR_ST && daddr < GICD_ISPENDR_ED + 4) {
- assert((daddr-GICD_ISPENDR_ST) >> 2 < 32);
- pendingInt[(daddr-GICD_ISPENDR_ST) >> 2] |= pkt->get<uint32_t>();
- pendingInt[0] &= SGI_MASK; // Don't allow SGIs to be changed
- updateIntState((daddr-GICD_ISPENDR_ST) >> 2);
+ if (GICD_ISPENDR.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ISPENDR.start()) >> 2;
+ auto mask = pkt->get<uint32_t>();
+ if (ix == 0) mask &= SGI_MASK; // Don't allow SGIs to be changed
+ getPendingInt(ctx_id, ix) |= mask;
+ updateIntState(ix);
goto done;
}
- if (daddr >= GICD_ICPENDR_ST && daddr < GICD_ICPENDR_ED + 4) {
- assert((daddr-GICD_ICPENDR_ST) >> 2 < 32);
- pendingInt[(daddr-GICD_ICPENDR_ST) >> 2] &= ~pkt->get<uint32_t>();
- pendingInt[0] &= SGI_MASK; // Don't allow SGIs to be changed
- updateIntState((daddr-GICD_ICPENDR_ST) >> 2);
+ if (GICD_ICPENDR.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ICPENDR.start()) >> 2;
+ auto mask = pkt->get<uint32_t>();
+ if (ix == 0) mask &= SGI_MASK; // Don't allow SGIs to be changed
+ getPendingInt(ctx_id, ix) &= ~mask;
+ updateIntState(ix);
goto done;
}
- if (daddr >= GICD_IPRIORITYR_ST && daddr < GICD_IPRIORITYR_ED + 4) {
- Addr int_num = daddr - GICD_IPRIORITYR_ST;
- assert(int_num < INT_LINES_MAX);
- uint8_t* int_p;
- if (int_num < (SGI_MAX + PPI_MAX))
- int_p = bankedIntPriority[ctx_id];
- else
- int_p = intPriority;
- uint32_t tmp;
+ if (GICD_ISACTIVER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ISACTIVER.start()) >> 2;
+ getActiveInt(ctx_id, ix) |= pkt->get<uint32_t>();
+ goto done;
+ }
+
+ if (GICD_ICACTIVER.contains(daddr)) {
+ uint32_t ix = (daddr - GICD_ICACTIVER.start()) >> 2;
+ getActiveInt(ctx_id, ix) &= ~pkt->get<uint32_t>();
+ goto done;
+ }
+
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev