diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2008-07-04 06:18:30 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2008-07-04 06:18:30 -0400 |
commit | 0525d29af0803bdfca40f9bb8b1f8cf5b9a84c05 (patch) | |
tree | f63aa642de6062e065b2c6263de6ed0f21c5414d | |
parent | 84ad59ab83ecdced2bd517f1c8d1129d430d8cdc (diff) | |
download | seabios-0525d29af0803bdfca40f9bb8b1f8cf5b9a84c05.tar.gz |
Breakup rombios32.c into pciinit.c and smbios.c
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/memmap.c | 4 | ||||
-rw-r--r-- | src/pciinit.c | 222 | ||||
-rw-r--r-- | src/post.c | 24 | ||||
-rw-r--r-- | src/smbios.c (renamed from src/rombios32.c) | 300 | ||||
-rw-r--r-- | src/util.h | 7 |
7 files changed, 279 insertions, 284 deletions
@@ -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 \ @@ -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 diff --git a/src/memmap.c b/src/memmap.c index 279e6261..81d15f4d 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -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 index 00000000..303f581e --- /dev/null +++ b/src/pciinit.c @@ -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); +} @@ -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)) @@ -120,6 +122,24 @@ ram_probe(void) } 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() { dprintf(3, "init boot device ordering\n"); @@ -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/smbios.c index 089b49d3..fe78e12a 100644 --- a/src/rombios32.c +++ b/src/smbios.c @@ -1,35 +1,20 @@ -///////////////////////////////////////////////////////////////////////// +// smbios table generation (on emulators) // -// 32 bit Bochs BIOS init code -// Copyright (C) 2006 Fabrice Bellard +// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net> +// 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 +// This file may be distributed under the terms of the GNU GPLv3 license. #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) +/**************************************************************** + * UUID probe + ****************************************************************/ + +static void +uuid_probe(u8 *bios_uuid) { // Default to UUID not set memset(bios_uuid, 0, 16); @@ -56,225 +41,10 @@ void uuid_probe(void) 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 tables + ****************************************************************/ /* SMBIOS entry point -- must be written to a 16-bit aligned address between 0xf0000 and 0xfffff. @@ -432,6 +202,11 @@ 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, @@ -514,7 +289,7 @@ smbios_type_1_init(void *start) p->version_str = 0; p->serial_number_str = 0; - memcpy(p->uuid, bios_uuid, 16); + uuid_probe(p->uuid); p->wake_up_type = 0x06; /* power switch */ p->sku_number_str = 0; @@ -571,6 +346,8 @@ smbios_type_4_init(void *start, unsigned int cpu_number) 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; @@ -725,7 +502,8 @@ smbios_type_127_init(void *start) return start + 2; } -void smbios_init(void) +void +smbios_init(void) { unsigned cpu_num, nr_structs = 0, max_struct_size = 0; char *start, *p, *q; @@ -769,35 +547,3 @@ void smbios_init(void) 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"); - } -} @@ -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); |