.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.
&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);
}