Breakup rombios32.c into pciinit.c and smbios.c
authorKevin O'Connor <kevin@koconnor.net>
Fri, 4 Jul 2008 10:18:30 +0000 (06:18 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Fri, 4 Jul 2008 10:18:30 +0000 (06:18 -0400)
Makefile
TODO
src/memmap.c
src/pciinit.c [new file with mode: 0644]
src/post.c
src/rombios32.c [deleted file]
src/smbios.c [new file with mode: 0644]
src/util.h

index a3e9a701ab8530a7f71638bd2b768e4af85c6993..dda74cdeb8ea087e448f40d1d4270968b077ff1b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,8 +11,8 @@ OUT=out/
 SRCBOTH=output.c util.c floppy.c ata.c system.c mouse.c kbd.c pci.c boot.c \
         serial.c clock.c pic.c
 SRC16=$(SRCBOTH) disk.c cdrom.c apm.c pcibios.c
-SRC32=$(SRCBOTH) post.c shadow.c rombios32.c post_menu.c memmap.c coreboot.c \
-      acpi.c pirtable.c smm.c smpdetect.c mptable.c
+SRC32=$(SRCBOTH) post.c shadow.c post_menu.c memmap.c coreboot.c \
+      acpi.c pirtable.c smm.c smpdetect.c mptable.c smbios.c pciinit.c
 TABLESRC=font.c cbt.c floppy_dbt.c
 
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
diff --git a/TODO b/TODO
index 723c3e0794f685a6e480f5666f4efbd2f2583b4b..d7acfe54489205d9b1fbbbd478156053d78f1510 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,5 +1,3 @@
-Split rombios32.c up into multiple files.
-
 Disable a20 on jump to 16bit mode.
 
 Do a pci scan for ide controllers - don't just assume ISA ports are
index 279e6261fb2ebeeada00847a69ed25f158b89abc..81d15f4dad671255db79b15754669f770ea1cf67 100644 (file)
@@ -152,4 +152,8 @@ memmap_finalize()
     SET_EBDA(e820_loc, bios_table_cur_addr);
     SET_EBDA(e820_count, e820_count);
     bios_table_cur_addr += msize;
+
+    dprintf(1, "bios_table_cur_addr: 0x%08x\n", bios_table_cur_addr);
+    if (bios_table_cur_addr > bios_table_end_addr)
+        BX_PANIC("bios_table_end_addr overflow!\n");
 }
