aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-19 21:56:15 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-12-10 11:44:56 +0000
commit6ba430b58abfdbe03cbdbad6188c7d0384fffbea (patch)
tree370f166b406bf7c730369eccc2a04dfdab97ce7f
parent46f4976f22a4549322307b34272e053d38653243 (diff)
hw/intc/armv7m_nvic: Implement read/write for RAS register block
The RAS feature has a block of memory-mapped registers at offset 0x5000 within the PPB. For a "minimal RAS" implementation we provide no error records and so the only registers that exist in the block are ERRIIDR and ERRDEVID. The "RAZ/WI for privileged, BusFault for nonprivileged" behaviour of the "nvic-default" region is actually valid for minimal-RAS, so the main benefit of providing an explicit implementation of the register block is more accurate LOG_UNIMP messages, and a framework for where we could add a real RAS implementation later if necessary. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201119215617.29887-27-peter.maydell@linaro.org
-rw-r--r--hw/intc/armv7m_nvic.c56
-rw-r--r--include/hw/intc/armv7m_nvic.h1
2 files changed, 57 insertions, 0 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 01e331ab1e..f63aa2d871 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2519,6 +2519,56 @@ static const MemoryRegionOps nvic_systick_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+
+static MemTxResult ras_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ if (attrs.user) {
+ return MEMTX_ERROR;
+ }
+
+ switch (addr) {
+ case 0xe10: /* ERRIIDR */
+ /* architect field = Arm; product/variant/revision 0 */
+ *data = 0x43b;
+ break;
+ case 0xfc8: /* ERRDEVID */
+ /* Minimal RAS: we implement 0 error record indexes */
+ *data = 0;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Read RAS register offset 0x%x\n",
+ (uint32_t)addr);
+ *data = 0;
+ break;
+ }
+ return MEMTX_OK;
+}
+
+static MemTxResult ras_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ if (attrs.user) {
+ return MEMTX_ERROR;
+ }
+
+ switch (addr) {
+ default:
+ qemu_log_mask(LOG_UNIMP, "Write to RAS register offset 0x%x\n",
+ (uint32_t)addr);
+ break;
+ }
+ return MEMTX_OK;
+}
+
+static const MemoryRegionOps ras_ops = {
+ .read_with_attrs = ras_read,
+ .write_with_attrs = ras_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
/*
* Unassigned portions of the PPB space are RAZ/WI for privileged
* accesses, and fault for non-privileged accesses.
@@ -2866,6 +2916,12 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
&s->systick_ns_mem, 1);
}
+ if (cpu_isar_feature(aa32_ras, s->cpu)) {
+ memory_region_init_io(&s->ras_mem, OBJECT(s),
+ &ras_ops, s, "nvic_ras", 0x1000);
+ memory_region_add_subregion(&s->container, 0x5000, &s->ras_mem);
+ }
+
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
}
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index 33b6d8810c..39c71e1593 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -83,6 +83,7 @@ struct NVICState {
MemoryRegion sysreg_ns_mem;
MemoryRegion systickmem;
MemoryRegion systick_ns_mem;
+ MemoryRegion ras_mem;
MemoryRegion container;
MemoryRegion defaultmem;