aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Bennée <alex.bennee@linaro.org>2022-11-21 11:45:13 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-11-21 11:45:13 +0000
commit69e7e60d011846f066af97589660eef52898519a (patch)
tree68895e170c6698c4d74899a0d917c8d06baa828d
parent93e2da36ed944d05e78905e95983a44624ed064c (diff)
hw/intc: clean-up access to GIC multi-byte registers
gic_dist_readb was returning a word value which just happened to work as a result of the way we OR the data together. Lets fix it so only the explicit byte is returned for each part of GICD_TYPER. I've changed the return type to uint8_t although the overflow is only detected with an explicit -Wconversion. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/intc/arm_gic.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 492b2421ab..1a04144c38 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -941,7 +941,7 @@ static void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
gic_update(s);
}
-static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
+static uint8_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
{
GICState *s = (GICState *)opaque;
uint32_t res;
@@ -955,6 +955,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
cm = 1 << cpu;
if (offset < 0x100) {
if (offset == 0) { /* GICD_CTLR */
+ /* We rely here on the only non-zero bits being in byte 0 */
if (s->security_extn && !attrs.secure) {
/* The NS bank of this register is just an alias of the
* EnableGrp1 bit in the S bank version.
@@ -964,11 +965,14 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
return s->ctlr;
}
}
- if (offset == 4)
- /* Interrupt Controller Type Register */
- return ((s->num_irq / 32) - 1)
- | ((s->num_cpu - 1) << 5)
- | (s->security_extn << 10);
+ if (offset == 4) {
+ /* GICD_TYPER byte 0 */
+ return ((s->num_irq / 32) - 1) | ((s->num_cpu - 1) << 5);
+ }
+ if (offset == 5) {
+ /* GICD_TYPER byte 1 */
+ return (s->security_extn << 2);
+ }
if (offset < 0x08)
return 0;
if (offset >= 0x80) {