pc.c 32.4 KB
Newer Older
B
bellard 已提交
1 2
/*
 * QEMU PC System Emulator
3
 *
B
bellard 已提交
4
 * Copyright (c) 2003-2004 Fabrice Bellard
5
 *
B
bellard 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
24 25 26 27 28 29 30
#include "hw/hw.h"
#include "hw/pc.h"
#include "hw/serial.h"
#include "hw/apic.h"
#include "hw/fdc.h"
#include "hw/ide.h"
#include "hw/pci/pci.h"
31
#include "monitor/monitor.h"
32 33 34 35
#include "hw/fw_cfg.h"
#include "hw/hpet_emul.h"
#include "hw/smbios.h"
#include "hw/loader.h"
B
Blue Swirl 已提交
36
#include "elf.h"
37 38 39 40 41 42
#include "hw/multiboot.h"
#include "hw/mc146818rtc.h"
#include "hw/i8254.h"
#include "hw/pcspk.h"
#include "hw/pci/msi.h"
#include "hw/sysbus.h"
43 44
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
45
#include "kvm_i386.h"
46
#include "hw/xen.h"
47
#include "sysemu/blockdev.h"
48
#include "hw/block-common.h"
G
Gerd Hoffmann 已提交
49
#include "ui/qemu-spice.h"
50 51
#include "exec/memory.h"
#include "exec/address-spaces.h"
52
#include "sysemu/arch_init.h"
53
#include "qemu/bitmap.h"
B
bellard 已提交
54

B
Blue Swirl 已提交
55 56 57 58 59 60 61 62 63 64
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ

#ifdef DEBUG_IRQ
#define DPRINTF(fmt, ...)                                       \
    do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...)
#endif

65 66
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables.  */
#define ACPI_DATA_SIZE       0x10000
67
#define BIOS_CFG_IOPORT 0x510
68
#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
69
#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
J
Jes Sorensen 已提交
70
#define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)
J
Jes Sorensen 已提交
71
#define FW_CFG_E820_TABLE (FW_CFG_ARCH_LOCAL + 3)
72
#define FW_CFG_HPET (FW_CFG_ARCH_LOCAL + 4)
B
bellard 已提交
73

J
Jes Sorensen 已提交
74 75 76 77 78 79
#define E820_NR_ENTRIES		16

struct e820_entry {
    uint64_t address;
    uint64_t length;
    uint32_t type;
80
} QEMU_PACKED __attribute((__aligned__(4)));
J
Jes Sorensen 已提交
81 82 83 84

struct e820_table {
    uint32_t count;
    struct e820_entry entry[E820_NR_ENTRIES];
85
} QEMU_PACKED __attribute((__aligned__(4)));
J
Jes Sorensen 已提交
86 87

static struct e820_table e820_table;
B
Blue Swirl 已提交
88
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
J
Jes Sorensen 已提交
89

J
Jan Kiszka 已提交
90
void gsi_handler(void *opaque, int n, int level)
91
{
J
Jan Kiszka 已提交
92
    GSIState *s = opaque;
93

J
Jan Kiszka 已提交
94 95 96
    DPRINTF("pc: %s GSI %d\n", level ? "raising" : "lowering", n);
    if (n < ISA_NUM_IRQS) {
        qemu_set_irq(s->i8259_irq[n], level);
A
Avi Kivity 已提交
97
    }
J
Jan Kiszka 已提交
98
    qemu_set_irq(s->ioapic_irq[n], level);
99
}
100

J
Julien Grall 已提交
101 102
static void ioport80_write(void *opaque, hwaddr addr, uint64_t data,
                           unsigned size)
B
bellard 已提交
103 104 105
{
}

106 107
static uint64_t ioport80_read(void *opaque, hwaddr addr, unsigned size)
{
108
    return 0xffffffffffffffffULL;
109 110
}

111
/* MSDOS compatibility mode FPU exception support */
P
pbrook 已提交
112
static qemu_irq ferr_irq;
113 114 115 116 117 118

void pc_register_ferr_irq(qemu_irq irq)
{
    ferr_irq = irq;
}

119 120 121
/* XXX: add IGNNE support */
void cpu_set_ferr(CPUX86State *s)
{
P
pbrook 已提交
122
    qemu_irq_raise(ferr_irq);
123 124
}

J
Julien Grall 已提交
125 126
static void ioportF0_write(void *opaque, hwaddr addr, uint64_t data,
                           unsigned size)
127
{
P
pbrook 已提交
128
    qemu_irq_lower(ferr_irq);
129 130
}

131 132
static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size)
{
133
    return 0xffffffffffffffffULL;
134 135
}

B
bellard 已提交
136 137 138
/* TSC handling */
uint64_t cpu_get_tsc(CPUX86State *env)
{
139
    return cpu_get_ticks();
B
bellard 已提交
140 141
}

B
bellard 已提交
142
/* SMM support */
143 144 145 146 147 148 149 150 151 152 153 154

static cpu_set_smm_t smm_set;
static void *smm_arg;

void cpu_smm_register(cpu_set_smm_t callback, void *arg)
{
    assert(smm_set == NULL);
    assert(smm_arg == NULL);
    smm_set = callback;
    smm_arg = arg;
}

A
Andreas Färber 已提交
155
void cpu_smm_update(CPUX86State *env)
B
bellard 已提交
156
{
157 158
    if (smm_set && smm_arg && env == first_cpu)
        smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
B
bellard 已提交
159 160 161
}


