Giacomo Travaglini has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/55607 )

Change subject: arch-arm: Generalize KVM Gic state copying logic
......................................................................

arch-arm: Generalize KVM Gic state copying logic

By moving the Gic state copying logic from the MuxingKvmGic to the
BaseGic we allow different Gic releases (e.g Gicv2, Gicv3) to override
the implementation accoding to their personal architectural state

It is also possible to use the same logic outside of the KVM
context

Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Change-Id: I88d6fca69a9b61a889c5ec53221404b8396cc12d
---
M src/dev/arm/gic_v3.hh
M src/arch/arm/kvm/gic.cc
M src/arch/arm/kvm/gic.hh
M src/dev/arm/base_gic.cc
M src/dev/arm/base_gic.hh
M src/dev/arm/gic_v2.cc
M src/dev/arm/gic_v2.hh
M src/arch/arm/fastmodel/GIC/gic.hh
8 files changed, 185 insertions(+), 151 deletions(-)



diff --git a/src/arch/arm/fastmodel/GIC/gic.hh b/src/arch/arm/fastmodel/GIC/gic.hh
index 33a172d..d4f2614 100644
--- a/src/arch/arm/fastmodel/GIC/gic.hh
+++ b/src/arch/arm/fastmodel/GIC/gic.hh
@@ -140,6 +140,12 @@

     bool supportsVersion(GicVersion version) override;

+    void
+    copyGicState(BaseGicRegisters* from, BaseGicRegisters* to) override
+    {
+        panic("copyGicState unimplemented for fastmodel GIC\n");
+    }
+
AddrRangeList getAddrRanges() const override { return AddrRangeList(); }
     Tick read(PacketPtr pkt) override { return 0; }
     Tick write(PacketPtr pkt) override { return 0; }
diff --git a/src/arch/arm/kvm/gic.cc b/src/arch/arm/kvm/gic.cc
index ac7a7f5..b0c3d96 100644
--- a/src/arch/arm/kvm/gic.cc
+++ b/src/arch/arm/kvm/gic.cc
@@ -284,130 +284,6 @@
         return GicV2::updateIntState(hint);
 }

