From: Giacomo Travaglini Date: Mon, 15 Apr 2019 15:42:43 +0000 (+0100) Subject: dev-arm: Add several LPI methods in Gicv3Redistributor X-Git-Tag: v19.0.0.0~895 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=68f2f1c5f55bee74b7d4c99f3c612473869f81e6;p=gem5.git dev-arm: Add several LPI methods in Gicv3Redistributor Refactoring the existing in code in smaller methods will be crucial when adding the ITS module, which is a client for the redistributor class and which will require it to take different actions depending on the command it receives from software. List of methods: * read/writeEntryLPI Reading/Writing a byte from the LPI pending table * isPendingLPI Checks if the pINTID LPI is set. Knowing if an LPI is set is needed by the MOVI command, which is transfering the pending state from one redistributor to the other only if the LPI is pending. Change-Id: If14b1c28ff7f2aa20b12dcd822bf6a490cbe0270 Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18596 Maintainer: Andreas Sandberg Tested-by: kokoro --- diff --git a/src/dev/arm/gic_v3_redistributor.cc b/src/dev/arm/gic_v3_redistributor.cc index 79de7d55c..0ee6b8adc 100644 --- a/src/dev/arm/gic_v3_redistributor.cc +++ b/src/dev/arm/gic_v3_redistributor.cc @@ -860,6 +860,43 @@ Gicv3Redistributor::update() } } +uint8_t +Gicv3Redistributor::readEntryLPI(uint32_t lpi_id) +{ + Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8); + + uint8_t lpi_pending_entry; + ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId); + tc->getPhysProxy().readBlob(lpi_pending_entry_ptr, + (uint8_t*) &lpi_pending_entry, + sizeof(lpi_pending_entry)); + + return lpi_pending_entry; +} + +void +Gicv3Redistributor::writeEntryLPI(uint32_t lpi_id, uint8_t lpi_pending_entry) +{ + Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8); + + ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId); + tc->getPhysProxy().writeBlob(lpi_pending_entry_ptr, + (uint8_t*) &lpi_pending_entry, + sizeof(lpi_pending_entry)); +} + +bool +Gicv3Redistributor::isPendingLPI(uint32_t lpi_id) +{ + // Fetch the LPI pending entry from memory + uint8_t lpi_pending_entry = readEntryLPI(lpi_id); + + uint8_t lpi_pending_entry_bit_position = lpi_id % 8; + bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position); + + return is_set; +} + void Gicv3Redistributor::setClrLPI(uint64_t data, bool set) { @@ -878,12 +915,9 @@ Gicv3Redistributor::setClrLPI(uint64_t data, bool set) return; } - Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8); - uint8_t lpi_pending_entry; - ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId); - tc->getPhysProxy().readBlob(lpi_pending_entry_ptr, - (uint8_t*) &lpi_pending_entry, - sizeof(lpi_pending_entry)); + // Fetch the LPI pending entry from memory + uint8_t lpi_pending_entry = readEntryLPI(lpi_id); + uint8_t lpi_pending_entry_bit_position = lpi_id % 8; bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position); @@ -905,9 +939,8 @@ Gicv3Redistributor::setClrLPI(uint64_t data, bool set) lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position)); } - tc->getPhysProxy().writeBlob(lpi_pending_entry_ptr, - (uint8_t*) &lpi_pending_entry, - sizeof(lpi_pending_entry)); + writeEntryLPI(lpi_id, lpi_pending_entry); + updateAndInformCPUInterface(); } diff --git a/src/dev/arm/gic_v3_redistributor.hh b/src/dev/arm/gic_v3_redistributor.hh index 0e99b746d..6aff91db5 100644 --- a/src/dev/arm/gic_v3_redistributor.hh +++ b/src/dev/arm/gic_v3_redistributor.hh @@ -190,8 +190,17 @@ class Gicv3Redistributor : public Serializable return cpuInterface; } + uint32_t + processorNumber() const + { + return cpuId; + } + Gicv3::GroupId getIntGroup(int int_id) const; Gicv3::IntStatus intStatus(uint32_t int_id) const; + uint8_t readEntryLPI(uint32_t intid); + void writeEntryLPI(uint32_t intid, uint8_t lpi_entry); + bool isPendingLPI(uint32_t intid); void setClrLPI(uint64_t data, bool set); void reset(); void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);