B
bellard 已提交
162
/* IRQ handling */
A
Andreas Färber 已提交
163
int cpu_get_pic_interrupt(CPUX86State *env)
B
bellard 已提交
164 165 166
{
    int intno;

167
    intno = apic_get_interrupt(env->apic_state);
B
bellard 已提交
168 169 170 171
    if (intno >= 0) {
        return intno;
    }
    /* read the irq from the PIC */
172
    if (!apic_accept_pic_intr(env->apic_state)) {
173
        return -1;
174
    }
175

B
bellard 已提交
176 177 178 179
    intno = pic_read_irq(isa_pic);
    return intno;
}

P
pbrook 已提交
180
static void pic_irq_request(void *opaque, int irq, int level)
B
bellard 已提交
181
{
A
Andreas Färber 已提交
182
    CPUX86State *env = first_cpu;
183

B
Blue Swirl 已提交
184
    DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
A
aurel32 已提交
185 186
    if (env->apic_state) {
        while (env) {
187 188 189
            if (apic_accept_pic_intr(env->apic_state)) {
                apic_deliver_pic_intr(env->apic_state, level);
            }
A
aurel32 已提交
190 191 192
            env = env->next_cpu;
        }
    } else {
193 194
        CPUState *cs = CPU(x86_env_get_cpu(env));
        if (level) {
195
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
196 197 198
        } else {
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
        }
199
    }
B
bellard 已提交
200 201
}

B
bellard 已提交
202 203
/* PC cmos mappings */

B
bellard 已提交
204 205
#define REG_EQUIPMENT_BYTE          0x14

206
static int cmos_get_fd_drive_type(FDriveType fd0)
207 208 209 210
{
    int val;

    switch (fd0) {
211
    case FDRIVE_DRV_144:
212 213 214
        /* 1.44 Mb 3"5 drive */
        val = 4;
        break;
215
    case FDRIVE_DRV_288:
216 217 218
        /* 2.88 Mb 3"5 drive */
        val = 5;
        break;
219
    case FDRIVE_DRV_120:
220 221 222
        /* 1.2 Mb 5"5 drive */
        val = 2;
        break;
223
    case FDRIVE_DRV_NONE:
224 225 226 227 228 229 230
    default:
        val = 0;
        break;
    }
    return val;
}

231 232
static void cmos_init_hd(ISADevice *s, int type_ofs, int info_ofs,
                         int16_t cylinders, int8_t heads, int8_t sectors)
B
bellard 已提交
233 234 235 236 237 238 239 240 241 242 243 244 245
{
    rtc_set_memory(s, type_ofs, 47);
    rtc_set_memory(s, info_ofs, cylinders);
    rtc_set_memory(s, info_ofs + 1, cylinders >> 8);
    rtc_set_memory(s, info_ofs + 2, heads);
    rtc_set_memory(s, info_ofs + 3, 0xff);
    rtc_set_memory(s, info_ofs + 4, 0xff);
    rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3));
    rtc_set_memory(s, info_ofs + 6, cylinders);
    rtc_set_memory(s, info_ofs + 7, cylinders >> 8);
    rtc_set_memory(s, info_ofs + 8, sectors);
}

246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
/* convert boot_device letter to something recognizable by the bios */
static int boot_device2nibble(char boot_device)
{
    switch(boot_device) {
    case 'a':
    case 'b':
        return 0x01; /* floppy boot */
    case 'c':
        return 0x02; /* hard drive boot */
    case 'd':
        return 0x03; /* CD-ROM boot */
    case 'n':
        return 0x04; /* Network boot */
    }
    return 0;
}

263
static int set_boot_dev(ISADevice *s, const char *boot_device, int fd_bootchk)
264 265 266 267 268 269 270
{
#define PC_MAX_BOOT_DEVICES 3
    int nbds, bds[3] = { 0, };
    int i;

    nbds = strlen(boot_device);
    if (nbds > PC_MAX_BOOT_DEVICES) {
271
        error_report("Too many boot devices for PC");
272 273 274 275 276
        return(1);
    }
    for (i = 0; i < nbds; i++) {
        bds[i] = boot_device2nibble(boot_device[i]);
        if (bds[i] == 0) {
277 278
            error_report("Invalid boot device for PC: '%c'",
                         boot_device[i]);
279 280 281 282
            return(1);
        }
    }
    rtc_set_memory(s, 0x3d, (bds[1] << 4) | bds[0]);
283
    rtc_set_memory(s, 0x38, (bds[2] << 4) | (fd_bootchk ? 0x0 : 0x1));
284 285 286
    return(0);
}

287 288 289 290 291
static int pc_boot_set(void *opaque, const char *boot_device)
{
    return set_boot_dev(opaque, boot_device, 0);
}

292 293
typedef struct pc_cmos_init_late_arg {
    ISADevice *rtc_state;
294
    BusState *idebus[2];
295 296 297 298 299 300
} pc_cmos_init_late_arg;

