ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / i386 / kernel / std_resources.c
1 /*
2  *  Machine specific resource allocation for generic.
3  */
4
5 #include <linux/ioport.h>
6 #include <asm/io.h>
7 #include <asm/std_resources.h>
8
9 #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
10
11 static struct resource system_rom_resource = {
12         .name   = "System ROM",
13         .start  = 0xf0000,
14         .end    = 0xfffff,
15         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
16 };
17
18 static struct resource extension_rom_resource = {
19         .name   = "Extension ROM",
20         .start  = 0xe0000,
21         .end    = 0xeffff,
22         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
23 };
24
25 static struct resource adapter_rom_resources[] = { {
26         .name   = "Adapter ROM",
27         .start  = 0xc8000,
28         .end    = 0,
29         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
30 }, {
31         .name   = "Adapter ROM",
32         .start  = 0,
33         .end    = 0,
34         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
35 }, {
36         .name   = "Adapter ROM",
37         .start  = 0,
38         .end    = 0,
39         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
40 }, {
41         .name   = "Adapter ROM",
42         .start  = 0,
43         .end    = 0,
44         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
45 }, {
46         .name   = "Adapter ROM",
47         .start  = 0,
48         .end    = 0,
49         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
50 }, {
51         .name   = "Adapter ROM",
52         .start  = 0,
53         .end    = 0,
54         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
55 } };
56
57 #define ADAPTER_ROM_RESOURCES \
58         (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
59
60 static struct resource video_rom_resource = {
61         .name   = "Video ROM",
62         .start  = 0xc0000,
63         .end    = 0xc7fff,
64         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
65 };
66
67 static struct resource vram_resource = {
68         .name   = "Video RAM area",
69         .start  = 0xa0000,
70         .end    = 0xbffff,
71         .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
72 };
73
74 static struct resource standard_io_resources[] = { {
75         .name   = "dma1",
76         .start  = 0x0000,
77         .end    = 0x001f,
78         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
79 }, {
80         .name   = "pic1",
81         .start  = 0x0020,
82         .end    = 0x0021,
83         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
84 }, {
85         .name   = "timer",
86         .start  = 0x0040,
87         .end    = 0x005f,
88         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
89 }, {
90         .name   = "keyboard",
91         .start  = 0x0060,
92         .end    = 0x006f,
93         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
94 }, {
95         .name   = "dma page reg",
96         .start  = 0x0080,
97         .end    = 0x008f,
98         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
99 }, {
100         .name   = "pic2",
101         .start  = 0x00a0,
102         .end    = 0x00a1,
103         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
104 }, {
105         .name   = "dma2",
106         .start  = 0x00c0,
107         .end    = 0x00df,
108         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
109 }, {
110         .name   = "fpu",
111         .start  = 0x00f0,
112         .end    = 0x00ff,
113         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
114 } };
115
116 #define STANDARD_IO_RESOURCES \
117         (sizeof standard_io_resources / sizeof standard_io_resources[0])
118
119 static int __init checksum(unsigned char *rom, unsigned long length)
120 {
121         unsigned char *p, sum = 0;
122
123         for (p = rom; p < rom + length; p++)
124                 sum += *p;
125         return sum == 0;
126 }
127
128 void __init probe_roms(void)
129 {
130         unsigned long start, length, upper;
131         unsigned char *rom;
132         int           i;
133
134         /* video rom */
135         upper = adapter_rom_resources[0].start;
136         for (start = video_rom_resource.start; start < upper; start += 2048) {
137                 rom = isa_bus_to_virt(start);
138                 if (!romsignature(rom))
139                         continue;
140
141                 video_rom_resource.start = start;
142
143                 /* 0 < length <= 0x7f * 512, historically */
144                 length = rom[2] * 512;
145
146                 /* if checksum okay, trust length byte */
147                 if (length && checksum(rom, length))
148                         video_rom_resource.end = start + length - 1;
149
150                 request_resource(&iomem_resource, &video_rom_resource);
151                 break;
152         }
153
154         start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
155         if (start < upper)
156                 start = upper;
157
158         /* system rom */
159         request_resource(&iomem_resource, &system_rom_resource);
160         upper = system_rom_resource.start;
161
162         /* check for extension rom (ignore length byte!) */
163         rom = isa_bus_to_virt(extension_rom_resource.start);
164         if (romsignature(rom)) {
165                 length = extension_rom_resource.end - extension_rom_resource.start + 1;
166                 if (checksum(rom, length)) {
167                         request_resource(&iomem_resource, &extension_rom_resource);
168                         upper = extension_rom_resource.start;
169                 }
170         }
171
172         /* check for adapter roms on 2k boundaries */
173         for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
174                 rom = isa_bus_to_virt(start);
175                 if (!romsignature(rom))
176                         continue;
177
178                 /* 0 < length <= 0x7f * 512, historically */
179                 length = rom[2] * 512;
180
181                 /* but accept any length that fits if checksum okay */
182                 if (!length || start + length > upper || !checksum(rom, length))
183                         continue;
184
185                 adapter_rom_resources[i].start = start;
186                 adapter_rom_resources[i].end = start + length - 1;
187                 request_resource(&iomem_resource, &adapter_rom_resources[i]);
188
189                 start = adapter_rom_resources[i++].end & ~2047UL;
190         }
191 }
192
193 void __init request_graphics_resource(void)
194 {
195         request_resource(&iomem_resource, &vram_resource);
196 }
197
198 void __init request_standard_io_resources(void)
199 {
200         int i;
201
202         for (i = 0; i < STANDARD_IO_RESOURCES; i++)
203                 request_resource(&ioport_resource, &standard_io_resources[i]);
204 }