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