aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2010-06-22 17:57:49 +0900
committerKevin O'Connor <kevin@koconnor.net>2010-07-04 08:52:12 -0400
commit0a8eada0df7448526af83d3e6df8ed58e72d925d (patch)
treeceee0c62c6bab1d161a373eac934edc146560cf3
parentdfd94fafc2a157f4fc64014069e19dc6e6bbac52 (diff)
downloadseabios-0a8eada0df7448526af83d3e6df8ed58e72d925d.tar.gz
seabios: pciinit: make pci bar assigner preferchable memory aware.
Make pci bar assigner preferchable memory aware. This is needed for PCI bridge support because memory space and prefetchable memory space is filtered independently based on memory base/limit and prefetchable memory base/limit of pci bridge. On bus 0, such a distinction isn't necessary so keep existing behavior by checking bus=0. With this patch, pci mem assignment area has been decreased. To make seabios behave as before for compatible reason, define CONFIG_OLD_PCIMEM_ASSIGNMENT. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
-rw-r--r--src/config.h17
-rw-r--r--src/pciinit.c49
2 files changed, 59 insertions, 7 deletions
diff --git a/src/config.h b/src/config.h
index 238a2866..a7a6ccc6 100644
--- a/src/config.h
+++ b/src/config.h
@@ -161,7 +161,24 @@
// 32KB for shadow ram copying (works around emulator deficiencies)
#define BUILD_BIOS_TMP_ADDR 0x30000
#define BUILD_MAX_HIGHMEM 0xe0000000
+
+// Support old pci mem assignment behaviour
+//#define CONFIG_OLD_PCIMEM_ASSIGNMENT 1
+#if CONFIG_OLD_PCIMEM_ASSIGNMENT
+#define BUILD_PCIMEM_START 0xf0000000
+#define BUILD_PCIMEM_SIZE (BUILD_PCIMEM_END - BUILD_PCIMEM_START)
+#define BUILD_PCIMEM_END 0xfec00000 /* IOAPIC is mapped at */
+#define BUILD_PCIPREFMEM_START 0
+#define BUILD_PCIPREFMEM_SIZE 0
+#define BUILD_PCIPREFMEM_END 0
+#else
#define BUILD_PCIMEM_START 0xf0000000
+#define BUILD_PCIMEM_SIZE 0x08000000 /* half- of pci window */
+#define BUILD_PCIMEM_END (BUILD_PCIMEM_START + BUILD_PCIMEM_SIZE)
+#define BUILD_PCIPREFMEM_START BUILD_PCIMEM_END
+#define BUILD_PCIPREFMEM_SIZE (BUILD_PCIPREFMEM_END - BUILD_PCIPREFMEM_START)
+#define BUILD_PCIPREFMEM_END 0xfec00000 /* IOAPIC is mapped at */
+#endif
#define BUILD_APIC_ADDR 0xfee00000
#define BUILD_IOAPIC_ADDR 0xfec00000
diff --git a/src/pciinit.c b/src/pciinit.c
index b635e44b..a65c58da 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -16,6 +16,7 @@
static u32 pci_bios_io_addr;
static u32 pci_bios_mem_addr;
+static u32 pci_bios_prefmem_addr;
/* host irqs corresponding to PCI irqs A-D */
static u8 pci_irqs[4] = {
10, 10, 11, 11
@@ -66,21 +67,54 @@ static int pci_bios_allocate_region(u16 bdf, int region_num)
u32 val = pci_config_readl(bdf, ofs);
pci_config_writel(bdf, ofs, old);
+ u32 size = (~(val & mask)) + 1;
if (val != 0) {
- u32 size = (~(val & mask)) + 1;
- if (val & PCI_BASE_ADDRESS_SPACE_IO)
+ if (val & PCI_BASE_ADDRESS_SPACE_IO) {
paddr = &pci_bios_io_addr;
- else
+ if (ALIGN(*paddr, size) + size >= 64 * 1024) {
+ dprintf(1,
+ "io region of (bdf 0x%x bar %d) can't be mapped.\n",
+ bdf, region_num);
+ size = 0;
+ }
+ } else if ((val & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
+ /* keep behaviour on bus = 0 */
+ pci_bdf_to_bus(bdf) != 0 &&
+ /* If pci_bios_prefmem_addr == 0, keep old behaviour */
+ pci_bios_prefmem_addr != 0) {
+ paddr = &pci_bios_prefmem_addr;
+ if (ALIGN(*paddr, size) + size >= BUILD_PCIPREFMEM_END) {
+ dprintf(1,
+ "prefmem region of (bdf 0x%x bar %d) can't be mapped. "
+ "decrease BUILD_PCIMEM_SIZE and recompile. size %x\n",
+ bdf, region_num, BUILD_PCIPREFMEM_SIZE);
+ size = 0;
+ }
+ } else {
paddr = &pci_bios_mem_addr;
- *paddr = ALIGN(*paddr, size);
- pci_set_io_region_addr(bdf, region_num, *paddr);
- *paddr += size;
+ if (ALIGN(*paddr, size) + size >= BUILD_PCIMEM_END) {
+ dprintf(1,
+ "mem region of (bdf 0x%x bar %d) can't be mapped. "
+ "increase BUILD_PCIMEM_SIZE and recompile. size %x\n",
+ bdf, region_num, BUILD_PCIMEM_SIZE);
+ size = 0;
+ }
+ }
+ if (size > 0) {
+ *paddr = ALIGN(*paddr, size);
+ pci_set_io_region_addr(bdf, region_num, *paddr);
+ *paddr += size;
+ }
}
int is_64bit = !(val & PCI_BASE_ADDRESS_SPACE_IO) &&
(val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64;
if (is_64bit) {
- pci_config_writel(bdf, ofs + 4, 0);
+ if (size > 0) {
+ pci_config_writel(bdf, ofs + 4, 0);
+ } else {
+ pci_config_writel(bdf, ofs + 4, ~0);
+ }
}
return is_64bit;
}
@@ -220,6 +254,7 @@ pci_setup(void)
pci_bios_io_addr = 0xc000;
pci_bios_mem_addr = BUILD_PCIMEM_START;
+ pci_bios_prefmem_addr = BUILD_PCIPREFMEM_START;
int bdf, max;
foreachpci(bdf, max) {