Statistics
| Branch: | Revision:

root / hw / s390-virtio-bus.c @ 5414dec6

History | View | Annotate | Download (14.4 kB)

1 f3304eea Alexander Graf
/*
2 f3304eea Alexander Graf
 * QEMU S390 virtio target
3 f3304eea Alexander Graf
 *
4 f3304eea Alexander Graf
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
5 f3304eea Alexander Graf
 *
6 f3304eea Alexander Graf
 * This library is free software; you can redistribute it and/or
7 f3304eea Alexander Graf
 * modify it under the terms of the GNU Lesser General Public
8 f3304eea Alexander Graf
 * License as published by the Free Software Foundation; either
9 f3304eea Alexander Graf
 * version 2 of the License, or (at your option) any later version.
10 f3304eea Alexander Graf
 *
11 f3304eea Alexander Graf
 * This library is distributed in the hope that it will be useful,
12 f3304eea Alexander Graf
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 f3304eea Alexander Graf
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 f3304eea Alexander Graf
 * Lesser General Public License for more details.
15 f3304eea Alexander Graf
 *
16 f3304eea Alexander Graf
 * You should have received a copy of the GNU Lesser General Public
17 f3304eea Alexander Graf
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 f3304eea Alexander Graf
 */
19 f3304eea Alexander Graf
20 f3304eea Alexander Graf
#include "hw.h"
21 f3304eea Alexander Graf
#include "block.h"
22 f3304eea Alexander Graf
#include "sysemu.h"
23 f3304eea Alexander Graf
#include "net.h"
24 f3304eea Alexander Graf
#include "boards.h"
25 f3304eea Alexander Graf
#include "monitor.h"
26 f3304eea Alexander Graf
#include "loader.h"
27 f3304eea Alexander Graf
#include "elf.h"
28 f3304eea Alexander Graf
#include "hw/virtio.h"
29 98b19252 Amit Shah
#include "hw/virtio-serial.h"
30 f0c07c7c Alex Williamson
#include "hw/virtio-net.h"
31 f3304eea Alexander Graf
#include "hw/sysbus.h"
32 f3304eea Alexander Graf
#include "kvm.h"
33 f3304eea Alexander Graf
34 f3304eea Alexander Graf
#include "hw/s390-virtio-bus.h"
35 f3304eea Alexander Graf
36 f3304eea Alexander Graf
/* #define DEBUG_S390 */
37 f3304eea Alexander Graf
38 f3304eea Alexander Graf
#ifdef DEBUG_S390
39 f3304eea Alexander Graf
#define dprintf(fmt, ...) \
40 f3304eea Alexander Graf
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
41 f3304eea Alexander Graf
#else
42 f3304eea Alexander Graf
#define dprintf(fmt, ...) \
43 f3304eea Alexander Graf
    do { } while (0)
44 f3304eea Alexander Graf
#endif
45 f3304eea Alexander Graf
46 8103b4d1 Alexander Graf
#define VIRTIO_EXT_CODE   0x2603
47 8103b4d1 Alexander Graf
48 f3304eea Alexander Graf
struct BusInfo s390_virtio_bus_info = {
49 f3304eea Alexander Graf
    .name       = "s390-virtio",
50 f3304eea Alexander Graf
    .size       = sizeof(VirtIOS390Bus),
51 f3304eea Alexander Graf
};
52 f3304eea Alexander Graf
53 f3304eea Alexander Graf
static const VirtIOBindings virtio_s390_bindings;
54 f3304eea Alexander Graf
55 f3304eea Alexander Graf
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
56 f3304eea Alexander Graf
57 d1ff903c Alexander Graf
/* length of VirtIO device pages */
58 d1ff903c Alexander Graf
const target_phys_addr_t virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
59 d1ff903c Alexander Graf
60 eb3caa44 Jens Freimann
static void s390_virtio_bus_reset(void *opaque)
61 eb3caa44 Jens Freimann
{
62 eb3caa44 Jens Freimann
    VirtIOS390Bus *bus = opaque;
63 eb3caa44 Jens Freimann
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
64 eb3caa44 Jens Freimann
}
65 eb3caa44 Jens Freimann
66 4170aea1 Jens Freimann
void s390_virtio_reset_idx(VirtIOS390Device *dev)
67 4170aea1 Jens Freimann
{
68 4170aea1 Jens Freimann
    int i;
69 4170aea1 Jens Freimann
    target_phys_addr_t idx_addr;
70 4170aea1 Jens Freimann
    uint8_t num_vq;
71 4170aea1 Jens Freimann
72 4170aea1 Jens Freimann
    num_vq = s390_virtio_device_num_vq(dev);
73 4170aea1 Jens Freimann
    for (i = 0; i < num_vq; i++) {
74 4170aea1 Jens Freimann
        idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) +
75 4170aea1 Jens Freimann
            VIRTIO_VRING_AVAIL_IDX_OFFS;
76 4170aea1 Jens Freimann
        stw_phys(idx_addr, 0);
77 4170aea1 Jens Freimann
        idx_addr = virtio_queue_get_used_addr(dev->vdev, i) +
78 4170aea1 Jens Freimann
            VIRTIO_VRING_USED_IDX_OFFS;
79 4170aea1 Jens Freimann
        stw_phys(idx_addr, 0);
80 4170aea1 Jens Freimann
    }
