mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	Add optee based bnxt fw load driver. bnxt is Broadcom NetXtreme controller Ethernet card. This driver is used to load bnxt firmware binary using OpTEE. Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com> Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com> Reviewed-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			184 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: BSD-2-Clause
 | 
						|
/*
 | 
						|
 * Copyright 2020 Broadcom.
 | 
						|
 */
 | 
						|
 | 
						|
#include <common.h>
 | 
						|
#include <tee.h>
 | 
						|
#include <broadcom/chimp.h>
 | 
						|
 | 
						|
#ifdef CONFIG_CHIMP_OPTEE
 | 
						|
 | 
						|
#define CHMIP_BOOT_UUID { 0x6272636D, 0x2019, 0x0716, \
 | 
						|
		   { 0x42, 0x43, 0x4D, 0x5F, 0x53, 0x43, 0x48, 0x49 } }
 | 
						|
 | 
						|
enum {
 | 
						|
	TEE_CHIMP_FASTBOOT = 0,
 | 
						|
	TEE_CHIMP_HEALTH_STATUS,
 | 
						|
	TEE_CHIMP_HANDSHAKE_STATUS,
 | 
						|
} tee_chmip_cmd;
 | 
						|
 | 
						|
struct bcm_chimp_data {
 | 
						|
	struct udevice *tee;
 | 
						|
	u32 session;
 | 
						|
} chimp_data;
 | 
						|
 | 
						|
static int get_open_session(struct bcm_chimp_data *b_data)
 | 
						|
{
 | 
						|
	const struct tee_optee_ta_uuid uuid = CHMIP_BOOT_UUID;
 | 
						|
	struct tee_open_session_arg arg;
 | 
						|
	struct udevice *tee = NULL;
 | 
						|
	int rc;
 | 
						|
 | 
						|
	tee = tee_find_device(NULL, NULL, NULL, NULL);
 | 
						|
	if (!tee)
 | 
						|
		return -ENODEV;
 | 
						|
 | 
						|
	memset(&arg, 0, sizeof(arg));
 | 
						|
	tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
 | 
						|
	rc = tee_open_session(tee, &arg, 0, NULL);
 | 
						|
	if (rc < 0)
 | 
						|
		return -ENODEV;
 | 
						|
 | 
						|
	b_data->tee = tee;
 | 
						|
	b_data->session = arg.session;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int init_arg(struct tee_invoke_arg *arg, u32 func)
 | 
						|
{
 | 
						|
	if (get_open_session(&chimp_data))
 | 
						|
		return -EINVAL;
 | 
						|
 | 
						|
	memset(arg, 0, sizeof(struct tee_invoke_arg));
 | 
						|
	arg->func = func;
 | 
						|
	arg->session = chimp_data.session;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int chimp_handshake_status_optee(u32 timeout, u32 *hs)
 | 
						|
{
 | 
						|
	struct tee_invoke_arg arg;
 | 
						|
	struct tee_param param[1];
 | 
						|
	int ret;
 | 
						|
 | 
						|
	ret = init_arg(&arg, TEE_CHIMP_HANDSHAKE_STATUS);
 | 
						|
	if (ret < 0)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT;
 | 
						|
	param[0].u.value.a = timeout;
 | 
						|
 | 
						|
	ret = tee_invoke_func(chimp_data.tee, &arg, ARRAY_SIZE(param), param);
 | 
						|
	if (ret < 0) {
 | 
						|
		printf("Handshake status command failed\n");
 | 
						|
		goto out;
 | 
						|
	}
 | 
						|
 | 
						|
	switch (arg.ret) {
 | 
						|
	case TEE_SUCCESS:
 | 
						|
		*hs = param[0].u.value.a;
 | 
						|
		ret =  0;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		ret = -EINVAL;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
out:
 | 
						|
	tee_close_session(chimp_data.tee, chimp_data.session);
 | 
						|
	chimp_data.tee = NULL;
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
int chimp_health_status_optee(u32 *health)
 | 
						|
{
 | 
						|
	struct tee_invoke_arg arg;
 | 
						|
	struct tee_param param[1];
 | 
						|
	int ret;
 | 
						|
 | 
						|
	ret = init_arg(&arg, TEE_CHIMP_HEALTH_STATUS);
 | 
						|
	if (ret < 0)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;
 | 
						|
 | 
						|
	ret = tee_invoke_func(chimp_data.tee, &arg, ARRAY_SIZE(param), param);
 | 
						|
	if (ret < 0) {
 | 
						|
		printf("Helath status command failed\n");
 | 
						|
		goto out;
 | 
						|
	}
 | 
						|
 | 
						|
	switch (arg.ret) {
 | 
						|
	case TEE_SUCCESS:
 | 
						|
		*health = param[0].u.value.a;
 | 
						|
		ret =  0;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		ret = -EINVAL;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
out:
 | 
						|
	tee_close_session(chimp_data.tee, chimp_data.session);
 | 
						|
	chimp_data.tee = NULL;
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
int chimp_fastboot_optee(void)
 | 
						|
{
 | 
						|
	struct tee_invoke_arg arg;
 | 
						|
	int ret;
 | 
						|
 | 
						|
	ret = init_arg(&arg, TEE_CHIMP_FASTBOOT);
 | 
						|
	if (ret < 0)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	ret = tee_invoke_func(chimp_data.tee, &arg, 0, NULL);
 | 
						|
	if (ret < 0) {
 | 
						|
		printf("Chimp boot_fail\n");
 | 
						|
		goto out;
 | 
						|
	}
 | 
						|
 | 
						|
	switch (arg.ret) {
 | 
						|
	case TEE_SUCCESS:
 | 
						|
		ret = 0;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		ret = -EINVAL;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
out:
 | 
						|
	tee_close_session(chimp_data.tee, chimp_data.session);
 | 
						|
	chimp_data.tee = NULL;
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
#else
 | 
						|
int chimp_handshake_status_optee(u32 timeout, u32 *status)
 | 
						|
{
 | 
						|
	printf("ChiMP handshake status fail (OPTEE not enabled)\n");
 | 
						|
 | 
						|
	return -EINVAL;
 | 
						|
}
 | 
						|
 | 
						|
int chimp_health_status_optee(u32 *status)
 | 
						|
{
 | 
						|
	printf("ChiMP health status fail (OPTEE not enabled)\n");
 | 
						|
 | 
						|
	return -EINVAL;
 | 
						|
}
 | 
						|
 | 
						|
int chimp_fastboot_optee(void)
 | 
						|
{
 | 
						|
	printf("ChiMP secure boot fail (OPTEE not enabled)\n");
 | 
						|
 | 
						|
	return -EINVAL;
 | 
						|
}
 | 
						|
#endif /* CONFIG_CHIMP_OPTEE */
 |