diff options
author | Peter Maydell | 2020-11-19 22:56:15 +0100 |
---|---|---|
committer | Peter Maydell | 2020-12-10 12:44:56 +0100 |
commit | 6ba430b58abfdbe03cbdbad6188c7d0384fffbea (patch) | |
tree | 370f166b406bf7c730369eccc2a04dfdab97ce7f /hw/intc/armv7m_nvic.c | |
parent | target/arm: Implement M-profile "minimal RAS implementation" (diff) | |
download | qemu-6ba430b58abfdbe03cbdbad6188c7d0384fffbea.tar.gz qemu-6ba430b58abfdbe03cbdbad6188c7d0384fffbea.tar.xz qemu-6ba430b58abfdbe03cbdbad6188c7d0384fffbea.zip |
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
Diffstat (limited to 'hw/intc/armv7m_nvic.c')
-rw-r--r-- | hw/intc/armv7m_nvic.c | 56 |
1 files changed, 56 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); } |