linux/arch/x86/boot/compressed/acpi.c
<<
>>
Prefs
   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 */
  21struct mem_vector immovable_mem[MAX_NUMNODES*2];
  22
  23/*
  24 * Search EFI system tables for RSDP.  If both ACPI_20_TABLE_GUID and
  25 * ACPI_TABLE_GUID are found, take the former, which has more features.
  26 */
  27static acpi_physical_address
  28__efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables,
  29                    bool efi_64)
  30{
  31        acpi_physical_address rsdp_addr = 0;
  32
  33#ifdef CONFIG_EFI
  34        int i;
  35
  36        /* Get EFI tables from systab. */
  37        for (i = 0; i < nr_tables; i++) {
  38                acpi_physical_address table;
  39                efi_guid_t guid;
  40
  41                if (efi_64) {
  42                        efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables + i;
  43
  44                        guid  = tbl->guid;
  45                        table = tbl->table;
  46
  47                        if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
  48                                debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n");
  49                                return 0;
  50                        }
  51                } else {
  52                        efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables + i;
  53
  54                        guid  = tbl->guid;
  55                        table = tbl->table;
  56                }
  57
  58                if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))
  59                        rsdp_addr = table;
  60                else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
  61                        return table;
  62        }
  63#endif
  64        return rsdp_addr;
  65}
  66
  67/* EFI/kexec support is 64-bit only. */
  68#ifdef CONFIG_X86_64
  69static struct efi_setup_data *get_kexec_setup_data_addr(void)
  70{
  71        struct setup_data *data;
  72        u64 pa_data;
  73
  74        pa_data = boot_params->hdr.setup_data;
  75        while (pa_data) {
  76                data = (struct setup_data *)pa_data;
  77                if (data->type == SETUP_EFI)
  78                        return (struct efi_setup_data *)(pa_data + sizeof(struct setup_data));
  79
  80                pa_data = data->next;
  81        }
  82        return NULL;
  83}
  84
  85static acpi_physical_address kexec_get_rsdp_addr(void)
  86{
  87        efi_system_table_64_t *systab;
  88        struct efi_setup_data *esd;
  89        struct efi_info *ei;
  90        char *sig;
  91
  92        esd = (struct efi_setup_data *)get_kexec_setup_data_addr();
  93        if (!esd)
  94                return 0;
  95
  96        if (!esd->tables) {
  97                debug_putstr("Wrong kexec SETUP_EFI data.\n");
  98                return 0;
  99        }
 100
 101        ei = &boot_params->efi_info;
 102        sig = (char *)&ei->efi_loader_signature;
 103        if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
 104                debug_putstr("Wrong kexec EFI loader signature.\n");
 105                return 0;
 106        }
 107
 108        /* Get systab from boot params. */
 109        systab = (efi_system_table_64_t *) (ei->efi_systab | ((__u64)ei->efi_systab_hi << 32));
 110        if (!systab)
 111                error("EFI system table not found in kexec boot_params.");
 112
 113        return __efi_get_rsdp_addr((unsigned long)esd->tables, systab->nr_tables, true);
 114}
 115#else
 116static acpi_physical_address kexec_get_rsdp_addr(void) { return 0; }
 117#endif /* CONFIG_X86_64 */
 118
 119static acpi_physical_address efi_get_rsdp_addr(void)
 120{
 121#ifdef CONFIG_EFI
 122        unsigned long systab, config_tables;
 123        unsigned int nr_tables;
 124        struct efi_info *ei;
 125        bool efi_64;
 126        char *sig;
 127
 128        ei = &boot_params->efi_info;
 129        sig = (char *)&ei->efi_loader_signature;
 130
 131        if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
 132                efi_64 = true;
 133        } else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) {
 134                efi_64 = false;
 135        } else {
 136                debug_putstr("Wrong EFI loader signature.\n");
 137                return 0;
 138        }
 139
 140        /* Get systab from boot params. */
 141#ifdef CONFIG_X86_64
 142        systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
 143#else
 144        if (ei->efi_systab_hi || ei->efi_memmap_hi) {
 145                debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
 146                return 0;
 147        }
 148        systab = ei->efi_systab;
 149#endif
 150        if (!systab)
 151                error("EFI system table not found.");
 152
 153        /* Handle EFI bitness properly */
 154        if (efi_64) {
 155                efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab;
 156
 157                config_tables   = stbl->tables;
 158                nr_tables       = stbl->nr_tables;
 159        } else {
 160                efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
 161
 162                config_tables   = stbl->tables;
 163                nr_tables       = stbl->nr_tables;
 164        }
 165
 166        if (!config_tables)
 167                error("EFI config tables not found.");
 168
 169        return __efi_get_rsdp_addr(config_tables, nr_tables, efi_64);
 170#else
 171        return 0;
 172#endif
 173}
 174
 175static u8 compute_checksum(u8 *buffer, u32 length)
 176{
 177        u8 *end = buffer + length;
 178        u8 sum = 0;
 179
 180        while (buffer < end)
 181                sum += *(buffer++);
 182
 183        return sum;
 184}
 185
 186/* Search a block of memory for the RSDP signature. */
 187static u8 *scan_mem_for_rsdp(u8 *start, u32 length)
 188{
 189        struct acpi_table_rsdp *rsdp;
 190        u8 *address, *end;
 191
 192        end = start + length;
 193
 194        /* Search from given start address for the requested length */
 195        for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) {
 196                /*
 197                 * Both RSDP signature and checksum must be correct.
 198                 * Note: Sometimes there exists more than one RSDP in memory;
 199                 * the valid RSDP has a valid checksum, all others have an
 200                 * invalid checksum.
 201                 */
 202                rsdp = (struct acpi_table_rsdp *)address;
 203
 204                /* BAD Signature */
 205                if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature))
 206                        continue;
 207
 208                /* Check the standard checksum */
 209                if (compute_checksum((u8 *)rsdp, ACPI_RSDP_CHECKSUM_LENGTH))
 210                        continue;
 211
 212                /* Check extended checksum if table version >= 2 */
 213                if ((rsdp->revision >= 2) &&
 214                    (compute_checksum((u8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)))
 215                        continue;
 216
 217                /* Signature and checksum valid, we have found a real RSDP */
 218                return address;
 219        }
 220        return NULL;
 221}
 222
 223/* Search RSDP address in EBDA. */
 224static acpi_physical_address bios_get_rsdp_addr(void)
 225{
 226        unsigned long address;
 227        u8 *rsdp;
 228
 229        /* Get the location of the Extended BIOS Data Area (EBDA) */
 230        address = *(u16 *)ACPI_EBDA_PTR_LOCATION;
 231        address <<= 4;
 232
 233        /*
 234         * Search EBDA paragraphs (EBDA is required to be a minimum of
 235         * 1K length)
 236         */
 237        if (address > 0x400) {
 238                rsdp = scan_mem_for_rsdp((u8 *)address, ACPI_EBDA_WINDOW_SIZE);
 239                if (rsdp)
 240                        return (acpi_physical_address)(unsigned long)rsdp;
 241        }
 242
 243        /* Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
 244        rsdp = scan_mem_for_rsdp((u8 *) ACPI_HI_RSDP_WINDOW_BASE,
 245                                        ACPI_HI_RSDP_WINDOW_SIZE);
 246        if (rsdp)
 247                return (acpi_physical_address)(unsigned long)rsdp;
 248
 249        return 0;
 250}
 251
 252/* Return RSDP address on success, otherwise 0. */
 253acpi_physical_address get_rsdp_addr(void)
 254{
 255        acpi_physical_address pa;
 256
 257        pa = boot_params->acpi_rsdp_addr;
 258
 259        /*
 260         * Try to get EFI data from setup_data. This can happen when we're a
 261         * kexec'ed kernel and kexec(1) has passed all the required EFI info to
 262         * us.
 263         */
 264        if (!pa)
 265                pa = kexec_get_rsdp_addr();
 266
 267        if (!pa)
 268                pa = efi_get_rsdp_addr();
 269
 270        if (!pa)
 271                pa = bios_get_rsdp_addr();
 272
 273        return pa;
 274}
 275
 276#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
 277/*
 278 * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
 279 * digits, and '\0' for termination.
 280 */
 281#define MAX_ADDR_LEN 19
 282
 283static unsigned long get_cmdline_acpi_rsdp(void)
 284{
 285        unsigned long addr = 0;
 286
 287#ifdef CONFIG_KEXEC
 288        char val[MAX_ADDR_LEN] = { };
 289        int ret;
 290
 291        ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN);
 292        if (ret < 0)
 293                return 0;
 294
 295        if (boot_kstrtoul(val, 16, &addr))
 296                return 0;
 297#endif
 298        return addr;
 299}
 300
 301/* Compute SRAT address from RSDP. */
 302static unsigned long get_acpi_srat_table(void)
 303{
 304        unsigned long root_table, acpi_table;
 305        struct acpi_table_header *header;
 306        struct acpi_table_rsdp *rsdp;
 307        u32 num_entries, size, len;
 308        char arg[10];
 309        u8 *entry;
 310
 311        /*
 312         * Check whether we were given an RSDP on the command line. We don't
 313         * stash this in boot params because the kernel itself may have
 314         * different ideas about whether to trust a command-line parameter.
 315         */
 316        rsdp = (struct acpi_table_rsdp *)get_cmdline_acpi_rsdp();
 317        if (!rsdp)
 318                rsdp = (struct acpi_table_rsdp *)(long)
 319                        boot_params->acpi_rsdp_addr;
 320
 321        if (!rsdp)
 322                return 0;
 323
 324        /* Get ACPI root table from RSDP.*/
 325        if (!(cmdline_find_option("acpi", arg, sizeof(arg)) == 4 &&
 326            !strncmp(arg, "rsdt", 4)) &&
 327            rsdp->xsdt_physical_address &&
 328            rsdp->revision > 1) {
 329                root_table = rsdp->xsdt_physical_address;
 330                size = ACPI_XSDT_ENTRY_SIZE;
 331        } else {
 332                root_table = rsdp->rsdt_physical_address;
 333                size = ACPI_RSDT_ENTRY_SIZE;
 334        }
 335
 336        if (!root_table)
 337                return 0;
 338
 339        header = (struct acpi_table_header *)root_table;
 340        len = header->length;
 341        if (len < sizeof(struct acpi_table_header) + size)
 342                return 0;
 343
 344        num_entries = (len - sizeof(struct acpi_table_header)) / size;
 345        entry = (u8 *)(root_table + sizeof(struct acpi_table_header));
 346
 347        while (num_entries--) {
 348                if (size == ACPI_RSDT_ENTRY_SIZE)
 349                        acpi_table = *(u32 *)entry;
 350                else
 351                        acpi_table = *(u64 *)entry;
 352
 353                if (acpi_table) {
 354                        header = (struct acpi_table_header *)acpi_table;
 355
 356                        if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT))
 357                                return acpi_table;
 358                }
 359                entry += size;
 360        }
 361        return 0;
 362}
 363
 364/**
 365 * count_immovable_mem_regions - Parse SRAT and cache the immovable
 366 * memory regions into the immovable_mem array.
 367 *
 368 * Return the number of immovable memory regions on success, 0 on failure:
 369 *
 370 * - Too many immovable memory regions
 371 * - ACPI off or no SRAT found
 372 * - No immovable memory region found.
 373 */
 374int count_immovable_mem_regions(void)
 375{
 376        unsigned long table_addr, table_end, table;
 377        struct acpi_subtable_header *sub_table;
 378        struct acpi_table_header *table_header;
 379        char arg[MAX_ACPI_ARG_LENGTH];
 380        int num = 0;
 381
 382        if (cmdline_find_option("acpi", arg, sizeof(arg)) == 3 &&
 383            !strncmp(arg, "off", 3))
 384                return 0;
 385
 386        table_addr = get_acpi_srat_table();
 387        if (!table_addr)
 388                return 0;
 389
 390        table_header = (struct acpi_table_header *)table_addr;
 391        table_end = table_addr + table_header->length;
 392        table = table_addr + sizeof(struct acpi_table_srat);
 393
 394        while (table + sizeof(struct acpi_subtable_header) < table_end) {
 395
 396                sub_table = (struct acpi_subtable_header *)table;
 397                if (!sub_table->length) {
 398                        debug_putstr("Invalid zero length SRAT subtable.\n");
 399                        return 0;
 400                }
 401
 402                if (sub_table->type == ACPI_SRAT_TYPE_MEMORY_AFFINITY) {
 403                        struct acpi_srat_mem_affinity *ma;
 404
 405                        ma = (struct acpi_srat_mem_affinity *)sub_table;
 406                        if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && ma->length) {
 407                                immovable_mem[num].start = ma->base_address;
 408                                immovable_mem[num].size = ma->length;
 409                                num++;
 410                        }
 411
 412                        if (num >= MAX_NUMNODES*2) {
 413                                debug_putstr("Too many immovable memory regions, aborting.\n");
 414                                return 0;
 415                        }
 416                }
 417                table += sub_table->length;
 418        }
 419        return num;
 420}
 421#endif /* CONFIG_RANDOMIZE_BASE && CONFIG_MEMORY_HOTREMOVE */
 422