Statistics
| Branch: | Revision:

root / hw / isa-bus.c @ 9a3a8895

History | View | Annotate | Download (6.5 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 f915a115 Gerd Hoffmann
#include "isa.h"
23 c839adec Avi Kivity
#include "exec-memory.h"
24 f915a115 Gerd Hoffmann
25 f915a115 Gerd Hoffmann
static ISABus *isabus;
26 fbe3288d Paolo Bonzini
target_phys_addr_t isa_mem_base = 0;
27 f915a115 Gerd Hoffmann
28 2091ba23 Gerd Hoffmann
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
29 6a26e119 Gleb Natapov
static char *isabus_get_fw_dev_path(DeviceState *dev);
30 2091ba23 Gerd Hoffmann
31 0d936928 Anthony Liguori
static void isa_bus_class_init(ObjectClass *klass, void *data)
32 0d936928 Anthony Liguori
{
33 0d936928 Anthony Liguori
    BusClass *k = BUS_CLASS(klass);
34 0d936928 Anthony Liguori
35 0d936928 Anthony Liguori
    k->print_dev = isabus_dev_print;
36 0d936928 Anthony Liguori
    k->get_fw_dev_path = isabus_get_fw_dev_path;
37 0d936928 Anthony Liguori
}
38 0d936928 Anthony Liguori
39 0d936928 Anthony Liguori
static const TypeInfo isa_bus_info = {
40 0d936928 Anthony Liguori
    .name = TYPE_ISA_BUS,
41 0d936928 Anthony Liguori
    .parent = TYPE_BUS,
42 0d936928 Anthony Liguori
    .instance_size = sizeof(ISABus),
43 0d936928 Anthony Liguori
    .class_init = isa_bus_class_init,
44 f915a115 Gerd Hoffmann
};
45 f915a115 Gerd Hoffmann
46 c2d0d012 Richard Henderson
ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io)
47 f915a115 Gerd Hoffmann
{
48 f915a115 Gerd Hoffmann
    if (isabus) {
49 f915a115 Gerd Hoffmann
        fprintf(stderr, "Can't create a second ISA bus\n");
50 f915a115 Gerd Hoffmann
        return NULL;
51 f915a115 Gerd Hoffmann
    }
52 2091ba23 Gerd Hoffmann
    if (NULL == dev) {
53 2091ba23 Gerd Hoffmann
        dev = qdev_create(NULL, "isabus-bridge");
54 e23a1b33 Markus Armbruster
        qdev_init_nofail(dev);
55 2091ba23 Gerd Hoffmann
    }
56 f915a115 Gerd Hoffmann
57 0d936928 Anthony Liguori
    isabus = FROM_QBUS(ISABus, qbus_create(TYPE_ISA_BUS, dev, NULL));
58 c2d0d012 Richard Henderson
    isabus->address_space_io = address_space_io;
59 f915a115 Gerd Hoffmann
    return isabus;
60 f915a115 Gerd Hoffmann
}
61 f915a115 Gerd Hoffmann
62 48a18b3c Hervé Poussineau
void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
63 f915a115 Gerd Hoffmann
{
64 d3c68e4f Hervé Poussineau
    if (!bus) {
65 d3c68e4f Hervé Poussineau
        hw_error("Can't set isa irqs with no isa bus present.");
66 d3c68e4f Hervé Poussineau
    }
67 d3c68e4f Hervé Poussineau
    bus->irqs = irqs;
68 2091ba23 Gerd Hoffmann
}
69 2091ba23 Gerd Hoffmann
70 3a38d437 Jes Sorensen
/*
71 ee951a37 Jan Kiszka
 * isa_get_irq() returns the corresponding qemu_irq entry for the i8259.
72 3a38d437 Jes Sorensen
 *
73 3a38d437 Jes Sorensen
 * This function is only for special cases such as the 'ferr', and
74 3a38d437 Jes Sorensen
 * temporary use for normal devices until they are converted to qdev.
75 3a38d437 Jes Sorensen
 */