static void pc_cmos_init_late(void *opaque)
{
    pc_cmos_init_late_arg *arg = opaque;
    ISADevice *s = arg->rtc_state;
301 302
    int16_t cylinders;
    int8_t heads, sectors;
303
    int val;
304
    int i, trans;
305

306 307 308 309 310 311 312 313 314 315 316 317
    val = 0;
    if (ide_get_geometry(arg->idebus[0], 0,
                         &cylinders, &heads, &sectors) >= 0) {
        cmos_init_hd(s, 0x19, 0x1b, cylinders, heads, sectors);
        val |= 0xf0;
    }
    if (ide_get_geometry(arg->idebus[0], 1,
                         &cylinders, &heads, &sectors) >= 0) {
        cmos_init_hd(s, 0x1a, 0x24, cylinders, heads, sectors);
        val |= 0x0f;
    }
    rtc_set_memory(s, 0x12, val);
318 319 320

    val = 0;
    for (i = 0; i < 4; i++) {
321 322 323 324 325 326
        /* NOTE: ide_get_geometry() returns the physical
           geometry.  It is always such that: 1 <= sects <= 63, 1
           <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
           geometry can be different if a translation is done. */
        if (ide_get_geometry(arg->idebus[i / 2], i % 2,
                             &cylinders, &heads, &sectors) >= 0) {
327 328 329
            trans = ide_get_bios_chs_trans(arg->idebus[i / 2], i % 2) - 1;
            assert((trans & ~3) == 0);
            val |= trans << (i * 2);
330 331 332 333 334 335 336
        }
    }
    rtc_set_memory(s, 0x39, val);

    qemu_unregister_reset(pc_cmos_init_late, opaque);
}

337
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
338
                  const char *boot_device,
K
Kevin Wolf 已提交
339
                  ISADevice *floppy, BusState *idebus0, BusState *idebus1,
B
Blue Swirl 已提交
340
                  ISADevice *s)
B
bellard 已提交
341
{
342
    int val, nb, i;
343
    FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
344
    static pc_cmos_init_late_arg arg;
B
bellard 已提交
345 346

    /* various important CMOS locations needed by PC/Bochs bios */
B
bellard 已提交
347 348

    /* memory size */
349 350
    /* base memory (first MiB) */
    val = MIN(ram_size / 1024, 640);
B
bellard 已提交
351 352
    rtc_set_memory(s, 0x15, val);
    rtc_set_memory(s, 0x16, val >> 8);
353 354 355 356 357 358
    /* extended memory (next 64MiB) */
    if (ram_size > 1024 * 1024) {
        val = (ram_size - 1024 * 1024) / 1024;
    } else {
        val = 0;
    }
B
bellard 已提交
359 360
    if (val > 65535)
        val = 65535;
B
bellard 已提交
361 362 363 364
    rtc_set_memory(s, 0x17, val);
    rtc_set_memory(s, 0x18, val >> 8);
    rtc_set_memory(s, 0x30, val);
    rtc_set_memory(s, 0x31, val >> 8);
365 366 367 368
    /* memory between 16MiB and 4GiB */
    if (ram_size > 16 * 1024 * 1024) {
        val = (ram_size - 16 * 1024 * 1024) / 65536;
    } else {
B
bellard 已提交
369
        val = 0;
370
    }
B
bellard 已提交
371 372
    if (val > 65535)
        val = 65535;
B
bellard 已提交
373 374
    rtc_set_memory(s, 0x34, val);
    rtc_set_memory(s, 0x35, val >> 8);
375 376 377 378 379
    /* memory above 4GiB */
    val = above_4g_mem_size / 65536;
    rtc_set_memory(s, 0x5b, val);
    rtc_set_memory(s, 0x5c, val >> 8);
    rtc_set_memory(s, 0x5d, val >> 16);
380

A
aurel32 已提交
381 382 383
    /* set the number of CPU */
    rtc_set_memory(s, 0x5f, smp_cpus - 1);

384
    /* set boot devices, and disable floppy signature check if requested */
385
    if (set_boot_dev(s, boot_device, fd_bootchk)) {
386 387
        exit(1);
    }
B
bellard 已提交
388

B
bellard 已提交
389
    /* floppy type */
K
Kevin Wolf 已提交
390 391
    if (floppy) {
        for (i = 0; i < 2; i++) {
392
            fd_type[i] = isa_fdc_get_drive_type(floppy, i);
B
Blue Swirl 已提交
393 394 395 396
        }
    }
    val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |
        cmos_get_fd_drive_type(fd_type[1]);
B
bellard 已提交
397
    rtc_set_memory(s, 0x10, val);
398

B
bellard 已提交
399
    val = 0;
B
bellard 已提交
400
    nb = 0;
B
Blue Swirl 已提交
401
    if (fd_type[0] < FDRIVE_DRV_NONE) {
B
bellard 已提交
402
        nb++;
403
    }
B
Blue Swirl 已提交
404
    if (fd_type[1] < FDRIVE_DRV_NONE) {
B
bellard 已提交
405
        nb++;
406
    }
B
bellard 已提交
407 408 409 410
    switch (nb) {
    case 0:
        break;
    case 1:
B
bellard 已提交
411
        val |= 0x01; /* 1 drive, ready for boot */
B
bellard 已提交
412 413
        break;
    case 2:
B
bellard 已提交
414
        val |= 0x41; /* 2 drives, ready for boot */
B
bellard 已提交
415 416
        break;
    }
B
bellard 已提交
417 418 419 420
    val |= 0x02; /* FPU is there */
    val |= 0x04; /* PS/2 mouse installed */
    rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);

B
bellard 已提交
421
    /* hard drives */
422
    arg.rtc_state = s;
423 424
    arg.idebus[0] = idebus0;
    arg.idebus[1] = idebus1;
425
    qemu_register_reset(pc_cmos_init_late, &arg);
B
bellard 已提交
426 427
}

