From d4afc623ae3ca529ff16cc2cf5de9293310de3e6 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 24 Sep 2006 18:38:12 +0000 Subject: [PATCH] moved PCI, MP and ACPI init to bios git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2167 c046a42c-6fe2-441c-8c8c-71466251a162 --- pc-bios/bios.bin | Bin 65536 -> 131072 bytes pc-bios/bios.diff | 3068 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 2835 insertions(+), 233 deletions(-) diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin index 64be517b248ec359e109217b9021517050ec30e3..051fdbb1483a22a58ddbe6cf9d6edf51c31bff87 100644 GIT binary patch literal 131072 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 _rombios_.c + $(BCC) -o rombios.s -C-c -D__i86__ -0 -S _rombios_.c + sed -e 's/^\.text//' -e 's/^\.data//' rombios.s > _rombios_.s + $(AS86) _rombios_.s -b tmp.bin -u- -w- -g -0 -j -O -l rombios.txt + -perl ${srcdir}/makesym.perl < rombios.txt > rombios.sym +- mv tmp.bin BIOS-bochs-latest +- ./biossums BIOS-bochs-latest ++ mv tmp.bin rombios16.bin ++ ./biossums rombios16.bin + rm -f _rombios_.s + -+void set_e820_range(ES, DI, start, end, type) -+ Bit16u ES; -+ Bit16u DI; -+ Bit32u start; -+ Bit32u end; -+ Bit16u type; ++rombios32.bin: rombios32.out pad ++ objcopy -O binary $< tmp32.bin ++ ./pad < tmp32.bin > $@ 65536 0xff ++ ++rombios32.out: rombios32start.o rombios32.o rombios32.ld ++ ld -o $@ -T rombios32.ld rombios32start.o rombios32.o ++ ++rombios32.o: rombios32.c ++ $(GCC) -O2 -Wall -c -o $@ $< ++ ++rombios32start.o: rombios32start.S ++ $(GCC) -c -o $@ $< ++ ++BIOS-bochs-latest: rombios16.bin rombios32.bin ++ cat rombios32.bin rombios16.bin > $@ ++ ++pad: pad.c ++ $(GCC) -o $@ $< ++ + biossums: biossums.c + $(GCC) -o biossums biossums.c +diff -ruN --exclude Makefile bios/pad.c bios.new/pad.c +--- bios/pad.c 1970-01-01 01:00:00.000000000 +0100 ++++ bios.new/pad.c 2006-09-24 20:22:58.000000000 +0200 +@@ -0,0 +1,20 @@ ++#include ++#include ++ ++int main(int argc, char **argv) +{ -+ write_word(ES, DI, start); -+ write_word(ES, DI+2, start >> 16); -+ write_word(ES, DI+4, 0x00); -+ write_word(ES, DI+6, 0x00); -+ -+ end -= start; -+ write_word(ES, DI+8, end); -+ write_word(ES, DI+10, end >> 16); -+ write_word(ES, DI+12, 0x0000); -+ write_word(ES, DI+14, 0x0000); -+ -+ write_word(ES, DI+16, type); -+ write_word(ES, DI+18, 0x0); ++ int len, val, i, c; ++ ++ len = strtol(argv[1], NULL, 0); ++ val = strtol(argv[2], NULL, 0); ++ for(i = 0 ; i < len; i++) { ++ c = getchar(); ++ if (c == EOF) ++ break; ++ putchar(c); ++ } ++ for( ; i < len; i++) { ++ putchar(val); ++ } ++ return 0; ++} +diff -ruN --exclude Makefile bios/rombios32.c bios.new/rombios32.c +--- bios/rombios32.c 1970-01-01 01:00:00.000000000 +0100 ++++ bios.new/rombios32.c 2006-09-24 20:22:58.000000000 +0200 +@@ -0,0 +1,1324 @@ ++// 32 bit Bochs BIOS init code ++// Copyright (C) 2006 Fabrice Bellard ++// ++// This library is free software; you can redistribute it and/or ++// modify it under the terms of the GNU Lesser General Public ++// License as published by the Free Software Foundation; either ++// version 2 of the License, or (at your option) any later version. ++// ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++// Lesser General Public License for more details. ++// ++// You should have received a copy of the GNU Lesser General Public ++// License along with this library; if not, write to the Free Software ++// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++#include ++#include ++ ++typedef signed char int8_t; ++typedef short int16_t; ++typedef int int32_t; ++typedef long long int64_t; ++typedef unsigned char uint8_t; ++typedef unsigned short uint16_t; ++typedef unsigned int uint32_t; ++typedef unsigned long long uint64_t; ++ ++/* if true, put the MP float table and ACPI RSDT in EBDA and the MP ++ table in RAM. Unfortunately, Linux has bugs with that, so we prefer ++ to modify the BIOS in shadow RAM */ ++//#define BX_USE_EBDA_TABLES ++ ++/* define it if the (emulated) hardware supports SMM mode */ ++#define BX_USE_SMM ++ ++#define BX_INFO(fmt, args...) bios_printf(0, fmt, ## args); ++ ++#define INFO_PORT 0x402 ++ ++#define cpuid(index, eax, ebx, ecx, edx) \ ++ asm volatile ("cpuid" \ ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \ ++ : "0" (index)) ++ ++#define CPUID_APIC (1 << 9) ++ ++#define APIC_BASE ((uint8_t *)0xfee00000) ++#define APIC_ICR_LOW 0x300 ++#define APIC_SVR 0x0F0 ++#define APIC_ID 0x020 ++#define APIC_LVT3 0x370 ++ ++#define APIC_ENABLED 0x0100 ++ ++#define CPU_COUNT_ADDR 0xf000 ++#define AP_BOOT_ADDR 0x10000 ++ ++#define MPTABLE_MAX_SIZE 0x00002000 ++#define ACPI_DATA_SIZE 0x00010000 ++#define SMI_CMD_IO_ADDR 0xb2 ++#define PM_IO_BASE 0xb000 ++ ++#define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */ ++ ++static inline void outl(int addr, int val) ++{ ++ asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val)); +} + - void - int15_function32(regs, ES, DS, FLAGS) - pushad_regs_t regs; // REGS pushed via pushad -@@ -4063,19 +4090,8 @@ ++static inline void outw(int addr, int val) ++{ ++ asm volatile ("outw %w1, %w0" : : "d" (addr), "a" (val)); ++} ++ ++static inline void outb(int addr, int val) ++{ ++ asm volatile ("outb %b1, %w0" : : "d" (addr), "a" (val)); ++} ++ ++static inline uint32_t inl(int addr) ++{ ++ uint32_t val; ++ asm volatile ("inl %w1, %0" : "=a" (val) : "d" (addr)); ++ return val; ++} ++ ++static inline uint16_t inw(int addr) ++{ ++ uint16_t val; ++ asm volatile ("inw %w1, %w0" : "=a" (val) : "d" (addr)); ++ return val; ++} ++ ++static inline uint8_t inb(int addr) ++{ ++ uint8_t val; ++ asm volatile ("inb %w1, %b0" : "=a" (val) : "d" (addr)); ++ return val; ++} ++ ++static inline void writel(void *addr, uint32_t val) ++{ ++ *(volatile uint32_t *)addr = val; ++} ++ ++static inline void writew(void *addr, uint16_t val) ++{ ++ *(volatile uint16_t *)addr = val; ++} ++ ++static inline void writeb(void *addr, uint8_t val) ++{ ++ *(volatile uint8_t *)addr = val; ++} ++ ++static inline uint32_t readl(const void *addr) ++{ ++ return *(volatile const uint32_t *)addr; ++} ++ ++static inline uint16_t readw(const void *addr) ++{ ++ return *(volatile const uint16_t *)addr; ++} ++ ++static inline uint8_t readb(const void *addr) ++{ ++ return *(volatile const uint8_t *)addr; ++} ++ ++static inline void putc(int c) ++{ ++ outb(INFO_PORT, c); ++} ++ ++static inline int isdigit(int c) ++{ ++ return c >= '0' && c <= '9'; ++} ++ ++void *memset(void *d1, int val, size_t len) ++{ ++ uint8_t *d = d1; ++ ++ while (len--) { ++ *d++ = val; ++ } ++ return d1; ++} ++ ++void *memcpy(void *d1, const void *s1, size_t len) ++{ ++ uint8_t *d = d1; ++ const uint8_t *s = s1; ++ ++ while (len--) { ++ *d++ = *s++; ++ } ++ return d1; ++} ++ ++void *memmove(void *d1, const void *s1, size_t len) ++{ ++ uint8_t *d = d1; ++ const uint8_t *s = s1; ++ ++ if (d <= s) { ++ while (len--) { ++ *d++ = *s++; ++ } ++ } else { ++ d += len; ++ s += len; ++ while (len--) { ++ *--d = *--s; ++ } ++ } ++ return d1; ++} ++ ++size_t strlen(const char *s) ++{ ++ const char *s1; ++ for(s1 = s; *s1 != '\0'; s1++); ++ return s1 - s; ++} ++ ++/* from BSD ppp sources */ ++int vsnprintf(char *buf, int buflen, const char *fmt, va_list args) ++{ ++ int c, i, n; ++ int width, prec, fillch; ++ int base, len, neg; ++ unsigned long val = 0; ++ const char *f; ++ char *str, *buf0; ++ char num[32]; ++ static const char hexchars[] = "0123456789abcdef"; ++ ++ buf0 = buf; ++ --buflen; ++ while (buflen > 0) { ++ for (f = fmt; *f != '%' && *f != 0; ++f) ++ ; ++ if (f > fmt) { ++ len = f - fmt; ++ if (len > buflen) ++ len = buflen; ++ memcpy(buf, fmt, len); ++ buf += len; ++ buflen -= len; ++ fmt = f; ++ } ++ if (*fmt == 0) ++ break; ++ c = *++fmt; ++ width = prec = 0; ++ fillch = ' '; ++ if (c == '0') { ++ fillch = '0'; ++ c = *++fmt; ++ } ++ if (c == '*') { ++ width = va_arg(args, int); ++ c = *++fmt; ++ } else { ++ while (isdigit(c)) { ++ width = width * 10 + c - '0'; ++ c = *++fmt; ++ } ++ } ++ if (c == '.') { ++ c = *++fmt; ++ if (c == '*') { ++ prec = va_arg(args, int); ++ c = *++fmt; ++ } else { ++ while (isdigit(c)) { ++ prec = prec * 10 + c - '0'; ++ c = *++fmt; ++ } ++ } ++ } ++ /* modifiers */ ++ switch(c) { ++ case 'l': ++ c = *++fmt; ++ break; ++ default: ++ break; ++ } ++ str = 0; ++ base = 0; ++ neg = 0; ++ ++fmt; ++ switch (c) { ++ case 'd': ++ i = va_arg(args, int); ++ if (i < 0) { ++ neg = 1; ++ val = -i; ++ } else ++ val = i; ++ base = 10; ++ break; ++ case 'o': ++ val = va_arg(args, unsigned int); ++ base = 8; ++ break; ++ case 'x': ++ case 'X': ++ val = va_arg(args, unsigned int); ++ base = 16; ++ break; ++ case 'p': ++ val = (unsigned long) va_arg(args, void *); ++ base = 16; ++ neg = 2; ++ break; ++ case 's': ++ str = va_arg(args, char *); ++ break; ++ case 'c': ++ num[0] = va_arg(args, int); ++ num[1] = 0; ++ str = num; ++ break; ++ default: ++ *buf++ = '%'; ++ if (c != '%') ++ --fmt; /* so %z outputs %z etc. */ ++ --buflen; ++ continue; ++ } ++ if (base != 0) { ++ str = num + sizeof(num); ++ *--str = 0; ++ while (str > num + neg) { ++ *--str = hexchars[val % base]; ++ val = val / base; ++ if (--prec <= 0 && val == 0) ++ break; ++ } ++ switch (neg) { ++ case 1: ++ *--str = '-'; ++ break; ++ case 2: ++ *--str = 'x'; ++ *--str = '0'; ++ break; ++ } ++ len = num + sizeof(num) - 1 - str; ++ } else { ++ len = strlen(str); ++ if (prec > 0 && len > prec) ++ len = prec; ++ } ++ if (width > 0) { ++ if (width > buflen) ++ width = buflen; ++ if ((n = width - len) > 0) { ++ buflen -= n; ++ for (; n > 0; --n) ++ *buf++ = fillch; ++ } ++ } ++ if (len > buflen) ++ len = buflen; ++ memcpy(buf, str, len); ++ buf += len; ++ buflen -= len; ++ } ++ *buf = 0; ++ return buf - buf0; ++} ++ ++void bios_printf(int flags, const char *fmt, ...) ++{ ++ va_list ap; ++ char buf[1024]; ++ const char *s; ++ ++ va_start(ap, fmt); ++ vsnprintf(buf, sizeof(buf), fmt, ap); ++ s = buf; ++ while (*s) ++ putc(*s++); ++ va_end(ap); ++} ++ ++/* approximative ! */ ++void delay_ms(int n) ++{ ++ int i, j; ++ for(i = 0; i < n; i++) { ++ for(j = 0; j < 1000000; j++); ++ } ++} ++ ++int smp_cpus; ++uint32_t cpuid_features; ++uint32_t cpuid_ext_features; ++unsigned long ram_size; ++#ifdef BX_USE_EBDA_TABLES ++unsigned long ebda_cur_addr; ++#endif ++int acpi_enabled; ++uint32_t pm_io_base; ++int pm_sci_int; ++unsigned long bios_table_cur_addr; ++unsigned long bios_table_end_addr; ++ ++void cpu_probe(void) ++{ ++ uint32_t eax, ebx, ecx, edx; ++ cpuid(1, eax, ebx, ecx, edx); ++ cpuid_features = edx; ++ cpuid_ext_features = ecx; ++} ++ ++static int cmos_readb(int addr) ++{ ++ outb(0x70, addr); ++ return inb(0x71); ++} ++ ++void ram_probe(void) ++{ ++ ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 + ++ 16 * 1024 * 1024; ++#ifdef BX_USE_EBDA_TABLES ++ ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; ++#endif ++ BX_INFO("ram_size=0x%08lx\n"); ++} ++ ++/****************************************************/ ++/* SMP probe */ ++ ++extern uint8_t smp_ap_boot_code_start; ++extern uint8_t smp_ap_boot_code_end; ++ ++/* find the number of CPUs by launching a SIPI to them */ ++void smp_probe(void) ++{ ++ uint32_t val, sipi_vector; ++ ++ smp_cpus = 1; ++ if (cpuid_features & CPUID_APIC) { ++ ++ /* enable local APIC */ ++ val = readl(APIC_BASE + APIC_SVR); ++ val |= APIC_ENABLED; ++ writel(APIC_BASE + APIC_SVR, val); ++ ++ writew((void *)CPU_COUNT_ADDR, 1); ++ /* copy AP boot code */ ++ memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start, ++ &smp_ap_boot_code_end - &smp_ap_boot_code_start); ++ ++ /* broadcast SIPI */ ++ writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500); ++ sipi_vector = AP_BOOT_ADDR >> 12; ++ writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector); ++ ++ delay_ms(10); ++ ++ smp_cpus = readw((void *)CPU_COUNT_ADDR); ++ } ++ BX_INFO("Found %d cpus\n", smp_cpus); ++} ++ ++/****************************************************/ ++/* PCI init */ ++ ++#define PCI_ADDRESS_SPACE_MEM 0x00 ++#define PCI_ADDRESS_SPACE_IO 0x01 ++#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 ++ ++#define PCI_ROM_SLOT 6 ++#define PCI_NUM_REGIONS 7 ++ ++#define PCI_DEVICES_MAX 64 ++ ++#define PCI_VENDOR_ID 0x00 /* 16 bits */ ++#define PCI_DEVICE_ID 0x02 /* 16 bits */ ++#define PCI_COMMAND 0x04 /* 16 bits */ ++#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ ++#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ ++#define PCI_CLASS_DEVICE 0x0a /* Device class */ ++#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ ++#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ ++#define PCI_MIN_GNT 0x3e /* 8 bits */ ++#define PCI_MAX_LAT 0x3f /* 8 bits */ ++ ++typedef struct PCIDevice { ++ int bus; ++ int devfn; ++} PCIDevice; ++ ++static uint32_t pci_bios_io_addr; ++static uint32_t pci_bios_mem_addr; ++/* host irqs corresponding to PCI irqs A-D */ ++static uint8_t pci_irqs[4] = { 11, 9, 11, 9 }; ++static PCIDevice i440_pcidev; ++ ++static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) ++{ ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); ++ outl(0xcfc, val); ++} ++ ++static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val) ++{ ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); ++ outw(0xcfc + (addr & 2), val); ++} ++ ++static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val) ++{ ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); ++ outb(0xcfc + (addr & 3), val); ++} ++ ++static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr) ++{ ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); ++ return inl(0xcfc); ++} ++ ++static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr) ++{ ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); ++ return inw(0xcfc + (addr & 2)); ++} ++ ++static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr) ++{ ++ outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); ++ return inb(0xcfc + (addr & 3)); ++} ++ ++static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr) ++{ ++ uint16_t cmd; ++ uint32_t ofs, old_addr; ++ ++ if ( region_num == PCI_ROM_SLOT ) { ++ ofs = 0x30; ++ }else{ ++ ofs = 0x10 + region_num * 4; ++ } ++ ++ old_addr = pci_config_readl(d, ofs); ++ ++ pci_config_writel(d, ofs, addr); ++ BX_INFO("region %d: 0x%08x\n", region_num, addr); ++ ++ /* enable memory mappings */ ++ cmd = pci_config_readw(d, PCI_COMMAND); ++ if ( region_num == PCI_ROM_SLOT ) ++ cmd |= 2; ++ else if (old_addr & PCI_ADDRESS_SPACE_IO) ++ cmd |= 1; ++ else ++ cmd |= 2; ++ pci_config_writew(d, PCI_COMMAND, cmd); ++} ++ ++/* return the global irq number corresponding to a given device irq ++ pin. We could also use the bus number to have a more precise ++ mapping. */ ++static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) ++{ ++ int slot_addend; ++ slot_addend = (pci_dev->devfn >> 3) - 1; ++ return (irq_num + slot_addend) & 3; ++} ++ ++static int find_bios_table_area(void) ++{ ++ unsigned long addr; ++ for(addr = 0xf0000; addr < 0x100000; addr += 16) { ++ if (*(uint32_t *)addr == 0xaafb4442) { ++ bios_table_cur_addr = addr + 8; ++ bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4); ++ BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n", ++ bios_table_cur_addr, bios_table_end_addr); ++ return 0; ++ } ++ } ++ return -1; ++} ++ ++static void bios_shadow_init(PCIDevice *d) ++{ ++ int v; ++ ++ if (find_bios_table_area() < 0) ++ return; ++ ++ /* remap the BIOS to shadow RAM an keep it read/write while we ++ are writing tables */ ++ memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000); ++ v = pci_config_readb(d, 0x67); ++ v = (v & 0x0f) | (0x30); ++ pci_config_writeb(d, 0x67, v); ++ memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000); ++ ++ i440_pcidev = *d; ++} ++ ++static void bios_lock_shadow_ram(void) ++{ ++ PCIDevice *d = &i440_pcidev; ++ int v; ++ ++ v = pci_config_readb(d, 0x67); ++ v = (v & 0x0f) | (0x20); ++ pci_config_writeb(d, 0x67, v); ++} ++ ++static void pci_bios_init_bridges(PCIDevice *d) ++{ ++ uint16_t vendor_id, device_id; ++ ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID); ++ device_id = pci_config_readw(d, PCI_DEVICE_ID); ++ ++ if (vendor_id == 0x8086 && device_id == 0x7000) { ++ int i, irq; ++ uint8_t elcr[2]; ++ ++ /* PIIX3 bridge */ ++ ++ elcr[0] = 0x00; ++ elcr[1] = 0x00; ++ for(i = 0; i < 4; i++) { ++ irq = pci_irqs[i]; ++ /* set to trigger level */ ++ elcr[irq >> 3] |= (1 << (irq & 7)); ++ /* activate irq remapping in PIIX */ ++ pci_config_writeb(d, 0x60 + i, irq); ++ } ++ outb(0x4d0, elcr[0]); ++ outb(0x4d1, elcr[1]); ++ BX_INFO("PIIX3 init: elcr=%02x %02x\n", ++ elcr[0], elcr[1]); ++ } else if (vendor_id == 0x8086 && device_id == 0x1237) { ++ /* i440 PCI bridge */ ++ bios_shadow_init(d); ++ } ++} ++ ++extern uint8_t smm_relocation_start, smm_relocation_end; ++extern uint8_t smm_code_start, smm_code_end; ++ ++#ifdef BX_USE_SMM ++static void smm_init(void) ++{ ++ /* copy the SMM relocation code */ ++ memcpy((void *)0x38000, &smm_relocation_start, ++ &smm_relocation_end - &smm_relocation_start); ++ /* raise an SMI interrupt */ ++ outb(0xb2, 00); ++ ++ /* enable the SMM memory window */ ++ pci_config_writel(&i440_pcidev, 0x6c, (1 << 26) | 0x000a); ++ ++ /* copy the SMM code */ ++ memcpy((void *)0xa8000, &smm_code_start, ++ &smm_code_end - &smm_code_start); ++ ++ /* close the SMM memory window and enable normal SMM */ ++ pci_config_writel(&i440_pcidev, 0x6c, (1 << 31) | 0x000a); ++} ++#endif ++ ++static void pci_bios_init_device(PCIDevice *d) ++{ ++ int class; ++ uint32_t *paddr; ++ int i, pin, pic_irq, vendor_id, device_id; ++ ++ class = pci_config_readw(d, PCI_CLASS_DEVICE); ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID); ++ device_id = pci_config_readw(d, PCI_DEVICE_ID); ++ BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n", ++ d->bus, d->devfn, vendor_id, device_id); ++ switch(class) { ++ case 0x0101: ++ if (vendor_id == 0x8086 && device_id == 0x7010) { ++ /* PIIX3 IDE */ ++ pci_config_writew(d, 0x40, 0x8000); // enable IDE0 ++ pci_config_writew(d, 0x42, 0x8000); // enable IDE1 ++ goto default_map; ++ } else { ++ /* IDE: we map it as in ISA mode */ ++ pci_set_io_region_addr(d, 0, 0x1f0); ++ pci_set_io_region_addr(d, 1, 0x3f4); ++ pci_set_io_region_addr(d, 2, 0x170); ++ pci_set_io_region_addr(d, 3, 0x374); ++ } ++ break; ++ case 0x0300: ++ if (vendor_id != 0x1234) ++ goto default_map; ++ /* VGA: map frame buffer to default Bochs VBE address */ ++ pci_set_io_region_addr(d, 0, 0xE0000000); ++ break; ++ case 0x0800: ++ /* PIC */ ++ if (vendor_id == 0x1014) { ++ /* IBM */ ++ if (device_id == 0x0046 || device_id == 0xFFFF) { ++ /* MPIC & MPIC2 */ ++ pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000); ++ } ++ } ++ break; ++ case 0xff00: ++ if (vendor_id == 0x0106b && ++ (device_id == 0x0017 || device_id == 0x0022)) { ++ /* macio bridge */ ++ pci_set_io_region_addr(d, 0, 0x80800000); ++ } ++ break; ++ default: ++ default_map: ++ /* default memory mappings */ ++ for(i = 0; i < PCI_NUM_REGIONS; i++) { ++ int ofs; ++ uint32_t val, size ; ++ ++ if (i == PCI_ROM_SLOT) ++ ofs = 0x30; ++ else ++ ofs = 0x10 + i * 4; ++ pci_config_writel(d, ofs, 0xffffffff); ++ val = pci_config_readl(d, ofs); ++ if (val != 0) { ++ size = (~(val & ~0xf)) + 1; ++ if (val & PCI_ADDRESS_SPACE_IO) ++ paddr = &pci_bios_io_addr; ++ else ++ paddr = &pci_bios_mem_addr; ++ *paddr = (*paddr + size - 1) & ~(size - 1); ++ pci_set_io_region_addr(d, i, *paddr); ++ *paddr += size; ++ } ++ } ++ break; ++ } ++ ++ /* map the interrupt */ ++ pin = pci_config_readb(d, PCI_INTERRUPT_PIN); ++ if (pin != 0) { ++ pin = pci_slot_get_pirq(d, pin - 1); ++ pic_irq = pci_irqs[pin]; ++ pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq); ++ } ++ ++ if (vendor_id == 0x8086 && device_id == 0x7113) { ++ /* PIIX4 Power Management device (for ACPI) */ ++ pm_io_base = PM_IO_BASE; ++ pci_config_writel(d, 0x40, pm_io_base | 1); ++ pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */ ++ pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE); ++#ifdef BX_USE_SMM ++ smm_init(); ++#endif ++ acpi_enabled = 1; ++ } ++} ++ ++void pci_for_each_device(void (*init_func)(PCIDevice *d)) ++{ ++ PCIDevice d1, *d = &d1; ++ int bus, devfn; ++ uint16_t vendor_id, device_id; ++ ++ for(bus = 0; bus < 1; bus++) { ++ for(devfn = 0; devfn < 256; devfn++) { ++ d->bus = bus; ++ d->devfn = devfn; ++ vendor_id = pci_config_readw(d, PCI_VENDOR_ID); ++ device_id = pci_config_readw(d, PCI_DEVICE_ID); ++ if (vendor_id != 0xffff || device_id != 0xffff) { ++ init_func(d); ++ } ++ } ++ } ++} ++ ++void pci_bios_init(void) ++{ ++ pci_bios_io_addr = 0xc000; ++ pci_bios_mem_addr = 0xf0000000; ++ ++ pci_for_each_device(pci_bios_init_bridges); ++ ++ pci_for_each_device(pci_bios_init_device); ++} ++ ++/****************************************************/ ++/* Multi Processor table init */ ++ ++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; ++} ++ ++static unsigned long align(unsigned long addr, unsigned long v) ++{ ++ return (addr + v - 1) & ~(v - 1); ++} ++ ++static void mptable_init(void) ++{ ++ uint8_t *mp_config_table, *q, *float_pointer_struct; ++ int ioapic_id, i, len; ++ int mp_config_table_size; ++ ++ if (smp_cpus <= 1) ++ return; ++ ++#ifdef BX_USE_EBDA_TABLES ++ mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE); ++#else ++ bios_table_cur_addr = align(bios_table_cur_addr, 16); ++ mp_config_table = (uint8_t *)bios_table_cur_addr; ++#endif ++ 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); ++ ++ mp_config_table_size = q - mp_config_table; ++ ++#ifndef BX_USE_EBDA_TABLES ++ bios_table_cur_addr += mp_config_table_size; ++#endif ++ ++ /* floating pointer structure */ ++#ifdef BX_USE_EBDA_TABLES ++ ebda_cur_addr = align(ebda_cur_addr, 16); ++ float_pointer_struct = (uint8_t *)ebda_cur_addr; ++#else ++ bios_table_cur_addr = align(bios_table_cur_addr, 16); ++ float_pointer_struct = (uint8_t *)bios_table_cur_addr; ++#endif ++ q = float_pointer_struct; ++ putstr(&q, "_MP_"); ++ /* pointer to MP config table */ ++ putle32(&q, (unsigned long)mp_config_table); ++ ++ 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); ++#ifdef BX_USE_EBDA_TABLES ++ ebda_cur_addr += (q - float_pointer_struct); ++#else ++ bios_table_cur_addr += (q - float_pointer_struct); ++#endif ++ BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n", ++ (unsigned long)float_pointer_struct, ++ (unsigned long)mp_config_table, ++ mp_config_table_size); ++} ++ ++/****************************************************/ ++/* ACPI tables init */ ++ ++/* Table structure from Linux kernel (the ACPI tables are under the ++ BSD license) */ ++ ++#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \ ++ uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\ ++ uint32_t length; /* Length of table, in bytes, including header */\ ++ uint8_t revision; /* ACPI Specification minor version # */\ ++ uint8_t checksum; /* To make sum of entire table == 0 */\ ++ uint8_t oem_id [6]; /* OEM identification */\ ++ uint8_t oem_table_id [8]; /* OEM table identification */\ ++ uint32_t oem_revision; /* OEM revision number */\ ++ uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\ ++ uint32_t asl_compiler_revision; /* ASL compiler revision number */ ++ ++ ++struct acpi_table_header /* ACPI common table header */ ++{ ++ ACPI_TABLE_HEADER_DEF ++}; ++ ++struct rsdp_descriptor /* Root System Descriptor Pointer */ ++{ ++ uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */ ++ uint8_t checksum; /* To make sum of struct == 0 */ ++ uint8_t oem_id [6]; /* OEM identification */ ++ uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */ ++ uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */ ++ uint32_t length; /* XSDT Length in bytes including hdr */ ++ uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */ ++ uint8_t extended_checksum; /* Checksum of entire table */ ++ uint8_t reserved [3]; /* Reserved field must be 0 */ ++}; ++ ++/* ++ * ACPI 1.0 Root System Description Table (RSDT) ++ */ ++struct rsdt_descriptor_rev1 ++{ ++ ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ++ uint32_t table_offset_entry [2]; /* Array of pointers to other */ ++ /* ACPI tables */ ++}; ++ ++/* ++ * ACPI 1.0 Firmware ACPI Control Structure (FACS) ++ */ ++struct facs_descriptor_rev1 ++{ ++ uint8_t signature[4]; /* ACPI Signature */ ++ uint32_t length; /* Length of structure, in bytes */ ++ uint32_t hardware_signature; /* Hardware configuration signature */ ++ uint32_t firmware_waking_vector; /* ACPI OS waking vector */ ++ uint32_t global_lock; /* Global Lock */ ++ uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */ ++ uint32_t reserved1 : 31; /* Must be 0 */ ++ uint8_t resverved3 [40]; /* Reserved - must be zero */ ++}; ++ ++ ++/* ++ * ACPI 1.0 Fixed ACPI Description Table (FADT) ++ */ ++struct fadt_descriptor_rev1 ++{ ++ ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ++ uint32_t firmware_ctrl; /* Physical address of FACS */ ++ uint32_t dsdt; /* Physical address of DSDT */ ++ uint8_t model; /* System Interrupt Model */ ++ uint8_t reserved1; /* Reserved */ ++ uint16_t sci_int; /* System vector of SCI interrupt */ ++ uint32_t smi_cmd; /* Port address of SMI command port */ ++ uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */ ++ uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */ ++ uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ ++ uint8_t reserved2; /* Reserved - must be zero */ ++ uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ ++ uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ ++ uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ ++ uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ ++ uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ ++ uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ ++ uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ ++ uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ ++ uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ ++ uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ ++ uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ ++ uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */ ++ uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ ++ uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ ++ uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */ ++ uint8_t reserved3; /* Reserved */ ++ uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ ++ uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ ++ uint16_t flush_size; /* Size of area read to flush caches */ ++ uint16_t flush_stride; /* Stride used in flushing caches */ ++ uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */ ++ uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */ ++ uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ ++ uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ ++ uint8_t century; /* Index to century in RTC CMOS RAM */ ++ uint8_t reserved4; /* Reserved */ ++ uint8_t reserved4a; /* Reserved */ ++ uint8_t reserved4b; /* Reserved */ ++#if 0 ++ uint32_t wb_invd : 1; /* The wbinvd instruction works properly */ ++ uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ ++ uint32_t proc_c1 : 1; /* All processors support C1 state */ ++ uint32_t plvl2_up : 1; /* C2 state works on MP system */ ++ uint32_t pwr_button : 1; /* Power button is handled as a generic feature */ ++ uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ ++ uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ ++ uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ ++ uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */ ++ uint32_t reserved5 : 23; /* Reserved - must be zero */ ++#else ++ uint32_t flags; ++#endif ++}; ++ ++/* ++ * MADT values and structures ++ */ ++ ++/* Values for MADT PCATCompat */ ++ ++#define DUAL_PIC 0 ++#define MULTIPLE_APIC 1 ++ ++ ++/* Master MADT */ ++ ++struct multiple_apic_table ++{ ++ ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ++ uint32_t local_apic_address; /* Physical address of local APIC */ ++#if 0 ++ uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */ ++ uint32_t reserved1 : 31; ++#else ++ uint32_t flags; ++#endif ++}; ++ ++ ++/* Values for Type in APIC_HEADER_DEF */ ++ ++#define APIC_PROCESSOR 0 ++#define APIC_IO 1 ++#define APIC_XRUPT_OVERRIDE 2 ++#define APIC_NMI 3 ++#define APIC_LOCAL_NMI 4 ++#define APIC_ADDRESS_OVERRIDE 5 ++#define APIC_IO_SAPIC 6 ++#define APIC_LOCAL_SAPIC 7 ++#define APIC_XRUPT_SOURCE 8 ++#define APIC_RESERVED 9 /* 9 and greater are reserved */ ++ ++/* ++ * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE) ++ */ ++#define APIC_HEADER_DEF /* Common APIC sub-structure header */\ ++ uint8_t type; \ ++ uint8_t length; ++ ++/* Sub-structures for MADT */ ++ ++struct madt_processor_apic ++{ ++ APIC_HEADER_DEF ++ uint8_t processor_id; /* ACPI processor id */ ++ uint8_t local_apic_id; /* Processor's local APIC id */ ++#if 0 ++ uint32_t processor_enabled: 1; /* Processor is usable if set */ ++ uint32_t reserved2 : 31; /* Reserved, must be zero */ ++#else ++ uint32_t flags; ++#endif ++}; ++ ++struct madt_io_apic ++{ ++ APIC_HEADER_DEF ++ uint8_t io_apic_id; /* I/O APIC ID */ ++ uint8_t reserved; /* Reserved - must be zero */ ++ uint32_t address; /* APIC physical address */ ++ uint32_t interrupt; /* Global system interrupt where INTI ++ * lines start */ ++}; ++ ++#include "acpi-dsdt.hex" ++ ++static inline uint16_t cpu_to_le16(uint16_t x) ++{ ++ return x; ++} ++ ++static inline uint32_t cpu_to_le32(uint32_t x) ++{ ++ return x; ++} ++ ++static int acpi_checksum(const uint8_t *data, int len) ++{ ++ int sum, i; ++ sum = 0; ++ for(i = 0; i < len; i++) ++ sum += data[i]; ++ return (-sum) & 0xff; ++} ++ ++static void acpi_build_table_header(struct acpi_table_header *h, ++ char *sig, int len) ++{ ++ memcpy(h->signature, sig, 4); ++ h->length = cpu_to_le32(len); ++ h->revision = 0; ++ memcpy(h->oem_id, "QEMU ", 6); ++ memcpy(h->oem_table_id, "QEMU", 4); ++ memcpy(h->oem_table_id + 4, sig, 4); ++ h->oem_revision = cpu_to_le32(1); ++ memcpy(h->asl_compiler_id, "QEMU", 4); ++ h->asl_compiler_revision = cpu_to_le32(1); ++ h->checksum = acpi_checksum((void *)h, len); ++} ++ ++/* base_addr must be a multiple of 4KB */ ++void acpi_bios_init(void) ++{ ++ struct rsdp_descriptor *rsdp; ++ struct rsdt_descriptor_rev1 *rsdt; ++ struct fadt_descriptor_rev1 *fadt; ++ struct facs_descriptor_rev1 *facs; ++ struct multiple_apic_table *madt; ++ uint8_t *dsdt; ++ uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr; ++ uint32_t acpi_tables_size, madt_addr, madt_size; ++ int i; ++ ++ /* reserve memory space for tables */ ++#ifdef BX_USE_EBDA_TABLES ++ ebda_cur_addr = align(ebda_cur_addr, 16); ++ rsdp = (void *)(ebda_cur_addr); ++ ebda_cur_addr += sizeof(*rsdp); ++#else ++ bios_table_cur_addr = align(bios_table_cur_addr, 16); ++ rsdp = (void *)(bios_table_cur_addr); ++ bios_table_cur_addr += sizeof(*rsdp); ++#endif ++ ++ addr = base_addr = ram_size - ACPI_DATA_SIZE; ++ rsdt_addr = addr; ++ rsdt = (void *)(addr); ++ addr += sizeof(*rsdt); ++ ++ fadt_addr = addr; ++ fadt = (void *)(addr); ++ addr += sizeof(*fadt); ++ ++ /* XXX: FACS should be in RAM */ ++ addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */ ++ facs_addr = addr; ++ facs = (void *)(addr); ++ addr += sizeof(*facs); ++ ++ dsdt_addr = addr; ++ dsdt = (void *)(addr); ++ addr += sizeof(AmlCode); ++ ++ addr = (addr + 7) & ~7; ++ madt_addr = addr; ++ madt_size = sizeof(*madt) + ++ sizeof(struct madt_processor_apic) * smp_cpus + ++ sizeof(struct madt_io_apic); ++ madt = (void *)(addr); ++ addr += madt_size; ++ ++ acpi_tables_size = addr - base_addr; ++ ++ BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n", ++ (unsigned long)rsdp, ++ (unsigned long)rsdt, acpi_tables_size); ++ ++ /* RSDP */ ++ memset(rsdp, 0, sizeof(*rsdp)); ++ memcpy(rsdp->signature, "RSD PTR ", 8); ++ memcpy(rsdp->oem_id, "QEMU ", 6); ++ rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr); ++ rsdp->checksum = acpi_checksum((void *)rsdp, 20); ++ ++ /* RSDT */ ++ rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr); ++ rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr); ++ acpi_build_table_header((struct acpi_table_header *)rsdt, ++ "RSDT", sizeof(*rsdt)); ++ ++ /* FADT */ ++ memset(fadt, 0, sizeof(*fadt)); ++ fadt->firmware_ctrl = cpu_to_le32(facs_addr); ++ fadt->dsdt = cpu_to_le32(dsdt_addr); ++ fadt->model = 1; ++ fadt->reserved1 = 0; ++ fadt->sci_int = cpu_to_le16(pm_sci_int); ++ fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR); ++ fadt->acpi_enable = 0xf1; ++ fadt->acpi_disable = 0xf0; ++ fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base); ++ fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04); ++ fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08); ++ fadt->pm1_evt_len = 4; ++ fadt->pm1_cnt_len = 2; ++ fadt->pm_tmr_len = 4; ++ fadt->plvl2_lat = cpu_to_le16(50); ++ fadt->plvl3_lat = cpu_to_le16(50); ++ fadt->plvl3_lat = cpu_to_le16(50); ++ /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */ ++ fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6)); ++ acpi_build_table_header((struct acpi_table_header *)fadt, "FACP", ++ sizeof(*fadt)); ++ ++ /* FACS */ ++ memset(facs, 0, sizeof(*facs)); ++ memcpy(facs->signature, "FACS", 4); ++ facs->length = cpu_to_le32(sizeof(*facs)); ++ ++ /* DSDT */ ++ memcpy(dsdt, AmlCode, sizeof(AmlCode)); ++ ++ /* MADT */ ++ { ++ struct madt_processor_apic *apic; ++ struct madt_io_apic *io_apic; ++ ++ memset(madt, 0, madt_size); ++ madt->local_apic_address = cpu_to_le32(0xfee00000); ++ madt->flags = cpu_to_le32(1); ++ apic = (void *)(madt + 1); ++ for(i=0;itype = APIC_PROCESSOR; ++ apic->length = sizeof(*apic); ++ apic->processor_id = i; ++ apic->local_apic_id = i; ++ apic->flags = cpu_to_le32(1); ++ apic++; ++ } ++ io_apic = (void *)apic; ++ io_apic->type = APIC_IO; ++ io_apic->length = sizeof(*io_apic); ++ io_apic->io_apic_id = smp_cpus; ++ io_apic->address = cpu_to_le32(0xfec00000); ++ io_apic->interrupt = cpu_to_le32(0); ++ ++ acpi_build_table_header((struct acpi_table_header *)madt, ++ "APIC", madt_size); ++ } ++} ++ ++void rombios32_init(void) ++{ ++ BX_INFO("Starting rombios32\n"); ++ ++ ram_probe(); ++ ++ cpu_probe(); ++ ++ smp_probe(); ++ ++ pci_bios_init(); ++ ++ if (bios_table_cur_addr != 0) { ++ ++ mptable_init(); ++ ++ if (acpi_enabled) ++ acpi_bios_init(); ++ ++ bios_lock_shadow_ram(); ++ } ++} +diff -ruN --exclude Makefile bios/rombios32.ld bios.new/rombios32.ld +--- bios/rombios32.ld 1970-01-01 01:00:00.000000000 +0100 ++++ bios.new/rombios32.ld 2006-09-24 20:28:05.000000000 +0200 +@@ -0,0 +1,19 @@ ++OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") ++OUTPUT_ARCH(i386) ++ENTRY(_start); ++SECTIONS ++{ ++ . = 0x00040000; ++ .text : { *(.text) } ++ .rodata : { *(.rodata) } ++ . = ALIGN(4096); ++ .data : { *(.data) } ++ __bss_start = . ; ++ .bss : { *(.bss) *(COMMON) } ++ _end = . ; ++ /DISCARD/ : { *(.stab) ++ *(.stabstr) ++ *(.comment) ++ *(.note) ++ } ++} +diff -ruN --exclude Makefile bios/rombios32start.S bios.new/rombios32start.S +--- bios/rombios32start.S 1970-01-01 01:00:00.000000000 +0100 ++++ bios.new/rombios32start.S 2006-09-24 20:22:58.000000000 +0200 +@@ -0,0 +1,76 @@ ++.globl _start ++.globl smp_ap_boot_code_start ++.globl smp_ap_boot_code_end ++.global smm_relocation_start ++.global smm_relocation_end ++.global smm_code_start ++.global smm_code_end ++ ++#define PM_IO_BASE 0xb000 ++ ++_start: ++ /* clear bss section */ ++ xor %eax, %eax ++ mov $__bss_start, %edi ++ mov $_end, %ecx ++ sub %edi, %ecx ++ rep stosb ++ ++ jmp rombios32_init ++ ++#define CPU_COUNT 0xf000 ++ ++ .code16 ++smp_ap_boot_code_start: ++ xor %ax, %ax ++ mov %ax, %ds ++ incw CPU_COUNT ++1: ++ hlt ++ jmp 1b ++smp_ap_boot_code_end: ++ ++/* code to relocate SMBASE to 0xa0000 */ ++smm_relocation_start: ++ mov $0x38000 + 0x7efc, %ebx ++ mov (%ebx), %al /* revision ID to see if x86_64 or x86 */ ++ cmp $0x64, %al ++ je 1f ++ mov $0x38000 + 0x7ef8, %ebx ++ jmp 2f ++1: ++ mov $0x38000 + 0x7f00, %ebx ++2: ++ movl $0xa0000, %eax ++ movl %eax, (%ebx) ++ rsm ++smm_relocation_end: ++ ++/* minimal SMM code to enable or disable ACPI */ ++smm_code_start: ++ movw $0xb2, %dx ++ inb %dx, %al ++ cmp $0xf0, %al ++ jne 1f ++ ++ /* ACPI disable */ ++ mov $PM_IO_BASE + 0x04, %dx /* PMCNTRL */ ++ inw %dx, %ax ++ andw $~1, %ax ++ outw %ax, %dx ++ ++ jmp 2f ++ ++1: ++ cmp $0xf1, %al ++ jne 2f ++ ++ /* ACPI enable */ ++ mov $PM_IO_BASE + 0x04, %dx /* PMCNTRL */ ++ inw %dx, %ax ++ orw $1, %ax ++ outw %ax, %dx ++ ++2: ++ rsm ++smm_code_end: +diff -ruN --exclude Makefile bios/rombios.c bios.new/rombios.c +--- bios/rombios.c 2006-08-11 19:34:12.000000000 +0200 ++++ bios.new/rombios.c 2006-09-24 20:35:47.000000000 +0200 +@@ -24,7 +24,7 @@ + // License along with this library; if not, write to the Free Software + // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +-// ROM BIOS for use with Bochs/Plex x86 emulation environment ++// ROM BIOS for use with Bochs/Plex x86/QEMU emulation environment + + + // ROM BIOS compatability entry points: +@@ -143,6 +143,7 @@ + #define BX_FLOPPY_ON_CNT 37 /* 2 seconds */ + #define BX_PCIBIOS 1 + #define BX_APM 1 ++#define BX_ROMBIOS32 1 + + #define BX_USE_ATADRV 1 + #define BX_ELTORITO_BOOT 1 +@@ -159,6 +160,9 @@ + #define BIOS_REVISION 1 + #define BIOS_CONFIG_TABLE 0xe6f5 + ++/* define it to include QEMU specific code */ ++#define BX_QEMU ++ + #ifndef BIOS_BUILD_DATE + # define BIOS_BUILD_DATE "06/23/99" + #endif +@@ -170,7 +174,9 @@ + #define BASE_MEM_IN_K (640 - EBDA_SIZE) + + // Define the application NAME +-#ifdef PLEX86 ++#if defined(BX_QEMU) ++# define BX_APPNAME "QEMU" ++#elif defined(PLEX86) + # define BX_APPNAME "Plex86" + #else + # define BX_APPNAME "Bochs" +@@ -1826,6 +1832,9 @@ + #ifdef BX_ELTORITO_BOOT + "eltorito " + #endif ++#ifdef BX_ROMBIOS32 ++ "rombios32 " ++#endif + "\n\n"); + } + +@@ -4085,6 +4094,24 @@ + case 0x20: // coded by osmaker aka K.J. + if(regs.u.r32.edx == 0x534D4150) + { ++ extended_memory_size = inb_cmos(0x35); ++ extended_memory_size <<= 8; ++ extended_memory_size |= inb_cmos(0x34); ++ extended_memory_size *= 64; ++ // greater than EFF00000??? ++ if(extended_memory_size > 0x3bc000) { ++ extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000 ++ } ++ extended_memory_size *= 1024; ++ extended_memory_size += (16L * 1024 * 1024); ++ ++ if(extended_memory_size <= (16L * 1024 * 1024)) { ++ extended_memory_size = inb_cmos(0x31); ++ extended_memory_size <<= 8; ++ extended_memory_size |= inb_cmos(0x30); ++ extended_memory_size *= 1024; ++ } ++ switch(regs.u.r16.bx) { case 0: -- write_word(ES, regs.u.r16.di, 0x00); -- write_word(ES, regs.u.r16.di+2, 0x00); -- write_word(ES, regs.u.r16.di+4, 0x00); -- write_word(ES, regs.u.r16.di+6, 0x00); -- -- write_word(ES, regs.u.r16.di+8, 0xFC00); -- write_word(ES, regs.u.r16.di+10, 0x0009); -- write_word(ES, regs.u.r16.di+12, 0x0000); -- write_word(ES, regs.u.r16.di+14, 0x0000); -- -- write_word(ES, regs.u.r16.di+16, 0x1); -- write_word(ES, regs.u.r16.di+18, 0x0); -- -+ set_e820_range(ES, regs.u.r16.di, -+ 0x0000000L, 0x0009fc00L, 1); - regs.u.r32.ebx = 1; - regs.u.r32.eax = 0x534D4150; - regs.u.r32.ecx = 0x14; -@@ -4083,6 +4099,24 @@ +@@ -4115,27 +4142,9 @@ return; break; - case 1: + case 3: +- extended_memory_size = inb_cmos(0x35); +- extended_memory_size <<= 8; +- extended_memory_size |= inb_cmos(0x34); +- extended_memory_size *= 64; +- if(extended_memory_size > 0x3bc000) // greater than EFF00000??? +- { +- extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000 +- } +- extended_memory_size *= 1024; +- extended_memory_size += (16L * 1024 * 1024); +- +- if(extended_memory_size <= (16L * 1024 * 1024)) +- { +- extended_memory_size = inb_cmos(0x31); +- extended_memory_size <<= 8; +- extended_memory_size |= inb_cmos(0x30); +- extended_memory_size *= 1024; +- } +- + set_e820_range(ES, regs.u.r16.di, +- 0x00100000L, extended_memory_size, 1); ++ 0x00100000L, ++ extended_memory_size - 0x10000L, 1); + regs.u.r32.ebx = 4; + regs.u.r32.eax = 0x534D4150; + regs.u.r32.ecx = 0x14; +@@ -4143,6 +4152,16 @@ + return; + break; + case 4: + set_e820_range(ES, regs.u.r16.di, -+ 0x0009fc00L, 0x000a0000L, 2); -+ regs.u.r32.ebx = 2; ++ extended_memory_size - 0x10000L, ++ extended_memory_size, 3); // ACPI RAM ++ regs.u.r32.ebx = 5; + regs.u.r32.eax = 0x534D4150; + regs.u.r32.ecx = 0x14; + CLEAR_CF(); + return; + break; -+ case 2: -+ set_e820_range(ES, regs.u.r16.di, -+ 0x000e8000L, 0x00100000L, 2); -+ regs.u.r32.ebx = 3; -+ regs.u.r32.eax = 0x534D4150; -+ regs.u.r32.ecx = 0x14; -+ CLEAR_CF(); -+ return; -+ break; -+ case 3: - extended_memory_size = inb_cmos(0x35); - extended_memory_size <<= 8; - extended_memory_size |= inb_cmos(0x34); -@@ -4092,9 +4126,9 @@ - extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000 - } - extended_memory_size *= 1024; -- extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off -+ extended_memory_size += (16L * 1024 * 1024); - -- if(extended_memory_size <= 15728640) -+ if(extended_memory_size <= (16L * 1024 * 1024)) - { - extended_memory_size = inb_cmos(0x31); - extended_memory_size <<= 8; -@@ -4102,28 +4136,23 @@ - extended_memory_size *= 1024; - } - -- write_word(ES, regs.u.r16.di, 0x0000); -- write_word(ES, regs.u.r16.di+2, 0x0010); -- write_word(ES, regs.u.r16.di+4, 0x0000); -- write_word(ES, regs.u.r16.di+6, 0x0000); -- -- write_word(ES, regs.u.r16.di+8, extended_memory_size); -- extended_memory_size >>= 16; -- write_word(ES, regs.u.r16.di+10, extended_memory_size); -- extended_memory_size >>= 16; -- write_word(ES, regs.u.r16.di+12, extended_memory_size); -- extended_memory_size >>= 16; -- write_word(ES, regs.u.r16.di+14, extended_memory_size); -- -- write_word(ES, regs.u.r16.di+16, 0x1); -- write_word(ES, regs.u.r16.di+18, 0x0); -- -- regs.u.r32.ebx = 0; -+ set_e820_range(ES, regs.u.r16.di, -+ 0x00100000L, extended_memory_size, 1); -+ regs.u.r32.ebx = 4; - regs.u.r32.eax = 0x534D4150; - regs.u.r32.ecx = 0x14; - CLEAR_CF(); - return; - break; -+ case 4: -+ /* 256KB BIOS area at the end of 4 GB */ -+ set_e820_range(ES, regs.u.r16.di, -+ 0xfffc0000L, 0x00000000L, 2); -+ regs.u.r32.ebx = 0; -+ regs.u.r32.eax = 0x534D4150; -+ regs.u.r32.ecx = 0x14; -+ CLEAR_CF(); -+ return; - default: /* AX=E820, DX=534D4150, BX unrecognized */ - goto int15_unimplemented; - break; -@@ -8713,6 +8742,7 @@ ++ case 5: + /* 256KB BIOS area at the end of 4 GB */ + set_e820_range(ES, regs.u.r16.di, + 0xfffc0000L, 0x00000000L, 2); +@@ -8757,6 +8776,9 @@ + unknown_service: mov al, #0x80 bios32_end: ++#ifdef BX_QEMU ++ and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu ++#endif popf -+ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu retf - .align 16 -@@ -8823,17 +8853,17 @@ +@@ -8868,6 +8890,9 @@ pci_pro_fail: pop edi pop esi -- sti ++#ifdef BX_QEMU ++ and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu ++#endif popf stc -+ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu retf - pci_pro_ok: +@@ -8875,6 +8900,9 @@ xor ah, ah pop edi pop esi -- sti ++#ifdef BX_QEMU ++ and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu ++#endif popf clc -+ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu retf - - pci_pro_select_reg: -@@ -8971,7 +9001,7 @@ - jmp pci_real_ok - pci_real_f0d: ;; write configuration dword - cmp al, #0x0d -- jne pci_real_unknown -+ jne pci_real_f0e - call pci_real_select_reg - push dx - mov dx, #0x0cfc -@@ -8979,6 +9009,46 @@ - out dx, eax - pop dx - jmp pci_real_ok -+pci_real_f0e: ;; get irq routing options -+ cmp al, #0x0e -+ jne pci_real_unknown -+ SEG ES -+ cmp word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start -+ jb pci_real_too_small -+ SEG ES -+ mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start -+ pushf -+ push ds -+ push es -+ push cx -+ push si -+ push di -+ cld -+ mov si, #pci_routing_table_structure_start -+ push cs -+ pop ds -+ SEG ES -+ mov cx, [di+2] -+ SEG ES -+ mov es, [di+4] -+ mov di, cx -+ mov cx, #pci_routing_table_structure_end - pci_routing_table_structure_start -+ rep -+ movsb -+ pop di -+ pop si -+ pop cx -+ pop es -+ pop ds -+ popf -+ mov bx, #(1 << 9) | (1 << 11) ;; irq 9 and 11 are used -+ jmp pci_real_ok -+pci_real_too_small: -+ SEG ES -+ mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start -+ mov ah, #0x89 -+ jmp pci_real_fail -+ - pci_real_unknown: - mov ah, #0x81 - pci_real_fail: -@@ -9019,6 +9089,7 @@ - dw 0,0 ;; Miniport data - db 0,0,0,0,0,0,0,0,0,0,0 ;; reserved - db 0x07 ;; checksum -+pci_routing_table_structure_start: - ;; first slot entry PCI-to-ISA (embedded) - db 0 ;; pci bus number - db 0x08 ;; pci device number (bit 7-3) -@@ -9097,6 +9168,7 @@ - dw 0xdef8 ;; IRQ bitmap INTD# - db 5 ;; physical slot (0 = embedded) +@@ -9183,227 +9211,118 @@ db 0 ;; reserved -+pci_routing_table_structure_end: + pci_routing_table_structure_end: - pci_irq_list: - db 11, 10, 9, 5; +-pci_irq_list: +- db 11, 10, 9, 5; ++#endif // BX_PCIBIOS + +-pcibios_init_sel_reg: +- push eax +- mov eax, #0x800000 +- mov ax, bx +- shl eax, #8 +- and dl, #0xfc +- or al, dl +- mov dx, #0x0cf8 +- out dx, eax +- pop eax +- ret +- +-pcibios_init_iomem_bases: +- push bp +- mov bp, sp +- mov eax, #0xe0000000 ;; base for memory init +- push eax +- mov ax, #0xc000 ;; base for i/o init +- push ax +- mov ax, #0x0010 ;; start at base address #0 ++#if BX_ROMBIOS32 ++rombios32_init: ++ ;; save a20 and enable it ++ in al, 0x92 + push ax +- mov bx, #0x0008 +-pci_init_io_loop1: +- mov dl, #0x00 +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- in ax, dx +- cmp ax, #0xffff +- jz next_pci_dev +- mov dl, #0x04 ;; disable i/o and memory space access +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- in al, dx +- and al, #0xfc +- out dx, al +-pci_init_io_loop2: +- mov dl, [bp-8] +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- in eax, dx +- test al, #0x01 +- jnz init_io_base +- mov ecx, eax +- mov eax, #0xffffffff +- out dx, eax +- in eax, dx +- cmp eax, ecx +- je next_pci_base +- xor eax, #0xffffffff +- mov ecx, eax +- mov eax, [bp-4] +- out dx, eax +- add eax, ecx ;; calculate next free mem base +- add eax, #0x01000000 +- and eax, #0xff000000 +- mov [bp-4], eax +- jmp next_pci_base +-init_io_base: +- mov cx, ax +- mov ax, #0xffff +- out dx, ax +- in ax, dx +- cmp ax, cx +- je next_pci_base +- xor ax, #0xfffe +- mov cx, ax +- mov ax, [bp-6] +- out dx, ax +- add ax, cx ;; calculate next free i/o base +- add ax, #0x0100 +- and ax, #0xff00 +- mov [bp-6], ax +-next_pci_base: +- mov al, [bp-8] +- add al, #0x04 +- cmp al, #0x28 +- je enable_iomem_space +- mov byte ptr[bp-8], al +- jmp pci_init_io_loop2 +-enable_iomem_space: +- mov dl, #0x04 ;; enable i/o and memory space access if available +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- in al, dx +- or al, #0x07 +- out dx, al +-next_pci_dev: +- mov byte ptr[bp-8], #0x10 +- inc bx +- cmp bx, #0x0100 +- jne pci_init_io_loop1 +- mov sp, bp +- pop bp +- ret ++ or al, #0x02 ++ out 0x92, al + +-pcibios_init_set_elcr: +- push ax +- push cx +- mov dx, #0x04d0 +- test al, #0x08 +- jz is_master_pic +- inc dx +- and al, #0x07 +-is_master_pic: +- mov cl, al +- mov bl, #0x01 +- shl bl, cl +- in al, dx +- or al, bl +- out dx, al +- pop cx +- pop ax +- ret ++ ;; save SS:SP to the BDA ++ xor ax, ax ++ mov ds, ax ++ mov 0x0469, ss ++ mov 0x0467, sp + +-pcibios_init_irqs: +- push ds +- push bp +- mov ax, #0xf000 +- mov ds, ax +- mov dx, #0x04d0 ;; reset ELCR1 + ELCR2 +- mov al, #0x00 +- out dx, al +- inc dx +- out dx, al +- mov si, #pci_routing_table_structure +- mov bh, [si+8] +- mov bl, [si+9] +- mov dl, #0x00 +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- in eax, dx +- cmp eax, [si+12] ;; check irq router +- jne pci_init_end +- mov dl, [si+34] +- call pcibios_init_sel_reg +- push bx ;; save irq router bus + devfunc +- mov dx, #0x0cfc +- mov ax, #0x8080 +- out dx, ax ;; reset PIRQ route control +- inc dx +- inc dx +- out dx, ax +- mov ax, [si+6] +- sub ax, #0x20 +- shr ax, #4 +- mov cx, ax +- add si, #0x20 ;; set pointer to 1st entry +- mov bp, sp +- mov ax, #pci_irq_list +- push ax +- xor ax, ax +- push ax +-pci_init_irq_loop1: +- mov bh, [si] +- mov bl, [si+1] +-pci_init_irq_loop2: +- mov dl, #0x00 +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- in ax, dx +- cmp ax, #0xffff +- jnz pci_test_int_pin +- test bl, #0x07 +- jz next_pir_entry +- jmp next_pci_func +-pci_test_int_pin: +- mov dl, #0x3c +- call pcibios_init_sel_reg +- mov dx, #0x0cfd +- in al, dx +- and al, #0x07 +- jz next_pci_func +- dec al ;; determine pirq reg +- mov dl, #0x03 +- mul al, dl +- add al, #0x02 +- xor ah, ah +- mov bx, ax +- mov al, [si+bx] +- mov dl, al +- mov bx, [bp] +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- and al, #0x03 +- add dl, al +- in al, dx +- cmp al, #0x80 +- jb pirq_found +- mov bx, [bp-2] ;; pci irq list pointer +- mov al, [bx] +- out dx, al +- inc bx +- mov [bp-2], bx +- call pcibios_init_set_elcr +-pirq_found: +- mov bh, [si] +- mov bl, [si+1] +- add bl, [bp-3] ;; pci function number +- mov dl, #0x3c +- call pcibios_init_sel_reg +- mov dx, #0x0cfc +- out dx, al +-next_pci_func: +- inc byte ptr[bp-3] +- inc bl +- test bl, #0x07 +- jnz pci_init_irq_loop2 +-next_pir_entry: +- add si, #0x10 +- mov byte ptr[bp-3], #0x00 +- loop pci_init_irq_loop1 +- mov sp, bp +- pop bx +-pci_init_end: +- pop bp +- pop ds ++ SEG CS ++ lidt [pmode_IDT_info] ++ SEG CS ++ lgdt [rombios32_gdt_48] ++ ;; set PE bit in CR0 ++ mov eax, cr0 ++ or al, #0x01 ++ mov cr0, eax ++ ;; start protected mode code: ljmpl 0x10:rombios32_init1 ++ db 0x66, 0xea ++ dw rombios32_05 ++ dw 0x000f ;; high 16 bit address ++ dw 0x0010 ++ ++use32 386 ++rombios32_05: ++ ;; init data segments ++ mov eax, #0x18 ++ mov ds, ax ++ mov es, ax ++ mov ss, ax ++ xor eax, eax ++ mov fs, ax ++ mov gs, ax ++ cld ++ ++ ;; copy rombios32 code to ram (ram offset = 1MB) ++ mov esi, #0xfffe0000 ++ mov edi, #0x00040000 ++ mov ecx, #0x10000 / 4 ++ rep ++ movsd ++ ++ ;; init the stack pointer ++ mov esp, #0x00080000 ++ ++ ;; call rombios32 code ++ mov eax, #0x00040000 ++ call eax ++ ++ ;; return to 16 bit protected mode first ++ db 0xea ++ dd rombios32_10 ++ dw 0x20 ++ ++use16 386 ++rombios32_10: ++ ;; restore data segment limits to 0xffff ++ mov ax, #0x28 ++ mov ds, ax ++ mov es, ax ++ mov ss, ax ++ mov fs, ax ++ mov gs, ax ++ ++ ;; reset PE bit in CR0 ++ mov eax, cr0 ++ and al, #0xFE ++ mov cr0, eax ++ ++ ;; far jump to flush CPU queue after transition to real mode ++ JMP_AP(0xf000, rombios32_real_mode) ++ ++rombios32_real_mode: ++ ;; restore IDT to normal real-mode defaults ++ SEG CS ++ lidt [rmode_IDT_info] ++ ++ xor ax, ax ++ mov ds, ax ++ mov es, ax ++ mov fs, ax ++ mov gs, ax ++ ++ ;; restore SS:SP from the BDA ++ mov ss, 0x0469 ++ mov sp, 0x0467 ++ ;; restore a20 ++ pop ax ++ out 0x92, al + ret +-#endif // BX_PCIBIOS ++ ++rombios32_gdt_48: ++ dw 0x30 ++ dw rombios32_gdt ++ dw 0x000f ++ ++rombios32_gdt: ++ dw 0, 0, 0, 0 ++ dw 0, 0, 0, 0 ++ dw 0xffff, 0, 0x9b00, 0x00cf ; 32 bit flat code segment (0x10) ++ dw 0xffff, 0, 0x9300, 0x00cf ; 32 bit flat data segment (0x18) ++ dw 0xffff, 0, 0x9b0f, 0x0000 ; 16 bit code segment base=0xf0000 limit=0xffff ++ dw 0xffff, 0, 0x9300, 0x0000 ; 16 bit data segment base=0x0 limit=0xffff ++#endif ++ + + ; parallel port detection: base address in DX, index in BX, timeout in CL + detect_parport: +@@ -9535,10 +9454,17 @@ + ;; DATA_SEG_DEFS_HERE + + ++;; the following area can be used to write dynamically generated tables ++ .align 16 ++bios_table_area_start: ++ dd 0xaafb4442 ++ dd bios_table_area_end - bios_table_area_start - 8; ++ + ;-------- + ;- POST - + ;-------- + .org 0xe05b ; POST Entry Point ++bios_table_area_end: + post: + + xor ax, ax +@@ -9802,9 +9728,9 @@ + #endif + out 0xa1, AL ;slave pic: unmask IRQ 12, 13, 14 + +- call pcibios_init_iomem_bases +- call pcibios_init_irqs +- ++#if BX_ROMBIOS32 ++ call rombios32_init ++#endif + call rom_scan + + call _print_bios_banner