^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Extensible Firmware Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2020 Western Digital Corporation or its affiliates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on Extensible Firmware Interface Specification version 2.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Adapted from drivers/firmware/efi/arm-runtime.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mm_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/preempt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/rwsem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/pgalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static bool __init efi_virtmap_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) efi_memory_desc_t *md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) efi_mm.pgd = pgd_alloc(&efi_mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) mm_init_cpumask(&efi_mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) init_new_context(NULL, &efi_mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) for_each_efi_memory_desc(md) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) phys_addr_t phys = md->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (!(md->attribute & EFI_MEMORY_RUNTIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (md->virt_addr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ret = efi_create_mapping(&efi_mm, md);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) pr_warn(" EFI remap %pa: failed to create mapping (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) &phys, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (efi_memattr_apply_permissions(&efi_mm, efi_set_mapping_permissions))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * non-early mapping of the UEFI system table and virtual mappings for all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * EFI_MEMORY_RUNTIME regions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int __init riscv_enable_runtime_services(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u64 mapsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (!efi_enabled(EFI_BOOT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) pr_info("EFI services will not be available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) efi_memmap_unmap();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) mapsize = efi.memmap.desc_size * efi.memmap.nr_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (efi_memmap_init_late(efi.memmap.phys_map, mapsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) pr_err("Failed to remap EFI memory map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (efi_soft_reserve_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) efi_memory_desc_t *md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) for_each_efi_memory_desc(md) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int md_size = md->num_pages << EFI_PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (!(md->attribute & EFI_MEMORY_SP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) res = kzalloc(sizeof(*res), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (WARN_ON(!res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) res->start = md->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) res->end = md->phys_addr + md_size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) res->name = "Soft Reserved";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) res->flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) res->desc = IORES_DESC_SOFT_RESERVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) insert_resource(&iomem_resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (efi_runtime_disabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) pr_info("EFI runtime services will be disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (efi_enabled(EFI_RUNTIME_SERVICES)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pr_info("EFI runtime services access via paravirt.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pr_info("Remapping and enabling EFI services.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!efi_virtmap_init()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Set up runtime services function pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) efi_native_runtime_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) early_initcall(riscv_enable_runtime_services);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) void efi_virtmap_load(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) switch_mm(current->active_mm, &efi_mm, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) void efi_virtmap_unload(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) switch_mm(&efi_mm, current->active_mm, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }