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