Statistics
| Branch: | Revision:

root / hw / s390-virtio.c @ 9f953ca0

History | View | Annotate | Download (7.3 kB)

1 8cb310e1 Alexander Graf
/*
2 8cb310e1 Alexander Graf
 * QEMU S390 virtio target
3 8cb310e1 Alexander Graf
 *
4 8cb310e1 Alexander Graf
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
5 8cb310e1 Alexander Graf
 *
6 8cb310e1 Alexander Graf
 * This library is free software; you can redistribute it and/or
7 8cb310e1 Alexander Graf
 * modify it under the terms of the GNU Lesser General Public
8 8cb310e1 Alexander Graf
 * License as published by the Free Software Foundation; either
9 8cb310e1 Alexander Graf
 * version 2 of the License, or (at your option) any later version.
10 8cb310e1 Alexander Graf
 *
11 8cb310e1 Alexander Graf
 * This library is distributed in the hope that it will be useful,
12 8cb310e1 Alexander Graf
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 8cb310e1 Alexander Graf
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 8cb310e1 Alexander Graf
 * Lesser General Public License for more details.
15 8cb310e1 Alexander Graf
 *
16 8cb310e1 Alexander Graf
 * You should have received a copy of the GNU Lesser General Public
17 8cb310e1 Alexander Graf
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 8cb310e1 Alexander Graf
 */
19 8cb310e1 Alexander Graf
20 8cb310e1 Alexander Graf
#include "hw.h"
21 8cb310e1 Alexander Graf
#include "block.h"
22 6c33286a Alexander Graf
#include "blockdev.h"
23 8cb310e1 Alexander Graf
#include "sysemu.h"
24 8cb310e1 Alexander Graf
#include "net.h"
25 8cb310e1 Alexander Graf
#include "boards.h"
26 8cb310e1 Alexander Graf
#include "monitor.h"
27 8cb310e1 Alexander Graf
#include "loader.h"
28 8cb310e1 Alexander Graf
#include "elf.h"
29 8cb310e1 Alexander Graf
#include "hw/virtio.h"
30 8cb310e1 Alexander Graf
#include "hw/sysbus.h"
31 8cb310e1 Alexander Graf
#include "kvm.h"
32 8cb310e1 Alexander Graf
33 8cb310e1 Alexander Graf
#include "hw/s390-virtio-bus.h"
34 8cb310e1 Alexander Graf
35 8cb310e1 Alexander Graf
//#define DEBUG_S390
36 8cb310e1 Alexander Graf
37 8cb310e1 Alexander Graf
#ifdef DEBUG_S390
38 8cb310e1 Alexander Graf
#define dprintf(fmt, ...) \
39 8cb310e1 Alexander Graf
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
40 8cb310e1 Alexander Graf
#else
41 8cb310e1 Alexander Graf
#define dprintf(fmt, ...) \
42 8cb310e1 Alexander Graf
    do { } while (0)
