diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-06-03 22:34:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-04 06:01:57 -0400 |
commit | ee0c80fadfa56bf4f9d90c1c023429a6bd8edd69 (patch) | |
tree | 74139bd2a4437a327fc65a00cafb42549d601670 /arch/x86/kernel/e820.c | |
parent | 84b56fa46b36c2df508e7d421feab514fad30f81 (diff) |
x86: move e820_register_active() to e820.c
to prepare 32-bit to use it.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/e820.c')
-rw-r--r-- | arch/x86/kernel/e820.c | 109 |
1 files changed, 109 insertions, 0 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 | */ | ||
780 | unsigned long __initdata end_user_pfn = MAX_ARCH_PFN; | ||
781 | |||
782 | /* | ||
783 | * Find the highest page frame number we have available | ||
784 | */ | ||
785 | unsigned 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 | */ | ||
806 | int __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 */ | ||
842 | void __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 | */ | ||
861 | u64 __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 | } | ||