81 4170aea1 Jens Freimann
}
82 4170aea1 Jens Freimann
83 f3304eea Alexander Graf
VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
84 f3304eea Alexander Graf
{
85 f3304eea Alexander Graf
    VirtIOS390Bus *bus;
86 f3304eea Alexander Graf
    BusState *_bus;
87 f3304eea Alexander Graf
    DeviceState *dev;
88 f3304eea Alexander Graf
89 f3304eea Alexander Graf
    /* Create bridge device */
90 f3304eea Alexander Graf
    dev = qdev_create(NULL, "s390-virtio-bridge");
91 f3304eea Alexander Graf
    qdev_init_nofail(dev);
92 f3304eea Alexander Graf
93 f3304eea Alexander Graf
    /* Create bus on bridge device */
94 f3304eea Alexander Graf
95 f3304eea Alexander Graf
    _bus = qbus_create(&s390_virtio_bus_info, dev, "s390-virtio");
96 f3304eea Alexander Graf
    bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
97 f3304eea Alexander Graf
98 f3304eea Alexander Graf
    bus->dev_page = *ram_size;
99 f3304eea Alexander Graf
    bus->dev_offs = bus->dev_page;
100 f3304eea Alexander Graf
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
101 f3304eea Alexander Graf
102 7fa41e53 Alexander Graf
    /* Enable hotplugging */
103 7fa41e53 Alexander Graf
    _bus->allow_hotplug = 1;
104 7fa41e53 Alexander Graf
105 f3304eea Alexander Graf
    /* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
106 f3304eea Alexander Graf
    *ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
107 f3304eea Alexander Graf
108 eb3caa44 Jens Freimann
    qemu_register_reset(s390_virtio_bus_reset, bus);
109 f3304eea Alexander Graf
    return bus;
110 f3304eea Alexander Graf
}
111 f3304eea Alexander Graf
112 0e4213a7 Andreas Färber
static void s390_virtio_irq(CPUS390XState *env, int config_change, uint64_t token)
113 7fa41e53 Alexander Graf
{
114 7fa41e53 Alexander Graf
    if (kvm_enabled()) {
115 7fa41e53 Alexander Graf
        kvm_s390_virtio_irq(env, config_change, token);
116 7fa41e53 Alexander Graf
    } else {
117 7fa41e53 Alexander Graf
        cpu_inject_ext(env, VIRTIO_EXT_CODE, config_change, token);
118 7fa41e53 Alexander Graf
    }
119 7fa41e53 Alexander Graf
}
120 7fa41e53 Alexander Graf
121 f3304eea Alexander Graf
static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
122 f3304eea Alexander Graf
{
123 f3304eea Alexander Graf
    VirtIOS390Bus *bus;
124 f3304eea Alexander Graf
    int dev_len;
125 f3304eea Alexander Graf
126 f3304eea Alexander Graf
    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
127 f3304eea Alexander Graf
    dev->vdev = vdev;
128 f3304eea Alexander Graf
    dev->dev_offs = bus->dev_offs;
129 f3304eea Alexander Graf
    dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */
130 f3304eea Alexander Graf
131 f3304eea Alexander Graf
    dev_len = VIRTIO_DEV_OFFS_CONFIG;
132 f3304eea Alexander Graf
    dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
133 f3304eea Alexander Graf
    dev_len += dev->feat_len * 2;
134 f3304eea Alexander Graf
    dev_len += vdev->config_len;
135 f3304eea Alexander Graf
136 f3304eea Alexander Graf
    bus->dev_offs += dev_len;
137 f3304eea Alexander Graf
138 f3304eea Alexander Graf
    virtio_bind_device(vdev, &virtio_s390_bindings, dev);
139 8172539d Michael S. Tsirkin
    dev->host_features = vdev->get_features(vdev, dev->host_features);
140 f3304eea Alexander Graf
    s390_virtio_device_sync(dev);
141 4170aea1 Jens Freimann
    s390_virtio_reset_idx(dev);
142 7fa41e53 Alexander Graf
    if (dev->qdev.hotplugged) {
143 0e4213a7 Andreas Färber
        CPUS390XState *env = s390_cpu_addr2state(0);
144 7fa41e53 Alexander Graf
        s390_virtio_irq(env, VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
145 7fa41e53 Alexander Graf
    }
146 7fa41e53 Alexander Graf
147 f3304eea Alexander Graf
    return 0;
148 f3304eea Alexander Graf
}
149 f3304eea Alexander Graf
150 f3304eea Alexander Graf
static int s390_virtio_net_init(VirtIOS390Device *dev)
151 f3304eea Alexander Graf
{
152 f3304eea Alexander Graf
    VirtIODevice *vdev;
153 f3304eea Alexander Graf
154 f0c07c7c Alex Williamson
    vdev = virtio_net_init((DeviceState *)dev, &dev->nic, &dev->net);
155 f3304eea Alexander Graf
    if (!vdev) {
156 f3304eea Alexander Graf
        return -1;
157 f3304eea Alexander Graf
    }
158 f3304eea Alexander Graf
159 f3304eea Alexander Graf
    return s390_virtio_device_init(dev, vdev);
160 f3304eea Alexander Graf
}
161 f3304eea Alexander Graf
162 f3304eea Alexander Graf
static int s390_virtio_blk_init(VirtIOS390Device *dev)
163 f3304eea Alexander Graf
{
164 f3304eea Alexander Graf
    VirtIODevice *vdev;
165 f3304eea Alexander Graf
166 12c5674b Paolo Bonzini
    vdev = virtio_blk_init((DeviceState *)dev, &dev->blk);
167 f3304eea Alexander Graf
    if (!vdev) {
168 f3304eea Alexander Graf
        return -1;
169 f3304eea Alexander Graf
    }
170 f3304eea Alexander Graf
171 f3304eea Alexander Graf
    return s390_virtio_device_init(dev, vdev);
172 f3304eea Alexander Graf
}
173 f3304eea Alexander Graf
174 98b19252 Amit Shah
static int s390_virtio_serial_init(VirtIOS390Device *dev)
175 f3304eea Alexander Graf
{
176 f3304eea Alexander Graf
    VirtIOS390Bus *bus;
177 f3304eea Alexander Graf
    VirtIODevice *vdev;
178 f3304eea Alexander Graf
    int r;
179 f3304eea Alexander Graf
180 f3304eea Alexander Graf
    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
181 f3304eea Alexander Graf
182 6be9b414 Alexander Graf
    vdev = virtio_serial_init((DeviceState *)dev, &dev->serial);
183 f3304eea Alexander Graf
    if (!vdev) {
184 f3304eea Alexander Graf
        return -1;
185 f3304eea Alexander Graf
    }
186 f3304eea Alexander Graf
187 f3304eea Alexander Graf
    r = s390_virtio_device_init(dev, vdev);
188 f3304eea Alexander Graf
    if (!r) {
189 f3304eea Alexander Graf
        bus->console = dev;
190 f3304eea Alexander Graf
    }
191 f3304eea Alexander Graf
192 f3304eea Alexander Graf
    return r;
193 f3304eea Alexander Graf
}
194 f3304eea Alexander Graf
195 973abc7f Stefan Hajnoczi
static int s390_virtio_scsi_init(VirtIOS390Device *dev)
196 973abc7f Stefan Hajnoczi
{
197 973abc7f Stefan Hajnoczi
    VirtIODevice *vdev;
198 973abc7f Stefan Hajnoczi
199 973abc7f Stefan Hajnoczi
    vdev = virtio_scsi_init((DeviceState *)dev, &dev->scsi);
200 973abc7f Stefan Hajnoczi
    if (!vdev) {
201 973abc7f Stefan Hajnoczi
        return -1;
202 973abc7f Stefan Hajnoczi
    }
203 973abc7f Stefan Hajnoczi
204 973abc7f Stefan Hajnoczi
    return s390_virtio_device_init(dev, vdev);
205 973abc7f Stefan Hajnoczi
}
206 973abc7f Stefan Hajnoczi
207 f3304eea Alexander Graf
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
208 f3304eea Alexander Graf
{
209 f3304eea Alexander Graf
    ram_addr_t token_off;
210 f3304eea Alexander Graf
211 f3304eea Alexander Graf
    token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
212 f3304eea Alexander Graf
                (vq * VIRTIO_VQCONFIG_LEN) +
213 f3304eea Alexander Graf
                VIRTIO_VQCONFIG_OFFS_TOKEN;
214 f3304eea Alexander Graf
215 04bc74ed Alexander Graf
    return ldq_be_phys(token_off);
216 f3304eea Alexander Graf
}
217 f3304eea Alexander Graf
218 f3304eea Alexander Graf
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
219 f3304eea Alexander Graf
{
220 f3304eea Alexander Graf
    VirtIODevice *vdev = dev->vdev;
221 f3304eea Alexander Graf
    int num_vq;
222 f3304eea Alexander Graf
223 f3304eea Alexander Graf
    for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
224 f3304eea Alexander Graf
        if (!virtio_queue_get_num(vdev, num_vq)) {
225 f3304eea Alexander Graf
            break;
226 f3304eea Alexander Graf
        }
227 f3304eea Alexander Graf
    }
228 f3304eea Alexander Graf
229 f3304eea Alexander Graf
    return num_vq;
230 f3304eea Alexander Graf
}
231 f3304eea Alexander Graf
232 f3304eea Alexander Graf
static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
233 f3304eea Alexander Graf
{
234 f3304eea Alexander Graf
    ram_addr_t r = bus->next_ring;
235 f3304eea Alexander Graf
236 f3304eea Alexander Graf
    bus->next_ring += VIRTIO_RING_LEN;
237 f3304eea Alexander Graf
    return r;
238 f3304eea Alexander Graf
}
239 f3304eea Alexander Graf
240 baf0b55a Alexander Graf
void s390_virtio_device_sync(VirtIOS390Device *dev)
241 f3304eea Alexander Graf
{
242 f3304eea Alexander Graf
    VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
243 f3304eea Alexander Graf
    ram_addr_t cur_offs;
244 f3304eea Alexander Graf
    uint8_t num_vq;
245 f3304eea Alexander Graf
    int i;
246 f3304eea Alexander Graf
247 f3304eea Alexander Graf
    virtio_reset(dev->vdev);
248 f3304eea Alexander Graf
249 f3304eea Alexander Graf
    /* Sync dev space */
250 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id);
251 f3304eea Alexander Graf
252 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, s390_virtio_device_num_vq(dev));
253 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len);
254 f3304eea Alexander Graf
255 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len);
256 f3304eea Alexander Graf
257 f3304eea Alexander Graf
    num_vq = s390_virtio_device_num_vq(dev);
258 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq);
259 f3304eea Alexander Graf
260 f3304eea Alexander Graf
    /* Sync virtqueues */
261 f3304eea Alexander Graf
    for (i = 0; i < num_vq; i++) {
262 f3304eea Alexander Graf
        ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
263 f3304eea Alexander Graf
                        (i * VIRTIO_VQCONFIG_LEN);
264 f3304eea Alexander Graf
        ram_addr_t vring;
265 f3304eea Alexander Graf
266 f3304eea Alexander Graf
        vring = s390_virtio_next_ring(bus);
267 f3304eea Alexander Graf
        virtio_queue_set_addr(dev->vdev, i, vring);
268 f3304eea Alexander Graf
        virtio_queue_set_vector(dev->vdev, i, i);
269 04bc74ed Alexander Graf
        stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
270 04bc74ed Alexander Graf
        stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
271 f3304eea Alexander Graf
    }
272 f3304eea Alexander Graf
273 f3304eea Alexander Graf
    cur_offs = dev->dev_offs;
274 f3304eea Alexander Graf
    cur_offs += VIRTIO_DEV_OFFS_CONFIG;
275 f3304eea Alexander Graf
    cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
276 f3304eea Alexander Graf
277 f3304eea Alexander Graf
    /* Sync feature bitmap */
