smccc_conduit_fn_t smccc_psci_call;
-static void _dtb_get_psci_method(void *fdt)
+#ifdef CONFIG_UKPLAT_ACPI
+static int get_psci_method(struct ukplat_bootinfo *bi __unused)
+{
+ struct acpi_fadt *acpi_fadt = acpi_get_fadt();
+
+ if (unlikely(!acpi_fadt))
+ return -ENOTSUP;
+
+ if (unlikely(!(acpi_fadt->arm_bflags & ACPI_FADT_ARM_BFLAGS_PSCI)))
+ return -ENOTSUP;
+
+ if (acpi_fadt->arm_bflags & ACPI_FADT_ARM_BFLAGS_PSCI_HVC)
+ smccc_psci_call = smccc_hvc;
+ else
+ smccc_psci_call = smccc_smc;
+
+ return 0;
+}
+#else
+static int get_psci_method(struct ukplat_bootinfo *bi)
{
- int fdtpsci, len;
const char *fdtmethod;
+ int fdtpsci, len;
+ void *fdt;
+
+ fdt = (void *)bi->dtb;
+ UK_ASSERT(bi->dtb);
/*
* We just support PSCI-0.2 and PSCI-1.0, the PSCI-0.1 would not
* be supported.
*/
- fdtpsci = fdt_node_offset_by_compatible(fdt, -1,
- "arm,psci-1.0");
- if (fdtpsci < 0)
- fdtpsci = fdt_node_offset_by_compatible(fdt,
- -1, "arm,psci-0.2");
+ fdtpsci = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-1.0");
+ if (unlikely(fdtpsci < 0))
+ fdtpsci = fdt_node_offset_by_compatible(fdt, -1,
+ "arm,psci-0.2");
- if (fdtpsci < 0) {
+ if (unlikely(fdtpsci < 0)) {
uk_pr_info("No PSCI conduit found in DTB\n");
goto enomethod;
}
fdtmethod = fdt_getprop(fdt, fdtpsci, "method", &len);
- if (!fdtmethod || (len <= 0)) {
+ if (unlikely(!fdtmethod || len <= 0)) {
uk_pr_info("No PSCI method found\n");
goto enomethod;
}
else if (!strcmp(fdtmethod, "smc"))
smccc_psci_call = smccc_smc;
else {
- uk_pr_info("Invalid PSCI conduit method: %s\n",
- fdtmethod);
+ uk_pr_info("Invalid PSCI conduit method: %s\n", fdtmethod);
goto enomethod;
}
uk_pr_info("PSCI method: %s\n", fdtmethod);
- return;
+
+ return 0;
enomethod:
uk_pr_info("Support PSCI from PSCI-0.2\n");
smccc_psci_call = NULL;
+
+ return -ENOENT;
}
+#endif
static char *cmdline;
static __sz cmdline_len;
UK_CRASH("Boot stack alloc failed\n");
bstack = (void *)((__uptr)bstack + __STACK_SIZE);
- /* Get PSCI method from DTB */
- _dtb_get_psci_method(fdt);
/* Initialize paging */
rc = ukplat_mem_init();
UK_CRASH("SMP initialization failed: %d.\n", rc);
#endif /* CONFIG_HAVE_SMP */
+ rc = get_psci_method(bi);
+ if (unlikely(rc < 0))
+ UK_CRASH("Failed to get PSCI method: %d.\n", rc);
+
/*
* Switch away from the bootstrap stack as early as possible.
*/