pc.c 33.2 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
#include "hw/hw.h"
P
Paolo Bonzini 已提交
25 26 27 28
#include "hw/i386/pc.h"
#include "hw/char/serial.h"
#include "hw/i386/apic.h"
#include "hw/block/fdc.h"
29 30
#include "hw/ide.h"
#include "hw/pci/pci.h"
31
#include "monitor/monitor.h"
P
Paolo Bonzini 已提交
32 33 34
#include "hw/nvram/fw_cfg.h"
#include "hw/timer/hpet.h"
#include "hw/i386/smbios.h"
35
#include "hw/loader.h"
B
Blue Swirl 已提交
36
#include "elf.h"
37
#include "hw/multiboot.h"
P
Paolo Bonzini 已提交
38 39 40
#include "hw/timer/mc146818rtc.h"
#include "hw/timer/i8254.h"
#include "hw/audio/pcspk.h"
41 42
#include "hw/pci/msi.h"
#include "hw/sysbus.h"
43 44
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
45
#include "kvm_i386.h"
P
Paolo Bonzini 已提交
46
#include "hw/xen/xen.h"
47
#include "sysemu/blockdev.h"
P
Paolo Bonzini 已提交
48
#include "hw/block/block.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"
54
#include "qemu/config-file.h"
B
bellard 已提交
55

B
Blue Swirl 已提交
56 57 58 59 60 61 62 63 64 65
/* 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

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

75 76
#define IO_APIC_DEFAULT_ADDRESS 0xfec00000

J
Jes Sorensen 已提交
77 78 79 80 81 82
#define E820_NR_ENTRIES		16

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

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

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

J
Jan Kiszka 已提交
93
void gsi_handler(void *opaque, int n, int level)
94
{
J
Jan Kiszka 已提交
95
    GSIState *s = opaque;
96

J
Jan Kiszka 已提交
97 98 99
    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 已提交
100
    }
J
Jan Kiszka 已提交
101
    qemu_set_irq(s->ioapic_irq[n], level);
102
}
103

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

109 110
static uint64_t ioport80_read(void *opaque, hwaddr addr, unsigned size)
{
111
    return 0xffffffffffffffffULL;
112 113
}

114
/* MSDOS compatibility mode FPU exception support */
P
pbrook 已提交
115
static qemu_irq ferr_irq;
116 117 118 119 120 121

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

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

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

134 135
static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size)
{
136
    return 0xffffffffffffffffULL;
137 138
}

B
bellard 已提交
139 140 141
/* TSC handling */
uint64_t cpu_get_tsc(CPUX86State *env)
{
142
    return cpu_get_ticks();
B
bellard 已提交
143 144
}

B
bellard 已提交
145
/* SMM support */
146 147 148 149 150 151 152 153 154 155 156 157

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 已提交
158
void cpu_smm_update(CPUX86State *env)
B
bellard 已提交
159
{
160 161
    if (smm_set && smm_arg && env == first_cpu)
        smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
B
bellard 已提交
162 163 164
}


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

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

B
bellard 已提交
179 180 181 182
    intno = pic_read_irq(isa_pic);
    return intno;
}

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

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

B
bellard 已提交
205 206
/* PC cmos mappings */

B
bellard 已提交
207 208
#define REG_EQUIPMENT_BYTE          0x14

209
static int cmos_get_fd_drive_type(FDriveType fd0)
210 211 212 213
{
    int val;

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

234 235
static void cmos_init_hd(ISADevice *s, int type_ofs, int info_ofs,
                         int16_t cylinders, int8_t heads, int8_t sectors)
B
bellard 已提交
236 237 238 239 240 241 242 243 244 245 246 247 248
{
    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);
}

249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
/* 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;
}

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

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

290 291 292 293 294
static int pc_boot_set(void *opaque, const char *boot_device)
{
    return set_boot_dev(opaque, boot_device, 0);
}

295 296
typedef struct pc_cmos_init_late_arg {
    ISADevice *rtc_state;
297
    BusState *idebus[2];
298 299 300 301 302 303
} 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;
304 305
    int16_t cylinders;
    int8_t heads, sectors;
306
    int val;
307
    int i, trans;
308

309 310 311 312 313 314 315 316 317 318 319 320
    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);
321 322 323

    val = 0;
    for (i = 0; i < 4; i++) {
324 325 326 327 328 329
        /* 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) {
330 331 332
            trans = ide_get_bios_chs_trans(arg->idebus[i / 2], i % 2) - 1;
            assert((trans & ~3) == 0);
            val |= trans << (i * 2);
333 334 335 336 337 338 339
        }
    }
    rtc_set_memory(s, 0x39, val);

    qemu_unregister_reset(pc_cmos_init_late, opaque);
}

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

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

    /* memory size */
352 353
    /* base memory (first MiB) */
    val = MIN(ram_size / 1024, 640);
B
bellard 已提交
354 355
    rtc_set_memory(s, 0x15, val);
    rtc_set_memory(s, 0x16, val >> 8);
356 357 358 359 360 361
    /* extended memory (next 64MiB) */
    if (ram_size > 1024 * 1024) {
        val = (ram_size - 1024 * 1024) / 1024;
    } else {
        val = 0;
    }
B
bellard 已提交
362 363
    if (val > 65535)
        val = 65535;
B
bellard 已提交
364 365 366 367
    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);
368 369 370 371
    /* memory between 16MiB and 4GiB */
    if (ram_size > 16 * 1024 * 1024) {
        val = (ram_size - 16 * 1024 * 1024) / 65536;
    } else {
B
bellard 已提交
372
        val = 0;
373
    }
B
bellard 已提交
374 375
    if (val > 65535)
        val = 65535;
B
bellard 已提交
376 377
    rtc_set_memory(s, 0x34, val);
    rtc_set_memory(s, 0x35, val >> 8);
378 379 380 381 382
    /* 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);
383

A
aurel32 已提交
384 385 386
    /* set the number of CPU */
    rtc_set_memory(s, 0x5f, smp_cpus - 1);

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

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

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

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

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

439 440
static void port92_write(void *opaque, hwaddr addr, uint64_t val,
                         unsigned size)
441 442 443 444 445 446 447 448 449 450 451
{
    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();
    }
}

452 453
static uint64_t port92_read(void *opaque, hwaddr addr,
                            unsigned size)
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 485 486 487
{
    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;
}

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

498 499 500 501
static int port92_initfn(ISADevice *dev)
{
    Port92State *s = DO_UPCAST(Port92State, dev, dev);

502 503 504
    memory_region_init_io(&s->io, &port92_ops, s, "port92", 1);
    isa_register_ioport(dev, &s->io, 0x92);

505 506 507 508
    s->outport = 0;
    return 0;
}

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

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

A
Andreas Färber 已提交
526
static void port92_register_types(void)
527
{
528
    type_register_static(&port92_info);
529
}
A
Andreas Färber 已提交
530 531

type_init(port92_register_types)
532

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

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

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

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

551 552 553
    entry->address = cpu_to_le64(address);
    entry->length = cpu_to_le64(length);
    entry->type = cpu_to_le32(type);
J
Jes Sorensen 已提交
554

555 556
    e820_table.count = cpu_to_le32(index);
    return index;
J
Jes Sorensen 已提交
557 558
}

559 560 561 562 563 564 565 566 567 568 569 570
/* 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 已提交
571
static void *bochs_bios_init(void)
B
bellard 已提交
572
{
573
    void *fw_cfg;
574 575
    uint8_t *smbios_table;
    size_t smbios_len;
576 577
    uint64_t *numa_fw_cfg;
    int i, j;
578
    unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
579 580

    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
    /* 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);
596
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
597
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
598 599
    fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
                     acpi_tables, acpi_tables_len);
600
    fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
601 602 603 604 605

    smbios_table = smbios_get_table(&smbios_len);
    if (smbios_table)
        fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                         smbios_table, smbios_len);
606 607
    fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
                     &e820_table, sizeof(e820_table));
608

609
    fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_cfg, sizeof(hpet_cfg));
610 611 612 613
    /* 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.
     */
614
    numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + nb_numa_nodes);
615
    numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
616
    for (i = 0; i < max_cpus; i++) {
617 618
        unsigned int apic_id = x86_cpu_apic_id_from_index(i);
        assert(apic_id < apic_id_limit);
619
        for (j = 0; j < nb_numa_nodes; j++) {
620
            if (test_bit(i, node_cpumask[j])) {
621
                numa_fw_cfg[apic_id + 1] = cpu_to_le64(j);
622 623 624 625 626
                break;
            }
        }
    }
    for (i = 0; i < nb_numa_nodes; i++) {
627
        numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(node_mem[i]);
628
    }
629
    fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
630 631
                     (1 + apic_id_limit + nb_numa_nodes) *
                     sizeof(*numa_fw_cfg));
A
Alexander Graf 已提交
632 633

    return fw_cfg;
B
bellard 已提交
634 635
}

T
ths 已提交
636 637 638 639 640 641 642 643 644 645 646 647 648 649
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 已提交
650
static void load_linux(void *fw_cfg,
651
                       const char *kernel_filename,
L
liguang 已提交
652 653
                       const char *initrd_filename,
                       const char *kernel_cmdline,
A
Avi Kivity 已提交
654
                       hwaddr max_ram_size)
T
ths 已提交
655 656
{
    uint16_t protocol;
P
Paul Brook 已提交
657
    int setup_size, kernel_size, initrd_size = 0, cmdline_size;
T
ths 已提交
658
    uint32_t initrd_max;
659
    uint8_t header[8192], *setup, *kernel, *initrd_data;
A
Avi Kivity 已提交
660
    hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
661
    FILE *f;
P
Pascal Terjan 已提交
662
    char *vmode;
T
ths 已提交
663 664 665 666 667 668 669

    /* 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)) ||
L
liguang 已提交
670 671 672 673 674
        fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) !=
        MIN(ARRAY_SIZE(header), kernel_size)) {
        fprintf(stderr, "qemu: could not load kernel '%s': %s\n",
                kernel_filename, strerror(errno));
        exit(1);
T
ths 已提交
675 676 677
    }

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

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

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

    /* highest address for loading the initrd */
L
liguang 已提交
721 722 723 724 725
    if (protocol >= 0x203) {
        initrd_max = ldl_p(header+0x22c);
    } else {
        initrd_max = 0x37ffffff;
    }
T
ths 已提交
726

G
Glauber Costa 已提交
727 728
    if (initrd_max >= max_ram_size-ACPI_DATA_SIZE)
    	initrd_max = max_ram_size-ACPI_DATA_SIZE-1;
T
ths 已提交
729

730 731
    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);
732
    fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
T
ths 已提交
733 734

    if (protocol >= 0x202) {
L
liguang 已提交
735
        stl_p(header+0x228, cmdline_addr);
T
ths 已提交
736
    } else {
L
liguang 已提交
737 738
        stw_p(header+0x20, 0xA33F);
        stw_p(header+0x22, cmdline_addr-real_addr);
T
ths 已提交
739 740
    }

P
Pascal Terjan 已提交
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
    /* 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 已提交
759
    /* loader type */
S
Stefan Weil 已提交
760
    /* High nybble = B reserved for QEMU; low nybble is revision number.
T
ths 已提交
761 762
       If this code is substantially changed, you may want to consider
       incrementing the revision. */
L
liguang 已提交
763 764 765
    if (protocol >= 0x200) {
        header[0x210] = 0xB0;
    }