278 04bc74ed Alexander Graf
    stl_le_phys(cur_offs, dev->host_features);
279 f3304eea Alexander Graf
280 f3304eea Alexander Graf
    dev->feat_offs = cur_offs + dev->feat_len;
281 f3304eea Alexander Graf
    cur_offs += dev->feat_len * 2;
282 f3304eea Alexander Graf
283 f3304eea Alexander Graf
    /* Sync config space */
284 f3304eea Alexander Graf
    if (dev->vdev->get_config) {
285 f3304eea Alexander Graf
        dev->vdev->get_config(dev->vdev, dev->vdev->config);
286 f3304eea Alexander Graf
    }
287 f3304eea Alexander Graf
288 54f7b4a3 Stefan Weil
    cpu_physical_memory_write(cur_offs,
289 54f7b4a3 Stefan Weil
                              dev->vdev->config, dev->vdev->config_len);
290 f3304eea Alexander Graf
    cur_offs += dev->vdev->config_len;
291 f3304eea Alexander Graf
}
292 f3304eea Alexander Graf
293 f3304eea Alexander Graf
void s390_virtio_device_update_status(VirtIOS390Device *dev)
294 f3304eea Alexander Graf
{
295 f3304eea Alexander Graf
    VirtIODevice *vdev = dev->vdev;
296 f3304eea Alexander Graf
    uint32_t features;
297 f3304eea Alexander Graf
298 3e607cb5 Michael S. Tsirkin
    virtio_set_status(vdev, ldub_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS));
