aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-04-08 15:15:13 +0100
committerPeter Maydell <peter.maydell@linaro.org>2022-04-22 09:19:24 +0100
commit50a3a309e12789e28a3c4e260348ed7305c28b99 (patch)
tree4e16a119a46832bbbdd24f44225a74f4b1255b25 /hw/intc
parent671927a1165fa1a1dc6ebb413f58615f62105d6d (diff)
downloadqemu-50a3a309e12789e28a3c4e260348ed7305c28b99.zip
qemu-50a3a309e12789e28a3c4e260348ed7305c28b99.tar.gz
qemu-50a3a309e12789e28a3c4e260348ed7305c28b99.tar.bz2
hw/intc/arm_gicv3: Report correct PIDR0 values for ID registers
We use the common function gicv3_idreg() to supply the CoreSight ID register values for the GICv3 for the copies of these ID registers in the distributor, redistributor and ITS register frames. This isn't quite correct, because while most of the register values are the same, the PIDR0 value should vary to indicate which of these three frames it is. (You can see this and also the correct values of these PIDR0 registers by looking at the GIC-600 or GIC-700 TRMs, for example.) Make gicv3_idreg() take an extra argument for the PIDR0 value. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220408141550.1271295-5-peter.maydell@linaro.org
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/arm_gicv3_dist.c2
-rw-r--r--hw/intc/arm_gicv3_its.c2
-rw-r--r--hw/intc/arm_gicv3_redist.c2
-rw-r--r--hw/intc/gicv3_internal.h15
4 files changed, 16 insertions, 5 deletions
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
index 28d913b..7f62753 100644
--- a/hw/intc/arm_gicv3_dist.c
+++ b/hw/intc/arm_gicv3_dist.c
@@ -557,7 +557,7 @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
}
case GICD_IDREGS ... GICD_IDREGS + 0x2f:
/* ID registers */
- *data = gicv3_idreg(offset - GICD_IDREGS);
+ *data = gicv3_idreg(offset - GICD_IDREGS, GICV3_PIDR0_DIST);
return true;
case GICD_SGIR:
/* WO registers, return unknown value */
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 44914f2..f8467b6 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -1161,7 +1161,7 @@ static bool its_readl(GICv3ITSState *s, hwaddr offset,
break;
case GITS_IDREGS ... GITS_IDREGS + 0x2f:
/* ID registers */
- *data = gicv3_idreg(offset - GITS_IDREGS);
+ *data = gicv3_idreg(offset - GITS_IDREGS, GICV3_PIDR0_ITS);
break;
case GITS_TYPER:
*data = extract64(s->typer, 0, 32);
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
index 412a04f..dc9729e 100644
--- a/hw/intc/arm_gicv3_redist.c
+++ b/hw/intc/arm_gicv3_redist.c
@@ -234,7 +234,7 @@ static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
*data = cs->gicr_nsacr;
return MEMTX_OK;
case GICR_IDREGS ... GICR_IDREGS + 0x2f:
- *data = gicv3_idreg(offset - GICR_IDREGS);
+ *data = gicv3_idreg(offset - GICR_IDREGS, GICV3_PIDR0_REDIST);
return MEMTX_OK;
default:
return MEMTX_ERROR;
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
index 2bf1bae..dec413f 100644
--- a/hw/intc/gicv3_internal.h
+++ b/hw/intc/gicv3_internal.h
@@ -555,7 +555,12 @@ static inline uint32_t gicv3_iidr(void)
return 0x43b;
}
-static inline uint32_t gicv3_idreg(int regoffset)
+/* CoreSight PIDR0 values for ARM GICv3 implementations */
+#define GICV3_PIDR0_DIST 0x92
+#define GICV3_PIDR0_REDIST 0x93
+#define GICV3_PIDR0_ITS 0x94
+
+static inline uint32_t gicv3_idreg(int regoffset, uint8_t pidr0)
{
/* Return the value of the CoreSight ID register at the specified
* offset from the first ID register (as found in the distributor
@@ -565,7 +570,13 @@ static inline uint32_t gicv3_idreg(int regoffset)
static const uint8_t gicd_ids[] = {
0x44, 0x00, 0x00, 0x00, 0x92, 0xB4, 0x3B, 0x00, 0x0D, 0xF0, 0x05, 0xB1
};
- return gicd_ids[regoffset / 4];
+
+ regoffset /= 4;
+
+ if (regoffset == 4) {
+ return pidr0;
+ }
+ return gicd_ids[regoffset];
}
/**