armv8: layerscape: get rid of smc_call()
authorMichael Walle <michael@walle.cc>
Fri, 22 Apr 2022 09:23:27 +0000 (14:53 +0530)
committerPriyanka Jain <priyanka.jain@nxp.com>
Tue, 26 Apr 2022 11:43:57 +0000 (17:13 +0530)
There are two different implementations to do a secure monitor call:
smc_call() and arm_smccc_smc(). The former is defined in fwcall.c and
seems to be an ad-hoc implementation. The latter is imported from linux.

smc_call() is also only available if CONFIG_ARMV8_PSCI is not defined.
This makes it impossible to have both PSCI calls and PSCI implementation
in one u-boot build. The layerscape SoC code decide at runtime via
check_psci() if there is a PSCI support. Therefore, this is a
prerequisite patch to add PSCI implementation support for the layerscape
SoCs.

Note, for the TFA part, this is only compile time tested with
(ls1028ardb_tfa_defconfig).

Signed-off-by: Michael Walle <michael@walle.cc>
[Rebased]
Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com>
arch/arm/cpu/armv8/fsl-layerscape/Kconfig
arch/arm/cpu/armv8/fsl-layerscape/cpu.c
arch/arm/cpu/armv8/fsl-layerscape/mp.c
arch/arm/cpu/armv8/sec_firmware.c

index dd95380..6f8d5cb 100644 (file)
@@ -333,6 +333,7 @@ menu "Layerscape architecture"
 
 config FSL_LAYERSCAPE
        bool
+       select ARM_SMCCC
 
 config HAS_FEATURE_GIC64K_ALIGN
        bool
index cf46980..a71ee63 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/ptrace.h>
+#include <linux/arm-smccc.h>
 #include <linux/errno.h>
 #include <asm/system.h>
 #include <fm_eth.h>