299 f3304eea Alexander Graf
300 f3304eea Alexander Graf
    /* Update guest supported feature bitmap */
301 f3304eea Alexander Graf
302 04bc74ed Alexander Graf
    features = bswap32(ldl_be_phys(dev->feat_offs));
303 ad0c9332 Paolo Bonzini
    virtio_set_features(vdev, features);
304 f3304eea Alexander Graf
}
305 f3304eea Alexander Graf
306 f3304eea Alexander Graf
VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
307 f3304eea Alexander Graf
{
308 f3304eea Alexander Graf
    return bus->console;
309 f3304eea Alexander Graf
}
310 f3304eea Alexander Graf
311 f3304eea Alexander Graf
/* Find a device by vring address */
312 f3304eea Alexander Graf
VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
313 f3304eea Alexander Graf
                                             ram_addr_t mem,
314 f3304eea Alexander Graf
                                             int *vq_num)
315 f3304eea Alexander Graf
{
316 f3304eea Alexander Graf
    VirtIOS390Device *_dev;
317 f3304eea Alexander Graf
    DeviceState *dev;
318 f3304eea Alexander Graf
    int i;
319 f3304eea Alexander Graf
320 d8bb00d6 Paolo Bonzini
    QTAILQ_FOREACH(dev, &bus->bus.children, sibling) {
321 f3304eea Alexander Graf
        _dev = (VirtIOS390Device *)dev;
322 f3304eea Alexander Graf
        for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
323 f3304eea Alexander Graf
            if (!virtio_queue_get_addr(_dev->vdev, i))
324 f3304eea Alexander Graf
                break;
325 f3304eea Alexander Graf
            if (virtio_queue_get_addr(_dev->vdev, i) == mem) {
326 f3304eea Alexander Graf
                if (vq_num) {
327 f3304eea Alexander Graf
                    *vq_num = i;
328 f3304eea Alexander Graf
                }
329 f3304eea Alexander Graf
                return _dev;
330 f3304eea Alexander Graf
            }
331 f3304eea Alexander Graf
        }
332 f3304eea Alexander Graf
    }
