From f8fbeae6fcd0797a36ccfec615d244b5e6220cd2 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Wed, 14 Aug 2019 19:26:45 +0100 Subject: [PATCH] dev-arm: Start using GITS_CTLR.quiescent bit 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 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20257 Maintainer: Andreas Sandberg Tested-by: kokoro --- src/dev/arm/gic_v3_its.cc | 18 ++++++++++++++++-- src/dev/arm/gic_v3_its.hh | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/dev/arm/gic_v3_its.cc b/src/dev/arm/gic_v3_its.cc index de2683c24..ddf06f4cc 100644 --- a/src/dev/arm/gic_v3_its.cc +++ b/src/dev/arm/gic_v3_its.cc @@ -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(); + gitsControl = (pkt->getLE() & ~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: diff --git a/src/dev/arm/gic_v3_its.hh b/src/dev/arm/gic_v3_its.hh index dae18d516..1ca98a824 100644 --- a/src/dev/arm/gic_v3_its.hh +++ b/src/dev/arm/gic_v3_its.hh @@ -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 -- 2.30.2