Statistics
| Branch: | Revision:

root / hw / isa-bus.c @ 0dad6c35

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