diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-09-24 18:48:00 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-09-24 18:48:00 +0000 |
commit | a5954d5c34502ebeaae95b8719a734066f596f1e (patch) | |
tree | cd73ee36044215a6db4d5eeef3c7c47f65a4b5ee /hw/pc.c | |
parent | f537a28c9747d5b8864dabf7dda4972a9ec4687c (diff) | |
download | qemu-a5954d5c34502ebeaae95b8719a734066f596f1e.zip |
moved MP table init to BIOS
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2172 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/pc.c')
-rw-r--r-- | hw/pc.c | 178 |
1 files changed, 15 insertions, 163 deletions
@@ -40,6 +40,7 @@ static fdctrl_t *floppy_controller; static RTCState *rtc_state; static PITState *pit; static IOAPICState *ioapic; +static PCIDevice *i440fx_state; static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { @@ -73,6 +74,14 @@ uint64_t cpu_get_tsc(CPUX86State *env) } } +/* SMM support */ +void cpu_smm_update(CPUState *env) +{ + if (i440fx_state && env == first_cpu) + i440fx_set_smm(i440fx_state, (env->hflags >> HF_SMM_SHIFT) & 1); +} + + /* IRQ handling */ int cpu_get_pic_interrupt(CPUState *env) { @@ -398,156 +407,6 @@ static void main_cpu_reset(void *opaque) cpu_reset(env); } -/*************************************************/ - -static void putb(uint8_t **pp, int val) -{ - uint8_t *q; - q = *pp; - *q++ = val; - *pp = q; -} - -static void putstr(uint8_t **pp, const char *str) -{ - uint8_t *q; - q = *pp; - while (*str) - *q++ = *str++; - *pp = q; -} - -static void putle16(uint8_t **pp, int val) -{ - uint8_t *q; - q = *pp; - *q++ = val; - *q++ = val >> 8; - *pp = q; -} - -static void putle32(uint8_t **pp, int val) -{ - uint8_t *q; - q = *pp; - *q++ = val; - *q++ = val >> 8; - *q++ = val >> 16; - *q++ = val >> 24; - *pp = q; -} - -static int mpf_checksum(const uint8_t *data, int len) -{ - int sum, i; - sum = 0; - for(i = 0; i < len; i++) - sum += data[i]; - return sum & 0xff; -} - -/* Build the Multi Processor table in the BIOS. Same values as Bochs. */ -static void bios_add_mptable(uint8_t *bios_data) -{ - uint8_t *mp_config_table, *q, *float_pointer_struct; - int ioapic_id, offset, i, len; - - if (smp_cpus <= 1) - return; - - mp_config_table = bios_data + 0xb000; - q = mp_config_table; - putstr(&q, "PCMP"); /* "PCMP signature */ - putle16(&q, 0); /* table length (patched later) */ - putb(&q, 4); /* spec rev */ - putb(&q, 0); /* checksum (patched later) */ - putstr(&q, "QEMUCPU "); /* OEM id */ - putstr(&q, "0.1 "); /* vendor id */ - putle32(&q, 0); /* OEM table ptr */ - putle16(&q, 0); /* OEM table size */ - putle16(&q, 20); /* entry count */ - putle32(&q, 0xfee00000); /* local APIC addr */ - putle16(&q, 0); /* ext table length */ - putb(&q, 0); /* ext table checksum */ - putb(&q, 0); /* reserved */ - - for(i = 0; i < smp_cpus; i++) { - putb(&q, 0); /* entry type = processor */ - putb(&q, i); /* APIC id */ - putb(&q, 0x11); /* local APIC version number */ - if (i == 0) - putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */ - else - putb(&q, 1); /* cpu flags: enabled */ - putb(&q, 0); /* cpu signature */ - putb(&q, 6); - putb(&q, 0); - putb(&q, 0); - putle16(&q, 0x201); /* feature flags */ - putle16(&q, 0); - - putle16(&q, 0); /* reserved */ - putle16(&q, 0); - putle16(&q, 0); - putle16(&q, 0); - } - - /* isa bus */ - putb(&q, 1); /* entry type = bus */ - putb(&q, 0); /* bus ID */ - putstr(&q, "ISA "); - - /* ioapic */ - ioapic_id = smp_cpus; - putb(&q, 2); /* entry type = I/O APIC */ - putb(&q, ioapic_id); /* apic ID */ - putb(&q, 0x11); /* I/O APIC version number */ - putb(&q, 1); /* enable */ - putle32(&q, 0xfec00000); /* I/O APIC addr */ - - /* irqs */ - for(i = 0; i < 16; i++) { - putb(&q, 3); /* entry type = I/O interrupt */ - putb(&q, 0); /* interrupt type = vectored interrupt */ - putb(&q, 0); /* flags: po=0, el=0 */ - putb(&q, 0); - putb(&q, 0); /* source bus ID = ISA */ - putb(&q, i); /* source bus IRQ */ - putb(&q, ioapic_id); /* dest I/O APIC ID */ - putb(&q, i); /* dest I/O APIC interrupt in */ - } - /* patch length */ - len = q - mp_config_table; - mp_config_table[4] = len; - mp_config_table[5] = len >> 8; - - mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table); - - /* align to 16 */ - offset = q - bios_data; - offset = (offset + 15) & ~15; - float_pointer_struct = bios_data + offset; - - /* floating pointer structure */ - q = float_pointer_struct; - putstr(&q, "_MP_"); - /* pointer to MP config table */ - putle32(&q, mp_config_table - bios_data + 0x000f0000); - - putb(&q, 1); /* length in 16 byte units */ - putb(&q, 4); /* MP spec revision */ - putb(&q, 0); /* checksum (patched later) */ - putb(&q, 0); /* MP feature byte 1 */ - - putb(&q, 0); - putb(&q, 0); - putb(&q, 0); - putb(&q, 0); - float_pointer_struct[10] = - -mpf_checksum(float_pointer_struct, q - float_pointer_struct); -} - - static const int ide_iobase[2] = { 0x1f0, 0x170 }; static const int ide_iobase2[2] = { 0x3f6, 0x376 }; static const int ide_irq[2] = { 14, 15 }; @@ -632,7 +491,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, /* XXX: enable it in all cases */ env->cpuid_features |= CPUID_APIC; } - register_savevm("cpu", i, 3, cpu_save, cpu_load, env); + register_savevm("cpu", i, 4, cpu_save, cpu_load, env); qemu_register_reset(main_cpu_reset, env); if (pci_enabled) { apic_init(env); @@ -659,9 +518,6 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf); exit(1); } - if (bios_size == 65536) { - bios_add_mptable(phys_ram_base + bios_offset); - } /* VGA BIOS load */ if (cirrus_vga_enabled) { @@ -747,7 +603,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, } if (pci_enabled) { - pci_bus = i440fx_init(); + pci_bus = i440fx_init(&i440fx_state); piix3_devfn = piix3_init(pci_bus); } else { pci_bus = NULL; @@ -850,7 +706,10 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, if (pci_enabled && acpi_enabled) { piix4_pm_init(pci_bus, piix3_devfn + 3); } - + + if (i440fx_state) { + i440fx_init_memory_mappings(i440fx_state); + } #if 0 /* ??? Need to figure out some way for the user to specify SCSI devices. */ @@ -868,13 +727,6 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, lsi_scsi_attach(scsi, bdrv, -1); } #endif - /* must be done after all PCI devices are instanciated */ - /* XXX: should be done in the Bochs BIOS */ - if (pci_enabled) { - pci_bios_init(); - if (acpi_enabled) - acpi_bios_init(); - } } static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device, |