summaryrefslogtreecommitdiff
path: root/src/dev/arm/gic_v3_redistributor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/arm/gic_v3_redistributor.cc')
-rw-r--r--src/dev/arm/gic_v3_redistributor.cc45
1 files changed, 31 insertions, 14 deletions
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);