xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-meson/sm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Secure monitor calls.
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <common.h>
10*4882a593Smuzhiyun #include <asm/arch/gxbb.h>
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define FN_GET_SHARE_MEM_INPUT_BASE	0x82000020
14*4882a593Smuzhiyun #define FN_GET_SHARE_MEM_OUTPUT_BASE	0x82000021
15*4882a593Smuzhiyun #define FN_EFUSE_READ			0x82000030
16*4882a593Smuzhiyun #define FN_EFUSE_WRITE			0x82000031
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun static void *shmem_input;
19*4882a593Smuzhiyun static void *shmem_output;
20*4882a593Smuzhiyun 
meson_init_shmem(void)21*4882a593Smuzhiyun static void meson_init_shmem(void)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun 	struct pt_regs regs;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	if (shmem_input && shmem_output)
26*4882a593Smuzhiyun 		return;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	regs.regs[0] = FN_GET_SHARE_MEM_INPUT_BASE;
29*4882a593Smuzhiyun 	smc_call(&regs);
30*4882a593Smuzhiyun 	shmem_input = (void *)regs.regs[0];
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	regs.regs[0] = FN_GET_SHARE_MEM_OUTPUT_BASE;
33*4882a593Smuzhiyun 	smc_call(&regs);
34*4882a593Smuzhiyun 	shmem_output = (void *)regs.regs[0];
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	debug("Secure Monitor shmem: 0x%p 0x%p\n", shmem_input, shmem_output);
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun 
meson_sm_read_efuse(uintptr_t offset,void * buffer,size_t size)39*4882a593Smuzhiyun ssize_t meson_sm_read_efuse(uintptr_t offset, void *buffer, size_t size)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	struct pt_regs regs;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	meson_init_shmem();
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	regs.regs[0] = FN_EFUSE_READ;
46*4882a593Smuzhiyun 	regs.regs[1] = offset;
47*4882a593Smuzhiyun 	regs.regs[2] = size;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	smc_call(&regs);
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	if (regs.regs[0] == 0)
52*4882a593Smuzhiyun 		return -1;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	memcpy(buffer, shmem_output, min(size, regs.regs[0]));
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	return regs.regs[0];
57*4882a593Smuzhiyun }
58