Statistics
| Branch: | Revision:

root / arch_init.c @ 68fb89a2

History | View | Annotate | Download (11.7 kB)

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/types.h>
28
#include <sys/mman.h>
29
#endif
30
#include "config.h"
31
#include "monitor.h"
32
#include "sysemu.h"
33
#include "arch_init.h"
34
#include "audio/audio.h"
35
#include "hw/pc.h"
36
#include "hw/pci.h"
37
#include "hw/audiodev.h"
38
#include "kvm.h"
39
#include "migration.h"
40
#include "net.h"
41
#include "gdbstub.h"
42
#include "hw/smbios.h"
43

    
44
#ifdef TARGET_SPARC
45
int graphic_width = 1024;
46
int graphic_height = 768;
47
int graphic_depth = 8;
48
#else
49
int graphic_width = 800;
50
int graphic_height = 600;
51
int graphic_depth = 15;
52
#endif
53

    
54
const char arch_config_name[] = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf";
55

    
56
#if defined(TARGET_ALPHA)
57
#define QEMU_ARCH QEMU_ARCH_ALPHA
58
#elif defined(TARGET_ARM)
59
#define QEMU_ARCH QEMU_ARCH_ARM
60
#elif defined(TARGET_CRIS)
61
#define QEMU_ARCH QEMU_ARCH_CRIS
62
#elif defined(TARGET_I386)
63
#define QEMU_ARCH QEMU_ARCH_I386
64
#elif defined(TARGET_M68K)
65
#define QEMU_ARCH QEMU_ARCH_M68K
66
#elif defined(TARGET_MICROBLAZE)
67
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
68
#elif defined(TARGET_MIPS)
69
#define QEMU_ARCH QEMU_ARCH_MIPS
70
#elif defined(TARGET_PPC)
71
#define QEMU_ARCH QEMU_ARCH_PPC
72
#elif defined(TARGET_S390X)
73
#define QEMU_ARCH QEMU_ARCH_S390X
74
#elif defined(TARGET_SH4)
75
#define QEMU_ARCH QEMU_ARCH_SH4
76
#elif defined(TARGET_SPARC)
77
#define QEMU_ARCH QEMU_ARCH_SPARC
78
#endif
79

    
80
const uint32_t arch_type = QEMU_ARCH;
81

    
82
/***********************************************************/
83
/* ram save/restore */
84

    
85
#define RAM_SAVE_FLAG_FULL        0x01 /* Obsolete, not used anymore */
86
#define RAM_SAVE_FLAG_COMPRESS        0x02
87
#define RAM_SAVE_FLAG_MEM_SIZE        0x04
88
#define RAM_SAVE_FLAG_PAGE        0x08
89
#define RAM_SAVE_FLAG_EOS        0x10
90

    
91
static int is_dup_page(uint8_t *page, uint8_t ch)
92
{
93
    uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
94
    uint32_t *array = (uint32_t *)page;
95
    int i;
96

    
97
    for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
98
        if (array[i] != val) {
99
            return 0;
100
        }
101
    }
102

    
103
    return 1;
104
}
105

    
106
static int ram_save_block(QEMUFile *f)
107
{
108
    static ram_addr_t current_addr = 0;
109
    ram_addr_t saved_addr = current_addr;
110
    ram_addr_t addr = 0;
111
    int found = 0;
112

    
113
    while (addr < last_ram_offset) {
114
        if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
115
            uint8_t *p;
116

    
117
            cpu_physical_memory_reset_dirty(current_addr,
118
                                            current_addr + TARGET_PAGE_SIZE,
119
                                            MIGRATION_DIRTY_FLAG);
120

    
121
            p = qemu_get_ram_ptr(current_addr);
122

    
123
            if (is_dup_page(p, *p)) {
124
                qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
125
                qemu_put_byte(f, *p);
126
            } else {
127
                qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
128
                qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
129
            }
130

    
131
            found = 1;
132
            break;
133
        }
134
        addr += TARGET_PAGE_SIZE;
135
        current_addr = (saved_addr + addr) % last_ram_offset;
136
    }
137

    
138
    return found;
139
}
140

    
141
static uint64_t bytes_transferred;
142

    
143
static ram_addr_t ram_save_remaining(void)
144
{
145
    ram_addr_t addr;
146
    ram_addr_t count = 0;
147

    
148
    for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
149
        if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
150
            count++;
151
        }
152
    }
153

    
154
    return count;
