Re: [PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block

2020-12-01 Thread Richard Henderson
On 11/19/20 3:56 PM, Peter Maydell wrote:
> 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 
> ---
>  include/hw/intc/armv7m_nvic.h |  1 +
>  hw/intc/armv7m_nvic.c | 56 +++
>  2 files changed, 57 insertions(+)

Reviewed-by: Richard Henderson 

r~



[PATCH v2 26/28] hw/intc/armv7m_nvic: Implement read/write for RAS register block

2020-11-19 Thread Peter Maydell
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 
---
 include/hw/intc/armv7m_nvic.h |  1 +
 hw/intc/armv7m_nvic.c | 56 +++
 2 files changed, 57 insertions(+)

diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index 33b6d8810c7..39c71e15936 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;
 
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c42b291f881..5ab77a3530c 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2530,6 +2530,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.
@@ -2877,6 +2927,12 @@ static void armv7m_nvic_realize(DeviceState *dev, Error 
**errp)
 >systick_ns_mem, 1);
 }
 
+if (cpu_isar_feature(aa32_ras, s->cpu)) {
+memory_region_init_io(>ras_mem, OBJECT(s),
+  _ops, s, "nvic_ras", 0x1000);
+memory_region_add_subregion(>container, 0x5000, >ras_mem);
+}
+
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >container);
 }
 
-- 
2.20.1