T
ths 已提交
766 767
    /* heap */
    if (protocol >= 0x201) {
L
liguang 已提交
768 769
        header[0x211] |= 0x80;	/* CAN_USE_HEAP */
        stw_p(header+0x224, cmdline_addr-real_addr-0x200);
T
ths 已提交
770 771 772 773
    }

    /* load initrd */
    if (initrd_filename) {
L
liguang 已提交
774 775 776 777
        if (protocol < 0x200) {
            fprintf(stderr, "qemu: linux kernel too old to load a ram disk\n");
            exit(1);
        }
T
ths 已提交
778

L
liguang 已提交
779
        initrd_size = get_image_size(initrd_filename);
M
M. Mohan Kumar 已提交
780 781 782 783 784 785
        if (initrd_size < 0) {
            fprintf(stderr, "qemu: error reading initrd %s\n",
                    initrd_filename);
            exit(1);
        }

786
        initrd_addr = (initrd_max-initrd_size) & ~4095;
787

788
        initrd_data = g_malloc(initrd_size);
789 790 791 792 793
        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 已提交
794

L
liguang 已提交
795 796
        stl_p(header+0x218, initrd_addr);
        stl_p(header+0x21c, initrd_size);
T
ths 已提交
797 798
    }

799
    /* load kernel and setup */
T
ths 已提交
800
    setup_size = header[0x1f1];
L
liguang 已提交
801 802 803
    if (setup_size == 0) {
        setup_size = 4;
    }
T
ths 已提交
804
    setup_size = (setup_size+1)*512;
805
    kernel_size -= setup_size;
T
ths 已提交
806

807 808
    setup  = g_malloc(setup_size);
    kernel = g_malloc(kernel_size);
809
    fseek(f, 0, SEEK_SET);
810 811 812 813 814 815 816 817
    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 已提交
818
    fclose(f);
819
    memcpy(setup, header, MIN(sizeof(header), setup_size));
820 821 822 823 824 825 826 827 828

    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 已提交
829 830
    option_rom[nb_option_roms].name = "linuxboot.bin";
    option_rom[nb_option_roms].bootindex = 0;
831
    nb_option_roms++;
T
ths 已提交
832 833
}

B
bellard 已提交
834 835
#define NE2000_NB_MAX 6

B
Blue Swirl 已提交
836 837 838
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 已提交
839

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

843
void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
844 845 846 847 848
{
    static int nb_ne2k = 0;

    if (nb_ne2k == NE2000_NB_MAX)
        return;
849
    isa_ne2000_init(bus, ne2000_io[nb_ne2k],
G
Gerd Hoffmann 已提交
850
                    ne2000_irq[nb_ne2k], nd);
851 852 853
    nb_ne2k++;
}

B
Blue Swirl 已提交
854
DeviceState *cpu_get_current_apic(void)
855 856 857 858 859 860 861 862
{
    if (cpu_single_env) {
        return cpu_single_env->apic_state;
    } else {
        return NULL;
    }
}

863
void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
B
Blue Swirl 已提交
864
{
865
    X86CPU *cpu = opaque;
B
Blue Swirl 已提交
866 867

    if (level) {
868
        cpu_interrupt(CPU(cpu), CPU_INTERRUPT_SMI);
B
Blue Swirl 已提交
869 870 871
    }
}

872
void pc_cpus_init(const char *cpu_model)
873 874 875 876 877 878 879 880 881 882 883 884
{
    int i;

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

885 886 887 888
    for (i = 0; i < smp_cpus; i++) {
        if (!cpu_x86_init(cpu_model)) {
            exit(1);
        }
889 890 891
    }
}

G
Gerd Hoffmann 已提交
892 893
void pc_acpi_init(const char *default_dsdt)
{
894
    char *filename;
G
Gerd Hoffmann 已提交
895 896 897 898 899 900 901 902 903

    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);
