--- /home/rossb/local/linux-2.4.18/arch/i386/kernel/setup.c 2003-09-23 19:55:13.000000000 -0700 +++ setup.c 2004-03-24 10:20:56.000000000 -0800 @@ -113,6 +113,17 @@ #include #include #include + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) + +/* + * Reserved space for vmalloc and iomap - defined in asm/page.h + */ +#define MAXMEM_PFN PFN_DOWN(MAXMEM) +#define MAX_NONPAE_PFN (1 << 20) + /* * Machine setup.. */ @@ -121,6 +132,8 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; unsigned long mmu_cr4_features; +unsigned long num_e820physpages; +unsigned long num_e820_nonpae_physpages; /* * Bus types .. @@ -151,6 +164,7 @@ }; struct e820map e820; +struct e820map bios_e820; unsigned char aux_device_present; @@ -710,11 +724,44 @@ char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; int usermem = 0; + int i; + unsigned long max_pfn; /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + /* Compute this here in case the user wants to know it later. */ + max_pfn = 0; + max_low_pfn = 0; + for (i = 0; i < e820.nr_map; i++) { + unsigned long start, end; + /* RAM? */ + if (e820.map[i].type != E820_RAM && + e820.map[i].type != E820_ACPI) + continue; + + start = PFN_UP(e820.map[i].addr); + end = PFN_DOWN(e820.map[i].addr + e820.map[i].size); + if (start >= end) + continue; + if (end > MAX_NONPAE_PFN) { + if (start < MAX_NONPAE_PFN) { + max_low_pfn = MAX_NONPAE_PFN; + } + } else { + if (end > max_low_pfn) { + max_low_pfn = end; + } + } + if (end > max_pfn) + max_pfn = end; + } + + num_e820physpages = max_pfn; + num_e820_nonpae_physpages = max_low_pfn; + memcpy(&bios_e820, &e820, sizeof(e820)); + for (;;) { /* * "mem=nopentium" disables the 4MB page tables. @@ -783,6 +830,7 @@ { unsigned long bootmap_size, low_mem_size; unsigned long start_pfn, max_pfn, max_low_pfn; + unsigned long e820_low_mem_size; int i; #ifdef CONFIG_VISWS @@ -822,16 +870,6 @@ parse_mem_cmdline(cmdline_p); -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) - -/* - * Reserved space for vmalloc and iomap - defined in asm/page.h - */ -#define MAXMEM_PFN PFN_DOWN(MAXMEM) -#define MAX_NONPAE_PFN (1 << 20) - /* * partially used pages are not usable - thus * we are rounding upwards: @@ -1032,8 +1070,16 @@ /* Tell the PCI layer not to allocate too close to the RAM area.. */ low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff; + + e820_low_mem_size = ((num_e820_nonpae_physpages << PAGE_SHIFT) + + 0xfffff) & ~0xfffff; + + if (e820_low_mem_size > pci_mem_start) + pci_mem_start = e820_low_mem_size; + if (low_mem_size > pci_mem_start) pci_mem_start = low_mem_size; + #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE)