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 * 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
  29static 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. */
  48static 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
 136static 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. */
 148static 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. */
 185static 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. */
 214acpi_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. */
 234static 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 */
 297int 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