pc.c 32.3 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.
 */
P
pbrook 已提交
24 25
#include "hw.h"
#include "pc.h"
G
Gerd Hoffmann 已提交
26
#include "serial.h"
27
#include "apic.h"
P
pbrook 已提交
28
#include "fdc.h"
29
#include "ide.h"
30
#include "pci/pci.h"
31
#include "monitor/monitor.h"
32
#include "fw_cfg.h"
A
aliguori 已提交
33
#include "hpet_emul.h"
34
#include "smbios.h"
B
Blue Swirl 已提交
35 36
#include "loader.h"
#include "elf.h"
37
#include "multiboot.h"
38
#include "mc146818rtc.h"
J
Jan Kiszka 已提交
39
#include "i8254.h"
J
Jan Kiszka 已提交
40
#include "pcspk.h"
41
#include "pci/msi.h"
J
Jan Kiszka 已提交
42
#include "sysbus.h"
43 44
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
45
#include "kvm_i386.h"
46
#include "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 {
A
aurel32 已提交
193 194 195 196
        if (level)
            cpu_interrupt(env, CPU_INTERRUPT_HARD);
        else
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
197
    }
B
bellard 已提交
198 199
}

B
bellard 已提交
200 201
/* PC cmos mappings */

B
bellard 已提交
202 203
#define REG_EQUIPMENT_BYTE          0x14

204
static int cmos_get_fd_drive_type(FDriveType fd0)
205 206 207 208
{
    int val;

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

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

244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
/* 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;
}

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

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

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

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

304 305 306 307 308 309 310 311 312 313 314 315
    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);
316 317 318

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

    qemu_unregister_reset(pc_cmos_init_late, opaque);
}

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

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

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

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

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

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

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

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

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

434 435
static void port92_write(void *opaque, hwaddr addr, uint64_t val,
                         unsigned size)
436 437 438 439 440 441 442 443 444 445 446
{
    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();
    }
}

447 448
static uint64_t port92_read(void *opaque, hwaddr addr,
                            unsigned size)
449 450 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
{
    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;
}

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

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

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

500 501 502 503
    s->outport = 0;
    return 0;
}

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

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

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

type_init(port92_register_types)
527

B
Blue Swirl 已提交
528
static void handle_a20_line_change(void *opaque, int irq, int level)
529
{
A
Andreas Färber 已提交
530
    CPUX86State *cpu = opaque;
B
bellard 已提交
531

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

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

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

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

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

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

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

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

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

    return fw_cfg;
B
bellard 已提交
629 630
}

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

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

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

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

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

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

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

723 724
    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);
725
    fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
T
ths 已提交
726 727

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

P
Pascal Terjan 已提交
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751
    /* 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 已提交
752
    /* loader type */
S
Stefan Weil 已提交
753
    /* High nybble = B reserved for QEMU; low nybble is revision number.
T
ths 已提交
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
       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);
	}

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

779
        initrd_addr = (initrd_max-initrd_size) & ~4095;
780

781
        initrd_data = g_malloc(initrd_size);
782 783 784 785 786
        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 已提交
787

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

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

799 800
    setup  = g_malloc(setup_size);
    kernel = g_malloc(kernel_size);
801
    fseek(f, 0, SEEK_SET);
802 803 804 805 806 807 808 809
    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 已提交
810
    fclose(f);
811
    memcpy(setup, header, MIN(sizeof(header), setup_size));
812 813 814 815 816 817 818 819 820

    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 已提交
821 822
    option_rom[nb_option_roms].name = "linuxboot.bin";
    option_rom[nb_option_roms].bootindex = 0;
823
    nb_option_roms++;
T
ths 已提交
824 825
}

B
bellard 已提交
826 827
#define NE2000_NB_MAX 6

B
Blue Swirl 已提交
828 829 830
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 已提交
831

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

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

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

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

855
void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
B
Blue Swirl 已提交
856
{
A
Andreas Färber 已提交
857
    CPUX86State *s = opaque;
B
Blue Swirl 已提交
858 859 860 861 862 863

    if (level) {
        cpu_interrupt(s, CPU_INTERRUPT_SMI);
    }
}

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

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

877 878 879 880 881
    for (i = 0; i < smp_cpus; i++) {
        if (!cpu_x86_init(cpu_model)) {
            fprintf(stderr, "Unable to find x86 CPU definition\n");
            exit(1);
        }
882 883 884
    }
}

G
Gerd Hoffmann 已提交
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
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);
}

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

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

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

945 946 947

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

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

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

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

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

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

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

979 980 981 982 983 984
    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;
985
    }
986
    return dev;
987 988
}

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

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

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

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

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

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

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

1041 1042 1043 1044 1045 1046 1047
    /*
     * 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())) {
1048
        hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL);
J
Jan Kiszka 已提交
1049

B
Blue Swirl 已提交
1050
        if (hpet) {
J
Jan Kiszka 已提交
1051
            for (i = 0; i < GSI_NUM_PINS; i++) {
1052
                sysbus_connect_irq(SYS_BUS_DEVICE(hpet), i, gsi[i]);
B
Blue Swirl 已提交
1053
            }
1054 1055 1056
            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 已提交
1057
        }
1058
    }
1059
    *rtc_state = rtc_init(isa_bus, 2000, rtc_irq);
1060 1061 1062

    qemu_register_boot_set(pc_boot_set, *rtc_state);

1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
    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);
1074
    }
1075 1076 1077

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

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

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

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

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

1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
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);
        }
    }
}

1128
void pc_pci_device_init(PCIBus *pci_bus)
1129 1130 1131 1132 1133 1134 1135 1136 1137
{
    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");
    }
}
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154

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);
1155
    d = SYS_BUS_DEVICE(dev);
1156 1157 1158 1159 1160 1161
    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);
    }
}