24
#include "qemu/osdep.h"
27
#include "hw/misc/grlib_ahb_apb_pnp.h"
30
#define GRLIB_PNP_VENDOR_SHIFT (24)
31
#define GRLIB_PNP_VENDOR_SIZE (8)
32
#define GRLIB_PNP_DEV_SHIFT (12)
33
#define GRLIB_PNP_DEV_SIZE (12)
34
#define GRLIB_PNP_VER_SHIFT (5)
35
#define GRLIB_PNP_VER_SIZE (5)
36
#define GRLIB_PNP_IRQ_SHIFT (0)
37
#define GRLIB_PNP_IRQ_SIZE (5)
38
#define GRLIB_PNP_ADDR_SHIFT (20)
39
#define GRLIB_PNP_ADDR_SIZE (12)
40
#define GRLIB_PNP_MASK_SHIFT (4)
41
#define GRLIB_PNP_MASK_SIZE (12)
43
#define GRLIB_AHB_DEV_ADDR_SHIFT (20)
44
#define GRLIB_AHB_DEV_ADDR_SIZE (12)
45
#define GRLIB_AHB_ENTRY_SIZE (0x20)
46
#define GRLIB_AHB_MAX_DEV (64)
47
#define GRLIB_AHB_SLAVE_OFFSET (0x800)
49
#define GRLIB_APB_DEV_ADDR_SHIFT (8)
50
#define GRLIB_APB_DEV_ADDR_SIZE (12)
51
#define GRLIB_APB_ENTRY_SIZE (0x08)
52
#define GRLIB_APB_MAX_DEV (512)
54
#define GRLIB_PNP_MAX_REGS (0x1000)
56
typedef struct AHBPnp {
57
SysBusDevice parent_obj;
60
uint32_t regs[GRLIB_PNP_MAX_REGS >> 2];
65
void grlib_ahb_pnp_add_entry(AHBPnp *dev, uint32_t address, uint32_t mask,
66
uint8_t vendor, uint16_t device, int slave,
69
unsigned int reg_start;
100
assert(dev->slave_count < GRLIB_AHB_MAX_DEV);
101
reg_start = (GRLIB_AHB_SLAVE_OFFSET
102
+ (dev->slave_count * GRLIB_AHB_ENTRY_SIZE)) >> 2;
105
assert(dev->master_count < GRLIB_AHB_MAX_DEV);
106
reg_start = (dev->master_count * GRLIB_AHB_ENTRY_SIZE) >> 2;
110
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
111
GRLIB_PNP_VENDOR_SHIFT,
112
GRLIB_PNP_VENDOR_SIZE,
114
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
120
dev->regs[reg_start] = type;
121
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
122
GRLIB_PNP_ADDR_SHIFT,
125
GRLIB_AHB_DEV_ADDR_SHIFT,
126
GRLIB_AHB_DEV_ADDR_SIZE));
127
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
128
GRLIB_PNP_MASK_SHIFT,
133
static uint64_t grlib_ahb_pnp_read(void *opaque, hwaddr offset, unsigned size)
135
AHBPnp *ahb_pnp = GRLIB_AHB_PNP(opaque);
138
val = ahb_pnp->regs[offset >> 2];
139
val = extract32(val, (4 - (offset & 3) - size) * 8, size * 8);
140
trace_grlib_ahb_pnp_read(offset, size, val);
145
static void grlib_ahb_pnp_write(void *opaque, hwaddr addr,
146
uint64_t val, unsigned size)
148
qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
151
static const MemoryRegionOps grlib_ahb_pnp_ops = {
152
.read = grlib_ahb_pnp_read,
153
.write = grlib_ahb_pnp_write,
154
.endianness = DEVICE_BIG_ENDIAN,
156
.min_access_size = 1,
157
.max_access_size = 4,
161
static void grlib_ahb_pnp_realize(DeviceState *dev, Error **errp)
163
AHBPnp *ahb_pnp = GRLIB_AHB_PNP(dev);
164
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
166
memory_region_init_io(&ahb_pnp->iomem, OBJECT(dev), &grlib_ahb_pnp_ops,
167
ahb_pnp, TYPE_GRLIB_AHB_PNP, GRLIB_PNP_MAX_REGS);
168
sysbus_init_mmio(sbd, &ahb_pnp->iomem);
171
static void grlib_ahb_pnp_class_init(ObjectClass *klass, void *data)
173
DeviceClass *dc = DEVICE_CLASS(klass);
175
dc->realize = grlib_ahb_pnp_realize;
178
static const TypeInfo grlib_ahb_pnp_info = {
179
.name = TYPE_GRLIB_AHB_PNP,
180
.parent = TYPE_SYS_BUS_DEVICE,
181
.instance_size = sizeof(AHBPnp),
182
.class_init = grlib_ahb_pnp_class_init,
187
typedef struct APBPnp {
188
SysBusDevice parent_obj;
191
uint32_t regs[GRLIB_PNP_MAX_REGS >> 2];
192
uint32_t entry_count;
195
void grlib_apb_pnp_add_entry(APBPnp *dev, uint32_t address, uint32_t mask,
196
uint8_t vendor, uint16_t device, uint8_t version,
197
uint8_t irq, int type)
199
unsigned int reg_start;
211
assert(dev->entry_count < GRLIB_APB_MAX_DEV);
212
reg_start = (dev->entry_count * GRLIB_APB_ENTRY_SIZE) >> 2;
215
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
216
GRLIB_PNP_VENDOR_SHIFT,
217
GRLIB_PNP_VENDOR_SIZE,
219
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
223
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
227
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
232
dev->regs[reg_start] = type;
233
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
234
GRLIB_PNP_ADDR_SHIFT,
237
GRLIB_APB_DEV_ADDR_SHIFT,
238
GRLIB_APB_DEV_ADDR_SIZE));
239
dev->regs[reg_start] = deposit32(dev->regs[reg_start],
240
GRLIB_PNP_MASK_SHIFT,
245
static uint64_t grlib_apb_pnp_read(void *opaque, hwaddr offset, unsigned size)
247
APBPnp *apb_pnp = GRLIB_APB_PNP(opaque);
250
val = apb_pnp->regs[offset >> 2];
251
val = extract32(val, (4 - (offset & 3) - size) * 8, size * 8);
252
trace_grlib_apb_pnp_read(offset, size, val);
257
static void grlib_apb_pnp_write(void *opaque, hwaddr addr,
258
uint64_t val, unsigned size)
260
qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
263
static const MemoryRegionOps grlib_apb_pnp_ops = {
264
.read = grlib_apb_pnp_read,
265
.write = grlib_apb_pnp_write,
266
.endianness = DEVICE_BIG_ENDIAN,
268
.min_access_size = 1,
269
.max_access_size = 4,
273
static void grlib_apb_pnp_realize(DeviceState *dev, Error **errp)
275
APBPnp *apb_pnp = GRLIB_APB_PNP(dev);
276
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
278
memory_region_init_io(&apb_pnp->iomem, OBJECT(dev), &grlib_apb_pnp_ops,
279
apb_pnp, TYPE_GRLIB_APB_PNP, GRLIB_PNP_MAX_REGS);
280
sysbus_init_mmio(sbd, &apb_pnp->iomem);
283
static void grlib_apb_pnp_class_init(ObjectClass *klass, void *data)
285
DeviceClass *dc = DEVICE_CLASS(klass);
287
dc->realize = grlib_apb_pnp_realize;
290
static const TypeInfo grlib_apb_pnp_info = {
291
.name = TYPE_GRLIB_APB_PNP,
292
.parent = TYPE_SYS_BUS_DEVICE,
293
.instance_size = sizeof(APBPnp),
294
.class_init = grlib_apb_pnp_class_init,
297
static void grlib_ahb_apb_pnp_register_types(void)
299
type_register_static(&grlib_ahb_pnp_info);
300
type_register_static(&grlib_apb_pnp_info);
303
type_init(grlib_ahb_apb_pnp_register_types)