diff --git a/src/pciinit.c b/src/pciinit.c
new file mode 100644 (file)
index 0000000..303f581
--- /dev/null
@@ -0,0 +1,222 @@
+// Initialize PCI devices (on emulators)
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "util.h" // dprintf
+#include "pci.h" // PCIDevice
+
+#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
+
+static u32 pci_bios_io_addr;
+static u32 pci_bios_mem_addr;
+static u32 pci_bios_bigmem_addr;
+/* host irqs corresponding to PCI irqs A-D */
+static u8 pci_irqs[4] = { 11, 9, 11, 9 };
+
+static void pci_set_io_region_addr(PCIDevice d, int region_num, u32 addr)
+{
+    u16 cmd;
+    u32 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);
+    dprintf(1, "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 void pci_bios_init_bridges(PCIDevice d)
+{
+    u16 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;
+        u8 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(elcr[0], 0x4d0);
+        outb(elcr[1], 0x4d1);
+        dprintf(1, "PIIX3 init: elcr=%02x %02x\n",
+                elcr[0], elcr[1]);
+    }
+}
+
+static void pci_bios_init_device(PCIDevice d)
+{
+    int class;
+    u32 *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);
+    dprintf(1, "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;
+            u32 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 if (size >= 0x04000000)
+                    paddr = &pci_bios_bigmem_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) */
+        u32 pm_io_base = BUILD_PM_IO_BASE;
+        pci_config_writel(d, 0x40, pm_io_base | 1);
+        pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
+        u32 smb_io_base = BUILD_SMB_IO_BASE;
+        pci_config_writel(d, 0x90, smb_io_base | 1);
+        pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
+    }
+}
+
+static void pci_for_each_device(void (*init_func)(PCIDevice d))
+{
+    int bus, devfn;
+    u16 vendor_id, device_id;
+
+    for(bus = 0; bus < 1; bus++) {
+        for(devfn = 0; devfn < 256; devfn++) {
+            PCIDevice d = pci_bd(bus, 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_setup(void)
+{
+    if (CONFIG_COREBOOT)
+        // Already done by coreboot.
+        return;
+
+    pci_bios_io_addr = 0xc000;
+    pci_bios_mem_addr = 0xf0000000;
+    pci_bios_bigmem_addr = GET_EBDA(ram_size);
+    if (pci_bios_bigmem_addr < 0x90000000)
+        pci_bios_bigmem_addr = 0x90000000;
+
+    pci_for_each_device(pci_bios_init_bridges);
+
+    pci_for_each_device(pci_bios_init_device);
+}
index b41e77f8f264c0a77aaaa272b2339e140c394e61..e1ec630ee9b565982df08002ff08ca2d6e100c01 100644 (file)
@@ -16,6 +16,8 @@
 #include "disk.h" // floppy_drive_setup
 #include "memmap.h" // add_e820
 #include "pic.h" // pic_setup
+#include "pci.h" // create_pirtable
+#include "acpi.h" // acpi_bios_init
 
 #define bda ((struct bios_data_area_s *)MAKE_FARPTR(SEG_BDA, 0))
 #define ebda ((struct extended_bios_data_area_s *)MAKE_FARPTR(SEG_EBDA, 0))
@@ -119,6 +121,24 @@ ram_probe(void)
     dprintf(1, "ram_size=0x%08x\n", GET_EBDA(ram_size));
 }
 
+static void
+init_bios_tables(void)
+{
+    if (CONFIG_COREBOOT)
+        // XXX - not supported on coreboot yet.
+        return;
+
+    smm_init();
+
+    create_pirtable();
+
+    mptable_init();
+
+    smbios_init();
+
+    acpi_bios_init();
+}
+
 static void
 init_boot_vectors()
 {
@@ -247,7 +267,9 @@ post()
 
     printf("BIOS - begin\n\n");
 
-    rombios32_init();
+    pci_bios_setup();
+
+    init_bios_tables();
 
     memmap_finalize();
 
diff --git a/src/rombios32.c b/src/rombios32.c
deleted file mode 100644 (file)
index 089b49d..0000000
+++ /dev/null
@@ -1,803 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-//
-//  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 "util.h" // dprintf
-#include "pci.h" // PCIDevice
-#include "types.h" // u32
-#include "config.h" // CONFIG_*
-#include "memmap.h" // bios_table_cur_addr
-#include "acpi.h" // acpi_bios_init
-
-u32 cpuid_signature;
-u32 cpuid_features;
-u32 cpuid_ext_features;
-u8 bios_uuid[16];
-
-void uuid_probe(void)
-{
-    // Default to UUID not set
-    memset(bios_uuid, 0, 16);
-
-    if (! CONFIG_QEMU)
-        return;
-
-    // check if backdoor port exists
-    u32 eax, ebx, ecx, edx;
-    asm volatile ("outl %%eax, %%dx"
-                  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
-                  : "a" (0x564d5868), "c" (0xa), "d" (0x5658));
-    if (ebx != 0x564d5868)
-        return;
-
-    u32 *uuid_ptr = (u32 *)bios_uuid;
-    // get uuid
-    asm volatile ("outl %%eax, %%dx"
-                  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
-                  : "a" (0x564d5868), "c" (0x13), "d" (0x5658));
-    uuid_ptr[0] = eax;
-    uuid_ptr[1] = ebx;
-    uuid_ptr[2] = ecx;
-    uuid_ptr[3] = edx;
-}
-
-void cpu_probe(void)
-{
-    u32 eax, ebx, ecx, edx;
-    cpuid(1, &eax, &ebx, &ecx, &edx);
-    cpuid_signature = eax;
-    cpuid_features = edx;
-    cpuid_ext_features = ecx;
-}
-
-/****************************************************/
-/* 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
-
-static u32 pci_bios_io_addr;
-static u32 pci_bios_mem_addr;
-static u32 pci_bios_bigmem_addr;
-/* host irqs corresponding to PCI irqs A-D */
-static u8 pci_irqs[4] = { 11, 9, 11, 9 };
-
-static void pci_set_io_region_addr(PCIDevice d, int region_num, u32 addr)
-{
-    u16 cmd;
-    u32 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);
-    dprintf(1, "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 void pci_bios_init_bridges(PCIDevice d)
-{
-    u16 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;
-        u8 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(elcr[0], 0x4d0);
-        outb(elcr[1], 0x4d1);
-        dprintf(1, "PIIX3 init: elcr=%02x %02x\n",
-                elcr[0], elcr[1]);
-    }
-}
-
-static void pci_bios_init_device(PCIDevice d)
-{
-    int class;
-    u32 *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);
-    dprintf(1, "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;
-            u32 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 if (size >= 0x04000000)
-                    paddr = &pci_bios_bigmem_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) */
-        u32 pm_io_base = BUILD_PM_IO_BASE;
-        pci_config_writel(d, 0x40, pm_io_base | 1);
-        pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
-        u32 smb_io_base = BUILD_SMB_IO_BASE;
-        pci_config_writel(d, 0x90, smb_io_base | 1);
-        pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
-    }
-}
-
-void pci_for_each_device(void (*init_func)(PCIDevice d))
-{
-    int bus, devfn;
-    u16 vendor_id, device_id;
-
-    for(bus = 0; bus < 1; bus++) {
-        for(devfn = 0; devfn < 256; devfn++) {
-            PCIDevice d = pci_bd(bus, 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_bios_bigmem_addr = GET_EBDA(ram_size);
-    if (pci_bios_bigmem_addr < 0x90000000)
-        pci_bios_bigmem_addr = 0x90000000;
-
-    pci_for_each_device(pci_bios_init_bridges);
-
-    pci_for_each_device(pci_bios_init_device);
-}
-
-/* SMBIOS entry point -- must be written to a 16-bit aligned address
-   between 0xf0000 and 0xfffff.
- */
-struct smbios_entry_point {
-       char anchor_string[4];
-       u8 checksum;
-       u8 length;
-       u8 smbios_major_version;
-       u8 smbios_minor_version;
-       u16 max_structure_size;
-       u8 entry_point_revision;
-       u8 formatted_area[5];
-       char intermediate_anchor_string[5];
-       u8 intermediate_checksum;
-       u16 structure_table_length;
-       u32 structure_table_address;
-       u16 number_of_structures;
-       u8 smbios_bcd_revision;
-} __attribute__((__packed__));
-
-/* This goes at the beginning of every SMBIOS structure. */
-struct smbios_structure_header {
-       u8 type;
-       u8 length;
-       u16 handle;
-} __attribute__((__packed__));
-
-/* SMBIOS type 0 - BIOS Information */
-struct smbios_type_0 {
-       struct smbios_structure_header header;
-       u8 vendor_str;
-       u8 bios_version_str;
-       u16 bios_starting_address_segment;
-       u8 bios_release_date_str;
-       u8 bios_rom_size;
-       u8 bios_characteristics[8];
-       u8 bios_characteristics_extension_bytes[2];
-       u8 system_bios_major_release;
-       u8 system_bios_minor_release;
-       u8 embedded_controller_major_release;
-       u8 embedded_controller_minor_release;
-} __attribute__((__packed__));
-
-/* SMBIOS type 1 - System Information */
-struct smbios_type_1 {
-       struct smbios_structure_header header;
-       u8 manufacturer_str;
-       u8 product_name_str;
-       u8 version_str;
-       u8 serial_number_str;
-       u8 uuid[16];
-       u8 wake_up_type;
-       u8 sku_number_str;
-       u8 family_str;
-} __attribute__((__packed__));
-
-/* SMBIOS type 3 - System Enclosure (v2.3) */
-struct smbios_type_3 {
-       struct smbios_structure_header header;
-       u8 manufacturer_str;
-       u8 type;
-       u8 version_str;
-       u8 serial_number_str;
-       u8 asset_tag_number_str;
-       u8 boot_up_state;
-       u8 power_supply_state;
-       u8 thermal_state;
-       u8 security_status;
-    u32 oem_defined;
-    u8 height;
-    u8 number_of_power_cords;
-    u8 contained_element_count;
-    // contained elements follow
-} __attribute__((__packed__));
-
-/* SMBIOS type 4 - Processor Information (v2.0) */
-struct smbios_type_4 {
-       struct smbios_structure_header header;
-       u8 socket_designation_str;
-       u8 processor_type;
-       u8 processor_family;
-       u8 processor_manufacturer_str;
-       u32 processor_id[2];
-       u8 processor_version_str;
-       u8 voltage;
-       u16 external_clock;
-       u16 max_speed;
-       u16 current_speed;
-       u8 status;
-       u8 processor_upgrade;
-} __attribute__((__packed__));
-
-/* SMBIOS type 16 - Physical Memory Array
- *   Associated with one type 17 (Memory Device).
- */
-struct smbios_type_16 {
-       struct smbios_structure_header header;
-       u8 location;
-       u8 use;
-       u8 error_correction;
-       u32 maximum_capacity;
-       u16 memory_error_information_handle;
-       u16 number_of_memory_devices;
-} __attribute__((__packed__));
-
-/* SMBIOS type 17 - Memory Device
- *   Associated with one type 19
- */
-struct smbios_type_17 {
-       struct smbios_structure_header header;
-       u16 physical_memory_array_handle;
-       u16 memory_error_information_handle;
-       u16 total_width;
-       u16 data_width;
-       u16 size;
-       u8 form_factor;
-       u8 device_set;
-       u8 device_locator_str;
-       u8 bank_locator_str;
-       u8 memory_type;
-       u16 type_detail;
-} __attribute__((__packed__));
-
-/* SMBIOS type 19 - Memory Array Mapped Address */
-struct smbios_type_19 {
-       struct smbios_structure_header header;
-       u32 starting_address;
-       u32 ending_address;
-       u16 memory_array_handle;
-       u8 partition_width;
-} __attribute__((__packed__));
-
-/* SMBIOS type 20 - Memory Device Mapped Address */
-struct smbios_type_20 {
-       struct smbios_structure_header header;
-       u32 starting_address;
-       u32 ending_address;
-       u16 memory_device_handle;
-       u16 memory_array_mapped_address_handle;
-       u8 partition_row_position;
-       u8 interleave_position;
-       u8 interleaved_data_depth;
-} __attribute__((__packed__));
-
-/* SMBIOS type 32 - System Boot Information */
-struct smbios_type_32 {
-       struct smbios_structure_header header;
-       u8 reserved[6];
-       u8 boot_status;
-} __attribute__((__packed__));
-
-/* SMBIOS type 127 -- End-of-table */
-struct smbios_type_127 {
-       struct smbios_structure_header header;
-} __attribute__((__packed__));
-
-static void
-smbios_entry_point_init(void *start,
-                        u16 max_structure_size,
-                        u16 structure_table_length,
-                        u32 structure_table_address,
-                        u16 number_of_structures)
-{
-    struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
-
-    memcpy(ep->anchor_string, "_SM_", 4);
-    ep->length = 0x1f;
-    ep->smbios_major_version = 2;
-    ep->smbios_minor_version = 4;
-    ep->max_structure_size = max_structure_size;
-    ep->entry_point_revision = 0;
-    memset(ep->formatted_area, 0, 5);
-    memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
-
-    ep->structure_table_length = structure_table_length;
-    ep->structure_table_address = structure_table_address;
-    ep->number_of_structures = number_of_structures;
-    ep->smbios_bcd_revision = 0x24;
-
-    ep->checksum = 0;
-    ep->intermediate_checksum = 0;
-
-    ep->checksum = -checksum(start, 0x10);
-
-    ep->intermediate_checksum = -checksum(start + 0x10, ep->length - 0x10);
-}
-
-/* Type 0 -- BIOS Information */
-#define RELEASE_DATE_STR "01/01/2007"
-static void *
-smbios_type_0_init(void *start)
-{
-    struct smbios_type_0 *p = (struct smbios_type_0 *)start;
-
-    p->header.type = 0;
-    p->header.length = sizeof(struct smbios_type_0);
-    p->header.handle = 0;
-
-    p->vendor_str = 1;
-    p->bios_version_str = 1;
-    p->bios_starting_address_segment = 0xe800;
-    p->bios_release_date_str = 2;
-    p->bios_rom_size = 0; /* FIXME */
-
-    memset(p->bios_characteristics, 0, 7);
-    p->bios_characteristics[7] = 0x08; /* BIOS characteristics not supported */
-    p->bios_characteristics_extension_bytes[0] = 0;
-    p->bios_characteristics_extension_bytes[1] = 0;
-
-    p->system_bios_major_release = 1;
-    p->system_bios_minor_release = 0;
-    p->embedded_controller_major_release = 0xff;
-    p->embedded_controller_minor_release = 0xff;
-
-    start += sizeof(struct smbios_type_0);
-    memcpy((char *)start, CONFIG_APPNAME, sizeof(CONFIG_APPNAME));
-    start += sizeof(CONFIG_APPNAME);
-    memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
-    start += sizeof(RELEASE_DATE_STR);
-    *((u8 *)start) = 0;
-
-    return start+1;
-}
-
-/* Type 1 -- System Information */
-static void *
-smbios_type_1_init(void *start)
-{
-    struct smbios_type_1 *p = (struct smbios_type_1 *)start;
-    p->header.type = 1;
-    p->header.length = sizeof(struct smbios_type_1);
-    p->header.handle = 0x100;
-
-    p->manufacturer_str = 0;
-    p->product_name_str = 0;
-    p->version_str = 0;
-    p->serial_number_str = 0;
-
-    memcpy(p->uuid, bios_uuid, 16);
-
-    p->wake_up_type = 0x06; /* power switch */
-    p->sku_number_str = 0;
-    p->family_str = 0;
-
-    start += sizeof(struct smbios_type_1);
-    *((u16 *)start) = 0;
-
-    return start+2;
-}
-
-/* Type 3 -- System Enclosure */
-static void *
-smbios_type_3_init(void *start)
-{
-    struct smbios_type_3 *p = (struct smbios_type_3 *)start;
-
-    p->header.type = 3;
-    p->header.length = sizeof(struct smbios_type_3);
-    p->header.handle = 0x300;
-
-    p->manufacturer_str = 0;
-    p->type = 0x01; /* other */
-    p->version_str = 0;
-    p->serial_number_str = 0;
-    p->asset_tag_number_str = 0;
-    p->boot_up_state = 0x03; /* safe */
-    p->power_supply_state = 0x03; /* safe */
-    p->thermal_state = 0x03; /* safe */
-    p->security_status = 0x02; /* unknown */
-    p->oem_defined = 0;
-    p->height = 0;
-    p->number_of_power_cords = 0;
-    p->contained_element_count = 0;
-
-    start += sizeof(struct smbios_type_3);
-    *((u16 *)start) = 0;
-
-    return start+2;
-}
-
-/* Type 4 -- Processor Information */
-static void *
-smbios_type_4_init(void *start, unsigned int cpu_number)
-{
-    struct smbios_type_4 *p = (struct smbios_type_4 *)start;
-
-    p->header.type = 4;
-    p->header.length = sizeof(struct smbios_type_4);
-    p->header.handle = 0x400 + cpu_number;
-
-    p->socket_designation_str = 1;
-    p->processor_type = 0x03; /* CPU */
-    p->processor_family = 0x01; /* other */
-    p->processor_manufacturer_str = 0;
-
-    p->processor_id[0] = cpuid_signature;
-    p->processor_id[1] = cpuid_features;
-
-    p->processor_version_str = 0;
-    p->voltage = 0;
-    p->external_clock = 0;
-
-    p->max_speed = 0; /* unknown */
-    p->current_speed = 0; /* unknown */
-
-    p->status = 0x41; /* socket populated, CPU enabled */
-    p->processor_upgrade = 0x01; /* other */
-
-    start += sizeof(struct smbios_type_4);
-
-    memcpy((char *)start, "CPU  " "\0" "" "\0" "", 7);
-       ((char *)start)[4] = cpu_number + '0';
-
-    return start+7;
-}
-
-/* Type 16 -- Physical Memory Array */
-static void *
-smbios_type_16_init(void *start, u32 memsize)
-{
-    struct smbios_type_16 *p = (struct smbios_type_16*)start;
-
-    p->header.type = 16;
-    p->header.length = sizeof(struct smbios_type_16);
-    p->header.handle = 0x1000;
-
-    p->location = 0x01; /* other */
-    p->use = 0x03; /* system memory */
-    p->error_correction = 0x01; /* other */
-    p->maximum_capacity = memsize * 1024;
-    p->memory_error_information_handle = 0xfffe; /* none provided */
-    p->number_of_memory_devices = 1;
-
-    start += sizeof(struct smbios_type_16);
-    *((u16 *)start) = 0;
-
-    return start + 2;
-}
-
-/* Type 17 -- Memory Device */
-static void *
-smbios_type_17_init(void *start, u32 memory_size_mb)
-{
-    struct smbios_type_17 *p = (struct smbios_type_17 *)start;
-
-    p->header.type = 17;
-    p->header.length = sizeof(struct smbios_type_17);
-    p->header.handle = 0x1100;
-
-    p->physical_memory_array_handle = 0x1000;
-    p->total_width = 64;
-    p->data_width = 64;
-    /* truncate memory_size_mb to 16 bits and clear most significant
-       bit [indicates size in MB] */
-    p->size = (u16) memory_size_mb & 0x7fff;
-    p->form_factor = 0x09; /* DIMM */
-    p->device_set = 0;
-    p->device_locator_str = 1;
-    p->bank_locator_str = 0;
-    p->memory_type = 0x07; /* RAM */
-    p->type_detail = 0;
-
-    start += sizeof(struct smbios_type_17);
-    memcpy((char *)start, "DIMM 1", 7);
-    start += 7;
-    *((u8 *)start) = 0;
-
-    return start+1;
-}
-
-/* Type 19 -- Memory Array Mapped Address */
-static void *
-smbios_type_19_init(void *start, u32 memory_size_mb)
-{
-    struct smbios_type_19 *p = (struct smbios_type_19 *)start;
-
-    p->header.type = 19;
-    p->header.length = sizeof(struct smbios_type_19);
-    p->header.handle = 0x1300;
-
-    p->starting_address = 0;
-    p->ending_address = (memory_size_mb-1) * 1024;
-    p->memory_array_handle = 0x1000;
-    p->partition_width = 1;
-
-    start += sizeof(struct smbios_type_19);
-    *((u16 *)start) = 0;
-
-    return start + 2;
-}
-
-/* Type 20 -- Memory Device Mapped Address */
-static void *
-smbios_type_20_init(void *start, u32 memory_size_mb)
-{
-    struct smbios_type_20 *p = (struct smbios_type_20 *)start;
-
-    p->header.type = 20;
-    p->header.length = sizeof(struct smbios_type_20);
-    p->header.handle = 0x1400;
-
-    p->starting_address = 0;
-    p->ending_address = (memory_size_mb-1)*1024;
-    p->memory_device_handle = 0x1100;
-    p->memory_array_mapped_address_handle = 0x1300;
-    p->partition_row_position = 1;
-    p->interleave_position = 0;
-    p->interleaved_data_depth = 0;
-
-    start += sizeof(struct smbios_type_20);
-
-    *((u16 *)start) = 0;
-    return start+2;
-}
-
-/* Type 32 -- System Boot Information */
-static void *
-smbios_type_32_init(void *start)
-{
-    struct smbios_type_32 *p = (struct smbios_type_32 *)start;
-
-    p->header.type = 32;
-    p->header.length = sizeof(struct smbios_type_32);
-    p->header.handle = 0x2000;
-    memset(p->reserved, 0, 6);
-    p->boot_status = 0; /* no errors detected */
-
-    start += sizeof(struct smbios_type_32);
-    *((u16 *)start) = 0;
-
-    return start+2;
-}
-
-/* Type 127 -- End of Table */
-static void *
-smbios_type_127_init(void *start)
-{
-    struct smbios_type_127 *p = (struct smbios_type_127 *)start;
-
-    p->header.type = 127;
-    p->header.length = sizeof(struct smbios_type_127);
-    p->header.handle = 0x7f00;
-
-    start += sizeof(struct smbios_type_127);
-    *((u16 *)start) = 0;
-
-    return start + 2;
-}
-
-void smbios_init(void)
-{
-    unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
-    char *start, *p, *q;
-    int memsize = GET_EBDA(ram_size) / (1024 * 1024);
-
-    bios_table_cur_addr = ALIGN(bios_table_cur_addr, 16);
-    start = (void *)(bios_table_cur_addr);
-
-    p = (char *)start + sizeof(struct smbios_entry_point);
-
-#define add_struct(fn) { \
-    q = (fn); \
-    nr_structs++; \
-    if ((q - p) > max_struct_size) \
-        max_struct_size = q - p; \
-    p = q; \
-}
-
-    add_struct(smbios_type_0_init(p));
-    add_struct(smbios_type_1_init(p));
-    add_struct(smbios_type_3_init(p));
-    int smp_cpus = smp_probe();
-    for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
-        add_struct(smbios_type_4_init(p, cpu_num));
-    add_struct(smbios_type_16_init(p, memsize));
-    add_struct(smbios_type_17_init(p, memsize));
-    add_struct(smbios_type_19_init(p, memsize));
-    add_struct(smbios_type_20_init(p, memsize));
-    add_struct(smbios_type_32_init(p));
-    add_struct(smbios_type_127_init(p));
-
-#undef add_struct
-
-    smbios_entry_point_init(
-        start, max_struct_size,
-        (p - (char *)start) - sizeof(struct smbios_entry_point),
-        (u32)(start + sizeof(struct smbios_entry_point)),
-        nr_structs);
-
-    bios_table_cur_addr += (p - (char *)start);
-
-    dprintf(1, "SMBIOS table addr=0x%08lx\n", (unsigned long)start);
-}
-
-void rombios32_init(void)
-{
-    if (CONFIG_COREBOOT)
-        // XXX - not supported on coreboot yet.
-        return;
-
-    dprintf(1, "Starting rombios32\n");
-
-    cpu_probe();
-
-    pci_bios_init();
-
-    smm_init();
-
-    create_pirtable();
-
-    if (bios_table_cur_addr != 0) {
-
-        mptable_init();
-
-        uuid_probe();
-
-        smbios_init();
-
-        acpi_bios_init();
-
-        dprintf(1, "bios_table_cur_addr: 0x%08x\n", bios_table_cur_addr);
-        if (bios_table_cur_addr > bios_table_end_addr)
-            BX_PANIC("bios_table_end_addr overflow!\n");
-    }
-}
diff --git a/src/smbios.c b/src/smbios.c
new file mode 100644 (file)
index 0000000..fe78e12
--- /dev/null
@@ -0,0 +1,549 @@
+// smbios table generation (on emulators)
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "util.h" // dprintf
+#include "memmap.h" // bios_table_cur_addr
+
+
+/****************************************************************
+ * UUID probe
+ ****************************************************************/
+
+static void
+uuid_probe(u8 *bios_uuid)
+{
+    // Default to UUID not set
+    memset(bios_uuid, 0, 16);
+
+    if (! CONFIG_QEMU)
+        return;
+
+    // check if backdoor port exists
+    u32 eax, ebx, ecx, edx;
+    asm volatile ("outl %%eax, %%dx"
+                  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+                  : "a" (0x564d5868), "c" (0xa), "d" (0x5658));
+    if (ebx != 0x564d5868)
+        return;
+
+    u32 *uuid_ptr = (u32 *)bios_uuid;
+    // get uuid
+    asm volatile ("outl %%eax, %%dx"
+                  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+                  : "a" (0x564d5868), "c" (0x13), "d" (0x5658));
+    uuid_ptr[0] = eax;
+    uuid_ptr[1] = ebx;
+    uuid_ptr[2] = ecx;
+    uuid_ptr[3] = edx;
+}
+
+
+/****************************************************************
+ * smbios tables
+ ****************************************************************/
+
+/* SMBIOS entry point -- must be written to a 16-bit aligned address
+   between 0xf0000 and 0xfffff.
+ */
+struct smbios_entry_point {
+       char anchor_string[4];
+       u8 checksum;
+       u8 length;
+       u8 smbios_major_version;
+       u8 smbios_minor_version;
+       u16 max_structure_size;
+       u8 entry_point_revision;
+       u8 formatted_area[5];
+       char intermediate_anchor_string[5];
+       u8 intermediate_checksum;
+       u16 structure_table_length;
+       u32 structure_table_address;
+       u16 number_of_structures;
+       u8 smbios_bcd_revision;
+} __attribute__((__packed__));
+
+/* This goes at the beginning of every SMBIOS structure. */
+struct smbios_structure_header {
+       u8 type;
+       u8 length;
+       u16 handle;
+} __attribute__((__packed__));
+
+/* SMBIOS type 0 - BIOS Information */
+struct smbios_type_0 {
+       struct smbios_structure_header header;
+       u8 vendor_str;
+       u8 bios_version_str;
+       u16 bios_starting_address_segment;
+       u8 bios_release_date_str;
+       u8 bios_rom_size;
+       u8 bios_characteristics[8];
+       u8 bios_characteristics_extension_bytes[2];
+       u8 system_bios_major_release;
+       u8 system_bios_minor_release;
+       u8 embedded_controller_major_release;
+       u8 embedded_controller_minor_release;
+} __attribute__((__packed__));
+
+/* SMBIOS type 1 - System Information */
+struct smbios_type_1 {
+       struct smbios_structure_header header;
+       u8 manufacturer_str;
+       u8 product_name_str;
+       u8 version_str;
+       u8 serial_number_str;
+       u8 uuid[16];
+       u8 wake_up_type;
+       u8 sku_number_str;
+       u8 family_str;
+} __attribute__((__packed__));
+
+/* SMBIOS type 3 - System Enclosure (v2.3) */
+struct smbios_type_3 {
+       struct smbios_structure_header header;
+       u8 manufacturer_str;
+       u8 type;
+       u8 version_str;
+       u8 serial_number_str;
+       u8 asset_tag_number_str;
+       u8 boot_up_state;
+       u8 power_supply_state;
+       u8 thermal_state;
+       u8 security_status;
+    u32 oem_defined;
+    u8 height;
+    u8 number_of_power_cords;
+    u8 contained_element_count;
+    // contained elements follow
+} __attribute__((__packed__));
+
+/* SMBIOS type 4 - Processor Information (v2.0) */
+struct smbios_type_4 {
+       struct smbios_structure_header header;
+       u8 socket_designation_str;
+       u8 processor_type;
+       u8 processor_family;
+       u8 processor_manufacturer_str;
+       u32 processor_id[2];
+       u8 processor_version_str;
+       u8 voltage;
+       u16 external_clock;
+       u16 max_speed;
+       u16 current_speed;
+       u8 status;
+       u8 processor_upgrade;
+} __attribute__((__packed__));
+
+/* SMBIOS type 16 - Physical Memory Array
+ *   Associated with one type 17 (Memory Device).
+ */
+struct smbios_type_16 {
+       struct smbios_structure_header header;
+       u8 location;
+       u8 use;
+       u8 error_correction;
+       u32 maximum_capacity;
+       u16 memory_error_information_handle;
+       u16 number_of_memory_devices;
+} __attribute__((__packed__));
+
+/* SMBIOS type 17 - Memory Device
+ *   Associated with one type 19
+ */
+struct smbios_type_17 {
+       struct smbios_structure_header header;
+       u16 physical_memory_array_handle;
+       u16 memory_error_information_handle;
+       u16 total_width;
+       u16 data_width;
+       u16 size;
+       u8 form_factor;
+       u8 device_set;
+       u8 device_locator_str;
+       u8 bank_locator_str;
+       u8 memory_type;
+       u16 type_detail;
+} __attribute__((__packed__));
+
+/* SMBIOS type 19 - Memory Array Mapped Address */
+struct smbios_type_19 {
+       struct smbios_structure_header header;
+       u32 starting_address;
+       u32 ending_address;
+       u16 memory_array_handle;
+       u8 partition_width;
+} __attribute__((__packed__));
+
+/* SMBIOS type 20 - Memory Device Mapped Address */
+struct smbios_type_20 {
+       struct smbios_structure_header header;
+       u32 starting_address;
+       u32 ending_address;
+       u16 memory_device_handle;
+       u16 memory_array_mapped_address_handle;
+       u8 partition_row_position;
+       u8 interleave_position;
+       u8 interleaved_data_depth;
+} __attribute__((__packed__));
+
+/* SMBIOS type 32 - System Boot Information */
+struct smbios_type_32 {
+       struct smbios_structure_header header;
+       u8 reserved[6];
+       u8 boot_status;
+} __attribute__((__packed__));
+
+/* SMBIOS type 127 -- End-of-table */
+struct smbios_type_127 {
+       struct smbios_structure_header header;
+} __attribute__((__packed__));
+
+
+/****************************************************************
+ * smbios init
+ ****************************************************************/
+
+static void
+smbios_entry_point_init(void *start,
+                        u16 max_structure_size,
+                        u16 structure_table_length,
+                        u32 structure_table_address,
+                        u16 number_of_structures)
+{
+    struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
+
+    memcpy(ep->anchor_string, "_SM_", 4);
+    ep->length = 0x1f;
+    ep->smbios_major_version = 2;
+    ep->smbios_minor_version = 4;
+    ep->max_structure_size = max_structure_size;
+    ep->entry_point_revision = 0;
+    memset(ep->formatted_area, 0, 5);
+    memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
+
+    ep->structure_table_length = structure_table_length;
+    ep->structure_table_address = structure_table_address;
+    ep->number_of_structures = number_of_structures;
+    ep->smbios_bcd_revision = 0x24;
+
+    ep->checksum = 0;
+    ep->intermediate_checksum = 0;
+
+    ep->checksum = -checksum(start, 0x10);
+
+    ep->intermediate_checksum = -checksum(start + 0x10, ep->length - 0x10);
+}
+
+/* Type 0 -- BIOS Information */
+#define RELEASE_DATE_STR "01/01/2007"
+static void *
+smbios_type_0_init(void *start)
+{
+    struct smbios_type_0 *p = (struct smbios_type_0 *)start;
+
+    p->header.type = 0;
+    p->header.length = sizeof(struct smbios_type_0);
+    p->header.handle = 0;
+
+    p->vendor_str = 1;
+    p->bios_version_str = 1;
+    p->bios_starting_address_segment = 0xe800;
+    p->bios_release_date_str = 2;
+    p->bios_rom_size = 0; /* FIXME */
+
+    memset(p->bios_characteristics, 0, 7);
+    p->bios_characteristics[7] = 0x08; /* BIOS characteristics not supported */
+    p->bios_characteristics_extension_bytes[0] = 0;
+    p->bios_characteristics_extension_bytes[1] = 0;
+
+    p->system_bios_major_release = 1;
+    p->system_bios_minor_release = 0;
+    p->embedded_controller_major_release = 0xff;
+    p->embedded_controller_minor_release = 0xff;
+
+    start += sizeof(struct smbios_type_0);
+    memcpy((char *)start, CONFIG_APPNAME, sizeof(CONFIG_APPNAME));
+    start += sizeof(CONFIG_APPNAME);
+    memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
+    start += sizeof(RELEASE_DATE_STR);
+    *((u8 *)start) = 0;
+
+    return start+1;
+}
+
+/* Type 1 -- System Information */
+static void *
+smbios_type_1_init(void *start)
+{
+    struct smbios_type_1 *p = (struct smbios_type_1 *)start;
+    p->header.type = 1;
+    p->header.length = sizeof(struct smbios_type_1);
+    p->header.handle = 0x100;
+
+    p->manufacturer_str = 0;
+    p->product_name_str = 0;
+    p->version_str = 0;
+    p->serial_number_str = 0;
+
+    uuid_probe(p->uuid);
+
+    p->wake_up_type = 0x06; /* power switch */
+    p->sku_number_str = 0;
+    p->family_str = 0;
+
+    start += sizeof(struct smbios_type_1);
+    *((u16 *)start) = 0;
+
+    return start+2;
+}
+
+/* Type 3 -- System Enclosure */
+static void *
+smbios_type_3_init(void *start)
+{
+    struct smbios_type_3 *p = (struct smbios_type_3 *)start;
+
+    p->header.type = 3;
+    p->header.length = sizeof(struct smbios_type_3);
+    p->header.handle = 0x300;
+
+    p->manufacturer_str = 0;
+    p->type = 0x01; /* other */
+    p->version_str = 0;
+    p->serial_number_str = 0;
+    p->asset_tag_number_str = 0;
+    p->boot_up_state = 0x03; /* safe */
+    p->power_supply_state = 0x03; /* safe */
+    p->thermal_state = 0x03; /* safe */
+    p->security_status = 0x02; /* unknown */
+    p->oem_defined = 0;
+    p->height = 0;
+    p->number_of_power_cords = 0;
+    p->contained_element_count = 0;
+
+    start += sizeof(struct smbios_type_3);
+    *((u16 *)start) = 0;
+
+    return start+2;
+}
+
+/* Type 4 -- Processor Information */
+static void *
+smbios_type_4_init(void *start, unsigned int cpu_number)
+{
+    struct smbios_type_4 *p = (struct smbios_type_4 *)start;
+
+    p->header.type = 4;
+    p->header.length = sizeof(struct smbios_type_4);
+    p->header.handle = 0x400 + cpu_number;
+
+    p->socket_designation_str = 1;
+    p->processor_type = 0x03; /* CPU */
+    p->processor_family = 0x01; /* other */
+    p->processor_manufacturer_str = 0;
+
+    u32 cpuid_signature, ebx, ecx, cpuid_features;
+    cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
+    p->processor_id[0] = cpuid_signature;
+    p->processor_id[1] = cpuid_features;
+
+    p->processor_version_str = 0;
+    p->voltage = 0;
+    p->external_clock = 0;
+
+    p->max_speed = 0; /* unknown */
+    p->current_speed = 0; /* unknown */
+
+    p->status = 0x41; /* socket populated, CPU enabled */
+    p->processor_upgrade = 0x01; /* other */
+
+    start += sizeof(struct smbios_type_4);
+
+    memcpy((char *)start, "CPU  " "\0" "" "\0" "", 7);
+       ((char *)start)[4] = cpu_number + '0';
+
+    return start+7;
+}
+
+/* Type 16 -- Physical Memory Array */
+static void *
+smbios_type_16_init(void *start, u32 memsize)
+{
+    struct smbios_type_16 *p = (struct smbios_type_16*)start;
+
+    p->header.type = 16;
+    p->header.length = sizeof(struct smbios_type_16);
+    p->header.handle = 0x1000;
+
+    p->location = 0x01; /* other */
+    p->use = 0x03; /* system memory */
+    p->error_correction = 0x01; /* other */
+    p->maximum_capacity = memsize * 1024;
+    p->memory_error_information_handle = 0xfffe; /* none provided */
+    p->number_of_memory_devices = 1;
+
+    start += sizeof(struct smbios_type_16);
+    *((u16 *)start) = 0;
+
+    return start + 2;
+}
+
+/* Type 17 -- Memory Device */
+static void *
+smbios_type_17_init(void *start, u32 memory_size_mb)
+{
+    struct smbios_type_17 *p = (struct smbios_type_17 *)start;
+
+    p->header.type = 17;
+    p->header.length = sizeof(struct smbios_type_17);
+    p->header.handle = 0x1100;
+
+    p->physical_memory_array_handle = 0x1000;
+    p->total_width = 64;
+    p->data_width = 64;
+    /* truncate memory_size_mb to 16 bits and clear most significant
+       bit [indicates size in MB] */
+    p->size = (u16) memory_size_mb & 0x7fff;
+    p->form_factor = 0x09; /* DIMM */
+    p->device_set = 0;
+    p->device_locator_str = 1;
+    p->bank_locator_str = 0;
+    p->memory_type = 0x07; /* RAM */
+    p->type_detail = 0;
+
+    start += sizeof(struct smbios_type_17);
+    memcpy((char *)start, "DIMM 1", 7);
+    start += 7;
+    *((u8 *)start) = 0;
+
+    return start+1;
+}
+
+/* Type 19 -- Memory Array Mapped Address */
+static void *
+smbios_type_19_init(void *start, u32 memory_size_mb)
+{
+    struct smbios_type_19 *p = (struct smbios_type_19 *)start;
+
+    p->header.type = 19;
+    p->header.length = sizeof(struct smbios_type_19);
+    p->header.handle = 0x1300;
+
+    p->starting_address = 0;
+    p->ending_address = (memory_size_mb-1) * 1024;
+    p->memory_array_handle = 0x1000;
+    p->partition_width = 1;
+
+    start += sizeof(struct smbios_type_19);
+    *((u16 *)start) = 0;
+
+    return start + 2;
+}
+
+/* Type 20 -- Memory Device Mapped Address */
+static void *
+smbios_type_20_init(void *start, u32 memory_size_mb)
+{
+    struct smbios_type_20 *p = (struct smbios_type_20 *)start;
+
+    p->header.type = 20;
+    p->header.length = sizeof(struct smbios_type_20);
+    p->header.handle = 0x1400;
+
+    p->starting_address = 0;
+    p->ending_address = (memory_size_mb-1)*1024;
+    p->memory_device_handle = 0x1100;
+    p->memory_array_mapped_address_handle = 0x1300;
+    p->partition_row_position = 1;
+    p->interleave_position = 0;
+    p->interleaved_data_depth = 0;
+
+    start += sizeof(struct smbios_type_20);
+
+    *((u16 *)start) = 0;
+    return start+2;
+}
+
+/* Type 32 -- System Boot Information */
+static void *
+smbios_type_32_init(void *start)
+{
+    struct smbios_type_32 *p = (struct smbios_type_32 *)start;
+
+    p->header.type = 32;
+    p->header.length = sizeof(struct smbios_type_32);
+    p->header.handle = 0x2000;
+    memset(p->reserved, 0, 6);
+    p->boot_status = 0; /* no errors detected */
+
+    start += sizeof(struct smbios_type_32);
+    *((u16 *)start) = 0;
+
+    return start+2;
+}
+
+/* Type 127 -- End of Table */
+static void *
+smbios_type_127_init(void *start)
+{
+    struct smbios_type_127 *p = (struct smbios_type_127 *)start;
+
+    p->header.type = 127;
+    p->header.length = sizeof(struct smbios_type_127);
+    p->header.handle = 0x7f00;
+
+    start += sizeof(struct smbios_type_127);
+    *((u16 *)start) = 0;
+
+    return start + 2;
+}
+
+void
+smbios_init(void)
+{
+    unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
+    char *start, *p, *q;
+    int memsize = GET_EBDA(ram_size) / (1024 * 1024);
+
+    bios_table_cur_addr = ALIGN(bios_table_cur_addr, 16);
+    start = (void *)(bios_table_cur_addr);
+
+    p = (char *)start + sizeof(struct smbios_entry_point);
+
+#define add_struct(fn) { \
+    q = (fn); \
+    nr_structs++; \
+    if ((q - p) > max_struct_size) \
+        max_struct_size = q - p; \
+    p = q; \
+}
+
+    add_struct(smbios_type_0_init(p));
+    add_struct(smbios_type_1_init(p));
+    add_struct(smbios_type_3_init(p));
+    int smp_cpus = smp_probe();
+    for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
+        add_struct(smbios_type_4_init(p, cpu_num));
+    add_struct(smbios_type_16_init(p, memsize));
+    add_struct(smbios_type_17_init(p, memsize));
+    add_struct(smbios_type_19_init(p, memsize));
+    add_struct(smbios_type_20_init(p, memsize));
+    add_struct(smbios_type_32_init(p));
+    add_struct(smbios_type_127_init(p));
+
+#undef add_struct
+
+    smbios_entry_point_init(
+        start, max_struct_size,
+        (p - (char *)start) - sizeof(struct smbios_entry_point),
+        (u32)(start + sizeof(struct smbios_entry_point)),
+        nr_structs);
+
+    bios_table_cur_addr += (p - (char *)start);
+
+    dprintf(1, "SMBIOS table addr=0x%08lx\n", (unsigned long)start);
+}
index bccf750be6a8e93706ab1df69aa3d90f2186a0d8..3f7283f0a8328f2481d0725f64883c5ed7a187a8 100644 (file)
@@ -194,8 +194,8 @@ u8 checksum(u8 *far_data, u32 len);
 void make_bios_writable();
 void make_bios_readonly();
 
-// rombios32.c
-void rombios32_init(void);
+// pciinit.c
+void pci_bios_setup(void);
 
 // smm.c
 void smm_init();
@@ -206,6 +206,9 @@ int smp_probe(void);
 // mptable.c
 void mptable_init(void);
 
+// smbios.c
+void smbios_init(void);
+
 // boot.c
 void printf_bootdev(u16 bootdev);