1 // SPDX-License-Identifier: GPL-2.0
3 * Extensible Firmware Interface
5 * Based on Extensible Firmware Interface Specification version 1.0
7 * Copyright (C) 1999 VA Linux Systems
8 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
9 * Copyright (C) 1999-2002 Hewlett-Packard Co.
10 * David Mosberger-Tang <davidm@hpl.hp.com>
11 * Stephane Eranian <eranian@hpl.hp.com>
13 * All EFI Runtime Services are not implemented yet as EFI only
14 * supports physical mode addressing on SoftSDV. This is to be fixed
15 * in a future version. --drummond 1999-07-20
17 * Implemented EFI runtime services and virtual mode calls. --davidm
19 * Goutham Rao: <goutham.rao@intel.com>
20 * Skip non-WB memory and ignore empty memory ranges.
23 #include <linux/kernel.h>
24 #include <linux/types.h>
25 #include <linux/ioport.h>
26 #include <linux/efi.h>
27 #include <linux/pgtable.h>
32 #include <asm/set_memory.h>
33 #include <asm/tlbflush.h>
36 void __init
efi_map_region(efi_memory_desc_t
*md
)
38 u64 start_pfn
, end_pfn
, end
;
42 start_pfn
= PFN_DOWN(md
->phys_addr
);
43 size
= md
->num_pages
<< PAGE_SHIFT
;
44 end
= md
->phys_addr
+ size
;
45 end_pfn
= PFN_UP(end
);
47 if (pfn_range_is_mapped(start_pfn
, end_pfn
)) {
48 va
= __va(md
->phys_addr
);
50 if (!(md
->attribute
& EFI_MEMORY_WB
))
51 set_memory_uc((unsigned long)va
, md
->num_pages
);
53 va
= ioremap_cache(md
->phys_addr
, size
);
56 md
->virt_addr
= (unsigned long)va
;
58 pr_err("ioremap of 0x%llX failed!\n", md
->phys_addr
);
62 * To make EFI call EFI runtime service in physical addressing mode we need
63 * prolog/epilog before/after the invocation to claim the EFI runtime service
64 * handler exclusively and to duplicate a memory mapping in low memory space,
68 int __init
efi_alloc_page_tables(void)
73 void efi_sync_low_kernel_mappings(void) {}
75 void __init
efi_dump_pagetable(void)
77 #ifdef CONFIG_EFI_PGT_DUMP
78 ptdump_walk_pgd_level(NULL
, &init_mm
);
82 int __init
efi_setup_page_tables(unsigned long pa_memmap
, unsigned num_pages
)
87 void __init
efi_map_region_fixed(efi_memory_desc_t
*md
) {}
88 void __init
parse_efi_setup(u64 phys_addr
, u32 data_len
) {}
90 efi_status_t
efi_call_svam(efi_runtime_services_t
* const *,
91 u32
, u32
, u32
, void *, u32
);
93 efi_status_t __init
efi_set_virtual_address_map(unsigned long memory_map_size
,
94 unsigned long descriptor_size
,
95 u32 descriptor_version
,
96 efi_memory_desc_t
*virtual_map
,
97 unsigned long systab_phys
)
99 const efi_system_table_t
*systab
= (efi_system_table_t
*)systab_phys
;
100 struct desc_ptr gdt_descr
;
105 /* Current pgd is swapper_pg_dir, we'll restore it later: */
106 save_pgd
= swapper_pg_dir
;
107 load_cr3(initial_page_table
);
110 gdt_descr
.address
= get_cpu_gdt_paddr(0);
111 gdt_descr
.size
= GDT_SIZE
- 1;
112 load_gdt(&gdt_descr
);
114 /* Disable interrupts around EFI calls: */
115 local_irq_save(flags
);
116 status
= efi_call_svam(&systab
->runtime
,
117 memory_map_size
, descriptor_size
,
118 descriptor_version
, virtual_map
,
120 local_irq_restore(flags
);
129 void __init
efi_runtime_update_mappings(void)
131 if (__supported_pte_mask
& _PAGE_NX
) {
132 efi_memory_desc_t
*md
;
134 /* Make EFI runtime service code area executable */
135 for_each_efi_memory_desc(md
) {
136 if (md
->type
!= EFI_RUNTIME_SERVICES_CODE
)
139 set_memory_x(md
->virt_addr
, md
->num_pages
);