43 8cb310e1 Alexander Graf
#endif
44 8cb310e1 Alexander Graf
45 8cb310e1 Alexander Graf
#define KVM_S390_VIRTIO_NOTIFY          0
46 8cb310e1 Alexander Graf
#define KVM_S390_VIRTIO_RESET           1
47 8cb310e1 Alexander Graf
#define KVM_S390_VIRTIO_SET_STATUS      2
48 8cb310e1 Alexander Graf
49 8cb310e1 Alexander Graf
#define KERN_IMAGE_START                0x010000UL
50 8cb310e1 Alexander Graf
#define KERN_PARM_AREA                  0x010480UL
51 8cb310e1 Alexander Graf
#define INITRD_START                    0x800000UL
52 8cb310e1 Alexander Graf
#define INITRD_PARM_START               0x010408UL
53 8cb310e1 Alexander Graf
#define INITRD_PARM_SIZE                0x010410UL
54 8cb310e1 Alexander Graf
#define PARMFILE_START                  0x001000UL
55 8cb310e1 Alexander Graf
56 fe270d04 Alexander Graf
#define ZIPL_START                        0x009000UL
57 fe270d04 Alexander Graf
#define ZIPL_LOAD_ADDR                        0x009000UL
58 fe270d04 Alexander Graf
#define ZIPL_FILENAME                        "s390-zipl.rom"
59 fe270d04 Alexander Graf
60 8cb310e1 Alexander Graf
#define MAX_BLK_DEVS                    10
61 8cb310e1 Alexander Graf
62 8cb310e1 Alexander Graf
static VirtIOS390Bus *s390_bus;
63 8cb310e1 Alexander Graf
static CPUState **ipi_states;
64 8cb310e1 Alexander Graf
65 8cb310e1 Alexander Graf
void irq_info(Monitor *mon);
66 8cb310e1 Alexander Graf
void pic_info(Monitor *mon);
67 8cb310e1 Alexander Graf
68 8cb310e1 Alexander Graf
void irq_info(Monitor *mon)
69 8cb310e1 Alexander Graf
{
70 8cb310e1 Alexander Graf
}
71 8cb310e1 Alexander Graf
72 8cb310e1 Alexander Graf
void pic_info(Monitor *mon)
73 8cb310e1 Alexander Graf
{
74 8cb310e1 Alexander Graf
}
75 8cb310e1 Alexander Graf
76 8cb310e1 Alexander Graf
CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
77 8cb310e1 Alexander Graf
{
78 8cb310e1 Alexander Graf
    if (cpu_addr >= smp_cpus) {
79 8cb310e1 Alexander Graf
        return NULL;
80 8cb310e1 Alexander Graf
    }
81 8cb310e1 Alexander Graf
82 8cb310e1 Alexander Graf
    return ipi_states[cpu_addr];
83 8cb310e1 Alexander Graf
}
84 8cb310e1 Alexander Graf
85 8cb310e1 Alexander Graf
int s390_virtio_hypercall(CPUState *env)
86 8cb310e1 Alexander Graf
{
87 8cb310e1 Alexander Graf
    int r = 0, i;
88 8cb310e1 Alexander Graf
    target_ulong mem = env->regs[2];
89 8cb310e1 Alexander Graf
90 8cb310e1 Alexander Graf
    dprintf("KVM hypercall: %ld\n", env->regs[1]);
91 8cb310e1 Alexander Graf
    switch (env->regs[1]) {
92 8cb310e1 Alexander Graf
    case KVM_S390_VIRTIO_NOTIFY:
93 8cb310e1 Alexander Graf
        if (mem > ram_size) {
94 8cb310e1 Alexander Graf
            VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
95 8cb310e1 Alexander Graf
                                                               mem, &i);
96 8cb310e1 Alexander Graf
            if (dev) {
97 8cb310e1 Alexander Graf
                virtio_queue_notify(dev->vdev, i);
98 8cb310e1 Alexander Graf
            } else {
99 8cb310e1 Alexander Graf
                r = -EINVAL;
100 8cb310e1 Alexander Graf
            }
101 8cb310e1 Alexander Graf
        } else {
102 8cb310e1 Alexander Graf
            /* Early printk */
103 8cb310e1 Alexander Graf
        }
104 8cb310e1 Alexander Graf
        break;
105 8cb310e1 Alexander Graf
    case KVM_S390_VIRTIO_RESET:
106 8cb310e1 Alexander Graf
    {
107 baf0b55a Alexander Graf
        VirtIOS390Device *dev;
108 baf0b55a Alexander Graf
109 baf0b55a Alexander Graf
        dev = s390_virtio_bus_find_mem(s390_bus, mem);
110 baf0b55a Alexander Graf
        virtio_reset(dev->vdev);
111 baf0b55a Alexander Graf
        s390_virtio_device_sync(dev);
112 8cb310e1 Alexander Graf
        break;
113 8cb310e1 Alexander Graf
    }
114 8cb310e1 Alexander Graf
    case KVM_S390_VIRTIO_SET_STATUS:
115 8cb310e1 Alexander Graf
    {
116 8cb310e1 Alexander Graf
        VirtIOS390Device *dev;
117 8cb310e1 Alexander Graf
118 8cb310e1 Alexander Graf
        dev = s390_virtio_bus_find_mem(s390_bus, mem);
119 8cb310e1 Alexander Graf
        if (dev) {
120 8cb310e1 Alexander Graf
            s390_virtio_device_update_status(dev);
121 8cb310e1 Alexander Graf
        } else {
122 8cb310e1 Alexander Graf
            r = -EINVAL;
123 8cb310e1 Alexander Graf
        }
124 8cb310e1 Alexander Graf
        break;
125 8cb310e1 Alexander Graf
    }
126 8cb310e1 Alexander Graf
    default:
127 8cb310e1 Alexander Graf
        r = -EINVAL;
128 8cb310e1 Alexander Graf
        break;
129 8cb310e1 Alexander Graf
    }