-void
-MuxingKvmGic::copyDistRegister(BaseGicRegisters* from, BaseGicRegisters* to,
-                               ContextID ctx, Addr daddr)
-{
-    auto val = from->readDistributor(ctx, daddr);
-    DPRINTF(GIC, "copy dist 0x%x 0x%08x\n", daddr, val);
-    to->writeDistributor(ctx, daddr, val);
-}
-
-void
-MuxingKvmGic::copyCpuRegister(BaseGicRegisters* from, BaseGicRegisters* to,
-                               ContextID ctx, Addr daddr)
-{
-    auto val = from->readCpu(ctx, daddr);
-    DPRINTF(GIC, "copy cpu  0x%x 0x%08x\n", daddr, val);
-    to->writeCpu(ctx, daddr, val);
-}
-
-void
-MuxingKvmGic::copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
-                                  Addr daddr, size_t size)
-{
-    for (int ctx = 0; ctx < system.threads.size(); ++ctx)
-        for (auto a = daddr; a < daddr + size; a += 4)
-            copyDistRegister(from, to, ctx, a);
-}
-
-void
-MuxingKvmGic::clearBankedDistRange(BaseGicRegisters* to,
-                                   Addr daddr, size_t size)
-{
-    for (int ctx = 0; ctx < system.threads.size(); ++ctx)
-        for (auto a = daddr; a < daddr + size; a += 4)
-            to->writeDistributor(ctx, a, 0xFFFFFFFF);
-}
-
-void
-MuxingKvmGic::copyDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
-                            Addr daddr, size_t size)
-{
-    for (auto a = daddr; a < daddr + size; a += 4)
-        copyDistRegister(from, to, 0, a);
-}
-
-void
-MuxingKvmGic::clearDistRange(BaseGicRegisters* to,
-                             Addr daddr, size_t size)
-{
-    for (auto a = daddr; a < daddr + size; a += 4)
-        to->writeDistributor(0, a, 0xFFFFFFFF);
-}
-
-void
-MuxingKvmGic::copyGicState(BaseGicRegisters* from, BaseGicRegisters* to)
-{
-    Addr set, clear;
-    size_t size;
-
-    /// CPU state (GICC_*)
-    // Copy CPU Interface Control Register (CTLR),
-    //      Interrupt Priority Mask Register (PMR), and
-    //      Binary Point Register (BPR)
-    for (int ctx = 0; ctx < system.threads.size(); ++ctx) {
-        copyCpuRegister(from, to, ctx, GICC_CTLR);
-        copyCpuRegister(from, to, ctx, GICC_PMR);
-        copyCpuRegister(from, to, ctx, GICC_BPR);
-    }
-
-
-    /// Distributor state (GICD_*)
-    // Copy Distributor Control Register (CTLR)
-    copyDistRegister(from, to, 0, GICD_CTLR);
-
- // Copy interrupt-enabled statuses (I[CS]ENABLERn; R0 is per-CPU banked)
-    set   = GicV2::GICD_ISENABLER.start();
-    clear = GicV2::GICD_ICENABLER.start();
-    size  = GicV2::itLines / 8;
-    clearBankedDistRange(to, clear, 4);
-    copyBankedDistRange(from, to, set, 4);
-
-    set += 4, clear += 4, size -= 4;
-    clearDistRange(to, clear, size);
-    copyDistRange(from, to, set, size);
-
-    // Copy pending interrupts (I[CS]PENDRn; R0 is per-CPU banked)
-    set   = GicV2::GICD_ISPENDR.start();
-    clear = GicV2::GICD_ICPENDR.start();
-    size  = GicV2::itLines / 8;
-    clearBankedDistRange(to, clear, 4);
-    copyBankedDistRange(from, to, set, 4);
-
-    set += 4, clear += 4, size -= 4;
-    clearDistRange(to, clear, size);
-    copyDistRange(from, to, set, size);
-
-    // Copy active interrupts (I[CS]ACTIVERn; R0 is per-CPU banked)
-    set   = GicV2::GICD_ISACTIVER.start();
-    clear = GicV2::GICD_ICACTIVER.start();
-    size  = GicV2::itLines / 8;
-    clearBankedDistRange(to, clear, 4);
-    copyBankedDistRange(from, to, set, 4);
-
-    set += 4, clear += 4, size -= 4;
-    clearDistRange(to, clear, size);
-    copyDistRange(from, to, set, size);
-
-    // Copy interrupt priorities (IPRIORITYRn; R0-7 are per-CPU banked)
-    set   = GicV2::GICD_IPRIORITYR.start();
-    copyBankedDistRange(from, to, set, 32);
-
-    set += 32;
-    size = GicV2::itLines - 32;
-    copyDistRange(from, to, set, size);
-
-    // Copy interrupt processor target regs (ITARGETRn; R0-7 are read-only)
-    set = GicV2::GICD_ITARGETSR.start() + 32;
-    size = GicV2::itLines - 32;
-    copyDistRange(from, to, set, size);
-
-    // Copy interrupt configuration registers (ICFGRn)
-    set = GicV2::GICD_ICFGR.start();
-    size = GicV2::itLines / 4;
-    copyDistRange(from, to, set, size);
-}

 void
 MuxingKvmGic::fromGicV2ToKvm()
diff --git a/src/arch/arm/kvm/gic.hh b/src/arch/arm/kvm/gic.hh
index 465ecdf..71ec3bc 100644
--- a/src/arch/arm/kvm/gic.hh
+++ b/src/arch/arm/kvm/gic.hh
@@ -205,22 +205,6 @@
     /** Multiplexing implementation */
     void fromGicV2ToKvm();
     void fromKvmToGicV2();
-
-    void copyGicState(BaseGicRegisters* from, BaseGicRegisters* to);
-
-    void copyDistRegister(BaseGicRegisters* from, BaseGicRegisters* to,
-                          ContextID ctx, Addr daddr);
-    void copyCpuRegister(BaseGicRegisters* from, BaseGicRegisters* to,
-                         ContextID ctx, Addr daddr);
-
-    void copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
-                             Addr daddr, size_t size);
-    void clearBankedDistRange(BaseGicRegisters* to,
-                              Addr daddr, size_t size);
-    void copyDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
-                       Addr daddr, size_t size);
-    void clearDistRange(BaseGicRegisters* to,
-                        Addr daddr, size_t size);
 };

 } // namespace gem5
diff --git a/src/dev/arm/base_gic.cc b/src/dev/arm/base_gic.cc
index 4685ce4..4a881e8 100644
--- a/src/dev/arm/base_gic.cc
+++ b/src/dev/arm/base_gic.cc
@@ -38,6 +38,7 @@
 #include "dev/arm/base_gic.hh"

 #include "cpu/thread_context.hh"
