x86: e820 merge parsing of the mem=/memmap= boot parameters
since we now have 32-bit support for e820_register_active_regions(), we can merge the parsing of the mem=/memmap= boot parameters. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Родитель
df5f6c212c
Коммит
ab4a465e96
|
@ -890,3 +890,89 @@ u64 __init e820_hole_size(u64 start, u64 end)
|
|||
}
|
||||
return end - start - ((u64)ram << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
static void early_panic(char *msg)
|
||||
{
|
||||
early_printk(msg);
|
||||
panic(msg);
|
||||
}
|
||||
|
||||
/* "mem=nopentium" disables the 4MB page tables. */
|
||||
static int __init parse_memopt(char *p)
|
||||
{
|
||||
u64 mem_size;
|
||||
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
if (!strcmp(p, "nopentium")) {
|
||||
setup_clear_cpu_cap(X86_FEATURE_PSE);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
mem_size = memparse(p, &p);
|
||||
end_user_pfn = mem_size>>PAGE_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
early_param("mem", parse_memopt);
|
||||
|
||||
static int userdef __initdata;
|
||||
|
||||
static int __init parse_memmap_opt(char *p)
|
||||
{
|
||||
char *oldp;
|
||||
u64 start_at, mem_size;
|
||||
|
||||
if (!strcmp(p, "exactmap")) {
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
/*
|
||||
* If we are doing a crash dump, we still need to know
|
||||
* the real mem size before original memory map is
|
||||
* reset.
|
||||
*/
|
||||
e820_register_active_regions(0, 0, -1UL);
|
||||
saved_max_pfn = e820_end_of_ram();
|
||||
remove_all_active_ranges();
|
||||
#endif
|
||||
e820.nr_map = 0;
|
||||
userdef = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
oldp = p;
|
||||
mem_size = memparse(p, &p);
|
||||
if (p == oldp)
|
||||
return -EINVAL;
|
||||
|
||||
userdef = 1;
|
||||
if (*p == '@') {
|
||||
start_at = memparse(p+1, &p);
|
||||
add_memory_region(start_at, mem_size, E820_RAM);
|
||||
} else if (*p == '#') {
|
||||
start_at = memparse(p+1, &p);
|
||||
add_memory_region(start_at, mem_size, E820_ACPI);
|
||||
} else if (*p == '$') {
|
||||
start_at = memparse(p+1, &p);
|
||||
add_memory_region(start_at, mem_size, E820_RESERVED);
|
||||
} else {
|
||||
end_user_pfn = (mem_size >> PAGE_SHIFT);
|
||||
}
|
||||
return *p == '\0' ? 0 : -EINVAL;
|
||||
}
|
||||
early_param("memmap", parse_memmap_opt);
|
||||
|
||||
void __init finish_e820_parsing(void)
|
||||
{
|
||||
if (userdef) {
|
||||
int nr = e820.nr_map;
|
||||
|
||||
if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
|
||||
early_panic("Invalid user supplied memory map");
|
||||
e820.nr_map = nr;
|
||||
|
||||
printk(KERN_INFO "user-defined physical RAM map:\n");
|
||||
e820_print_map("user");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,36 +207,6 @@ void __init init_iomem_resources(struct resource *code_resource,
|
|||
}
|
||||
}
|
||||
|
||||
void __init limit_regions(unsigned long long size)
|
||||
{
|
||||
unsigned long long current_addr;
|
||||
int i;
|
||||
|
||||
e820_print_map("limit_regions start");
|
||||
for (i = 0; i < e820.nr_map; i++) {
|
||||
current_addr = e820.map[i].addr + e820.map[i].size;
|
||||
if (current_addr < size)
|
||||
continue;
|
||||
|
||||
if (e820.map[i].type != E820_RAM)
|
||||
continue;
|
||||
|
||||
if (e820.map[i].addr >= size) {
|
||||
/*
|
||||
* This region starts past the end of the
|
||||
* requested size, skip it completely.
|
||||
*/
|
||||
e820.nr_map = i;
|
||||
} else {
|
||||
e820.nr_map = i + 1;
|
||||
e820.map[i].size -= current_addr - size;
|
||||
}
|
||||
e820_print_map("limit_regions endfor");
|
||||
return;
|
||||
}
|
||||
e820_print_map("limit_regions endfunc");
|
||||
}
|
||||
|
||||
/* Overridden in paravirt.c if CONFIG_PARAVIRT */
|
||||
char * __init __attribute__((weak)) memory_setup(void)
|
||||
{
|
||||
|
@ -249,93 +219,3 @@ void __init setup_memory_map(void)
|
|||
e820_print_map(memory_setup());
|
||||
}
|
||||
|
||||
static int __initdata user_defined_memmap;
|
||||
|
||||
/*
|
||||
* "mem=nopentium" disables the 4MB page tables.
|
||||
* "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
|
||||
* to <mem>, overriding the bios size.
|
||||
* "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
|
||||
* <start> to <start>+<mem>, overriding the bios size.
|
||||
*
|
||||
* HPA tells me bootloaders need to parse mem=, so no new
|
||||
* option should be mem= [also see Documentation/i386/boot.txt]
|
||||
*/
|
||||
static int __init parse_mem(char *arg)
|
||||
{
|
||||
if (!arg)
|
||||
return -EINVAL;
|
||||
|
||||
if (strcmp(arg, "nopentium") == 0) {
|
||||
setup_clear_cpu_cap(X86_FEATURE_PSE);
|
||||
} else {
|
||||
/* If the user specifies memory size, we
|
||||
* limit the BIOS-provided memory map to
|
||||
* that size. exactmap can be used to specify
|
||||
* the exact map. mem=number can be used to
|
||||
* trim the existing memory map.
|
||||
*/
|
||||
unsigned long long mem_size;
|
||||
|
||||
mem_size = memparse(arg, &arg);
|
||||
limit_regions(mem_size);
|
||||
user_defined_memmap = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
early_param("mem", parse_mem);
|
||||
|
||||
static int __init parse_memmap(char *arg)
|
||||
{
|
||||
if (!arg)
|
||||
return -EINVAL;
|
||||
|
||||
if (strcmp(arg, "exactmap") == 0) {
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
/* If we are doing a crash dump, we
|
||||
* still need to know the real mem
|
||||
* size before original memory map is
|
||||
* reset.
|
||||
*/
|
||||
e820_register_active_regions(0, 0, -1UL);
|
||||
saved_max_pfn = e820_end_of_ram();
|
||||
remove_all_active_ranges();
|
||||
#endif
|
||||
e820.nr_map = 0;
|
||||
user_defined_memmap = 1;
|
||||
} else {
|
||||
/* If the user specifies memory size, we
|
||||
* limit the BIOS-provided memory map to
|
||||
* that size. exactmap can be used to specify
|
||||
* the exact map. mem=number can be used to
|
||||
* trim the existing memory map.
|
||||
*/
|
||||
unsigned long long start_at, mem_size;
|
||||
|
||||
mem_size = memparse(arg, &arg);
|
||||
if (*arg == '@') {
|
||||
start_at = memparse(arg+1, &arg);
|
||||
add_memory_region(start_at, mem_size, E820_RAM);
|
||||
} else if (*arg == '#') {
|
||||
start_at = memparse(arg+1, &arg);
|
||||
add_memory_region(start_at, mem_size, E820_ACPI);
|
||||
} else if (*arg == '$') {
|
||||
start_at = memparse(arg+1, &arg);
|
||||
add_memory_region(start_at, mem_size, E820_RESERVED);
|
||||
} else {
|
||||
limit_regions(mem_size);
|
||||
user_defined_memmap = 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
early_param("memmap", parse_memmap);
|
||||
|
||||
void __init finish_e820_parsing(void)
|
||||
{
|
||||
if (user_defined_memmap) {
|
||||
printk(KERN_INFO "user-defined physical RAM map:\n");
|
||||
e820_print_map("user");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,75 +96,6 @@ char *__init machine_specific_memory_setup(void)
|
|||
return who;
|
||||
}
|
||||
|
||||
static int __init parse_memopt(char *p)
|
||||
{
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
end_user_pfn = memparse(p, &p);
|
||||
end_user_pfn >>= PAGE_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
early_param("mem", parse_memopt);
|
||||
|
||||
static int userdef __initdata;
|
||||
|
||||
static int __init parse_memmap_opt(char *p)
|
||||
{
|
||||
char *oldp;
|
||||
unsigned long long start_at, mem_size;
|
||||
|
||||
if (!strcmp(p, "exactmap")) {
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
/*
|
||||
* If we are doing a crash dump, we still need to know
|
||||
* the real mem size before original memory map is
|
||||
* reset.
|
||||
*/
|
||||
e820_register_active_regions(0, 0, -1UL);
|
||||
saved_max_pfn = e820_end_of_ram();
|
||||
remove_all_active_ranges();
|
||||
#endif
|
||||
e820.nr_map = 0;
|
||||
userdef = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
oldp = p;
|
||||
mem_size = memparse(p, &p);
|
||||
if (p == oldp)
|
||||
return -EINVAL;
|
||||
|
||||
userdef = 1;
|
||||
if (*p == '@') {
|
||||
start_at = memparse(p+1, &p);
|
||||
add_memory_region(start_at, mem_size, E820_RAM);
|
||||
} else if (*p == '#') {
|
||||
start_at = memparse(p+1, &p);
|
||||
add_memory_region(start_at, mem_size, E820_ACPI);
|
||||
} else if (*p == '$') {
|
||||
start_at = memparse(p+1, &p);
|
||||
add_memory_region(start_at, mem_size, E820_RESERVED);
|
||||
} else {
|
||||
end_user_pfn = (mem_size >> PAGE_SHIFT);
|
||||
}
|
||||
return *p == '\0' ? 0 : -EINVAL;
|
||||
}
|
||||
early_param("memmap", parse_memmap_opt);
|
||||
|
||||
void __init finish_e820_parsing(void)
|
||||
{
|
||||
if (userdef) {
|
||||
int nr = e820.nr_map;
|
||||
|
||||
if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
|
||||
early_panic("Invalid user supplied memory map");
|
||||
e820.nr_map = nr;
|
||||
|
||||
printk(KERN_INFO "user-defined physical RAM map:\n");
|
||||
e820_print_map("user");
|
||||
}
|
||||
}
|
||||
|
||||
int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -98,6 +98,8 @@ extern int e820_find_active_region(const struct e820entry *ei,
|
|||
extern void e820_register_active_regions(int nid, unsigned long start_pfn,
|
||||
unsigned long end_pfn);
|
||||
extern u64 e820_hole_size(u64 start, u64 end);
|
||||
extern void finish_e820_parsing(void);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#define ISA_START_ADDRESS 0xa0000
|
||||
|
|
|
@ -19,9 +19,7 @@
|
|||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void setup_memory_map(void);
|
||||
extern void finish_e820_parsing(void);
|
||||
|
||||
extern void limit_regions(unsigned long long size);
|
||||
extern void init_iomem_resources(struct resource *code_resource,
|
||||
struct resource *data_resource,
|
||||
struct resource *bss_resource);
|
||||
|
|
|
@ -22,8 +22,6 @@ extern int is_memory_any_valid(unsigned long start, unsigned long end);
|
|||
extern int e820_all_non_reserved(unsigned long start, unsigned long end);
|
||||
extern int is_memory_all_valid(unsigned long start, unsigned long end);
|
||||
|
||||
extern void finish_e820_parsing(void);
|
||||
|
||||
#endif/*!__ASSEMBLY__*/
|
||||
|
||||
#endif/*__E820_HEADER*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче