]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * QEMU Empty Slot | |
3 | * | |
4 | * The empty_slot device emulates known to a bus but not connected devices. | |
5 | * | |
6 | * Copyright (c) 2010 Artyom Tarasenko | |
7 | * | |
8 | * This code is licensed under the GNU GPL v2 or (at your option) any later | |
9 | * version. | |
10 | */ | |
11 | ||
12 | #include "hw.h" | |
13 | #include "sysbus.h" | |
14 | #include "empty_slot.h" | |
15 | ||
16 | //#define DEBUG_EMPTY_SLOT | |
17 | ||
18 | #ifdef DEBUG_EMPTY_SLOT | |
19 | #define DPRINTF(fmt, ...) \ | |
20 | do { printf("empty_slot: " fmt , ## __VA_ARGS__); } while (0) | |
21 | #else | |
22 | #define DPRINTF(fmt, ...) do {} while (0) | |
23 | #endif | |
24 | ||
25 | typedef struct EmptySlot { | |
26 | SysBusDevice busdev; | |
27 | MemoryRegion iomem; | |
28 | uint64_t size; | |
29 | } EmptySlot; | |
30 | ||
31 | static uint64_t empty_slot_read(void *opaque, hwaddr addr, | |
32 | unsigned size) | |
33 | { | |
34 | DPRINTF("read from " TARGET_FMT_plx "\n", addr); | |
35 | return 0; | |
36 | } | |
37 | ||
38 | static void empty_slot_write(void *opaque, hwaddr addr, | |
39 | uint64_t val, unsigned size) | |
40 | { | |
41 | DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr); | |
42 | } | |
43 | ||
44 | static const MemoryRegionOps empty_slot_ops = { | |
45 | .read = empty_slot_read, | |
46 | .write = empty_slot_write, | |
47 | .endianness = DEVICE_NATIVE_ENDIAN, | |
48 | }; | |
49 | ||
50 | void empty_slot_init(hwaddr addr, uint64_t slot_size) | |
51 | { | |
52 | if (slot_size > 0) { | |
53 | /* Only empty slots larger than 0 byte need handling. */ | |
54 | DeviceState *dev; | |
55 | SysBusDevice *s; | |
56 | EmptySlot *e; | |
57 | ||
58 | dev = qdev_create(NULL, "empty_slot"); | |
59 | s = sysbus_from_qdev(dev); | |
60 | e = FROM_SYSBUS(EmptySlot, s); | |
61 | e->size = slot_size; | |
62 | ||
63 | qdev_init_nofail(dev); | |
64 | ||
65 | sysbus_mmio_map(s, 0, addr); | |
66 | } | |
67 | } | |
68 | ||
69 | static int empty_slot_init1(SysBusDevice *dev) | |
70 | { | |
71 | EmptySlot *s = FROM_SYSBUS(EmptySlot, dev); | |
72 | ||
73 | memory_region_init_io(&s->iomem, &empty_slot_ops, s, | |
74 | "empty-slot", s->size); | |
75 | sysbus_init_mmio(dev, &s->iomem); | |
76 | return 0; | |
77 | } | |
78 | ||
79 | static void empty_slot_class_init(ObjectClass *klass, void *data) | |
80 | { | |
81 | SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
82 | ||
83 | k->init = empty_slot_init1; | |
84 | } | |
85 | ||
86 | static TypeInfo empty_slot_info = { | |
87 | .name = "empty_slot", | |
88 | .parent = TYPE_SYS_BUS_DEVICE, | |
89 | .instance_size = sizeof(EmptySlot), | |
90 | .class_init = empty_slot_class_init, | |
91 | }; | |
92 | ||
93 | static void empty_slot_register_types(void) | |
94 | { | |
95 | type_register_static(&empty_slot_info); | |
96 | } | |
97 | ||
98 | type_init(empty_slot_register_types) |