xref: /qemu/hw/misc/iotkit-sysinfo.c (revision dde0c4910395445da6b2b756193f89ab578d31a1)
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
15c667a25bSPeter Maydell  * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
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"
22c667a25bSPeter Maydell #include "trace.h"
23c667a25bSPeter Maydell #include "qapi/error.h"
24c667a25bSPeter Maydell #include "sysemu/sysemu.h"
25c667a25bSPeter Maydell #include "hw/sysbus.h"
26c667a25bSPeter Maydell #include "hw/registerfields.h"
27c667a25bSPeter Maydell #include "hw/misc/iotkit-sysinfo.h"
28c667a25bSPeter Maydell 
29c667a25bSPeter Maydell REG32(SYS_VERSION, 0x0)
30c667a25bSPeter Maydell REG32(SYS_CONFIG, 0x4)
31c667a25bSPeter Maydell REG32(PID4, 0xfd0)
32c667a25bSPeter Maydell REG32(PID5, 0xfd4)
33c667a25bSPeter Maydell REG32(PID6, 0xfd8)
34c667a25bSPeter Maydell REG32(PID7, 0xfdc)
35c667a25bSPeter Maydell REG32(PID0, 0xfe0)
36c667a25bSPeter Maydell REG32(PID1, 0xfe4)
37c667a25bSPeter Maydell REG32(PID2, 0xfe8)
38c667a25bSPeter Maydell REG32(PID3, 0xfec)
39c667a25bSPeter Maydell REG32(CID0, 0xff0)
40c667a25bSPeter Maydell REG32(CID1, 0xff4)
41c667a25bSPeter Maydell REG32(CID2, 0xff8)
42c667a25bSPeter Maydell REG32(CID3, 0xffc)
43c667a25bSPeter Maydell 
44c667a25bSPeter Maydell /* PID/CID values */
45c667a25bSPeter Maydell static const int sysinfo_id[] = {
46c667a25bSPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
47c667a25bSPeter Maydell     0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
48c667a25bSPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
49c667a25bSPeter Maydell };
50c667a25bSPeter Maydell 
51c667a25bSPeter Maydell static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
52c667a25bSPeter Maydell                                     unsigned size)
53c667a25bSPeter Maydell {
54*dde0c491SPeter Maydell     IoTKitSysInfo *s = IOTKIT_SYSINFO(opaque);
55c667a25bSPeter Maydell     uint64_t r;
56c667a25bSPeter Maydell 
57c667a25bSPeter Maydell     switch (offset) {
58c667a25bSPeter Maydell     case A_SYS_VERSION:
59*dde0c491SPeter Maydell         r = s->sys_version;
60c667a25bSPeter Maydell         break;
61c667a25bSPeter Maydell 
62c667a25bSPeter Maydell     case A_SYS_CONFIG:
63*dde0c491SPeter Maydell         r = s->sys_config;
64c667a25bSPeter Maydell         break;
65c667a25bSPeter Maydell     case A_PID4 ... A_CID3:
66c667a25bSPeter Maydell         r = sysinfo_id[(offset - A_PID4) / 4];
67c667a25bSPeter Maydell         break;
68c667a25bSPeter Maydell     default:
69c667a25bSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
70c667a25bSPeter Maydell                       "IoTKit SysInfo read: bad offset %x\n", (int)offset);
71c667a25bSPeter Maydell         r = 0;
72c667a25bSPeter Maydell         break;
73c667a25bSPeter Maydell     }
74c667a25bSPeter Maydell     trace_iotkit_sysinfo_read(offset, r, size);
75c667a25bSPeter Maydell     return r;
76c667a25bSPeter Maydell }
77c667a25bSPeter Maydell 
78c667a25bSPeter Maydell static void iotkit_sysinfo_write(void *opaque, hwaddr offset,
79c667a25bSPeter Maydell                                  uint64_t value, unsigned size)
80c667a25bSPeter Maydell {
81c667a25bSPeter Maydell     trace_iotkit_sysinfo_write(offset, value, size);
82c667a25bSPeter Maydell 
83c667a25bSPeter Maydell     qemu_log_mask(LOG_GUEST_ERROR,
84c667a25bSPeter Maydell                   "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset);
85c667a25bSPeter Maydell }
86c667a25bSPeter Maydell 
87c667a25bSPeter Maydell static const MemoryRegionOps iotkit_sysinfo_ops = {
88c667a25bSPeter Maydell     .read = iotkit_sysinfo_read,
89c667a25bSPeter Maydell     .write = iotkit_sysinfo_write,
90c667a25bSPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
91c667a25bSPeter Maydell     /* byte/halfword accesses are just zero-padded on reads and writes */
92c667a25bSPeter Maydell     .impl.min_access_size = 4,
93c667a25bSPeter Maydell     .impl.max_access_size = 4,
94c667a25bSPeter Maydell     .valid.min_access_size = 1,
95c667a25bSPeter Maydell     .valid.max_access_size = 4,
96c667a25bSPeter Maydell };
97c667a25bSPeter Maydell 
98*dde0c491SPeter Maydell static Property iotkit_sysinfo_props[] = {
99*dde0c491SPeter Maydell     DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
100*dde0c491SPeter Maydell     DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
101*dde0c491SPeter Maydell     DEFINE_PROP_END_OF_LIST()
102*dde0c491SPeter Maydell };
103*dde0c491SPeter Maydell 
104c667a25bSPeter Maydell static void iotkit_sysinfo_init(Object *obj)
105c667a25bSPeter Maydell {
106c667a25bSPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
107c667a25bSPeter Maydell     IoTKitSysInfo *s = IOTKIT_SYSINFO(obj);
108c667a25bSPeter Maydell 
109c667a25bSPeter Maydell     memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops,
110c667a25bSPeter Maydell                           s, "iotkit-sysinfo", 0x1000);
111c667a25bSPeter Maydell     sysbus_init_mmio(sbd, &s->iomem);
112c667a25bSPeter Maydell }
113c667a25bSPeter Maydell 
114c667a25bSPeter Maydell static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
115c667a25bSPeter Maydell {
116*dde0c491SPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
117*dde0c491SPeter Maydell 
118c667a25bSPeter Maydell     /*
119c667a25bSPeter Maydell      * This device has no guest-modifiable state and so it
120c667a25bSPeter Maydell      * does not need a reset function or VMState.
121c667a25bSPeter Maydell      */
122*dde0c491SPeter Maydell 
123*dde0c491SPeter Maydell     dc->props = iotkit_sysinfo_props;
124c667a25bSPeter Maydell }
125c667a25bSPeter Maydell 
126c667a25bSPeter Maydell static const TypeInfo iotkit_sysinfo_info = {
127c667a25bSPeter Maydell     .name = TYPE_IOTKIT_SYSINFO,
128c667a25bSPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
129c667a25bSPeter Maydell     .instance_size = sizeof(IoTKitSysInfo),
130c667a25bSPeter Maydell     .instance_init = iotkit_sysinfo_init,
131c667a25bSPeter Maydell     .class_init = iotkit_sysinfo_class_init,
132c667a25bSPeter Maydell };
133c667a25bSPeter Maydell 
134c667a25bSPeter Maydell static void iotkit_sysinfo_register_types(void)
135c667a25bSPeter Maydell {
136c667a25bSPeter Maydell     type_register_static(&iotkit_sysinfo_info);
137c667a25bSPeter Maydell }
138c667a25bSPeter Maydell 
139c667a25bSPeter Maydell type_init(iotkit_sysinfo_register_types);
140