333 f3304eea Alexander Graf
334 f3304eea Alexander Graf
    return NULL;
335 f3304eea Alexander Graf
}
336 f3304eea Alexander Graf
337 f3304eea Alexander Graf
/* Find a device by device descriptor location */
338 f3304eea Alexander Graf
VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
339 f3304eea Alexander Graf
{
340 f3304eea Alexander Graf
    VirtIOS390Device *_dev;
341 f3304eea Alexander Graf
    DeviceState *dev;
342 f3304eea Alexander Graf
343 d8bb00d6 Paolo Bonzini
    QTAILQ_FOREACH(dev, &bus->bus.children, sibling) {
344 f3304eea Alexander Graf
        _dev = (VirtIOS390Device *)dev;
345 f3304eea Alexander Graf
        if (_dev->dev_offs == mem) {
346 f3304eea Alexander Graf
            return _dev;
347 f3304eea Alexander Graf
        }
348 f3304eea Alexander Graf
    }
349 f3304eea Alexander Graf
350 f3304eea Alexander Graf
    return NULL;
351 f3304eea Alexander Graf
}
352 f3304eea Alexander Graf
353 f3304eea Alexander Graf
static void virtio_s390_notify(void *opaque, uint16_t vector)
354 f3304eea Alexander Graf
{
355 f3304eea Alexander Graf
    VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
356 f3304eea Alexander Graf
    uint64_t token = s390_virtio_device_vq_token(dev, vector);
357 0e4213a7 Andreas Färber
    CPUS390XState *env = s390_cpu_addr2state(0);
358 f3304eea Alexander Graf
359 7fa41e53 Alexander Graf
    s390_virtio_irq(env, 0, token);
360 f3304eea Alexander Graf
}
361 f3304eea Alexander Graf
362 8172539d Michael S. Tsirkin
static unsigned virtio_s390_get_features(void *opaque)
363 8172539d Michael S. Tsirkin
{
364 8172539d Michael S. Tsirkin
    VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
365 8172539d Michael S. Tsirkin
    return dev->host_features;
366 8172539d Michael S. Tsirkin
}
367 8172539d Michael S. Tsirkin
368 f3304eea Alexander Graf
/**************** S390 Virtio Bus Device Descriptions *******************/
369 f3304eea Alexander Graf
370 f3304eea Alexander Graf
static const VirtIOBindings virtio_s390_bindings = {
371 f3304eea Alexander Graf
    .notify = virtio_s390_notify,
372 8172539d Michael S. Tsirkin
    .get_features = virtio_s390_get_features,
373 f3304eea Alexander Graf
};
374 f3304eea Alexander Graf
375 39bffca2 Anthony Liguori
static Property s390_virtio_net_properties[] = {
376 39bffca2 Anthony Liguori
    DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic),
377 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("x-txtimer", VirtIOS390Device,
378 39bffca2 Anthony Liguori
                       net.txtimer, TX_TIMER_INTERVAL),
379 39bffca2 Anthony Liguori
    DEFINE_PROP_INT32("x-txburst", VirtIOS390Device,
380 39bffca2 Anthony Liguori
                      net.txburst, TX_BURST),
381 39bffca2 Anthony Liguori
    DEFINE_PROP_STRING("tx", VirtIOS390Device, net.tx),
382 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
383 39bffca2 Anthony Liguori
};
384 39bffca2 Anthony Liguori
385 19b6914a Anthony Liguori
static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
386 19b6914a Anthony Liguori
{
387 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
388 39bffca2 Anthony Liguori
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
389 19b6914a Anthony Liguori
390 39bffca2 Anthony Liguori
    k->init = s390_virtio_net_init;
391 39bffca2 Anthony Liguori
    dc->props = s390_virtio_net_properties;
392 19b6914a Anthony Liguori
}
393 19b6914a Anthony Liguori
394 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_net = {
395 39bffca2 Anthony Liguori
    .name          = "virtio-net-s390",
396 39bffca2 Anthony Liguori
    .parent        = TYPE_VIRTIO_S390_DEVICE,
397 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
398 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_net_class_init,
399 39bffca2 Anthony Liguori
};
400 39bffca2 Anthony Liguori
401 39bffca2 Anthony Liguori
static Property s390_virtio_blk_properties[] = {
402 12c5674b Paolo Bonzini
    DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, blk.conf),
