|
@@ -70,11 +70,15 @@ EXPORT_SYMBOL(efi);
|
|
|
struct efi_memory_map memmap;
|
|
|
|
|
|
bool efi_64bit;
|
|
|
-static bool efi_native;
|
|
|
|
|
|
static struct efi efi_phys __initdata;
|
|
|
static efi_system_table_t efi_systab __initdata;
|
|
|
|
|
|
+static inline bool efi_is_native(void)
|
|
|
+{
|
|
|
+ return IS_ENABLED(CONFIG_X86_64) == efi_64bit;
|
|
|
+}
|
|
|
+
|
|
|
static int __init setup_noefi(char *arg)
|
|
|
{
|
|
|
efi_enabled = 0;
|
|
@@ -420,7 +424,7 @@ void __init efi_reserve_boot_services(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void __init efi_unmap_memmap(void)
|
|
|
+void __init efi_unmap_memmap(void)
|
|
|
{
|
|
|
if (memmap.map) {
|
|
|
early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
|
|
@@ -432,7 +436,7 @@ void __init efi_free_boot_services(void)
|
|
|
{
|
|
|
void *p;
|
|
|
|
|
|
- if (!efi_native)
|
|
|
+ if (!efi_is_native())
|
|
|
return;
|
|
|
|
|
|
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
@@ -684,12 +688,10 @@ void __init efi_init(void)
|
|
|
return;
|
|
|
}
|
|
|
efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
|
|
|
- efi_native = !efi_64bit;
|
|
|
#else
|
|
|
efi_phys.systab = (efi_system_table_t *)
|
|
|
(boot_params.efi_info.efi_systab |
|
|
|
((__u64)boot_params.efi_info.efi_systab_hi<<32));
|
|
|
- efi_native = efi_64bit;
|
|
|
#endif
|
|
|
|
|
|
if (efi_systab_init(efi_phys.systab)) {
|
|
@@ -723,7 +725,7 @@ void __init efi_init(void)
|
|
|
* that doesn't match the kernel 32/64-bit mode.
|
|
|
*/
|
|
|
|
|
|
- if (!efi_native)
|
|
|
+ if (!efi_is_native())
|
|
|
pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
|
|
|
else if (efi_runtime_init()) {
|
|
|
efi_enabled = 0;
|
|
@@ -735,7 +737,7 @@ void __init efi_init(void)
|
|
|
return;
|
|
|
}
|
|
|
#ifdef CONFIG_X86_32
|
|
|
- if (efi_native) {
|
|
|
+ if (efi_is_native()) {
|
|
|
x86_platform.get_wallclock = efi_get_time;
|
|
|
x86_platform.set_wallclock = efi_set_rtc_mmss;
|
|
|
}
|
|
@@ -810,6 +812,16 @@ void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+void efi_memory_uc(u64 addr, unsigned long size)
|
|
|
+{
|
|
|
+ unsigned long page_shift = 1UL << EFI_PAGE_SHIFT;
|
|
|
+ u64 npages;
|
|
|
+
|
|
|
+ npages = round_up(size, page_shift) / page_shift;
|
|
|
+ memrange_efi_to_native(&addr, &npages);
|
|
|
+ set_memory_uc(addr, npages);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This function will switch the EFI runtime services to virtual mode.
|
|
|
* Essentially, look through the EFI memmap and map every region that
|
|
@@ -823,7 +835,7 @@ void __init efi_enter_virtual_mode(void)
|
|
|
efi_memory_desc_t *md, *prev_md = NULL;
|
|
|
efi_status_t status;
|
|
|
unsigned long size;
|
|
|
- u64 end, systab, addr, npages, end_pfn;
|
|
|
+ u64 end, systab, end_pfn;
|
|
|
void *p, *va, *new_memmap = NULL;
|
|
|
int count = 0;
|
|
|
|
|
@@ -834,7 +846,7 @@ void __init efi_enter_virtual_mode(void)
|
|
|
* non-native EFI
|
|
|
*/
|
|
|
|
|
|
- if (!efi_native) {
|
|
|
+ if (!efi_is_native()) {
|
|
|
efi_unmap_memmap();
|
|
|
return;
|
|
|
}
|
|
@@ -879,10 +891,14 @@ void __init efi_enter_virtual_mode(void)
|
|
|
end_pfn = PFN_UP(end);
|
|
|
if (end_pfn <= max_low_pfn_mapped
|
|
|
|| (end_pfn > (1UL << (32 - PAGE_SHIFT))
|
|
|
- && end_pfn <= max_pfn_mapped))
|
|
|
+ && end_pfn <= max_pfn_mapped)) {
|
|
|
va = __va(md->phys_addr);
|
|
|
- else
|
|
|
- va = efi_ioremap(md->phys_addr, size, md->type);
|
|
|
+
|
|
|
+ if (!(md->attribute & EFI_MEMORY_WB))
|
|
|
+ efi_memory_uc((u64)(unsigned long)va, size);
|
|
|
+ } else
|
|
|
+ va = efi_ioremap(md->phys_addr, size,
|
|
|
+ md->type, md->attribute);
|
|
|
|
|
|
md->virt_addr = (u64) (unsigned long) va;
|
|
|
|
|
@@ -892,13 +908,6 @@ void __init efi_enter_virtual_mode(void)
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- if (!(md->attribute & EFI_MEMORY_WB)) {
|
|
|
- addr = md->virt_addr;
|
|
|
- npages = md->num_pages;
|
|
|
- memrange_efi_to_native(&addr, &npages);
|
|
|
- set_memory_uc(addr, npages);
|
|
|
- }
|
|
|
-
|
|
|
systab = (u64) (unsigned long) efi_phys.systab;
|
|
|
if (md->phys_addr <= systab && systab < end) {
|
|
|
systab += md->virt_addr - md->phys_addr;
|