xref: /qemu/hw/misc/armv7m_ras.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
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