dev-arm: Get a Gicv3Redistributor ptr from phys address
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 26 Apr 2019 10:24:17 +0000 (11:24 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 2 May 2019 14:42:42 +0000 (14:42 +0000)
The patch is adding the following method to Gicv3:

* Gicv3::getRedistributorByAddr
This will be needed by the ITS when trying to select the target
redistributor after decoding the collection table entry (RDBase).

Change-Id: I40e2c155f2fdc8ca6d3c20ff7a27702e02499f20
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/public/gem5/+/18597
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/dev/arm/gic_v3.cc
src/dev/arm/gic_v3.hh

index 2832d33f8d8a293edfb76d2e9beb0fb5700d44ef..9004f656f0f5e8a58ad115cf7774b6cf541b98d7 100644 (file)
@@ -110,19 +110,15 @@ Gicv3::read(PacketPtr pkt)
                 "size %d is_secure_access %d (value %#x)\n",
                 pkt->req->contextId(), daddr, size, is_secure_access, resp);
     } else if (redistRange.contains(addr)) {
-        Addr daddr = addr - redistRange.start();
-        uint32_t redistributor_id =
-            daddr / redistSize;
-        daddr = daddr % redistSize;
-        panic_if(redistributor_id >= redistributors.size(),
-                 "Invalid redistributor_id!");
-        panic_if(!redistributors[redistributor_id], "Redistributor is null!");
-        resp = redistributors[redistributor_id]->read(daddr, size,
-                                                      is_secure_access);
+        Addr daddr = (addr - redistRange.start()) % redistSize;
+
+        Gicv3Redistributor *redist = getRedistributorByAddr(addr);
+        resp = redist->read(daddr, size, is_secure_access);
+
         delay = params()->redist_pio_delay;
         DPRINTF(GIC, "Gicv3::read(): (redistributor %d) context_id %d "
                 "register %#x size %d is_secure_access %d (value %#x)\n",
-                redistributor_id, pkt->req->contextId(), daddr, size,
+                redist->processorNumber(), pkt->req->contextId(), daddr, size,
                 is_secure_access, resp);
     } else {
         panic("Gicv3::read(): unknown address %#x\n", addr);
@@ -151,19 +147,16 @@ Gicv3::write(PacketPtr pkt)
         distributor->write(daddr, data, size, is_secure_access);
         delay = params()->dist_pio_delay;
     } else if (redistRange.contains(addr)) {
-        Addr daddr = addr - redistRange.start();
-        uint32_t redistributor_id =
-            daddr / redistSize;
-        daddr = daddr % redistSize;
-        panic_if(redistributor_id >= redistributors.size(),
-                 "Invalid redistributor_id!");
-        panic_if(!redistributors[redistributor_id], "Redistributor is null!");
+        Addr daddr = (addr - redistRange.start()) % redistSize;
+
+        Gicv3Redistributor *redist = getRedistributorByAddr(addr);
         DPRINTF(GIC, "Gicv3::write(): (redistributor %d) context_id %d "
                 "register %#x size %d is_secure_access %d value %#x\n",
-                redistributor_id, pkt->req->contextId(), daddr, size,
+                redist->processorNumber(), pkt->req->contextId(), daddr, size,
                 is_secure_access, data);
-        redistributors[redistributor_id]->write(daddr, data, size,
-                                                is_secure_access);
+
+        redist->write(daddr, data, size, is_secure_access);
+
         delay = params()->redist_pio_delay;
     } else {
         panic("Gicv3::write(): unknown address %#x\n", addr);
@@ -228,6 +221,22 @@ Gicv3::getRedistributorByAffinity(uint32_t affinity) const
     return nullptr;
 }
 
+Gicv3Redistributor *
+Gicv3::getRedistributorByAddr(Addr addr) const
+{
+    panic_if(!redistRange.contains(addr),
+        "Address not pointing to a valid redistributor\n");
+
+    const Addr daddr = addr - redistRange.start();
+    const uint32_t redistributor_id = daddr / redistSize;
+
+    panic_if(redistributor_id >= redistributors.size(),
+             "Invalid redistributor_id!");
+    panic_if(!redistributors[redistributor_id], "Redistributor is null!");
+
+    return redistributors[redistributor_id];
+}
+
 void
 Gicv3::serialize(CheckpointOut & cp) const
 {
index 48cc52029dd91a2e2b5d969d92e075715eff277b..5a13a74793d40fc8d31cca584a3acc69e9ff627c 100644 (file)
@@ -141,6 +141,10 @@ class Gicv3 : public BaseGic
 
     Gicv3Redistributor *
     getRedistributorByAffinity(uint32_t affinity) const;
+
+    Gicv3Redistributor *
+    getRedistributorByAddr(Addr address) const;
+
     void postInt(uint32_t cpu, ArmISA::InterruptTypes int_type);
 };