summary refs log tree commit diff stats
path: root/hw/intc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-01-25 17:04:47 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-25 17:04:47 +0000
commit2077fef91d5eb8e3745a84fabd87a5ee7d2b535d (patch)
tree99dbdca9cf5c1ef16e06c57661898b3584ba81ea /hw/intc
parenta3f9362af5c7071036fafb66665b85fda1e49bcc (diff)
parent24da047af0e99a83fcc0d50b86c0f2627f7418b3 (diff)
downloadfocaccia-qemu-2077fef91d5eb8e3745a84fabd87a5ee7d2b535d.tar.gz
focaccia-qemu-2077fef91d5eb8e3745a84fabd87a5ee7d2b535d.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180125' into staging
target-arm queue:
 * target/arm: Fix address truncation in 64-bit pagetable walks
 * i.MX: Fix FEC/ENET receive functions
 * target/arm: preparatory refactoring for SVE emulation
 * hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
 * hw/intc/arm_gic: Fix C_RPR value on idle priority
 * hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
 * hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
 * hw/arm/virt: Check that the CPU realize method succeeded
 * sdhci: fix a NULL pointer dereference due to uninitialized AddressSpace object
 * xilinx_spips: Correct usage of an uninitialized local variable
 * pl110: Implement vertical compare/next base interrupts

# gpg: Signature made Thu 25 Jan 2018 12:59:25 GMT
# gpg:                using RSA key 0x3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20180125: (21 commits)
  pl110: Implement vertical compare/next base interrupts
  xilinx_spips: Correct usage of an uninitialized local variable
  sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object
  hw/arm/virt: Check that the CPU realize method succeeded
  hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
  hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
  hw/intc/arm_gic: Fix C_RPR value on idle priority
  hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
  target/arm: Simplify fp_exception_el for user-only
  target/arm: Hoist store to flags output in cpu_get_tb_cpu_state
  target/arm: Move cpu_get_tb_cpu_state out of line
  target/arm: Add ARM_FEATURE_SVE
  vmstate: Add VMSTATE_UINT64_SUB_ARRAY
  target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers
  target/arm: Change the type of vfp.regs
  target/arm: Use pointers in neon tbl helper
  target/arm: Use pointers in neon zip/uzp helpers
  target/arm: Use pointers in crypto helpers
  target/arm: Mark disas_set_insn_syndrome inline
  i.MX: Fix FEC/ENET receive funtions
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/arm_gic.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index d701e49ff9..724bc9fa61 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -93,6 +93,7 @@ void gic_update(GICState *s)
         best_irq = 1023;
         for (irq = 0; irq < s->num_irq; irq++) {
             if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
+                (!GIC_TEST_ACTIVE(irq, cm)) &&
                 (irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
                 if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
                     best_prio = GIC_GET_PRIORITY(irq, cpu);
@@ -255,7 +256,8 @@ static int gic_get_group_priority(GICState *s, int cpu, int irq)
     if (gic_has_groups(s) &&
         !(s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) &&
         GIC_TEST_GROUP(irq, (1 << cpu))) {
-        bpr = s->abpr[cpu];
+        bpr = s->abpr[cpu] - 1;
+        assert(bpr >= 0);
     } else {
         bpr = s->bpr[cpu];
     }
@@ -503,6 +505,11 @@ static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value,
 
 static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs)
 {
+    if ((s->revision != REV_11MPCORE) && (s->running_priority[cpu] > 0xff)) {
+        /* Idle priority */
+        return 0xff;
+    }
+
     if (s->security_extn && !attrs.secure) {
         if (s->running_priority[cpu] & 0x80) {
             /* Running priority in upper half of range: return the Non-secure
@@ -1205,8 +1212,13 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
         break;
     case 0x08: /* Binary Point */
         if (s->security_extn && !attrs.secure) {
-            /* BPR is banked. Non-secure copy stored in ABPR. */
-            *data = s->abpr[cpu];
+            if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
+                /* NS view of BPR when CBPR is 1 */
+                *data = MIN(s->bpr[cpu] + 1, 7);
+            } else {
+                /* BPR is banked. Non-secure copy stored in ABPR. */
+                *data = s->abpr[cpu];
+            }
         } else {
             *data = s->bpr[cpu];
         }
@@ -1279,7 +1291,12 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
         break;
     case 0x08: /* Binary Point */
         if (s->security_extn && !attrs.secure) {
-            s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR);
+            if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
+                /* WI when CBPR is 1 */
+                return MEMTX_OK;
+            } else {
+                s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR);
+            }
         } else {
             s->bpr[cpu] = MAX(value & 0x7, GIC_MIN_BPR);
         }