diff options
Diffstat (limited to 'arch/x86/kernel/e820_64.c')
-rw-r--r-- | arch/x86/kernel/e820_64.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c index c617174e8963..9f65b4cc323c 100644 --- a/arch/x86/kernel/e820_64.c +++ b/arch/x86/kernel/e820_64.c | |||
@@ -54,30 +54,33 @@ static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT; | |||
54 | 54 | ||
55 | struct early_res { | 55 | struct early_res { |
56 | unsigned long start, end; | 56 | unsigned long start, end; |
57 | char name[16]; | ||
57 | }; | 58 | }; |
58 | static struct early_res early_res[MAX_EARLY_RES] __initdata = { | 59 | static struct early_res early_res[MAX_EARLY_RES] __initdata = { |
59 | { 0, PAGE_SIZE }, /* BIOS data page */ | 60 | { 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */ |
60 | #ifdef CONFIG_SMP | 61 | #ifdef CONFIG_SMP |
61 | { SMP_TRAMPOLINE_BASE, SMP_TRAMPOLINE_BASE + 2*PAGE_SIZE }, | 62 | { SMP_TRAMPOLINE_BASE, SMP_TRAMPOLINE_BASE + 2*PAGE_SIZE, "SMP_TRAMPOLINE" }, |
62 | #endif | 63 | #endif |
63 | {} | 64 | {} |
64 | }; | 65 | }; |
65 | 66 | ||
66 | void __init reserve_early(unsigned long start, unsigned long end) | 67 | void __init reserve_early(unsigned long start, unsigned long end, char *name) |
67 | { | 68 | { |
68 | int i; | 69 | int i; |
69 | struct early_res *r; | 70 | struct early_res *r; |
70 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { | 71 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { |
71 | r = &early_res[i]; | 72 | r = &early_res[i]; |
72 | if (end > r->start && start < r->end) | 73 | if (end > r->start && start < r->end) |
73 | panic("Overlapping early reservations %lx-%lx to %lx-%lx\n", | 74 | panic("Overlapping early reservations %lx-%lx %s to %lx-%lx %s\n", |
74 | start, end, r->start, r->end); | 75 | start, end - 1, name?name:"", r->start, r->end - 1, r->name); |
75 | } | 76 | } |
76 | if (i >= MAX_EARLY_RES) | 77 | if (i >= MAX_EARLY_RES) |
77 | panic("Too many early reservations"); | 78 | panic("Too many early reservations"); |
78 | r = &early_res[i]; | 79 | r = &early_res[i]; |
79 | r->start = start; | 80 | r->start = start; |
80 | r->end = end; | 81 | r->end = end; |
82 | if (name) | ||
83 | strncpy(r->name, name, sizeof(r->name) - 1); | ||
81 | } | 84 | } |
82 | 85 | ||
83 | void __init early_res_to_bootmem(void) | 86 | void __init early_res_to_bootmem(void) |
@@ -85,6 +88,8 @@ void __init early_res_to_bootmem(void) | |||
85 | int i; | 88 | int i; |
86 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { | 89 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { |
87 | struct early_res *r = &early_res[i]; | 90 | struct early_res *r = &early_res[i]; |
91 | printk(KERN_INFO "early res: %d [%lx-%lx] %s\n", i, | ||
92 | r->start, r->end - 1, r->name); | ||
88 | reserve_bootmem_generic(r->start, r->end - r->start); | 93 | reserve_bootmem_generic(r->start, r->end - r->start); |
89 | } | 94 | } |
90 | } | 95 | } |
@@ -166,12 +171,13 @@ int __init e820_all_mapped(unsigned long start, unsigned long end, | |||
166 | } | 171 | } |
167 | 172 | ||
168 | /* | 173 | /* |
169 | * Find a free area in a specific range. | 174 | * Find a free area with specified alignment in a specific range. |
170 | */ | 175 | */ |
171 | unsigned long __init find_e820_area(unsigned long start, unsigned long end, | 176 | unsigned long __init find_e820_area(unsigned long start, unsigned long end, |
172 | unsigned size) | 177 | unsigned size, unsigned long align) |
173 | { | 178 | { |
174 | int i; | 179 | int i; |
180 | unsigned long mask = ~(align - 1); | ||
175 | 181 | ||
176 | for (i = 0; i < e820.nr_map; i++) { | 182 | for (i = 0; i < e820.nr_map; i++) { |
177 | struct e820entry *ei = &e820.map[i]; | 183 | struct e820entry *ei = &e820.map[i]; |
@@ -185,7 +191,8 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, | |||
185 | continue; | 191 | continue; |
186 | while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size) | 192 | while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size) |
187 | ; | 193 | ; |
188 | last = PAGE_ALIGN(addr) + size; | 194 | addr = (addr + align - 1) & mask; |
195 | last = addr + size; | ||
189 | if (last > ei->addr + ei->size) | 196 | if (last > ei->addr + ei->size) |
190 | continue; | 197 | continue; |
191 | if (last > end) | 198 | if (last > end) |