xref: /qemu/hw/ppc/pnv_adu.c (revision 53f18b3ef2c3e898e7dae21a1f33f9e2f3eed764)
1 /*
2  * QEMU PowerPC PowerNV ADU unit
3  *
4  * The ADU unit actually implements XSCOM, which is the bridge between MMIO
5  * and PIB. However it also includes control and status registers and other
6  * functions that are exposed as PIB (xscom) registers.
7  *
8  * To keep things simple, pnv_xscom.c remains the XSCOM bridge
9  * implementation, and pnv_adu.c implements the ADU registers and other
10  * functions.
11  *
12  * Copyright (c) 2024, IBM Corporation.
13  *
14  * SPDX-License-Identifier: GPL-2.0-or-later
15  */
16 
17 #include "qemu/osdep.h"
18 #include "qemu/log.h"
19 
20 #include "hw/qdev-properties.h"
21 #include "hw/ppc/pnv.h"
22 #include "hw/ppc/pnv_adu.h"
23 #include "hw/ppc/pnv_chip.h"
24 #include "hw/ppc/pnv_xscom.h"
25 #include "trace.h"
26 
27 static uint64_t pnv_adu_xscom_read(void *opaque, hwaddr addr, unsigned width)
28 {
29     uint32_t offset = addr >> 3;
30     uint64_t val = 0;
31 
32     switch (offset) {
33     case 0x18:     /* Receive status reg */
34     case 0x12:     /* log register */
35     case 0x13:     /* error register */
36         break;
37 
38     default:
39         qemu_log_mask(LOG_UNIMP, "ADU Unimplemented read register: Ox%08x\n",
40                                                                      offset);
41     }
42 
43     trace_pnv_adu_xscom_read(addr, val);
44 
45     return val;
46 }
47 
48 static void pnv_adu_xscom_write(void *opaque, hwaddr addr, uint64_t val,
49                                 unsigned width)
50 {
51     uint32_t offset = addr >> 3;
52 
53     trace_pnv_adu_xscom_write(addr, val);
54 
55     switch (offset) {
56     case 0x18:     /* Receive status reg */
57     case 0x12:     /* log register */
58     case 0x13:     /* error register */
59         break;
60 
61     default:
62         qemu_log_mask(LOG_UNIMP, "ADU Unimplemented write register: Ox%08x\n",
63                                                                      offset);
64     }
65 }
66 
67 const MemoryRegionOps pnv_adu_xscom_ops = {
68     .read = pnv_adu_xscom_read,
69     .write = pnv_adu_xscom_write,
70     .valid.min_access_size = 8,
71     .valid.max_access_size = 8,
72     .impl.min_access_size = 8,
73     .impl.max_access_size = 8,
74     .endianness = DEVICE_BIG_ENDIAN,
75 };
76 
77 static void pnv_adu_realize(DeviceState *dev, Error **errp)
78 {
79     PnvADU *adu = PNV_ADU(dev);
80 
81     /* XScom regions for ADU registers */
82     pnv_xscom_region_init(&adu->xscom_regs, OBJECT(dev),
83                           &pnv_adu_xscom_ops, adu, "xscom-adu",
84                           PNV9_XSCOM_ADU_SIZE);
85 }
86 
87 static void pnv_adu_class_init(ObjectClass *klass, void *data)
88 {
89     DeviceClass *dc = DEVICE_CLASS(klass);
90 
91     dc->realize = pnv_adu_realize;
92     dc->desc = "PowerNV ADU";
93     dc->user_creatable = false;
94 }
95 
96 static const TypeInfo pnv_adu_type_info = {
97     .name          = TYPE_PNV_ADU,
98     .parent        = TYPE_DEVICE,
99     .instance_size = sizeof(PnvADU),
100     .class_init    = pnv_adu_class_init,
101     .interfaces    = (InterfaceInfo[]) {
102         { TYPE_PNV_XSCOM_INTERFACE },
103         { } },
104 };
105 
106 static void pnv_adu_register_types(void)
107 {
108     type_register_static(&pnv_adu_type_info);
109 }
110 
111 type_init(pnv_adu_register_types);
112