428 429 430
/* port 92 stuff: could be split off */
typedef struct Port92State {
    ISADevice dev;
431
    MemoryRegion io;
432 433 434 435
    uint8_t outport;
    qemu_irq *a20_out;
} Port92State;

436 437
static void port92_write(void *opaque, hwaddr addr, uint64_t val,
                         unsigned size)
438 439 440 441 442 443 444 445 446 447 448
{
    Port92State *s = opaque;

    DPRINTF("port92: write 0x%02x\n", val);
    s->outport = val;
    qemu_set_irq(*s->a20_out, (val >> 1) & 1);
    if (val & 1) {
        qemu_system_reset_request();
    }
}

449 450
static uint64_t port92_read(void *opaque, hwaddr addr,
                            unsigned size)
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
{
    Port92State *s = opaque;
    uint32_t ret;

    ret = s->outport;
    DPRINTF("port92: read 0x%02x\n", ret);
    return ret;
}

static void port92_init(ISADevice *dev, qemu_irq *a20_out)
{
    Port92State *s = DO_UPCAST(Port92State, dev, dev);

    s->a20_out = a20_out;
}

static const VMStateDescription vmstate_port92_isa = {
    .name = "port92",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField []) {
        VMSTATE_UINT8(outport, Port92State),
        VMSTATE_END_OF_LIST()
    }
};

static void port92_reset(DeviceState *d)
{
    Port92State *s = container_of(d, Port92State, dev.qdev);

    s->outport &= ~1;
}

485
static const MemoryRegionOps port92_ops = {
486 487 488 489 490 491 492
    .read = port92_read,
    .write = port92_write,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
493 494
};

495 496 497 498
static int port92_initfn(ISADevice *dev)
{
    Port92State *s = DO_UPCAST(Port92State, dev, dev);

499 500 501
    memory_region_init_io(&s->io, &port92_ops, s, "port92", 1);
    isa_register_ioport(dev, &s->io, 0x92);

502 503 504 505
    s->outport = 0;
    return 0;
}

506 507
static void port92_class_initfn(ObjectClass *klass, void *data)
{
508
    DeviceClass *dc = DEVICE_CLASS(klass);
509 510
    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
    ic->init = port92_initfn;
511 512 513
    dc->no_user = 1;
    dc->reset = port92_reset;
    dc->vmsd = &vmstate_port92_isa;
514 515
}

516
static const TypeInfo port92_info = {
517 518 519 520
    .name          = "port92",
    .parent        = TYPE_ISA_DEVICE,
    .instance_size = sizeof(Port92State),
    .class_init    = port92_class_initfn,
521 522
};

A
Andreas Färber 已提交
523
static void port92_register_types(void)
524
{
525
    type_register_static(&port92_info);
526
}
A
Andreas Färber 已提交
527 528

type_init(port92_register_types)
529

B
Blue Swirl 已提交
530
static void handle_a20_line_change(void *opaque, int irq, int level)
531
{
532
    X86CPU *cpu = opaque;
B
bellard 已提交
533

B
Blue Swirl 已提交
534
    /* XXX: send to all CPUs ? */
535
    /* XXX: add logic to handle multiple A20 line sources */
536
    x86_cpu_set_a20(cpu, level);
B
bellard 已提交
537 538
}

J
Jes Sorensen 已提交
539 540
int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
{
541
    int index = le32_to_cpu(e820_table.count);
J
Jes Sorensen 已提交
542 543 544 545
    struct e820_entry *entry;

    if (index >= E820_NR_ENTRIES)
        return -EBUSY;
546
    entry = &e820_table.entry[index++];
J
Jes Sorensen 已提交
547

548 549 550
    entry->address = cpu_to_le64(address);
    entry->length = cpu_to_le64(length);
    entry->type = cpu_to_le32(type);
J
Jes Sorensen 已提交
551

552 553
    e820_table.count = cpu_to_le32(index);
    return index;
J
Jes Sorensen 已提交
554 555
}

556 557 558 559 560 561 562 563 564 565 566 567
/* Calculates the limit to CPU APIC ID values
 *
 * This function returns the limit for the APIC ID value, so that all
 * CPU APIC IDs are < pc_apic_id_limit().
 *
 * This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
 */
static unsigned int pc_apic_id_limit(unsigned int max_cpus)
{
    return x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
}

A
Alexander Graf 已提交
568
static void *bochs_bios_init(void)
B
bellard 已提交
569
{
570
    void *fw_cfg;
571 572
    uint8_t *smbios_table;
    size_t smbios_len;
573 574
    uint64_t *numa_fw_cfg;
    int i, j;
575
    unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
576 577

    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
    /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
     *
     * SeaBIOS needs FW_CFG_MAX_CPUS for CPU hotplug, but the CPU hotplug
     * QEMU<->SeaBIOS interface is not based on the "CPU index", but on the APIC
     * ID of hotplugged CPUs[1]. This means that FW_CFG_MAX_CPUS is not the
     * "maximum number of CPUs", but the "limit to the APIC ID values SeaBIOS
     * may see".
     *
     * So, this means we must not use max_cpus, here, but the maximum possible
     * APIC ID value, plus one.
     *
     * [1] The only kind of "CPU identifier" used between SeaBIOS and QEMU is
     *     the APIC ID, not the "CPU index"
     */
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)apic_id_limit);
593
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
594
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
595 596
    fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
                     acpi_tables, acpi_tables_len);
597
    fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
