xref: /openbmc/qemu/hw/misc/armv7m_ras.c (revision 2f9db77e)
1 /*
2  * Arm M-profile RAS (Reliability, Availability and Serviceability) block
3  *
4  * Copyright (c) 2021 Linaro Limited
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License version 2 or
8  *  (at your option) any later version.
9  */
10 
11 #include "qemu/osdep.h"
12 #include "hw/misc/armv7m_ras.h"
13 #include "qemu/log.h"
14 
ras_read(void * opaque,hwaddr addr,uint64_t * data,unsigned size,MemTxAttrs attrs)15 static MemTxResult ras_read(void *opaque, hwaddr addr,
16                             uint64_t *data, unsigned size,
17                             MemTxAttrs attrs)
18 {
19     if (attrs.user) {
20         return MEMTX_ERROR;
21     }
22 
23     switch (addr) {
24     case 0xe10: /* ERRIIDR */
25         /* architect field = Arm; product/variant/revision 0 */
26         *data = 0x43b;
27         break;
28     case 0xfc8: /* ERRDEVID */
29         /* Minimal RAS: we implement 0 error record indexes */
30         *data = 0;
31         break;
32     default:
33         qemu_log_mask(LOG_UNIMP, "Read RAS register offset 0x%x\n",
34                       (uint32_t)addr);
35         *data = 0;
36         break;
37     }
38     return MEMTX_OK;
39 }
40 
ras_write(void * opaque,hwaddr addr,uint64_t value,unsigned size,MemTxAttrs attrs)41 static MemTxResult ras_write(void *opaque, hwaddr addr,
42                              uint64_t value, unsigned size,
43                              MemTxAttrs attrs)
44 {
45     if (attrs.user) {
46         return MEMTX_ERROR;
47     }
48 
49     switch (addr) {
50     default:
51         qemu_log_mask(LOG_UNIMP, "Write to RAS register offset 0x%x\n",
52                       (uint32_t)addr);
53         break;
54     }
55     return MEMTX_OK;
56 }
57 
58 static const MemoryRegionOps ras_ops = {
59     .read_with_attrs = ras_read,
60     .write_with_attrs = ras_write,
61     .endianness = DEVICE_NATIVE_ENDIAN,
62 };
63 
64 
armv7m_ras_init(Object * obj)65 static void armv7m_ras_init(Object *obj)
66 {
67     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
68     ARMv7MRAS *s = ARMV7M_RAS(obj);
69 
70     memory_region_init_io(&s->iomem, obj, &ras_ops,
71                           s, "armv7m-ras", 0x1000);
72     sysbus_init_mmio(sbd, &s->iomem);
73 }
74 
armv7m_ras_class_init(ObjectClass * klass,void * data)75 static void armv7m_ras_class_init(ObjectClass *klass, void *data)
76 {
77     /* This device has no state: no need for vmstate or reset */
78 }
79 
80 static const TypeInfo armv7m_ras_info = {
81     .name = TYPE_ARMV7M_RAS,
82     .parent = TYPE_SYS_BUS_DEVICE,
83     .instance_size = sizeof(ARMv7MRAS),
84     .instance_init = armv7m_ras_init,
85     .class_init = armv7m_ras_class_init,
86 };
87 
armv7m_ras_register_types(void)88 static void armv7m_ras_register_types(void)
89 {
90     type_register_static(&armv7m_ras_info);
91 }
92 
93 type_init(armv7m_ras_register_types);
94