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 1.0
0006  *
0007  * Copyright (C) 1999 VA Linux Systems
0008  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
0009  * Copyright (C) 1999-2002 Hewlett-Packard Co.
0010  *  David Mosberger-Tang <davidm@hpl.hp.com>
0011  *  Stephane Eranian <eranian@hpl.hp.com>
0012  *
0013  * All EFI Runtime Services are not implemented yet as EFI only
0014  * supports physical mode addressing on SoftSDV. This is to be fixed
0015  * in a future version.  --drummond 1999-07-20
0016  *
0017  * Implemented EFI runtime services and virtual mode calls.  --davidm
0018  *
0019  * Goutham Rao: <goutham.rao@intel.com>
0020  *  Skip non-WB memory and ignore empty memory ranges.
0021  */
0022 
0023 #include <linux/kernel.h>
0024 #include <linux/types.h>
0025 #include <linux/ioport.h>
0026 #include <linux/efi.h>
0027 #include <linux/pgtable.h>
0028 
0029 #include <asm/io.h>
0030 #include <asm/desc.h>
0031 #include <asm/page.h>
0032 #include <asm/set_memory.h>
0033 #include <asm/tlbflush.h>
0034 #include <asm/efi.h>
0035 
0036 void __init efi_map_region(efi_memory_desc_t *md)
0037 {
0038     u64 start_pfn, end_pfn, end;
0039     unsigned long size;
0040     void *va;
0041 
0042     start_pfn   = PFN_DOWN(md->phys_addr);
0043     size        = md->num_pages << PAGE_SHIFT;
0044     end     = md->phys_addr + size;
0045     end_pfn     = PFN_UP(end);
0046 
0047     if (pfn_range_is_mapped(start_pfn, end_pfn)) {
0048         va = __va(md->phys_addr);
0049 
0050         if (!(md->attribute & EFI_MEMORY_WB))
0051             set_memory_uc((unsigned long)va, md->num_pages);
0052     } else {
0053         va = ioremap_cache(md->phys_addr, size);
0054     }
0055 
0056     md->virt_addr = (unsigned long)va;
0057     if (!va)
0058         pr_err("ioremap of 0x%llX failed!\n", md->phys_addr);
0059 }
0060 
0061 /*
0062  * To make EFI call EFI runtime service in physical addressing mode we need
0063  * prolog/epilog before/after the invocation to claim the EFI runtime service
0064  * handler exclusively and to duplicate a memory mapping in low memory space,
0065  * say 0 - 3G.
0066  */
0067 
0068 int __init efi_alloc_page_tables(void)
0069 {
0070     return 0;
0071 }
0072 
0073 void efi_sync_low_kernel_mappings(void) {}
0074 
0075 void __init efi_dump_pagetable(void)
0076 {
0077 #ifdef CONFIG_EFI_PGT_DUMP
0078     ptdump_walk_pgd_level(NULL, &init_mm);
0079 #endif
0080 }
0081 
0082 int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
0083 {
0084     return 0;
0085 }
0086 
0087 void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
0088 void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
0089 
0090 efi_status_t efi_call_svam(efi_runtime_services_t * const *,
0091                u32, u32, u32, void *, u32);
0092 
0093 efi_status_t __init efi_set_virtual_address_map(unsigned long memory_map_size,
0094                         unsigned long descriptor_size,
0095                         u32 descriptor_version,
0096                         efi_memory_desc_t *virtual_map,
0097                         unsigned long systab_phys)
0098 {
0099     const efi_system_table_t *systab = (efi_system_table_t *)systab_phys;
0100     struct desc_ptr gdt_descr;
0101     efi_status_t status;
0102     unsigned long flags;
0103     pgd_t *save_pgd;
0104 
0105     /* Current pgd is swapper_pg_dir, we'll restore it later: */
0106     save_pgd = swapper_pg_dir;
0107     load_cr3(initial_page_table);
0108     __flush_tlb_all();
0109 
0110     gdt_descr.address = get_cpu_gdt_paddr(0);
0111     gdt_descr.size = GDT_SIZE - 1;
0112     load_gdt(&gdt_descr);
0113 
0114     /* Disable interrupts around EFI calls: */
0115     local_irq_save(flags);
0116     status = efi_call_svam(&systab->runtime,
0117                    memory_map_size, descriptor_size,
0118                    descriptor_version, virtual_map,
0119                    __pa(&efi.runtime));
0120     local_irq_restore(flags);
0121 
0122     load_fixmap_gdt(0);
0123     load_cr3(save_pgd);
0124     __flush_tlb_all();
0125 
0126     return status;
0127 }
0128 
0129 void __init efi_runtime_update_mappings(void)
0130 {
0131     if (__supported_pte_mask & _PAGE_NX) {
0132         efi_memory_desc_t *md;
0133 
0134         /* Make EFI runtime service code area executable */
0135         for_each_efi_memory_desc(md) {
0136             if (md->type != EFI_RUNTIME_SERVICES_CODE)
0137                 continue;
0138 
0139             set_memory_x(md->virt_addr, md->num_pages);
0140         }
0141     }
0142 }