Statistics
| Branch: | Revision:

root / hw / isa-bus.c @ 2afee49f

History | View | Annotate | Download (5.7 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 81a322d4 Gerd Hoffmann
static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
114 f915a115 Gerd Hoffmann
{
115 f915a115 Gerd Hoffmann
    ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
116 f915a115 Gerd Hoffmann
    ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base);
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 81a322d4 Gerd Hoffmann
    return info->init(dev);
122 f915a115 Gerd Hoffmann
}
123 f915a115 Gerd Hoffmann
124 f915a115 Gerd Hoffmann
void isa_qdev_register(ISADeviceInfo *info)
125 f915a115 Gerd Hoffmann
{
126 f915a115 Gerd Hoffmann
    info->qdev.init = isa_qdev_init;
127 f915a115 Gerd Hoffmann
    info->qdev.bus_info = &isa_bus_info;
128 f915a115 Gerd Hoffmann
    qdev_register(&info->qdev);
129 f915a115 Gerd Hoffmann
}
130 f915a115 Gerd Hoffmann
131 48a18b3c Hervé Poussineau
ISADevice *isa_create(ISABus *bus, const char *name)
132 f915a115 Gerd Hoffmann
{
133 f915a115 Gerd Hoffmann
    DeviceState *dev;
134 f915a115 Gerd Hoffmann
135 75782268 Hervé Poussineau
    if (!bus) {
136 74782223 Tristan Gingold
        hw_error("Tried to create isa device %s with no isa bus present.",
137 3f66aa9c Markus Armbruster
                 name);
138 f915a115 Gerd Hoffmann
    }
139 75782268 Hervé Poussineau
    dev = qdev_create(&bus->qbus, name);
140 2e15e23b Gerd Hoffmann
    return DO_UPCAST(ISADevice, qdev, dev);
141 f915a115 Gerd Hoffmann
}
142 2091ba23 Gerd Hoffmann
143 48a18b3c Hervé Poussineau
ISADevice *isa_try_create(ISABus *bus, const char *name)
144 86f4a9a5 Blue Swirl
{
145 86f4a9a5 Blue Swirl
    DeviceState *dev;
146 86f4a9a5 Blue Swirl
147 75782268 Hervé Poussineau
    if (!bus) {
148 86f4a9a5 Blue Swirl
        hw_error("Tried to create isa device %s with no isa bus present.",
149 86f4a9a5 Blue Swirl
                 name);
150 86f4a9a5 Blue Swirl
    }
151 75782268 Hervé Poussineau
    dev = qdev_try_create(&bus->qbus, name);
152 86f4a9a5 Blue Swirl
    return DO_UPCAST(ISADevice, qdev, dev);
153 86f4a9a5 Blue Swirl
}
154 86f4a9a5 Blue Swirl
155 48a18b3c Hervé Poussineau
ISADevice *isa_create_simple(ISABus *bus, const char *name)
156 924f6d72 Gerd Hoffmann
{
157 924f6d72 Gerd Hoffmann
    ISADevice *dev;
158 924f6d72 Gerd Hoffmann
159 48a18b3c Hervé Poussineau
    dev = isa_create(bus, name);
160 3f66aa9c Markus Armbruster
    qdev_init_nofail(&dev->qdev);
161 924f6d72 Gerd Hoffmann
    return dev;
162 924f6d72 Gerd Hoffmann
}
163 924f6d72 Gerd Hoffmann
164 2091ba23 Gerd Hoffmann
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
165 2091ba23 Gerd Hoffmann
{
166 2091ba23 Gerd Hoffmann
    ISADevice *d = DO_UPCAST(ISADevice, qdev, dev);
167 2091ba23 Gerd Hoffmann
168 2091ba23 Gerd Hoffmann
    if (d->isairq[1] != -1) {
169 2091ba23 Gerd Hoffmann
        monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
170 2091ba23 Gerd Hoffmann
                       d->isairq[0], d->isairq[1]);
171 2091ba23 Gerd Hoffmann
    } else if (d->isairq[0] != -1) {
172 2091ba23 Gerd Hoffmann
        monitor_printf(mon, "%*sisa irq %d\n", indent, "",
173 2091ba23 Gerd Hoffmann
                       d->isairq[0]);
174 2091ba23 Gerd Hoffmann
    }
175 2091ba23 Gerd Hoffmann
}
176 2091ba23 Gerd Hoffmann
177 81a322d4 Gerd Hoffmann
static int isabus_bridge_init(SysBusDevice *dev)
178 2091ba23 Gerd Hoffmann
{
179 2091ba23 Gerd Hoffmann
    /* nothing */
180 81a322d4 Gerd Hoffmann
    return 0;
181 2091ba23 Gerd Hoffmann
}
182 2091ba23 Gerd Hoffmann
183 2091ba23 Gerd Hoffmann
static SysBusDeviceInfo isabus_bridge_info = {
184 2091ba23 Gerd Hoffmann
    .init = isabus_bridge_init,
185 2091ba23 Gerd Hoffmann
    .qdev.name  = "isabus-bridge",
186 779206de Gleb Natapov
    .qdev.fw_name  = "isa",
187 2091ba23 Gerd Hoffmann
    .qdev.size  = sizeof(SysBusDevice),
188 787aa97a Gerd Hoffmann
    .qdev.no_user = 1,
189 2091ba23 Gerd Hoffmann
};
190 2091ba23 Gerd Hoffmann
191 2091ba23 Gerd Hoffmann
static void isabus_register_devices(void)
192 2091ba23 Gerd Hoffmann
{
193 2091ba23 Gerd Hoffmann
    sysbus_register_withprop(&isabus_bridge_info);
194 2091ba23 Gerd Hoffmann
}
195 2091ba23 Gerd Hoffmann
196 6a26e119 Gleb Natapov
static char *isabus_get_fw_dev_path(DeviceState *dev)
197 6a26e119 Gleb Natapov
{
198 6a26e119 Gleb Natapov
    ISADevice *d = (ISADevice*)dev;
199 6a26e119 Gleb Natapov
    char path[40];
200 6a26e119 Gleb Natapov
    int off;
201 6a26e119 Gleb Natapov
202 6a26e119 Gleb Natapov
    off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));
203 ebf47c24 Richard Henderson
    if (d->ioport_id) {
204 ebf47c24 Richard Henderson
        snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);
205 6a26e119 Gleb Natapov
    }
206 6a26e119 Gleb Natapov
207 6a26e119 Gleb Natapov
    return strdup(path);
208 6a26e119 Gleb Natapov
}
209 6a26e119 Gleb Natapov
210 c839adec Avi Kivity
MemoryRegion *isa_address_space(ISADevice *dev)
211 c839adec Avi Kivity
{
212 c839adec Avi Kivity
    return get_system_memory();
213 c839adec Avi Kivity
}
214 c839adec Avi Kivity
215 2091ba23 Gerd Hoffmann
device_init(isabus_register_devices)