@@ -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();
+
+ 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;
}
@@ -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;
+}
@@ -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 */
+
/* Basic configuration for ACPI */
static inline void disable_acpi(void)
{