// SPDX-License-Identifier: GPL-2.0-only1/*2* ARM64 Specific Low-Level ACPI Boot Support3*4* Copyright (C) 2013-2014, Linaro Ltd.5* Author: Al Stone <[email protected]>6* Author: Graeme Gregory <[email protected]>7* Author: Hanjun Guo <[email protected]>8* Author: Tomasz Nowicki <[email protected]>9* Author: Naresh Bhat <[email protected]>10*/1112#define pr_fmt(fmt) "ACPI: " fmt1314#include <linux/acpi.h>15#include <linux/arm-smccc.h>16#include <linux/cpumask.h>17#include <linux/efi.h>18#include <linux/efi-bgrt.h>19#include <linux/init.h>20#include <linux/irq.h>21#include <linux/irqdomain.h>22#include <linux/irq_work.h>23#include <linux/memblock.h>24#include <linux/of_fdt.h>25#include <linux/libfdt.h>26#include <linux/smp.h>27#include <linux/serial_core.h>28#include <linux/suspend.h>29#include <linux/pgtable.h>3031#include <acpi/ghes.h>32#include <acpi/processor.h>33#include <asm/cputype.h>34#include <asm/cpu_ops.h>35#include <asm/daifflags.h>36#include <asm/smp_plat.h>3738int acpi_noirq = 1; /* skip ACPI IRQ initialization */39int acpi_disabled = 1;40EXPORT_SYMBOL(acpi_disabled);4142int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */43EXPORT_SYMBOL(acpi_pci_disabled);4445static bool param_acpi_off __initdata;46static bool param_acpi_on __initdata;47static bool param_acpi_force __initdata;48static bool param_acpi_nospcr __initdata;4950static int __init parse_acpi(char *arg)51{52if (!arg)53return -EINVAL;5455/* "acpi=off" disables both ACPI table parsing and interpreter */56if (strcmp(arg, "off") == 0)57param_acpi_off = true;58else if (strcmp(arg, "on") == 0) /* prefer ACPI over DT */59param_acpi_on = true;60else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */61param_acpi_force = true;62else if (strcmp(arg, "nospcr") == 0) /* disable SPCR as default console */63param_acpi_nospcr = true;64else65return -EINVAL; /* Core will print when we return error */6667return 0;68}69early_param("acpi", parse_acpi);7071static bool __init dt_is_stub(void)72{73int node;7475fdt_for_each_subnode(node, initial_boot_params, 0) {76const char *name = fdt_get_name(initial_boot_params, node, NULL);77if (strcmp(name, "chosen") == 0)78continue;79if (strcmp(name, "hypervisor") == 0 &&80of_flat_dt_is_compatible(node, "xen,xen"))81continue;8283return false;84}8586return true;87}8889/*90* __acpi_map_table() will be called before page_init(), so early_ioremap()91* or early_memremap() should be called here to for ACPI table mapping.92*/93void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)94{95if (!size)96return NULL;9798return early_memremap(phys, size);99}100101void __init __acpi_unmap_table(void __iomem *map, unsigned long size)102{103if (!map || !size)104return;105106early_memunmap(map, size);107}108109bool __init acpi_psci_present(void)110{111return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;112}113114/* Whether HVC must be used instead of SMC as the PSCI conduit */115bool acpi_psci_use_hvc(void)116{117return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;118}119120/*121* acpi_fadt_sanity_check() - Check FADT presence and carry out sanity122* checks on it123*124* Return 0 on success, <0 on failure125*/126static int __init acpi_fadt_sanity_check(void)127{128struct acpi_table_header *table;129struct acpi_table_fadt *fadt;130acpi_status status;131int ret = 0;132133/*134* FADT is required on arm64; retrieve it to check its presence135* and carry out revision and ACPI HW reduced compliance tests136*/137status = acpi_get_table(ACPI_SIG_FADT, 0, &table);138if (ACPI_FAILURE(status)) {139const char *msg = acpi_format_exception(status);140141pr_err("Failed to get FADT table, %s\n", msg);142return -ENODEV;143}144145fadt = (struct acpi_table_fadt *)table;146147/*148* Revision in table header is the FADT Major revision, and there149* is a minor revision of FADT which was introduced by ACPI 5.1,150* we only deal with ACPI 5.1 or newer revision to get GIC and SMP151* boot protocol configuration data.152*/153if (table->revision < 5 ||154(table->revision == 5 && fadt->minor_revision < 1)) {155pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 5.1+\n",156table->revision, fadt->minor_revision);157158if (!fadt->arm_boot_flags) {159ret = -EINVAL;160goto out;161}162pr_err("FADT has ARM boot flags set, assuming 5.1\n");163}164165if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {166pr_err("FADT not ACPI hardware reduced compliant\n");167ret = -EINVAL;168}169170out:171/*172* acpi_get_table() creates FADT table mapping that173* should be released after parsing and before resuming boot174*/175acpi_put_table(table);176return ret;177}178179/*180* acpi_boot_table_init() called from setup_arch(), always.181* 1. find RSDP and get its address, and then find XSDT182* 2. extract all tables and checksums them all183* 3. check ACPI FADT revision184* 4. check ACPI FADT HW reduced flag185*186* We can parse ACPI boot-time tables such as MADT after187* this function is called.188*189* On return ACPI is enabled if either:190*191* - ACPI tables are initialized and sanity checks passed192* - acpi=force was passed in the command line and ACPI was not disabled193* explicitly through acpi=off command line parameter194*195* ACPI is disabled on function return otherwise196*/197void __init acpi_boot_table_init(void)198{199/*200* Enable ACPI instead of device tree unless201* - ACPI has been disabled explicitly (acpi=off), or202* - the device tree is not empty (it has more than just a /chosen node,203* and a /hypervisor node when running on Xen)204* and ACPI has not been [force] enabled (acpi=on|force)205*/206if (param_acpi_off ||207(!param_acpi_on && !param_acpi_force && !dt_is_stub()))208goto done;209210/*211* ACPI is disabled at this point. Enable it in order to parse212* the ACPI tables and carry out sanity checks213*/214enable_acpi();215216/*217* If ACPI tables are initialized and FADT sanity checks passed,218* leave ACPI enabled and carry on booting; otherwise disable ACPI219* on initialization error.220* If acpi=force was passed on the command line it forces ACPI221* to be enabled even if its initialization failed.222*/223if (acpi_table_init() || acpi_fadt_sanity_check()) {224pr_err("Failed to init ACPI tables\n");225if (!param_acpi_force)226disable_acpi();227}228229done:230if (acpi_disabled) {231if (earlycon_acpi_spcr_enable)232early_init_dt_scan_chosen_stdout();233} else {234#ifdef CONFIG_HIBERNATION235struct acpi_table_header *facs = NULL;236acpi_get_table(ACPI_SIG_FACS, 1, &facs);237if (facs) {238swsusp_hardware_signature =239((struct acpi_table_facs *)facs)->hardware_signature;240acpi_put_table(facs);241}242#endif243244/*245* For varying privacy and security reasons, sometimes need246* to completely silence the serial console output, and only247* enable it when needed.248* But there are many existing systems that depend on this249* behaviour, use acpi=nospcr to disable console in ACPI SPCR250* table as default serial console.251*/252acpi_parse_spcr(earlycon_acpi_spcr_enable,253!param_acpi_nospcr);254255if (IS_ENABLED(CONFIG_ACPI_BGRT))256acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);257}258}259260static pgprot_t __acpi_get_writethrough_mem_attribute(void)261{262/*263* Although UEFI specifies the use of Normal Write-through for264* EFI_MEMORY_WT, it is seldom used in practice and not implemented265* by most (all?) CPUs. Rather than allocate a MAIR just for this266* purpose, emit a warning and use Normal Non-cacheable instead.267*/268pr_warn_once("No MAIR allocation for EFI_MEMORY_WT; treating as Normal Non-cacheable\n");269return __pgprot(PROT_NORMAL_NC);270}271272pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)273{274/*275* According to "Table 8 Map: EFI memory types to AArch64 memory276* types" of UEFI 2.5 section 2.3.6.1, each EFI memory type is277* mapped to a corresponding MAIR attribute encoding.278* The EFI memory attribute advises all possible capabilities279* of a memory region.280*/281282u64 attr;283284attr = efi_mem_attributes(addr);285if (attr & EFI_MEMORY_WB)286return PAGE_KERNEL;287if (attr & EFI_MEMORY_WC)288return __pgprot(PROT_NORMAL_NC);289if (attr & EFI_MEMORY_WT)290return __acpi_get_writethrough_mem_attribute();291return __pgprot(PROT_DEVICE_nGnRnE);292}293294void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)295{296efi_memory_desc_t *md, *region = NULL;297pgprot_t prot;298299if (WARN_ON_ONCE(!efi_enabled(EFI_MEMMAP)))300return NULL;301302for_each_efi_memory_desc(md) {303u64 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);304305if (phys < md->phys_addr || phys >= end)306continue;307308if (phys + size > end) {309pr_warn(FW_BUG "requested region covers multiple EFI memory regions\n");310return NULL;311}312region = md;313break;314}315316/*317* It is fine for AML to remap regions that are not represented in the318* EFI memory map at all, as it only describes normal memory, and MMIO319* regions that require a virtual mapping to make them accessible to320* the EFI runtime services.321*/322prot = __pgprot(PROT_DEVICE_nGnRnE);323if (region) {324switch (region->type) {325case EFI_LOADER_CODE:326case EFI_LOADER_DATA:327case EFI_BOOT_SERVICES_CODE:328case EFI_BOOT_SERVICES_DATA:329case EFI_CONVENTIONAL_MEMORY:330case EFI_PERSISTENT_MEMORY:331if (memblock_is_map_memory(phys) ||332!memblock_is_region_memory(phys, size)) {333pr_warn(FW_BUG "requested region covers kernel memory @ %pa\n", &phys);334return NULL;335}336/*337* Mapping kernel memory is permitted if the region in338* question is covered by a single memblock with the339* NOMAP attribute set: this enables the use of ACPI340* table overrides passed via initramfs, which are341* reserved in memory using arch_reserve_mem_area()342* below. As this particular use case only requires343* read access, fall through to the R/O mapping case.344*/345fallthrough;346347case EFI_RUNTIME_SERVICES_CODE:348/*349* This would be unusual, but not problematic per se,350* as long as we take care not to create a writable351* mapping for executable code.352*/353prot = PAGE_KERNEL_RO;354break;355356case EFI_ACPI_RECLAIM_MEMORY:357/*358* ACPI reclaim memory is used to pass firmware tables359* and other data that is intended for consumption by360* the OS only, which may decide it wants to reclaim361* that memory and use it for something else. We never362* do that, but we usually add it to the linear map363* anyway, in which case we should use the existing364* mapping.365*/366if (memblock_is_map_memory(phys))367return (void __iomem *)__phys_to_virt(phys);368fallthrough;369370default:371if (region->attribute & EFI_MEMORY_WB)372prot = PAGE_KERNEL;373else if (region->attribute & EFI_MEMORY_WC)374prot = __pgprot(PROT_NORMAL_NC);375else if (region->attribute & EFI_MEMORY_WT)376prot = __acpi_get_writethrough_mem_attribute();377}378}379return ioremap_prot(phys, size, prot);380}381382/*383* Claim Synchronous External Aborts as a firmware first notification.384*385* Used by KVM and the arch do_sea handler.386* @regs may be NULL when called from process context.387*/388int apei_claim_sea(struct pt_regs *regs)389{390int err = -ENOENT;391bool return_to_irqs_enabled;392unsigned long current_flags;393394if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES))395return err;396397current_flags = local_daif_save_flags();398399/* current_flags isn't useful here as daif doesn't tell us about pNMI */400return_to_irqs_enabled = !irqs_disabled_flags(arch_local_save_flags());401402if (regs)403return_to_irqs_enabled = !regs_irqs_disabled(regs);404405/*406* SEA can interrupt SError, mask it and describe this as an NMI so407* that APEI defers the handling.408*/409local_daif_restore(DAIF_ERRCTX);410nmi_enter();411err = ghes_notify_sea();412nmi_exit();413414/*415* APEI NMI-like notifications are deferred to irq_work. Unless416* we interrupted irqs-masked code, we can do that now.417*/418if (!err) {419if (return_to_irqs_enabled) {420local_daif_restore(DAIF_PROCCTX_NOIRQ);421__irq_enter();422irq_work_run();423__irq_exit();424} else {425pr_warn_ratelimited("APEI work queued but not completed\n");426err = -EINPROGRESS;427}428}429430local_daif_restore(current_flags);431432return err;433}434435void arch_reserve_mem_area(acpi_physical_address addr, size_t size)436{437memblock_mark_nomap(addr, size);438}439440#ifdef CONFIG_ACPI_HOTPLUG_CPU441int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,442int *pcpu)443{444/* If an error code is passed in this stub can't fix it */445if (*pcpu < 0) {446pr_warn_once("Unable to map CPU to valid ID\n");447return *pcpu;448}449450return 0;451}452EXPORT_SYMBOL(acpi_map_cpu);453454int acpi_unmap_cpu(int cpu)455{456return 0;457}458EXPORT_SYMBOL(acpi_unmap_cpu);459#endif /* CONFIG_ACPI_HOTPLUG_CPU */460461462