598 599 600 601 602

    smbios_table = smbios_get_table(&smbios_len);
    if (smbios_table)
        fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                         smbios_table, smbios_len);
603 604
    fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
                     &e820_table, sizeof(e820_table));
605

606
    fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_cfg, sizeof(hpet_cfg));
607 608 609 610
    /* allocate memory for the NUMA channel: one (64bit) word for the number
     * of nodes, one word for each VCPU->node and one word for each node to
     * hold the amount of memory.
     */
611
    numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + nb_numa_nodes);
612
    numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
613
    for (i = 0; i < max_cpus; i++) {
614 615
        unsigned int apic_id = x86_cpu_apic_id_from_index(i);
        assert(apic_id < apic_id_limit);
616
        for (j = 0; j < nb_numa_nodes; j++) {
617
            if (test_bit(i, node_cpumask[j])) {
618
                numa_fw_cfg[apic_id + 1] = cpu_to_le64(j);
619 620 621 622 623
                break;
            }
        }
    }
    for (i = 0; i < nb_numa_nodes; i++) {
624
        numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(node_mem[i]);
625
    }
626
    fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
627 628
                     (1 + apic_id_limit + nb_numa_nodes) *
                     sizeof(*numa_fw_cfg));
A
Alexander Graf 已提交
629 630

    return fw_cfg;
B
bellard 已提交
631 632
}

T
ths 已提交
633 634 635 636 637 638 639 640 641 642 643 644 645 646
static long get_file_size(FILE *f)
{
    long where, size;

    /* XXX: on Unix systems, using fstat() probably makes more sense */

    where = ftell(f);
    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, where, SEEK_SET);

    return size;
}

A
Alexander Graf 已提交
647
static void load_linux(void *fw_cfg,
648
                       const char *kernel_filename,
T
ths 已提交
649
		       const char *initrd_filename,
G
Glauber Costa 已提交
650
		       const char *kernel_cmdline,
A
Avi Kivity 已提交
651
                       hwaddr max_ram_size)
T
ths 已提交
652 653
{
    uint16_t protocol;
P
Paul Brook 已提交
654
    int setup_size, kernel_size, initrd_size = 0, cmdline_size;
T
ths 已提交
655
    uint32_t initrd_max;
656
    uint8_t header[8192], *setup, *kernel, *initrd_data;
A
Avi Kivity 已提交
657
    hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
658
    FILE *f;
P
Pascal Terjan 已提交
659
    char *vmode;
T
ths 已提交
660 661 662 663 664 665 666

    /* Align to 16 bytes as a paranoia measure */
    cmdline_size = (strlen(kernel_cmdline)+16) & ~15;

    /* load the kernel header */
    f = fopen(kernel_filename, "rb");
    if (!f || !(kernel_size = get_file_size(f)) ||
A
Alexander Graf 已提交
667 668
	fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) !=
	MIN(ARRAY_SIZE(header), kernel_size)) {
669 670
	fprintf(stderr, "qemu: could not load kernel '%s': %s\n",
		kernel_filename, strerror(errno));
T
ths 已提交
671 672 673 674
	exit(1);
    }

    /* kernel protocol version */
B
bellard 已提交
675
#if 0
T
ths 已提交
676
    fprintf(stderr, "header magic: %#x\n", ldl_p(header+0x202));
B
bellard 已提交
677
#endif
T
ths 已提交
678 679
    if (ldl_p(header+0x202) == 0x53726448)
	protocol = lduw_p(header+0x206);
A
Alexander Graf 已提交
680 681 682
    else {
	/* This looks like a multiboot kernel. If it is, let's stop
	   treating it like a Linux kernel. */
683 684
        if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename,
                           kernel_cmdline, kernel_size, header))
B
Blue Swirl 已提交
685
            return;
T
ths 已提交
686
	protocol = 0;
A
Alexander Graf 已提交
687
    }
T
ths 已提交
688 689 690

    if (protocol < 0x200 || !(header[0x211] & 0x01)) {
	/* Low kernel */
691 692 693
	real_addr    = 0x90000;
	cmdline_addr = 0x9a000 - cmdline_size;
	prot_addr    = 0x10000;
T
ths 已提交
694 695
    } else if (protocol < 0x202) {
	/* High but ancient kernel */
696 697 698
	real_addr    = 0x90000;
	cmdline_addr = 0x9a000 - cmdline_size;
	prot_addr    = 0x100000;
T
ths 已提交
699 700
    } else {
	/* High and recent kernel */
701 702 703
	real_addr    = 0x10000;
	cmdline_addr = 0x20000;
	prot_addr    = 0x100000;
T
ths 已提交
704 705
    }

B
bellard 已提交
706
#if 0
T
ths 已提交
707
    fprintf(stderr,
708 709 710
	    "qemu: real_addr     = 0x" TARGET_FMT_plx "\n"
	    "qemu: cmdline_addr  = 0x" TARGET_FMT_plx "\n"
	    "qemu: prot_addr     = 0x" TARGET_FMT_plx "\n",
711 712 713
	    real_addr,
	    cmdline_addr,
	    prot_addr);
B
bellard 已提交
714
#endif
T
ths 已提交
715 716 717 718 719 720 721

    /* highest address for loading the initrd */
    if (protocol >= 0x203)
	initrd_max = ldl_p(header+0x22c);
    else
	initrd_max = 0x37ffffff;

G
Glauber Costa 已提交
722 723
    if (initrd_max >= max_ram_size-ACPI_DATA_SIZE)
    	initrd_max = max_ram_size-ACPI_DATA_SIZE-1;