155
}
156

    
157
uint64_t ram_bytes_remaining(void)
158
{
159
    return ram_save_remaining() * TARGET_PAGE_SIZE;
160
}
161

    
162
uint64_t ram_bytes_transferred(void)
163
{
164
    return bytes_transferred;
165
}
166

    
167
uint64_t ram_bytes_total(void)
168
{
169
    return last_ram_offset;
170
}
171

    
172
int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
173
{
174
    ram_addr_t addr;
175
    uint64_t bytes_transferred_last;
176
    double bwidth = 0;
177
    uint64_t expected_time = 0;
178

    
179
    if (stage < 0) {
180
        cpu_physical_memory_set_dirty_tracking(0);
181
        return 0;
182
    }
183

    
184
    if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
185
        qemu_file_set_error(f);
186
        return 0;
187
    }
188

    
189
    if (stage == 1) {
190
        bytes_transferred = 0;
191

    
192
        /* Make sure all dirty bits are set */
193
        for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
194
            if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
195
                cpu_physical_memory_set_dirty(addr);
196
            }
197
        }
198

    
199
        /* Enable dirty memory tracking */
200
        cpu_physical_memory_set_dirty_tracking(1);
201

    
202
        qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
203
    }
204

    
205
    bytes_transferred_last = bytes_transferred;
206
    bwidth = qemu_get_clock_ns(rt_clock);
207

    
208
    while (!qemu_file_rate_limit(f)) {
209
        int ret;
210

    
211
        ret = ram_save_block(f);
212
        bytes_transferred += ret * TARGET_PAGE_SIZE;
213
        if (ret == 0) { /* no more blocks */
214
            break;
215
        }
216
    }
217

    
218
    bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
219
    bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
220

    
221
    /* if we haven't transferred anything this round, force expected_time to a
222
     * a very high value, but without crashing */
223
    if (bwidth == 0) {
224
        bwidth = 0.000001;
225
    }
226

    
227
    /* try transferring iterative blocks of memory */
228
    if (stage == 3) {
229
        /* flush all remaining blocks regardless of rate limiting */
230
        while (ram_save_block(f) != 0) {
231
            bytes_transferred += TARGET_PAGE_SIZE;
232
        }
233
        cpu_physical_memory_set_dirty_tracking(0);
234
    }
235

    
236
    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
237

    
238
    expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
239

    
240
    return (stage == 2) && (expected_time <= migrate_max_downtime());
241
}
242

    
243
int ram_load(QEMUFile *f, void *opaque, int version_id)
244
{
245
    ram_addr_t addr;
246
    int flags;
247

    
248
    if (version_id != 3) {
249
        return -EINVAL;
250
    }
251

    
252
    do {
253
        addr = qemu_get_be64(f);
254

    
255
        flags = addr & ~TARGET_PAGE_MASK;
256
        addr &= TARGET_PAGE_MASK;
257

    
258
        if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
259
            if (addr != last_ram_offset) {
260
                return -EINVAL;
261
            }
262
        }
263

    
264
        if (flags & RAM_SAVE_FLAG_COMPRESS) {
265
            uint8_t ch = qemu_get_byte(f);
266
            memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
267
#ifndef _WIN32
268
            if (ch == 0 &&
269
                (!kvm_enabled() || kvm_has_sync_mmu())) {
270
                madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE,
271
                        MADV_DONTNEED);
272
            }
273
#endif
274
        } else if (flags & RAM_SAVE_FLAG_PAGE) {
275
            qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
276
        }
277
        if (qemu_file_has_error(f)) {
278
            return -EIO;
279
        }
280
    } while (!(flags & RAM_SAVE_FLAG_EOS));
281

    
282
    return 0;
