mirror of https://github.com/xemu-project/xemu.git
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
This commit is contained in:
parent
46f4976f22
commit
6ba430b58a
|
@ -2519,6 +2519,56 @@ static const MemoryRegionOps nvic_systick_ops = {
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.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
|
* Unassigned portions of the PPB space are RAZ/WI for privileged
|
||||||
* accesses, and fault for non-privileged accesses.
|
* 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);
|
&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);
|
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ struct NVICState {
|
||||||
MemoryRegion sysreg_ns_mem;
|
MemoryRegion sysreg_ns_mem;
|
||||||
MemoryRegion systickmem;
|
MemoryRegion systickmem;
|
||||||
MemoryRegion systick_ns_mem;
|
MemoryRegion systick_ns_mem;
|
||||||
|
MemoryRegion ras_mem;
|
||||||
MemoryRegion container;
|
MemoryRegion container;
|
||||||
MemoryRegion defaultmem;
|
MemoryRegion defaultmem;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue