diff options
Diffstat (limited to 'drivers/firmware/efi/arm-init.c')
-rw-r--r-- | drivers/firmware/efi/arm-init.c | 96 |
1 files changed, 70 insertions, 26 deletions
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 8714f8c271ba..ef90f0c4b70a 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c | |||
@@ -11,17 +11,19 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) "efi: " fmt | ||
15 | |||
14 | #include <linux/efi.h> | 16 | #include <linux/efi.h> |
15 | #include <linux/init.h> | 17 | #include <linux/init.h> |
16 | #include <linux/memblock.h> | 18 | #include <linux/memblock.h> |
17 | #include <linux/mm_types.h> | 19 | #include <linux/mm_types.h> |
18 | #include <linux/of.h> | 20 | #include <linux/of.h> |
19 | #include <linux/of_fdt.h> | 21 | #include <linux/of_fdt.h> |
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/screen_info.h> | ||
20 | 24 | ||
21 | #include <asm/efi.h> | 25 | #include <asm/efi.h> |
22 | 26 | ||
23 | struct efi_memory_map memmap; | ||
24 | |||
25 | u64 efi_system_table; | 27 | u64 efi_system_table; |
26 | 28 | ||
27 | static int __init is_normal_ram(efi_memory_desc_t *md) | 29 | static int __init is_normal_ram(efi_memory_desc_t *md) |
@@ -40,7 +42,7 @@ static phys_addr_t efi_to_phys(unsigned long addr) | |||
40 | { | 42 | { |
41 | efi_memory_desc_t *md; | 43 | efi_memory_desc_t *md; |
42 | 44 | ||
43 | for_each_efi_memory_desc(&memmap, md) { | 45 | for_each_efi_memory_desc(md) { |
44 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | 46 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) |
45 | continue; | 47 | continue; |
46 | if (md->virt_addr == 0) | 48 | if (md->virt_addr == 0) |
@@ -53,6 +55,36 @@ static phys_addr_t efi_to_phys(unsigned long addr) | |||
53 | return addr; | 55 | return addr; |
54 | } | 56 | } |
55 | 57 | ||
58 | static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR; | ||
59 | |||
60 | static __initdata efi_config_table_type_t arch_tables[] = { | ||
61 | {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, NULL, &screen_info_table}, | ||
62 | {NULL_GUID, NULL, NULL} | ||
63 | }; | ||
64 | |||
65 | static void __init init_screen_info(void) | ||
66 | { | ||
67 | struct screen_info *si; | ||
68 | |||
69 | if (screen_info_table != EFI_INVALID_TABLE_ADDR) { | ||
70 | si = early_memremap_ro(screen_info_table, sizeof(*si)); | ||
71 | if (!si) { | ||
72 | pr_err("Could not map screen_info config table\n"); | ||
73 | return; | ||
74 | } | ||
75 | screen_info = *si; | ||
76 | early_memunmap(si, sizeof(*si)); | ||
77 | |||
78 | /* dummycon on ARM needs non-zero values for columns/lines */ | ||
79 | screen_info.orig_video_cols = 80; | ||
80 | screen_info.orig_video_lines = 25; | ||
81 | } | ||
82 | |||
83 | if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && | ||
84 | memblock_is_map_memory(screen_info.lfb_base)) | ||
85 | memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size); | ||
86 | } | ||
87 | |||
56 | static int __init uefi_init(void) | 88 | static int __init uefi_init(void) |
57 | { | 89 | { |
58 | efi_char16_t *c16; | 90 | efi_char16_t *c16; |
@@ -85,6 +117,8 @@ static int __init uefi_init(void) | |||
85 | efi.systab->hdr.revision >> 16, | 117 | efi.systab->hdr.revision >> 16, |
86 | efi.systab->hdr.revision & 0xffff); | 118 | efi.systab->hdr.revision & 0xffff); |
87 | 119 | ||
120 | efi.runtime_version = efi.systab->hdr.revision; | ||
121 | |||
88 | /* Show what we know for posterity */ | 122 | /* Show what we know for posterity */ |
89 | c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor), | 123 | c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor), |
90 | sizeof(vendor) * sizeof(efi_char16_t)); | 124 | sizeof(vendor) * sizeof(efi_char16_t)); |
@@ -108,7 +142,8 @@ static int __init uefi_init(void) | |||
108 | goto out; | 142 | goto out; |
109 | } | 143 | } |
110 | retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, | 144 | retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, |
111 | sizeof(efi_config_table_t), NULL); | 145 | sizeof(efi_config_table_t), |
146 | arch_tables); | ||
112 | 147 | ||
113 | early_memunmap(config_tables, table_size); | 148 | early_memunmap(config_tables, table_size); |
114 | out: | 149 | out: |
@@ -143,7 +178,7 @@ static __init void reserve_regions(void) | |||
143 | if (efi_enabled(EFI_DBG)) | 178 | if (efi_enabled(EFI_DBG)) |
144 | pr_info("Processing EFI memory map:\n"); | 179 | pr_info("Processing EFI memory map:\n"); |
145 | 180 | ||
146 | for_each_efi_memory_desc(&memmap, md) { | 181 | for_each_efi_memory_desc(md) { |
147 | paddr = md->phys_addr; | 182 | paddr = md->phys_addr; |
148 | npages = md->num_pages; | 183 | npages = md->num_pages; |
149 | 184 | ||
@@ -184,9 +219,9 @@ void __init efi_init(void) | |||
184 | 219 | ||
185 | efi_system_table = params.system_table; | 220 | efi_system_table = params.system_table; |
186 | 221 | ||
187 | memmap.phys_map = params.mmap; | 222 | efi.memmap.phys_map = params.mmap; |
188 | memmap.map = early_memremap_ro(params.mmap, params.mmap_size); | 223 | efi.memmap.map = early_memremap_ro(params.mmap, params.mmap_size); |
189 | if (memmap.map == NULL) { | 224 | if (efi.memmap.map == NULL) { |
190 | /* | 225 | /* |
191 | * If we are booting via UEFI, the UEFI memory map is the only | 226 | * If we are booting via UEFI, the UEFI memory map is the only |
192 | * description of memory we have, so there is little point in | 227 | * description of memory we have, so there is little point in |
@@ -194,28 +229,37 @@ void __init efi_init(void) | |||
194 | */ | 229 | */ |
195 | panic("Unable to map EFI memory map.\n"); | 230 | panic("Unable to map EFI memory map.\n"); |
196 | } | 231 | } |
197 | memmap.map_end = memmap.map + params.mmap_size; | 232 | efi.memmap.map_end = efi.memmap.map + params.mmap_size; |
198 | memmap.desc_size = params.desc_size; | 233 | efi.memmap.desc_size = params.desc_size; |
199 | memmap.desc_version = params.desc_ver; | 234 | efi.memmap.desc_version = params.desc_ver; |
235 | |||
236 | WARN(efi.memmap.desc_version != 1, | ||
237 | "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", | ||
238 | efi.memmap.desc_version); | ||
200 | 239 | ||
201 | if (uefi_init() < 0) | 240 | if (uefi_init() < 0) |
202 | return; | 241 | return; |
203 | 242 | ||
204 | reserve_regions(); | 243 | reserve_regions(); |
205 | early_memunmap(memmap.map, params.mmap_size); | 244 | efi_memattr_init(); |
245 | early_memunmap(efi.memmap.map, params.mmap_size); | ||
206 | 246 | ||
207 | if (IS_ENABLED(CONFIG_ARM)) { | 247 | memblock_reserve(params.mmap & PAGE_MASK, |
208 | /* | 248 | PAGE_ALIGN(params.mmap_size + |
209 | * ARM currently does not allow ioremap_cache() to be called on | 249 | (params.mmap & ~PAGE_MASK))); |
210 | * memory regions that are covered by struct page. So remove the | 250 | |
211 | * UEFI memory map from the linear mapping. | 251 | init_screen_info(); |
212 | */ | 252 | } |
213 | memblock_mark_nomap(params.mmap & PAGE_MASK, | 253 | |
214 | PAGE_ALIGN(params.mmap_size + | 254 | static int __init register_gop_device(void) |
215 | (params.mmap & ~PAGE_MASK))); | 255 | { |
216 | } else { | 256 | void *pd; |
217 | memblock_reserve(params.mmap & PAGE_MASK, | 257 | |
218 | PAGE_ALIGN(params.mmap_size + | 258 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) |
219 | (params.mmap & ~PAGE_MASK))); | 259 | return 0; |
220 | } | 260 | |
261 | pd = platform_device_register_data(NULL, "efi-framebuffer", 0, | ||
262 | &screen_info, sizeof(screen_info)); | ||
263 | return PTR_ERR_OR_ZERO(pd); | ||
221 | } | 264 | } |
265 | subsys_initcall(register_gop_device); | ||