283
}
284

    
285
void qemu_service_io(void)
286
{
287
    qemu_notify_event();
288
}
289

    
290
#ifdef HAS_AUDIO
291
struct soundhw soundhw[] = {
292
#ifdef HAS_AUDIO_CHOICE
293
#if defined(TARGET_I386) || defined(TARGET_MIPS)
294
    {
295
        "pcspk",
296
        "PC speaker",
297
        0,
298
        1,
299
        { .init_isa = pcspk_audio_init }
300
    },
301
#endif
302

    
303
#ifdef CONFIG_SB16
304
    {
305
        "sb16",
306
        "Creative Sound Blaster 16",
307
        0,
308
        1,
309
        { .init_isa = SB16_init }
310
    },
311
#endif
312

    
313
#ifdef CONFIG_CS4231A
314
    {
315
        "cs4231a",
316
        "CS4231A",
317
        0,
318
        1,
319
        { .init_isa = cs4231a_init }
320
    },
321
#endif
322

    
323
#ifdef CONFIG_ADLIB
324
    {
325
        "adlib",
326
#ifdef HAS_YMF262
327
        "Yamaha YMF262 (OPL3)",
328
#else
329
        "Yamaha YM3812 (OPL2)",
330
#endif
331
        0,
332
        1,
333
        { .init_isa = Adlib_init }
334
    },
335
#endif
336

    
337
#ifdef CONFIG_GUS
338
    {
339
        "gus",
340
        "Gravis Ultrasound GF1",
341
        0,
342
        1,
343
        { .init_isa = GUS_init }
344
    },
345
#endif
346

    
347
#ifdef CONFIG_AC97
348
    {
349
        "ac97",
350
        "Intel 82801AA AC97 Audio",
351
        0,
352
        0,
353
        { .init_pci = ac97_init }
354
    },
355
#endif
356

    
357
#ifdef CONFIG_ES1370
358
    {
359
        "es1370",
360
        "ENSONIQ AudioPCI ES1370",
361
        0,
362
        0,
363
        { .init_pci = es1370_init }
364
    },
365
#endif
366

    
367
#endif /* HAS_AUDIO_CHOICE */
368

    
369
    { NULL, NULL, 0, 0, { NULL } }
370
};
371

    
372
void select_soundhw(const char *optarg)
373
{
374
    struct soundhw *c;
375

    
376
    if (*optarg == '?') {
377
    show_valid_cards:
378

    
379
        printf("Valid sound card names (comma separated):\n");
380
        for (c = soundhw; c->name; ++c) {
381
            printf ("%-11s %s\n", c->name, c->descr);
382
        }
383
        printf("\n-soundhw all will enable all of the above\n");
384
        exit(*optarg != '?');
385
    }
386
    else {
387
        size_t l;
388
        const char *p;
389
        char *e;
390
        int bad_card = 0;
391

    
392
        if (!strcmp(optarg, "all")) {
393
            for (c = soundhw; c->name; ++c) {
394
                c->enabled = 1;
395
            }
396
            return;
397
        }
398

    
399
        p = optarg;
400
        while (*p) {
401
            e = strchr(p, ',');
402
            l = !e ? strlen(p) : (size_t) (e - p);
403

    
404
            for (c = soundhw; c->name; ++c) {
405
                if (!strncmp(c->name, p, l) && !c->name[l]) {
406
                    c->enabled = 1;
407
                    break;
408
                }
409
            }
410

    
411
            if (!c->name) {
412
                if (l > 80) {
413
                    fprintf(stderr,
414
                            "Unknown sound card name (too big to show)\n");
415
                }
416
                else {
417
                    fprintf(stderr, "Unknown sound card name `%.*s'\n",
418
                            (int) l, p);
419
                }
420
                bad_card = 1;
421
            }
422
            p += l + (e != NULL);
423
        }
424

    
425
        if (bad_card) {
426
            goto show_valid_cards;
427
        }
428
    }
429
}
430
#else
431
void select_soundhw(const char *optarg)
432
{
433
}
434
#endif
435

    
436
int qemu_uuid_parse(const char *str, uint8_t *uuid)
437
{
438
    int ret;
439

    
440
    if (strlen(str) != 36) {
441
        return -1;
442
    }
443

    
444
    ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
445
                 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
446
                 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14],
447
                 &uuid[15]);
448

    
449
    if (ret != 16) {
450
        return -1;
451
    }
452
#ifdef TARGET_I386
453
    smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
454
#endif
455
    return 0;
456
}
457

    
458
void do_acpitable_option(const char *optarg)
459
{
460
#ifdef TARGET_I386
461
    if (acpi_table_add(optarg) < 0) {
462
        fprintf(stderr, "Wrong acpi table provided\n");
463
        exit(1);
464
    }
465
#endif
466
}
467

    
468
void do_smbios_option(const char *optarg)
469
{
470
#ifdef TARGET_I386
471
    if (smbios_entry_add(optarg) < 0) {
472
        fprintf(stderr, "Wrong smbios provided\n");
473
        exit(1);
474
    }
475
#endif
476
}
477

    
478
void cpudef_init(void)
479
{
480
#if defined(cpudef_setup)
481
    cpudef_setup(); /* parse cpu definitions in target config file */
482
#endif
483
}
484

    
485
int audio_available(void)
486
{
487
#ifdef HAS_AUDIO
488
    return 1;
489
#else
490
    return 0;
491
#endif
492
}
493

    
494
int kvm_available(void)
495
{
496
#ifdef CONFIG_KVM
497
    return 1;
498
#else
499
    return 0;
500
#endif
501
}
502

    
503
int xen_available(void)
504
{
505
#ifdef CONFIG_XEN
506
    return 1;
507
#else
508
    return 0;
509
#endif
510
}