12f9db77eSPeter Maydell /*
22f9db77eSPeter Maydell * Arm M-profile RAS (Reliability, Availability and Serviceability) block
32f9db77eSPeter Maydell *
42f9db77eSPeter Maydell * Copyright (c) 2021 Linaro Limited
52f9db77eSPeter Maydell *
62f9db77eSPeter Maydell * This program is free software; you can redistribute it and/or modify
72f9db77eSPeter Maydell * it under the terms of the GNU General Public License version 2 or
82f9db77eSPeter Maydell * (at your option) any later version.
92f9db77eSPeter Maydell */
102f9db77eSPeter Maydell
112f9db77eSPeter Maydell #include "qemu/osdep.h"
122f9db77eSPeter Maydell #include "hw/misc/armv7m_ras.h"
132f9db77eSPeter Maydell #include "qemu/log.h"
142f9db77eSPeter Maydell
ras_read(void * opaque,hwaddr addr,uint64_t * data,unsigned size,MemTxAttrs attrs)152f9db77eSPeter Maydell static MemTxResult ras_read(void *opaque, hwaddr addr,
162f9db77eSPeter Maydell uint64_t *data, unsigned size,
172f9db77eSPeter Maydell MemTxAttrs attrs)
182f9db77eSPeter Maydell {
192f9db77eSPeter Maydell if (attrs.user) {
202f9db77eSPeter Maydell return MEMTX_ERROR;
212f9db77eSPeter Maydell }
222f9db77eSPeter Maydell
232f9db77eSPeter Maydell switch (addr) {
242f9db77eSPeter Maydell case 0xe10: /* ERRIIDR */
252f9db77eSPeter Maydell /* architect field = Arm; product/variant/revision 0 */
262f9db77eSPeter Maydell *data = 0x43b;
272f9db77eSPeter Maydell break;
282f9db77eSPeter Maydell case 0xfc8: /* ERRDEVID */
292f9db77eSPeter Maydell /* Minimal RAS: we implement 0 error record indexes */
302f9db77eSPeter Maydell *data = 0;
312f9db77eSPeter Maydell break;
322f9db77eSPeter Maydell default:
332f9db77eSPeter Maydell qemu_log_mask(LOG_UNIMP, "Read RAS register offset 0x%x\n",
342f9db77eSPeter Maydell (uint32_t)addr);
352f9db77eSPeter Maydell *data = 0;
362f9db77eSPeter Maydell break;
372f9db77eSPeter Maydell }
382f9db77eSPeter Maydell return MEMTX_OK;
392f9db77eSPeter Maydell }
402f9db77eSPeter Maydell
ras_write(void * opaque,hwaddr addr,uint64_t value,unsigned size,MemTxAttrs attrs)412f9db77eSPeter Maydell static MemTxResult ras_write(void *opaque, hwaddr addr,
422f9db77eSPeter Maydell uint64_t value, unsigned size,
432f9db77eSPeter Maydell MemTxAttrs attrs)
442f9db77eSPeter Maydell {
452f9db77eSPeter Maydell if (attrs.user) {
462f9db77eSPeter Maydell return MEMTX_ERROR;
472f9db77eSPeter Maydell }
482f9db77eSPeter Maydell
492f9db77eSPeter Maydell switch (addr) {
502f9db77eSPeter Maydell default:
512f9db77eSPeter Maydell qemu_log_mask(LOG_UNIMP, "Write to RAS register offset 0x%x\n",
522f9db77eSPeter Maydell (uint32_t)addr);
532f9db77eSPeter Maydell break;
542f9db77eSPeter Maydell }
552f9db77eSPeter Maydell return MEMTX_OK;
562f9db77eSPeter Maydell }
572f9db77eSPeter Maydell
582f9db77eSPeter Maydell static const MemoryRegionOps ras_ops = {
592f9db77eSPeter Maydell .read_with_attrs = ras_read,
602f9db77eSPeter Maydell .write_with_attrs = ras_write,
612f9db77eSPeter Maydell .endianness = DEVICE_NATIVE_ENDIAN,
622f9db77eSPeter Maydell };
632f9db77eSPeter Maydell
642f9db77eSPeter Maydell
armv7m_ras_init(Object * obj)652f9db77eSPeter Maydell static void armv7m_ras_init(Object *obj)
662f9db77eSPeter Maydell {
672f9db77eSPeter Maydell SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
682f9db77eSPeter Maydell ARMv7MRAS *s = ARMV7M_RAS(obj);
692f9db77eSPeter Maydell
702f9db77eSPeter Maydell memory_region_init_io(&s->iomem, obj, &ras_ops,
712f9db77eSPeter Maydell s, "armv7m-ras", 0x1000);
722f9db77eSPeter Maydell sysbus_init_mmio(sbd, &s->iomem);
732f9db77eSPeter Maydell }
742f9db77eSPeter Maydell
armv7m_ras_class_init(ObjectClass * klass,const void * data)75*12d1a768SPhilippe Mathieu-Daudé static void armv7m_ras_class_init(ObjectClass *klass, const void *data)
762f9db77eSPeter Maydell {
772f9db77eSPeter Maydell /* This device has no state: no need for vmstate or reset */
782f9db77eSPeter Maydell }
792f9db77eSPeter Maydell
802f9db77eSPeter Maydell static const TypeInfo armv7m_ras_info = {
812f9db77eSPeter Maydell .name = TYPE_ARMV7M_RAS,
822f9db77eSPeter Maydell .parent = TYPE_SYS_BUS_DEVICE,
832f9db77eSPeter Maydell .instance_size = sizeof(ARMv7MRAS),
842f9db77eSPeter Maydell .instance_init = armv7m_ras_init,
852f9db77eSPeter Maydell .class_init = armv7m_ras_class_init,
862f9db77eSPeter Maydell };
872f9db77eSPeter Maydell
armv7m_ras_register_types(void)882f9db77eSPeter Maydell static void armv7m_ras_register_types(void)
892f9db77eSPeter Maydell {
902f9db77eSPeter Maydell type_register_static(&armv7m_ras_info);
912f9db77eSPeter Maydell }
922f9db77eSPeter Maydell
932f9db77eSPeter Maydell type_init(armv7m_ras_register_types);
94