Statistics
| Branch: | Revision:

root / hw / isa-bus.c @ a1bc20df

History | View | Annotate | Download (6.9 kB)

1 f915a115 Gerd Hoffmann
/*
2 f915a115 Gerd Hoffmann
 * isa bus support for qdev.
3 f915a115 Gerd Hoffmann
 *
4 f915a115 Gerd Hoffmann
 * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com>
5 f915a115 Gerd Hoffmann
 *
6 f915a115 Gerd Hoffmann
 * This library is free software; you can redistribute it and/or
7 f915a115 Gerd Hoffmann
 * modify it under the terms of the GNU Lesser General Public
8 f915a115 Gerd Hoffmann
 * License as published by the Free Software Foundation; either
9 f915a115 Gerd Hoffmann
 * version 2 of the License, or (at your option) any later version.
10 f915a115 Gerd Hoffmann
 *
11 f915a115 Gerd Hoffmann
 * This library is distributed in the hope that it will be useful,
12 f915a115 Gerd Hoffmann
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 f915a115 Gerd Hoffmann
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 f915a115 Gerd Hoffmann
 * Lesser General Public License for more details.
15 f915a115 Gerd Hoffmann
 *
16 f915a115 Gerd Hoffmann
 * You should have received a copy of the GNU Lesser General Public
17 f915a115 Gerd Hoffmann
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 f915a115 Gerd Hoffmann
 */
19 f915a115 Gerd Hoffmann
#include "hw.h"
20 2091ba23 Gerd Hoffmann
#include "monitor.h"
21 2091ba23 Gerd Hoffmann
#include "sysbus.h"
22 14e7a645 Aurelien Jarno
#include "sysemu.h"
23 f915a115 Gerd Hoffmann
#include "isa.h"
24 c839adec Avi Kivity
#include "exec-memory.h"
25 f915a115 Gerd Hoffmann
26 f915a115 Gerd Hoffmann
static ISABus *isabus;
27 a8170e5e Avi Kivity
hwaddr isa_mem_base = 0;
28 f915a115 Gerd Hoffmann
29 2091ba23 Gerd Hoffmann
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
30 6a26e119 Gleb Natapov
static char *isabus_get_fw_dev_path(DeviceState *dev);
31 2091ba23 Gerd Hoffmann
32 0d936928 Anthony Liguori
static void isa_bus_class_init(ObjectClass *klass, void *data)
33 0d936928 Anthony Liguori
{
34 0d936928 Anthony Liguori
    BusClass *k = BUS_CLASS(klass);
35 0d936928 Anthony Liguori
36 0d936928 Anthony Liguori
    k->print_dev = isabus_dev_print;
37 0d936928 Anthony Liguori
    k->get_fw_dev_path = isabus_get_fw_dev_path;
38 0d936928 Anthony Liguori
}
39 0d936928 Anthony Liguori
40 0d936928 Anthony Liguori
static const TypeInfo isa_bus_info = {
41 0d936928 Anthony Liguori
    .name = TYPE_ISA_BUS,
42 0d936928 Anthony Liguori
    .parent = TYPE_BUS,
43 0d936928 Anthony Liguori
    .instance_size = sizeof(ISABus),
44 0d936928 Anthony Liguori
    .class_init = isa_bus_class_init,
45 f915a115 Gerd Hoffmann
};
46 f915a115 Gerd Hoffmann
47 c2d0d012 Richard Henderson
ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io)
48 f915a115 Gerd Hoffmann
{
49 f915a115 Gerd Hoffmann
    if (isabus) {
50 f915a115 Gerd Hoffmann
        fprintf(stderr, "Can't create a second ISA bus\n");
51 f915a115 Gerd Hoffmann
        return NULL;
52 f915a115 Gerd Hoffmann
    }
53 2091ba23 Gerd Hoffmann
    if (NULL == dev) {
54 2091ba23 Gerd Hoffmann
        dev = qdev_create(NULL, "isabus-bridge");
55 e23a1b33 Markus Armbruster
        qdev_init_nofail(dev);
56 2091ba23 Gerd Hoffmann
    }
57 f915a115 Gerd Hoffmann
58 0d936928 Anthony Liguori
    isabus = FROM_QBUS(ISABus, qbus_create(TYPE_ISA_BUS, dev, NULL));
59 c2d0d012 Richard Henderson
    isabus->address_space_io = address_space_io;
60 f915a115 Gerd Hoffmann
    return isabus;
61 f915a115 Gerd Hoffmann
}
62 f915a115 Gerd Hoffmann
63 48a18b3c Hervé Poussineau
void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
64 f915a115 Gerd Hoffmann
{
65 d3c68e4f Hervé Poussineau
    if (!bus) {
66 d3c68e4f Hervé Poussineau
        hw_error("Can't set isa irqs with no isa bus present.");
67 d3c68e4f Hervé Poussineau
    }
68 d3c68e4f Hervé Poussineau
    bus->irqs = irqs;
69 2091ba23 Gerd Hoffmann
}
70 2091ba23 Gerd Hoffmann
71 3a38d437 Jes Sorensen
/*
72 ee951a37 Jan Kiszka
 * isa_get_irq() returns the corresponding qemu_irq entry for the i8259.
73 3a38d437 Jes Sorensen
 *
74 3a38d437 Jes Sorensen
 * This function is only for special cases such as the 'ferr', and
75 3a38d437 Jes Sorensen
 * temporary use for normal devices until they are converted to qdev.
76 3a38d437 Jes Sorensen
 */
