#include <asm/setup.h>
#include <asm/efi.h>
#include <asm/time.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
#define EFI_DEBUG 1
#define PFX "EFI: "
struct efi efi_phys __initdata;
static efi_system_table_t efi_systab __initdata;
+static int __init setup_noefi(char *arg)
+{
+ efi_enabled = 0;
+ return 0;
+}
+early_param("noefi", setup_noefi);
+
static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
{
return efi_call_virt2(get_time, tm, tc);
memmap.desc_version = boot_params.efi_info.efi_memdesc_version;
memmap.desc_size = boot_params.efi_info.efi_memdesc_size;
- efi.systab = efi_early_ioremap((unsigned long)efi_phys.systab,
- sizeof(efi_system_table_t));
+ efi.systab = early_ioremap((unsigned long)efi_phys.systab,
+ sizeof(efi_system_table_t));
if (efi.systab == NULL)
printk(KERN_ERR "Couldn't map the EFI system table!\n");
memcpy(&efi_systab, efi.systab, sizeof(efi_system_table_t));
- efi_early_iounmap(efi.systab, sizeof(efi_system_table_t));
+ early_iounmap(efi.systab, sizeof(efi_system_table_t));
efi.systab = &efi_systab;
/*
/*
* Show what we know for posterity
*/
- c16 = tmp = efi_early_ioremap(efi.systab->fw_vendor, 2);
+ c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2);
if (c16) {
for (i = 0; i < sizeof(vendor) && *c16; ++i)
vendor[i] = *c16++;
vendor[i] = '\0';
} else
printk(KERN_ERR PFX "Could not map the firmware vendor!\n");
- efi_early_iounmap(tmp, 2);
+ early_iounmap(tmp, 2);
printk(KERN_INFO "EFI v%u.%.02u by %s \n",
efi.systab->hdr.revision >> 16,
/*
* Let's see what config tables the firmware passed to us.
*/
- config_tables = efi_early_ioremap(
+ config_tables = early_ioremap(
efi.systab->tables,
efi.systab->nr_tables * sizeof(efi_config_table_t));
if (config_tables == NULL)
}
}
printk("\n");
- efi_early_iounmap(config_tables,
+ early_iounmap(config_tables,
efi.systab->nr_tables * sizeof(efi_config_table_t));
/*
* address of several of the EFI runtime functions, needed to
* set the firmware into virtual mode.
*/
- runtime = efi_early_ioremap((unsigned long)efi.systab->runtime,
- sizeof(efi_runtime_services_t));
+ runtime = early_ioremap((unsigned long)efi.systab->runtime,
+ sizeof(efi_runtime_services_t));
if (runtime != NULL) {
/*
* We will only need *early* access to the following
} else
printk(KERN_ERR "Could not map the EFI runtime service "
"table!\n");
- efi_early_iounmap(runtime, sizeof(efi_runtime_services_t));
+ early_iounmap(runtime, sizeof(efi_runtime_services_t));
/* Map the EFI memory map */
- memmap.map = efi_early_ioremap((unsigned long)memmap.phys_map,
- memmap.nr_map * memmap.desc_size);
+ memmap.map = early_ioremap((unsigned long)memmap.phys_map,
+ memmap.nr_map * memmap.desc_size);
if (memmap.map == NULL)
printk(KERN_ERR "Could not map the EFI memory map!\n");
memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
printk(KERN_WARNING "Kernel-defined memdesc"
"doesn't match the one from EFI!\n");
-#ifdef CONFIG_X86_64
/* Setup for EFI runtime service */
reboot_type = BOOT_EFI;
-#endif
#if EFI_DEBUG
print_efi_memmap();
#endif
}
+static void __init runtime_code_page_mkexec(void)
+{
+ efi_memory_desc_t *md;
+ void *p;
+
+ /* Make EFI runtime service code area executable */
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+ md = p;
+
+ if (md->type != EFI_RUNTIME_SERVICES_CODE)
+ continue;
+
+ set_memory_x(md->virt_addr, md->num_pages << EFI_PAGE_SHIFT);
+ }
+}
+
/*
* This function will switch the EFI runtime services to virtual mode.
* Essentially, look through the EFI memmap and map every region that
{
efi_memory_desc_t *md;
efi_status_t status;
- unsigned long end;
- void *p;
+ unsigned long size;
+ u64 end, systab;
+ void *p, *va;
efi.systab = NULL;
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
md = p;
if (!(md->attribute & EFI_MEMORY_RUNTIME))
continue;
- if ((md->attribute & EFI_MEMORY_WB) &&
- (((md->phys_addr + (md->num_pages<<EFI_PAGE_SHIFT)) >>
- PAGE_SHIFT) < end_pfn_map))
- md->virt_addr = (unsigned long)__va(md->phys_addr);
+
+ size = md->num_pages << EFI_PAGE_SHIFT;
+ end = md->phys_addr + size;
+
+ if ((end >> PAGE_SHIFT) <= max_pfn_mapped)
+ va = __va(md->phys_addr);
else
- md->virt_addr = (unsigned long)
- efi_ioremap(md->phys_addr,
- md->num_pages << EFI_PAGE_SHIFT);
- if (!md->virt_addr)
+ va = efi_ioremap(md->phys_addr, size);
+
+ md->virt_addr = (u64) (unsigned long) va;
+
+ if (!va) {
printk(KERN_ERR PFX "ioremap of 0x%llX failed!\n",
(unsigned long long)md->phys_addr);
- end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
- if ((md->phys_addr <= (unsigned long)efi_phys.systab) &&
- ((unsigned long)efi_phys.systab < end))
- efi.systab = (efi_system_table_t *)(unsigned long)
- (md->virt_addr - md->phys_addr +
- (unsigned long)efi_phys.systab);
+ continue;
+ }
+
+ if (!(md->attribute & EFI_MEMORY_WB))
+ set_memory_uc(md->virt_addr, size);
+
+ systab = (u64) (unsigned long) efi_phys.systab;
+ if (md->phys_addr <= systab && systab < end) {
+ systab += md->virt_addr - md->phys_addr;
+ efi.systab = (efi_system_table_t *) (unsigned long) systab;
+ }
}
BUG_ON(!efi.systab);
efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
efi.reset_system = virt_efi_reset_system;
efi.set_virtual_address_map = virt_efi_set_virtual_address_map;
-#ifdef CONFIG_X86_64
- runtime_code_page_mkexec();
-#endif
+ if (__supported_pte_mask & _PAGE_NX)
+ runtime_code_page_mkexec();
+ early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
+ memmap.map = NULL;
}
/*