Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Extensible Firmware Interface
0004  *
0005  * Based on Extensible Firmware Interface Specification version 2.4
0006  *
0007  * Copyright (C) 2013, 2014 Linaro Ltd.
0008  */
0009 
0010 #include <linux/dmi.h>
0011 #include <linux/efi.h>
0012 #include <linux/io.h>
0013 #include <linux/memblock.h>
0014 #include <linux/mm_types.h>
0015 #include <linux/preempt.h>
0016 #include <linux/rbtree.h>
0017 #include <linux/rwsem.h>
0018 #include <linux/sched.h>
0019 #include <linux/slab.h>
0020 #include <linux/spinlock.h>
0021 #include <linux/pgtable.h>
0022 
0023 #include <asm/cacheflush.h>
0024 #include <asm/efi.h>
0025 #include <asm/mmu.h>
0026 #include <asm/pgalloc.h>
0027 
0028 #if defined(CONFIG_PTDUMP_DEBUGFS) && defined(CONFIG_ARM64)
0029 #include <asm/ptdump.h>
0030 
0031 static struct ptdump_info efi_ptdump_info = {
0032     .mm     = &efi_mm,
0033     .markers    = (struct addr_marker[]){
0034         { 0,                "UEFI runtime start" },
0035         { DEFAULT_MAP_WINDOW_64,    "UEFI runtime end" },
0036         { -1,               NULL }
0037     },
0038     .base_addr  = 0,
0039 };
0040 
0041 static int __init ptdump_init(void)
0042 {
0043     if (efi_enabled(EFI_RUNTIME_SERVICES))
0044         ptdump_debugfs_register(&efi_ptdump_info, "efi_page_tables");
0045 
0046     return 0;
0047 }
0048 device_initcall(ptdump_init);
0049 
0050 #endif
0051 
0052 static bool __init efi_virtmap_init(void)
0053 {
0054     efi_memory_desc_t *md;
0055 
0056     efi_mm.pgd = pgd_alloc(&efi_mm);
0057     mm_init_cpumask(&efi_mm);
0058     init_new_context(NULL, &efi_mm);
0059 
0060     for_each_efi_memory_desc(md) {
0061         phys_addr_t phys = md->phys_addr;
0062         int ret;
0063 
0064         if (!(md->attribute & EFI_MEMORY_RUNTIME))
0065             continue;
0066         if (md->virt_addr == 0)
0067             return false;
0068 
0069         ret = efi_create_mapping(&efi_mm, md);
0070         if (ret) {
0071             pr_warn("  EFI remap %pa: failed to create mapping (%d)\n",
0072                 &phys, ret);
0073             return false;
0074         }
0075     }
0076 
0077     if (efi_memattr_apply_permissions(&efi_mm, efi_set_mapping_permissions))
0078         return false;
0079 
0080     return true;
0081 }
0082 
0083 /*
0084  * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
0085  * non-early mapping of the UEFI system table and virtual mappings for all
0086  * EFI_MEMORY_RUNTIME regions.
0087  */
0088 static int __init arm_enable_runtime_services(void)
0089 {
0090     u64 mapsize;
0091 
0092     if (!efi_enabled(EFI_BOOT)) {
0093         pr_info("EFI services will not be available.\n");
0094         return 0;
0095     }
0096 
0097     efi_memmap_unmap();
0098 
0099     mapsize = efi.memmap.desc_size * efi.memmap.nr_map;
0100 
0101     if (efi_memmap_init_late(efi.memmap.phys_map, mapsize)) {
0102         pr_err("Failed to remap EFI memory map\n");
0103         return 0;
0104     }
0105 
0106     if (efi_soft_reserve_enabled()) {
0107         efi_memory_desc_t *md;
0108 
0109         for_each_efi_memory_desc(md) {
0110             int md_size = md->num_pages << EFI_PAGE_SHIFT;
0111             struct resource *res;
0112 
0113             if (!(md->attribute & EFI_MEMORY_SP))
0114                 continue;
0115 
0116             res = kzalloc(sizeof(*res), GFP_KERNEL);
0117             if (WARN_ON(!res))
0118                 break;
0119 
0120             res->start  = md->phys_addr;
0121             res->end    = md->phys_addr + md_size - 1;
0122             res->name   = "Soft Reserved";
0123             res->flags  = IORESOURCE_MEM;
0124             res->desc   = IORES_DESC_SOFT_RESERVED;
0125 
0126             insert_resource(&iomem_resource, res);
0127         }
0128     }
0129 
0130     if (efi_runtime_disabled()) {
0131         pr_info("EFI runtime services will be disabled.\n");
0132         return 0;
0133     }
0134 
0135     if (efi_enabled(EFI_RUNTIME_SERVICES)) {
0136         pr_info("EFI runtime services access via paravirt.\n");
0137         return 0;
0138     }
0139 
0140     pr_info("Remapping and enabling EFI services.\n");
0141 
0142     if (!efi_virtmap_init()) {
0143         pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n");
0144         return -ENOMEM;
0145     }
0146 
0147     /* Set up runtime services function pointers */
0148     efi_native_runtime_setup();
0149     set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
0150 
0151     return 0;
0152 }
0153 early_initcall(arm_enable_runtime_services);
0154 
0155 void efi_virtmap_load(void)
0156 {
0157     preempt_disable();
0158     efi_set_pgd(&efi_mm);
0159 }
0160 
0161 void efi_virtmap_unload(void)
0162 {
0163     efi_set_pgd(current->active_mm);
0164     preempt_enable();
0165 }
0166 
0167 
0168 static int __init arm_dmi_init(void)
0169 {
0170     /*
0171      * On arm64/ARM, DMI depends on UEFI, and dmi_setup() needs to
0172      * be called early because dmi_id_init(), which is an arch_initcall
0173      * itself, depends on dmi_scan_machine() having been called already.
0174      */
0175     dmi_setup();
0176     return 0;
0177 }
0178 core_initcall(arm_dmi_init);