
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 --- arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 1 + arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 49 +++++++++-------------- arch/arm/cpu/armv8/fsl-layerscape/mp.c | 11 ++--- arch/arm/cpu/armv8/sec_firmware.c | 19 ++++----- 4 files changed, 31 insertions(+), 49 deletions(-)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index 1a057f7059..14ef07e74f 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -321,6 +321,7 @@ menu "Layerscape architecture"
config FSL_LAYERSCAPE bool + select ARM_SMCCC
config HAS_FEATURE_GIC64K_ALIGN bool diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 1a359d060e..38bef4432d 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -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> @@ -766,7 +767,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) @@ -776,11 +777,9 @@ enum boot_src get_boot_src(void) #endif
if (current_el() == 2) { - regs.regs[0] = SIP_SVC_RCW; - - smc_call(®s); - 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) { @@ -1079,9 +1078,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; @@ -1099,11 +1098,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(®s); + 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 "); @@ -1343,25 +1341,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(®s); - 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);
@@ -1369,19 +1362,15 @@ static int tfa_dram_init_banksize(void) return -EINVAL;
do { - regs.regs[0] = SMC_DRAM_BANK_INFO; - regs.regs[1] = i; - - smc_call(®s); - 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;
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/mp.c b/arch/arm/cpu/armv8/fsl-layerscape/mp.c index d28ab26533..c6d76034b6 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/mp.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/mp.c @@ -301,6 +301,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);
@@ -325,16 +326,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(®s); - if (regs.regs[0]) + ret = invoke_psci_fn(PSCI_0_2_FN64_CPU_ON, nr, boot_addr, 0); + if (ret) return -1; }
diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c index e62e9dc380..d0ad6eeb0a 100644 --- a/arch/arm/cpu/armv8/sec_firmware.c +++ b/arch/arm/cpu/armv8/sec_firmware.c @@ -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(®s);
- 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 1; }
- 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 1; }