403 12c5674b Paolo Bonzini
    DEFINE_PROP_STRING("serial", VirtIOS390Device, blk.serial),
404 a6c5c84a Paolo Bonzini
#ifdef __linux__
405 a6c5c84a Paolo Bonzini
    DEFINE_PROP_BIT("scsi", VirtIOS390Device, blk.scsi, 0, true),
406 a6c5c84a Paolo Bonzini
#endif
407 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
408 f3304eea Alexander Graf
};
409 f3304eea Alexander Graf
410 19b6914a Anthony Liguori
static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
411 19b6914a Anthony Liguori
{
412 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
413 39bffca2 Anthony Liguori
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
414 19b6914a Anthony Liguori
415 39bffca2 Anthony Liguori
    k->init = s390_virtio_blk_init;
416 39bffca2 Anthony Liguori
    dc->props = s390_virtio_blk_properties;
417 19b6914a Anthony Liguori
}
418 19b6914a Anthony Liguori
419 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_blk = {
420 39bffca2 Anthony Liguori
    .name          = "virtio-blk-s390",
421 39bffca2 Anthony Liguori
    .parent        = TYPE_VIRTIO_S390_DEVICE,
422 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
423 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_blk_class_init,
424 39bffca2 Anthony Liguori
};
425 39bffca2 Anthony Liguori
426 39bffca2 Anthony Liguori
static Property s390_virtio_serial_properties[] = {
427 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("max_ports", VirtIOS390Device,
428 39bffca2 Anthony Liguori
                       serial.max_virtserial_ports, 31),
429 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
430 f3304eea Alexander Graf
};
431 f3304eea Alexander Graf
432 19b6914a Anthony Liguori
static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
433 19b6914a Anthony Liguori
{
434 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
435 39bffca2 Anthony Liguori
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
436 19b6914a Anthony Liguori
437 39bffca2 Anthony Liguori
    k->init = s390_virtio_serial_init;
438 39bffca2 Anthony Liguori
    dc->props = s390_virtio_serial_properties;
439 19b6914a Anthony Liguori
}
440 19b6914a Anthony Liguori
441 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_serial = {
442 39bffca2 Anthony Liguori
    .name          = "virtio-serial-s390",
443 39bffca2 Anthony Liguori
    .parent        = TYPE_VIRTIO_S390_DEVICE,
444 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
445 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_serial_class_init,
446 f3304eea Alexander Graf
};
447 f3304eea Alexander Graf
448 d307af79 Anthony Liguori
static int s390_virtio_busdev_init(DeviceState *dev)
449 f3304eea Alexander Graf
{
450 f3304eea Alexander Graf
    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
451 19b6914a Anthony Liguori
    VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
452 f3304eea Alexander Graf
453 f3304eea Alexander Graf
    return _info->init(_dev);
454 f3304eea Alexander Graf
}
455 f3304eea Alexander Graf
456 39bffca2 Anthony Liguori
static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
457 f3304eea Alexander Graf
{
458 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
459 f3304eea Alexander Graf
460 39bffca2 Anthony Liguori
    dc->init = s390_virtio_busdev_init;
461 39bffca2 Anthony Liguori
    dc->bus_info = &s390_virtio_bus_info;
462 39bffca2 Anthony Liguori
    dc->unplug = qdev_simple_unplug_cb;
463 f3304eea Alexander Graf
}
464 f3304eea Alexander Graf
465 19b6914a Anthony Liguori
static TypeInfo virtio_s390_device_info = {
466 19b6914a Anthony Liguori
    .name = TYPE_VIRTIO_S390_DEVICE,
467 19b6914a Anthony Liguori
    .parent = TYPE_DEVICE,
468 19b6914a Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
469 39bffca2 Anthony Liguori
    .class_init = virtio_s390_device_class_init,
470 e87f7fc6 Anthony Liguori
    .class_size = sizeof(VirtIOS390DeviceClass),
471 19b6914a Anthony Liguori
    .abstract = true,
472 19b6914a Anthony Liguori
};
473 19b6914a Anthony Liguori
474 973abc7f Stefan Hajnoczi
static Property s390_virtio_scsi_properties[] = {
475 973abc7f Stefan Hajnoczi
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOS390Device, host_features, scsi),
476 973abc7f Stefan Hajnoczi
    DEFINE_PROP_END_OF_LIST(),
