summaryrefslogtreecommitdiff
path: root/src/dev/arm
diff options
context:
space:
mode:
authorGiacomo Travaglini <giacomo.travaglini@arm.com>2019-08-20 12:26:17 +0100
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2019-09-06 08:32:04 +0000
commit1768c47bc4fc00e89601ad03c9091c9b949a6c97 (patch)
tree51950301f0669eaacc2b94a6c5daa084b829d0c7 /src/dev/arm
parentaec83a6451c78f64de5656c2f4075b7453020425 (diff)
downloadgem5-1768c47bc4fc00e89601ad03c9091c9b949a6c97.tar.xz
dev-arm: Fix SGI generation
The patch is fixing the following aspects of SGIs * The conditons over which an SGI can be forwarded to a PE * SGIs in AArch32 (see below) It is in fact refactoring SGI generation under a common method in the cpu interface. It is abandoning the implicit fallthrough mechanism not only for cosmetic reasons, but also because checking "misc_reg ==" was only working if the register was an AArch64 one (e.g. MISCREG_ICC_SGI0R_EL1) and not the AArch32 counterpart (MISCREG_SGI0R). Change-Id: I6fedfb80388666f4f1d20f6abef378a9f093aa83 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/+/20610 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/dev/arm')
-rw-r--r--src/dev/arm/gic_v3_cpu_interface.cc121
-rw-r--r--src/dev/arm/gic_v3_cpu_interface.hh13
-rw-r--r--src/dev/arm/gic_v3_redistributor.cc45
3 files changed, 111 insertions, 68 deletions
diff --git a/src/dev/arm/gic_v3_cpu_interface.cc b/src/dev/arm/gic_v3_cpu_interface.cc
index 348819316..97d914568 100644
--- a/src/dev/arm/gic_v3_cpu_interface.cc
+++ b/src/dev/arm/gic_v3_cpu_interface.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2018 Metempsy Technology Consulting
* All rights reserved.
*
@@ -1416,68 +1428,25 @@ Gicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
// Software Generated Interrupt Group 0 Register
case MISCREG_ICC_SGI0R:
case MISCREG_ICC_SGI0R_EL1:
+ generateSGI(val, Gicv3::G0S);
+ break;
// Software Generated Interrupt Group 1 Register
case MISCREG_ICC_SGI1R:
- case MISCREG_ICC_SGI1R_EL1:
+ case MISCREG_ICC_SGI1R_EL1: {
+ Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
+
+ generateSGI(val, group);
+ break;
+ }
// Alias Software Generated Interrupt Group 1 Register
case MISCREG_ICC_ASGI1R:
case MISCREG_ICC_ASGI1R_EL1: {
- bool ns = !inSecureState();
- Gicv3::GroupId group;
-
- if (misc_reg == MISCREG_ICC_SGI1R_EL1) {
- group = ns ? Gicv3::G1NS : Gicv3::G1S;
- } else if (misc_reg == MISCREG_ICC_ASGI1R_EL1) {
- group = ns ? Gicv3::G1S : Gicv3::G1NS;
- } else {
- group = Gicv3::G0S;
- }
-
- if (distributor->DS && group == Gicv3::G1S) {
- group = Gicv3::G0S;
- }
-
- uint8_t aff3 = bits(val, 55, 48);
- uint8_t aff2 = bits(val, 39, 32);
- uint8_t aff1 = bits(val, 23, 16);;
- uint16_t target_list = bits(val, 15, 0);
- uint32_t int_id = bits(val, 27, 24);
- bool irm = bits(val, 40, 40);
- uint8_t rs = bits(val, 47, 44);
-
- for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
- Gicv3Redistributor * redistributor_i =
- gic->getRedistributor(i);
- uint32_t affinity_i = redistributor_i->getAffinity();
-
- if (irm) {
- // Interrupts routed to all PEs in the system,
- // excluding "self"
- if (affinity_i == redistributor->getAffinity()) {
- continue;
- }
- } else {
- // Interrupts routed to the PEs specified by
- // Aff3.Aff2.Aff1.<target list>
- if ((affinity_i >> 8) !=
- ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
- continue;
- }
-
- uint8_t aff0_i = bits(affinity_i, 7, 0);
-
- if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
- ((0x1 << (aff0_i - rs * 16)) & target_list))) {
- continue;
- }
- }
+ Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;
- redistributor_i->sendSGI(int_id, group, ns);
- }
-
- break;
+ generateSGI(val, group);
+ break;
}
// System Register Enable Register EL1
@@ -1790,6 +1759,50 @@ Gicv3CPUInterface::virtualDropPriority()
}
void
+Gicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
+{
+ uint8_t aff3 = bits(val, 55, 48);
+ uint8_t aff2 = bits(val, 39, 32);
+ uint8_t aff1 = bits(val, 23, 16);;
+ uint16_t target_list = bits(val, 15, 0);
+ uint32_t int_id = bits(val, 27, 24);
+ bool irm = bits(val, 40, 40);
+ uint8_t rs = bits(val, 47, 44);
+
+ bool ns = !inSecureState();
+
+ for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
+ Gicv3Redistributor * redistributor_i =
+ gic->getRedistributor(i);
+ uint32_t affinity_i = redistributor_i->getAffinity();
+
+ if (irm) {
+ // Interrupts routed to all PEs in the system,
+ // excluding "self"
+ if (affinity_i == redistributor->getAffinity()) {
+ continue;
+ }
+ } else {
+ // Interrupts routed to the PEs specified by
+ // Aff3.Aff2.Aff1.<target list>
+ if ((affinity_i >> 8) !=
+ ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
+ continue;
+ }
+
+ uint8_t aff0_i = bits(affinity_i, 7, 0);
+
+ if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
+ ((0x1 << (aff0_i - rs * 16)) & target_list))) {
+ continue;
+ }
+ }
+
+ redistributor_i->sendSGI(int_id, group, ns);
+ }
+}
+
+void
Gicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
{
// Update active priority registers.
diff --git a/src/dev/arm/gic_v3_cpu_interface.hh b/src/dev/arm/gic_v3_cpu_interface.hh
index e6dcb51ff..5c66fd75f 100644
--- a/src/dev/arm/gic_v3_cpu_interface.hh
+++ b/src/dev/arm/gic_v3_cpu_interface.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2018 Metempsy Technology Consulting
* All rights reserved.
*
@@ -286,6 +298,7 @@ class Gicv3CPUInterface : public ArmISA::BaseISADevice, public Serializable
protected:
void activateIRQ(uint32_t intid, Gicv3::GroupId group);
+ void generateSGI(RegVal val, Gicv3::GroupId group);
int currEL() const;
void deactivateIRQ(uint32_t intid, Gicv3::GroupId group);
void dropPriority(Gicv3::GroupId group);
diff --git a/src/dev/arm/gic_v3_redistributor.cc b/src/dev/arm/gic_v3_redistributor.cc
index 37f169f19..71e74bfb8 100644
--- a/src/dev/arm/gic_v3_redistributor.cc
+++ b/src/dev/arm/gic_v3_redistributor.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2018 Metempsy Technology Consulting
* All rights reserved.
*
@@ -730,26 +742,31 @@ Gicv3Redistributor::sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
assert(int_id < Gicv3::SGI_MAX);
Gicv3::GroupId int_group = getIntGroup(int_id);
- // asked for secure group 1
- // configured as group 0
- // send group 0
- if (int_group == Gicv3::G0S && group == Gicv3::G1S) {
- group = Gicv3::G0S;
- }
-
- if (group == Gicv3::G0S and int_group != Gicv3::G0S) {
- return;
- }
+ bool forward = false;
- if (ns && distributor->DS == 0) {
+ if (ns) {
+ // Non-Secure EL1 and EL2 access
int nsaccess = irqNsacr[int_id];
+ if (int_group == Gicv3::G0S) {
- if ((int_group == Gicv3::G0S && nsaccess < 1) ||
- (int_group == Gicv3::G1S && nsaccess < 2)) {
- return;
+ forward = distributor->DS || (nsaccess >= 1);
+
+ } else if (int_group == Gicv3::G1S) {
+ forward = ((group == Gicv3::G1S || group == Gicv3::G1NS ) &&
+ nsaccess == 2);
+ } else {
+ // G1NS
+ forward = group == Gicv3::G1NS;
}
+ } else {
+ // Secure EL1 and EL3 access
+ forward = (group == int_group) ||
+ (group == Gicv3::G1S && int_group == Gicv3::G0S &&
+ distributor->DS);
}
+ if (!forward) return;
+
irqPending[int_id] = true;
DPRINTF(GIC, "Gicv3ReDistributor::sendSGI(): "
"int_id %d (SGI) pending bit set\n", int_id);