76 48a18b3c Hervé Poussineau
qemu_irq isa_get_irq(ISADevice *dev, int isairq)
77 3a38d437 Jes Sorensen
{
78 48a18b3c Hervé Poussineau
    assert(!dev || DO_UPCAST(ISABus, qbus, dev->qdev.parent_bus) == isabus);
79 3a38d437 Jes Sorensen
    if (isairq < 0 || isairq > 15) {
80 74782223 Tristan Gingold
        hw_error("isa irq %d invalid", isairq);
81 3a38d437 Jes Sorensen
    }
82 3a38d437 Jes Sorensen
    return isabus->irqs[isairq];
83 3a38d437 Jes Sorensen
}
84 3a38d437 Jes Sorensen
85 2e15e23b Gerd Hoffmann
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
86 f915a115 Gerd Hoffmann
{
87 2e15e23b Gerd Hoffmann
    assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
88 2e15e23b Gerd Hoffmann
    dev->isairq[dev->nirqs] = isairq;
89 48a18b3c Hervé Poussineau
    *p = isa_get_irq(dev, isairq);
90 f915a115 Gerd Hoffmann
    dev->nirqs++;
91 f915a115 Gerd Hoffmann
}
92 f915a115 Gerd Hoffmann
93 0d959524 Richard Henderson
static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
94 dee41d58 Gleb Natapov
{
95 0d959524 Richard Henderson
    if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) {
96 0d959524 Richard Henderson
        dev->ioport_id = ioport;
97 dee41d58 Gleb Natapov
    }
98 dee41d58 Gleb Natapov
}
99 dee41d58 Gleb Natapov
100 78e20593 Richard Henderson
void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
101 78e20593 Richard Henderson
{
102 78e20593 Richard Henderson
    memory_region_add_subregion(isabus->address_space_io, start, io);
103 0d959524 Richard Henderson
    isa_init_ioport(dev, start);
104 78e20593 Richard Henderson
}
105 78e20593 Richard Henderson
106 d7500734 Avi Kivity
void isa_register_portio_list(ISADevice *dev, uint16_t start,
107 d7500734 Avi Kivity
                              const MemoryRegionPortio *pio_start,
108 d7500734 Avi Kivity
                              void *opaque, const char *name)
