dev-arm: Start using GITS_CTLR.quiescent bit
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 14 Aug 2019 18:26:45 +0000 (19:26 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 22 Aug 2019 08:49:00 +0000 (08:49 +0000)
The GITS_CTLR.quiescent bit is used by priviledged sw to check when the
ITS has finished draining its state (all pending translations/table
walks have ended) once it has been disabled (by setting the
GITS_CTLR.enable bit to 0).
This patch is modelling this behaviour by

* Changing the reset state to enable=0, quiescent=1
* Making the GITS_CTLR.quiescent bit RO
* Updating the bit once a new translation/command is being processed
(quiescent=0) and when there are no pending translation/commands
(quiescent=1)

Change-Id: I7cfe94b25d603400364b1cdfc2d2397acf5dfad8
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/+/20257
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/dev/arm/gic_v3_its.cc
src/dev/arm/gic_v3_its.hh

index de2683c24baf35ba49d15bb1eab093b7027dedf4..ddf06f4ccf9da862e422f99ce7f0c729758103d7 100644 (file)
@@ -52,6 +52,8 @@
 
 const AddrRange Gicv3Its::GITS_BASER(0x0100, 0x0138);
 
+const uint32_t Gicv3Its::CTLR_QUIESCENT = 0x80000000;
+
 ItsProcess::ItsProcess(Gicv3Its &_its)
   : its(_its), coroutine(nullptr)
 {
@@ -218,12 +220,15 @@ ItsTranslation::ItsTranslation(Gicv3Its &_its)
 {
     reinit();
     its.pendingTranslations++;
+    its.gitsControl.quiescent = 0;
 }
 
 ItsTranslation::~ItsTranslation()
 {
     assert(its.pendingTranslations >= 1);
     its.pendingTranslations--;
+    if (!its.pendingTranslations && !its.pendingCommands)
+        its.gitsControl.quiescent = 1;
 }
 
 void
@@ -309,11 +314,16 @@ ItsCommand::ItsCommand(Gicv3Its &_its)
 {
     reinit();
     its.pendingCommands = true;
+
+    its.gitsControl.quiescent = 0;
 }
 
 ItsCommand::~ItsCommand()
 {
     its.pendingCommands = false;
+
+    if (!its.pendingTranslations)
+        its.gitsControl.quiescent = 1;
 }
 
 std::string
@@ -766,7 +776,7 @@ ItsCommand::vsync(Yield &yield, CommandEntry &command)
 Gicv3Its::Gicv3Its(const Gicv3ItsParams *params)
  : BasicPioDevice(params, params->pio_size),
    dmaPort(name() + ".dma", *this),
-   gitsControl(0x1),
+   gitsControl(CTLR_QUIESCENT),
    gitsTyper(params->gits_typer),
    gitsCbaser(0), gitsCreadr(0),
    gitsCwriter(0), gitsIidr(0),
@@ -881,7 +891,11 @@ Gicv3Its::write(PacketPtr pkt)
     switch (addr) {
       case GITS_CTLR:
         assert(pkt->getSize() == sizeof(uint32_t));
-        gitsControl = pkt->getLE<uint32_t>();
+        gitsControl = (pkt->getLE<uint32_t>() & ~CTLR_QUIESCENT);
+        // We should check here if the ITS has been disabled, and if
+        // that's the case, flush GICv3 caches to external memory.
+        // This is not happening now, since LPI caching is not
+        // currently implemented in gem5.
         break;
 
       case GITS_IIDR:
index dae18d516d3ef84f0551bc7bbc09dfc9cf91412e..1ca98a824449267b8385e35631fa2f28f661dc8f 100644 (file)
@@ -114,6 +114,9 @@ class Gicv3Its : public BasicPioDevice
 
     static const uint32_t NUM_BASER_REGS = 8;
 
+    // GITS_CTLR.quiescent mask
+    static const uint32_t CTLR_QUIESCENT;
+
     enum : Addr
     {
         // Control frame