.. | .. |
---|
24 | 24 | #include <linux/types.h> |
---|
25 | 25 | #include <linux/ioport.h> |
---|
26 | 26 | #include <linux/efi.h> |
---|
| 27 | +#include <linux/pgtable.h> |
---|
27 | 28 | |
---|
28 | 29 | #include <asm/io.h> |
---|
29 | 30 | #include <asm/desc.h> |
---|
30 | 31 | #include <asm/page.h> |
---|
31 | | -#include <asm/pgtable.h> |
---|
| 32 | +#include <asm/set_memory.h> |
---|
32 | 33 | #include <asm/tlbflush.h> |
---|
33 | 34 | #include <asm/efi.h> |
---|
| 35 | + |
---|
| 36 | +void __init efi_map_region(efi_memory_desc_t *md) |
---|
| 37 | +{ |
---|
| 38 | + u64 start_pfn, end_pfn, end; |
---|
| 39 | + unsigned long size; |
---|
| 40 | + void *va; |
---|
| 41 | + |
---|
| 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); |
---|
| 46 | + |
---|
| 47 | + if (pfn_range_is_mapped(start_pfn, end_pfn)) { |
---|
| 48 | + va = __va(md->phys_addr); |
---|
| 49 | + |
---|
| 50 | + if (!(md->attribute & EFI_MEMORY_WB)) |
---|
| 51 | + set_memory_uc((unsigned long)va, md->num_pages); |
---|
| 52 | + } else { |
---|
| 53 | + va = ioremap_cache(md->phys_addr, size); |
---|
| 54 | + } |
---|
| 55 | + |
---|
| 56 | + md->virt_addr = (unsigned long)va; |
---|
| 57 | + if (!va) |
---|
| 58 | + pr_err("ioremap of 0x%llX failed!\n", md->phys_addr); |
---|
| 59 | +} |
---|
34 | 60 | |
---|
35 | 61 | /* |
---|
36 | 62 | * To make EFI call EFI runtime service in physical addressing mode we need |
---|
.. | .. |
---|
49 | 75 | void __init efi_dump_pagetable(void) |
---|
50 | 76 | { |
---|
51 | 77 | #ifdef CONFIG_EFI_PGT_DUMP |
---|
52 | | - ptdump_walk_pgd_level(NULL, swapper_pg_dir); |
---|
| 78 | + ptdump_walk_pgd_level(NULL, &init_mm); |
---|
53 | 79 | #endif |
---|
54 | 80 | } |
---|
55 | 81 | |
---|
.. | .. |
---|
58 | 84 | return 0; |
---|
59 | 85 | } |
---|
60 | 86 | |
---|
61 | | -void __init efi_map_region(efi_memory_desc_t *md) |
---|
62 | | -{ |
---|
63 | | - old_map_region(md); |
---|
64 | | -} |
---|
65 | | - |
---|
66 | 87 | void __init efi_map_region_fixed(efi_memory_desc_t *md) {} |
---|
67 | 88 | void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} |
---|
68 | 89 | |
---|
69 | | -pgd_t * __init efi_call_phys_prolog(void) |
---|
| 90 | +efi_status_t efi_call_svam(efi_runtime_services_t * const *, |
---|
| 91 | + u32, u32, u32, void *, u32); |
---|
| 92 | + |
---|
| 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) |
---|
70 | 98 | { |
---|
| 99 | + const efi_system_table_t *systab = (efi_system_table_t *)systab_phys; |
---|
71 | 100 | struct desc_ptr gdt_descr; |
---|
| 101 | + efi_status_t status; |
---|
| 102 | + unsigned long flags; |
---|
72 | 103 | pgd_t *save_pgd; |
---|
73 | 104 | |
---|
74 | 105 | /* Current pgd is swapper_pg_dir, we'll restore it later: */ |
---|
.. | .. |
---|
80 | 111 | gdt_descr.size = GDT_SIZE - 1; |
---|
81 | 112 | load_gdt(&gdt_descr); |
---|
82 | 113 | |
---|
83 | | - return save_pgd; |
---|
84 | | -} |
---|
| 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, |
---|
| 119 | + __pa(&efi.runtime)); |
---|
| 120 | + local_irq_restore(flags); |
---|
85 | 121 | |
---|
86 | | -void __init efi_call_phys_epilog(pgd_t *save_pgd) |
---|
87 | | -{ |
---|
88 | 122 | load_fixmap_gdt(0); |
---|
89 | 123 | load_cr3(save_pgd); |
---|
90 | 124 | __flush_tlb_all(); |
---|
| 125 | + |
---|
| 126 | + return status; |
---|
91 | 127 | } |
---|
92 | 128 | |
---|
93 | 129 | void __init efi_runtime_update_mappings(void) |
---|
94 | 130 | { |
---|
95 | | - if (__supported_pte_mask & _PAGE_NX) |
---|
96 | | - runtime_code_page_mkexec(); |
---|
| 131 | + if (__supported_pte_mask & _PAGE_NX) { |
---|
| 132 | + efi_memory_desc_t *md; |
---|
| 133 | + |
---|
| 134 | + /* Make EFI runtime service code area executable */ |
---|
| 135 | + for_each_efi_memory_desc(md) { |
---|
| 136 | + if (md->type != EFI_RUNTIME_SERVICES_CODE) |
---|
| 137 | + continue; |
---|
| 138 | + |
---|
| 139 | + set_memory_x(md->virt_addr, md->num_pages); |
---|
| 140 | + } |
---|
| 141 | + } |
---|
97 | 142 | } |
---|