T
ths 已提交
724

725 726
    fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
    fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline)+1);
727
    fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
T
ths 已提交
728 729

    if (protocol >= 0x202) {
730
	stl_p(header+0x228, cmdline_addr);
T
ths 已提交
731 732 733 734 735
    } else {
	stw_p(header+0x20, 0xA33F);
	stw_p(header+0x22, cmdline_addr-real_addr);
    }

P
Pascal Terjan 已提交
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
    /* handle vga= parameter */
    vmode = strstr(kernel_cmdline, "vga=");
    if (vmode) {
        unsigned int video_mode;
        /* skip "vga=" */
        vmode += 4;
        if (!strncmp(vmode, "normal", 6)) {
            video_mode = 0xffff;
        } else if (!strncmp(vmode, "ext", 3)) {
            video_mode = 0xfffe;
        } else if (!strncmp(vmode, "ask", 3)) {
            video_mode = 0xfffd;
        } else {
            video_mode = strtol(vmode, NULL, 0);
        }
        stw_p(header+0x1fa, video_mode);
    }

T
ths 已提交
754
    /* loader type */
S
Stefan Weil 已提交
755
    /* High nybble = B reserved for QEMU; low nybble is revision number.
T
ths 已提交
756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773
       If this code is substantially changed, you may want to consider
       incrementing the revision. */
    if (protocol >= 0x200)
	header[0x210] = 0xB0;

    /* heap */
    if (protocol >= 0x201) {
	header[0x211] |= 0x80;	/* CAN_USE_HEAP */
	stw_p(header+0x224, cmdline_addr-real_addr-0x200);
    }

    /* load initrd */
    if (initrd_filename) {
	if (protocol < 0x200) {
	    fprintf(stderr, "qemu: linux kernel too old to load a ram disk\n");
	    exit(1);
	}

774
	initrd_size = get_image_size(initrd_filename);
M
M. Mohan Kumar 已提交
775 776 777 778 779 780
        if (initrd_size < 0) {
            fprintf(stderr, "qemu: error reading initrd %s\n",
                    initrd_filename);
            exit(1);
        }

781
        initrd_addr = (initrd_max-initrd_size) & ~4095;
782

783
        initrd_data = g_malloc(initrd_size);
784 785 786 787 788
        load_image(initrd_filename, initrd_data);

        fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
        fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
        fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, initrd_size);
T
ths 已提交
789

790
	stl_p(header+0x218, initrd_addr);
T
ths 已提交
791 792 793
	stl_p(header+0x21c, initrd_size);
    }

794
    /* load kernel and setup */
T
ths 已提交
795 796 797 798
    setup_size = header[0x1f1];
    if (setup_size == 0)
	setup_size = 4;
    setup_size = (setup_size+1)*512;
799
    kernel_size -= setup_size;
T
ths 已提交
800

801 802
    setup  = g_malloc(setup_size);
    kernel = g_malloc(kernel_size);
803
    fseek(f, 0, SEEK_SET);
804 805 806 807 808 809 810 811
    if (fread(setup, 1, setup_size, f) != setup_size) {
        fprintf(stderr, "fread() failed\n");
        exit(1);
    }
    if (fread(kernel, 1, kernel_size, f) != kernel_size) {
        fprintf(stderr, "fread() failed\n");
        exit(1);
    }
T
ths 已提交
812
    fclose(f);
813
    memcpy(setup, header, MIN(sizeof(header), setup_size));
814 815 816 817 818 819 820 821 822

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);

    fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
    fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
    fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);

G
Gleb Natapov 已提交
823 824
    option_rom[nb_option_roms].name = "linuxboot.bin";
    option_rom[nb_option_roms].bootindex = 0;
825
    nb_option_roms++;
T
ths 已提交
826 827
}

B
bellard 已提交
828 829
#define NE2000_NB_MAX 6

B
Blue Swirl 已提交
830 831 832
static const int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360,
                                              0x280, 0x380 };
static const int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
B
bellard 已提交
833

B
Blue Swirl 已提交
834 835
static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
836

837
void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
838 839 840 841 842
{
    static int nb_ne2k = 0;

    if (nb_ne2k == NE2000_NB_MAX)
        return;
843
    isa_ne2000_init(bus, ne2000_io[nb_ne2k],
G
Gerd Hoffmann 已提交
844
                    ne2000_irq[nb_ne2k], nd);
845 846 847
    nb_ne2k++;
}

B
Blue Swirl 已提交
848
DeviceState *cpu_get_current_apic(void)
849 850 851 852 853 854 855 856
{
    if (cpu_single_env) {
        return cpu_single_env->apic_state;
    } else {
        return NULL;
    }
}

857
void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
B
Blue Swirl 已提交
858
{
859
    X86CPU *cpu = opaque;
B
Blue Swirl 已提交
860 861

    if (level) {
862
        cpu_interrupt(CPU(cpu), CPU_INTERRUPT_SMI);
B
Blue Swirl 已提交
863 864 865
    }
}

866
void pc_cpus_init(const char *cpu_model)
867 868 869 870 871 872 873 874 875 876 877 878
{
    int i;

    /* init CPUs */
    if (cpu_model == NULL) {
#ifdef TARGET_X86_64
        cpu_model = "qemu64";
#else
        cpu_model = "qemu32";
#endif
    }

879 880 881 882
    for (i = 0; i < smp_cpus; i++) {
        if (!cpu_x86_init(cpu_model)) {
            exit(1);
        }
883 884 885
    }
}

