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