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 <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18596
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Giacomo Travaglini
2019-04-15 16:42:43 +01:00
parent c16b504299
commit 68f2f1c5f5
2 changed files with 51 additions and 9 deletions

View File

@@ -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();
}

View File

@@ -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);