109 d7500734 Avi Kivity
{
110 d7500734 Avi Kivity
    PortioList *piolist = g_new(PortioList, 1);
111 d7500734 Avi Kivity
112 d7500734 Avi Kivity
    /* START is how we should treat DEV, regardless of the actual
113 d7500734 Avi Kivity
       contents of the portio array.  This is how the old code
114 d7500734 Avi Kivity
       actually handled e.g. the FDC device.  */
115 0d959524 Richard Henderson
    isa_init_ioport(dev, start);
116 d7500734 Avi Kivity
117 d7500734 Avi Kivity
    portio_list_init(piolist, pio_start, opaque, name);
118 d7500734 Avi Kivity
    portio_list_add(piolist, isabus->address_space_io, start);
119 d7500734 Avi Kivity
}
120 d7500734 Avi Kivity
121 d307af79 Anthony Liguori
static int isa_qdev_init(DeviceState *qdev)
122 f915a115 Gerd Hoffmann
{
123 8f04ee08 Anthony Liguori
    ISADevice *dev = ISA_DEVICE(qdev);
124 8f04ee08 Anthony Liguori
    ISADeviceClass *klass = ISA_DEVICE_GET_CLASS(dev);
125 f915a115 Gerd Hoffmann
126 2091ba23 Gerd Hoffmann
    dev->isairq[0] = -1;
127 2091ba23 Gerd Hoffmann
    dev->isairq[1] = -1;
128 81a322d4 Gerd Hoffmann
129 8f04ee08 Anthony Liguori
    if (klass->init) {
130 8f04ee08 Anthony Liguori
        return klass->init(dev);
131 8f04ee08 Anthony Liguori
    }
132 8f04ee08 Anthony Liguori
133 8f04ee08 Anthony Liguori
    return 0;
134 8f04ee08 Anthony Liguori
}
135 8f04ee08 Anthony Liguori
136 48a18b3c Hervé Poussineau
ISADevice *isa_create(ISABus *bus, const char *name)
137 f915a115 Gerd Hoffmann
{
138 f915a115 Gerd Hoffmann
    DeviceState *dev;
139 f915a115 Gerd Hoffmann
140 75782268 Hervé Poussineau
    if (!bus) {
141 74782223 Tristan Gingold
        hw_error("Tried to create isa device %s with no isa bus present.",
142 3f66aa9c Markus Armbruster
                 name);
143 f915a115 Gerd Hoffmann
    }
144 75782268 Hervé Poussineau
    dev = qdev_create(&bus->qbus, name);
145 8f04ee08 Anthony Liguori
    return ISA_DEVICE(dev);
146 f915a115 Gerd Hoffmann
}
147 2091ba23 Gerd Hoffmann
148 48a18b3c Hervé Poussineau
ISADevice *isa_try_create(ISABus *bus, const char *name)
149 86f4a9a5 Blue Swirl
{
150 86f4a9a5 Blue Swirl
    DeviceState *dev;
151 86f4a9a5 Blue Swirl
152 75782268 Hervé Poussineau
    if (!bus) {
153 86f4a9a5 Blue Swirl
        hw_error("Tried to create isa device %s with no isa bus present.",
154 86f4a9a5 Blue Swirl
                 name);
155 86f4a9a5 Blue Swirl
    }
156 75782268 Hervé Poussineau
    dev = qdev_try_create(&bus->qbus, name);
157 8f04ee08 Anthony Liguori
    return ISA_DEVICE(dev);
158 86f4a9a5 Blue Swirl
}
159 86f4a9a5 Blue Swirl
160 48a18b3c Hervé Poussineau
ISADevice *isa_create_simple(ISABus *bus, const char *name)
161 924f6d72 Gerd Hoffmann
{
162 924f6d72 Gerd Hoffmann
    ISADevice *dev;
163 924f6d72 Gerd Hoffmann
164 48a18b3c Hervé Poussineau
    dev = isa_create(bus, name);
165 3f66aa9c Markus Armbruster
    qdev_init_nofail(&dev->qdev);
166 924f6d72 Gerd Hoffmann
    return dev;
167 924f6d72 Gerd Hoffmann
}
168 924f6d72 Gerd Hoffmann
169 2091ba23 Gerd Hoffmann
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
170 2091ba23 Gerd Hoffmann
{
171 8f04ee08 Anthony Liguori
    ISADevice *d = ISA_DEVICE(dev);
172 2091ba23 Gerd Hoffmann
173 2091ba23 Gerd Hoffmann
    if (d->isairq[1] != -1) {
174 2091ba23 Gerd Hoffmann
        monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
175 2091ba23 Gerd Hoffmann
                       d->isairq[0], d->isairq[1]);
176 2091ba23 Gerd Hoffmann
    } else if (d->isairq[0] != -1) {
177 2091ba23 Gerd Hoffmann
        monitor_printf(mon, "%*sisa irq %d\n", indent, "",
178 2091ba23 Gerd Hoffmann
                       d->isairq[0]);
179 2091ba23 Gerd Hoffmann
    }
