~fboudra/qemu-linaro/new-upstream-release-1.2.0-2012.09-0ubuntu1

« back to all changes in this revision

Viewing changes to hw/pc.c

  • Committer: Fathi Boudra
  • Author(s): Fathi Boudra
  • Date: 2012-08-21 06:47:11 UTC
  • mfrom: (0.1.16)
  • Revision ID: fathi.boudra@linaro.org-20120821064711-7yxmubp2v8a44xce
Tags: 1.1.50-2012.08-0ubuntu1
* New upstream release.
  - support emulated systems with more than 2G of memory. (LP: #1030588)
* Drop powerpc-missing-include.patch - merged upstream.
* Update debian/control: 
  - drop perl build dependency.
  - add libfdt-dev build dependency.
* Update debian/qemu-keymaps.install file.
* Update debian/rules:
  - update QEMU_CPU for ARM architecture: armv4l -> armv7l.
  - update conf_audio_drv: default to PulseAudio since PA is the default on
    Ubuntu.
  - enable KVM on ARM architecture.
  - enable flat device tree support (--enable-fdt). (LP: #1030594)

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
#include "sysbus.h"
43
43
#include "sysemu.h"
44
44
#include "kvm.h"
 
45
#include "kvm_i386.h"
 
46
#include "xen.h"
45
47
#include "blockdev.h"
 
48
#include "hw/block-common.h"
46
49
#include "ui/qemu-spice.h"
47
50
#include "memory.h"
48
51
#include "exec-memory.h"
 
52
#include "arch_init.h"
 
53
#include "bitmap.h"
49
54
 
50
55
/* output Bochs bios info messages */
51
56
//#define DEBUG_BIOS
140
145
    smm_arg = arg;
141
146
}
142
147
 
143
 
void cpu_smm_update(CPUState *env)
 
148
void cpu_smm_update(CPUX86State *env)
144
149
{
145
150
    if (smm_set && smm_arg && env == first_cpu)
146
151
        smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
148
153
 
149
154
 
150
155
/* IRQ handling */
151
 
int cpu_get_pic_interrupt(CPUState *env)
 
156
int cpu_get_pic_interrupt(CPUX86State *env)
152
157
{
153
158
    int intno;
154
159
 
167
172
 
168
173
static void pic_irq_request(void *opaque, int irq, int level)
169
174
{
170
 
    CPUState *env = first_cpu;
 
175
    CPUX86State *env = first_cpu;
171
176
 
172
177
    DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
173
178
    if (env->apic_state) {
214
219
    return val;
215
220
}
216
221
 
217
 
static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd,
218
 
                         ISADevice *s)
 
222
static void cmos_init_hd(ISADevice *s, int type_ofs, int info_ofs,
 
223
                         int16_t cylinders, int8_t heads, int8_t sectors)
219
224
{
220
 
    int cylinders, heads, sectors;
221
 
    bdrv_get_geometry_hint(hd, &cylinders, &heads, &sectors);
222
225
    rtc_set_memory(s, type_ofs, 47);
223
226
    rtc_set_memory(s, info_ofs, cylinders);
224
227
    rtc_set_memory(s, info_ofs + 1, cylinders >> 8);
279
282
 
280
283
typedef struct pc_cmos_init_late_arg {
281
284
    ISADevice *rtc_state;
282
 
    BusState *idebus0, *idebus1;
 
285
    BusState *idebus[2];
283
286
} pc_cmos_init_late_arg;
284
287
 
285
288
static void pc_cmos_init_late(void *opaque)
286
289
{
287
290
    pc_cmos_init_late_arg *arg = opaque;
288
291
    ISADevice *s = arg->rtc_state;
 
292
    int16_t cylinders;
 
293
    int8_t heads, sectors;
289
294
    int val;
290
 
    BlockDriverState *hd_table[4];
291
 
    int i;
292
 
 
293
 
    ide_get_bs(hd_table, arg->idebus0);
294
 
    ide_get_bs(hd_table + 2, arg->idebus1);
295
 
 
296
 
    rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
297
 
    if (hd_table[0])
298
 
        cmos_init_hd(0x19, 0x1b, hd_table[0], s);
299
 
    if (hd_table[1])
300
 
        cmos_init_hd(0x1a, 0x24, hd_table[1], s);
 
295
    int i, trans;
 
296
 
 
297
    val = 0;
 
298
    if (ide_get_geometry(arg->idebus[0], 0,
 
299
                         &cylinders, &heads, &sectors) >= 0) {
 
300
        cmos_init_hd(s, 0x19, 0x1b, cylinders, heads, sectors);
 
301
        val |= 0xf0;
 
302
    }
 
303
    if (ide_get_geometry(arg->idebus[0], 1,
 
304
                         &cylinders, &heads, &sectors) >= 0) {
 
305
        cmos_init_hd(s, 0x1a, 0x24, cylinders, heads, sectors);
 
306
        val |= 0x0f;
 
307
    }
 
308
    rtc_set_memory(s, 0x12, val);
301
309
 
302
310
    val = 0;
303
311
    for (i = 0; i < 4; i++) {
304
 
        if (hd_table[i]) {
305
 
            int cylinders, heads, sectors, translation;
306
 
            /* NOTE: bdrv_get_geometry_hint() returns the physical
307
 
                geometry.  It is always such that: 1 <= sects <= 63, 1
308
 
                <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
309
 
                geometry can be different if a translation is done. */
310
 
            translation = bdrv_get_translation_hint(hd_table[i]);
311
 
            if (translation == BIOS_ATA_TRANSLATION_AUTO) {
312
 
                bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
313
 
                if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
314
 
                    /* No translation. */
315
 
                    translation = 0;
316
 
                } else {
317
 
                    /* LBA translation. */
318
 
                    translation = 1;
319
 
                }
320
 
            } else {
321
 
                translation--;
322
 
            }
323
 
            val |= translation << (i * 2);
 
312
        /* NOTE: ide_get_geometry() returns the physical
 
313
           geometry.  It is always such that: 1 <= sects <= 63, 1
 
314
           <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
 
315
           geometry can be different if a translation is done. */
 
316
        if (ide_get_geometry(arg->idebus[i / 2], i % 2,
 
317
                             &cylinders, &heads, &sectors) >= 0) {
 
318
            trans = ide_get_bios_chs_trans(arg->idebus[i / 2], i % 2) - 1;
 
319
            assert((trans & ~3) == 0);
 
320
            val |= trans << (i * 2);
324
321
        }
325
322
    }
326
323
    rtc_set_memory(s, 0x39, val);
333
330
                  ISADevice *floppy, BusState *idebus0, BusState *idebus1,
334
331
                  ISADevice *s)
335
332
{
336
 
    int val, nb, nb_heads, max_track, last_sect, i;
 
333
    int val, nb, i;
337
334
    FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
338
 
    FDriveRate rate;
339
 
    BlockDriverState *fd[MAX_FD];
340
335
    static pc_cmos_init_late_arg arg;
341
336
 
342
337
    /* various important CMOS locations needed by PC/Bochs bios */
379
374
 
380
375
    /* floppy type */
381
376
    if (floppy) {
382
 
        fdc_get_bs(fd, floppy);
383
377
        for (i = 0; i < 2; i++) {
384
 
            if (fd[i] && bdrv_is_inserted(fd[i])) {
385
 
                bdrv_get_floppy_geometry_hint(fd[i], &nb_heads, &max_track,
386
 
                                              &last_sect, FDRIVE_DRV_NONE,
387
 
                                              &fd_type[i], &rate);
388
 
            }
 
378
            fd_type[i] = isa_fdc_get_drive_type(floppy, i);
389
379
        }
390
380
    }
391
381
    val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |
416
406
 
417
407
    /* hard drives */
418
408
    arg.rtc_state = s;
419
 
    arg.idebus0 = idebus0;
420
 
    arg.idebus1 = idebus1;
 
409
    arg.idebus[0] = idebus0;
 
410
    arg.idebus[1] = idebus1;
421
411
    qemu_register_reset(pc_cmos_init_late, &arg);
422
412
}
423
413
 
522
512
 
523
513
static void handle_a20_line_change(void *opaque, int irq, int level)
524
514
{
525
 
    CPUState *cpu = opaque;
 
515
    CPUX86State *cpu = opaque;
526
516
 
527
517
    /* XXX: send to all CPUs ? */
528
518
    /* XXX: add logic to handle multiple A20 line sources */
637
627
    numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
638
628
    for (i = 0; i < max_cpus; i++) {
639
629
        for (j = 0; j < nb_numa_nodes; j++) {
640
 
            if (node_cpumask[j] & (1 << i)) {
 
630
            if (test_bit(i, node_cpumask[j])) {
641
631
                numa_fw_cfg[i + 1] = cpu_to_le64(j);
642
632
                break;
643
633
            }
776
766
    }
777
767
 
778
768
    /* loader type */
779
 
    /* High nybble = B reserved for Qemu; low nybble is revision number.
 
769
    /* High nybble = B reserved for QEMU; low nybble is revision number.
780
770
       If this code is substantially changed, you may want to consider
781
771
       incrementing the revision. */
782
772
    if (protocol >= 0x200)
869
859
    nb_ne2k++;
870
860
}
871
861
 
872
 
int cpu_is_bsp(CPUState *env)
873
 
{
874
 
    /* We hard-wire the BSP to the first CPU. */
875
 
    return env->cpu_index == 0;
876
 
}
877
 
 
878
862
DeviceState *cpu_get_current_apic(void)
879
863
{
880
864
    if (cpu_single_env) {
891
875
 
892
876
    if (kvm_irqchip_in_kernel()) {
893
877
        dev = qdev_create(NULL, "kvm-apic");
 
878
    } else if (xen_enabled()) {
 
879
        dev = qdev_create(NULL, "xen-apic");
894
880
    } else {
895
881
        dev = qdev_create(NULL, "apic");
896
882
    }
 
883
 
897
884
    qdev_prop_set_uint8(dev, "id", apic_id);
898
885
    qdev_prop_set_ptr(dev, "cpu_env", env);
899
886
    qdev_init_nofail(dev);
907
894
        apic_mapped = 1;
908
895
    }
909
896
 
910
 
    /* KVM does not support MSI yet. */
911
 
    if (!kvm_irqchip_in_kernel()) {
912
 
        msi_supported = true;
913
 
    }
914
 
 
915
897
    return dev;
916
898
}
917
899
 
918
900
void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
919
901
{
920
 
    CPUState *s = opaque;
 
902
    CPUX86State *s = opaque;
921
903
 
922
904
    if (level) {
923
905
        cpu_interrupt(s, CPU_INTERRUPT_SMI);
924
906
    }
925
907
}
926
908
 
927
 
static void pc_cpu_reset(void *opaque)
928
 
{
929
 
    CPUState *env = opaque;
930
 
 
931
 
    cpu_reset(env);
932
 
    env->halted = !cpu_is_bsp(env);
933
 
}
934
 
 
935
 
static CPUState *pc_new_cpu(const char *cpu_model)
936
 
{
937
 
    CPUState *env;
938
 
 
939
 
    env = cpu_init(cpu_model);
940
 
    if (!env) {
 
909
static X86CPU *pc_new_cpu(const char *cpu_model)
 
910
{
 
911
    X86CPU *cpu;
 
912
    CPUX86State *env;
 
913
 
 
914
    cpu = cpu_x86_init(cpu_model);
 
915
    if (cpu == NULL) {
941
916
        fprintf(stderr, "Unable to find x86 CPU definition\n");
942
917
        exit(1);
943
918
    }
 
919
    env = &cpu->env;
944
920
    if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) {
945
921
        env->apic_state = apic_init(env, env->cpuid_apic_id);
946
922
    }
947
 
    qemu_register_reset(pc_cpu_reset, env);
948
 
    pc_cpu_reset(env);
949
 
    return env;
 
923
    cpu_reset(CPU(cpu));
 
924
    return cpu;
950
925
}
951
926
 
952
927
void pc_cpus_init(const char *cpu_model)
967
942
    }
968
943
}
969
944
 
970
 
void pc_memory_init(MemoryRegion *system_memory,
 
945
void *pc_memory_init(MemoryRegion *system_memory,
971
946
                    const char *kernel_filename,
972
947
                    const char *kernel_cmdline,
973
948
                    const char *initrd_filename,
1026
1001
    for (i = 0; i < nb_option_roms; i++) {
1027
1002
        rom_add_option(option_rom[i].name, option_rom[i].bootindex);
1028
1003
    }
 
1004
    return fw_cfg;
1029
1005
}
1030
1006
 
1031
1007
qemu_irq *pc_allocate_cpu_irq(void)
1070
1046
 
1071
1047
static void cpu_request_exit(void *opaque, int irq, int level)
1072
1048
{
1073
 
    CPUState *env = cpu_single_env;
 
1049
    CPUX86State *env = cpu_single_env;
1074
1050
 
1075
1051
    if (env && level) {
1076
1052
        cpu_exit(env);
1089
1065
    qemu_irq pit_alt_irq = NULL;
1090
1066
    qemu_irq rtc_irq = NULL;
1091
1067
    qemu_irq *a20_line;
1092
 
    ISADevice *i8042, *port92, *vmmouse, *pit;
 
1068
    ISADevice *i8042, *port92, *vmmouse, *pit = NULL;
1093
1069
    qemu_irq *cpu_exit_irq;
1094
1070
 
1095
1071
    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
1096
1072
 
1097
1073
    register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
1098
1074
 
1099
 
    if (!no_hpet) {
 
1075
    /*
 
1076
     * Check if an HPET shall be created.
 
1077
     *
 
1078
     * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT
 
1079
     * when the HPET wants to take over. Thus we have to disable the latter.
 
1080
     */
 
1081
    if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) {
1100
1082
        hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL);
1101
1083
 
1102
1084
        if (hpet) {
1112
1094
 
1113
1095
    qemu_register_boot_set(pc_boot_set, *rtc_state);
1114
1096
 
1115
 
    pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq);
1116
 
    if (hpet) {
1117
 
        /* connect PIT to output control line of the HPET */
1118
 
        qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(&pit->qdev, 0));
 
1097
    if (!xen_enabled()) {
 
1098
        if (kvm_irqchip_in_kernel()) {
 
1099
            pit = kvm_pit_init(isa_bus, 0x40);
 
1100
        } else {
 
1101
            pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq);
 
1102
        }
 
1103
        if (hpet) {
 
1104
            /* connect PIT to output control line of the HPET */
 
1105
            qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(&pit->qdev, 0));
 
1106
        }
 
1107
        pcspk_init(isa_bus, pit);
1119
1108
    }
1120
 
    pcspk_init(isa_bus, pit);
1121
1109
 
1122
1110
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
1123
1111
        if (serial_hds[i]) {