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