77 48a18b3c Hervé Poussineau
qemu_irq isa_get_irq(ISADevice *dev, int isairq)
78 3a38d437 Jes Sorensen
{
79 48a18b3c Hervé Poussineau
    assert(!dev || DO_UPCAST(ISABus, qbus, dev->qdev.parent_bus) == isabus);
80 3a38d437 Jes Sorensen
    if (isairq < 0 || isairq > 15) {
81 74782223 Tristan Gingold
        hw_error("isa irq %d invalid", isairq);
82 3a38d437 Jes Sorensen
    }
83 3a38d437 Jes Sorensen
    return isabus->irqs[isairq];
84 3a38d437 Jes Sorensen
}
85 3a38d437 Jes Sorensen
86 2e15e23b Gerd Hoffmann
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
87 f915a115 Gerd Hoffmann
{
88 2e15e23b Gerd Hoffmann
    assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
89 2e15e23b Gerd Hoffmann
    dev->isairq[dev->nirqs] = isairq;
90 48a18b3c Hervé Poussineau
    *p = isa_get_irq(dev, isairq);
91 f915a115 Gerd Hoffmann
    dev->nirqs++;
92 f915a115 Gerd Hoffmann
}
93 f915a115 Gerd Hoffmann
94 0d959524 Richard Henderson
static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
95 dee41d58 Gleb Natapov
{
96 0d959524 Richard Henderson
    if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) {
97 0d959524 Richard Henderson
        dev->ioport_id = ioport;
98 dee41d58 Gleb Natapov
    }
99 dee41d58 Gleb Natapov
}
100 dee41d58 Gleb Natapov
101 78e20593 Richard Henderson
void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
102 78e20593 Richard Henderson
{
103 78e20593 Richard Henderson
    memory_region_add_subregion(isabus->address_space_io, start, io);
104 0d959524 Richard Henderson
    isa_init_ioport(dev, start);
105 78e20593 Richard Henderson
}
106 78e20593 Richard Henderson
107 d7500734 Avi Kivity
void isa_register_portio_list(ISADevice *dev, uint16_t start,
108 d7500734 Avi Kivity
                              const MemoryRegionPortio *pio_start,
109 d7500734 Avi Kivity
                              void *opaque, const char *name)
