aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/e820.c152
-rw-r--r--arch/i386/kernel/setup.c153
-rw-r--r--include/asm-i386/e820.h2
3 files changed, 155 insertions, 152 deletions
diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c
index 47c495bf0cbc..b755255f2721 100644
--- a/arch/i386/kernel/e820.c
+++ b/arch/i386/kernel/e820.c
@@ -33,6 +33,7 @@ unsigned long pci_mem_start = 0x10000000;
33#ifdef CONFIG_PCI 33#ifdef CONFIG_PCI
34EXPORT_SYMBOL(pci_mem_start); 34EXPORT_SYMBOL(pci_mem_start);
35#endif 35#endif
36extern int user_defined_memmap;
36struct resource data_resource = { 37struct resource data_resource = {
37 .name = "Kernel data", 38 .name = "Kernel data",
38 .start = 0, 39 .start = 0,
@@ -706,3 +707,154 @@ void __init register_memory(void)
706 printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", 707 printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
707 pci_mem_start, gapstart, gapsize); 708 pci_mem_start, gapstart, gapsize);
708} 709}
710
711void __init print_memory_map(char *who)
712{
713 int i;
714
715 for (i = 0; i < e820.nr_map; i++) {
716 printk(" %s: %016Lx - %016Lx ", who,
717 e820.map[i].addr,
718 e820.map[i].addr + e820.map[i].size);
719 switch (e820.map[i].type) {
720 case E820_RAM: printk("(usable)\n");
721 break;
722 case E820_RESERVED:
723 printk("(reserved)\n");
724 break;
725 case E820_ACPI:
726 printk("(ACPI data)\n");
727 break;
728 case E820_NVS:
729 printk("(ACPI NVS)\n");
730 break;
731 default: printk("type %lu\n", e820.map[i].type);
732 break;
733 }
734 }
735}
736
737void __init limit_regions(unsigned long long size)
738{
739 unsigned long long current_addr = 0;
740 int i;
741
742 print_memory_map("limit_regions start");
743 if (efi_enabled) {
744 efi_memory_desc_t *md;
745 void *p;
746
747 for (p = memmap.map, i = 0; p < memmap.map_end;
748 p += memmap.desc_size, i++) {
749 md = p;
750 current_addr = md->phys_addr + (md->num_pages << 12);
751 if (md->type == EFI_CONVENTIONAL_MEMORY) {
752 if (current_addr >= size) {
753 md->num_pages -=
754 (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
755 memmap.nr_map = i + 1;
756 return;
757 }
758 }
759 }
760 }
761 for (i = 0; i < e820.nr_map; i++) {
762 current_addr = e820.map[i].addr + e820.map[i].size;
763 if (current_addr < size)
764 continue;
765
766 if (e820.map[i].type != E820_RAM)
767 continue;
768
769 if (e820.map[i].addr >= size) {
770 /*
771 * This region starts past the end of the
772 * requested size, skip it completely.
773 */
774 e820.nr_map = i;
775 } else {
776 e820.nr_map = i + 1;
777 e820.map[i].size -= current_addr - size;
778 }
779 print_memory_map("limit_regions endfor");
780 return;
781 }
782 print_memory_map("limit_regions endfunc");
783}
784
785 /*
786 * This function checks if the entire range <start,end> is mapped with type.
787 *
788 * Note: this function only works correct if the e820 table is sorted and
789 * not-overlapping, which is the case
790 */
791int __init
792e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
793{
794 u64 start = s;
795 u64 end = e;
796 int i;
797 for (i = 0; i < e820.nr_map; i++) {
798 struct e820entry *ei = &e820.map[i];
799 if (type && ei->type != type)
800 continue;
801 /* is the region (part) in overlap with the current region ?*/
802 if (ei->addr >= end || ei->addr + ei->size <= start)
803 continue;
804 /* if the region is at the beginning of <start,end> we move
805 * start to the end of the region since it's ok until there
806 */
807 if (ei->addr <= start)
808 start = ei->addr + ei->size;
809 /* if start is now at or beyond end, we're done, full
810 * coverage */
811 if (start >= end)
812 return 1; /* we're done */
813 }
814 return 0;
815}
816
817static int __init parse_memmap(char *arg)
818{
819 if (!arg)
820 return -EINVAL;
821
822 if (strcmp(arg, "exactmap") == 0) {
823#ifdef CONFIG_CRASH_DUMP
824 /* If we are doing a crash dump, we
825 * still need to know the real mem
826 * size before original memory map is
827 * reset.
828 */
829 find_max_pfn();
830 saved_max_pfn = max_pfn;
831#endif
832 e820.nr_map = 0;
833 user_defined_memmap = 1;
834 } else {
835 /* If the user specifies memory size, we
836 * limit the BIOS-provided memory map to
837 * that size. exactmap can be used to specify
838 * the exact map. mem=number can be used to
839 * trim the existing memory map.
840 */
841 unsigned long long start_at, mem_size;
842
843 mem_size = memparse(arg, &arg);
844 if (*arg == '@') {
845 start_at = memparse(arg+1, &arg);
846 add_memory_region(start_at, mem_size, E820_RAM);
847 } else if (*arg == '#') {
848 start_at = memparse(arg+1, &arg);
849 add_memory_region(start_at, mem_size, E820_ACPI);
850 } else if (*arg == '$') {
851 start_at = memparse(arg+1, &arg);
852 add_memory_region(start_at, mem_size, E820_RESERVED);
853 } else {
854 limit_regions(mem_size);
855 user_defined_memmap = 1;
856 }
857 }
858 return 0;
859}
860early_param("memmap", parse_memmap);
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 51ed015a1f35..e5bb87aa5a45 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -73,7 +73,6 @@ int disable_pse __devinitdata = 0;
73/* 73/*
74 * Machine setup.. 74 * Machine setup..
75 */ 75 */
76extern struct e820map e820;
77extern struct resource code_resource; 76extern struct resource code_resource;
78extern struct resource data_resource; 77extern struct resource data_resource;
79 78
@@ -137,79 +136,6 @@ static char command_line[COMMAND_LINE_SIZE];
137 136
138unsigned char __initdata boot_params[PARAM_SIZE]; 137unsigned char __initdata boot_params[PARAM_SIZE];
139 138
140static void __init limit_regions(unsigned long long size)
141{
142 unsigned long long current_addr = 0;
143 int i;
144
145 if (efi_enabled) {
146 efi_memory_desc_t *md;
147 void *p;
148
149 for (p = memmap.map, i = 0; p < memmap.map_end;
150 p += memmap.desc_size, i++) {
151 md = p;
152 current_addr = md->phys_addr + (md->num_pages << 12);
153 if (md->type == EFI_CONVENTIONAL_MEMORY) {
154 if (current_addr >= size) {
155 md->num_pages -=
156 (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
157 memmap.nr_map = i + 1;
158 return;
159 }
160 }
161 }
162 }
163 for (i = 0; i < e820.nr_map; i++) {
164 current_addr = e820.map[i].addr + e820.map[i].size;
165 if (current_addr < size)
166 continue;
167
168 if (e820.map[i].type != E820_RAM)
169 continue;
170
171 if (e820.map[i].addr >= size) {
172 /*
173 * This region starts past the end of the
174 * requested size, skip it completely.
175 */
176 e820.nr_map = i;
177 } else {
178 e820.nr_map = i + 1;
179 e820.map[i].size -= current_addr - size;
180 }
181 return;
182 }
183}
184
185#define E820_DEBUG 1
186
187static void __init print_memory_map(char *who)
188{
189 int i;
190
191 for (i = 0; i < e820.nr_map; i++) {
192 printk(" %s: %016Lx - %016Lx ", who,
193 e820.map[i].addr,
194 e820.map[i].addr + e820.map[i].size);
195 switch (e820.map[i].type) {
196 case E820_RAM: printk("(usable)\n");
197 break;
198 case E820_RESERVED:
199 printk("(reserved)\n");
200 break;
201 case E820_ACPI:
202 printk("(ACPI data)\n");
203 break;
204 case E820_NVS:
205 printk("(ACPI NVS)\n");
206 break;
207 default: printk("type %lu\n", e820.map[i].type);
208 break;
209 }
210 }
211}
212
213#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 139#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
214struct edd edd; 140struct edd edd;
215#ifdef CONFIG_EDD_MODULE 141#ifdef CONFIG_EDD_MODULE
@@ -233,7 +159,7 @@ static inline void copy_edd(void)
233} 159}
234#endif 160#endif
235 161
236static int __initdata user_defined_memmap = 0; 162int __initdata user_defined_memmap = 0;
237 163
238/* 164/*
239 * "mem=nopentium" disables the 4MB page tables. 165 * "mem=nopentium" disables the 4MB page tables.
@@ -270,51 +196,6 @@ static int __init parse_mem(char *arg)
270} 196}
271early_param("mem", parse_mem); 197early_param("mem", parse_mem);
272 198
273static int __init parse_memmap(char *arg)
274{
275 if (!arg)
276 return -EINVAL;
277
278 if (strcmp(arg, "exactmap") == 0) {
279#ifdef CONFIG_CRASH_DUMP
280 /* If we are doing a crash dump, we
281 * still need to know the real mem
282 * size before original memory map is
283 * reset.
284 */
285 find_max_pfn();
286 saved_max_pfn = max_pfn;
287#endif
288 e820.nr_map = 0;
289 user_defined_memmap = 1;
290 } else {
291 /* If the user specifies memory size, we
292 * limit the BIOS-provided memory map to
293 * that size. exactmap can be used to specify
294 * the exact map. mem=number can be used to
295 * trim the existing memory map.
296 */
297 unsigned long long start_at, mem_size;
298
299 mem_size = memparse(arg, &arg);
300 if (*arg == '@') {
301 start_at = memparse(arg+1, &arg);
302 add_memory_region(start_at, mem_size, E820_RAM);
303 } else if (*arg == '#') {
304 start_at = memparse(arg+1, &arg);
305 add_memory_region(start_at, mem_size, E820_ACPI);
306 } else if (*arg == '$') {
307 start_at = memparse(arg+1, &arg);
308 add_memory_region(start_at, mem_size, E820_RESERVED);
309 } else {
310 limit_regions(mem_size);
311 user_defined_memmap = 1;
312 }
313 }
314 return 0;
315}
316early_param("memmap", parse_memmap);
317
318#ifdef CONFIG_PROC_VMCORE 199#ifdef CONFIG_PROC_VMCORE
319/* elfcorehdr= specifies the location of elf core header 200/* elfcorehdr= specifies the location of elf core header
320 * stored by the crashed kernel. 201 * stored by the crashed kernel.
@@ -378,38 +259,6 @@ static int __init parse_reservetop(char *arg)
378} 259}
379early_param("reservetop", parse_reservetop); 260early_param("reservetop", parse_reservetop);
380 261
381 /*
382 * This function checks if the entire range <start,end> is mapped with type.
383 *
384 * Note: this function only works correct if the e820 table is sorted and
385 * not-overlapping, which is the case
386 */
387int __init
388e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
389{
390 u64 start = s;
391 u64 end = e;
392 int i;
393 for (i = 0; i < e820.nr_map; i++) {
394 struct e820entry *ei = &e820.map[i];
395 if (type && ei->type != type)
396 continue;
397 /* is the region (part) in overlap with the current region ?*/
398 if (ei->addr >= end || ei->addr + ei->size <= start)
399 continue;
400 /* if the region is at the beginning of <start,end> we move
401 * start to the end of the region since it's ok until there
402 */
403 if (ei->addr <= start)
404 start = ei->addr + ei->size;
405 /* if start is now at or beyond end, we're done, full
406 * coverage */
407 if (start >= end)
408 return 1; /* we're done */
409 }
410 return 0;
411}
412
413/* 262/*
414 * Determine low and high memory ranges: 263 * Determine low and high memory ranges:
415 */ 264 */
diff --git a/include/asm-i386/e820.h b/include/asm-i386/e820.h
index 8da4175a5533..395077aba583 100644
--- a/include/asm-i386/e820.h
+++ b/include/asm-i386/e820.h
@@ -41,6 +41,8 @@ extern int e820_all_mapped(unsigned long start, unsigned long end,
41extern void find_max_pfn(void); 41extern void find_max_pfn(void);
42extern void register_bootmem_low_pages(unsigned long max_low_pfn); 42extern void register_bootmem_low_pages(unsigned long max_low_pfn);
43extern void register_memory(void); 43extern void register_memory(void);
44extern void limit_regions(unsigned long long size);
45extern void print_memory_map(char *who);
44 46
45#endif/*!__ASSEMBLY__*/ 47#endif/*!__ASSEMBLY__*/
46 48