130 8cb310e1 Alexander Graf
131 8cb310e1 Alexander Graf
    env->regs[2] = r;
132 8cb310e1 Alexander Graf
    return 0;
133 8cb310e1 Alexander Graf
}
134 8cb310e1 Alexander Graf
135 8cb310e1 Alexander Graf
/* PC hardware initialisation */
136 8cb310e1 Alexander Graf
static void s390_init(ram_addr_t ram_size,
137 8cb310e1 Alexander Graf
                      const char *boot_device,
138 8cb310e1 Alexander Graf
                      const char *kernel_filename,
139 8cb310e1 Alexander Graf
                      const char *kernel_cmdline,
140 8cb310e1 Alexander Graf
                      const char *initrd_filename,
141 8cb310e1 Alexander Graf
                      const char *cpu_model)
142 8cb310e1 Alexander Graf
{
143 8cb310e1 Alexander Graf
    CPUState *env = NULL;
144 8cb310e1 Alexander Graf
    ram_addr_t ram_addr;
145 8cb310e1 Alexander Graf
    ram_addr_t kernel_size = 0;
146 8cb310e1 Alexander Graf
    ram_addr_t initrd_offset;
147 8cb310e1 Alexander Graf
    ram_addr_t initrd_size = 0;
148 8cb310e1 Alexander Graf
    int i;
149 8cb310e1 Alexander Graf
150 e249651c Alexander Graf
    /* XXX we only work on KVM for now */
151 e249651c Alexander Graf
152 e249651c Alexander Graf
    if (!kvm_enabled()) {
153 e249651c Alexander Graf
        fprintf(stderr, "The S390 target only works with KVM enabled\n");
154 e249651c Alexander Graf
        exit(1);
155 e249651c Alexander Graf
    }
156 e249651c Alexander Graf
157 8cb310e1 Alexander Graf
    /* get a BUS */
158 8cb310e1 Alexander Graf
    s390_bus = s390_virtio_bus_init(&ram_size);
159 8cb310e1 Alexander Graf
160 8cb310e1 Alexander Graf
    /* allocate RAM */
161 1724f049 Alex Williamson
    ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size);
162 8cb310e1 Alexander Graf
    cpu_register_physical_memory(0, ram_size, ram_addr);
163 8cb310e1 Alexander Graf
164 8cb310e1 Alexander Graf
    /* init CPUs */
165 8cb310e1 Alexander Graf
    if (cpu_model == NULL) {
166 8cb310e1 Alexander Graf
        cpu_model = "host";
167 8cb310e1 Alexander Graf
    }
168 8cb310e1 Alexander Graf
169 8cb310e1 Alexander Graf
    ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus);