904 905 906 907
    } else {
        char *arg;
        QemuOpts *opts;
        Error *err = NULL;
G
Gerd Hoffmann 已提交
908

909
        arg = g_strdup_printf("file=%s", filename);
910

911 912 913
        /* creates a deep copy of "arg" */
        opts = qemu_opts_parse(qemu_find_opts("acpi"), arg, 0);
        g_assert(opts != NULL);
914

915 916 917 918 919 920 921 922
        acpi_table_add(opts, &err);
        if (err) {
            fprintf(stderr, "WARNING: failed to load %s: %s\n", filename,
                    error_get_pretty(err));
            error_free(err);
        }
        g_free(arg);
        g_free(filename);
G
Gerd Hoffmann 已提交
923 924 925
    }
}

926
void *pc_memory_init(MemoryRegion *system_memory,
A
Avi Kivity 已提交
927
                    const char *kernel_filename,
928 929
                    const char *kernel_cmdline,
                    const char *initrd_filename,
930
                    ram_addr_t below_4g_mem_size,
A
Avi Kivity 已提交
931
                    ram_addr_t above_4g_mem_size,
932
                    MemoryRegion *rom_memory,
A
Avi Kivity 已提交
933
                    MemoryRegion **ram_memory)
B
bellard 已提交
934
{
935 936
    int linux_boot, i;
    MemoryRegion *ram, *option_rom_mr;
937
    MemoryRegion *ram_below_4g, *ram_above_4g;
938
    void *fw_cfg;
939

B
bellard 已提交
940 941
    linux_boot = (kernel_filename != NULL);

942
    /* Allocate RAM.  We allocate it as a single memory region and use
D
Dong Xu Wang 已提交
943
     * aliases to address portions of it, mostly for backwards compatibility
944 945
     * with older qemus that used qemu_ram_alloc().
     */
946
    ram = g_malloc(sizeof(*ram));
947
    memory_region_init_ram(ram, "pc.ram",
948
                           below_4g_mem_size + above_4g_mem_size);
949
    vmstate_register_ram_global(ram);
A
Avi Kivity 已提交
950
    *ram_memory = ram;
951
    ram_below_4g = g_malloc(sizeof(*ram_below_4g));
952 953 954
    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);
955
    if (above_4g_mem_size > 0) {
956
        ram_above_4g = g_malloc(sizeof(*ram_above_4g));
957 958 959 960
        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);
961
    }
962

963 964 965

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

967
    option_rom_mr = g_malloc(sizeof(*option_rom_mr));
968 969
    memory_region_init_ram(option_rom_mr, "pc.rom", PC_ROM_SIZE);
    vmstate_register_ram_global(option_rom_mr);
970
    memory_region_add_subregion_overlap(rom_memory,
971 972 973
                                        PC_ROM_MIN_VGA,
                                        option_rom_mr,
                                        1);
974

A
Alexander Graf 已提交
975
    fw_cfg = bochs_bios_init();
G
Gerd Hoffmann 已提交
976
    rom_set_fw(fw_cfg);
A
Alexander Graf 已提交
977

978
    if (linux_boot) {
979
        load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
980 981 982
    }

    for (i = 0; i < nb_option_roms; i++) {
G
Gleb Natapov 已提交
983
        rom_add_option(option_rom[i].name, option_rom[i].bootindex);
984
    }
985
    return fw_cfg;
986 987
}

988 989 990 991 992
qemu_irq *pc_allocate_cpu_irq(void)
{
    return qemu_allocate_irqs(pic_irq_request, NULL, 1);
}

993
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
994
{
995 996
    DeviceState *dev = NULL;

997 998 999 1000 1001 1002
    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;
1003
    }
1004
    return dev;
1005 1006
}

B
Blue Swirl 已提交
1007 1008
static void cpu_request_exit(void *opaque, int irq, int level)
{
A
Andreas Färber 已提交
1009
    CPUX86State *env = cpu_single_env;
B
Blue Swirl 已提交
1010 1011 1012 1013 1014 1015

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

J
Julien Grall 已提交
1016 1017
static const MemoryRegionOps ioport80_io_ops = {
    .write = ioport80_write,
1018
    .read = ioport80_read,
J
Julien Grall 已提交
1019 1020 1021 1022 1023 1024 1025 1026 1027
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
};

static const MemoryRegionOps ioportF0_io_ops = {
    .write = ioportF0_write,
1028
    .read = ioportF0_read,
J
Julien Grall 已提交
1029 1030 1031 1032 1033 1034 1035
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
};

1036
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
1037
                          ISADevice **rtc_state,
K
Kevin Wolf 已提交
1038
                          ISADevice **floppy,
1039
                          bool no_vmport)