110 d7500734 Avi Kivity
{
111 d7500734 Avi Kivity
    PortioList *piolist = g_new(PortioList, 1);
112 d7500734 Avi Kivity
113 d7500734 Avi Kivity
    /* START is how we should treat DEV, regardless of the actual
114 d7500734 Avi Kivity
       contents of the portio array.  This is how the old code
115 d7500734 Avi Kivity
       actually handled e.g. the FDC device.  */
116 0d959524 Richard Henderson
    isa_init_ioport(dev, start);
117 d7500734 Avi Kivity
118 d7500734 Avi Kivity
    portio_list_init(piolist, pio_start, opaque, name);
119 d7500734 Avi Kivity
    portio_list_add(piolist, isabus->address_space_io, start);
120 d7500734 Avi Kivity
}
121 d7500734 Avi Kivity
122 d307af79 Anthony Liguori
static int isa_qdev_init(DeviceState *qdev)
123 f915a115 Gerd Hoffmann
{
124 8f04ee08 Anthony Liguori
    ISADevice *dev = ISA_DEVICE(qdev);
125 8f04ee08 Anthony Liguori
    ISADeviceClass *klass = ISA_DEVICE_GET_CLASS(dev);
126 f915a115 Gerd Hoffmann
127 2091ba23 Gerd Hoffmann
    dev->isairq[0] = -1;
128 2091ba23 Gerd Hoffmann
    dev->isairq[1] = -1;
129 81a322d4 Gerd Hoffmann
130 8f04ee08 Anthony Liguori
    if (klass->init) {
131 8f04ee08 Anthony Liguori
        return klass->init(dev);
132 8f04ee08 Anthony Liguori
    }
133 8f04ee08 Anthony Liguori
134 8f04ee08 Anthony Liguori
    return 0;
135 8f04ee08 Anthony Liguori
}
136 8f04ee08 Anthony Liguori
137 48a18b3c Hervé Poussineau
ISADevice *isa_create(ISABus *bus, const char *name)
138 f915a115 Gerd Hoffmann
{
139 f915a115 Gerd Hoffmann
    DeviceState *dev;
140 f915a115 Gerd Hoffmann
141 75782268 Hervé Poussineau
    if (!bus) {
142 74782223 Tristan Gingold
        hw_error("Tried to create isa device %s with no isa bus present.",
143 3f66aa9c Markus Armbruster
                 name);
144 f915a115 Gerd Hoffmann
    }
145 75782268 Hervé Poussineau
    dev = qdev_create(&bus->qbus, name);
146 8f04ee08 Anthony Liguori
    return ISA_DEVICE(dev);
147 f915a115 Gerd Hoffmann
}
148 2091ba23 Gerd Hoffmann
149 48a18b3c Hervé Poussineau
ISADevice *isa_try_create(ISABus *bus, const char *name)
150 86f4a9a5 Blue Swirl
{
151 86f4a9a5 Blue Swirl
    DeviceState *dev;
152 86f4a9a5 Blue Swirl
153 75782268 Hervé Poussineau
    if (!bus) {
154 86f4a9a5 Blue Swirl
        hw_error("Tried to create isa device %s with no isa bus present.",
155 86f4a9a5 Blue Swirl
                 name);
156 86f4a9a5 Blue Swirl
    }
157 75782268 Hervé Poussineau
    dev = qdev_try_create(&bus->qbus, name);
158 8f04ee08 Anthony Liguori
    return ISA_DEVICE(dev);
159 86f4a9a5 Blue Swirl
}
160 86f4a9a5 Blue Swirl
161 48a18b3c Hervé Poussineau
ISADevice *isa_create_simple(ISABus *bus, const char *name)
162 924f6d72 Gerd Hoffmann
{
163 924f6d72 Gerd Hoffmann
    ISADevice *dev;
164 924f6d72 Gerd Hoffmann
165 48a18b3c Hervé Poussineau
    dev = isa_create(bus, name);
166 3f66aa9c Markus Armbruster
    qdev_init_nofail(&dev->qdev);
167 924f6d72 Gerd Hoffmann
    return dev;
168 924f6d72 Gerd Hoffmann
}
169 924f6d72 Gerd Hoffmann
170 14e7a645 Aurelien Jarno
ISADevice *isa_vga_init(ISABus *bus)
171 14e7a645 Aurelien Jarno
{
172 14e7a645 Aurelien Jarno
    switch (vga_interface_type) {
173 14e7a645 Aurelien Jarno
    case VGA_CIRRUS:
174 14e7a645 Aurelien Jarno
        return isa_create_simple(bus, "isa-cirrus-vga");
175 14e7a645 Aurelien Jarno
    case VGA_QXL:
176 14e7a645 Aurelien Jarno
        fprintf(stderr, "%s: qxl: no PCI bus\n", __func__);
177 14e7a645 Aurelien Jarno
        return NULL;
178 14e7a645 Aurelien Jarno
    case VGA_STD:
179 14e7a645 Aurelien Jarno
        return isa_create_simple(bus, "isa-vga");
180 14e7a645 Aurelien Jarno
    case VGA_VMWARE:
181 14e7a645 Aurelien Jarno
        fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __func__);
182 14e7a645 Aurelien Jarno
        return NULL;
183 14e7a645 Aurelien Jarno
    case VGA_NONE:
184 14e7a645 Aurelien Jarno
    default:
185 14e7a645 Aurelien Jarno
        return NULL;
186 14e7a645 Aurelien Jarno
    }
187 14e7a645 Aurelien Jarno
}
188 14e7a645 Aurelien Jarno
189 2091ba23 Gerd Hoffmann
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
190 2091ba23 Gerd Hoffmann
{
191 8f04ee08 Anthony Liguori
    ISADevice *d = ISA_DEVICE(dev);
192 2091ba23 Gerd Hoffmann
193 2091ba23 Gerd Hoffmann
    if (d->isairq[1] != -1) {
194 2091ba23 Gerd Hoffmann
        monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
195 2091ba23 Gerd Hoffmann
                       d->isairq[0], d->isairq[1]);
196 2091ba23 Gerd Hoffmann
    } else if (d->isairq[0] != -1) {
197 2091ba23 Gerd Hoffmann
        monitor_printf(mon, "%*sisa irq %d\n", indent, "",
198 2091ba23 Gerd Hoffmann
                       d->isairq[0]);
199 2091ba23 Gerd Hoffmann
    }
