aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/probe_roms_32.c166
-rw-r--r--arch/x86/kernel/setup_32.c146
-rw-r--r--include/asm-x86/setup.h1
4 files changed, 168 insertions, 146 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 9a71be827927..9c9ce75e3ae4 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -19,6 +19,7 @@ obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
19obj-y += traps_$(BITS).o irq_$(BITS).o 19obj-y += traps_$(BITS).o irq_$(BITS).o
20obj-y += time_$(BITS).o ioport.o ldt.o 20obj-y += time_$(BITS).o ioport.o ldt.o
21obj-y += setup_$(BITS).o i8259.o irqinit_$(BITS).o setup.o 21obj-y += setup_$(BITS).o i8259.o irqinit_$(BITS).o setup.o
22obj-$(CONFIG_X86_32) += probe_roms_32.o
22obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o 23obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
23obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o 24obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
24obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o 25obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o
diff --git a/arch/x86/kernel/probe_roms_32.c b/arch/x86/kernel/probe_roms_32.c
new file mode 100644
index 000000000000..675a48c404a5
--- /dev/null
+++ b/arch/x86/kernel/probe_roms_32.c
@@ -0,0 +1,166 @@
1#include <linux/sched.h>
2#include <linux/mm.h>
3#include <linux/uaccess.h>
4#include <linux/mmzone.h>
5#include <linux/ioport.h>
6#include <linux/seq_file.h>
7#include <linux/console.h>
8#include <linux/init.h>
9#include <linux/edd.h>
10#include <linux/dmi.h>
11#include <linux/pfn.h>
12#include <linux/pci.h>
13#include <asm/pci-direct.h>
14
15
16#include <asm/e820.h>
17#include <asm/mmzone.h>
18#include <asm/setup.h>
19#include <asm/sections.h>
20#include <asm/io.h>
21#include <setup_arch.h>
22
23static struct resource system_rom_resource = {
24 .name = "System ROM",
25 .start = 0xf0000,
26 .end = 0xfffff,
27 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
28};
29
30static struct resource extension_rom_resource = {
31 .name = "Extension ROM",
32 .start = 0xe0000,
33 .end = 0xeffff,
34 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
35};
36
37static struct resource adapter_rom_resources[] = { {
38 .name = "Adapter ROM",
39 .start = 0xc8000,
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 .name = "Adapter ROM",
64 .start = 0,
65 .end = 0,
66 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
67} };
68
69static struct resource video_rom_resource = {
70 .name = "Video ROM",
71 .start = 0xc0000,
72 .end = 0xc7fff,
73 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
74};
75
76#define ROMSIGNATURE 0xaa55
77
78static int __init romsignature(const unsigned char *rom)
79{
80 const unsigned short * const ptr = (const unsigned short *)rom;
81 unsigned short sig;
82
83 return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
84}
85
86static int __init romchecksum(const unsigned char *rom, unsigned long length)
87{
88 unsigned char sum, c;
89
90 for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
91 sum += c;
92 return !length && !sum;
93}
94
95void __init probe_roms(void)
96{
97 const unsigned char *rom;
98 unsigned long start, length, upper;
99 unsigned char c;
100 int i;
101
102 /* video rom */
103 upper = adapter_rom_resources[0].start;
104 for (start = video_rom_resource.start; start < upper; start += 2048) {
105 rom = isa_bus_to_virt(start);
106 if (!romsignature(rom))
107 continue;
108
109 video_rom_resource.start = start;
110
111 if (probe_kernel_address(rom + 2, c) != 0)
112 continue;
113
114 /* 0 < length <= 0x7f * 512, historically */
115 length = c * 512;
116
117 /* if checksum okay, trust length byte */
118 if (length && romchecksum(rom, length))
119 video_rom_resource.end = start + length - 1;
120
121 request_resource(&iomem_resource, &video_rom_resource);
122 break;
123 }
124
125 start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
126 if (start < upper)
127 start = upper;
128
129 /* system rom */
130 request_resource(&iomem_resource, &system_rom_resource);
131 upper = system_rom_resource.start;
132
133 /* check for extension rom (ignore length byte!) */
134 rom = isa_bus_to_virt(extension_rom_resource.start);
135 if (romsignature(rom)) {
136 length = extension_rom_resource.end - extension_rom_resource.start + 1;
137 if (romchecksum(rom, length)) {
138 request_resource(&iomem_resource, &extension_rom_resource);
139 upper = extension_rom_resource.start;
140 }
141 }
142
143 /* check for adapter roms on 2k boundaries */
144 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
145 rom = isa_bus_to_virt(start);
146 if (!romsignature(rom))
147 continue;
148
149 if (probe_kernel_address(rom + 2, c) != 0)
150 continue;
151
152 /* 0 < length <= 0x7f * 512, historically */
153 length = c * 512;
154
155 /* but accept any length that fits if checksum okay */
156 if (!length || start + length > upper || !romchecksum(rom, length))
157 continue;
158
159 adapter_rom_resources[i].start = start;
160 adapter_rom_resources[i].end = start + length - 1;
161 request_resource(&iomem_resource, &adapter_rom_resources[i]);
162
163 start = adapter_rom_resources[i++].end & ~2047UL;
164 }
165}
166
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index e274ee6ff582..865838b11792 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -606,8 +606,6 @@ static void set_mca_bus(int x)
606static void set_mca_bus(int x) { } 606static void set_mca_bus(int x) { }
607#endif 607#endif
608 608
609static void probe_roms(void);
610
611/* 609/*
612 * Determine if we were loaded by an EFI loader. If so, then we have also been 610 * Determine if we were loaded by an EFI loader. If so, then we have also been
613 * passed the efi memmap, systab, etc., so we should use these data structures 611 * passed the efi memmap, systab, etc., so we should use these data structures
@@ -843,147 +841,3 @@ void __init setup_arch(char **cmdline_p)
843#endif 841#endif
844} 842}
845 843
846static struct resource system_rom_resource = {
847 .name = "System ROM",
848 .start = 0xf0000,
849 .end = 0xfffff,
850 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
851};
852
853static struct resource extension_rom_resource = {
854 .name = "Extension ROM",
855 .start = 0xe0000,
856 .end = 0xeffff,
857 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
858};
859
860static struct resource adapter_rom_resources[] = { {
861 .name = "Adapter ROM",
862 .start = 0xc8000,
863 .end = 0,
864 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
865}, {
866 .name = "Adapter ROM",
867 .start = 0,
868 .end = 0,
869 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
870}, {
871 .name = "Adapter ROM",
872 .start = 0,
873 .end = 0,
874 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
875}, {
876 .name = "Adapter ROM",
877 .start = 0,
878 .end = 0,
879 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
880}, {
881 .name = "Adapter ROM",
882 .start = 0,
883 .end = 0,
884 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
885}, {
886 .name = "Adapter ROM",
887 .start = 0,
888 .end = 0,
889 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
890} };
891
892static struct resource video_rom_resource = {
893 .name = "Video ROM",
894 .start = 0xc0000,
895 .end = 0xc7fff,
896 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
897};
898
899#define ROMSIGNATURE 0xaa55
900
901static int __init romsignature(const unsigned char *rom)
902{
903 const unsigned short * const ptr = (const unsigned short *)rom;
904 unsigned short sig;
905
906 return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
907}
908
909static int __init romchecksum(const unsigned char *rom, unsigned long length)
910{
911 unsigned char sum, c;
912
913 for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
914 sum += c;
915 return !length && !sum;
916}
917
918static void __init probe_roms(void)
919{
920 const unsigned char *rom;
921 unsigned long start, length, upper;
922 unsigned char c;
923 int i;
924
925 /* video rom */
926 upper = adapter_rom_resources[0].start;
927 for (start = video_rom_resource.start; start < upper; start += 2048) {
928 rom = isa_bus_to_virt(start);
929 if (!romsignature(rom))
930 continue;
931
932 video_rom_resource.start = start;
933
934 if (probe_kernel_address(rom + 2, c) != 0)
935 continue;
936
937 /* 0 < length <= 0x7f * 512, historically */
938 length = c * 512;
939
940 /* if checksum okay, trust length byte */
941 if (length && romchecksum(rom, length))
942 video_rom_resource.end = start + length - 1;
943
944 request_resource(&iomem_resource, &video_rom_resource);
945 break;
946 }
947
948 start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
949 if (start < upper)
950 start = upper;
951
952 /* system rom */
953 request_resource(&iomem_resource, &system_rom_resource);
954 upper = system_rom_resource.start;
955
956 /* check for extension rom (ignore length byte!) */
957 rom = isa_bus_to_virt(extension_rom_resource.start);
958 if (romsignature(rom)) {
959 length = extension_rom_resource.end - extension_rom_resource.start + 1;
960 if (romchecksum(rom, length)) {
961 request_resource(&iomem_resource, &extension_rom_resource);
962 upper = extension_rom_resource.start;
963 }
964 }
965
966 /* check for adapter roms on 2k boundaries */
967 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
968 rom = isa_bus_to_virt(start);
969 if (!romsignature(rom))
970 continue;
971
972 if (probe_kernel_address(rom + 2, c) != 0)
973 continue;
974
975 /* 0 < length <= 0x7f * 512, historically */
976 length = c * 512;
977
978 /* but accept any length that fits if checksum okay */
979 if (!length || start + length > upper || !romchecksum(rom, length))
980 continue;
981
982 adapter_rom_resources[i].start = start;
983 adapter_rom_resources[i].end = start + length - 1;
984 request_resource(&iomem_resource, &adapter_rom_resources[i]);
985
986 start = adapter_rom_resources[i++].end & ~2047UL;
987 }
988}
989
diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h
index b434bdd82ba7..cf87d6d3675c 100644
--- a/include/asm-x86/setup.h
+++ b/include/asm-x86/setup.h
@@ -54,6 +54,7 @@ extern struct boot_params boot_params;
54#ifdef __i386__ 54#ifdef __i386__
55 55
56void __init i386_start_kernel(void); 56void __init i386_start_kernel(void);
57extern void probe_roms(void);
57 58
58extern unsigned long init_pg_tables_start; 59extern unsigned long init_pg_tables_start;
59extern unsigned long init_pg_tables_end; 60extern unsigned long init_pg_tables_end;