1040 1041 1042
{
    int i;
    DriveInfo *fd[MAX_FD];
1043 1044 1045
    DeviceState *hpet = NULL;
    int pit_isa_irq = 0;
    qemu_irq pit_alt_irq = NULL;
1046
    qemu_irq rtc_irq = NULL;
B
Blue Swirl 已提交
1047
    qemu_irq *a20_line;
1048
    ISADevice *i8042, *port92, *vmmouse, *pit = NULL;
B
Blue Swirl 已提交
1049
    qemu_irq *cpu_exit_irq;
J
Julien Grall 已提交
1050 1051
    MemoryRegion *ioport80_io = g_new(MemoryRegion, 1);
    MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
1052

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

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

1059 1060 1061 1062 1063 1064 1065
    /*
     * 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())) {
1066
        hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL);
J
Jan Kiszka 已提交
1067

B
Blue Swirl 已提交
1068
        if (hpet) {
J
Jan Kiszka 已提交
1069
            for (i = 0; i < GSI_NUM_PINS; i++) {
1070
                sysbus_connect_irq(SYS_BUS_DEVICE(hpet), i, gsi[i]);
B
Blue Swirl 已提交
1071
            }
1072 1073 1074
            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 已提交
1075
        }
1076
    }
1077
    *rtc_state = rtc_init(isa_bus, 2000, rtc_irq);
1078 1079 1080

    qemu_register_boot_set(pc_boot_set, *rtc_state);

1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
    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);
1092
    }
1093 1094 1095

    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
        if (serial_hds[i]) {
1096
            serial_isa_init(isa_bus, i, serial_hds[i]);
1097 1098 1099 1100 1101
        }
    }

    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
        if (parallel_hds[i]) {
1102
            parallel_init(isa_bus, i, parallel_hds[i]);
1103 1104 1105
        }
    }

1106 1107
    a20_line = qemu_allocate_irqs(handle_a20_line_change,
                                  x86_env_get_cpu(first_cpu), 2);
1108
    i8042 = isa_create_simple(isa_bus, "i8042");
1109
    i8042_setup_a20_line(i8042, &a20_line[0]);
1110
    if (!no_vmport) {
1111 1112
        vmport_init(isa_bus);
        vmmouse = isa_try_create(isa_bus, "vmmouse");
1113 1114 1115
    } else {
        vmmouse = NULL;
    }
B
Blue Swirl 已提交
1116 1117
    if (vmmouse) {
        qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042);
J
Jan Kiszka 已提交
1118
        qdev_init_nofail(&vmmouse->qdev);
B
Blue Swirl 已提交
1119
    }
1120
    port92 = isa_create_simple(isa_bus, "port92");
1121
    port92_init(port92, &a20_line[1]);
B
Blue Swirl 已提交
1122

B
Blue Swirl 已提交
1123 1124
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
    DMA_init(0, cpu_exit_irq);
1125 1126 1127 1128

    for(i = 0; i < MAX_FD; i++) {
        fd[i] = drive_get(IF_FLOPPY, 0, i);
    }
1129
    *floppy = fdctrl_init_isa(isa_bus, fd);
1130 1131
}

1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
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);
        }
    }
}

1147
void pc_pci_device_init(PCIBus *pci_bus)
1148 1149 1150 1151 1152 1153 1154 1155 1156
{
    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");
    }
}
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173

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);
1174
    d = SYS_BUS_DEVICE(dev);
1175
    sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS);
1176 1177 1178 1179 1180

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