G
Gerd Hoffmann 已提交
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
void pc_acpi_init(const char *default_dsdt)
{
    char *filename = NULL, *arg = NULL;

    if (acpi_tables != NULL) {
        /* manually set via -acpitable, leave it alone */
        return;
    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, default_dsdt);
    if (filename == NULL) {
        fprintf(stderr, "WARNING: failed to find %s\n", default_dsdt);
        return;
    }

    arg = g_strdup_printf("file=%s", filename);
    if (acpi_table_add(arg) != 0) {
        fprintf(stderr, "WARNING: failed to load %s\n", filename);
    }
    g_free(arg);
    g_free(filename);
}

909
void *pc_memory_init(MemoryRegion *system_memory,
A
Avi Kivity 已提交
910
                    const char *kernel_filename,
911 912
                    const char *kernel_cmdline,
                    const char *initrd_filename,
913
                    ram_addr_t below_4g_mem_size,
A
Avi Kivity 已提交
914
                    ram_addr_t above_4g_mem_size,
915
                    MemoryRegion *rom_memory,
A
Avi Kivity 已提交
916
                    MemoryRegion **ram_memory)
B
bellard 已提交
917
{
918 919
    int linux_boot, i;
    MemoryRegion *ram, *option_rom_mr;
920
    MemoryRegion *ram_below_4g, *ram_above_4g;
921
    void *fw_cfg;
922

B
bellard 已提交
923 924
    linux_boot = (kernel_filename != NULL);

925
    /* Allocate RAM.  We allocate it as a single memory region and use
D
Dong Xu Wang 已提交
926
     * aliases to address portions of it, mostly for backwards compatibility
927 928
     * with older qemus that used qemu_ram_alloc().
     */
929
    ram = g_malloc(sizeof(*ram));
930
    memory_region_init_ram(ram, "pc.ram",
931
                           below_4g_mem_size + above_4g_mem_size);
932
    vmstate_register_ram_global(ram);
A
Avi Kivity 已提交
933
    *ram_memory = ram;
934
    ram_below_4g = g_malloc(sizeof(*ram_below_4g));
935 936 937
    memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
                             0, below_4g_mem_size);
    memory_region_add_subregion(system_memory, 0, ram_below_4g);
938
    if (above_4g_mem_size > 0) {
939
        ram_above_4g = g_malloc(sizeof(*ram_above_4g));
940 941 942 943
        memory_region_init_alias(ram_above_4g, "ram-above-4g", ram,
                                 below_4g_mem_size, above_4g_mem_size);
        memory_region_add_subregion(system_memory, 0x100000000ULL,
                                    ram_above_4g);
944
    }
945

946 947 948

    /* Initialize PC system firmware */
    pc_system_firmware_init(rom_memory);
949

950
    option_rom_mr = g_malloc(sizeof(*option_rom_mr));
951 952
    memory_region_init_ram(option_rom_mr, "pc.rom", PC_ROM_SIZE);
    vmstate_register_ram_global(option_rom_mr);
953
    memory_region_add_subregion_overlap(rom_memory,
954 955 956
                                        PC_ROM_MIN_VGA,
                                        option_rom_mr,
                                        1);
957

A
Alexander Graf 已提交
958
    fw_cfg = bochs_bios_init();
G
Gerd Hoffmann 已提交
959
    rom_set_fw(fw_cfg);
A
Alexander Graf 已提交
960

961
    if (linux_boot) {
962
        load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
963 964 965
    }

    for (i = 0; i < nb_option_roms; i++) {
G
Gleb Natapov 已提交
966
        rom_add_option(option_rom[i].name, option_rom[i].bootindex);
967
    }
968
    return fw_cfg;
969 970
}

971 972 973 974 975
qemu_irq *pc_allocate_cpu_irq(void)
{
    return qemu_allocate_irqs(pic_irq_request, NULL, 1);
}

976
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
977
{
978 979
    DeviceState *dev = NULL;

980 981 982 983 984 985
    if (pci_bus) {
        PCIDevice *pcidev = pci_vga_init(pci_bus);
        dev = pcidev ? &pcidev->qdev : NULL;
    } else if (isa_bus) {
        ISADevice *isadev = isa_vga_init(isa_bus);
        dev = isadev ? &isadev->qdev : NULL;
986
    }
987
    return dev;
988 989
}

B
Blue Swirl 已提交
990 991
static void cpu_request_exit(void *opaque, int irq, int level)
{
A
Andreas Färber 已提交
992
    CPUX86State *env = cpu_single_env;
B
Blue Swirl 已提交
993 994 995 996 997 998

    if (env && level) {
        cpu_exit(env);
    }
}

J
Julien Grall 已提交
999 1000
static const MemoryRegionOps ioport80_io_ops = {
    .write = ioport80_write,
1001
    .read = ioport80_read,
J
Julien Grall 已提交
1002 1003 1004 1005 1006 1007 1008 1009 1010
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
};

static const MemoryRegionOps ioportF0_io_ops = {
    .write = ioportF0_write,
1011
    .read = ioportF0_read,
J
Julien Grall 已提交
1012 1013 1014 1015 1016 1017 1018
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
};

1019
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
1020
                          ISADevice **rtc_state,
K
Kevin Wolf 已提交
1021
                          ISADevice **floppy,
1022
                          bool no_vmport)
