Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 94
b: refs/heads/master
c: a1e9778
h: refs/heads/master
v: v3
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Apr 16, 2005
1 parent ed3d1b8 commit 1ea1914
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cf94b62f7005805be0a3ba02c624cb8cd3595bac
refs/heads/master: a1e9778203b15b86bc2219e87478d3be9acce735
59 changes: 59 additions & 0 deletions trunk/arch/x86_64/kernel/e820.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,62 @@ void __init parse_memopt(char *p, char **from)
end_user_pfn >>= PAGE_SHIFT;
}

unsigned long pci_mem_start = 0xaeedbabe;

/*
* Search for the biggest gap in the low 32 bits of the e820
* memory space. We pass this space to PCI to assign MMIO resources
* for hotplug or unconfigured devices in.
* Hopefully the BIOS let enough space left.
*/
__init void e820_setup_gap(void)
{
unsigned long gapstart, gapsize;
unsigned long last;
int i;
int found = 0;

last = 0x100000000ull;
gapstart = 0x10000000;
gapsize = 0x400000;
i = e820.nr_map;
while (--i >= 0) {
unsigned long long start = e820.map[i].addr;
unsigned long long end = start + e820.map[i].size;

/*
* Since "last" is at most 4GB, we know we'll
* fit in 32 bits if this condition is true
*/
if (last > end) {
unsigned long gap = last - end;

if (gap > gapsize) {
gapsize = gap;
gapstart = end;
found = 1;
}
}
if (start < last)
last = start;
}

if (!found) {
gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024;
printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n"
KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n");
}

/*
* Start allocating dynamic PCI memory a bit into the gap,
* aligned up to the nearest megabyte.
*
* Question: should we try to pad it up a bit (do something
* like " + (gapsize >> 3)" in there too?). We now have the
* technology.
*/
pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;

printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
pci_mem_start, gapstart, gapsize);
}
12 changes: 1 addition & 11 deletions trunk/arch/x86_64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ int __initdata acpi_force = 0;

int acpi_numa __initdata;

/* For PCI or other memory-mapped resources */
unsigned long pci_mem_start = 0x10000000;

/* Boot loader ID as an integer, for the benefit of proc_dointvec */
int bootloader_type;

Expand Down Expand Up @@ -495,7 +492,6 @@ static void __init reserve_ebda_region(void)

void __init setup_arch(char **cmdline_p)
{
unsigned long low_mem_size;
unsigned long kernel_end;

ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
Expand Down Expand Up @@ -654,13 +650,7 @@ void __init setup_arch(char **cmdline_p)
request_resource(&ioport_resource, &standard_io_resources[i]);
}

/* Will likely break when you have unassigned resources with more
than 4GB memory and bridges that don't support more than 4GB.
Doing it properly would require to use pci_alloc_consistent
in this case. */
low_mem_size = ((end_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
if (low_mem_size > pci_mem_start)
pci_mem_start = low_mem_size;
e820_setup_gap();

#ifdef CONFIG_GART_IOMMU
iommu_hole_init();
Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-x86_64/e820.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern void e820_print_map(char *who);
extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);

extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
extern void e820_setup_gap(void);

extern void __init parse_memopt(char *p, char **end);

Expand Down

0 comments on commit 1ea1914

Please sign in to comment.