efi.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:14k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Extensible Firmware Interface
  3.  *
  4.  * Based on Extensible Firmware Interface Specification version 0.9 April 30, 1999
  5.  *
  6.  * Copyright (C) 1999 VA Linux Systems
  7.  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  8.  * Copyright (C) 1999-2001 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/config.h>
  22. #include <linux/kernel.h>
  23. #include <linux/init.h>
  24. #include <linux/types.h>
  25. #include <linux/time.h>
  26. #include <linux/proc_fs.h>
  27. #include <asm/efi.h>
  28. #include <asm/io.h>
  29. #include <asm/kregs.h>
  30. #include <asm/pgtable.h>
  31. #include <asm/processor.h>
  32. #define EFI_DEBUG 0
  33. extern efi_status_t efi_call_phys (void *, ...);
  34. struct efi efi;
  35. static efi_runtime_services_t *runtime;
  36. /*
  37.  * efi_dir is allocated here, but the directory isn't created
  38.  * here, as proc_mkdir() doesn't work this early in the bootup
  39.  * process.  Therefore, each module, like efivars, must test for
  40.  *    if (!efi_dir)  efi_dir = proc_mkdir("efi", NULL);
  41.  * prior to creating their own entries under /proc/efi.
  42.  */
  43. #ifdef CONFIG_PROC_FS
  44. struct proc_dir_entry *efi_dir = NULL;
  45. #endif
  46. static unsigned long mem_limit = ~0UL;
  47. static efi_status_t
  48. phys_get_time (efi_time_t *tm, efi_time_cap_t *tc)
  49. {
  50. return efi_call_phys(__va(runtime->get_time), __pa(tm), __pa(tc));
  51. }
  52. static efi_status_t
  53. phys_set_time (efi_time_t *tm)
  54. {
  55. return efi_call_phys(__va(runtime->set_time), __pa(tm));
  56. }
  57. static efi_status_t
  58. phys_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
  59. {
  60. return efi_call_phys(__va(runtime->get_wakeup_time), __pa(enabled), __pa(pending),
  61.      __pa(tm));
  62. }
  63. static efi_status_t
  64. phys_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
  65. {
  66. return efi_call_phys(__va(runtime->set_wakeup_time), enabled, __pa(tm));
  67. }
  68. static efi_status_t
  69. phys_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
  70.    unsigned long *data_size, void *data)
  71. {
  72. return efi_call_phys(__va(runtime->get_variable), __pa(name), __pa(vendor), __pa(attr),
  73.      __pa(data_size), __pa(data));
  74. }
  75. static efi_status_t
  76. phys_get_next_variable (unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor)
  77. {
  78. return efi_call_phys(__va(runtime->get_next_variable), __pa(name_size), __pa(name),
  79.      __pa(vendor));
  80. }
  81. static efi_status_t
  82. phys_set_variable (efi_char16_t *name, efi_guid_t *vendor, u32 attr,
  83.    unsigned long data_size, void *data)
  84. {
  85. return efi_call_phys(__va(runtime->set_variable), __pa(name), __pa(vendor), attr,
  86.      data_size, __pa(data));
  87. }
  88. static efi_status_t
  89. phys_get_next_high_mono_count (u64 *count)
  90. {
  91. return efi_call_phys(__va(runtime->get_next_high_mono_count), __pa(count));
  92. }
  93. static void
  94. phys_reset_system (int reset_type, efi_status_t status,
  95.    unsigned long data_size, efi_char16_t *data)
  96. {
  97. efi_call_phys(__va(runtime->reset_system), status, data_size, __pa(data));
  98. }
  99. void
  100. efi_gettimeofday (struct timeval *tv)
  101. {
  102. efi_time_t tm;
  103. memset(tv, 0, sizeof(tv));
  104. if ((*efi.get_time)(&tm, 0) != EFI_SUCCESS)
  105. return;
  106. tv->tv_sec = mktime(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
  107. tv->tv_usec = tm.nanosecond / 1000;
  108. }
  109. /*
  110.  * Walks the EFI memory map and calls CALLBACK once for each EFI
  111.  * memory descriptor that has memory that is available for OS use.
  112.  */
  113. void
  114. efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
  115. {
  116. int prev_valid = 0;
  117. struct range {
  118. u64 start;
  119. u64 end;
  120. } prev, curr;
  121. void *efi_map_start, *efi_map_end, *p;
  122. efi_memory_desc_t *md;
  123. u64 efi_desc_size, start, end;
  124. efi_map_start = __va(ia64_boot_param->efi_memmap);
  125. efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
  126. efi_desc_size = ia64_boot_param->efi_memdesc_size;
  127. for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
  128. md = p;
  129. switch (md->type) {
  130.       case EFI_LOADER_CODE:
  131.       case EFI_LOADER_DATA:
  132.       case EFI_BOOT_SERVICES_CODE:
  133.       case EFI_BOOT_SERVICES_DATA:
  134.       case EFI_CONVENTIONAL_MEMORY:
  135. if (!(md->attribute & EFI_MEMORY_WB))
  136. continue;
  137. if (md->phys_addr + (md->num_pages << 12) > mem_limit) {
  138. if (md->phys_addr > mem_limit)
  139. continue;
  140. md->num_pages = (mem_limit - md->phys_addr) >> 12;
  141. }
  142. if (md->num_pages == 0) {
  143. printk("efi_memmap_walk: ignoring empty region at 0x%lx",
  144.        md->phys_addr);
  145. continue;
  146. }
  147. curr.start = PAGE_OFFSET + md->phys_addr;
  148. curr.end   = curr.start + (md->num_pages << 12);
  149. if (!prev_valid) {
  150. prev = curr;
  151. prev_valid = 1;
  152. } else {
  153. if (curr.start < prev.start)
  154. printk("Oops: EFI memory table not ordered!n");
  155. if (prev.end == curr.start) {
  156. /* merge two consecutive memory ranges */
  157. prev.end = curr.end;
  158. } else {
  159. start = PAGE_ALIGN(prev.start);
  160. end = prev.end & PAGE_MASK;
  161. if ((end > start) && (*callback)(start, end, arg) < 0)
  162. return;
  163. prev = curr;
  164. }
  165. }
  166. break;
  167.       default:
  168. continue;
  169. }
  170. }
  171. if (prev_valid) {
  172. start = PAGE_ALIGN(prev.start);
  173. end = prev.end & PAGE_MASK;
  174. if (end > start)
  175. (*callback)(start, end, arg);
  176. }
  177. }
  178. /*
  179.  * Look for the PAL_CODE region reported by EFI and maps it using an
  180.  * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
  181.  * Abstraction Layer chapter 11 in ADAG
  182.  */
  183. void
  184. efi_map_pal_code (void)
  185. {
  186. void *efi_map_start, *efi_map_end, *p;
  187. efi_memory_desc_t *md;
  188. u64 efi_desc_size;
  189. int pal_code_count=0;
  190. u64 mask, flags;
  191. u64 vaddr;
  192. efi_map_start = __va(ia64_boot_param->efi_memmap);
  193. efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
  194. efi_desc_size = ia64_boot_param->efi_memdesc_size;
  195. for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
  196. md = p;
  197. if (md->type != EFI_PAL_CODE)
  198. continue;
  199. if (++pal_code_count > 1) {
  200. printk(KERN_ERR "Too many EFI Pal Code memory ranges, dropped @ %lxn",
  201.        md->phys_addr);
  202. continue;
  203. }
  204. /*
  205.  * The only ITLB entry in region 7 that is used is the one installed by
  206.  * __start().  That entry covers a 64MB range.
  207.  */
  208. mask  = ~((1 << KERNEL_TR_PAGE_SHIFT) - 1);
  209. vaddr = PAGE_OFFSET + md->phys_addr;
  210. /*
  211.  * We must check that the PAL mapping won't overlap with the kernel
  212.  * mapping.
  213.  *
  214.  * PAL code is guaranteed to be aligned on a power of 2 between 4k and
  215.  * 256KB and that only one ITR is needed to map it. This implies that the
  216.  * PAL code is always aligned on its size, i.e., the closest matching page
  217.  * size supported by the TLB. Therefore PAL code is guaranteed never to
  218.  * cross a 64MB unless it is bigger than 64MB (very unlikely!).  So for
  219.  * now the following test is enough to determine whether or not we need a
  220.  * dedicated ITR for the PAL code.
  221.  */
  222. if ((vaddr & mask) == (KERNEL_START & mask)) {
  223. printk(__FUNCTION__ ": no need to install ITR for PAL coden");
  224. continue;
  225. }
  226. if (md->num_pages << 12 > IA64_GRANULE_SIZE)
  227. panic("Woah!  PAL code size bigger than a granule!");
  228. mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
  229. printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)n",
  230.        smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << 12),
  231.        vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
  232. /*
  233.  * Cannot write to CRx with PSR.ic=1
  234.  */
  235. ia64_clear_ic(flags);
  236. ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask,
  237.  pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)), IA64_GRANULE_SHIFT);
  238. local_irq_restore(flags);
  239. ia64_srlz_i();
  240. }
  241. }
  242. void __init
  243. efi_init (void)
  244. {
  245. void *efi_map_start, *efi_map_end;
  246. efi_config_table_t *config_tables;
  247. efi_char16_t *c16;
  248. u64 efi_desc_size;
  249. char *cp, *end, vendor[100] = "unknown";
  250. extern char saved_command_line[];
  251. int i;
  252. /* it's too early to be able to use the standard kernel command line support... */
  253. for (cp = saved_command_line; *cp; ) {
  254. if (memcmp(cp, "mem=", 4) == 0) {
  255. cp += 4;
  256. mem_limit = memparse(cp, &end) - 1;
  257. if (end != cp)
  258. break;
  259. cp = end;
  260. } else {
  261. while (*cp != ' ' && *cp)
  262. ++cp;
  263. while (*cp == ' ')
  264. ++cp;
  265. }
  266. }
  267. if (mem_limit != ~0UL)
  268. printk("Ignoring memory above %luMBn", mem_limit >> 20);
  269. efi.systab = __va(ia64_boot_param->efi_systab);
  270. /*
  271.  * Verify the EFI Table
  272.  */
  273. if (efi.systab == NULL)
  274. panic("Woah! Can't find EFI system table.n");
  275. if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
  276. panic("Woah! EFI system table signature incorrectn");
  277. if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
  278. printk("Warning: EFI system table major version mismatch: "
  279.        "got %d.%02d, expected %d.%02dn",
  280.        efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
  281.        EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
  282. config_tables = __va(efi.systab->tables);
  283. /* Show what we know for posterity */
  284. c16 = __va(efi.systab->fw_vendor);
  285. if (c16) {
  286. for (i = 0;i < sizeof(vendor) && *c16; ++i)
  287. vendor[i] = *c16++;
  288. vendor[i] = '';
  289. }
  290. printk("EFI v%u.%.02u by %s:",
  291.        efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor);
  292. for (i = 0; i < efi.systab->nr_tables; i++) {
  293. if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
  294. efi.mps = __va(config_tables[i].table);
  295. printk(" MPS=0x%lx", config_tables[i].table);
  296. } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {
  297. efi.acpi20 = __va(config_tables[i].table);
  298. printk(" ACPI 2.0=0x%lx", config_tables[i].table);
  299. } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {
  300. efi.acpi = __va(config_tables[i].table);
  301. printk(" ACPI=0x%lx", config_tables[i].table);
  302. } else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {
  303. efi.smbios = __va(config_tables[i].table);
  304. printk(" SMBIOS=0x%lx", config_tables[i].table);
  305. } else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {
  306. efi.sal_systab = __va(config_tables[i].table);
  307. printk(" SALsystab=0x%lx", config_tables[i].table);
  308. }
  309. }
  310. printk("n");
  311. runtime = __va(efi.systab->runtime);
  312. efi.get_time = phys_get_time;
  313. efi.set_time = phys_set_time;
  314. efi.get_wakeup_time = phys_get_wakeup_time;
  315. efi.set_wakeup_time = phys_set_wakeup_time;
  316. efi.get_variable = phys_get_variable;
  317. efi.get_next_variable = phys_get_next_variable;
  318. efi.set_variable = phys_set_variable;
  319. efi.get_next_high_mono_count = phys_get_next_high_mono_count;
  320. efi.reset_system = phys_reset_system;
  321. efi_map_start = __va(ia64_boot_param->efi_memmap);
  322. efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
  323. efi_desc_size = ia64_boot_param->efi_memdesc_size;
  324. #if EFI_DEBUG
  325. /* print EFI memory map: */
  326. {
  327. efi_memory_desc_t *md;
  328. void *p;
  329. for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
  330. md = p;
  331. printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)n",
  332.        i, md->type, md->attribute, md->phys_addr,
  333.        md->phys_addr + (md->num_pages<<12) - 1, md->num_pages >> 8);
  334. }
  335. }
  336. #endif
  337. efi_map_pal_code();
  338. efi_enter_virtual_mode();
  339. }
  340. void
  341. efi_enter_virtual_mode (void)
  342. {
  343. void *efi_map_start, *efi_map_end, *p;
  344. efi_memory_desc_t *md;
  345. efi_status_t status;
  346. u64 efi_desc_size;
  347. efi_map_start = __va(ia64_boot_param->efi_memmap);
  348. efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
  349. efi_desc_size = ia64_boot_param->efi_memdesc_size;
  350. for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
  351. md = p;
  352. if (md->attribute & EFI_MEMORY_RUNTIME) {
  353. /*
  354.  * Some descriptors have multiple bits set, so the order of
  355.  * the tests is relevant.
  356.  */
  357. if (md->attribute & EFI_MEMORY_WB) {
  358. md->virt_addr = (u64) __va(md->phys_addr);
  359. } else if (md->attribute & EFI_MEMORY_UC) {
  360. md->virt_addr = (u64) ioremap(md->phys_addr, 0);
  361. } else if (md->attribute & EFI_MEMORY_WC) {
  362. #if 0
  363. md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P
  364.    | _PAGE_D
  365.    | _PAGE_MA_WC
  366.    | _PAGE_PL_0
  367.    | _PAGE_AR_RW));
  368. #else
  369. printk("EFI_MEMORY_WC mappingn");
  370. md->virt_addr = (u64) ioremap(md->phys_addr, 0);
  371. #endif
  372. } else if (md->attribute & EFI_MEMORY_WT) {
  373. #if 0
  374. md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P
  375.    | _PAGE_D | _PAGE_MA_WT
  376.    | _PAGE_PL_0
  377.    | _PAGE_AR_RW));
  378. #else
  379. printk("EFI_MEMORY_WT mappingn");
  380. md->virt_addr = (u64) ioremap(md->phys_addr, 0);
  381. #endif
  382. }
  383. }
  384. }
  385. status = efi_call_phys(__va(runtime->set_virtual_address_map),
  386.        ia64_boot_param->efi_memmap_size,
  387.        efi_desc_size, ia64_boot_param->efi_memdesc_version,
  388.        ia64_boot_param->efi_memmap);
  389. if (status != EFI_SUCCESS) {
  390. printk("Warning: unable to switch EFI into virtual mode (status=%lu)n", status);
  391. return;
  392. }
  393. /*
  394.  * Now that EFI is in virtual mode, we arrange for EFI functions to be
  395.  * called directly:
  396.  */
  397. efi.get_time = __va(runtime->get_time);
  398. efi.set_time = __va(runtime->set_time);
  399. efi.get_wakeup_time = __va(runtime->get_wakeup_time);
  400. efi.set_wakeup_time = __va(runtime->set_wakeup_time);
  401. efi.get_variable = __va(runtime->get_variable);
  402. efi.get_next_variable = __va(runtime->get_next_variable);
  403. efi.set_variable = __va(runtime->set_variable);
  404. efi.get_next_high_mono_count = __va(runtime->get_next_high_mono_count);
  405. efi.reset_system = __va(runtime->reset_system);
  406. }
  407. /*
  408.  * Walk the EFI memory map looking for the I/O port range.  There can only be one entry of
  409.  * this type, other I/O port ranges should be described via ACPI.
  410.  */
  411. u64
  412. efi_get_iobase (void)
  413. {
  414. void *efi_map_start, *efi_map_end, *p;
  415. efi_memory_desc_t *md;
  416. u64 efi_desc_size;
  417. efi_map_start = __va(ia64_boot_param->efi_memmap);
  418. efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
  419. efi_desc_size = ia64_boot_param->efi_memdesc_size;
  420. for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
  421. md = p;
  422. if (md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
  423. /* paranoia attribute checking */
  424. if (md->attribute == (EFI_MEMORY_UC | EFI_MEMORY_RUNTIME))
  425. return md->phys_addr;
  426. }
  427. }
  428. return 0;
  429. }
  430. static void __exit
  431. efivars_exit(void)
  432. {
  433. #ifdef CONFIG_PROC_FS
  434.   remove_proc_entry(efi_dir->name, NULL);
  435. #endif
  436. }