aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/e820.c109
-rw-r--r--arch/x86/kernel/e820_64.c97
-rw-r--r--include/asm-x86/e820.h11
-rw-r--r--include/asm-x86/e820_64.h5
4 files changed, 120 insertions, 102 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index cd2b99e27d43..c140f731743b 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -764,3 +764,112 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
764 return addr; 764 return addr;
765} 765}
766 766
767#ifdef CONFIG_X86_32
768# ifdef CONFIG_X86_PAE
769# define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
770# else
771# define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
772# endif
773#else /* CONFIG_X86_32 */
774# define MAX_ARCH_PFN MAXMEM<<PAGE_SHIFT
775#endif
776
777/*
778 * Last pfn which the user wants to use.
779 */
780unsigned long __initdata end_user_pfn = MAX_ARCH_PFN;
781
782/*
783 * Find the highest page frame number we have available
784 */
785unsigned long __init e820_end_of_ram(void)
786{
787 unsigned long last_pfn;
788 unsigned long max_arch_pfn = MAX_ARCH_PFN;
789
790 last_pfn = find_max_pfn_with_active_regions();
791
792 if (last_pfn > max_arch_pfn)
793 last_pfn = max_arch_pfn;
794 if (last_pfn > end_user_pfn)
795 last_pfn = end_user_pfn;
796
797 printk(KERN_INFO "last_pfn = %lu max_arch_pfn = %lu\n",
798 last_pfn, max_arch_pfn);
799 return last_pfn;
800}
801
802/*
803 * Finds an active region in the address range from start_pfn to last_pfn and
804 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
805 */
806int __init e820_find_active_region(const struct e820entry *ei,
807 unsigned long start_pfn,
808 unsigned long last_pfn,
809 unsigned long *ei_startpfn,
810 unsigned long *ei_endpfn)
811{
812 u64 align = PAGE_SIZE;
813
814 *ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
815 *ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
816
817 /* Skip map entries smaller than a page */
818 if (*ei_startpfn >= *ei_endpfn)
819 return 0;
820
821 /* Skip if map is outside the node */
822 if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
823 *ei_startpfn >= last_pfn)
824 return 0;
825
826 /* Check for overlaps */
827 if (*ei_startpfn < start_pfn)
828 *ei_startpfn = start_pfn;
829 if (*ei_endpfn > last_pfn)
830 *ei_endpfn = last_pfn;
831
832 /* Obey end_user_pfn to save on memmap */
833 if (*ei_startpfn >= end_user_pfn)
834 return 0;
835 if (*ei_endpfn > end_user_pfn)
836 *ei_endpfn = end_user_pfn;
837
838 return 1;
839}
840
841/* Walk the e820 map and register active regions within a node */
842void __init e820_register_active_regions(int nid, unsigned long start_pfn,
843 unsigned long last_pfn)
844{
845 unsigned long ei_startpfn;
846 unsigned long ei_endpfn;
847 int i;
848
849 for (i = 0; i < e820.nr_map; i++)
850 if (e820_find_active_region(&e820.map[i],
851 start_pfn, last_pfn,
852 &ei_startpfn, &ei_endpfn))
853 add_active_range(nid, ei_startpfn, ei_endpfn);
854}
855
856/*
857 * Find the hole size (in bytes) in the memory range.
858 * @start: starting address of the memory range to scan
859 * @end: ending address of the memory range to scan
860 */
861u64 __init e820_hole_size(u64 start, u64 end)
862{
863 unsigned long start_pfn = start >> PAGE_SHIFT;
864 unsigned long last_pfn = end >> PAGE_SHIFT;
865 unsigned long ei_startpfn, ei_endpfn, ram = 0;
866 int i;
867
868 for (i = 0; i < e820.nr_map; i++) {
869 if (e820_find_active_region(&e820.map[i],
870 start_pfn, last_pfn,
871 &ei_startpfn, &ei_endpfn))
872 ram += ei_endpfn - ei_startpfn;
873 }
874 return end - start - ((u64)ram << PAGE_SHIFT);
875}
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index a11bec20f65d..0afee2ca0bf8 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -42,29 +42,6 @@ unsigned long end_pfn;
42unsigned long max_pfn_mapped; 42unsigned long max_pfn_mapped;
43 43
44/* 44/*
45 * Last pfn which the user wants to use.
46 */
47static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
48
49/*
50 * Find the highest page frame number we have available
51 */
52unsigned long __init e820_end_of_ram(void)
53{
54 unsigned long last_pfn;
55
56 last_pfn = find_max_pfn_with_active_regions();
57
58 if (last_pfn > MAXMEM>>PAGE_SHIFT)
59 last_pfn = MAXMEM>>PAGE_SHIFT;
60 if (last_pfn > end_user_pfn)
61 last_pfn = end_user_pfn;
62
63 printk(KERN_INFO "last_pfn = %lu\n", last_pfn);
64 return last_pfn;
65}
66
67/*
68 * Mark e820 reserved areas as busy for the resource manager. 45 * Mark e820 reserved areas as busy for the resource manager.
69 */ 46 */
70void __init e820_reserve_resources(void) 47void __init e820_reserve_resources(void)
@@ -88,80 +65,6 @@ void __init e820_reserve_resources(void)
88 } 65 }
89} 66}
90 67
91/*
92 * Finds an active region in the address range from start_pfn to last_pfn and
93 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
94 */
95static int __init e820_find_active_region(const struct e820entry *ei,
96 unsigned long start_pfn,
97 unsigned long last_pfn,
98 unsigned long *ei_startpfn,
99 unsigned long *ei_endpfn)
100{
101 *ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
102 *ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) >> PAGE_SHIFT;
103
104 /* Skip map entries smaller than a page */
105 if (*ei_startpfn >= *ei_endpfn)
106 return 0;
107
108 /* Skip if map is outside the node */
109 if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
110 *ei_startpfn >= last_pfn)
111 return 0;
112
113 /* Check for overlaps */
114 if (*ei_startpfn < start_pfn)
115 *ei_startpfn = start_pfn;
116 if (*ei_endpfn > last_pfn)
117 *ei_endpfn = last_pfn;
118
119 /* Obey end_user_pfn to save on memmap */
120 if (*ei_startpfn >= end_user_pfn)
121 return 0;
122 if (*ei_endpfn > end_user_pfn)
123 *ei_endpfn = end_user_pfn;
124
125 return 1;
126}
127
128/* Walk the e820 map and register active regions within a node */
129void __init
130e820_register_active_regions(int nid, unsigned long start_pfn,
131 unsigned long last_pfn)
132{
133 unsigned long ei_startpfn;
134 unsigned long ei_endpfn;
135 int i;
136
137 for (i = 0; i < e820.nr_map; i++)
138 if (e820_find_active_region(&e820.map[i],
139 start_pfn, last_pfn,
140 &ei_startpfn, &ei_endpfn))
141 add_active_range(nid, ei_startpfn, ei_endpfn);
142}
143
144/*
145 * Find the hole size (in bytes) in the memory range.
146 * @start: starting address of the memory range to scan
147 * @end: ending address of the memory range to scan
148 */
149unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
150{
151 unsigned long start_pfn = start >> PAGE_SHIFT;
152 unsigned long last_pfn = end >> PAGE_SHIFT;
153 unsigned long ei_startpfn, ei_endpfn, ram = 0;
154 int i;
155
156 for (i = 0; i < e820.nr_map; i++) {
157 if (e820_find_active_region(&e820.map[i],
158 start_pfn, last_pfn,
159 &ei_startpfn, &ei_endpfn))
160 ram += ei_endpfn - ei_startpfn;
161 }
162 return end - start - (ram << PAGE_SHIFT);
163}
164
165static void early_panic(char *msg) 68static void early_panic(char *msg)
166{ 69{
167 early_printk(msg); 70 early_printk(msg);
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
index ee8fe4c5da41..44ed9c0a4dfd 100644
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -79,6 +79,8 @@ static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
79} 79}
80#endif 80#endif
81 81
82extern unsigned long end_user_pfn;
83
82extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); 84extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
83extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); 85extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
84extern void reserve_early(u64 start, u64 end, char *name); 86extern void reserve_early(u64 start, u64 end, char *name);
@@ -86,6 +88,15 @@ extern void free_early(u64 start, u64 end);
86extern void early_res_to_bootmem(u64 start, u64 end); 88extern void early_res_to_bootmem(u64 start, u64 end);
87extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); 89extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
88 90
91extern unsigned long e820_end_of_ram(void);
92extern int e820_find_active_region(const struct e820entry *ei,
93 unsigned long start_pfn,
94 unsigned long last_pfn,
95 unsigned long *ei_startpfn,
96 unsigned long *ei_endpfn);
97extern void e820_register_active_regions(int nid, unsigned long start_pfn,
98 unsigned long end_pfn);
99extern u64 e820_hole_size(u64 start, u64 end);
89#endif /* __ASSEMBLY__ */ 100#endif /* __ASSEMBLY__ */
90 101
91#define ISA_START_ADDRESS 0xa0000 102#define ISA_START_ADDRESS 0xa0000
diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h
index 917963ccab69..368585daaa42 100644
--- a/include/asm-x86/e820_64.h
+++ b/include/asm-x86/e820_64.h
@@ -16,16 +16,11 @@
16#ifndef __ASSEMBLY__ 16#ifndef __ASSEMBLY__
17extern void setup_memory_region(void); 17extern void setup_memory_region(void);
18extern void contig_e820_setup(void); 18extern void contig_e820_setup(void);
19extern unsigned long e820_end_of_ram(void);
20extern void e820_reserve_resources(void); 19extern void e820_reserve_resources(void);
21extern int e820_any_non_reserved(unsigned long start, unsigned long end); 20extern int e820_any_non_reserved(unsigned long start, unsigned long end);
22extern int is_memory_any_valid(unsigned long start, unsigned long end); 21extern int is_memory_any_valid(unsigned long start, unsigned long end);
23extern int e820_all_non_reserved(unsigned long start, unsigned long end); 22extern int e820_all_non_reserved(unsigned long start, unsigned long end);
24extern int is_memory_all_valid(unsigned long start, unsigned long end); 23extern int is_memory_all_valid(unsigned long start, unsigned long end);
25extern unsigned long e820_hole_size(unsigned long start, unsigned long end);
26
27extern void e820_register_active_regions(int nid, unsigned long start_pfn,
28 unsigned long end_pfn);
29 24
30extern void finish_e820_parsing(void); 25extern void finish_e820_parsing(void);
31 26