diff options
author | Yinghai Lu <yinghai@kernel.org> | 2010-02-10 04:20:16 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-10 20:47:18 -0500 |
commit | 264ebb182e85f30aa473fa2189d5d5ea173ec3ab (patch) | |
tree | ec99673b588988496ae41b5980863d6b32a8140c | |
parent | 1842f90cc98625d4d9bf8f8b927f17705ceb4e9c (diff) |
x86: Introduce max_early_res and early_res_count
To prepare allocate early res array from fine_e820_area.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
LKML-Reference: <1265793639-15071-13-git-send-email-yinghai@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | arch/x86/kernel/e820.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index f406efeb4dc4..7053f4adb8ed 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -732,14 +732,18 @@ core_initcall(e820_mark_nvs_memory); | |||
732 | /* | 732 | /* |
733 | * Early reserved memory areas. | 733 | * Early reserved memory areas. |
734 | */ | 734 | */ |
735 | #define MAX_EARLY_RES 32 | 735 | /* |
736 | * need to make sure this one is bigger enough before | ||
737 | * find_e820_area could be used | ||
738 | */ | ||
739 | #define MAX_EARLY_RES_X 32 | ||
736 | 740 | ||
737 | struct early_res { | 741 | struct early_res { |
738 | u64 start, end; | 742 | u64 start, end; |
739 | char name[16]; | 743 | char name[15]; |
740 | char overlap_ok; | 744 | char overlap_ok; |
741 | }; | 745 | }; |
742 | static struct early_res early_res[MAX_EARLY_RES] __initdata = { | 746 | static struct early_res early_res_x[MAX_EARLY_RES_X] __initdata = { |
743 | { 0, PAGE_SIZE, "BIOS data page", 1 }, /* BIOS data page */ | 747 | { 0, PAGE_SIZE, "BIOS data page", 1 }, /* BIOS data page */ |
744 | #if defined(CONFIG_X86_32) && defined(CONFIG_X86_TRAMPOLINE) | 748 | #if defined(CONFIG_X86_32) && defined(CONFIG_X86_TRAMPOLINE) |
745 | /* | 749 | /* |
@@ -753,12 +757,22 @@ static struct early_res early_res[MAX_EARLY_RES] __initdata = { | |||
753 | {} | 757 | {} |
754 | }; | 758 | }; |
755 | 759 | ||
760 | static int max_early_res __initdata = MAX_EARLY_RES_X; | ||
761 | static struct early_res *early_res __initdata = &early_res_x[0]; | ||
762 | static int early_res_count __initdata = | ||
763 | #ifdef CONFIG_X86_32 | ||
764 | 2 | ||
765 | #else | ||
766 | 1 | ||
767 | #endif | ||
768 | ; | ||
769 | |||
756 | static int __init find_overlapped_early(u64 start, u64 end) | 770 | static int __init find_overlapped_early(u64 start, u64 end) |
757 | { | 771 | { |
758 | int i; | 772 | int i; |
759 | struct early_res *r; | 773 | struct early_res *r; |
760 | 774 | ||
761 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { | 775 | for (i = 0; i < max_early_res && early_res[i].end; i++) { |
762 | r = &early_res[i]; | 776 | r = &early_res[i]; |
763 | if (end > r->start && start < r->end) | 777 | if (end > r->start && start < r->end) |
764 | break; | 778 | break; |
@@ -776,13 +790,14 @@ static void __init drop_range(int i) | |||
776 | { | 790 | { |
777 | int j; | 791 | int j; |
778 | 792 | ||
779 | for (j = i + 1; j < MAX_EARLY_RES && early_res[j].end; j++) | 793 | for (j = i + 1; j < max_early_res && early_res[j].end; j++) |
780 | ; | 794 | ; |
781 | 795 | ||
782 | memmove(&early_res[i], &early_res[i + 1], | 796 | memmove(&early_res[i], &early_res[i + 1], |
783 | (j - 1 - i) * sizeof(struct early_res)); | 797 | (j - 1 - i) * sizeof(struct early_res)); |
784 | 798 | ||
785 | early_res[j - 1].end = 0; | 799 | early_res[j - 1].end = 0; |
800 | early_res_count--; | ||
786 | } | 801 | } |
787 | 802 | ||
788 | /* | 803 | /* |
@@ -801,9 +816,9 @@ static void __init drop_overlaps_that_are_ok(u64 start, u64 end) | |||
801 | struct early_res *r; | 816 | struct early_res *r; |
802 | u64 lower_start, lower_end; | 817 | u64 lower_start, lower_end; |
803 | u64 upper_start, upper_end; | 818 | u64 upper_start, upper_end; |
804 | char name[16]; | 819 | char name[15]; |
805 | 820 | ||
806 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { | 821 | for (i = 0; i < max_early_res && early_res[i].end; i++) { |
807 | r = &early_res[i]; | 822 | r = &early_res[i]; |
808 | 823 | ||
809 | /* Continue past non-overlapping ranges */ | 824 | /* Continue past non-overlapping ranges */ |
@@ -859,7 +874,7 @@ static void __init __reserve_early(u64 start, u64 end, char *name, | |||
859 | struct early_res *r; | 874 | struct early_res *r; |
860 | 875 | ||
861 | i = find_overlapped_early(start, end); | 876 | i = find_overlapped_early(start, end); |
862 | if (i >= MAX_EARLY_RES) | 877 | if (i >= max_early_res) |
863 | panic("Too many early reservations"); | 878 | panic("Too many early reservations"); |
864 | r = &early_res[i]; | 879 | r = &early_res[i]; |
865 | if (r->end) | 880 | if (r->end) |
@@ -872,6 +887,7 @@ static void __init __reserve_early(u64 start, u64 end, char *name, | |||
872 | r->overlap_ok = overlap_ok; | 887 | r->overlap_ok = overlap_ok; |
873 | if (name) | 888 | if (name) |
874 | strncpy(r->name, name, sizeof(r->name) - 1); | 889 | strncpy(r->name, name, sizeof(r->name) - 1); |
890 | early_res_count++; | ||
875 | } | 891 | } |
876 | 892 | ||
877 | /* | 893 | /* |
@@ -924,7 +940,7 @@ void __init free_early(u64 start, u64 end) | |||
924 | 940 | ||
925 | i = find_overlapped_early(start, end); | 941 | i = find_overlapped_early(start, end); |
926 | r = &early_res[i]; | 942 | r = &early_res[i]; |
927 | if (i >= MAX_EARLY_RES || r->end != end || r->start != start) | 943 | if (i >= max_early_res || r->end != end || r->start != start) |
928 | panic("free_early on not reserved area: %llx-%llx!", | 944 | panic("free_early on not reserved area: %llx-%llx!", |
929 | start, end - 1); | 945 | start, end - 1); |
930 | 946 | ||
@@ -935,14 +951,15 @@ void __init early_res_to_bootmem(u64 start, u64 end) | |||
935 | { | 951 | { |
936 | int i, count; | 952 | int i, count; |
937 | u64 final_start, final_end; | 953 | u64 final_start, final_end; |
954 | int idx = 0; | ||
938 | 955 | ||
939 | count = 0; | 956 | count = 0; |
940 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) | 957 | for (i = 0; i < max_early_res && early_res[i].end; i++) |
941 | count++; | 958 | count++; |
942 | 959 | ||
943 | printk(KERN_INFO "(%d early reservations) ==> bootmem [%010llx - %010llx]\n", | 960 | printk(KERN_INFO "(%d/%d early reservations) ==> bootmem [%010llx - %010llx]\n", |
944 | count, start, end); | 961 | count - idx, max_early_res, start, end); |
945 | for (i = 0; i < count; i++) { | 962 | for (i = idx; i < count; i++) { |
946 | struct early_res *r = &early_res[i]; | 963 | struct early_res *r = &early_res[i]; |
947 | printk(KERN_INFO " #%d [%010llx - %010llx] %16s", i, | 964 | printk(KERN_INFO " #%d [%010llx - %010llx] %16s", i, |
948 | r->start, r->end, r->name); | 965 | r->start, r->end, r->name); |
@@ -969,7 +986,7 @@ static inline int __init bad_addr(u64 *addrp, u64 size, u64 align) | |||
969 | again: | 986 | again: |
970 | i = find_overlapped_early(addr, addr + size); | 987 | i = find_overlapped_early(addr, addr + size); |
971 | r = &early_res[i]; | 988 | r = &early_res[i]; |
972 | if (i < MAX_EARLY_RES && r->end) { | 989 | if (i < max_early_res && r->end) { |
973 | *addrp = addr = round_up(r->end, align); | 990 | *addrp = addr = round_up(r->end, align); |
974 | changed = 1; | 991 | changed = 1; |
975 | goto again; | 992 | goto again; |
@@ -986,7 +1003,7 @@ static inline int __init bad_addr_size(u64 *addrp, u64 *sizep, u64 align) | |||
986 | int changed = 0; | 1003 | int changed = 0; |
987 | again: | 1004 | again: |
988 | last = addr + size; | 1005 | last = addr + size; |
989 | for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { | 1006 | for (i = 0; i < max_early_res && early_res[i].end; i++) { |
990 | struct early_res *r = &early_res[i]; | 1007 | struct early_res *r = &early_res[i]; |
991 | if (last > r->start && addr < r->start) { | 1008 | if (last > r->start && addr < r->start) { |
992 | size = r->start - addr; | 1009 | size = r->start - addr; |