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