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