mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 01:04:19 +08:00
5e89c55e4e
The SBBR and ACPI specifications allow ACPI based systems that do not implement PSCI (eg systems with no EL3) to boot through the ACPI parking protocol specification[1]. This patch implements the ACPI parking protocol CPU operations, and adds code that eases parsing the parking protocol data structures to the ARM64 SMP initializion carried out at the same time as cpus enumeration. To wake-up the CPUs from the parked state, this patch implements a wakeup IPI for ARM64 (ie arch_send_wakeup_ipi_mask()) that mirrors the ARM one, so that a specific IPI is sent for wake-up purpose in order to distinguish it from other IPI sources. Given the current ACPI MADT parsing API, the patch implements a glue layer that helps passing MADT GICC data structure from SMP initialization code to the parking protocol implementation somewhat overriding the CPU operations interfaces. This to avoid creating a completely trasparent DT/ACPI CPU operations layer that would require creating opaque structure handling for CPUs data (DT represents CPU through DT nodes, ACPI through static MADT table entries), which seems overkill given that ACPI on ARM64 mandates only two booting protocols (PSCI and parking protocol), so there is no need for further protocol additions. Based on the original work by Mark Salter <msalter@redhat.com> [1] https://acpica.org/sites/acpica/files/MP%20Startup%20for%20ARM%20platforms.docx Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Tested-by: Loc Ho <lho@apm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Hanjun Guo <hanjun.guo@linaro.org> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mark Salter <msalter@redhat.com> Cc: Al Stone <ahs3@redhat.com> [catalin.marinas@arm.com: Added WARN_ONCE(!acpi_parking_protocol_valid() on the IPI] Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
117 lines
3.0 KiB
C
117 lines
3.0 KiB
C
/*
|
|
* Copyright (C) 2013-2014, Linaro Ltd.
|
|
* Author: Al Stone <al.stone@linaro.org>
|
|
* Author: Graeme Gregory <graeme.gregory@linaro.org>
|
|
* Author: Hanjun Guo <hanjun.guo@linaro.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation;
|
|
*/
|
|
|
|
#ifndef _ASM_ACPI_H
|
|
#define _ASM_ACPI_H
|
|
|
|
#include <linux/mm.h>
|
|
#include <linux/psci.h>
|
|
|
|
#include <asm/cputype.h>
|
|
#include <asm/smp_plat.h>
|
|
|
|
/* Macros for consistency checks of the GICC subtable of MADT */
|
|
#define ACPI_MADT_GICC_LENGTH \
|
|
(acpi_gbl_FADT.header.revision < 6 ? 76 : 80)
|
|
|
|
#define BAD_MADT_GICC_ENTRY(entry, end) \
|
|
(!(entry) || (unsigned long)(entry) + sizeof(*(entry)) > (end) || \
|
|
(entry)->header.length != ACPI_MADT_GICC_LENGTH)
|
|
|
|
/* Basic configuration for ACPI */
|
|
#ifdef CONFIG_ACPI
|
|
/* ACPI table mapping after acpi_gbl_permanent_mmap is set */
|
|
static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
|
|
acpi_size size)
|
|
{
|
|
if (!page_is_ram(phys >> PAGE_SHIFT))
|
|
return ioremap(phys, size);
|
|
|
|
return ioremap_cache(phys, size);
|
|
}
|
|
#define acpi_os_ioremap acpi_os_ioremap
|
|
|
|
typedef u64 phys_cpuid_t;
|
|
#define PHYS_CPUID_INVALID INVALID_HWID
|
|
|
|
#define acpi_strict 1 /* No out-of-spec workarounds on ARM64 */
|
|
extern int acpi_disabled;
|
|
extern int acpi_noirq;
|
|
extern int acpi_pci_disabled;
|
|
|
|
static inline void disable_acpi(void)
|
|
{
|
|
acpi_disabled = 1;
|
|
acpi_pci_disabled = 1;
|
|
acpi_noirq = 1;
|
|
}
|
|
|
|
static inline void enable_acpi(void)
|
|
{
|
|
acpi_disabled = 0;
|
|
acpi_pci_disabled = 0;
|
|
acpi_noirq = 0;
|
|
}
|
|
|
|
/*
|
|
* The ACPI processor driver for ACPI core code needs this macro
|
|
* to find out this cpu was already mapped (mapping from CPU hardware
|
|
* ID to CPU logical ID) or not.
|
|
*/
|
|
#define cpu_physical_id(cpu) cpu_logical_map(cpu)
|
|
|
|
/*
|
|
* It's used from ACPI core in kdump to boot UP system with SMP kernel,
|
|
* with this check the ACPI core will not override the CPU index
|
|
* obtained from GICC with 0 and not print some error message as well.
|
|
* Since MADT must provide at least one GICC structure for GIC
|
|
* initialization, CPU will be always available in MADT on ARM64.
|
|
*/
|
|
static inline bool acpi_has_cpu_in_madt(void)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static inline void arch_fix_phys_package_id(int num, u32 slot) { }
|
|
void __init acpi_init_cpus(void);
|
|
|
|
#else
|
|
static inline void acpi_init_cpus(void) { }
|
|
#endif /* CONFIG_ACPI */
|
|
|
|
#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
|
|
bool acpi_parking_protocol_valid(int cpu);
|
|
void __init
|
|
acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor);
|
|
#else
|
|
static inline bool acpi_parking_protocol_valid(int cpu) { return false; }
|
|
static inline void
|
|
acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor)
|
|
{}
|
|
#endif
|
|
|
|
static inline const char *acpi_get_enable_method(int cpu)
|
|
{
|
|
if (acpi_psci_present())
|
|
return "psci";
|
|
|
|
if (acpi_parking_protocol_valid(cpu))
|
|
return "parking-protocol";
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef CONFIG_ACPI_APEI
|
|
pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
|
|
#endif
|
|
|
|
#endif /*_ASM_ACPI_H*/
|