xref: /openbmc/linux/arch/x86/boot/compressed/acpi.c (revision 151f4e2b)
1 // SPDX-License-Identifier: GPL-2.0
2 #define BOOT_CTYPE_H
3 #include "misc.h"
4 #include "error.h"
5 #include "../string.h"
6 
7 #include <linux/numa.h>
8 #include <linux/efi.h>
9 #include <asm/efi.h>
10 
11 /*
12  * Longest parameter of 'acpi=' is 'copy_dsdt', plus an extra '\0'
13  * for termination.
14  */
15 #define MAX_ACPI_ARG_LENGTH 10
16 
17 /*
18  * Immovable memory regions representation. Max amount of memory regions is
19  * MAX_NUMNODES*2.
20  */
21 struct mem_vector immovable_mem[MAX_NUMNODES*2];
22 
23 /*
24  * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
25  * digits, and '\0' for termination.
26  */
27 #define MAX_ADDR_LEN 19
28 
29 static acpi_physical_address get_acpi_rsdp(void)
30 {
31 	acpi_physical_address addr = 0;
32 
33 #ifdef CONFIG_KEXEC
34 	char val[MAX_ADDR_LEN] = { };
35 	int ret;
36 
37 	ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN);
38 	if (ret < 0)
39 		return 0;
40 
41 	if (kstrtoull(val, 16, &addr))
42 		return 0;
43 #endif
44 	return addr;
45 }
46 
47 /* Search EFI system tables for RSDP. */
48 static acpi_physical_address efi_get_rsdp_addr(void)
49 {
50 	acpi_physical_address rsdp_addr = 0;
51 
52 #ifdef CONFIG_EFI
53 	unsigned long systab, systab_tables, config_tables;
54 	unsigned int nr_tables;
55 	struct efi_info *ei;
56 	bool efi_64;
57 	int size, i;
58 	char *sig;
59 
60 	ei = &boot_params->efi_info;
61 	sig = (char *)&ei->efi_loader_signature;
62 
63 	if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
64 		efi_64 = true;
65 	} else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) {
66 		efi_64 = false;
67 	} else {
68 		debug_putstr("Wrong EFI loader signature.\n");
69 		return 0;
70 	}
71 
72 	/* Get systab from boot params. */
73 #ifdef CONFIG_X86_64
74 	systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
75 #else
76 	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
77 		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
78 		return 0;
79 	}
80 	systab = ei->efi_systab;
81 #endif
82 	if (!systab)
83 		error("EFI system table not found.");
84 
85 	/* Handle EFI bitness properly */
86 	if (efi_64) {
87 		efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab;
88 
89 		config_tables	= stbl->tables;
90 		nr_tables	= stbl->nr_tables;
91 		size		= sizeof(efi_config_table_64_t);
92 	} else {
93 		efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
94 
95 		config_tables	= stbl->tables;
96 		nr_tables	= stbl->nr_tables;
97 		size		= sizeof(efi_config_table_32_t);
98 	}
99 
100 	if (!config_tables)
101 		error("EFI config tables not found.");
102 
103 	/* Get EFI tables from systab. */
104 	for (i = 0; i < nr_tables; i++) {
105 		acpi_physical_address table;
106 		efi_guid_t guid;
107 
108 		config_tables += size;
109 
110 		if (efi_64) {
111 			efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables;
112 
113 			guid  = tbl->guid;
114 			table = tbl->table;
115 
116 			if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
117 				debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n");
118 				return 0;
119 			}
120 		} else {
121 			efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables;
122 
123 			guid  = tbl->guid;
124 			table = tbl->table;
125 		}
126 
127 		if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))
128 			rsdp_addr = table;
129 		else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
130 			return table;
131 	}
132 #endif
133 	return rsdp_addr;
134 }
135 
136 static u8 compute_checksum(u8 *buffer, u32 length)
137 {
138 	u8 *end = buffer + length;
139 	u8 sum = 0;
140 
141 	while (buffer < end)
142 		sum += *(buffer++);
143 
144 	return sum;
145 }
146 
147 /* Search a block of memory for the RSDP signature. */
148 static u8 *scan_mem_for_rsdp(u8 *start, u32 length)
149 {
150 	struct acpi_table_rsdp *rsdp;
151 	u8 *address, *end;
152 
153 	end = start + length;
154 
155 	/* Search from given start address for the requested length */
156 	for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) {
157 		/*
158 		 * Both RSDP signature and checksum must be correct.
159 		 * Note: Sometimes there exists more than one RSDP in memory;
160 		 * the valid RSDP has a valid checksum, all others have an
161 		 * invalid checksum.
162 		 */
163 		rsdp = (struct acpi_table_rsdp *)address;
164 
165 		/* BAD Signature */
166 		if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature))
167 			continue;
168 
169 		/* Check the standard checksum */
170 		if (compute_checksum((u8 *)rsdp, ACPI_RSDP_CHECKSUM_LENGTH))
171 			continue;
172 
173 		/* Check extended checksum if table version >= 2 */
174 		if ((rsdp->revision >= 2) &&
175 		    (compute_checksum((u8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)))
176 			continue;
177 
178 		/* Signature and checksum valid, we have found a real RSDP */
179 		return address;
180 	}
181 	return NULL;
182 }
183 
184 /* Search RSDP address in EBDA. */
185 static acpi_physical_address bios_get_rsdp_addr(void)
186 {
187 	unsigned long address;
188 	u8 *rsdp;
189 
190 	/* Get the location of the Extended BIOS Data Area (EBDA) */
191 	address = *(u16 *)ACPI_EBDA_PTR_LOCATION;
192 	address <<= 4;
193 
194 	/*
195 	 * Search EBDA paragraphs (EBDA is required to be a minimum of
196 	 * 1K length)
197 	 */
198 	if (address > 0x400) {
199 		rsdp = scan_mem_for_rsdp((u8 *)address, ACPI_EBDA_WINDOW_SIZE);
200 		if (rsdp)
201 			return (acpi_physical_address)(unsigned long)rsdp;
202 	}
203 
204 	/* Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
205 	rsdp = scan_mem_for_rsdp((u8 *) ACPI_HI_RSDP_WINDOW_BASE,
206 					ACPI_HI_RSDP_WINDOW_SIZE);
207 	if (rsdp)
208 		return (acpi_physical_address)(unsigned long)rsdp;
209 
210 	return 0;
211 }
212 
213 /* Return RSDP address on success, otherwise 0. */
214 acpi_physical_address get_rsdp_addr(void)
215 {
216 	acpi_physical_address pa;
217 
218 	pa = get_acpi_rsdp();
219 
220 	if (!pa)
221 		pa = boot_params->acpi_rsdp_addr;
222 
223 	if (!pa)
224 		pa = efi_get_rsdp_addr();
225 
226 	if (!pa)
227 		pa = bios_get_rsdp_addr();
228 
229 	return pa;
230 }
231 
232 #if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
233 /* Compute SRAT address from RSDP. */
234 static unsigned long get_acpi_srat_table(void)
235 {
236 	unsigned long root_table, acpi_table;
237 	struct acpi_table_header *header;
238 	struct acpi_table_rsdp *rsdp;
239 	u32 num_entries, size, len;
240 	char arg[10];
241 	u8 *entry;
242 
243 	rsdp = (struct acpi_table_rsdp *)(long)boot_params->acpi_rsdp_addr;
244 	if (!rsdp)
245 		return 0;
246 
247 	/* Get ACPI root table from RSDP.*/
248 	if (!(cmdline_find_option("acpi", arg, sizeof(arg)) == 4 &&
249 	    !strncmp(arg, "rsdt", 4)) &&
250 	    rsdp->xsdt_physical_address &&
251 	    rsdp->revision > 1) {
252 		root_table = rsdp->xsdt_physical_address;
253 		size = ACPI_XSDT_ENTRY_SIZE;
254 	} else {
255 		root_table = rsdp->rsdt_physical_address;
256 		size = ACPI_RSDT_ENTRY_SIZE;
257 	}
258 
259 	if (!root_table)
260 		return 0;
261 
262 	header = (struct acpi_table_header *)root_table;
263 	len = header->length;
264 	if (len < sizeof(struct acpi_table_header) + size)
265 		return 0;
266 
267 	num_entries = (len - sizeof(struct acpi_table_header)) / size;
268 	entry = (u8 *)(root_table + sizeof(struct acpi_table_header));
269 
270 	while (num_entries--) {
271 		if (size == ACPI_RSDT_ENTRY_SIZE)
272 			acpi_table = *(u32 *)entry;
273 		else
274 			acpi_table = *(u64 *)entry;
275 
276 		if (acpi_table) {
277 			header = (struct acpi_table_header *)acpi_table;
278 
279 			if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT))
280 				return acpi_table;
281 		}
282 		entry += size;
283 	}
284 	return 0;
285 }
286 
287 /**
288  * count_immovable_mem_regions - Parse SRAT and cache the immovable
289  * memory regions into the immovable_mem array.
290  *
291  * Return the number of immovable memory regions on success, 0 on failure:
292  *
293  * - Too many immovable memory regions
294  * - ACPI off or no SRAT found
295  * - No immovable memory region found.
296  */
297 int count_immovable_mem_regions(void)
298 {
299 	unsigned long table_addr, table_end, table;
300 	struct acpi_subtable_header *sub_table;
301 	struct acpi_table_header *table_header;
302 	char arg[MAX_ACPI_ARG_LENGTH];
303 	int num = 0;
304 
305 	if (cmdline_find_option("acpi", arg, sizeof(arg)) == 3 &&
306 	    !strncmp(arg, "off", 3))
307 		return 0;
308 
309 	table_addr = get_acpi_srat_table();
310 	if (!table_addr)
311 		return 0;
312 
313 	table_header = (struct acpi_table_header *)table_addr;
314 	table_end = table_addr + table_header->length;
315 	table = table_addr + sizeof(struct acpi_table_srat);
316 
317 	while (table + sizeof(struct acpi_subtable_header) < table_end) {
318 		sub_table = (struct acpi_subtable_header *)table;
319 		if (sub_table->type == ACPI_SRAT_TYPE_MEMORY_AFFINITY) {
320 			struct acpi_srat_mem_affinity *ma;
321 
322 			ma = (struct acpi_srat_mem_affinity *)sub_table;
323 			if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && ma->length) {
324 				immovable_mem[num].start = ma->base_address;
325 				immovable_mem[num].size = ma->length;
326 				num++;
327 			}
328 
329 			if (num >= MAX_NUMNODES*2) {
330 				debug_putstr("Too many immovable memory regions, aborting.\n");
331 				return 0;
332 			}
333 		}
334 		table += sub_table->length;
335 	}
336 	return num;
337 }
338 #endif /* CONFIG_RANDOMIZE_BASE && CONFIG_MEMORY_HOTREMOVE */
339