From: Sergiu Moga Date: Sun, 21 May 2023 13:25:14 +0000 (+0300) Subject: plat/kvm/arm: Enable fetching of the `PSCI` method through `ACPI` X-Git-Tag: RELEASE-0.14.0~45 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=b0aee57ae9ad1503ee7faa58cd5d53d1d168c072;p=unikraft%2Funikraft.git plat/kvm/arm: Enable fetching of the `PSCI` method through `ACPI` Add the alternative of fetching the `PSCI` method from `ACPI`'s `FADT`'s `ARM Boot Flags` field. Signed-off-by: Sergiu Moga Reviewed-by: Razvan Virtan Reviewed-by: Michalis Pappas Approved-by: Razvan Deaconescu Tested-by: Unikraft CI GitHub-Closes: #912 --- diff --git a/plat/kvm/arm/setup.c b/plat/kvm/arm/setup.c index 4975fdc4a..c6af9fd59 100644 --- a/plat/kvm/arm/setup.c +++ b/plat/kvm/arm/setup.c @@ -48,28 +48,50 @@ 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. */