Statistics
| Branch: | Revision:

root / hw / isa-bus.c @ be40edcd

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