+#include "debug/GIC.hh"
 #include "dev/arm/realview.hh"
 #include "params/ArmInterruptPin.hh"
 #include "params/ArmPPI.hh"
@@ -79,6 +80,58 @@
     return dynamic_cast<const Params &>(_params);
 }

+void
+BaseGic::copyDistRegister(BaseGicRegisters* from, BaseGicRegisters* to,
+                          ContextID ctx, Addr daddr)
+{
+    auto val = from->readDistributor(ctx, daddr);
+    DPRINTF(GIC, "copy dist 0x%x 0x%08x\n", daddr, val);
+    to->writeDistributor(ctx, daddr, val);
+}
+
+void
+BaseGic::copyCpuRegister(BaseGicRegisters* from, BaseGicRegisters* to,
+                         ContextID ctx, Addr daddr)
+{
+    auto val = from->readCpu(ctx, daddr);
+    DPRINTF(GIC, "copy cpu  0x%x 0x%08x\n", daddr, val);
+    to->writeCpu(ctx, daddr, val);
+}
+
+void
+BaseGic::copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
+                             Addr daddr, size_t size)
+{
+    for (int ctx = 0; ctx < sys->threads.size(); ++ctx)
+        for (auto a = daddr; a < daddr + size; a += 4)
+            copyDistRegister(from, to, ctx, a);
+}
+
+void
+BaseGic::clearBankedDistRange(BaseGicRegisters* to,
+                              Addr daddr, size_t size)
+{
+    for (int ctx = 0; ctx < sys->threads.size(); ++ctx)
+        for (auto a = daddr; a < daddr + size; a += 4)
+            to->writeDistributor(ctx, a, 0xFFFFFFFF);
+}
+
+void
+BaseGic::copyDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
+                       Addr daddr, size_t size)
+{
+    for (auto a = daddr; a < daddr + size; a += 4)
+        copyDistRegister(from, to, 0, a);
+}
+
+void
+BaseGic::clearDistRange(BaseGicRegisters* to,
+                        Addr daddr, size_t size)
+{
+    for (auto a = daddr; a < daddr + size; a += 4)
+        to->writeDistributor(0, a, 0xFFFFFFFF);
+}
+
 ArmInterruptPinGen::ArmInterruptPinGen(const ArmInterruptPinParams &p)
   : SimObject(p)
 {
diff --git a/src/dev/arm/base_gic.hh b/src/dev/arm/base_gic.hh
index 72fe9f4..7100f51 100644
--- a/src/dev/arm/base_gic.hh
+++ b/src/dev/arm/base_gic.hh
@@ -69,6 +69,17 @@
 struct ArmSigInterruptPinParams;
 struct BaseGicParams;

+class BaseGicRegisters
+{
+  public:
+    virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0;
+    virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0;
+
+    virtual void writeDistributor(ContextID ctx, Addr daddr,
+                                  uint32_t data) = 0;
+    virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0;
+};
+
 class BaseGic :  public PioDevice
 {
   public:
@@ -119,22 +130,29 @@
     /** Check if version supported */
     virtual bool supportsVersion(GicVersion version) = 0;

+  protected: // GIC state transfer
+    virtual void copyGicState(BaseGicRegisters* from,
+                              BaseGicRegisters* to) = 0;
+
+    void copyDistRegister(BaseGicRegisters* from, BaseGicRegisters* to,
+                          ContextID ctx, Addr daddr);
+    void copyCpuRegister(BaseGicRegisters* from, BaseGicRegisters* to,
+                         ContextID ctx, Addr daddr);
+
+    void copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
+                             Addr daddr, size_t size);
+    void clearBankedDistRange(BaseGicRegisters* to,
+                              Addr daddr, size_t size);
+    void copyDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
+                       Addr daddr, size_t size);
+    void clearDistRange(BaseGicRegisters* to,
+                        Addr daddr, size_t size);
+
   protected:
     /** Platform this GIC belongs to. */
     Platform *platform;
 };