200 2091ba23 Gerd Hoffmann
}
201 2091ba23 Gerd Hoffmann
202 81a322d4 Gerd Hoffmann
static int isabus_bridge_init(SysBusDevice *dev)
203 2091ba23 Gerd Hoffmann
{
204 2091ba23 Gerd Hoffmann
    /* nothing */
205 81a322d4 Gerd Hoffmann
    return 0;
206 2091ba23 Gerd Hoffmann
}
207 2091ba23 Gerd Hoffmann
208 999e12bb Anthony Liguori
static void isabus_bridge_class_init(ObjectClass *klass, void *data)
209 999e12bb Anthony Liguori
{
210 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
211 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
212 999e12bb Anthony Liguori
213 999e12bb Anthony Liguori
    k->init = isabus_bridge_init;
214 39bffca2 Anthony Liguori
    dc->fw_name = "isa";
215 39bffca2 Anthony Liguori
    dc->no_user = 1;
216 999e12bb Anthony Liguori
}
217 999e12bb Anthony Liguori
218 39bffca2 Anthony Liguori
static TypeInfo isabus_bridge_info = {
219 39bffca2 Anthony Liguori
    .name          = "isabus-bridge",
220 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
221 39bffca2 Anthony Liguori
    .instance_size = sizeof(SysBusDevice),
222 39bffca2 Anthony Liguori
    .class_init    = isabus_bridge_class_init,
223 2091ba23 Gerd Hoffmann
};
224 2091ba23 Gerd Hoffmann
225 39bffca2 Anthony Liguori
static void isa_device_class_init(ObjectClass *klass, void *data)
226 39bffca2 Anthony Liguori
{
227 39bffca2 Anthony Liguori
    DeviceClass *k = DEVICE_CLASS(klass);
228 39bffca2 Anthony Liguori
    k->init = isa_qdev_init;
229 0d936928 Anthony Liguori
    k->bus_type = TYPE_ISA_BUS;
230 39bffca2 Anthony Liguori
}
231 39bffca2 Anthony Liguori
232 8f04ee08 Anthony Liguori
static TypeInfo isa_device_type_info = {
233 8f04ee08 Anthony Liguori
    .name = TYPE_ISA_DEVICE,
234 8f04ee08 Anthony Liguori
    .parent = TYPE_DEVICE,
235 8f04ee08 Anthony Liguori
    .instance_size = sizeof(ISADevice),
236 8f04ee08 Anthony Liguori
    .abstract = true,
237 8f04ee08 Anthony Liguori
    .class_size = sizeof(ISADeviceClass),
238 39bffca2 Anthony Liguori
    .class_init = isa_device_class_init,
239 8f04ee08 Anthony Liguori
};
240 8f04ee08 Anthony Liguori
241 83f7d43a Andreas Färber
static void isabus_register_types(void)
242 2091ba23 Gerd Hoffmann
{
243 0d936928 Anthony Liguori
    type_register_static(&isa_bus_info);
244 39bffca2 Anthony Liguori
    type_register_static(&isabus_bridge_info);
245 8f04ee08 Anthony Liguori
    type_register_static(&isa_device_type_info);
246 2091ba23 Gerd Hoffmann
}
247 2091ba23 Gerd Hoffmann
248 6a26e119 Gleb Natapov
static char *isabus_get_fw_dev_path(DeviceState *dev)
249 6a26e119 Gleb Natapov
{
250 6a26e119 Gleb Natapov
    ISADevice *d = (ISADevice*)dev;
251 6a26e119 Gleb Natapov
    char path[40];
252 6a26e119 Gleb Natapov
    int off;
253 6a26e119 Gleb Natapov
254 6a26e119 Gleb Natapov
    off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));
255 ebf47c24 Richard Henderson
    if (d->ioport_id) {
256 ebf47c24 Richard Henderson
        snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);
257 6a26e119 Gleb Natapov
    }
258 6a26e119 Gleb Natapov
259 a5cf8262 Jim Meyering
    return g_strdup(path);
260 6a26e119 Gleb Natapov
}
261 6a26e119 Gleb Natapov
262 c839adec Avi Kivity
MemoryRegion *isa_address_space(ISADevice *dev)
263 c839adec Avi Kivity
{
264 c839adec Avi Kivity
    return get_system_memory();
265 c839adec Avi Kivity
}
266 c839adec Avi Kivity
267 83f7d43a Andreas Färber
type_init(isabus_register_types)