477 973abc7f Stefan Hajnoczi
};
478 973abc7f Stefan Hajnoczi
479 973abc7f Stefan Hajnoczi
static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
480 973abc7f Stefan Hajnoczi
{
481 973abc7f Stefan Hajnoczi
    DeviceClass *dc = DEVICE_CLASS(klass);
482 973abc7f Stefan Hajnoczi
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
483 973abc7f Stefan Hajnoczi
484 973abc7f Stefan Hajnoczi
    k->init = s390_virtio_scsi_init;
485 973abc7f Stefan Hajnoczi
    dc->props = s390_virtio_scsi_properties;
486 973abc7f Stefan Hajnoczi
}
487 973abc7f Stefan Hajnoczi
488 973abc7f Stefan Hajnoczi
static TypeInfo s390_virtio_scsi = {
489 973abc7f Stefan Hajnoczi
    .name          = "virtio-scsi-s390",
490 973abc7f Stefan Hajnoczi
    .parent        = TYPE_VIRTIO_S390_DEVICE,
491 973abc7f Stefan Hajnoczi
    .instance_size = sizeof(VirtIOS390Device),
492 973abc7f Stefan Hajnoczi
    .class_init    = s390_virtio_scsi_class_init,
493 973abc7f Stefan Hajnoczi
};
494 f3304eea Alexander Graf
495 f3304eea Alexander Graf
/***************** S390 Virtio Bus Bridge Device *******************/
496 f3304eea Alexander Graf
/* Only required to have the virtio bus as child in the system bus */
497 f3304eea Alexander Graf
498 f3304eea Alexander Graf
static int s390_virtio_bridge_init(SysBusDevice *dev)
499 f3304eea Alexander Graf
{
500 f3304eea Alexander Graf
    /* nothing */
501 f3304eea Alexander Graf
    return 0;
502 f3304eea Alexander Graf
}
503 f3304eea Alexander Graf
504 999e12bb Anthony Liguori
static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
505 999e12bb Anthony Liguori
{
506 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
507 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
508 999e12bb Anthony Liguori
509 999e12bb Anthony Liguori
    k->init = s390_virtio_bridge_init;
510 39bffca2 Anthony Liguori
    dc->no_user = 1;
511 999e12bb Anthony Liguori
}
512 999e12bb Anthony Liguori
513 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_bridge_info = {
514 39bffca2 Anthony Liguori
    .name          = "s390-virtio-bridge",
515 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
516 39bffca2 Anthony Liguori
    .instance_size = sizeof(SysBusDevice),
517 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_bridge_class_init,
518 f3304eea Alexander Graf
};
519 f3304eea Alexander Graf
520 83f7d43a Andreas Färber
static void s390_virtio_register_types(void)
521 f3304eea Alexander Graf
{
522 83f7d43a Andreas Färber
    type_register_static(&virtio_s390_device_info);
523 83f7d43a Andreas Färber
    type_register_static(&s390_virtio_serial);
524 83f7d43a Andreas Färber
    type_register_static(&s390_virtio_blk);
525 83f7d43a Andreas Färber
    type_register_static(&s390_virtio_net);
526 973abc7f Stefan Hajnoczi
    type_register_static(&s390_virtio_scsi);
527 39bffca2 Anthony Liguori
    type_register_static(&s390_virtio_bridge_info);
528 f3304eea Alexander Graf
}
529 f3304eea Alexander Graf
530 83f7d43a Andreas Färber
type_init(s390_virtio_register_types)