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

Reply via email to