aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/e820.c32
-rw-r--r--arch/x86/kernel/e820_32.c192
-rw-r--r--arch/x86/kernel/e820_64.c24
-rw-r--r--arch/x86/kernel/setup_32.c208
-rw-r--r--include/asm-x86/e820.h1
-rw-r--r--include/asm-x86/e820_32.h4
-rw-r--r--include/asm-x86/e820_64.h1
7 files changed, 208 insertions, 254 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 544dd12c70f4..432c49178577 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -998,3 +998,35 @@ void __init finish_e820_parsing(void)
998 e820_print_map("user"); 998 e820_print_map("user");
999 } 999 }
1000} 1000}
1001
1002/*
1003 * Mark e820 reserved areas as busy for the resource manager.
1004 */
1005void __init e820_reserve_resources(void)
1006{
1007 int i;
1008 struct resource *res;
1009
1010 res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
1011 for (i = 0; i < e820.nr_map; i++) {
1012 switch (e820.map[i].type) {
1013 case E820_RAM: res->name = "System RAM"; break;
1014 case E820_ACPI: res->name = "ACPI Tables"; break;
1015 case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
1016 default: res->name = "reserved";
1017 }
1018 res->start = e820.map[i].addr;
1019 res->end = res->start + e820.map[i].size - 1;
1020#ifndef CONFIG_RESOURCES_64BIT
1021 if (res->end > 0x100000000ULL) {
1022 res++;
1023 continue;
1024 }
1025#endif
1026 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
1027 insert_resource(&iomem_resource, res);
1028 res++;
1029 }
1030}
1031
1032
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c
index 8de3df9548db..1205ccf086d7 100644
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -15,198 +15,6 @@
15#include <asm/e820.h> 15#include <asm/e820.h>
16#include <asm/setup.h> 16#include <asm/setup.h>
17 17
18static struct resource system_rom_resource = {
19 .name = "System ROM",
20 .start = 0xf0000,
21 .end = 0xfffff,
22 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
23};
24
25static struct resource extension_rom_resource = {
26 .name = "Extension ROM",
27 .start = 0xe0000,
28 .end = 0xeffff,
29 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
30};
31
32static struct resource adapter_rom_resources[] = { {
33 .name = "Adapter ROM",
34 .start = 0xc8000,
35 .end = 0,
36 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
37}, {
38 .name = "Adapter ROM",
39 .start = 0,
40 .end = 0,
41 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
42}, {
43 .name = "Adapter ROM",
44 .start = 0,
45 .end = 0,
46 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
47}, {
48 .name = "Adapter ROM",
49 .start = 0,
50 .end = 0,
51 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
52}, {
53 .name = "Adapter ROM",
54 .start = 0,
55 .end = 0,
56 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
57}, {
58 .name = "Adapter ROM",
59 .start = 0,
60 .end = 0,
61 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
62} };
63
64static struct resource video_rom_resource = {
65 .name = "Video ROM",
66 .start = 0xc0000,
67 .end = 0xc7fff,
68 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
69};
70
71#define ROMSIGNATURE 0xaa55
72
73static int __init romsignature(const unsigned char *rom)
74{
75 const unsigned short * const ptr = (const unsigned short *)rom;
76 unsigned short sig;
77
78 return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
79}
80
81static int __init romchecksum(const unsigned char *rom, unsigned long length)
82{
83 unsigned char sum, c;
84
85 for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
86 sum += c;
87 return !length && !sum;
88}
89
90static void __init probe_roms(void)
91{
92 const unsigned char *rom;
93 unsigned long start, length, upper;
94 unsigned char c;
95 int i;
96
97 /* video rom */
98 upper = adapter_rom_resources[0].start;
99 for (start = video_rom_resource.start; start < upper; start += 2048) {
100 rom = isa_bus_to_virt(start);
101 if (!romsignature(rom))
102 continue;
103
104 video_rom_resource.start = start;
105
106 if (probe_kernel_address(rom + 2, c) != 0)
107 continue;
108
109 /* 0 < length <= 0x7f * 512, historically */
110 length = c * 512;
111
112 /* if checksum okay, trust length byte */
113 if (length && romchecksum(rom, length))
114 video_rom_resource.end = start + length - 1;
115
116 request_resource(&iomem_resource, &video_rom_resource);
117 break;
118 }
119
120 start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
121 if (start < upper)
122 start = upper;
123
124 /* system rom */
125 request_resource(&iomem_resource, &system_rom_resource);
126 upper = system_rom_resource.start;
127
128 /* check for extension rom (ignore length byte!) */
129 rom = isa_bus_to_virt(extension_rom_resource.start);
130 if (romsignature(rom)) {
131 length = extension_rom_resource.end - extension_rom_resource.start + 1;
132 if (romchecksum(rom, length)) {
133 request_resource(&iomem_resource, &extension_rom_resource);
134 upper = extension_rom_resource.start;
135 }
136 }
137
138 /* check for adapter roms on 2k boundaries */
139 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
140 rom = isa_bus_to_virt(start);
141 if (!romsignature(rom))
142 continue;
143
144 if (probe_kernel_address(rom + 2, c) != 0)
145 continue;
146
147 /* 0 < length <= 0x7f * 512, historically */
148 length = c * 512;
149
150 /* but accept any length that fits if checksum okay */
151 if (!length || start + length > upper || !romchecksum(rom, length))
152 continue;
153
154 adapter_rom_resources[i].start = start;
155 adapter_rom_resources[i].end = start + length - 1;
156 request_resource(&iomem_resource, &adapter_rom_resources[i]);
157
158 start = adapter_rom_resources[i++].end & ~2047UL;
159 }
160}
161
162/*
163 * Request address space for all standard RAM and ROM resources
164 * and also for regions reported as reserved by the e820.
165 */
166void __init init_iomem_resources(struct resource *code_resource,
167 struct resource *data_resource,
168 struct resource *bss_resource)
169{
170 int i;
171
172 probe_roms();
173 for (i = 0; i < e820.nr_map; i++) {
174 struct resource *res;
175#ifndef CONFIG_RESOURCES_64BIT
176 if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
177 continue;
178#endif
179 res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
180 switch (e820.map[i].type) {
181 case E820_RAM: res->name = "System RAM"; break;
182 case E820_ACPI: res->name = "ACPI Tables"; break;
183 case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
184 default: res->name = "reserved";
185 }
186 res->start = e820.map[i].addr;
187 res->end = res->start + e820.map[i].size - 1;
188 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
189 if (request_resource(&iomem_resource, res)) {
190 kfree(res);
191 continue;
192 }
193 if (e820.map[i].type == E820_RAM) {
194 /*
195 * We don't know which RAM region contains kernel data,
196 * so we try it repeatedly and let the resource manager
197 * test it.
198 */
199 request_resource(res, code_resource);
200 request_resource(res, data_resource);
201 request_resource(res, bss_resource);
202#ifdef CONFIG_KEXEC
203 if (crashk_res.start != crashk_res.end)
204 request_resource(res, &crashk_res);
205#endif
206 }
207 }
208}
209
210/* Overridden in paravirt.c if CONFIG_PARAVIRT */ 18/* Overridden in paravirt.c if CONFIG_PARAVIRT */
211char * __init __attribute__((weak)) memory_setup(void) 19char * __init __attribute__((weak)) memory_setup(void)
212{ 20{
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 47952b1690b6..cb03bff9fa2f 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -41,30 +41,6 @@ unsigned long end_pfn;
41 */ 41 */
42unsigned long max_pfn_mapped; 42unsigned long max_pfn_mapped;
43 43
44/*
45 * Mark e820 reserved areas as busy for the resource manager.
46 */
47void __init e820_reserve_resources(void)
48{
49 int i;
50 struct resource *res;
51
52 res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
53 for (i = 0; i < e820.nr_map; i++) {
54 switch (e820.map[i].type) {
55 case E820_RAM: res->name = "System RAM"; break;
56 case E820_ACPI: res->name = "ACPI Tables"; break;
57 case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
58 default: res->name = "reserved";
59 }
60 res->start = e820.map[i].addr;
61 res->end = res->start + e820.map[i].size - 1;
62 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
63 insert_resource(&iomem_resource, res);
64 res++;
65 }
66}
67
68static void early_panic(char *msg) 44static void early_panic(char *msg)
69{ 45{
70 early_printk(msg); 46 early_printk(msg);
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index 72b11d4557b7..f3ddba5ed9a7 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -445,25 +445,28 @@ static void __init reserve_crashkernel(void)
445 ret = parse_crashkernel(boot_command_line, total_mem, 445 ret = parse_crashkernel(boot_command_line, total_mem,
446 &crash_size, &crash_base); 446 &crash_size, &crash_base);
447 if (ret == 0 && crash_size > 0) { 447 if (ret == 0 && crash_size > 0) {
448 if (crash_base > 0) { 448 if (crash_base <= 0) {
449 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
450 "for crashkernel (System RAM: %ldMB)\n",
451 (unsigned long)(crash_size >> 20),
452 (unsigned long)(crash_base >> 20),
453 (unsigned long)(total_mem >> 20));
454
455 if (reserve_bootmem(crash_base, crash_size,
456 BOOTMEM_EXCLUSIVE) < 0) {
457 printk(KERN_INFO "crashkernel reservation "
458 "failed - memory is in use\n");
459 return;
460 }
461
462 crashk_res.start = crash_base;
463 crashk_res.end = crash_base + crash_size - 1;
464 } else
465 printk(KERN_INFO "crashkernel reservation failed - " 449 printk(KERN_INFO "crashkernel reservation failed - "
466 "you have to specify a base address\n"); 450 "you have to specify a base address\n");
451 return;
452 }
453
454 if (reserve_bootmem_generic(crash_base, crash_size,
455 BOOTMEM_EXCLUSIVE) < 0) {
456 printk(KERN_INFO "crashkernel reservation failed - "
457 "memory is in use\n");
458 return;
459 }
460
461 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
462 "for crashkernel (System RAM: %ldMB)\n",
463 (unsigned long)(crash_size >> 20),
464 (unsigned long)(crash_base >> 20),
465 (unsigned long)(total_mem >> 20));
466
467 crashk_res.start = crash_base;
468 crashk_res.end = crash_base + crash_size - 1;
469 insert_resource(&iomem_resource, &crashk_res);
467 } 470 }
468} 471}
469#else 472#else
@@ -675,6 +678,8 @@ int x86_cpu_to_node_map_init[NR_CPUS] = {
675DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; 678DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE;
676#endif 679#endif
677 680
681static void probe_roms(void);
682
678/* 683/*
679 * Determine if we were loaded by an EFI loader. If so, then we have also been 684 * Determine if we were loaded by an EFI loader. If so, then we have also been
680 * passed the efi memmap, systab, etc., so we should use these data structures 685 * passed the efi memmap, systab, etc., so we should use these data structures
@@ -684,6 +689,7 @@ DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE;
684 */ 689 */
685void __init setup_arch(char **cmdline_p) 690void __init setup_arch(char **cmdline_p)
686{ 691{
692 int i;
687 unsigned long max_low_pfn; 693 unsigned long max_low_pfn;
688 694
689 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); 695 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
@@ -745,6 +751,13 @@ void __init setup_arch(char **cmdline_p)
745 751
746 finish_e820_parsing(); 752 finish_e820_parsing();
747 753
754 probe_roms();
755
756 /* after parse_early_param, so could debug it */
757 insert_resource(&iomem_resource, &code_resource);
758 insert_resource(&iomem_resource, &data_resource);
759 insert_resource(&iomem_resource, &bss_resource);
760
748 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); 761 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
749 *cmdline_p = command_line; 762 *cmdline_p = command_line;
750 763
@@ -861,9 +874,16 @@ void __init setup_arch(char **cmdline_p)
861 "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); 874 "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n");
862#endif 875#endif
863 876
864 e820_setup_gap(); 877 e820_reserve_resources();
865 e820_mark_nosave_regions(max_low_pfn); 878 e820_mark_nosave_regions(max_low_pfn);
866 879
880 request_resource(&iomem_resource, &video_ram_resource);
881 /* request I/O space for devices used on all i[345]86 PCs */
882 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
883 request_resource(&ioport_resource, &standard_io_resources[i]);
884
885 e820_setup_gap();
886
867#ifdef CONFIG_VT 887#ifdef CONFIG_VT
868#if defined(CONFIG_VGA_CONSOLE) 888#if defined(CONFIG_VGA_CONSOLE)
869 if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) 889 if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
@@ -874,25 +894,147 @@ void __init setup_arch(char **cmdline_p)
874#endif 894#endif
875} 895}
876 896
877/* 897static struct resource system_rom_resource = {
878 * Request address space for all standard resources 898 .name = "System ROM",
879 * 899 .start = 0xf0000,
880 * This is called just before pcibios_init(), which is also a 900 .end = 0xfffff,
881 * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). 901 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
882 */ 902};
883static int __init request_standard_resources(void) 903
904static struct resource extension_rom_resource = {
905 .name = "Extension ROM",
906 .start = 0xe0000,
907 .end = 0xeffff,
908 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
909};
910
911static struct resource adapter_rom_resources[] = { {
912 .name = "Adapter ROM",
913 .start = 0xc8000,
914 .end = 0,
915 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
916}, {
917 .name = "Adapter ROM",
918 .start = 0,
919 .end = 0,
920 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
921}, {
922 .name = "Adapter ROM",
923 .start = 0,
924 .end = 0,
925 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
926}, {
927 .name = "Adapter ROM",
928 .start = 0,
929 .end = 0,
930 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
931}, {
932 .name = "Adapter ROM",
933 .start = 0,
934 .end = 0,
935 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
936}, {
937 .name = "Adapter ROM",
938 .start = 0,
939 .end = 0,
940 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
941} };
942
943static struct resource video_rom_resource = {
944 .name = "Video ROM",
945 .start = 0xc0000,
946 .end = 0xc7fff,
947 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
948};
949
950#define ROMSIGNATURE 0xaa55
951
952static int __init romsignature(const unsigned char *rom)
953{
954 const unsigned short * const ptr = (const unsigned short *)rom;
955 unsigned short sig;
956
957 return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
958}
959
960static int __init romchecksum(const unsigned char *rom, unsigned long length)
961{
962 unsigned char sum, c;
963
964 for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
965 sum += c;
966 return !length && !sum;
967}
968
969static void __init probe_roms(void)
884{ 970{
971 const unsigned char *rom;
972 unsigned long start, length, upper;
973 unsigned char c;
885 int i; 974 int i;
886 975
887 printk(KERN_INFO "Setting up standard PCI resources\n"); 976 /* video rom */
888 init_iomem_resources(&code_resource, &data_resource, &bss_resource); 977 upper = adapter_rom_resources[0].start;
978 for (start = video_rom_resource.start; start < upper; start += 2048) {
979 rom = isa_bus_to_virt(start);
980 if (!romsignature(rom))
981 continue;
889 982
890 request_resource(&iomem_resource, &video_ram_resource); 983 video_rom_resource.start = start;
891 984
892 /* request I/O space for devices used on all i[345]86 PCs */ 985 if (probe_kernel_address(rom + 2, c) != 0)
893 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) 986 continue;
894 request_resource(&ioport_resource, &standard_io_resources[i]); 987
895 return 0; 988 /* 0 < length <= 0x7f * 512, historically */
989 length = c * 512;
990
991 /* if checksum okay, trust length byte */
992 if (length && romchecksum(rom, length))
993 video_rom_resource.end = start + length - 1;
994
995 request_resource(&iomem_resource, &video_rom_resource);
996 break;
997 }
998
999 start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
1000 if (start < upper)
1001 start = upper;
1002
1003 /* system rom */
1004 request_resource(&iomem_resource, &system_rom_resource);
1005 upper = system_rom_resource.start;
1006
1007 /* check for extension rom (ignore length byte!) */
1008 rom = isa_bus_to_virt(extension_rom_resource.start);
1009 if (romsignature(rom)) {
1010 length = extension_rom_resource.end - extension_rom_resource.start + 1;
1011 if (romchecksum(rom, length)) {
1012 request_resource(&iomem_resource, &extension_rom_resource);
1013 upper = extension_rom_resource.start;
1014 }
1015 }
1016
1017 /* check for adapter roms on 2k boundaries */
1018 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
1019 rom = isa_bus_to_virt(start);
1020 if (!romsignature(rom))
1021 continue;
1022
1023 if (probe_kernel_address(rom + 2, c) != 0)
1024 continue;
1025
1026 /* 0 < length <= 0x7f * 512, historically */
1027 length = c * 512;
1028
1029 /* but accept any length that fits if checksum okay */
1030 if (!length || start + length > upper || !romchecksum(rom, length))
1031 continue;
1032
1033 adapter_rom_resources[i].start = start;
1034 adapter_rom_resources[i].end = start + length - 1;
1035 request_resource(&iomem_resource, &adapter_rom_resources[i]);
1036
1037 start = adapter_rom_resources[i++].end & ~2047UL;
1038 }
896} 1039}
897 1040
898subsys_initcall(request_standard_resources);
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
index 77fc24d89163..e860fe758e79 100644
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -100,6 +100,7 @@ extern void e820_register_active_regions(int nid, unsigned long start_pfn,
100 unsigned long end_pfn); 100 unsigned long end_pfn);
101extern u64 e820_hole_size(u64 start, u64 end); 101extern u64 e820_hole_size(u64 start, u64 end);
102extern void finish_e820_parsing(void); 102extern void finish_e820_parsing(void);
103extern void e820_reserve_resources(void);
103 104
104#endif /* __ASSEMBLY__ */ 105#endif /* __ASSEMBLY__ */
105 106
diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h
index 9135ce6e617e..557b890549ff 100644
--- a/include/asm-x86/e820_32.h
+++ b/include/asm-x86/e820_32.h
@@ -20,9 +20,5 @@
20 20
21extern void setup_memory_map(void); 21extern void setup_memory_map(void);
22 22
23extern void init_iomem_resources(struct resource *code_resource,
24 struct resource *data_resource,
25 struct resource *bss_resource);
26
27#endif/*!__ASSEMBLY__*/ 23#endif/*!__ASSEMBLY__*/
28#endif/*__E820_HEADER*/ 24#endif/*__E820_HEADER*/
diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h
index 478547c63222..8d992109969b 100644
--- a/include/asm-x86/e820_64.h
+++ b/include/asm-x86/e820_64.h
@@ -16,7 +16,6 @@
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 void e820_reserve_resources(void);
20extern int e820_any_non_reserved(unsigned long start, unsigned long end); 19extern int e820_any_non_reserved(unsigned long start, unsigned long end);
21extern int is_memory_any_valid(unsigned long start, unsigned long end); 20extern int is_memory_any_valid(unsigned long start, unsigned long end);
22extern int e820_all_non_reserved(unsigned long start, unsigned long end); 21extern int e820_all_non_reserved(unsigned long start, unsigned long end);