From 59370dde2efec2d19280d8453407ea8feda20370 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 20 Aug 2019 20:47:55 +0100 Subject: dev-arm: Fix GICv3 ITS cmdq wrapping Change-Id: I979e8d1378d5b5d2647158798479cf4238f2c349 Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20633 Tested-by: kokoro Maintainer: Andreas Sandberg --- src/dev/arm/gic_v3_its.cc | 17 ++++++++++++++--- src/dev/arm/gic_v3_its.hh | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/dev/arm') diff --git a/src/dev/arm/gic_v3_its.cc b/src/dev/arm/gic_v3_its.cc index ca363f409..ab0d8c2d0 100644 --- a/src/dev/arm/gic_v3_its.cc +++ b/src/dev/arm/gic_v3_its.cc @@ -1065,19 +1065,30 @@ Gicv3Its::incrementReadPointer() gitsCreadr.offset = gitsCreadr.offset + 1; // Check for wrapping - auto queue_end = (4096 * (gitsCbaser.size + 1)); - - if (gitsCreadr.offset == queue_end) { + if (gitsCreadr.offset == maxCommands()) { gitsCreadr.offset = 0; } } +uint64_t +Gicv3Its::maxCommands() const +{ + return (4096 * (gitsCbaser.size + 1)) / sizeof(ItsCommand::CommandEntry); +} + void Gicv3Its::checkCommandQueue() { if (!gitsControl.enabled || !gitsCbaser.valid) return; + // If GITS_CWRITER gets set by sw to a value bigger than the + // allowed one, the command queue should stop processing commands + // until the register gets reset to an allowed one + if (gitsCwriter.offset >= maxCommands()) { + return; + } + if (gitsCwriter.offset != gitsCreadr.offset) { // writer and reader pointing to different command // entries: queue not empty. diff --git a/src/dev/arm/gic_v3_its.hh b/src/dev/arm/gic_v3_its.hh index b9c1d8582..d11d7c0d7 100644 --- a/src/dev/arm/gic_v3_its.hh +++ b/src/dev/arm/gic_v3_its.hh @@ -257,6 +257,7 @@ class Gicv3Its : public BasicPioDevice bool lpiOutOfRange(uint32_t intid) const; private: // Command + uint64_t maxCommands() const; void checkCommandQueue(); void incrementReadPointer(); -- cgit v1.2.3