]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
plat/kvm/arm: Enable fetching of the `PSCI` method through `ACPI`
authorSergiu Moga <sergiu.moga@protonmail.com>
Sun, 21 May 2023 13:25:14 +0000 (16:25 +0300)
committerUnikraft <monkey@unikraft.io>
Fri, 11 Aug 2023 16:42:01 +0000 (16:42 +0000)
Add the alternative of fetching the `PSCI` method from `ACPI`'s
`FADT`'s `ARM Boot Flags` field.

Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com>
Reviewed-by: Razvan Virtan <virtanrazvan@gmail.com>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #912

plat/kvm/arm/setup.c

index 4975fdc4af5d8898a506cf8dd3de0fc4dd2d4783..c6af9fd599d21bc849c22f7cb26653e1f6381b27 100644 (file)
 
 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;
        }
@@ -79,17 +101,20 @@ static void _dtb_get_psci_method(void *fdt)
        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;
@@ -153,8 +178,6 @@ void __no_pauth _ukplat_entry(struct ukplat_bootinfo *bi)
                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();
@@ -204,6 +227,10 @@ void __no_pauth _ukplat_entry(struct ukplat_bootinfo *bi)
                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.
         */