2 * ASPEED SLI Controller
4 * Copyright (C) 2024 ASPEED Technology Inc.
6 * SPDX-License-Identifier: GPL-2.0-or-later
9 #include "qemu/osdep.h"
11 #include "qemu/error-report.h"
12 #include "hw/qdev-properties.h"
13 #include "hw/misc/aspeed_sli.h"
14 #include "qapi/error.h"
15 #include "migration/vmstate.h"
18 #define SLI_REGION_SIZE 0x500
19 #define TO_REG(addr) ((addr) >> 2)
21 static uint64_t aspeed_sli_read(void *opaque
, hwaddr addr
, unsigned int size
)
23 AspeedSLIState
*s
= ASPEED_SLI(opaque
);
24 int reg
= TO_REG(addr
);
26 if (reg
>= ARRAY_SIZE(s
->regs
)) {
27 qemu_log_mask(LOG_GUEST_ERROR
,
28 "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx
"\n",
33 trace_aspeed_sli_read(addr
, size
, s
->regs
[reg
]);
37 static void aspeed_sli_write(void *opaque
, hwaddr addr
, uint64_t data
,
40 AspeedSLIState
*s
= ASPEED_SLI(opaque
);
41 int reg
= TO_REG(addr
);
43 if (reg
>= ARRAY_SIZE(s
->regs
)) {
44 qemu_log_mask(LOG_GUEST_ERROR
,
45 "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx
"\n",
50 trace_aspeed_sli_write(addr
, size
, data
);
54 static uint64_t aspeed_sliio_read(void *opaque
, hwaddr addr
, unsigned int size
)
56 AspeedSLIState
*s
= ASPEED_SLI(opaque
);
57 int reg
= TO_REG(addr
);
59 if (reg
>= ARRAY_SIZE(s
->regs
)) {
60 qemu_log_mask(LOG_GUEST_ERROR
,
61 "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx
"\n",
66 trace_aspeed_sliio_read(addr
, size
, s
->regs
[reg
]);
70 static void aspeed_sliio_write(void *opaque
, hwaddr addr
, uint64_t data
,
73 AspeedSLIState
*s
= ASPEED_SLI(opaque
);
74 int reg
= TO_REG(addr
);
76 if (reg
>= ARRAY_SIZE(s
->regs
)) {
77 qemu_log_mask(LOG_GUEST_ERROR
,
78 "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx
"\n",
83 trace_aspeed_sliio_write(addr
, size
, data
);
87 static const MemoryRegionOps aspeed_sli_ops
= {
88 .read
= aspeed_sli_read
,
89 .write
= aspeed_sli_write
,
90 .endianness
= DEVICE_LITTLE_ENDIAN
,
97 static const MemoryRegionOps aspeed_sliio_ops
= {
98 .read
= aspeed_sliio_read
,
99 .write
= aspeed_sliio_write
,
100 .endianness
= DEVICE_LITTLE_ENDIAN
,
102 .min_access_size
= 1,
103 .max_access_size
= 4,
107 static void aspeed_sli_realize(DeviceState
*dev
, Error
**errp
)
109 AspeedSLIState
*s
= ASPEED_SLI(dev
);
110 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
112 memory_region_init_io(&s
->iomem
, OBJECT(s
), &aspeed_sli_ops
, s
,
113 TYPE_ASPEED_SLI
, SLI_REGION_SIZE
);
114 sysbus_init_mmio(sbd
, &s
->iomem
);
117 static void aspeed_sliio_realize(DeviceState
*dev
, Error
**errp
)
119 AspeedSLIState
*s
= ASPEED_SLI(dev
);
120 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
122 memory_region_init_io(&s
->iomem
, OBJECT(s
), &aspeed_sliio_ops
, s
,
123 TYPE_ASPEED_SLI
, SLI_REGION_SIZE
);
124 sysbus_init_mmio(sbd
, &s
->iomem
);
127 static void aspeed_sli_class_init(ObjectClass
*klass
, void *data
)
129 DeviceClass
*dc
= DEVICE_CLASS(klass
);
131 dc
->desc
= "Aspeed SLI Controller";
132 dc
->realize
= aspeed_sli_realize
;
135 static const TypeInfo aspeed_sli_info
= {
136 .name
= TYPE_ASPEED_SLI
,
137 .parent
= TYPE_SYS_BUS_DEVICE
,
138 .instance_size
= sizeof(AspeedSLIState
),
139 .class_init
= aspeed_sli_class_init
,
143 static void aspeed_2700_sli_class_init(ObjectClass
*klass
, void *data
)
145 DeviceClass
*dc
= DEVICE_CLASS(klass
);
147 dc
->desc
= "AST2700 SLI Controller";
150 static void aspeed_2700_sliio_class_init(ObjectClass
*klass
, void *data
)
152 DeviceClass
*dc
= DEVICE_CLASS(klass
);
154 dc
->desc
= "AST2700 I/O SLI Controller";
155 dc
->realize
= aspeed_sliio_realize
;
158 static const TypeInfo aspeed_2700_sli_info
= {
159 .name
= TYPE_ASPEED_2700_SLI
,
160 .parent
= TYPE_ASPEED_SLI
,
161 .class_init
= aspeed_2700_sli_class_init
,
164 static const TypeInfo aspeed_2700_sliio_info
= {
165 .name
= TYPE_ASPEED_2700_SLIIO
,
166 .parent
= TYPE_ASPEED_SLI
,
167 .class_init
= aspeed_2700_sliio_class_init
,
170 static void aspeed_sli_register_types(void)
172 type_register_static(&aspeed_sli_info
);
173 type_register_static(&aspeed_2700_sli_info
);
174 type_register_static(&aspeed_2700_sliio_info
);
177 type_init(aspeed_sli_register_types
);