-class BaseGicRegisters
-{
-  public:
-    virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0;
-    virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0;
-
-    virtual void writeDistributor(ContextID ctx, Addr daddr,
-                                  uint32_t data) = 0;
-    virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0;
-};
-
 /**
  * This SimObject is instantiated in the python world and
  * serves as an ArmInterruptPin generator. In this way it
diff --git a/src/dev/arm/gic_v2.cc b/src/dev/arm/gic_v2.cc
index bceccf8..9a2e246 100644
--- a/src/dev/arm/gic_v2.cc
+++ b/src/dev/arm/gic_v2.cc
@@ -995,6 +995,78 @@
 }

 void
+GicV2::copyGicState(BaseGicRegisters* from, BaseGicRegisters* to)
+{
+    Addr set, clear;
+    size_t size;
+
+    /// CPU state (GICC_*)
+    // Copy CPU Interface Control Register (CTLR),
+    //      Interrupt Priority Mask Register (PMR), and
+    //      Binary Point Register (BPR)
+    for (int ctx = 0; ctx < sys->threads.size(); ++ctx) {
+        copyCpuRegister(from, to, ctx, GICC_CTLR);
+        copyCpuRegister(from, to, ctx, GICC_PMR);
+        copyCpuRegister(from, to, ctx, GICC_BPR);
+    }
+
+    /// Distributor state (GICD_*)
+    // Copy Distributor Control Register (CTLR)
+    copyDistRegister(from, to, 0, GICD_CTLR);
+
+ // Copy interrupt-enabled statuses (I[CS]ENABLERn; R0 is per-CPU banked)
+    set   = GICD_ISENABLER.start();
+    clear = GICD_ICENABLER.start();
+    size  = itLines / 8;
+    clearBankedDistRange(to, clear, 4);
+    copyBankedDistRange(from, to, set, 4);
+
+    set += 4, clear += 4, size -= 4;
+    clearDistRange(to, clear, size);
+    copyDistRange(from, to, set, size);
+
+    // Copy pending interrupts (I[CS]PENDRn; R0 is per-CPU banked)
+    set   = GICD_ISPENDR.start();
+    clear = GICD_ICPENDR.start();
+    size  = itLines / 8;
+    clearBankedDistRange(to, clear, 4);
+    copyBankedDistRange(from, to, set, 4);
+
+    set += 4, clear += 4, size -= 4;
+    clearDistRange(to, clear, size);
+    copyDistRange(from, to, set, size);
+
+    // Copy active interrupts (I[CS]ACTIVERn; R0 is per-CPU banked)
+    set   = GICD_ISACTIVER.start();
+    clear = GICD_ICACTIVER.start();
+    size  = itLines / 8;
+    clearBankedDistRange(to, clear, 4);
+    copyBankedDistRange(from, to, set, 4);
+
+    set += 4, clear += 4, size -= 4;
+    clearDistRange(to, clear, size);
+    copyDistRange(from, to, set, size);
+
+    // Copy interrupt priorities (IPRIORITYRn; R0-7 are per-CPU banked)
+    set   = GICD_IPRIORITYR.start();
+    copyBankedDistRange(from, to, set, 32);
+
+    set += 32;
+    size = itLines - 32;
+    copyDistRange(from, to, set, size);
+
+    // Copy interrupt processor target regs (ITARGETRn; R0-7 are read-only)
+    set = GICD_ITARGETSR.start() + 32;
+    size = itLines - 32;
+    copyDistRange(from, to, set, size);
+
+    // Copy interrupt configuration registers (ICFGRn)
+    set = GICD_ICFGR.start();
+    size = itLines / 4;
+    copyDistRange(from, to, set, size);
+}
+
+void
 GicV2::serialize(CheckpointOut &cp) const
 {
     DPRINTF(Checkpoint, "Serializing Arm GIC\n");
diff --git a/src/dev/arm/gic_v2.hh b/src/dev/arm/gic_v2.hh
index 9e68745..6fc5087 100644
--- a/src/dev/arm/gic_v2.hh
+++ b/src/dev/arm/gic_v2.hh
@@ -512,6 +512,8 @@

     bool supportsVersion(GicVersion version) override;

+ void copyGicState(BaseGicRegisters* from, BaseGicRegisters* to) override;
+
   protected:
     /** Handle a read to the distributor portion of the GIC
      * @param pkt packet to respond to
diff --git a/src/dev/arm/gic_v3.hh b/src/dev/arm/gic_v3.hh
index f4aaea5..37e0367 100644
--- a/src/dev/arm/gic_v3.hh
+++ b/src/dev/arm/gic_v3.hh
@@ -127,6 +127,12 @@
     Tick write(PacketPtr pkt) override;
     bool supportsVersion(GicVersion version) override;

+    void
+    copyGicState(BaseGicRegisters* from, BaseGicRegisters* to) override
+    {
+        panic("copyGicState unimplemented for Gicv3\n");
+    }
+
   public:

     Gicv3(const Params &p);

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/55607
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I88d6fca69a9b61a889c5ec53221404b8396cc12d
Gerrit-Change-Number: 55607
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to