From b90fcd7357dfc065908e60def2b9c18c1a091627 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Thu, 15 Aug 2019 10:20:44 +0100 Subject: [PATCH] dev-arm: Fix GITS_BASER initialization/access The patch is fixing/improving GITS_BASER registers initialization. * Not using reserved table types anymore (GITS_BASER.TYPE) * Using write mask for handling WI bits Change-Id: Ibe24667fdf22b42b86496167c19fc00bbb0ba191 Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20328 Maintainer: Andreas Sandberg Tested-by: kokoro --- src/dev/arm/gic_v3_its.cc | 37 +++++++++++++++++++++++++------------ src/dev/arm/gic_v3_its.hh | 12 ++++++++++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/dev/arm/gic_v3_its.cc b/src/dev/arm/gic_v3_its.cc index ddf06f4cc..692bbd071 100644 --- a/src/dev/arm/gic_v3_its.cc +++ b/src/dev/arm/gic_v3_its.cc @@ -780,18 +780,22 @@ Gicv3Its::Gicv3Its(const Gicv3ItsParams *params) gitsTyper(params->gits_typer), gitsCbaser(0), gitsCreadr(0), gitsCwriter(0), gitsIidr(0), + tableBases(NUM_BASER_REGS, 0), masterId(params->system->getMasterId(this)), gic(nullptr), commandEvent([this] { checkCommandQueue(); }, name()), pendingCommands(false), pendingTranslations(0) { - for (auto idx = 0; idx < NUM_BASER_REGS; idx++) { - BASER gits_baser = 0; - gits_baser.type = idx; - gits_baser.entrySize = sizeof(uint64_t) - 1; - tableBases.push_back(gits_baser); - } + BASER device_baser = 0; + device_baser.type = DEVICE_TABLE; + device_baser.entrySize = sizeof(uint64_t) - 1; + tableBases[0] = device_baser; + + BASER icollect_baser = 0; + icollect_baser.type = COLLECTION_TABLE; + icollect_baser.entrySize = sizeof(uint64_t) - 1; + tableBases[1] = icollect_baser; } void @@ -958,12 +962,12 @@ Gicv3Its::write(PacketPtr pkt) auto relative_addr = addr - GITS_BASER.start(); auto baser_index = relative_addr / sizeof(uint64_t); - BASER val = pkt->getLE(); - - panic_if(val.indirect, - "We currently don't support two level ITS tables"); + const uint64_t table_base = tableBases[baser_index]; + const uint64_t w_mask = tableBases[baser_index].type ? + BASER_WMASK : BASER_WMASK_UNIMPL; + const uint64_t val = pkt->getLE() & w_mask; - tableBases[baser_index] = val; + tableBases[baser_index] = table_base | val; break; } else { panic("Unrecognized register access\n"); @@ -1224,7 +1228,16 @@ Gicv3Its::getRedistributor(uint64_t rd_base) Addr Gicv3Its::pageAddress(Gicv3Its::ItsTables table) { - const BASER base = tableBases[table]; + auto base_it = std::find_if( + tableBases.begin(), tableBases.end(), + [table] (const BASER &b) { return b.type == table; } + ); + + panic_if(base_it == tableBases.end(), + "ITS Table not recognised\n"); + + const BASER base = *base_it; + // real address depends on page size switch (base.pageSize) { case SIZE_4K: diff --git a/src/dev/arm/gic_v3_its.hh b/src/dev/arm/gic_v3_its.hh index 1ca98a824..40d95c8b8 100644 --- a/src/dev/arm/gic_v3_its.hh +++ b/src/dev/arm/gic_v3_its.hh @@ -114,6 +114,18 @@ class Gicv3Its : public BasicPioDevice static const uint32_t NUM_BASER_REGS = 8; + // We currently don't support two level ITS tables + // The indirect bit is RAZ/WI for implementations that only + // support flat tables. + static const uint64_t BASER_INDIRECT = 0x4000000000000000; + static const uint64_t BASER_TYPE = 0x0700000000000000; + static const uint64_t BASER_ESZ = 0x001F000000000000; + static const uint64_t BASER_SZ = 0x00000000000000FF; + static const uint64_t BASER_WMASK = + ~(BASER_INDIRECT | BASER_TYPE | BASER_ESZ); + static const uint64_t BASER_WMASK_UNIMPL = + ~(BASER_INDIRECT | BASER_TYPE | BASER_ESZ | BASER_SZ); + // GITS_CTLR.quiescent mask static const uint32_t CTLR_QUIESCENT; -- 2.30.2