170 8cb310e1 Alexander Graf
171 8cb310e1 Alexander Graf
    for (i = 0; i < smp_cpus; i++) {
172 8cb310e1 Alexander Graf
        CPUState *tmp_env;
173 8cb310e1 Alexander Graf
174 8cb310e1 Alexander Graf
        tmp_env = cpu_init(cpu_model);
175 8cb310e1 Alexander Graf
        if (!env) {
176 8cb310e1 Alexander Graf
            env = tmp_env;
177 8cb310e1 Alexander Graf
        }
178 8cb310e1 Alexander Graf
        ipi_states[i] = tmp_env;
179 8cb310e1 Alexander Graf
        tmp_env->halted = 1;
180 8cb310e1 Alexander Graf
        tmp_env->exception_index = EXCP_HLT;
181 8cb310e1 Alexander Graf
    }
182 8cb310e1 Alexander Graf
183 8cb310e1 Alexander Graf
    env->halted = 0;
184 8cb310e1 Alexander Graf
    env->exception_index = 0;
185 8cb310e1 Alexander Graf
186 8cb310e1 Alexander Graf
    if (kernel_filename) {
187 8cb310e1 Alexander Graf
        kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
188 8cb310e1 Alexander Graf
189 8cb310e1 Alexander Graf
        if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
190 8cb310e1 Alexander Graf
            fprintf(stderr, "Specified image is not an s390 boot image\n");
191 8cb310e1 Alexander Graf
            exit(1);
192 8cb310e1 Alexander Graf
        }
193 8cb310e1 Alexander Graf
194 8cb310e1 Alexander Graf
        env->psw.addr = KERN_IMAGE_START;
195 0435d393 Michael S. Tsirkin
        env->psw.mask = 0x0000000180000000ULL;
196 fe270d04 Alexander Graf
    } else {
197 fe270d04 Alexander Graf
        ram_addr_t bios_size = 0;
198 fe270d04 Alexander Graf
        char *bios_filename;
199 fe270d04 Alexander Graf
200 fe270d04 Alexander Graf
        /* Load zipl bootloader */
201 fe270d04 Alexander Graf
        if (bios_name == NULL) {
202 fe270d04 Alexander Graf
            bios_name = ZIPL_FILENAME;
203 fe270d04 Alexander Graf
        }
204 fe270d04 Alexander Graf
205 fe270d04 Alexander Graf
        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
206 fe270d04 Alexander Graf
        bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR));
207 9f953ca0 Stefan Weil
        qemu_free(bios_filename);
208 fe270d04 Alexander Graf
209 fe270d04 Alexander Graf
        if ((long)bios_size < 0) {
210 fe270d04 Alexander Graf
            hw_error("could not load bootloader '%s'\n", bios_name);
211 fe270d04 Alexander Graf
        }
212 fe270d04 Alexander Graf
213 fe270d04 Alexander Graf
        if (bios_size > 4096) {
214 fe270d04 Alexander Graf
            hw_error("stage1 bootloader is > 4k\n");
215 fe270d04 Alexander Graf
        }
216 fe270d04 Alexander Graf
217 fe270d04 Alexander Graf
        env->psw.addr = ZIPL_START;
218 fe270d04 Alexander Graf
        env->psw.mask = 0x0000000180000000ULL;
219 8cb310e1 Alexander Graf
    }
220 8cb310e1 Alexander Graf
221 8cb310e1 Alexander Graf
    if (initrd_filename) {
222 8cb310e1 Alexander Graf
        initrd_offset = INITRD_START;
223 8cb310e1 Alexander Graf
        while (kernel_size + 0x100000 > initrd_offset) {
224 8cb310e1 Alexander Graf
            initrd_offset += 0x100000;
225 8cb310e1 Alexander Graf
        }
226 8cb310e1 Alexander Graf
        initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));
227 8cb310e1 Alexander Graf
228 8cb310e1 Alexander Graf
        stq_phys(INITRD_PARM_START, initrd_offset);
229 8cb310e1 Alexander Graf
        stq_phys(INITRD_PARM_SIZE, initrd_size);
230 8cb310e1 Alexander Graf
    }
