efi_32.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Extensible Firmware Interface
  3. *
  4. * Based on Extensible Firmware Interface Specification version 1.0
  5. *
  6. * Copyright (C) 1999 VA Linux Systems
  7. * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  8. * Copyright (C) 1999-2002 Hewlett-Packard Co.
  9. * David Mosberger-Tang <davidm@hpl.hp.com>
  10. * Stephane Eranian <eranian@hpl.hp.com>
  11. *
  12. * All EFI Runtime Services are not implemented yet as EFI only
  13. * supports physical mode addressing on SoftSDV. This is to be fixed
  14. * in a future version. --drummond 1999-07-20
  15. *
  16. * Implemented EFI runtime services and virtual mode calls. --davidm
  17. *
  18. * Goutham Rao: <goutham.rao@intel.com>
  19. * Skip non-WB memory and ignore empty memory ranges.
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/init.h>
  23. #include <linux/mm.h>
  24. #include <linux/types.h>
  25. #include <linux/time.h>
  26. #include <linux/spinlock.h>
  27. #include <linux/bootmem.h>
  28. #include <linux/ioport.h>
  29. #include <linux/module.h>
  30. #include <linux/efi.h>
  31. #include <linux/kexec.h>
  32. #include <asm/setup.h>
  33. #include <asm/io.h>
  34. #include <asm/page.h>
  35. #include <asm/pgtable.h>
  36. #include <asm/processor.h>
  37. #include <asm/desc.h>
  38. #include <asm/tlbflush.h>
  39. #define PFX "EFI: "
  40. /*
  41. * To make EFI call EFI runtime service in physical addressing mode we need
  42. * prelog/epilog before/after the invocation to disable interrupt, to
  43. * claim EFI runtime service handler exclusively and to duplicate a memory in
  44. * low memory space say 0 - 3G.
  45. */
  46. static unsigned long efi_rt_eflags;
  47. static DEFINE_SPINLOCK(efi_rt_lock);
  48. static pgd_t efi_bak_pg_dir_pointer[2];
  49. void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
  50. {
  51. unsigned long cr4;
  52. unsigned long temp;
  53. struct desc_ptr gdt_descr;
  54. spin_lock(&efi_rt_lock);
  55. local_irq_save(efi_rt_eflags);
  56. /*
  57. * If I don't have PSE, I should just duplicate two entries in page
  58. * directory. If I have PSE, I just need to duplicate one entry in
  59. * page directory.
  60. */
  61. cr4 = read_cr4();
  62. if (cr4 & X86_CR4_PSE) {
  63. efi_bak_pg_dir_pointer[0].pgd =
  64. swapper_pg_dir[pgd_index(0)].pgd;
  65. swapper_pg_dir[0].pgd =
  66. swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
  67. } else {
  68. efi_bak_pg_dir_pointer[0].pgd =
  69. swapper_pg_dir[pgd_index(0)].pgd;
  70. efi_bak_pg_dir_pointer[1].pgd =
  71. swapper_pg_dir[pgd_index(0x400000)].pgd;
  72. swapper_pg_dir[pgd_index(0)].pgd =
  73. swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
  74. temp = PAGE_OFFSET + 0x400000;
  75. swapper_pg_dir[pgd_index(0x400000)].pgd =
  76. swapper_pg_dir[pgd_index(temp)].pgd;
  77. }
  78. /*
  79. * After the lock is released, the original page table is restored.
  80. */
  81. local_flush_tlb();
  82. gdt_descr.address = __pa(get_cpu_gdt_table(0));
  83. gdt_descr.size = GDT_SIZE - 1;
  84. load_gdt(&gdt_descr);
  85. }
  86. void efi_call_phys_epilog(void) __releases(efi_rt_lock)
  87. {
  88. unsigned long cr4;
  89. struct desc_ptr gdt_descr;
  90. gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
  91. gdt_descr.size = GDT_SIZE - 1;
  92. load_gdt(&gdt_descr);
  93. cr4 = read_cr4();
  94. if (cr4 & X86_CR4_PSE) {
  95. swapper_pg_dir[pgd_index(0)].pgd =
  96. efi_bak_pg_dir_pointer[0].pgd;
  97. } else {
  98. swapper_pg_dir[pgd_index(0)].pgd =
  99. efi_bak_pg_dir_pointer[0].pgd;
  100. swapper_pg_dir[pgd_index(0x400000)].pgd =
  101. efi_bak_pg_dir_pointer[1].pgd;
  102. }
  103. /*
  104. * After the lock is released, the original page table is restored.
  105. */
  106. local_flush_tlb();
  107. local_irq_restore(efi_rt_eflags);
  108. spin_unlock(&efi_rt_lock);
  109. }
  110. int is_available_memory(efi_memory_desc_t * md)
  111. {
  112. if (!(md->attribute & EFI_MEMORY_WB))
  113. return 0;
  114. switch (md->type) {
  115. case EFI_LOADER_CODE:
  116. case EFI_LOADER_DATA:
  117. case EFI_BOOT_SERVICES_CODE:
  118. case EFI_BOOT_SERVICES_DATA:
  119. case EFI_CONVENTIONAL_MEMORY:
  120. return 1;
  121. }
  122. return 0;
  123. }
  124. /*
  125. * We need to map the EFI memory map again after paging_init().
  126. */
  127. void __init efi_map_memmap(void)
  128. {
  129. memmap.map = NULL;
  130. memmap.map = bt_ioremap((unsigned long) memmap.phys_map,
  131. (memmap.nr_map * memmap.desc_size));
  132. if (memmap.map == NULL)
  133. printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
  134. memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
  135. }
  136. /*
  137. * Walks the EFI memory map and calls CALLBACK once for each EFI
  138. * memory descriptor that has memory that is available for kernel use.
  139. */
  140. void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
  141. {
  142. int prev_valid = 0;
  143. struct range {
  144. unsigned long start;
  145. unsigned long end;
  146. } uninitialized_var(prev), curr;
  147. efi_memory_desc_t *md;
  148. unsigned long start, end;
  149. void *p;
  150. for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
  151. md = p;
  152. if ((md->num_pages == 0) || (!is_available_memory(md)))
  153. continue;
  154. curr.start = md->phys_addr;
  155. curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
  156. if (!prev_valid) {
  157. prev = curr;
  158. prev_valid = 1;
  159. } else {
  160. if (curr.start < prev.start)
  161. printk(KERN_INFO PFX "Unordered memory map\n");
  162. if (prev.end == curr.start)
  163. prev.end = curr.end;
  164. else {
  165. start =
  166. (unsigned long) (PAGE_ALIGN(prev.start));
  167. end = (unsigned long) (prev.end & PAGE_MASK);
  168. if ((end > start)
  169. && (*callback) (start, end, arg) < 0)
  170. return;
  171. prev = curr;
  172. }
  173. }
  174. }
  175. if (prev_valid) {
  176. start = (unsigned long) PAGE_ALIGN(prev.start);
  177. end = (unsigned long) (prev.end & PAGE_MASK);
  178. if (end > start)
  179. (*callback) (start, end, arg);
  180. }
  181. }
  182. void __init
  183. efi_initialize_iomem_resources(struct resource *code_resource,
  184. struct resource *data_resource,
  185. struct resource *bss_resource)
  186. {
  187. struct resource *res;
  188. efi_memory_desc_t *md;
  189. void *p;
  190. for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
  191. md = p;
  192. if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
  193. 0x100000000ULL)
  194. continue;
  195. res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
  196. switch (md->type) {
  197. case EFI_RESERVED_TYPE:
  198. res->name = "Reserved Memory";
  199. break;
  200. case EFI_LOADER_CODE:
  201. res->name = "Loader Code";
  202. break;
  203. case EFI_LOADER_DATA:
  204. res->name = "Loader Data";
  205. break;
  206. case EFI_BOOT_SERVICES_DATA:
  207. res->name = "BootServices Data";
  208. break;
  209. case EFI_BOOT_SERVICES_CODE:
  210. res->name = "BootServices Code";
  211. break;
  212. case EFI_RUNTIME_SERVICES_CODE:
  213. res->name = "Runtime Service Code";
  214. break;
  215. case EFI_RUNTIME_SERVICES_DATA:
  216. res->name = "Runtime Service Data";
  217. break;
  218. case EFI_CONVENTIONAL_MEMORY:
  219. res->name = "Conventional Memory";
  220. break;
  221. case EFI_UNUSABLE_MEMORY:
  222. res->name = "Unusable Memory";
  223. break;
  224. case EFI_ACPI_RECLAIM_MEMORY:
  225. res->name = "ACPI Reclaim";
  226. break;
  227. case EFI_ACPI_MEMORY_NVS:
  228. res->name = "ACPI NVS";
  229. break;
  230. case EFI_MEMORY_MAPPED_IO:
  231. res->name = "Memory Mapped IO";
  232. break;
  233. case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
  234. res->name = "Memory Mapped IO Port Space";
  235. break;
  236. default:
  237. res->name = "Reserved";
  238. break;
  239. }
  240. res->start = md->phys_addr;
  241. res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1);
  242. res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  243. if (request_resource(&iomem_resource, res) < 0)
  244. printk(KERN_ERR PFX "Failed to allocate res %s : "
  245. "0x%llx-0x%llx\n", res->name,
  246. (unsigned long long)res->start,
  247. (unsigned long long)res->end);
  248. /*
  249. * We don't know which region contains kernel data so we try
  250. * it repeatedly and let the resource manager test it.
  251. */
  252. if (md->type == EFI_CONVENTIONAL_MEMORY) {
  253. request_resource(res, code_resource);
  254. request_resource(res, data_resource);
  255. request_resource(res, bss_resource);
  256. #ifdef CONFIG_KEXEC
  257. request_resource(res, &crashk_res);
  258. #endif
  259. }
  260. }
  261. }