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