231 8cb310e1 Alexander Graf
232 8cb310e1 Alexander Graf
    if (kernel_cmdline) {
233 8cb310e1 Alexander Graf
        cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline,
234 8cb310e1 Alexander Graf
                               strlen(kernel_cmdline), 1);
235 8cb310e1 Alexander Graf
    }
236 8cb310e1 Alexander Graf
237 8cb310e1 Alexander Graf
    /* Create VirtIO network adapters */
238 8cb310e1 Alexander Graf
    for(i = 0; i < nb_nics; i++) {
239 8cb310e1 Alexander Graf
        NICInfo *nd = &nd_table[i];
240 8cb310e1 Alexander Graf
        DeviceState *dev;
241 8cb310e1 Alexander Graf
242 8cb310e1 Alexander Graf
        if (!nd->model) {
243 5a2b3fc5 Stefan Weil
            nd->model = qemu_strdup("virtio");
244 8cb310e1 Alexander Graf
        }
245 8cb310e1 Alexander Graf
246 8cb310e1 Alexander Graf
        if (strcmp(nd->model, "virtio")) {
247 8cb310e1 Alexander Graf
            fprintf(stderr, "S390 only supports VirtIO nics\n");
248 8cb310e1 Alexander Graf
            exit(1);
249 8cb310e1 Alexander Graf
        }
250 8cb310e1 Alexander Graf
251 8cb310e1 Alexander Graf
        dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");
252 8cb310e1 Alexander Graf
        qdev_set_nic_properties(dev, nd);
253 8cb310e1 Alexander Graf
        qdev_init_nofail(dev);
254 8cb310e1 Alexander Graf
    }
255 8cb310e1 Alexander Graf
256 8cb310e1 Alexander Graf
    /* Create VirtIO disk drives */
257 8cb310e1 Alexander Graf
    for(i = 0; i < MAX_BLK_DEVS; i++) {
258 8cb310e1 Alexander Graf
        DriveInfo *dinfo;
259 8cb310e1 Alexander Graf
        DeviceState *dev;
260 8cb310e1 Alexander Graf
261 8cb310e1 Alexander Graf
        dinfo = drive_get(IF_IDE, 0, i);
262 8cb310e1 Alexander Graf
        if (!dinfo) {
263 8cb310e1 Alexander Graf
            continue;
264 8cb310e1 Alexander Graf
        }
265 8cb310e1 Alexander Graf
266 8cb310e1 Alexander Graf
        dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");
267 18846dee Markus Armbruster
        qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);
268 8cb310e1 Alexander Graf
        qdev_init_nofail(dev);
269 8cb310e1 Alexander Graf
    }
270 8cb310e1 Alexander Graf
}
271 8cb310e1 Alexander Graf
272 8cb310e1 Alexander Graf
static QEMUMachine s390_machine = {
273 8cb310e1 Alexander Graf
    .name = "s390-virtio",
274 8cb310e1 Alexander Graf
    .alias = "s390",
275 8cb310e1 Alexander Graf
    .desc = "VirtIO based S390 machine",
276 8cb310e1 Alexander Graf
    .init = s390_init,
277 986c5f78 Gerd Hoffmann
    .no_serial = 1,
278 986c5f78 Gerd Hoffmann
    .no_parallel = 1,
279 cf708987 Michael S. Tsirkin
    .use_virtcon = 1,
280 986c5f78 Gerd Hoffmann
    .no_vga = 1,
281 8cb310e1 Alexander Graf
    .max_cpus = 255,
282 8cb310e1 Alexander Graf
    .is_default = 1,
283 8cb310e1 Alexander Graf
};
284 8cb310e1 Alexander Graf
285 8cb310e1 Alexander Graf
static void s390_machine_init(void)
286 8cb310e1 Alexander Graf
{
287 8cb310e1 Alexander Graf
    qemu_register_machine(&s390_machine);
288 8cb310e1 Alexander Graf
}
289 8cb310e1 Alexander Graf
290 8cb310e1 Alexander Graf
machine_init(s390_machine_init);