180 2091ba23 Gerd Hoffmann
}
181 2091ba23 Gerd Hoffmann
182 81a322d4 Gerd Hoffmann
static int isabus_bridge_init(SysBusDevice *dev)
183 2091ba23 Gerd Hoffmann
{
184 2091ba23 Gerd Hoffmann
    /* nothing */
185 81a322d4 Gerd Hoffmann
    return 0;
186 2091ba23 Gerd Hoffmann
}
187 2091ba23 Gerd Hoffmann
188 999e12bb Anthony Liguori
static void isabus_bridge_class_init(ObjectClass *klass, void *data)
189 999e12bb Anthony Liguori
{
190 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
191 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
192 999e12bb Anthony Liguori
193 999e12bb Anthony Liguori
    k->init = isabus_bridge_init;
194 39bffca2 Anthony Liguori
    dc->fw_name = "isa";
195 39bffca2 Anthony Liguori
    dc->no_user = 1;
196 999e12bb Anthony Liguori
}
197 999e12bb Anthony Liguori
198 39bffca2 Anthony Liguori
static TypeInfo isabus_bridge_info = {
199 39bffca2 Anthony Liguori
    .name          = "isabus-bridge",
200 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
201 39bffca2 Anthony Liguori
    .instance_size = sizeof(SysBusDevice),
202 39bffca2 Anthony Liguori
    .class_init    = isabus_bridge_class_init,
203 2091ba23 Gerd Hoffmann
};
204 2091ba23 Gerd Hoffmann
205 39bffca2 Anthony Liguori
static void isa_device_class_init(ObjectClass *klass, void *data)
206 39bffca2 Anthony Liguori
{
207 39bffca2 Anthony Liguori
    DeviceClass *k = DEVICE_CLASS(klass);
208 39bffca2 Anthony Liguori
    k->init = isa_qdev_init;
209 0d936928 Anthony Liguori
    k->bus_type = TYPE_ISA_BUS;
210 39bffca2 Anthony Liguori
}
211 39bffca2 Anthony Liguori
212 8f04ee08 Anthony Liguori
static TypeInfo isa_device_type_info = {
213 8f04ee08 Anthony Liguori
    .name = TYPE_ISA_DEVICE,
214 8f04ee08 Anthony Liguori
    .parent = TYPE_DEVICE,
215 8f04ee08 Anthony Liguori
    .instance_size = sizeof(ISADevice),
216 8f04ee08 Anthony Liguori
    .abstract = true,
217 8f04ee08 Anthony Liguori
    .class_size = sizeof(ISADeviceClass),
218 39bffca2 Anthony Liguori
    .class_init = isa_device_class_init,
219 8f04ee08 Anthony Liguori
};
220 8f04ee08 Anthony Liguori
221 83f7d43a Andreas Färber
static void isabus_register_types(void)
222 2091ba23 Gerd Hoffmann
{
223 0d936928 Anthony Liguori
    type_register_static(&isa_bus_info);
224 39bffca2 Anthony Liguori
    type_register_static(&isabus_bridge_info);
225 8f04ee08 Anthony Liguori
    type_register_static(&isa_device_type_info);
226 2091ba23 Gerd Hoffmann
}
227 2091ba23 Gerd Hoffmann
228 6a26e119 Gleb Natapov
static char *isabus_get_fw_dev_path(DeviceState *dev)
229 6a26e119 Gleb Natapov
{
230 6a26e119 Gleb Natapov
    ISADevice *d = (ISADevice*)dev;
231 6a26e119 Gleb Natapov
    char path[40];
232 6a26e119 Gleb Natapov
    int off;
233 6a26e119 Gleb Natapov
234 6a26e119 Gleb Natapov
    off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));
235 ebf47c24 Richard Henderson
    if (d->ioport_id) {
236 ebf47c24 Richard Henderson
        snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);
237 6a26e119 Gleb Natapov
    }
238 6a26e119 Gleb Natapov
239 6a26e119 Gleb Natapov
    return strdup(path);
240 6a26e119 Gleb Natapov
}
241 6a26e119 Gleb Natapov
242 c839adec Avi Kivity
MemoryRegion *isa_address_space(ISADevice *dev)
243 c839adec Avi Kivity
{
244 c839adec Avi Kivity
    return get_system_memory();
245 c839adec Avi Kivity
}
246 c839adec Avi Kivity
247 83f7d43a Andreas Färber
type_init(isabus_register_types)