1023 1024 1025
{
    int i;
    DriveInfo *fd[MAX_FD];
1026 1027 1028
    DeviceState *hpet = NULL;
    int pit_isa_irq = 0;
    qemu_irq pit_alt_irq = NULL;
1029
    qemu_irq rtc_irq = NULL;
B
Blue Swirl 已提交
1030
    qemu_irq *a20_line;
1031
    ISADevice *i8042, *port92, *vmmouse, *pit = NULL;
B
Blue Swirl 已提交
1032
    qemu_irq *cpu_exit_irq;
J
Julien Grall 已提交
1033 1034
    MemoryRegion *ioport80_io = g_new(MemoryRegion, 1);
    MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
1035

J
Julien Grall 已提交
1036 1037
    memory_region_init_io(ioport80_io, &ioport80_io_ops, NULL, "ioport80", 1);
    memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io);
1038

J
Julien Grall 已提交
1039 1040
    memory_region_init_io(ioportF0_io, &ioportF0_io_ops, NULL, "ioportF0", 1);
    memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io);
1041

1042 1043 1044 1045 1046 1047 1048
    /*
     * Check if an HPET shall be created.
     *
     * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT
     * when the HPET wants to take over. Thus we have to disable the latter.
     */
    if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) {
1049
        hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL);
J
Jan Kiszka 已提交
1050

B
Blue Swirl 已提交
1051
        if (hpet) {
J
Jan Kiszka 已提交
1052
            for (i = 0; i < GSI_NUM_PINS; i++) {
1053
                sysbus_connect_irq(SYS_BUS_DEVICE(hpet), i, gsi[i]);
B
Blue Swirl 已提交
1054
            }
1055 1056 1057
            pit_isa_irq = -1;
            pit_alt_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_PIT_INT);
            rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT);
J
Jan Kiszka 已提交
1058
        }
1059
    }
1060
    *rtc_state = rtc_init(isa_bus, 2000, rtc_irq);
1061 1062 1063

    qemu_register_boot_set(pc_boot_set, *rtc_state);

1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
    if (!xen_enabled()) {
        if (kvm_irqchip_in_kernel()) {
            pit = kvm_pit_init(isa_bus, 0x40);
        } else {
            pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq);
        }
        if (hpet) {
            /* connect PIT to output control line of the HPET */
            qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(&pit->qdev, 0));
        }
        pcspk_init(isa_bus, pit);
1075
    }
1076 1077 1078

    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
        if (serial_hds[i]) {
1079
            serial_isa_init(isa_bus, i, serial_hds[i]);
1080 1081 1082 1083 1084
        }
    }

    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
        if (parallel_hds[i]) {
1085
            parallel_init(isa_bus, i, parallel_hds[i]);
1086 1087 1088
        }
    }

1089 1090
    a20_line = qemu_allocate_irqs(handle_a20_line_change,
                                  x86_env_get_cpu(first_cpu), 2);
1091
    i8042 = isa_create_simple(isa_bus, "i8042");
1092
    i8042_setup_a20_line(i8042, &a20_line[0]);
1093
    if (!no_vmport) {
1094 1095
        vmport_init(isa_bus);
        vmmouse = isa_try_create(isa_bus, "vmmouse");
1096 1097 1098
    } else {
        vmmouse = NULL;
    }
B
Blue Swirl 已提交
1099 1100
    if (vmmouse) {
        qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042);
J
Jan Kiszka 已提交
1101
        qdev_init_nofail(&vmmouse->qdev);
B
Blue Swirl 已提交
1102
    }
1103
    port92 = isa_create_simple(isa_bus, "port92");
1104
    port92_init(port92, &a20_line[1]);
B
Blue Swirl 已提交
1105

B
Blue Swirl 已提交
1106 1107
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
    DMA_init(0, cpu_exit_irq);
1108 1109 1110 1111

    for(i = 0; i < MAX_FD; i++) {
        fd[i] = drive_get(IF_FLOPPY, 0, i);
    }
1112
    *floppy = fdctrl_init_isa(isa_bus, fd);
1113 1114
}

1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
{
    int i;

    for (i = 0; i < nb_nics; i++) {
        NICInfo *nd = &nd_table[i];

        if (!pci_bus || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) {
            pc_init_ne2k_isa(isa_bus, nd);
        } else {
            pci_nic_init_nofail(nd, "e1000", NULL);
        }
    }
}

1130
void pc_pci_device_init(PCIBus *pci_bus)
1131 1132 1133 1134 1135 1136 1137 1138 1139
{
    int max_bus;
    int bus;

    max_bus = drive_get_max_bus(IF_SCSI);
    for (bus = 0; bus <= max_bus; bus++) {
        pci_create_simple(pci_bus, -1, "lsi53c895a");
    }
}
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156

void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
{
    DeviceState *dev;
    SysBusDevice *d;
    unsigned int i;

    if (kvm_irqchip_in_kernel()) {
        dev = qdev_create(NULL, "kvm-ioapic");
    } else {
        dev = qdev_create(NULL, "ioapic");
    }
    if (parent_name) {
        object_property_add_child(object_resolve_path(parent_name, NULL),
                                  "ioapic", OBJECT(dev), NULL);
    }
    qdev_init_nofail(dev);
1157
    d = SYS_BUS_DEVICE(dev);
1158 1159 1160 1161 1162 1163
    sysbus_mmio_map(d, 0, 0xfec00000);

    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
        gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
    }
}