xref: /openbmc/qemu/hw/fsi/lbus.c (revision 28ae3179fc52d2e4d870b635c4a412aab99759e7)
199f0c046SNinad Palsule /*
299f0c046SNinad Palsule  * SPDX-License-Identifier: GPL-2.0-or-later
399f0c046SNinad Palsule  * Copyright (C) 2024 IBM Corp.
499f0c046SNinad Palsule  *
599f0c046SNinad Palsule  * IBM Local bus where FSI slaves are connected
699f0c046SNinad Palsule  */
799f0c046SNinad Palsule 
899f0c046SNinad Palsule #include "qemu/osdep.h"
999f0c046SNinad Palsule #include "qapi/error.h"
1099f0c046SNinad Palsule #include "hw/fsi/lbus.h"
1199f0c046SNinad Palsule #include "hw/qdev-properties.h"
12ca782334SNinad Palsule #include "qemu/log.h"
1399f0c046SNinad Palsule #include "trace.h"
1499f0c046SNinad Palsule 
15ca782334SNinad Palsule #define TO_REG(offset) ((offset) >> 2)
16ca782334SNinad Palsule 
fsi_lbus_init(Object * o)1799f0c046SNinad Palsule static void fsi_lbus_init(Object *o)
1899f0c046SNinad Palsule {
1999f0c046SNinad Palsule     FSILBus *lbus = FSI_LBUS(o);
2099f0c046SNinad Palsule 
2199f0c046SNinad Palsule     memory_region_init(&lbus->mr, OBJECT(lbus), TYPE_FSI_LBUS, 1 * MiB);
2299f0c046SNinad Palsule }
2399f0c046SNinad Palsule 
2499f0c046SNinad Palsule static const TypeInfo fsi_lbus_info = {
2599f0c046SNinad Palsule     .name = TYPE_FSI_LBUS,
2699f0c046SNinad Palsule     .parent = TYPE_BUS,
2799f0c046SNinad Palsule     .instance_init = fsi_lbus_init,
2899f0c046SNinad Palsule     .instance_size = sizeof(FSILBus),
2999f0c046SNinad Palsule };
3099f0c046SNinad Palsule 
3199f0c046SNinad Palsule static const TypeInfo fsi_lbus_device_type_info = {
3299f0c046SNinad Palsule     .name = TYPE_FSI_LBUS_DEVICE,
3399f0c046SNinad Palsule     .parent = TYPE_DEVICE,
3499f0c046SNinad Palsule     .instance_size = sizeof(FSILBusDevice),
3599f0c046SNinad Palsule     .abstract = true,
3699f0c046SNinad Palsule };
3799f0c046SNinad Palsule 
fsi_scratchpad_read(void * opaque,hwaddr addr,unsigned size)38ca782334SNinad Palsule static uint64_t fsi_scratchpad_read(void *opaque, hwaddr addr, unsigned size)
39ca782334SNinad Palsule {
40ca782334SNinad Palsule     FSIScratchPad *s = SCRATCHPAD(opaque);
41ca782334SNinad Palsule     int reg = TO_REG(addr);
42ca782334SNinad Palsule 
43ca782334SNinad Palsule     trace_fsi_scratchpad_read(addr, size);
44ca782334SNinad Palsule 
45ca782334SNinad Palsule     if (reg >= FSI_SCRATCHPAD_NR_REGS) {
46ca782334SNinad Palsule         qemu_log_mask(LOG_GUEST_ERROR,
47ca782334SNinad Palsule                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
48ca782334SNinad Palsule                       __func__, addr);
49ca782334SNinad Palsule         return 0;
50ca782334SNinad Palsule     }
51ca782334SNinad Palsule 
52ca782334SNinad Palsule     return s->regs[reg];
53ca782334SNinad Palsule }
54ca782334SNinad Palsule 
fsi_scratchpad_write(void * opaque,hwaddr addr,uint64_t data,unsigned size)55ca782334SNinad Palsule static void fsi_scratchpad_write(void *opaque, hwaddr addr, uint64_t data,
56ca782334SNinad Palsule                                  unsigned size)
57ca782334SNinad Palsule {
58ca782334SNinad Palsule     FSIScratchPad *s = SCRATCHPAD(opaque);
59ca782334SNinad Palsule 
60ca782334SNinad Palsule     trace_fsi_scratchpad_write(addr, size, data);
61ca782334SNinad Palsule     int reg = TO_REG(addr);
62ca782334SNinad Palsule 
63ca782334SNinad Palsule     if (reg >= FSI_SCRATCHPAD_NR_REGS) {
64ca782334SNinad Palsule         qemu_log_mask(LOG_GUEST_ERROR,
65ca782334SNinad Palsule                       "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
66ca782334SNinad Palsule                       __func__, addr);
67ca782334SNinad Palsule         return;
68ca782334SNinad Palsule     }
69ca782334SNinad Palsule 
70ca782334SNinad Palsule     s->regs[reg] = data;
71ca782334SNinad Palsule }
72ca782334SNinad Palsule 
73ca782334SNinad Palsule static const struct MemoryRegionOps scratchpad_ops = {
74ca782334SNinad Palsule     .read = fsi_scratchpad_read,
75ca782334SNinad Palsule     .write = fsi_scratchpad_write,
76ca782334SNinad Palsule     .endianness = DEVICE_BIG_ENDIAN,
77ca782334SNinad Palsule };
78ca782334SNinad Palsule 
fsi_scratchpad_realize(DeviceState * dev,Error ** errp)79ca782334SNinad Palsule static void fsi_scratchpad_realize(DeviceState *dev, Error **errp)
80ca782334SNinad Palsule {
81ca782334SNinad Palsule     FSILBusDevice *ldev = FSI_LBUS_DEVICE(dev);
82ca782334SNinad Palsule 
83ca782334SNinad Palsule     memory_region_init_io(&ldev->iomem, OBJECT(ldev), &scratchpad_ops,
84ca782334SNinad Palsule                           ldev, TYPE_FSI_SCRATCHPAD, 0x400);
85ca782334SNinad Palsule }
86ca782334SNinad Palsule 
fsi_scratchpad_reset(DeviceState * dev)87ca782334SNinad Palsule static void fsi_scratchpad_reset(DeviceState *dev)
88ca782334SNinad Palsule {
89ca782334SNinad Palsule     FSIScratchPad *s = SCRATCHPAD(dev);
90ca782334SNinad Palsule 
91ca782334SNinad Palsule     memset(s->regs, 0, sizeof(s->regs));
92ca782334SNinad Palsule }
93ca782334SNinad Palsule 
fsi_scratchpad_class_init(ObjectClass * klass,void * data)94ca782334SNinad Palsule static void fsi_scratchpad_class_init(ObjectClass *klass, void *data)
95ca782334SNinad Palsule {
96ca782334SNinad Palsule     DeviceClass *dc = DEVICE_CLASS(klass);
97ca782334SNinad Palsule 
98ca782334SNinad Palsule     dc->bus_type = TYPE_FSI_LBUS;
99ca782334SNinad Palsule     dc->realize = fsi_scratchpad_realize;
100*e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, fsi_scratchpad_reset);
101ca782334SNinad Palsule }
102ca782334SNinad Palsule 
103ca782334SNinad Palsule static const TypeInfo fsi_scratchpad_info = {
104ca782334SNinad Palsule     .name = TYPE_FSI_SCRATCHPAD,
105ca782334SNinad Palsule     .parent = TYPE_FSI_LBUS_DEVICE,
106ca782334SNinad Palsule     .instance_size = sizeof(FSIScratchPad),
107ca782334SNinad Palsule     .class_init = fsi_scratchpad_class_init,
108ca782334SNinad Palsule };
109ca782334SNinad Palsule 
fsi_lbus_register_types(void)11099f0c046SNinad Palsule static void fsi_lbus_register_types(void)
11199f0c046SNinad Palsule {
11299f0c046SNinad Palsule     type_register_static(&fsi_lbus_info);
11399f0c046SNinad Palsule     type_register_static(&fsi_lbus_device_type_info);
114ca782334SNinad Palsule     type_register_static(&fsi_scratchpad_info);
11599f0c046SNinad Palsule }
11699f0c046SNinad Palsule 
11799f0c046SNinad Palsule type_init(fsi_lbus_register_types);
118