@@ -768,7 +769,7 @@ enum boot_src __get_boot_src(u32 porsr1)
 
 enum boot_src get_boot_src(void)
 {
-       struct pt_regs regs;
+       struct arm_smccc_res res;
        u32 porsr1 = 0;
 
 #if defined(CONFIG_FSL_LSCH3)
@@ -778,11 +779,9 @@ enum boot_src get_boot_src(void)
 #endif
 
        if (current_el() == 2) {
-               regs.regs[0] = SIP_SVC_RCW;
-
-               smc_call(&regs);
-               if (!regs.regs[0])
-                       porsr1 = regs.regs[1];
+               arm_smccc_smc(SIP_SVC_RCW, 0, 0, 0, 0, 0, 0, 0, &res);
+               if (!res.a0)
+                       porsr1 = res.a1;
        }
 
        if (current_el() == 3 || !porsr1) {
@@ -1081,9 +1080,9 @@ static void config_core_prefetch(void)
        char *buf = NULL;
        char buffer[HWCONFIG_BUFFER_SIZE];
        const char *prefetch_arg = NULL;
+       struct arm_smccc_res res;
        size_t arglen;
        unsigned int mask;
-       struct pt_regs regs;
 
        if (env_get_f("hwconfig", buffer, sizeof(buffer)) > 0)
                buf = buffer;
@@ -1101,11 +1100,10 @@ static void config_core_prefetch(void)
                }
 
 #define SIP_PREFETCH_DISABLE_64 0xC200FF13
-               regs.regs[0] = SIP_PREFETCH_DISABLE_64;
-               regs.regs[1] = mask;
-               smc_call(&regs);
+               arm_smccc_smc(SIP_PREFETCH_DISABLE_64, mask, 0, 0, 0, 0, 0, 0,
+                             &res);
 
-               if (regs.regs[0])
+               if (res.a0)
                        printf("Prefetch disable config failed for mask ");
                else
                        printf("Prefetch disable config passed for mask ");
@@ -1345,25 +1343,20 @@ phys_size_t get_effective_memsize(void)
 #ifdef CONFIG_TFABOOT
 phys_size_t tfa_get_dram_size(void)
 {
-       struct pt_regs regs;
-       phys_size_t dram_size = 0;
-
-       regs.regs[0] = SMC_DRAM_BANK_INFO;
-       regs.regs[1] = -1;
+       struct arm_smccc_res res;
 
-       smc_call(&regs);
-       if (regs.regs[0])
+       arm_smccc_smc(SMC_DRAM_BANK_INFO, -1, 0, 0, 0, 0, 0, 0, &res);
+       if (res.a0)
                return 0;
 
-       dram_size = regs.regs[1];
-       return dram_size;
+       return res.a1;
 }
 
 static int tfa_dram_init_banksize(void)
 {
        int i = 0, ret = 0;
-       struct pt_regs regs;
        phys_size_t dram_size = tfa_get_dram_size();
+       struct arm_smccc_res res;
 
        debug("dram_size %llx\n", dram_size);
 
@@ -1371,19 +1364,15 @@ static int tfa_dram_init_banksize(void)
                return -EINVAL;
 
        do {
-               regs.regs[0] = SMC_DRAM_BANK_INFO;
-               regs.regs[1] = i;
-
-               smc_call(&regs);
-               if (regs.regs[0]) {
+               arm_smccc_smc(SMC_DRAM_BANK_INFO, i, 0, 0, 0, 0, 0, 0, &res);
+               if (res.a0) {
                        ret = -EINVAL;
                        break;
                }
 
-               debug("bank[%d]: start %lx, size %lx\n", i, regs.regs[1],
-                     regs.regs[2]);
-               gd->bd->bi_dram[i].start = regs.regs[1];
-               gd->bd->bi_dram[i].size = regs.regs[2];
+               debug("bank[%d]: start %lx, size %lx\n", i, res.a1, res.a2);
+               gd->bd->bi_dram[i].start = res.a1;
+               gd->bd->bi_dram[i].size = res.a2;
 
                dram_size -= gd->bd->bi_dram[i].size;
 
index 2e2688e..7222119 100644 (file)
@@ -302,6 +302,7 @@ int cpu_release(u32 nr, int argc, char *const argv[])
        u64 boot_addr;
        u64 *table = get_spin_tbl_addr();
        int pos;
+       int ret;
 
        boot_addr = simple_strtoull(argv[0], NULL, 16);
 
@@ -326,16 +327,10 @@ int cpu_release(u32 nr, int argc, char *const argv[])
                asm volatile("sev");
        } else {
                /* Use PSCI to kick the core */
-               struct pt_regs regs;
-
                printf("begin to kick cpu core #%d to address %llx\n",
                       nr, boot_addr);
-               regs.regs[0] = PSCI_0_2_FN64_CPU_ON;
-               regs.regs[1] = nr;
-               regs.regs[2] = boot_addr;
-               regs.regs[3] = 0;
-               smc_call(&regs);
-               if (regs.regs[0])
+               ret = invoke_psci_fn(PSCI_0_2_FN64_CPU_ON, nr, boot_addr, 0);
+               if (ret)
                        return -1;
        }
 
index 267894f..7e6e406 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/global_data.h>
 #include <asm/ptrace.h>
 #include <linux/kernel.h>
+#include <linux/arm-smccc.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/types.h>
@@ -374,29 +375,25 @@ bool sec_firmware_support_hwrng(void)
  */
 int sec_firmware_get_random(uint8_t *rand, int bytes)
 {
+       struct arm_smccc_res res;
        unsigned long long num;
-       struct pt_regs regs;
        int param1;
 
        if (!bytes || bytes > 8) {
                printf("Max Random bytes genration supported is 8\n");
                return -1;
        }
-#define SIP_RNG_64 0xC200FF11
-       regs.regs[0] = SIP_RNG_64;
-
        if (bytes <= 4)
                param1 = 0;
        else
                param1 = 1;
-       regs.regs[1] = param1;
-
-       smc_call(&regs);
 
-       if (regs.regs[0])
+#define SIP_RNG_64 0xC200FF11
+       arm_smccc_smc(SIP_RNG_64, param1, 0, 0, 0, 0, 0, 0, &res);
+       if (res.a0)
                return -1;
 
-       num = regs.regs[1];
+       num = res.a1;
        memcpy(rand, &num, bytes);
 
        return 0;
@@ -473,8 +470,8 @@ int fdt_fixup_kaslr(void *fdt)
                return 0;
        }
 
-       ret = sec_firmware_get_random(rand, 8);
-       if (ret < 0) {
+       err = sec_firmware_get_random(rand, 8);
+       if (err < 0) {
                printf("WARNING: No random number to set kaslr-seed\n");
                return 0;
        }