[PATCH v3 13/62] arm/acpi: Parse FADT table and get PSCI flags
Stefano Stabellini
stefano.stabellini at eu.citrix.com
Mon Nov 23 04:42:09 PST 2015
On Tue, 17 Nov 2015, shannon.zhao at linaro.org wrote:
> From: Shannon Zhao <shannon.zhao at linaro.org>
>
> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
> the former signals to the OS that the hardware is PSCI compliant.
> The latter selects the appropriate conduit for PSCI calls by
> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
> (SMC).
>
> FADT table contains such information, parse FADT to get the flags
> for furture usage. At the same time, only ACPI 5.1 or higher verison
> supports PSCI, and FADT Major.Minor version was introduced in ACPI
> 5.1, but for Xen it needs FADT hypervisor_id introduced by ACPI 6.0 to
> tell Dom0 that it runs on Xen hypervisor, so we will check the version
> and only parse FADT table with version >= 6.0.
>
> If firmware provides ACPI tables with ACPI version less than 6.0,
> OS will be messed up with those information, so disable ACPI if we
> get an FADT table with version less that 6.0.
>
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> Signed-off-by: Naresh Bhat <naresh.bhat at linaro.org>
> Signed-off-by: Parth Dixit <parth.dixit at linaro.org>
> Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> ---
> xen/arch/arm/acpi/boot.c | 31 +++++++++++++++++++++++++++++++
> xen/arch/arm/acpi/lib.c | 12 ++++++++++++
> xen/include/asm-arm/acpi.h | 9 +++++++++
> 3 files changed, 52 insertions(+)
>
> diff --git a/xen/arch/arm/acpi/boot.c b/xen/arch/arm/acpi/boot.c
> index ad51afc..0fabe7d 100644
> --- a/xen/arch/arm/acpi/boot.c
> +++ b/xen/arch/arm/acpi/boot.c
> @@ -27,9 +27,33 @@
>
> #include <xen/init.h>
> #include <xen/acpi.h>
> +#include <xen/errno.h>
> +#include <acpi/actables.h>
> +#include <xen/mm.h>
>
> #include <asm/acpi.h>
>
> +static int __init acpi_parse_fadt(struct acpi_table_header *table)
> +{
> + struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
> +
> + /*
> + * Revision in table header is the FADT Major revision, and there
> + * is a minor revision of FADT which was introduced by ACPI 6.0,
> + * we only deal with ACPI 6.0 or newer revision to get GIC and SMP
> + * boot protocol configuration data, or we will disable ACPI.
> + */
> + if ( table->revision > 6
> + || (table->revision == 6 && fadt->minor_revision >= 0) )
> + return 0;
> +
> + printk("Unsupported FADT revision %d.%d, should be 6.0+, will disable ACPI\n",
> + table->revision, fadt->minor_revision);
> + disable_acpi();
This call to disable_acpi is redundant, given the other call below
> + return -EINVAL;
> +}
> +
> /*
> * acpi_boot_table_init() called from setup_arch(), always.
> * 1. find RSDP and get its address, and then find XSDT
> @@ -58,5 +82,12 @@ int __init acpi_boot_table_init(void)
> return error;
> }
>
> + if ( acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) )
> + {
> + /* disable ACPI if no FADT is found */
> + disable_acpi();
> + printk("Can't find FADT\n");
> + }
> +
> return 0;
> }
> diff --git a/xen/arch/arm/acpi/lib.c b/xen/arch/arm/acpi/lib.c
> index b68623b..d8b7635 100644
> --- a/xen/arch/arm/acpi/lib.c
> +++ b/xen/arch/arm/acpi/lib.c
> @@ -31,3 +31,15 @@ arch_acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
> {
> return __va(phys);
> }
> +
> +/* 1 to indicate PSCI 0.2+ is implemented */
> +bool_t __init acpi_psci_present(void)
> +{
> + return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;
> +}
> +
> +/* 1 to indicate HVC is present instead of SMC as the PSCI conduit */
> +bool_t __init acpi_psci_hvc_present(void)
> +{
> + return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
> +}
> diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h
> index e41e03b..65f80b1 100644
> --- a/xen/include/asm-arm/acpi.h
> +++ b/xen/include/asm-arm/acpi.h
> @@ -29,6 +29,15 @@
> #define COMPILER_DEPENDENT_UINT64 unsigned long long
>
> extern bool_t acpi_disabled;
> +
> +#ifdef CONFIG_ACPI
> +bool_t __init acpi_psci_present(void);
> +bool_t __init acpi_psci_hvc_present(void);
> +#else
> +static inline bool_t acpi_psci_present(void) { return false; }
> +static inline bool_t acpi_psci_hvc_present(void) {return false; }
> +#endif /* CONFIG_ACPI */
It doesn't look like this is necessary on x86, acpi_gbl_FADT is used in
a few places, including xen/arch/x86/time.c, without checking for
CONFIG_ACPI or HAS_ACPI. Is the x86 code wrong?
> /* Basic configuration for ACPI */
> static inline void disable_acpi(void)
> {
> --
> 2.1.0
>
More information about the linux-arm-kernel
mailing list