xref: /qemu/hw/misc/iotkit-sysinfo.c (revision 446587a914cfa57c2ce529056a9ca2215bde7111)
1c667a25bSPeter Maydell /*
2c667a25bSPeter Maydell  * ARM IoTKit system information block
3c667a25bSPeter Maydell  *
4c667a25bSPeter Maydell  * Copyright (c) 2018 Linaro Limited
5c667a25bSPeter Maydell  * Written by Peter Maydell
6c667a25bSPeter Maydell  *
7c667a25bSPeter Maydell  *  This program is free software; you can redistribute it and/or modify
8c667a25bSPeter Maydell  *  it under the terms of the GNU General Public License version 2 or
9c667a25bSPeter Maydell  *  (at your option) any later version.
10c667a25bSPeter Maydell  */
11c667a25bSPeter Maydell 
12c667a25bSPeter Maydell /*
13c667a25bSPeter Maydell  * This is a model of the "system information block" which is part of the
14c667a25bSPeter Maydell  * Arm IoTKit and documented in
1550b52b18SPeter Maydell  * https://developer.arm.com/documentation/ecm0601256/latest
16c667a25bSPeter Maydell  * It consists of 2 read-only version/config registers, plus the
17c667a25bSPeter Maydell  * usual ID registers.
18c667a25bSPeter Maydell  */
19c667a25bSPeter Maydell 
20c667a25bSPeter Maydell #include "qemu/osdep.h"
21c667a25bSPeter Maydell #include "qemu/log.h"
220b8fa32fSMarkus Armbruster #include "qemu/module.h"
23c667a25bSPeter Maydell #include "trace.h"
24c667a25bSPeter Maydell #include "qapi/error.h"
25c667a25bSPeter Maydell #include "hw/sysbus.h"
26c667a25bSPeter Maydell #include "hw/registerfields.h"
27c667a25bSPeter Maydell #include "hw/misc/iotkit-sysinfo.h"
28a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
2940766453SPeter Maydell #include "hw/arm/armsse-version.h"
30c667a25bSPeter Maydell 
31c667a25bSPeter Maydell REG32(SYS_VERSION, 0x0)
32c667a25bSPeter Maydell REG32(SYS_CONFIG, 0x4)
33*446587a9SPeter Maydell REG32(SYS_CONFIG1, 0x8)
34*446587a9SPeter Maydell REG32(IIDR, 0xfc8)
35c667a25bSPeter Maydell REG32(PID4, 0xfd0)
36c667a25bSPeter Maydell REG32(PID5, 0xfd4)
37c667a25bSPeter Maydell REG32(PID6, 0xfd8)
38c667a25bSPeter Maydell REG32(PID7, 0xfdc)
39c667a25bSPeter Maydell REG32(PID0, 0xfe0)
40c667a25bSPeter Maydell REG32(PID1, 0xfe4)
41c667a25bSPeter Maydell REG32(PID2, 0xfe8)
42c667a25bSPeter Maydell REG32(PID3, 0xfec)
43c667a25bSPeter Maydell REG32(CID0, 0xff0)
44c667a25bSPeter Maydell REG32(CID1, 0xff4)
45c667a25bSPeter Maydell REG32(CID2, 0xff8)
46c667a25bSPeter Maydell REG32(CID3, 0xffc)
47c667a25bSPeter Maydell 
48c667a25bSPeter Maydell /* PID/CID values */
49c667a25bSPeter Maydell static const int sysinfo_id[] = {
50c667a25bSPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
51c667a25bSPeter Maydell     0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
52c667a25bSPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
53c667a25bSPeter Maydell };
54c667a25bSPeter Maydell 
5540766453SPeter Maydell static const int sysinfo_sse300_id[] = {
5640766453SPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
5740766453SPeter Maydell     0x58, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
5840766453SPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
5940766453SPeter Maydell };
6040766453SPeter Maydell 
61c667a25bSPeter Maydell static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
62c667a25bSPeter Maydell                                     unsigned size)
63c667a25bSPeter Maydell {
64dde0c491SPeter Maydell     IoTKitSysInfo *s = IOTKIT_SYSINFO(opaque);
65c667a25bSPeter Maydell     uint64_t r;
66c667a25bSPeter Maydell 
67c667a25bSPeter Maydell     switch (offset) {
68c667a25bSPeter Maydell     case A_SYS_VERSION:
69dde0c491SPeter Maydell         r = s->sys_version;
70c667a25bSPeter Maydell         break;
71c667a25bSPeter Maydell 
72c667a25bSPeter Maydell     case A_SYS_CONFIG:
73dde0c491SPeter Maydell         r = s->sys_config;
74c667a25bSPeter Maydell         break;
75*446587a9SPeter Maydell     case A_SYS_CONFIG1:
76*446587a9SPeter Maydell         switch (s->sse_version) {
77*446587a9SPeter Maydell         case ARMSSE_SSE300:
78*446587a9SPeter Maydell             return 0;
79*446587a9SPeter Maydell             break;
80*446587a9SPeter Maydell         default:
81*446587a9SPeter Maydell             goto bad_read;
82*446587a9SPeter Maydell         }
83*446587a9SPeter Maydell         break;
84*446587a9SPeter Maydell     case A_IIDR:
85*446587a9SPeter Maydell         switch (s->sse_version) {
86*446587a9SPeter Maydell         case ARMSSE_SSE300:
87*446587a9SPeter Maydell             return s->iidr;
88*446587a9SPeter Maydell             break;
89*446587a9SPeter Maydell         default:
90*446587a9SPeter Maydell             goto bad_read;
91*446587a9SPeter Maydell         }
92*446587a9SPeter Maydell         break;
93c667a25bSPeter Maydell     case A_PID4 ... A_CID3:
9440766453SPeter Maydell         switch (s->sse_version) {
9540766453SPeter Maydell         case ARMSSE_SSE300:
9640766453SPeter Maydell             r = sysinfo_sse300_id[(offset - A_PID4) / 4];
9740766453SPeter Maydell             break;
9840766453SPeter Maydell         default:
99c667a25bSPeter Maydell             r = sysinfo_id[(offset - A_PID4) / 4];
100c667a25bSPeter Maydell             break;
10140766453SPeter Maydell         }
10240766453SPeter Maydell         break;
103c667a25bSPeter Maydell     default:
104*446587a9SPeter Maydell     bad_read:
105c667a25bSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
106c667a25bSPeter Maydell                       "IoTKit SysInfo read: bad offset %x\n", (int)offset);
107c667a25bSPeter Maydell         r = 0;
108c667a25bSPeter Maydell         break;
109c667a25bSPeter Maydell     }
110c667a25bSPeter Maydell     trace_iotkit_sysinfo_read(offset, r, size);
111c667a25bSPeter Maydell     return r;
112c667a25bSPeter Maydell }
113c667a25bSPeter Maydell 
114c667a25bSPeter Maydell static void iotkit_sysinfo_write(void *opaque, hwaddr offset,
115c667a25bSPeter Maydell                                  uint64_t value, unsigned size)
116c667a25bSPeter Maydell {
117c667a25bSPeter Maydell     trace_iotkit_sysinfo_write(offset, value, size);
118c667a25bSPeter Maydell 
119c667a25bSPeter Maydell     qemu_log_mask(LOG_GUEST_ERROR,
120c667a25bSPeter Maydell                   "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset);
121c667a25bSPeter Maydell }
122c667a25bSPeter Maydell 
123c667a25bSPeter Maydell static const MemoryRegionOps iotkit_sysinfo_ops = {
124c667a25bSPeter Maydell     .read = iotkit_sysinfo_read,
125c667a25bSPeter Maydell     .write = iotkit_sysinfo_write,
126c667a25bSPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
127c667a25bSPeter Maydell     /* byte/halfword accesses are just zero-padded on reads and writes */
128c667a25bSPeter Maydell     .impl.min_access_size = 4,
129c667a25bSPeter Maydell     .impl.max_access_size = 4,
130c667a25bSPeter Maydell     .valid.min_access_size = 1,
131c667a25bSPeter Maydell     .valid.max_access_size = 4,
132c667a25bSPeter Maydell };
133c667a25bSPeter Maydell 
134dde0c491SPeter Maydell static Property iotkit_sysinfo_props[] = {
135dde0c491SPeter Maydell     DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
136dde0c491SPeter Maydell     DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
13740766453SPeter Maydell     DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
138*446587a9SPeter Maydell     DEFINE_PROP_UINT32("IIDR", IoTKitSysInfo, iidr, 0),
139dde0c491SPeter Maydell     DEFINE_PROP_END_OF_LIST()
140dde0c491SPeter Maydell };
141dde0c491SPeter Maydell 
142c667a25bSPeter Maydell static void iotkit_sysinfo_init(Object *obj)
143c667a25bSPeter Maydell {
144c667a25bSPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
145c667a25bSPeter Maydell     IoTKitSysInfo *s = IOTKIT_SYSINFO(obj);
146c667a25bSPeter Maydell 
147c667a25bSPeter Maydell     memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops,
148c667a25bSPeter Maydell                           s, "iotkit-sysinfo", 0x1000);
149c667a25bSPeter Maydell     sysbus_init_mmio(sbd, &s->iomem);
150c667a25bSPeter Maydell }
151c667a25bSPeter Maydell 
15240766453SPeter Maydell static void iotkit_sysinfo_realize(DeviceState *dev, Error **errp)
15340766453SPeter Maydell {
15440766453SPeter Maydell     IoTKitSysInfo *s = IOTKIT_SYSINFO(dev);
15540766453SPeter Maydell 
15640766453SPeter Maydell     if (!armsse_version_valid(s->sse_version)) {
15740766453SPeter Maydell         error_setg(errp, "invalid sse-version value %d", s->sse_version);
15840766453SPeter Maydell         return;
15940766453SPeter Maydell     }
16040766453SPeter Maydell }
16140766453SPeter Maydell 
162c667a25bSPeter Maydell static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
163c667a25bSPeter Maydell {
164dde0c491SPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
165dde0c491SPeter Maydell 
166c667a25bSPeter Maydell     /*
167c667a25bSPeter Maydell      * This device has no guest-modifiable state and so it
168c667a25bSPeter Maydell      * does not need a reset function or VMState.
169c667a25bSPeter Maydell      */
17040766453SPeter Maydell     dc->realize = iotkit_sysinfo_realize;
1714f67d30bSMarc-André Lureau     device_class_set_props(dc, iotkit_sysinfo_props);
172c667a25bSPeter Maydell }
173c667a25bSPeter Maydell 
174c667a25bSPeter Maydell static const TypeInfo iotkit_sysinfo_info = {
175c667a25bSPeter Maydell     .name = TYPE_IOTKIT_SYSINFO,
176c667a25bSPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
177c667a25bSPeter Maydell     .instance_size = sizeof(IoTKitSysInfo),
178c667a25bSPeter Maydell     .instance_init = iotkit_sysinfo_init,
179c667a25bSPeter Maydell     .class_init = iotkit_sysinfo_class_init,
180c667a25bSPeter Maydell };
181c667a25bSPeter Maydell 
182c667a25bSPeter Maydell static void iotkit_sysinfo_register_types(void)
183c667a25bSPeter Maydell {
184c667a25bSPeter Maydell     type_register_static(&iotkit_sysinfo_info);
185c667a25bSPeter Maydell }
186c667a25bSPeter Maydell 
187c667a25bSPeter Maydell type_init(iotkit_sysinfo_register_types);
188