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 \
-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
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");
}
--- /dev/null
+// 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);
+}
#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))
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()
{
printf("BIOS - begin\n\n");
- rombios32_init();
+ pci_bios_setup();
+
+ init_bios_tables();
memmap_finalize();
+++ /dev/null
-/////////////////////////////////////////////////////////////////////////
-//
-// 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");
- }
-}
--- /dev/null
+// 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);
+}
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();
// mptable.c
void mptable_init(void);
+// smbios.c
+void smbios_init(void);
+
// boot.c
void printf_bootdev(u16 bootdev);