]> git.proxmox.com Git - mirror_qemu.git/blame - arch_init.c
Fix i386-bsd-user build
[mirror_qemu.git] / arch_init.c
CommitLineData
ad96090a
BS
1/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include <stdint.h>
25#include <stdarg.h>
26#ifndef _WIN32
27#include <sys/mman.h>
28#endif
29#include "config.h"
30#include "monitor.h"
31#include "sysemu.h"
32#include "arch_init.h"
33#include "audio/audio.h"
34#include "hw/pc.h"
35#include "hw/pci.h"
36#include "hw/audiodev.h"
37#include "kvm.h"
38#include "migration.h"
39#include "net.h"
40#include "gdbstub.h"
41#include "hw/smbios.h"
42
43#ifdef TARGET_SPARC
44int graphic_width = 1024;
45int graphic_height = 768;
46int graphic_depth = 8;
47#else
48int graphic_width = 800;
49int graphic_height = 600;
50int graphic_depth = 15;
51#endif
52
53const char arch_config_name[] = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf";
54
55#if defined(TARGET_ALPHA)
56#define QEMU_ARCH QEMU_ARCH_ALPHA
57#elif defined(TARGET_ARM)
58#define QEMU_ARCH QEMU_ARCH_ARM
59#elif defined(TARGET_CRIS)
60#define QEMU_ARCH QEMU_ARCH_CRIS
61#elif defined(TARGET_I386)
62#define QEMU_ARCH QEMU_ARCH_I386
63#elif defined(TARGET_M68K)
64#define QEMU_ARCH QEMU_ARCH_M68K
65#elif defined(TARGET_MICROBLAZE)
66#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
67#elif defined(TARGET_MIPS)
68#define QEMU_ARCH QEMU_ARCH_MIPS
69#elif defined(TARGET_PPC)
70#define QEMU_ARCH QEMU_ARCH_PPC
71#elif defined(TARGET_S390X)
72#define QEMU_ARCH QEMU_ARCH_S390X
73#elif defined(TARGET_SH4)
74#define QEMU_ARCH QEMU_ARCH_SH4
75#elif defined(TARGET_SPARC)
76#define QEMU_ARCH QEMU_ARCH_SPARC
77#endif
78
79const uint32_t arch_type = QEMU_ARCH;
80
81/***********************************************************/
82/* ram save/restore */
83
84#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
85#define RAM_SAVE_FLAG_COMPRESS 0x02
86#define RAM_SAVE_FLAG_MEM_SIZE 0x04
87#define RAM_SAVE_FLAG_PAGE 0x08
88#define RAM_SAVE_FLAG_EOS 0x10
89
90static int is_dup_page(uint8_t *page, uint8_t ch)
91{
92 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
93 uint32_t *array = (uint32_t *)page;
94 int i;
95
96 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
97 if (array[i] != val) {
98 return 0;
99 }
100 }
101
102 return 1;
103}
104
105static int ram_save_block(QEMUFile *f)
106{
107 static ram_addr_t current_addr = 0;
108 ram_addr_t saved_addr = current_addr;
109 ram_addr_t addr = 0;
110 int found = 0;
111
112 while (addr < last_ram_offset) {
113 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
114 uint8_t *p;
115
116 cpu_physical_memory_reset_dirty(current_addr,
117 current_addr + TARGET_PAGE_SIZE,
118 MIGRATION_DIRTY_FLAG);
119
120 p = qemu_get_ram_ptr(current_addr);
121
122 if (is_dup_page(p, *p)) {
123 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
124 qemu_put_byte(f, *p);
125 } else {
126 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
127 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
128 }
129
130 found = 1;
131 break;
132 }
133 addr += TARGET_PAGE_SIZE;
134 current_addr = (saved_addr + addr) % last_ram_offset;
135 }
136
137 return found;
138}
139
140static uint64_t bytes_transferred;
141
142static ram_addr_t ram_save_remaining(void)
143{
144 ram_addr_t addr;
145 ram_addr_t count = 0;
146
147 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
148 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
149 count++;
150 }
151 }
152
153 return count;
154}
155
156uint64_t ram_bytes_remaining(void)
157{
158 return ram_save_remaining() * TARGET_PAGE_SIZE;
159}
160
161uint64_t ram_bytes_transferred(void)
162{
163 return bytes_transferred;
164}
165
166uint64_t ram_bytes_total(void)
167{
168 return last_ram_offset;
169}
170
171int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
172{
173 ram_addr_t addr;
174 uint64_t bytes_transferred_last;
175 double bwidth = 0;
176 uint64_t expected_time = 0;
177
178 if (stage < 0) {
179 cpu_physical_memory_set_dirty_tracking(0);
180 return 0;
181 }
182
183 if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
184 qemu_file_set_error(f);
185 return 0;
186 }
187
188 if (stage == 1) {
189 bytes_transferred = 0;
190
191 /* Make sure all dirty bits are set */
192 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
193 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
194 cpu_physical_memory_set_dirty(addr);
195 }
196 }
197
198 /* Enable dirty memory tracking */
199 cpu_physical_memory_set_dirty_tracking(1);
200
201 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
202 }
203
204 bytes_transferred_last = bytes_transferred;
205 bwidth = qemu_get_clock_ns(rt_clock);
206
207 while (!qemu_file_rate_limit(f)) {
208 int ret;
209
210 ret = ram_save_block(f);
211 bytes_transferred += ret * TARGET_PAGE_SIZE;
212 if (ret == 0) { /* no more blocks */
213 break;
214 }
215 }
216
217 bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
218 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
219
220 /* if we haven't transferred anything this round, force expected_time to a
221 * a very high value, but without crashing */
222 if (bwidth == 0) {
223 bwidth = 0.000001;
224 }
225
226 /* try transferring iterative blocks of memory */
227 if (stage == 3) {
228 /* flush all remaining blocks regardless of rate limiting */
229 while (ram_save_block(f) != 0) {
230 bytes_transferred += TARGET_PAGE_SIZE;
231 }
232 cpu_physical_memory_set_dirty_tracking(0);
233 }
234
235 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
236
237 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
238
239 return (stage == 2) && (expected_time <= migrate_max_downtime());
240}
241
242int ram_load(QEMUFile *f, void *opaque, int version_id)
243{
244 ram_addr_t addr;
245 int flags;
246
247 if (version_id != 3) {
248 return -EINVAL;
249 }
250
251 do {
252 addr = qemu_get_be64(f);
253
254 flags = addr & ~TARGET_PAGE_MASK;
255 addr &= TARGET_PAGE_MASK;
256
257 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
258 if (addr != last_ram_offset) {
259 return -EINVAL;
260 }
261 }
262
263 if (flags & RAM_SAVE_FLAG_COMPRESS) {
264 uint8_t ch = qemu_get_byte(f);
265 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
266#ifndef _WIN32
267 if (ch == 0 &&
268 (!kvm_enabled() || kvm_has_sync_mmu())) {
269 madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE,
270 MADV_DONTNEED);
271 }
272#endif
273 } else if (flags & RAM_SAVE_FLAG_PAGE) {
274 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
275 }
276 if (qemu_file_has_error(f)) {
277 return -EIO;
278 }
279 } while (!(flags & RAM_SAVE_FLAG_EOS));
280
281 return 0;
282}
283
284void qemu_service_io(void)
285{
286 qemu_notify_event();
287}
288
289#ifdef HAS_AUDIO
290struct soundhw soundhw[] = {
291#ifdef HAS_AUDIO_CHOICE
292#if defined(TARGET_I386) || defined(TARGET_MIPS)
293 {
294 "pcspk",
295 "PC speaker",
296 0,
297 1,
298 { .init_isa = pcspk_audio_init }
299 },
300#endif
301
302#ifdef CONFIG_SB16
303 {
304 "sb16",
305 "Creative Sound Blaster 16",
306 0,
307 1,
308 { .init_isa = SB16_init }
309 },
310#endif
311
312#ifdef CONFIG_CS4231A
313 {
314 "cs4231a",
315 "CS4231A",
316 0,
317 1,
318 { .init_isa = cs4231a_init }
319 },
320#endif
321
322#ifdef CONFIG_ADLIB
323 {
324 "adlib",
325#ifdef HAS_YMF262
326 "Yamaha YMF262 (OPL3)",
327#else
328 "Yamaha YM3812 (OPL2)",
329#endif
330 0,
331 1,
332 { .init_isa = Adlib_init }
333 },
334#endif
335
336#ifdef CONFIG_GUS
337 {
338 "gus",
339 "Gravis Ultrasound GF1",
340 0,
341 1,
342 { .init_isa = GUS_init }
343 },
344#endif
345
346#ifdef CONFIG_AC97
347 {
348 "ac97",
349 "Intel 82801AA AC97 Audio",
350 0,
351 0,
352 { .init_pci = ac97_init }
353 },
354#endif
355
356#ifdef CONFIG_ES1370
357 {
358 "es1370",
359 "ENSONIQ AudioPCI ES1370",
360 0,
361 0,
362 { .init_pci = es1370_init }
363 },
364#endif
365
366#endif /* HAS_AUDIO_CHOICE */
367
368 { NULL, NULL, 0, 0, { NULL } }
369};
370
371void select_soundhw(const char *optarg)
372{
373 struct soundhw *c;
374
375 if (*optarg == '?') {
376 show_valid_cards:
377
378 printf("Valid sound card names (comma separated):\n");
379 for (c = soundhw; c->name; ++c) {
380 printf ("%-11s %s\n", c->name, c->descr);
381 }
382 printf("\n-soundhw all will enable all of the above\n");
383 exit(*optarg != '?');
384 }
385 else {
386 size_t l;
387 const char *p;
388 char *e;
389 int bad_card = 0;
390
391 if (!strcmp(optarg, "all")) {
392 for (c = soundhw; c->name; ++c) {
393 c->enabled = 1;
394 }
395 return;
396 }
397
398 p = optarg;
399 while (*p) {
400 e = strchr(p, ',');
401 l = !e ? strlen(p) : (size_t) (e - p);
402
403 for (c = soundhw; c->name; ++c) {
404 if (!strncmp(c->name, p, l) && !c->name[l]) {
405 c->enabled = 1;
406 break;
407 }
408 }
409
410 if (!c->name) {
411 if (l > 80) {
412 fprintf(stderr,
413 "Unknown sound card name (too big to show)\n");
414 }
415 else {
416 fprintf(stderr, "Unknown sound card name `%.*s'\n",
417 (int) l, p);
418 }
419 bad_card = 1;
420 }
421 p += l + (e != NULL);
422 }
423
424 if (bad_card) {
425 goto show_valid_cards;
426 }
427 }
428}
429#else
430void select_soundhw(const char *optarg)
431{
432}
433#endif
434
435int qemu_uuid_parse(const char *str, uint8_t *uuid)
436{
437 int ret;
438
439 if (strlen(str) != 36) {
440 return -1;
441 }
442
443 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
444 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
445 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14],
446 &uuid[15]);
447
448 if (ret != 16) {
449 return -1;
450 }
451#ifdef TARGET_I386
452 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
453#endif
454 return 0;
455}
456
457void do_acpitable_option(const char *optarg)
458{
459#ifdef TARGET_I386
460 if (acpi_table_add(optarg) < 0) {
461 fprintf(stderr, "Wrong acpi table provided\n");
462 exit(1);
463 }
464#endif
465}
466
467void do_smbios_option(const char *optarg)
468{
469#ifdef TARGET_I386
470 if (smbios_entry_add(optarg) < 0) {
471 fprintf(stderr, "Wrong smbios provided\n");
472 exit(1);
473 }
474#endif
475}
476
477void cpudef_init(void)
478{
479#if defined(cpudef_setup)
480 cpudef_setup(); /* parse cpu definitions in target config file */
481#endif
482}
483
484int audio_available(void)
485{
486#ifdef HAS_AUDIO
487 return 1;
488#else
489 return 0;
490#endif
491}
492
493int kvm_available(void)
494{
495#ifdef CONFIG_KVM
496 return 1;
497#else
498 return 0;
499#endif
500}
501
502int xen_available(void)
503{
504#ifdef CONFIG_XEN
505 return 1;
506#else
507 return 0;
508#endif
509}