mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-07 23:28:55 +00:00
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:
parent
df5f6c212c
commit
ab4a465e96
6 changed files with 88 additions and 193 deletions
|
@ -890,3 +890,89 @@ u64 __init e820_hole_size(u64 start, u64 end)
|
||||||
}
|
}
|
||||||
return end - start - ((u64)ram << PAGE_SHIFT);
|
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 */
|
/* Overridden in paravirt.c if CONFIG_PARAVIRT */
|
||||||
char * __init __attribute__((weak)) memory_setup(void)
|
char * __init __attribute__((weak)) memory_setup(void)
|
||||||
{
|
{
|
||||||
|
@ -249,93 +219,3 @@ void __init setup_memory_map(void)
|
||||||
e820_print_map(memory_setup());
|
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;
|
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 __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
|
||||||
{
|
{
|
||||||
int i;
|
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,
|
extern void e820_register_active_regions(int nid, unsigned long start_pfn,
|
||||||
unsigned long end_pfn);
|
unsigned long end_pfn);
|
||||||
extern u64 e820_hole_size(u64 start, u64 end);
|
extern u64 e820_hole_size(u64 start, u64 end);
|
||||||
|
extern void finish_e820_parsing(void);
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#define ISA_START_ADDRESS 0xa0000
|
#define ISA_START_ADDRESS 0xa0000
|
||||||
|
|
|
@ -19,9 +19,7 @@
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
extern void setup_memory_map(void);
|
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,
|
extern void init_iomem_resources(struct resource *code_resource,
|
||||||
struct resource *data_resource,
|
struct resource *data_resource,
|
||||||
struct resource *bss_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 e820_all_non_reserved(unsigned long start, unsigned long end);
|
||||||
extern int is_memory_all_valid(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/*!__ASSEMBLY__*/
|
||||||
|
|
||||||
#endif/*__E820_HEADER*/
|
#endif/*__E820_HEADER*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue