2 * Extensible Firmware Interface
4 * Based on Extensible Firmware Interface Specification version 2.4
6 * Copyright (C) 2013, 2014 Linaro Ltd.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 #include <linux/efi.h>
15 #include <linux/export.h>
16 #include <linux/memblock.h>
17 #include <linux/bootmem.h>
19 #include <linux/of_fdt.h>
20 #include <linux/sched.h>
21 #include <linux/slab.h>
23 #include <asm/cacheflush.h>
25 #include <asm/tlbflush.h>
26 #include <asm/mmu_context.h>
28 struct efi_memory_map memmap
;
30 static efi_runtime_services_t
*runtime
;
32 static u64 efi_system_table
;
34 static int uefi_debug __initdata
;
35 static int __init
uefi_debug_setup(char *str
)
41 early_param("uefi_debug", uefi_debug_setup
);
43 static int __init
is_normal_ram(efi_memory_desc_t
*md
)
45 if (md
->attribute
& EFI_MEMORY_WB
)
50 static void __init
efi_setup_idmap(void)
52 struct memblock_region
*r
;
53 efi_memory_desc_t
*md
;
54 u64 paddr
, npages
, size
;
56 for_each_memblock(memory
, r
)
57 create_id_mapping(r
->base
, r
->size
, 0);
59 /* map runtime io spaces */
60 for_each_efi_memory_desc(&memmap
, md
) {
61 if (!(md
->attribute
& EFI_MEMORY_RUNTIME
) || is_normal_ram(md
))
63 paddr
= md
->phys_addr
;
64 npages
= md
->num_pages
;
65 memrange_efi_to_native(&paddr
, &npages
);
66 size
= npages
<< PAGE_SHIFT
;
67 create_id_mapping(paddr
, size
, 1);
71 static int __init
uefi_init(void)
74 char vendor
[100] = "unknown";
77 efi
.systab
= early_memremap(efi_system_table
,
78 sizeof(efi_system_table_t
));
79 if (efi
.systab
== NULL
) {
80 pr_warn("Unable to map EFI system table.\n");
84 set_bit(EFI_BOOT
, &efi
.flags
);
85 set_bit(EFI_64BIT
, &efi
.flags
);
88 * Verify the EFI Table
90 if (efi
.systab
->hdr
.signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
91 pr_err("System table signature incorrect\n");
94 if ((efi
.systab
->hdr
.revision
>> 16) < 2)
95 pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n",
96 efi
.systab
->hdr
.revision
>> 16,
97 efi
.systab
->hdr
.revision
& 0xffff);
99 /* Show what we know for posterity */
100 c16
= early_memremap(efi
.systab
->fw_vendor
,
103 for (i
= 0; i
< (int) sizeof(vendor
) - 1 && *c16
; ++i
)
108 pr_info("EFI v%u.%.02u by %s\n",
109 efi
.systab
->hdr
.revision
>> 16,
110 efi
.systab
->hdr
.revision
& 0xffff, vendor
);
112 retval
= efi_config_init(NULL
);
114 set_bit(EFI_CONFIG_TABLES
, &efi
.flags
);
116 early_memunmap(c16
, sizeof(vendor
));
117 early_memunmap(efi
.systab
, sizeof(efi_system_table_t
));
122 static __initdata
char memory_type_name
[][32] = {
130 {"Conventional Memory"},
132 {"ACPI Reclaim Memory"},
134 {"Memory Mapped I/O"},
140 * Return true for RAM regions we want to permanently reserve.
142 static __init
int is_reserve_region(efi_memory_desc_t
*md
)
144 if (!is_normal_ram(md
))
147 if (md
->attribute
& EFI_MEMORY_RUNTIME
)
150 if (md
->type
== EFI_ACPI_RECLAIM_MEMORY
||
151 md
->type
== EFI_RESERVED_TYPE
)
157 static __init
void reserve_regions(void)
159 efi_memory_desc_t
*md
;
160 u64 paddr
, npages
, size
;
163 pr_info("Processing EFI memory map:\n");
165 for_each_efi_memory_desc(&memmap
, md
) {
166 paddr
= md
->phys_addr
;
167 npages
= md
->num_pages
;
170 pr_info(" 0x%012llx-0x%012llx [%s]",
171 paddr
, paddr
+ (npages
<< EFI_PAGE_SHIFT
) - 1,
172 memory_type_name
[md
->type
]);
174 memrange_efi_to_native(&paddr
, &npages
);
175 size
= npages
<< PAGE_SHIFT
;
177 if (is_normal_ram(md
))
178 early_init_dt_add_memory_arch(paddr
, size
);
180 if (is_reserve_region(md
) ||
181 md
->type
== EFI_BOOT_SERVICES_CODE
||
182 md
->type
== EFI_BOOT_SERVICES_DATA
) {
183 memblock_reserve(paddr
, size
);
192 set_bit(EFI_MEMMAP
, &efi
.flags
);
196 static u64 __init
free_one_region(u64 start
, u64 end
)
198 u64 size
= end
- start
;
201 pr_info(" EFI freeing: 0x%012llx-0x%012llx\n", start
, end
- 1);
203 free_bootmem_late(start
, size
);
207 static u64 __init
free_region(u64 start
, u64 end
)
209 u64 map_start
, map_end
, total
= 0;
214 map_start
= (u64
)memmap
.phys_map
;
215 map_end
= PAGE_ALIGN(map_start
+ (memmap
.map_end
- memmap
.map
));
216 map_start
&= PAGE_MASK
;
218 if (start
< map_end
&& end
> map_start
) {
219 /* region overlaps UEFI memmap */
220 if (start
< map_start
)
221 total
+= free_one_region(start
, map_start
);
224 total
+= free_one_region(map_end
, end
);
226 total
+= free_one_region(start
, end
);
231 static void __init
free_boot_services(void)
234 u64 keep_end
, free_start
, free_end
;
235 efi_memory_desc_t
*md
;
238 * If kernel uses larger pages than UEFI, we have to be careful
239 * not to inadvertantly free memory we want to keep if there is
240 * overlap at the kernel page size alignment. We do not want to
241 * free is_reserve_region() memory nor the UEFI memmap itself.
243 * The memory map is sorted, so we keep track of the end of
244 * any previous region we want to keep, remember any region
245 * we want to free and defer freeing it until we encounter
246 * the next region we want to keep. This way, before freeing
247 * it, we can clip it as needed to avoid freeing memory we
248 * want to keep for UEFI.
254 for_each_efi_memory_desc(&memmap
, md
) {
255 u64 paddr
, npages
, size
;
257 if (is_reserve_region(md
)) {
259 * We don't want to free any memory from this region.
262 /* adjust free_end then free region */
263 if (free_end
> md
->phys_addr
)
264 free_end
-= PAGE_SIZE
;
265 total_freed
+= free_region(free_start
, free_end
);
268 keep_end
= md
->phys_addr
+ (md
->num_pages
<< EFI_PAGE_SHIFT
);
272 if (md
->type
!= EFI_BOOT_SERVICES_CODE
&&
273 md
->type
!= EFI_BOOT_SERVICES_DATA
) {
274 /* no need to free this region */
279 * We want to free memory from this region.
281 paddr
= md
->phys_addr
;
282 npages
= md
->num_pages
;
283 memrange_efi_to_native(&paddr
, &npages
);
284 size
= npages
<< PAGE_SHIFT
;
287 if (paddr
<= free_end
)
288 free_end
= paddr
+ size
;
290 total_freed
+= free_region(free_start
, free_end
);
292 free_end
= paddr
+ size
;
296 free_end
= paddr
+ size
;
298 if (free_start
< keep_end
) {
299 free_start
+= PAGE_SIZE
;
300 if (free_start
>= free_end
)
305 total_freed
+= free_region(free_start
, free_end
);
308 pr_info("Freed 0x%llx bytes of EFI boot services memory",
312 void __init
efi_init(void)
314 struct efi_fdt_params params
;
316 /* Grab UEFI information placed in FDT by stub */
317 if (!efi_get_fdt_params(¶ms
, uefi_debug
))
320 efi_system_table
= params
.system_table
;
322 memblock_reserve(params
.mmap
& PAGE_MASK
,
323 PAGE_ALIGN(params
.mmap_size
+ (params
.mmap
& ~PAGE_MASK
)));
324 memmap
.phys_map
= (void *)params
.mmap
;
325 memmap
.map
= early_memremap(params
.mmap
, params
.mmap_size
);
326 memmap
.map_end
= memmap
.map
+ params
.mmap_size
;
327 memmap
.desc_size
= params
.desc_size
;
328 memmap
.desc_version
= params
.desc_ver
;
336 void __init
efi_idmap_init(void)
338 if (!efi_enabled(EFI_BOOT
))
341 /* boot time idmap_pg_dir is incomplete, so fill in missing parts */
345 static int __init
remap_region(efi_memory_desc_t
*md
, void **new)
347 u64 paddr
, vaddr
, npages
, size
;
349 paddr
= md
->phys_addr
;
350 npages
= md
->num_pages
;
351 memrange_efi_to_native(&paddr
, &npages
);
352 size
= npages
<< PAGE_SHIFT
;
354 if (is_normal_ram(md
))
355 vaddr
= (__force u64
)ioremap_cache(paddr
, size
);
357 vaddr
= (__force u64
)ioremap(paddr
, size
);
360 pr_err("Unable to remap 0x%llx pages @ %p\n",
361 npages
, (void *)paddr
);
365 /* adjust for any rounding when EFI and system pagesize differs */
366 md
->virt_addr
= vaddr
+ (md
->phys_addr
- paddr
);
369 pr_info(" EFI remap 0x%012llx => %p\n",
370 md
->phys_addr
, (void *)md
->virt_addr
);
372 memcpy(*new, md
, memmap
.desc_size
);
373 *new += memmap
.desc_size
;
379 * Switch UEFI from an identity map to a kernel virtual map
381 static int __init
arm64_enter_virtual_mode(void)
383 efi_memory_desc_t
*md
;
384 phys_addr_t virtmap_phys
;
385 void *virtmap
, *virt_md
;
391 if (!efi_enabled(EFI_BOOT
)) {
392 pr_info("EFI services will not be available.\n");
396 pr_info("Remapping and enabling EFI services.\n");
398 /* replace early memmap mapping with permanent mapping */
399 mapsize
= memmap
.map_end
- memmap
.map
;
400 early_memunmap(memmap
.map
, mapsize
);
401 memmap
.map
= (__force
void *)ioremap_cache((phys_addr_t
)memmap
.phys_map
,
403 memmap
.map_end
= memmap
.map
+ mapsize
;
405 efi
.memmap
= &memmap
;
407 /* Map the runtime regions */
408 virtmap
= kmalloc(mapsize
, GFP_KERNEL
);
410 pr_err("Failed to allocate EFI virtual memmap\n");
413 virtmap_phys
= virt_to_phys(virtmap
);
416 for_each_efi_memory_desc(&memmap
, md
) {
417 if (!(md
->attribute
& EFI_MEMORY_RUNTIME
))
419 if (!remap_region(md
, &virt_md
))
424 efi
.systab
= (__force
void *)efi_lookup_mapped_addr(efi_system_table
);
427 * If we have no virtual mapping for the System Table at this
428 * point, the memory map doesn't cover the physical offset where
429 * it resides. This means the System Table will be inaccessible
430 * to Runtime Services themselves once the virtual mapping is
433 pr_err("Failed to remap EFI System Table -- buggy firmware?\n");
436 set_bit(EFI_SYSTEM_TABLES
, &efi
.flags
);
438 local_irq_save(flags
);
439 cpu_switch_mm(idmap_pg_dir
, &init_mm
);
441 /* Call SetVirtualAddressMap with the physical address of the map */
442 runtime
= efi
.systab
->runtime
;
443 efi
.set_virtual_address_map
= runtime
->set_virtual_address_map
;
445 status
= efi
.set_virtual_address_map(count
* memmap
.desc_size
,
448 (efi_memory_desc_t
*)virtmap_phys
);
449 cpu_set_reserved_ttbr0();
451 local_irq_restore(flags
);
455 free_boot_services();
457 if (status
!= EFI_SUCCESS
) {
458 pr_err("Failed to set EFI virtual address map! [%lx]\n",
463 /* Set up runtime services function pointers */
464 runtime
= efi
.systab
->runtime
;
465 efi_native_runtime_setup();
466 set_bit(EFI_RUNTIME_SERVICES
, &efi
.flags
);
468 efi
.runtime_version
= efi
.systab
->hdr
.revision
;
473 /* unmap all mappings that succeeded: there are 'count' of those */
474 for (virt_md
= virtmap
; count
--; virt_md
+= memmap
.desc_size
) {
476 iounmap((__force
void __iomem
*)md
->virt_addr
);
481 early_initcall(arm64_enter_virtual_mode
);