Commit | Line | Data |
---|---|---|
628c3bb4 HC |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * EFI initialization | |
4 | * | |
5 | * Author: Jianmin Lv <lvjianmin@loongson.cn> | |
6 | * Huacai Chen <chenhuacai@loongson.cn> | |
7 | * | |
8 | * Copyright (C) 2020-2022 Loongson Technology Corporation Limited | |
9 | */ | |
10 | ||
11 | #include <linux/acpi.h> | |
12 | #include <linux/efi.h> | |
13 | #include <linux/efi-bgrt.h> | |
14 | #include <linux/init.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/export.h> | |
17 | #include <linux/io.h> | |
18 | #include <linux/kobject.h> | |
19 | #include <linux/memblock.h> | |
20 | #include <linux/reboot.h> | |
21 | #include <linux/uaccess.h> | |
22 | ||
23 | #include <asm/early_ioremap.h> | |
24 | #include <asm/efi.h> | |
25 | #include <asm/loongson.h> | |
26 | ||
27 | static unsigned long efi_nr_tables; | |
28 | static unsigned long efi_config_table; | |
29 | ||
40cd01a9 | 30 | static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR; |
88d4d957 | 31 | static unsigned long __initdata fdt_pointer = EFI_INVALID_TABLE_ADDR; |
40cd01a9 | 32 | |
628c3bb4 | 33 | static efi_system_table_t *efi_systab; |
40cd01a9 AB |
34 | static efi_config_table_type_t arch_tables[] __initdata = { |
35 | {LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" }, | |
88d4d957 | 36 | {DEVICE_TREE_GUID, &fdt_pointer, "FDTPTR" }, |
40cd01a9 AB |
37 | {}, |
38 | }; | |
628c3bb4 | 39 | |
88d4d957 BZ |
40 | void __init *efi_fdt_pointer(void) |
41 | { | |
42 | if (!efi_systab) | |
43 | return NULL; | |
44 | ||
45 | if (fdt_pointer == EFI_INVALID_TABLE_ADDR) | |
46 | return NULL; | |
47 | ||
48 | return early_memremap_ro(fdt_pointer, SZ_64K); | |
49 | } | |
50 | ||
628c3bb4 HC |
51 | void __init efi_runtime_init(void) |
52 | { | |
88d4d957 | 53 | if (!efi_enabled(EFI_BOOT) || !efi_systab->runtime) |
628c3bb4 HC |
54 | return; |
55 | ||
56 | if (efi_runtime_disabled()) { | |
57 | pr_info("EFI runtime services will be disabled.\n"); | |
58 | return; | |
59 | } | |
60 | ||
61 | efi.runtime = (efi_runtime_services_t *)efi_systab->runtime; | |
62 | efi.runtime_version = (unsigned int)efi.runtime->hdr.revision; | |
63 | ||
64 | efi_native_runtime_setup(); | |
65 | set_bit(EFI_RUNTIME_SERVICES, &efi.flags); | |
66 | } | |
67 | ||
732ea9db AB |
68 | unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; |
69 | ||
70 | static void __init init_screen_info(void) | |
71 | { | |
72 | struct screen_info *si; | |
73 | ||
74 | if (screen_info_table == EFI_INVALID_TABLE_ADDR) | |
75 | return; | |
76 | ||
77 | si = early_memremap(screen_info_table, sizeof(*si)); | |
78 | if (!si) { | |
79 | pr_err("Could not map screen_info config table\n"); | |
80 | return; | |
81 | } | |
82 | screen_info = *si; | |
83 | memset(si, 0, sizeof(*si)); | |
84 | early_memunmap(si, sizeof(*si)); | |
85 | ||
86 | memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); | |
87 | } | |
88 | ||
628c3bb4 HC |
89 | void __init efi_init(void) |
90 | { | |
91 | int size; | |
92 | void *config_tables; | |
40cd01a9 | 93 | struct efi_boot_memmap *tbl; |
628c3bb4 HC |
94 | |
95 | if (!efi_system_table) | |
96 | return; | |
97 | ||
98 | efi_systab = (efi_system_table_t *)early_memremap_ro(efi_system_table, sizeof(*efi_systab)); | |
99 | if (!efi_systab) { | |
100 | pr_err("Can't find EFI system table.\n"); | |
101 | return; | |
102 | } | |
103 | ||
40cd01a9 AB |
104 | efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor); |
105 | ||
628c3bb4 HC |
106 | set_bit(EFI_64BIT, &efi.flags); |
107 | efi_nr_tables = efi_systab->nr_tables; | |
108 | efi_config_table = (unsigned long)efi_systab->tables; | |
109 | ||
110 | size = sizeof(efi_config_table_t); | |
111 | config_tables = early_memremap(efi_config_table, efi_nr_tables * size); | |
112 | efi_config_parse_tables(config_tables, efi_systab->nr_tables, arch_tables); | |
113 | early_memunmap(config_tables, efi_nr_tables * size); | |
ead384d9 | 114 | |
40cd01a9 AB |
115 | set_bit(EFI_CONFIG_TABLES, &efi.flags); |
116 | ||
732ea9db | 117 | init_screen_info(); |
40cd01a9 AB |
118 | |
119 | if (boot_memmap == EFI_INVALID_TABLE_ADDR) | |
120 | return; | |
121 | ||
122 | tbl = early_memremap_ro(boot_memmap, sizeof(*tbl)); | |
123 | if (tbl) { | |
124 | struct efi_memory_map_data data; | |
125 | ||
126 | data.phys_map = boot_memmap + sizeof(*tbl); | |
127 | data.size = tbl->map_size; | |
128 | data.desc_size = tbl->desc_size; | |
129 | data.desc_version = tbl->desc_ver; | |
130 | ||
131 | if (efi_memmap_init_early(&data) < 0) | |
132 | panic("Unable to map EFI memory map.\n"); | |
133 | ||
134 | early_memunmap(tbl, sizeof(*tbl)); | |
135 | } | |
628c3bb4 | 136 | } |