From afce68658cee32c499af9eacf4ffa489a15c1e7c Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 26 Apr 2019 13:21:59 +0100 Subject: dev-arm: Check EnableLPIs before checking for pending LPIs Before reading the tables, GICR_PENDBASER and GICR_PROPBASER need to be properly set, and those will have a consistent value only once sw enables LPIs. Change-Id: Ifb87944a491045e7a13ce7a280c555cb0c1e47f4 Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18592 Maintainer: Andreas Sandberg Tested-by: kokoro --- src/dev/arm/gic_v3_redistributor.cc | 66 +++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'src/dev/arm') diff --git a/src/dev/arm/gic_v3_redistributor.cc b/src/dev/arm/gic_v3_redistributor.cc index d5a405a84..2b73c576e 100644 --- a/src/dev/arm/gic_v3_redistributor.cc +++ b/src/dev/arm/gic_v3_redistributor.cc @@ -830,38 +830,40 @@ Gicv3Redistributor::update() } // Check LPIs - const uint32_t largest_lpi_id = 1 << (lpiIDBits + 1); - char lpi_pending_table[largest_lpi_id / 8]; - ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId); - tc->getPhysProxy().readBlob(lpiPendingTablePtr, - (uint8_t *) lpi_pending_table, - sizeof(lpi_pending_table)); - - for (int lpi_id = SMALLEST_LPI_ID; lpi_id < largest_lpi_id; - lpi_id++) { - uint32_t lpi_pending_entry_byte = lpi_id / 8; - uint8_t lpi_pending_entry_bit_position = lpi_id % 8; - bool lpi_is_pending = lpi_pending_table[lpi_pending_entry_byte] & - 1 << lpi_pending_entry_bit_position; - uint32_t lpi_configuration_entry_index = lpi_id - SMALLEST_LPI_ID; - bool lpi_is_enable = - lpiConfigurationTable[lpi_configuration_entry_index].enable; - // LPIs are always Non-secure Group 1 interrupts, - // in a system where two Security states are enabled. - Gicv3::GroupId lpi_group = Gicv3::G1NS; - bool group_enabled = distributor->groupEnabled(lpi_group); - - if (lpi_is_pending && lpi_is_enable && group_enabled) { - uint8_t lpi_priority = - lpiConfigurationTable[lpi_configuration_entry_index].priority; - - if ((lpi_priority < cpuInterface->hppi.prio) || - (lpi_priority == cpuInterface->hppi.prio && - lpi_id < cpuInterface->hppi.intid)) { - cpuInterface->hppi.intid = lpi_id; - cpuInterface->hppi.prio = lpi_priority; - cpuInterface->hppi.group = lpi_group; - new_hppi = true; + if (EnableLPIs) { + const uint32_t largest_lpi_id = 1 << (lpiIDBits + 1); + char lpi_pending_table[largest_lpi_id / 8]; + ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId); + tc->getPhysProxy().readBlob(lpiPendingTablePtr, + (uint8_t *) lpi_pending_table, + sizeof(lpi_pending_table)); + + for (int lpi_id = SMALLEST_LPI_ID; lpi_id < largest_lpi_id; + lpi_id++) { + uint32_t lpi_pending_entry_byte = lpi_id / 8; + uint8_t lpi_pending_entry_bit_position = lpi_id % 8; + bool lpi_is_pending = lpi_pending_table[lpi_pending_entry_byte] & + 1 << lpi_pending_entry_bit_position; + uint32_t lpi_configuration_entry_index = lpi_id - SMALLEST_LPI_ID; + bool lpi_is_enable = + lpiConfigurationTable[lpi_configuration_entry_index].enable; + // LPIs are always Non-secure Group 1 interrupts, + // in a system where two Security states are enabled. + Gicv3::GroupId lpi_group = Gicv3::G1NS; + bool group_enabled = distributor->groupEnabled(lpi_group); + + if (lpi_is_pending && lpi_is_enable && group_enabled) { + uint8_t lpi_priority = + lpiConfigurationTable[lpi_configuration_entry_index].priority; + + if ((lpi_priority < cpuInterface->hppi.prio) || + (lpi_priority == cpuInterface->hppi.prio && + lpi_id < cpuInterface->hppi.intid)) { + cpuInterface->hppi.intid = lpi_id; + cpuInterface->hppi.prio = lpi_priority; + cpuInterface->hppi.group = lpi_group; + new_hppi = true; + } } } } -- cgit v1.2.3