e820.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include <linux/kernel.h>
  2. #include <linux/types.h>
  3. #include <linux/init.h>
  4. #include <linux/bootmem.h>
  5. #include <linux/ioport.h>
  6. #include <linux/string.h>
  7. #include <linux/kexec.h>
  8. #include <linux/module.h>
  9. #include <linux/mm.h>
  10. #include <linux/efi.h>
  11. #include <asm/pgtable.h>
  12. #include <asm/page.h>
  13. #include <asm/e820.h>
  14. #ifdef CONFIG_EFI
  15. int efi_enabled = 0;
  16. EXPORT_SYMBOL(efi_enabled);
  17. #endif
  18. struct e820map e820;
  19. struct resource data_resource = {
  20. .name = "Kernel data",
  21. .start = 0,
  22. .end = 0,
  23. .flags = IORESOURCE_BUSY | IORESOURCE_MEM
  24. };
  25. struct resource code_resource = {
  26. .name = "Kernel code",
  27. .start = 0,
  28. .end = 0,
  29. .flags = IORESOURCE_BUSY | IORESOURCE_MEM
  30. };
  31. static struct resource system_rom_resource = {
  32. .name = "System ROM",
  33. .start = 0xf0000,
  34. .end = 0xfffff,
  35. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  36. };
  37. static struct resource extension_rom_resource = {
  38. .name = "Extension ROM",
  39. .start = 0xe0000,
  40. .end = 0xeffff,
  41. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  42. };
  43. static struct resource adapter_rom_resources[] = { {
  44. .name = "Adapter ROM",
  45. .start = 0xc8000,
  46. .end = 0,
  47. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  48. }, {
  49. .name = "Adapter ROM",
  50. .start = 0,
  51. .end = 0,
  52. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  53. }, {
  54. .name = "Adapter ROM",
  55. .start = 0,
  56. .end = 0,
  57. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  58. }, {
  59. .name = "Adapter ROM",
  60. .start = 0,
  61. .end = 0,
  62. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  63. }, {
  64. .name = "Adapter ROM",
  65. .start = 0,
  66. .end = 0,
  67. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  68. }, {
  69. .name = "Adapter ROM",
  70. .start = 0,
  71. .end = 0,
  72. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  73. } };
  74. static struct resource video_rom_resource = {
  75. .name = "Video ROM",
  76. .start = 0xc0000,
  77. .end = 0xc7fff,
  78. .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  79. };
  80. static struct resource video_ram_resource = {
  81. .name = "Video RAM area",
  82. .start = 0xa0000,
  83. .end = 0xbffff,
  84. .flags = IORESOURCE_BUSY | IORESOURCE_MEM
  85. };
  86. static struct resource standard_io_resources[] = { {
  87. .name = "dma1",
  88. .start = 0x0000,
  89. .end = 0x001f,
  90. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  91. }, {
  92. .name = "pic1",
  93. .start = 0x0020,
  94. .end = 0x0021,
  95. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  96. }, {
  97. .name = "timer0",
  98. .start = 0x0040,
  99. .end = 0x0043,
  100. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  101. }, {
  102. .name = "timer1",
  103. .start = 0x0050,
  104. .end = 0x0053,
  105. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  106. }, {
  107. .name = "keyboard",
  108. .start = 0x0060,
  109. .end = 0x006f,
  110. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  111. }, {
  112. .name = "dma page reg",
  113. .start = 0x0080,
  114. .end = 0x008f,
  115. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  116. }, {
  117. .name = "pic2",
  118. .start = 0x00a0,
  119. .end = 0x00a1,
  120. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  121. }, {
  122. .name = "dma2",
  123. .start = 0x00c0,
  124. .end = 0x00df,
  125. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  126. }, {
  127. .name = "fpu",
  128. .start = 0x00f0,
  129. .end = 0x00ff,
  130. .flags = IORESOURCE_BUSY | IORESOURCE_IO
  131. } };
  132. #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
  133. static int __init romchecksum(unsigned char *rom, unsigned long length)
  134. {
  135. unsigned char *p, sum = 0;
  136. for (p = rom; p < rom + length; p++)
  137. sum += *p;
  138. return sum == 0;
  139. }
  140. static void __init probe_roms(void)
  141. {
  142. unsigned long start, length, upper;
  143. unsigned char *rom;
  144. int i;
  145. /* video rom */
  146. upper = adapter_rom_resources[0].start;
  147. for (start = video_rom_resource.start; start < upper; start += 2048) {
  148. rom = isa_bus_to_virt(start);
  149. if (!romsignature(rom))
  150. continue;
  151. video_rom_resource.start = start;
  152. /* 0 < length <= 0x7f * 512, historically */
  153. length = rom[2] * 512;
  154. /* if checksum okay, trust length byte */
  155. if (length && romchecksum(rom, length))
  156. video_rom_resource.end = start + length - 1;
  157. request_resource(&iomem_resource, &video_rom_resource);
  158. break;
  159. }
  160. start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
  161. if (start < upper)
  162. start = upper;
  163. /* system rom */
  164. request_resource(&iomem_resource, &system_rom_resource);
  165. upper = system_rom_resource.start;
  166. /* check for extension rom (ignore length byte!) */
  167. rom = isa_bus_to_virt(extension_rom_resource.start);
  168. if (romsignature(rom)) {
  169. length = extension_rom_resource.end - extension_rom_resource.start + 1;
  170. if (romchecksum(rom, length)) {
  171. request_resource(&iomem_resource, &extension_rom_resource);
  172. upper = extension_rom_resource.start;
  173. }
  174. }
  175. /* check for adapter roms on 2k boundaries */
  176. for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
  177. rom = isa_bus_to_virt(start);
  178. if (!romsignature(rom))
  179. continue;
  180. /* 0 < length <= 0x7f * 512, historically */
  181. length = rom[2] * 512;
  182. /* but accept any length that fits if checksum okay */
  183. if (!length || start + length > upper || !romchecksum(rom, length))
  184. continue;
  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. start = adapter_rom_resources[i++].end & ~2047UL;
  189. }
  190. }
  191. /*
  192. * Request address space for all standard RAM and ROM resources
  193. * and also for regions reported as reserved by the e820.
  194. */
  195. static void __init
  196. legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
  197. {
  198. int i;
  199. probe_roms();
  200. for (i = 0; i < e820.nr_map; i++) {
  201. struct resource *res;
  202. #ifndef CONFIG_RESOURCES_64BIT
  203. if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
  204. continue;
  205. #endif
  206. res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
  207. switch (e820.map[i].type) {
  208. case E820_RAM: res->name = "System RAM"; break;
  209. case E820_ACPI: res->name = "ACPI Tables"; break;
  210. case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
  211. default: res->name = "reserved";
  212. }
  213. res->start = e820.map[i].addr;
  214. res->end = res->start + e820.map[i].size - 1;
  215. res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  216. if (request_resource(&iomem_resource, res)) {
  217. kfree(res);
  218. continue;
  219. }
  220. if (e820.map[i].type == E820_RAM) {
  221. /*
  222. * We don't know which RAM region contains kernel data,
  223. * so we try it repeatedly and let the resource manager
  224. * test it.
  225. */
  226. request_resource(res, code_resource);
  227. request_resource(res, data_resource);
  228. #ifdef CONFIG_KEXEC
  229. request_resource(res, &crashk_res);
  230. #endif
  231. }
  232. }
  233. }
  234. /*
  235. * Request address space for all standard resources
  236. *
  237. * This is called just before pcibios_init(), which is also a
  238. * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
  239. */
  240. static int __init request_standard_resources(void)
  241. {
  242. int i;
  243. printk("Setting up standard PCI resources\n");
  244. if (efi_enabled)
  245. efi_initialize_iomem_resources(&code_resource, &data_resource);
  246. else
  247. legacy_init_iomem_resources(&code_resource, &data_resource);
  248. /* EFI systems may still have VGA */
  249. request_resource(&iomem_resource, &video_ram_resource);
  250. /* request I/O space for devices used on all i[345]86 PCs */
  251. for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
  252. request_resource(&ioport_resource, &standard_io_resources[i]);
  253. return 0;
  254. }
  255. subsys_initcall(request_standard_resources);