Hi,
(1) Figure which devices are needed to boot. That list should
include VGA, storage devices, NICs (with ROM), maybe all
devices with a ROM. Anything else?
(2) For devices which are not needed to boot we can:
(b) Skip device altogether.
Something like this ...
cheers,
Gerd
PS: full patch collection @
http://www.kraxel.org/cgit/seabios/log/?h=kraxel.q35
>From 99ff4d141d5a460eaf20fe2d4d13117c888eae15 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <[email protected]>
Date: Wed, 25 May 2011 13:56:52 +0200
Subject: [PATCH] init boot devices only on address space shortage
---
src/pci.c | 3 ++
src/pciinit.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++------
src/util.h | 1 +
3 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/src/pci.c b/src/pci.c
index 944a393..26c34bc 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -221,6 +221,9 @@ int pci_init_device(const struct pci_device_id *ids, u16
bdf, void *arg)
u16 device_id = pci_config_readw(bdf, PCI_DEVICE_ID);
u16 class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
+ if (!pci_enable_device(bdf))
+ return -1;
+
while (ids->vendid || ids->class_mask) {
if ((ids->vendid == PCI_ANY_ID || ids->vendid == vendor_id) &&
(ids->devid == PCI_ANY_ID || ids->devid == device_id) &&
diff --git a/src/pciinit.c b/src/pciinit.c
index 2e97b31..4aebd52 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -44,6 +44,7 @@ static struct pci_bus {
u32 io_base, mem_base, prefmem_base;
} *busses;
static int busses_count;
+static int boot_devices_only = 0;
static void pci_bios_init_device_in_bus(int bus);
static void pci_bios_check_device_in_bus(int bus);
@@ -144,6 +145,50 @@ static const struct pci_device_id pci_isa_bridge_tbl[] = {
#define PCI_PREF_MEMORY_ALIGN (1UL << 20)
#define PCI_PREF_MEMORY_SHIFT 16
+static int is_boot_device(u16 bdf)
+{
+ u32 ofs, old, val;
+ u16 class;
+
+ class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
+
+ /* check base class */
+ switch (class >> 8) {
+ case PCI_BASE_CLASS_STORAGE:
+ case PCI_BASE_CLASS_NETWORK:
+ case PCI_BASE_CLASS_BRIDGE:
+ case PCI_BASE_CLASS_SYSTEM:
+ return 1;
+ }
+
+ /* check class */
+ switch (class) {
+ case PCI_CLASS_DISPLAY_VGA:
+ case PCI_CLASS_SERIAL_USB:
+ return 1;
+ }
+
+ /* check if ROM present */
+ ofs = pci_bar(bdf, PCI_ROM_SLOT);
+ old = pci_config_readl(bdf, ofs);
+ pci_config_writel(bdf, ofs, PCI_ROM_ADDRESS_MASK);
+ val = pci_config_readl(bdf, ofs);
+ pci_config_writel(bdf, ofs, old);
+ if (val != 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int pci_enable_device(u16 bdf)
+{
+ if (boot_devices_only) {
+ return is_boot_device(bdf);
+ }
+ return 1;
+}
+
static void storage_ide_init(u16 bdf, void *arg)
{
/* IDE: we map it as in ISA mode */
@@ -387,6 +432,9 @@ static void pci_bios_check_device(struct pci_bus *bus, u16
bdf)
u16 class;
int i;
+ if (!pci_enable_device(bdf))
+ return;
+
class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
if (class == PCI_CLASS_BRIDGE_PCI) {
u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
@@ -437,6 +485,9 @@ static void pci_bios_map_device(struct pci_bus *bus, u16
bdf)
u16 class;
int i;
+ if (!pci_enable_device(bdf))
+ return;
+
class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
if (class == PCI_CLASS_BRIDGE_PCI) {
u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
@@ -499,10 +550,12 @@ static void pci_bios_map_device(struct pci_bus *bus, u16
bdf)
static void pci_bios_check_device_in_bus(int bus)
{
- int bdf, max;
+ int bdf, max, boot;
dprintf(1, "PCI: check devices bus %d\n", bus);
foreachpci_in_bus(bdf, max, bus) {
+ boot = is_boot_device(bdf);
+ dprintf(1, "PCI: check device bus %d, bfd 0x%x, boot %d\n", bus, bdf,
boot);
pci_bios_check_device(&busses[bus], bdf);
}
}
@@ -568,7 +621,7 @@ static void pci_bios_init_bus_bases(struct pci_bus *bus)
}
}
-static void pci_bios_init_root_regions(void)
+static int pci_bios_init_root_regions(void)
{
struct pci_bus *bus = &busses[0];
u32 reserved = 0xffffffff - 0xfec00000 + 1;
@@ -595,14 +648,12 @@ static void pci_bios_init_root_regions(void)
bus->io_base = 0xc000;
/* simple sanity check */
- /* TODO: check e820 table */
- if (bus->mem_base < RamSize) {
+ if (reserved > 0x10000000) {
dprintf(1, "PCI: out of space for memory bars\n");
- /* Hmm, what to do now? */
+ return -1;
+ } else {
+ return 0;
}
-
- dprintf(1, "PCI: init bases bus 0 (primary)\n");
- pci_bios_init_bus_bases(bus);
}
void
@@ -619,6 +670,15 @@ pci_setup(void)
dprintf(1, "=== PCI new allocation pass #1 ===\n");
pci_bios_check_device_in_bus(0 /* host bus */);
+ if (pci_bios_init_root_regions() != 0) {
+ dprintf(1, "=== PCI new allocation pass #1a (boot only) ===\n");
+ boot_devices_only = 1;
+ memset(busses, 0, busses_count * sizeof(struct pci_bus));
+ pci_bios_check_device_in_bus(0 /* host bus */);
+ if (pci_bios_init_root_regions() != 0) {
+ /* Hmm, we are in serious trouble now */
+ }
+ }
pci_region_init(&pci_bios_io_region, 0xc000, 64 * 1024 - 1);
struct pci_mem_addr addr = {
@@ -628,7 +688,8 @@ pci_setup(void)
pci_find_init_device(pci_mem_addr_tbl, &addr);
dprintf(1, "=== PCI new allocation pass #2 ===\n");
- pci_bios_init_root_regions();
+ dprintf(1, "PCI: init bases bus 0 (primary)\n");
+ pci_bios_init_bus_bases(&busses[0]);
pci_bios_map_device_in_bus(0 /* host bus */);
pci_bios_init_device_in_bus(0 /* host bus */);
diff --git a/src/util.h b/src/util.h
index 2160b37..ff61031 100644
--- a/src/util.h
+++ b/src/util.h
@@ -381,6 +381,7 @@ u32 pci_region_size(const struct pci_region *r);
// pciinit.c
extern const u8 pci_irqs[4];
+int pci_enable_device(u16 bdf);
void pci_bios_allocate_regions(u16 bdf, void *arg);
void pci_setup(void);
--
1.7.1
_______________________________________________
SeaBIOS mailing list
[email protected]
http://www.seabios.org/mailman/listinfo/seabios