From: James S. <jsi...@us...> - 2005-04-05 18:26:53
|
Update of /cvsroot/linuxconsole/ruby/ruby-2.6/arch/i386/kernel In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21490 Modified Files: setup.c Log Message: Syned to linus tree. Index: setup.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/ruby-2.6/arch/i386/kernel/setup.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- setup.c 22 Oct 2004 07:46:16 -0000 1.12 +++ setup.c 5 Apr 2005 18:26:36 -0000 1.13 @@ -32,13 +32,14 @@ #include <linux/initrd.h> #include <linux/bootmem.h> #include <linux/seq_file.h> -#include <linux/console.h> +#include <linux/mca.h> #include <linux/root_dev.h> #include <linux/highmem.h> #include <linux/module.h> #include <linux/efi.h> #include <linux/init.h> #include <linux/edd.h> +#include <linux/nodemask.h> #include <video/edid.h> #include <asm/e820.h> #include <asm/mpspec.h> @@ -73,7 +74,6 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; unsigned long mmu_cr4_features; -EXPORT_SYMBOL_GPL(mmu_cr4_features); #ifdef CONFIG_ACPI_INTERPRETER int acpi_disabled = 0; @@ -87,7 +87,6 @@ extern acpi_interrupt_flags acpi_sci_flags; #endif -int MCA_bus; /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; unsigned int machine_submodel_id; @@ -97,6 +96,9 @@ /* 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; + /* user-defined highmem size */ static unsigned int highmem_pages = -1; @@ -114,8 +116,6 @@ struct ist_info ist_info; struct e820map e820; -unsigned char aux_device_present; - extern void early_cpu_init(void); extern void dmi_scan_machine(void); extern void generic_apic_probe(char *); @@ -424,10 +424,10 @@ struct e820entry *pbios; /* pointer to original bios entry */ unsigned long long addr; /* address for this change point */ }; -struct change_member change_point_list[2*E820MAX] __initdata; -struct change_member *change_point[2*E820MAX] __initdata; -struct e820entry *overlap_list[E820MAX] __initdata; -struct e820entry new_bios[E820MAX] __initdata; +static struct change_member change_point_list[2*E820MAX] __initdata; +static struct change_member *change_point[2*E820MAX] __initdata; +static struct e820entry *overlap_list[E820MAX] __initdata; +static struct e820entry new_bios[E820MAX] __initdata; static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) { @@ -672,6 +672,8 @@ saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; for (;;) { + if (c != ' ') + goto next_char; /* * "mem=nopentium" disables the 4MB page tables. * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM @@ -682,7 +684,7 @@ * HPA tells me bootloaders need to parse mem=, so no new * option should be mem= [also see Documentation/i386/boot.txt] */ - if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (!memcmp(from, "mem=", 4)) { if (to != command_line) to--; if (!memcmp(from+4, "nopentium", 9)) { @@ -704,7 +706,7 @@ } } - if (c == ' ' && !memcmp(from, "memmap=", 7)) { + else if (!memcmp(from, "memmap=", 7)) { if (to != command_line) to--; if (!memcmp(from+7, "exactmap", 8)) { @@ -737,6 +739,10 @@ } } + else if (!memcmp(from, "noexec=", 7)) + noexec_setup(from + 7); + + #ifdef CONFIG_X86_SMP /* * If the BIOS enumerates physical processors before logical, @@ -812,7 +818,7 @@ * This works even on boxes that have no highmem otherwise. * This also works to reduce highmem size on bigger boxes. */ - if (c == ' ' && !memcmp(from, "highmem=", 8)) + else if (!memcmp(from, "highmem=", 8)) highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; /* @@ -820,9 +826,10 @@ * bytes. This can be used to increase (or decrease) the * vmalloc area - the default is 128m. */ - if (c == ' ' && !memcmp(from, "vmalloc=", 8)) + else if (!memcmp(from, "vmalloc=", 8)) __VMALLOC_RESERVE = memparse(from+8, &from); + next_char: c = *(from++); if (!c) break; @@ -941,8 +948,6 @@ return max_low_pfn; } -#ifndef CONFIG_DISCONTIGMEM - /* * Free all available memory for boot time allocation. Used * as a callback function by efi_memory_walk() @@ -1016,15 +1021,15 @@ reserve_bootmem(addr, PAGE_SIZE); } +#ifndef CONFIG_DISCONTIGMEM +void __init setup_bootmem_allocator(void); static unsigned long __init setup_memory(void) { - unsigned long bootmap_size, start_pfn, max_low_pfn; - /* * partially used pages are not usable - thus * we are rounding upwards: */ - start_pfn = PFN_UP(init_pg_tables_end); + min_low_pfn = PFN_UP(init_pg_tables_end); find_max_pfn(); @@ -1040,10 +1045,43 @@ #endif printk(KERN_NOTICE "%ldMB LOWMEM available.\n", pages_to_mb(max_low_pfn)); + + setup_bootmem_allocator(); + + return max_low_pfn; +} + +void __init zone_sizes_init(void) +{ + unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; + unsigned int max_dma, low; + + max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; + low = max_low_pfn; + + if (low < max_dma) + zones_size[ZONE_DMA] = low; + else { + zones_size[ZONE_DMA] = max_dma; + zones_size[ZONE_NORMAL] = low - max_dma; +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = highend_pfn - low; +#endif + } + free_area_init(zones_size); +} +#else +extern unsigned long setup_memory(void); +extern void zone_sizes_init(void); +#endif /* !CONFIG_DISCONTIGMEM */ + +void __init setup_bootmem_allocator(void) +{ + unsigned long bootmap_size; /* * Initialize the boot-time allocator (with low memory only): */ - bootmap_size = init_bootmem(start_pfn, max_low_pfn); + bootmap_size = init_bootmem(min_low_pfn, max_low_pfn); register_bootmem_low_pages(max_low_pfn); @@ -1053,7 +1091,7 @@ * the (very unlikely) case of us accidentally initializing the * bootmem allocator with an invalid RAM area. */ - reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) + + reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(min_low_pfn) + bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY)); /* @@ -1110,11 +1148,25 @@ } } #endif - return max_low_pfn; } -#else -extern unsigned long setup_memory(void); -#endif /* !CONFIG_DISCONTIGMEM */ + +/* + * The node 0 pgdat is initialized before all of these because + * it's needed for bootmem. node>0 pgdats have their virtual + * space allocated before the pagetables are in place to access + * them, so they can't be cleared then. + * + * This should all compile down to nothing when NUMA is off. + */ +void __init remapped_pgdat_init(void) +{ + int nid; + + for_each_online_node(nid) { + if (nid != 0) + memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); + } +} /* * Request address space for all standard RAM and ROM resources @@ -1156,9 +1208,10 @@ /* * Request address space for all standard resources */ -static void __init register_memory(unsigned long max_low_pfn) +static void __init register_memory(void) { - unsigned long low_mem_size; + unsigned long gapstart, gapsize; + unsigned long long last; int i; if (efi_enabled) @@ -1173,10 +1226,46 @@ for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_resource(&ioport_resource, &standard_io_resources[i]); - /* Tell the PCI layer not to allocate too close to the RAM area.. */ - low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff; - if (low_mem_size > pci_mem_start) - pci_mem_start = low_mem_size; + /* + * Search for the bigest gap in the low 32 bits of the e820 + * memory space. + */ + 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; + } + } + if (start < last) + last = start; + } + + /* + * 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("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", + pci_mem_start, gapstart, gapsize); } /* Use inline assembly to define this because the nops are defined @@ -1288,6 +1377,15 @@ static char * __init machine_specific_memory_setup(void); +#ifdef CONFIG_MCA +static void set_mca_bus(int x) +{ + MCA_bus = x; +} +#else +static void set_mca_bus(int x) { } +#endif + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -1323,12 +1421,12 @@ ist_info = IST_INFO; saved_videomode = VIDEO_MODE; if( SYS_DESC_TABLE.length != 0 ) { - MCA_bus = SYS_DESC_TABLE.table[3] &0x2; + set_mca_bus(SYS_DESC_TABLE.table[3] & 0x2); machine_id = SYS_DESC_TABLE.table[0]; machine_submodel_id = SYS_DESC_TABLE.table[1]; BIOS_revision = SYS_DESC_TABLE.table[2]; } - aux_device_present = AUX_DEVICE_INFO; + bootloader_type = LOADER_TYPE; #ifdef CONFIG_BLK_DEV_RAM rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; @@ -1375,6 +1473,8 @@ smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ #endif paging_init(); + remapped_pgdat_init(); + zone_sizes_init(); /* * NOTE: at this point the bootmem allocator is fully available. @@ -1404,6 +1504,7 @@ /* * Parse the ACPI tables for possible boot-time SMP configuration. */ + acpi_boot_table_init(); acpi_boot_init(); #ifdef CONFIG_X86_LOCAL_APIC @@ -1411,7 +1512,7 @@ get_smp_config(); #endif - register_memory(max_low_pfn); + register_memory(); } #include "setup_arch_post.h" |