qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] arm_gic: Implement GICC_AIAR, GICC_AEOIR and GICC_AHPPIR


From: Andrei Homescu
Subject: [PATCH] arm_gic: Implement GICC_AIAR, GICC_AEOIR and GICC_AHPPIR
Date: Tue, 19 Dec 2023 22:47:35 -0800

From: Arve Hjønnevåg <arve@android.com>

Implement aliased registers so group 1 interrupts can be used in secure
mode.

GICC_AEOIR is only implemented as a direct alias to GICC_EOIR for now as
gic_complete_irq does not currently check if the cpu is in secure mode.

Upstreamed from https://r.android.com/705890 and
https://r.android.com/859189.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Matthew Maurer <mmaurer@google.com>
Signed-off-by: Andrei Homescu <ah@immunant.com>
---
 hw/intc/arm_gic.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 074cf50af2..d0e267a4b2 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -854,7 +854,8 @@ static void gic_deactivate_irq(GICState *s, int cpu, int 
irq, MemTxAttrs attrs)
     gic_clear_active(s, irq, cpu);
 }
 
-static void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
+static void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs,
+                             bool ns_irq)
 {
     int cm = 1 << cpu;
     int group;
@@ -922,7 +923,7 @@ static void gic_complete_irq(GICState *s, int cpu, int irq, 
MemTxAttrs attrs)
 
     group = gic_has_groups(s) && gic_test_group(s, irq, cpu);
 
-    if (gic_cpu_ns_access(s, cpu, attrs) && !group) {
+    if (ns_irq && !group) {
         DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq);
         return;
     }
@@ -1647,6 +1648,22 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, 
int offset,
             *data = s->abpr[cpu];
         }
         break;
+    case 0x20: /* Aliased Interrupt Acknowledge */
+        if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) {
+            *data = 0;
+        } else {
+            attrs.secure = false;
+            *data = gic_acknowledge_irq(s, cpu, attrs);
+        }
+        break;
+    case 0x28: /* Aliased Highest Priority Pending Interrupt */
+        if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) {
+            *data = 0;
+        } else {
+            attrs.secure = false;
+            *data = gic_get_current_pending_irq(s, cpu, attrs);
+        }
+        break;
     case 0xd0: case 0xd4: case 0xd8: case 0xdc:
     {
         int regno = (offset - 0xd0) / 4;
@@ -1724,7 +1741,15 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, 
int offset,
         }
         break;
     case 0x10: /* End Of Interrupt */
-        gic_complete_irq(s, cpu, value & 0x3ff, attrs);
+        gic_complete_irq(s, cpu, value & 0x3ff, attrs,
+                         gic_cpu_ns_access(s, cpu, attrs));
+        return MEMTX_OK;
+    case 0x24: /* Aliased End Of Interrupt */
+        if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) {
+            /* unimplemented, or NS access: RAZ/WI */
+        } else {
+            gic_complete_irq(s, cpu, value & 0x3ff, attrs, true);
+        }
         return MEMTX_OK;
     case 0x1c: /* Aliased Binary Point */
         if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) {
-- 
2.42.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]