]> git.proxmox.com Git - mirror_qemu.git/blame - hw/isa/isa-bus.c
virtio-vga: add virtio gpu device with vga compatibility
[mirror_qemu.git] / hw / isa / isa-bus.c
CommitLineData
f915a115
GH
1/*
2 * isa bus support for qdev.
3 *
4 * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
83c9f4ca 19#include "hw/hw.h"
83c9089e 20#include "monitor/monitor.h"
83c9f4ca 21#include "hw/sysbus.h"
9c17d615 22#include "sysemu/sysemu.h"
0d09e41a 23#include "hw/isa/isa.h"
9157eee1 24#include "hw/i386/pc.h"
f915a115 25
f915a115
GH
26static ISABus *isabus;
27
2091ba23 28static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
6a26e119 29static char *isabus_get_fw_dev_path(DeviceState *dev);
2091ba23 30
0d936928
AL
31static void isa_bus_class_init(ObjectClass *klass, void *data)
32{
33 BusClass *k = BUS_CLASS(klass);
34
35 k->print_dev = isabus_dev_print;
36 k->get_fw_dev_path = isabus_get_fw_dev_path;
37}
38
39static const TypeInfo isa_bus_info = {
40 .name = TYPE_ISA_BUS,
41 .parent = TYPE_BUS,
42 .instance_size = sizeof(ISABus),
43 .class_init = isa_bus_class_init,
f915a115
GH
44};
45
bb2ed009
HP
46ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* address_space,
47 MemoryRegion *address_space_io)
f915a115
GH
48{
49 if (isabus) {
50 fprintf(stderr, "Can't create a second ISA bus\n");
51 return NULL;
52 }
337a3e5c 53 if (!dev) {
2091ba23 54 dev = qdev_create(NULL, "isabus-bridge");
e23a1b33 55 qdev_init_nofail(dev);
2091ba23 56 }
f915a115 57
2ae0e48d 58 isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL));
bb2ed009 59 isabus->address_space = address_space;
c2d0d012 60 isabus->address_space_io = address_space_io;
f915a115
GH
61 return isabus;
62}
63
48a18b3c 64void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
f915a115 65{
d3c68e4f
HP
66 if (!bus) {
67 hw_error("Can't set isa irqs with no isa bus present.");
68 }
69 bus->irqs = irqs;
2091ba23
GH
70}
71
3a38d437 72/*
ee951a37 73 * isa_get_irq() returns the corresponding qemu_irq entry for the i8259.
3a38d437
JS
74 *
75 * This function is only for special cases such as the 'ferr', and
76 * temporary use for normal devices until they are converted to qdev.
77 */
48a18b3c 78qemu_irq isa_get_irq(ISADevice *dev, int isairq)
3a38d437 79{
2ae0e48d 80 assert(!dev || ISA_BUS(qdev_get_parent_bus(DEVICE(dev))) == isabus);
3a38d437 81 if (isairq < 0 || isairq > 15) {
74782223 82 hw_error("isa irq %d invalid", isairq);
3a38d437 83 }
3a38d437
JS
84 return isabus->irqs[isairq];
85}
86
2e15e23b 87void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
f915a115 88{
2e15e23b 89 assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
2e15e23b 90 dev->isairq[dev->nirqs] = isairq;
48a18b3c 91 *p = isa_get_irq(dev, isairq);
f915a115
GH
92 dev->nirqs++;
93}
94
0d959524 95static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
dee41d58 96{
0d959524
RH
97 if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) {
98 dev->ioport_id = ioport;
dee41d58 99 }
dee41d58
GN
100}
101
78e20593
RH
102void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
103{
104 memory_region_add_subregion(isabus->address_space_io, start, io);
0d959524 105 isa_init_ioport(dev, start);
78e20593
RH
106}
107
d7500734
AK
108void isa_register_portio_list(ISADevice *dev, uint16_t start,
109 const MemoryRegionPortio *pio_start,
110 void *opaque, const char *name)
111{
848696bf 112 PortioList piolist;
d7500734
AK
113
114 /* START is how we should treat DEV, regardless of the actual
115 contents of the portio array. This is how the old code
116 actually handled e.g. the FDC device. */
0d959524 117 isa_init_ioport(dev, start);
d7500734 118
848696bf
KB
119 /* FIXME: the device should store created PortioList in its state. Note
120 that DEV can be NULL here and that single device can register several
121 portio lists. Current implementation is leaking memory allocated
122 in portio_list_init. The leak is not critical because it happens only
123 at initialization time. */
124 portio_list_init(&piolist, OBJECT(dev), pio_start, opaque, name);
125 portio_list_add(&piolist, isabus->address_space_io, start);
d7500734
AK
126}
127
c538ca66
AF
128static void isa_device_init(Object *obj)
129{
130 ISADevice *dev = ISA_DEVICE(obj);
131
132 dev->isairq[0] = -1;
133 dev->isairq[1] = -1;
134}
135
48a18b3c 136ISADevice *isa_create(ISABus *bus, const char *name)
f915a115
GH
137{
138 DeviceState *dev;
f915a115 139
75782268 140 if (!bus) {
74782223 141 hw_error("Tried to create isa device %s with no isa bus present.",
3f66aa9c 142 name);
f915a115 143 }
2ae0e48d 144 dev = qdev_create(BUS(bus), name);
8f04ee08 145 return ISA_DEVICE(dev);
f915a115 146}
2091ba23 147
48a18b3c 148ISADevice *isa_try_create(ISABus *bus, const char *name)
86f4a9a5
BS
149{
150 DeviceState *dev;
151
75782268 152 if (!bus) {
86f4a9a5
BS
153 hw_error("Tried to create isa device %s with no isa bus present.",
154 name);
155 }
2ae0e48d 156 dev = qdev_try_create(BUS(bus), name);
8f04ee08 157 return ISA_DEVICE(dev);
86f4a9a5
BS
158}
159
48a18b3c 160ISADevice *isa_create_simple(ISABus *bus, const char *name)
924f6d72
GH
161{
162 ISADevice *dev;
163
48a18b3c 164 dev = isa_create(bus, name);
4a17cc4f 165 qdev_init_nofail(DEVICE(dev));
924f6d72
GH
166 return dev;
167}
168
14e7a645
AJ
169ISADevice *isa_vga_init(ISABus *bus)
170{
171 switch (vga_interface_type) {
172 case VGA_CIRRUS:
173 return isa_create_simple(bus, "isa-cirrus-vga");
174 case VGA_QXL:
175 fprintf(stderr, "%s: qxl: no PCI bus\n", __func__);
176 return NULL;
177 case VGA_STD:
178 return isa_create_simple(bus, "isa-vga");
179 case VGA_VMWARE:
180 fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __func__);
181 return NULL;
182 case VGA_NONE:
183 default:
184 return NULL;
185 }
186}
187
2091ba23
GH
188static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
189{
8f04ee08 190 ISADevice *d = ISA_DEVICE(dev);
2091ba23
GH
191
192 if (d->isairq[1] != -1) {
193 monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
194 d->isairq[0], d->isairq[1]);
195 } else if (d->isairq[0] != -1) {
196 monitor_printf(mon, "%*sisa irq %d\n", indent, "",
197 d->isairq[0]);
198 }
199}
200
999e12bb
AL
201static void isabus_bridge_class_init(ObjectClass *klass, void *data)
202{
39bffca2 203 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 204
39bffca2 205 dc->fw_name = "isa";
999e12bb
AL
206}
207
8c43a6f0 208static const TypeInfo isabus_bridge_info = {
39bffca2
AL
209 .name = "isabus-bridge",
210 .parent = TYPE_SYS_BUS_DEVICE,
211 .instance_size = sizeof(SysBusDevice),
212 .class_init = isabus_bridge_class_init,
2091ba23
GH
213};
214
39bffca2
AL
215static void isa_device_class_init(ObjectClass *klass, void *data)
216{
217 DeviceClass *k = DEVICE_CLASS(klass);
0d936928 218 k->bus_type = TYPE_ISA_BUS;
39bffca2
AL
219}
220
8c43a6f0 221static const TypeInfo isa_device_type_info = {
8f04ee08
AL
222 .name = TYPE_ISA_DEVICE,
223 .parent = TYPE_DEVICE,
224 .instance_size = sizeof(ISADevice),
c538ca66 225 .instance_init = isa_device_init,
8f04ee08
AL
226 .abstract = true,
227 .class_size = sizeof(ISADeviceClass),
39bffca2 228 .class_init = isa_device_class_init,
8f04ee08
AL
229};
230
83f7d43a 231static void isabus_register_types(void)
2091ba23 232{
0d936928 233 type_register_static(&isa_bus_info);
39bffca2 234 type_register_static(&isabus_bridge_info);
8f04ee08 235 type_register_static(&isa_device_type_info);
2091ba23
GH
236}
237
6a26e119
GN
238static char *isabus_get_fw_dev_path(DeviceState *dev)
239{
4a17cc4f 240 ISADevice *d = ISA_DEVICE(dev);
6a26e119
GN
241 char path[40];
242 int off;
243
244 off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));
ebf47c24
RH
245 if (d->ioport_id) {
246 snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);
6a26e119
GN
247 }
248
a5cf8262 249 return g_strdup(path);
6a26e119
GN
250}
251
c839adec
AK
252MemoryRegion *isa_address_space(ISADevice *dev)
253{
bb2ed009
HP
254 if (dev) {
255 return isa_bus_from_device(dev)->address_space;
256 }
257
258 return isabus->address_space;
c839adec
AK
259}
260
ac100273
JG
261MemoryRegion *isa_address_space_io(ISADevice *dev)
262{
263 if (dev) {
264 return isa_bus_from_device(dev)->address_space_io;
265 }
266
267 return isabus->address_space_io;
268}
269
83f7d43a 270type_init(isabus_register_types)
9157eee1
MR
271
272static void parallel_init(ISABus *bus, int index, CharDriverState *chr)
273{
274 DeviceState *dev;
275 ISADevice *isadev;
276
277 isadev = isa_create(bus, "isa-parallel");
278 dev = DEVICE(isadev);
279 qdev_prop_set_uint32(dev, "index", index);
280 qdev_prop_set_chr(dev, "chardev", chr);
281 qdev_init_nofail(dev);
282}
283
284void parallel_hds_isa_init(ISABus *bus, int n)
285{
286 int i;
287
288 assert(n <= MAX_PARALLEL_PORTS);
289
290 for (i = 0; i < n; i++) {
291 if (parallel_hds[i]) {
292 parallel_init(bus, i, parallel_hds[i]);
293 }
294 }
295}