xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientRkNewFs_v1.c (revision df538e29bdfa27e8607f1bf29d6d641bd85ef124)
1*df538e29SHisping Lin /*
2*df538e29SHisping Lin  * Copyright 2020, Rockchip Electronics Co., Ltd
3*df538e29SHisping Lin  * hisping lin, <hisping.lin@rock-chips.com>
4*df538e29SHisping Lin  *
5*df538e29SHisping Lin  * SPDX-License-Identifier:	GPL-2.0+
6*df538e29SHisping Lin  */
7*df538e29SHisping Lin 
8*df538e29SHisping Lin #include <common.h>
9*df538e29SHisping Lin #include <stdlib.h>
10*df538e29SHisping Lin #include <command.h>
11*df538e29SHisping Lin #include <boot_rkimg.h>
12*df538e29SHisping Lin #include <part.h>
13*df538e29SHisping Lin #include <optee_include/OpteeClientRkNewFs.h>
14*df538e29SHisping Lin #include <optee_include/tee_client_api.h>
15*df538e29SHisping Lin 
16*df538e29SHisping Lin /*
17*df538e29SHisping Lin  *#define DEBUG_RKFSS
18*df538e29SHisping Lin  *#define DEBUG_CLEAN_RKSS
19*df538e29SHisping Lin  */
20*df538e29SHisping Lin 
21*df538e29SHisping Lin /*
22*df538e29SHisping Lin  *	RK Secure Storage Ctrl
23*df538e29SHisping Lin  *		Storage Size : 512 kb
24*df538e29SHisping Lin  *		Header Size : 8 byte * 2 for each top of 512 byte
25*df538e29SHisping Lin  *		Partision Table Size : 128 * 512 b (24 Files And Folder)
26*df538e29SHisping Lin  *		File number: 128 * 4 = 512
27*df538e29SHisping Lin  *		Data Size : 895 * 512 b
28*df538e29SHisping Lin  *
29*df538e29SHisping Lin  *	------ RKSS Structure --------
30*df538e29SHisping Lin  *	- 512 byte patition table1 [0]
31*df538e29SHisping Lin  *		- 126 * 4 = 504 byte table info
32*df538e29SHisping Lin  *		- 8 byte verification
33*df538e29SHisping Lin  *	- 512 byte patition table2 [1]
34*df538e29SHisping Lin  *	             ...
35*df538e29SHisping Lin  *	- 512 byte patition table128 [127]
36*df538e29SHisping Lin  *	- 512 byte section used refs [128]
37*df538e29SHisping Lin  *		- 1 byte = 2 flag
38*df538e29SHisping Lin  *	- 895 * 512 byte data	[129 - 1023]
39*df538e29SHisping Lin  *	------ RKSS Backup Structure --------
40*df538e29SHisping Lin  *	- 512 byte backup header  [1024]
41*df538e29SHisping Lin  *		- 1 * rkss_backup_verification + 31 * rkss_backup_info
42*df538e29SHisping Lin  *	- 255 * 512 byte backup data [1025 - 1279]
43*df538e29SHisping Lin  *
44*df538e29SHisping Lin  */
45*df538e29SHisping Lin #define RKSS_DATA_SECTION_COUNT		1024
46*df538e29SHisping Lin #define RKSS_DATA_SECTION_LEN			512
47*df538e29SHisping Lin #define RKSS_PARTITION_TABLE_COUNT	128		/* total size 512 * 128*/
48*df538e29SHisping Lin #define RKSS_EACH_SECTION_FILECOUNT	4		/* 504 / 126 = 4*/
49*df538e29SHisping Lin #define RKSS_MAX_NAME_LENGTH		117		/* 116 char + "\0"*/
50*df538e29SHisping Lin #define RKSS_USED_FLAGS_INDEX		RKSS_PARTITION_TABLE_COUNT
51*df538e29SHisping Lin #define RKSS_BACKUP_INDEX		RKSS_DATA_SECTION_COUNT
52*df538e29SHisping Lin #define RKSS_BACKUP_COUNT		256
53*df538e29SHisping Lin 
54*df538e29SHisping Lin #define RKSS_BACKUP_VERSION		(unsigned int)0x1
55*df538e29SHisping Lin #define RKSS_BACKUP_ENABLE		(unsigned int)0x55667788
56*df538e29SHisping Lin #define RKSS_BACKUP_USEDFLAG		(unsigned int)0xAABBCCDD
57*df538e29SHisping Lin 
58*df538e29SHisping Lin struct rkss_backup_verification {
59*df538e29SHisping Lin 	unsigned int backup_version;
60*df538e29SHisping Lin 	unsigned int backup_count;
61*df538e29SHisping Lin 	unsigned int reserve;
62*df538e29SHisping Lin 	unsigned int backup_enable;
63*df538e29SHisping Lin };
64*df538e29SHisping Lin 
65*df538e29SHisping Lin struct rkss_backup_info {
66*df538e29SHisping Lin 	unsigned int backup_index;
67*df538e29SHisping Lin 	unsigned int backup_num;
68*df538e29SHisping Lin 	unsigned int backup_data_index;
69*df538e29SHisping Lin 	unsigned int backup_usedflag;
70*df538e29SHisping Lin };
71*df538e29SHisping Lin 
72*df538e29SHisping Lin typedef struct rkss_file_info {
73*df538e29SHisping Lin 	uint8_t		used;
74*df538e29SHisping Lin 	char 		name[RKSS_MAX_NAME_LENGTH];
75*df538e29SHisping Lin 	uint16_t	index;	/* from 129 to 1023*/
76*df538e29SHisping Lin 	uint16_t	size;	/* size of data*/
77*df538e29SHisping Lin 	uint16_t	father;
78*df538e29SHisping Lin 	uint8_t 	id; /* file folder count index*/
79*df538e29SHisping Lin 	uint8_t		flags;
80*df538e29SHisping Lin } rkss_file_info; /* 126 byte for each*/
81*df538e29SHisping Lin 
82*df538e29SHisping Lin #define RKSS_CHECK_STR	((uint32_t)0x12345678)
83*df538e29SHisping Lin #define RKSS_CHECK_PT		((uint8_t)0xFC)
84*df538e29SHisping Lin typedef struct rkss_file_verification {
85*df538e29SHisping Lin 	uint32_t version;
86*df538e29SHisping Lin 	uint32_t checkstr;
87*df538e29SHisping Lin } rkss_file_verification;
88*df538e29SHisping Lin 
89*df538e29SHisping Lin typedef struct rk_secure_storage {
90*df538e29SHisping Lin 	unsigned long index;
91*df538e29SHisping Lin 	unsigned char data[RKSS_DATA_SECTION_LEN];
92*df538e29SHisping Lin } rk_secure_storage;
93*df538e29SHisping Lin 
94*df538e29SHisping Lin /* RK Secure Storage Calls */
95*df538e29SHisping Lin static char dir_cache[RKSS_MAX_NAME_LENGTH][12];
96*df538e29SHisping Lin static int dir_num;
97*df538e29SHisping Lin static int dir_seek;
98*df538e29SHisping Lin 
99*df538e29SHisping Lin static struct blk_desc *dev_desc;
100*df538e29SHisping Lin static disk_partition_t part_info;
101*df538e29SHisping Lin 
102*df538e29SHisping Lin static int check_security_exist(int print_flag)
103*df538e29SHisping Lin {
104*df538e29SHisping Lin 	if (!dev_desc) {
105*df538e29SHisping Lin 		dev_desc = rockchip_get_bootdev();
106*df538e29SHisping Lin 		if (!dev_desc) {
107*df538e29SHisping Lin 			printf("TEEC: %s: Could not find device\n", __func__);
108*df538e29SHisping Lin 			return -1;
109*df538e29SHisping Lin 		}
110*df538e29SHisping Lin 
111*df538e29SHisping Lin 		if (part_get_info_by_name(dev_desc,
112*df538e29SHisping Lin 					  "security", &part_info) < 0) {
113*df538e29SHisping Lin 			dev_desc = NULL;
114*df538e29SHisping Lin 			if (print_flag != 0)
115*df538e29SHisping Lin 				printf("TEEC: Could not find security partition\n");
116*df538e29SHisping Lin 			return -1;
117*df538e29SHisping Lin 		}
118*df538e29SHisping Lin 	}
119*df538e29SHisping Lin 	return 0;
120*df538e29SHisping Lin }
121*df538e29SHisping Lin 
122*df538e29SHisping Lin /*
123*df538e29SHisping Lin  * action1:
124*df538e29SHisping Lin  * rkss_begin_commit	set enable flag
125*df538e29SHisping Lin  * rkss_backup_sections	backup data
126*df538e29SHisping Lin  * blk_dwrite
127*df538e29SHisping Lin  * rkss_finish_commit	clear enable flag, clear backup data
128*df538e29SHisping Lin  * reboot
129*df538e29SHisping Lin  * rkss_resume	not find enable flag, do nothing
130*df538e29SHisping Lin  *
131*df538e29SHisping Lin  * action2:
132*df538e29SHisping Lin  * rkss_begin_commit	set enable flag
133*df538e29SHisping Lin  * rkss_backup_sections	backup data
134*df538e29SHisping Lin  * power off when blk_dwrite
135*df538e29SHisping Lin  *
136*df538e29SHisping Lin  * power on
137*df538e29SHisping Lin  * rkss_resume	find enable flag, resume all backup data
138*df538e29SHisping Lin  */
139*df538e29SHisping Lin static int rkss_begin_commit(void)
140*df538e29SHisping Lin {
141*df538e29SHisping Lin 	unsigned char data[RKSS_DATA_SECTION_LEN];
142*df538e29SHisping Lin 	struct rkss_backup_verification p;
143*df538e29SHisping Lin 	unsigned long ret;
144*df538e29SHisping Lin 
145*df538e29SHisping Lin 	if (check_security_exist(1) < 0)
146*df538e29SHisping Lin 		return -1;
147*df538e29SHisping Lin 
148*df538e29SHisping Lin 	debug("TEEC: %s\n", __func__);
149*df538e29SHisping Lin 	p.backup_version = RKSS_BACKUP_VERSION;
150*df538e29SHisping Lin 	p.backup_enable = RKSS_BACKUP_ENABLE;
151*df538e29SHisping Lin 	p.backup_count = 0;
152*df538e29SHisping Lin 
153*df538e29SHisping Lin 	memset(data, 0, sizeof(data));
154*df538e29SHisping Lin 	memcpy(data, &p, sizeof(p));
155*df538e29SHisping Lin 
156*df538e29SHisping Lin 	ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data);
157*df538e29SHisping Lin 	if (ret != 1) {
158*df538e29SHisping Lin 		printf("TEEC: blk_dwrite fail\n");
159*df538e29SHisping Lin 		return -1;
160*df538e29SHisping Lin 	}
161*df538e29SHisping Lin 	return 0;
162*df538e29SHisping Lin }
163*df538e29SHisping Lin 
164*df538e29SHisping Lin static int rkss_finish_commit(void)
165*df538e29SHisping Lin {
166*df538e29SHisping Lin 	unsigned char data[RKSS_DATA_SECTION_LEN];
167*df538e29SHisping Lin 	unsigned long ret;
168*df538e29SHisping Lin 
169*df538e29SHisping Lin 	if (check_security_exist(1) < 0)
170*df538e29SHisping Lin 		return -1;
171*df538e29SHisping Lin 
172*df538e29SHisping Lin 	debug("TEEC: %s\n", __func__);
173*df538e29SHisping Lin 	memset(data, 0, sizeof(data));
174*df538e29SHisping Lin 
175*df538e29SHisping Lin 	ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data);
176*df538e29SHisping Lin 	if (ret != 1) {
177*df538e29SHisping Lin 		printf("TEEC: blk_dwrite fail\n");
178*df538e29SHisping Lin 		return -1;
179*df538e29SHisping Lin 	}
180*df538e29SHisping Lin 	return 0;
181*df538e29SHisping Lin }
182*df538e29SHisping Lin 
183*df538e29SHisping Lin static int rkss_backup_sections(unsigned long index, unsigned int num)
184*df538e29SHisping Lin {
185*df538e29SHisping Lin 	unsigned char data[RKSS_DATA_SECTION_LEN];
186*df538e29SHisping Lin 	unsigned char *backup_data = NULL;
187*df538e29SHisping Lin 	struct rkss_backup_verification p;
188*df538e29SHisping Lin 	struct rkss_backup_info info_last, info_current;
189*df538e29SHisping Lin 	unsigned long ret;
190*df538e29SHisping Lin 
191*df538e29SHisping Lin 	if (check_security_exist(1) < 0)
192*df538e29SHisping Lin 		return -1;
193*df538e29SHisping Lin 
194*df538e29SHisping Lin 	ret = blk_dread(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data);
195*df538e29SHisping Lin 	if (ret != 1) {
196*df538e29SHisping Lin 		printf("TEEC: blk_dread fail\n");
197*df538e29SHisping Lin 		return -1;
198*df538e29SHisping Lin 	}
199*df538e29SHisping Lin 
200*df538e29SHisping Lin 	memcpy(&p, data, sizeof(p));
201*df538e29SHisping Lin 	if (p.backup_version == RKSS_BACKUP_VERSION &&
202*df538e29SHisping Lin 	    p.backup_enable == RKSS_BACKUP_ENABLE) {
203*df538e29SHisping Lin 		if (p.backup_count == 0) {
204*df538e29SHisping Lin 			info_current.backup_usedflag = RKSS_BACKUP_USEDFLAG;
205*df538e29SHisping Lin 			info_current.backup_index = index;
206*df538e29SHisping Lin 			info_current.backup_num = num;
207*df538e29SHisping Lin 			info_current.backup_data_index = RKSS_BACKUP_INDEX + 1;
208*df538e29SHisping Lin 		} else {
209*df538e29SHisping Lin 			memcpy(&info_last, data + sizeof(p) +
210*df538e29SHisping Lin 			       (p.backup_count - 1) * sizeof(info_last),
211*df538e29SHisping Lin 			       sizeof(info_last));
212*df538e29SHisping Lin 			info_current.backup_usedflag = RKSS_BACKUP_USEDFLAG;
213*df538e29SHisping Lin 			info_current.backup_index = index;
214*df538e29SHisping Lin 			info_current.backup_num = num;
215*df538e29SHisping Lin 			info_current.backup_data_index =
216*df538e29SHisping Lin 				info_last.backup_data_index +
217*df538e29SHisping Lin 				info_last.backup_num;
218*df538e29SHisping Lin 		}
219*df538e29SHisping Lin 		if ((info_current.backup_data_index + info_current.backup_num) >
220*df538e29SHisping Lin 			(RKSS_BACKUP_INDEX + RKSS_BACKUP_COUNT)) {
221*df538e29SHisping Lin 			printf("TEEC: Not enough backup sections!\n");
222*df538e29SHisping Lin 			goto error;
223*df538e29SHisping Lin 		}
224*df538e29SHisping Lin 		debug("TEEC: %s index=0x%lx num=0x%x backup_data_index=0x%x\n",
225*df538e29SHisping Lin 		      __func__, index, num, info_current.backup_data_index);
226*df538e29SHisping Lin 
227*df538e29SHisping Lin 		backup_data = malloc(num * RKSS_DATA_SECTION_LEN);
228*df538e29SHisping Lin 		if (!backup_data) {
229*df538e29SHisping Lin 			printf("TEEC: malloc backup_data fail\n");
230*df538e29SHisping Lin 			goto error;
231*df538e29SHisping Lin 		}
232*df538e29SHisping Lin 
233*df538e29SHisping Lin 		ret = blk_dread(dev_desc, part_info.start + index, num, backup_data);
234*df538e29SHisping Lin 		if (ret != num) {
235*df538e29SHisping Lin 			printf("TEEC: blk_dread fail\n");
236*df538e29SHisping Lin 			return -1;
237*df538e29SHisping Lin 		}
238*df538e29SHisping Lin 
239*df538e29SHisping Lin 		ret = blk_dwrite(dev_desc, part_info.start + info_current.backup_data_index,
240*df538e29SHisping Lin 				 num, backup_data);
241*df538e29SHisping Lin 		if (ret != num) {
242*df538e29SHisping Lin 			printf("TEEC: blk_dwrite fail\n");
243*df538e29SHisping Lin 			return -1;
244*df538e29SHisping Lin 		}
245*df538e29SHisping Lin 		free(backup_data);
246*df538e29SHisping Lin 		backup_data = NULL;
247*df538e29SHisping Lin 
248*df538e29SHisping Lin 		p.backup_count += 1;
249*df538e29SHisping Lin 
250*df538e29SHisping Lin 		memcpy(data, &p, sizeof(p));
251*df538e29SHisping Lin 		memcpy(data + sizeof(p) +
252*df538e29SHisping Lin 		       (p.backup_count - 1) * sizeof(info_current),
253*df538e29SHisping Lin 		       &info_current, sizeof(info_current));
254*df538e29SHisping Lin 
255*df538e29SHisping Lin 		ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data);
256*df538e29SHisping Lin 		if (ret != 1) {
257*df538e29SHisping Lin 			printf("TEEC: blk_dwrite fail\n");
258*df538e29SHisping Lin 			return -1;
259*df538e29SHisping Lin 		}
260*df538e29SHisping Lin 	}
261*df538e29SHisping Lin 
262*df538e29SHisping Lin 	return 0;
263*df538e29SHisping Lin error:
264*df538e29SHisping Lin 	if (backup_data)
265*df538e29SHisping Lin 		free(backup_data);
266*df538e29SHisping Lin 	return -1;
267*df538e29SHisping Lin }
268*df538e29SHisping Lin 
269*df538e29SHisping Lin static int rkss_resume(void)
270*df538e29SHisping Lin {
271*df538e29SHisping Lin 	unsigned char data[RKSS_DATA_SECTION_LEN];
272*df538e29SHisping Lin 	unsigned char *backup_data = NULL;
273*df538e29SHisping Lin 	struct rkss_backup_verification p;
274*df538e29SHisping Lin 	struct rkss_backup_info info_current;
275*df538e29SHisping Lin 	unsigned int i;
276*df538e29SHisping Lin 	unsigned long ret;
277*df538e29SHisping Lin 
278*df538e29SHisping Lin 	if (check_security_exist(1) < 0)
279*df538e29SHisping Lin 		return -1;
280*df538e29SHisping Lin 
281*df538e29SHisping Lin 	ret = blk_dread(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data);
282*df538e29SHisping Lin 	if (ret != 1) {
283*df538e29SHisping Lin 		printf("TEEC: blk_dread fail\n");
284*df538e29SHisping Lin 		return -1;
285*df538e29SHisping Lin 	}
286*df538e29SHisping Lin 
287*df538e29SHisping Lin 	memcpy(&p, data, sizeof(p));
288*df538e29SHisping Lin 	if (p.backup_version == RKSS_BACKUP_VERSION &&
289*df538e29SHisping Lin 	    p.backup_enable == RKSS_BACKUP_ENABLE) {
290*df538e29SHisping Lin 		for (i = p.backup_count; i > 0; i--) {
291*df538e29SHisping Lin 			memcpy(&info_current, data + sizeof(p) + (i - 1) *
292*df538e29SHisping Lin 			       sizeof(info_current), sizeof(info_current));
293*df538e29SHisping Lin 
294*df538e29SHisping Lin 			if (info_current.backup_usedflag ==
295*df538e29SHisping Lin 			    RKSS_BACKUP_USEDFLAG) {
296*df538e29SHisping Lin 				debug("TEEC: rkss_resume backup_index=0x%x \
297*df538e29SHisping Lin 				      backup_num=0x%x \
298*df538e29SHisping Lin 				      info_current.backup_data_index=0x%x\n",
299*df538e29SHisping Lin 				      info_current.backup_index,
300*df538e29SHisping Lin 				      info_current.backup_num,
301*df538e29SHisping Lin 				      info_current.backup_data_index);
302*df538e29SHisping Lin 				if ((info_current.backup_data_index +
303*df538e29SHisping Lin 				    info_current.backup_num) >
304*df538e29SHisping Lin 				    (RKSS_BACKUP_INDEX + RKSS_BACKUP_COUNT)) {
305*df538e29SHisping Lin 					printf("TEEC: backup sections error!");
306*df538e29SHisping Lin 					goto error;
307*df538e29SHisping Lin 				}
308*df538e29SHisping Lin 				if ((info_current.backup_index +
309*df538e29SHisping Lin 				    info_current.backup_num) >
310*df538e29SHisping Lin 				    RKSS_DATA_SECTION_COUNT) {
311*df538e29SHisping Lin 					printf("TEEC: original sections error!");
312*df538e29SHisping Lin 					goto error;
313*df538e29SHisping Lin 				}
314*df538e29SHisping Lin 				backup_data = malloc(info_current.backup_num *
315*df538e29SHisping Lin 						     RKSS_DATA_SECTION_LEN);
316*df538e29SHisping Lin 				if (!backup_data) {
317*df538e29SHisping Lin 					printf("TEEC: malloc backup_data fail\n");
318*df538e29SHisping Lin 					goto error;
319*df538e29SHisping Lin 				}
320*df538e29SHisping Lin 
321*df538e29SHisping Lin 				ret = blk_dread(dev_desc,
322*df538e29SHisping Lin 						part_info.start + info_current.backup_data_index,
323*df538e29SHisping Lin 						info_current.backup_num,
324*df538e29SHisping Lin 						backup_data);
325*df538e29SHisping Lin 				if (ret != info_current.backup_num) {
326*df538e29SHisping Lin 					printf("TEEC: blk_dread fail\n");
327*df538e29SHisping Lin 					return -1;
328*df538e29SHisping Lin 				}
329*df538e29SHisping Lin 
330*df538e29SHisping Lin 				ret = blk_dwrite(dev_desc,
331*df538e29SHisping Lin 						 part_info.start + info_current.backup_index,
332*df538e29SHisping Lin 						 info_current.backup_num,
333*df538e29SHisping Lin 						 backup_data);
334*df538e29SHisping Lin 				if (ret != info_current.backup_num) {
335*df538e29SHisping Lin 					printf("TEEC: blk_dwrite fail\n");
336*df538e29SHisping Lin 					return -1;
337*df538e29SHisping Lin 				}
338*df538e29SHisping Lin 				free(backup_data);
339*df538e29SHisping Lin 				backup_data = NULL;
340*df538e29SHisping Lin 			}
341*df538e29SHisping Lin 		}
342*df538e29SHisping Lin 	}
343*df538e29SHisping Lin 	memset(data, 0, sizeof(data));
344*df538e29SHisping Lin 	ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data);
345*df538e29SHisping Lin 	if (ret != 1) {
346*df538e29SHisping Lin 		printf("TEEC: blk_dwrite fail\n");
347*df538e29SHisping Lin 		return -1;
348*df538e29SHisping Lin 	}
349*df538e29SHisping Lin 	return 0;
350*df538e29SHisping Lin error:
351*df538e29SHisping Lin 	if (backup_data)
352*df538e29SHisping Lin 		free(backup_data);
353*df538e29SHisping Lin 	return -1;
354*df538e29SHisping Lin }
355*df538e29SHisping Lin 
356*df538e29SHisping Lin static int rkss_read_multi_sections(unsigned char *data, unsigned long index, unsigned int num)
357*df538e29SHisping Lin {
358*df538e29SHisping Lin 	unsigned long ret;
359*df538e29SHisping Lin 
360*df538e29SHisping Lin 	if (check_security_exist(1) < 0)
361*df538e29SHisping Lin 		return -1;
362*df538e29SHisping Lin 
363*df538e29SHisping Lin 	ret = blk_dread(dev_desc, part_info.start + index, num, data);
364*df538e29SHisping Lin 	if (ret != num) {
365*df538e29SHisping Lin 		printf("TEEC: blk_dread fail\n");
366*df538e29SHisping Lin 		return -1;
367*df538e29SHisping Lin 	}
368*df538e29SHisping Lin 	return 0;
369*df538e29SHisping Lin }
370*df538e29SHisping Lin 
371*df538e29SHisping Lin static int rkss_write_multi_sections(unsigned char *data, unsigned long index, unsigned int num)
372*df538e29SHisping Lin {
373*df538e29SHisping Lin 	unsigned long ret;
374*df538e29SHisping Lin 	int result;
375*df538e29SHisping Lin 
376*df538e29SHisping Lin 	result = rkss_backup_sections(index, num);
377*df538e29SHisping Lin 	if (result < 0) {
378*df538e29SHisping Lin 		printf("TEEC: rkss_backup_sections fail\n");
379*df538e29SHisping Lin 		return -1;
380*df538e29SHisping Lin 	}
381*df538e29SHisping Lin 
382*df538e29SHisping Lin 	if (check_security_exist(1) < 0)
383*df538e29SHisping Lin 		return -1;
384*df538e29SHisping Lin 
385*df538e29SHisping Lin 	ret = blk_dwrite(dev_desc, part_info.start + index, num, data);
386*df538e29SHisping Lin 	if (ret != num) {
387*df538e29SHisping Lin 		printf("TEEC: blk_dwrite fail\n");
388*df538e29SHisping Lin 		return -1;
389*df538e29SHisping Lin 	}
390*df538e29SHisping Lin 	return 0;
391*df538e29SHisping Lin }
392*df538e29SHisping Lin 
393*df538e29SHisping Lin static int rkss_read_patition_tables(unsigned char *data)
394*df538e29SHisping Lin {
395*df538e29SHisping Lin 	unsigned long ret;
396*df538e29SHisping Lin 
397*df538e29SHisping Lin 	if (check_security_exist(1) < 0)
398*df538e29SHisping Lin 		return -1;
399*df538e29SHisping Lin 
400*df538e29SHisping Lin 	ret = blk_dread(dev_desc, part_info.start, RKSS_PARTITION_TABLE_COUNT, data);
401*df538e29SHisping Lin 	if (ret != RKSS_PARTITION_TABLE_COUNT) {
402*df538e29SHisping Lin 		printf("TEEC: blk_dread fail\n");
403*df538e29SHisping Lin 		return -1;
404*df538e29SHisping Lin 	}
405*df538e29SHisping Lin 	return 0;
406*df538e29SHisping Lin }
407*df538e29SHisping Lin 
408*df538e29SHisping Lin #ifdef DEBUG_RKFSS
409*df538e29SHisping Lin static void rkss_dump(void *data, unsigned int len)
410*df538e29SHisping Lin {
411*df538e29SHisping Lin 	char *p = (char *)data;
412*df538e29SHisping Lin 	unsigned int i = 0;
413*df538e29SHisping Lin 	printf("-------------- DUMP %d --------------\n", len);
414*df538e29SHisping Lin 	for (i = 0; i < len; i++) {
415*df538e29SHisping Lin 		printf("%02x ", *(p + i));
416*df538e29SHisping Lin 	}
417*df538e29SHisping Lin 	printf("\n");
418*df538e29SHisping Lin 	printf("------------- DUMP END -------------\n");
419*df538e29SHisping Lin }
420*df538e29SHisping Lin 
421*df538e29SHisping Lin static void rkss_dump_ptable(void)
422*df538e29SHisping Lin {
423*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
424*df538e29SHisping Lin 	int i, n, ret;
425*df538e29SHisping Lin 	void *pdata;
426*df538e29SHisping Lin 	struct rkss_file_info *p;
427*df538e29SHisping Lin 	unsigned char *table_data;
428*df538e29SHisping Lin 
429*df538e29SHisping Lin 	table_data = malloc(RKSS_PARTITION_TABLE_COUNT * RKSS_DATA_SECTION_LEN);
430*df538e29SHisping Lin 	if (table_data == NULL) {
431*df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
432*df538e29SHisping Lin 		return;
433*df538e29SHisping Lin 	}
434*df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
435*df538e29SHisping Lin 	if (ret < 0) {
436*df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
437*df538e29SHisping Lin 		return;
438*df538e29SHisping Lin 	}
439*df538e29SHisping Lin 
440*df538e29SHisping Lin 	printf("-------------- DUMP ptable --------------\n");
441*df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
442*df538e29SHisping Lin 		rkss.index = i;
443*df538e29SHisping Lin 		memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN);
444*df538e29SHisping Lin 
445*df538e29SHisping Lin 		for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) {
446*df538e29SHisping Lin 			pdata = rkss.data;
447*df538e29SHisping Lin 			p = (struct rkss_file_info *)pdata;
448*df538e29SHisping Lin 			p += n;
449*df538e29SHisping Lin 			printf("[%02d][%c] %s , inx:%d, size:%d",
450*df538e29SHisping Lin 					i*RKSS_EACH_SECTION_FILECOUNT+n, p->used == 0 ? 'F':'T', p->name,
451*df538e29SHisping Lin 					p->index, p->size);
452*df538e29SHisping Lin 		}
453*df538e29SHisping Lin 	}
454*df538e29SHisping Lin 	free(table_data);
455*df538e29SHisping Lin 	printf("-------------- DUMP END --------------\n");
456*df538e29SHisping Lin }
457*df538e29SHisping Lin 
458*df538e29SHisping Lin static void rkss_dump_usedflags(void)
459*df538e29SHisping Lin {
460*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
461*df538e29SHisping Lin 	int ret;
462*df538e29SHisping Lin 
463*df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
464*df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
465*df538e29SHisping Lin 	if (ret < 0) {
466*df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
467*df538e29SHisping Lin 		return;
468*df538e29SHisping Lin 	}
469*df538e29SHisping Lin 	rkss_dump(rkss.data, RKSS_DATA_SECTION_LEN);
470*df538e29SHisping Lin }
471*df538e29SHisping Lin #endif
472*df538e29SHisping Lin 
473*df538e29SHisping Lin static int rkss_verify_ptable(unsigned char *table_data)
474*df538e29SHisping Lin {
475*df538e29SHisping Lin 	unsigned char *cp, *vp;
476*df538e29SHisping Lin 	struct rkss_file_verification *verify;
477*df538e29SHisping Lin 	int ret, i;
478*df538e29SHisping Lin 
479*df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
480*df538e29SHisping Lin 		cp = table_data + (i * RKSS_DATA_SECTION_LEN);
481*df538e29SHisping Lin 		vp = cp + RKSS_DATA_SECTION_LEN - sizeof(struct rkss_file_verification);
482*df538e29SHisping Lin 		verify = (struct rkss_file_verification *)(void *)vp;
483*df538e29SHisping Lin 
484*df538e29SHisping Lin 		if (verify->version != RKSS_VERSION_V1
485*df538e29SHisping Lin 				|| verify->checkstr != RKSS_CHECK_STR) {
486*df538e29SHisping Lin 			printf("TEEC: verify [%d] fail, cleanning ....", i);
487*df538e29SHisping Lin 			memset(cp, 0, RKSS_DATA_SECTION_LEN);
488*df538e29SHisping Lin 			verify->checkstr = RKSS_CHECK_STR;
489*df538e29SHisping Lin 			verify->version = RKSS_VERSION_V1;
490*df538e29SHisping Lin 		}
491*df538e29SHisping Lin 	}
492*df538e29SHisping Lin 	ret = rkss_write_multi_sections(table_data, 0, RKSS_PARTITION_TABLE_COUNT);
493*df538e29SHisping Lin 	if (ret < 0) {
494*df538e29SHisping Lin 		printf("TEEC: rkss_write_multi_sections failed!!! ret: %d.\n", ret);
495*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
496*df538e29SHisping Lin 	}
497*df538e29SHisping Lin 	debug("TEEC: verify ptable success.\n");
498*df538e29SHisping Lin 	return TEEC_SUCCESS;
499*df538e29SHisping Lin }
500*df538e29SHisping Lin 
501*df538e29SHisping Lin static int rkss_verify_usedflags(struct rk_secure_storage *rkss)
502*df538e29SHisping Lin {
503*df538e29SHisping Lin 	uint8_t *flags = (uint8_t *)rkss->data;
504*df538e29SHisping Lin 	int i, duel, flag, n, value, ret;
505*df538e29SHisping Lin 	uint8_t *flagw;
506*df538e29SHisping Lin 
507*df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT + 1; i++) {
508*df538e29SHisping Lin 		duel = *(flags + (int)i/2);
509*df538e29SHisping Lin 		flag = i & 0x1 ? duel & 0x0F : (duel & 0xF0) >> 4;
510*df538e29SHisping Lin 		if (flag != 0x1) {
511*df538e29SHisping Lin 			debug("TEEC: init usedflags section ...\n");
512*df538e29SHisping Lin 			memset(rkss->data, 0x00, RKSS_DATA_SECTION_LEN);
513*df538e29SHisping Lin 			for (n = 0; n < RKSS_PARTITION_TABLE_COUNT + 1; n++) {
514*df538e29SHisping Lin 				flagw = (uint8_t *)rkss->data + (int)n/2;
515*df538e29SHisping Lin 				value = 0x1;
516*df538e29SHisping Lin 				*flagw = n & 0x1 ? (*flagw & 0xF0) | (value & 0x0F) :
517*df538e29SHisping Lin 						(*flagw & 0x0F) | (value << 4);
518*df538e29SHisping Lin 			}
519*df538e29SHisping Lin 			ret = rkss_write_multi_sections(rkss->data, rkss->index, 1);
520*df538e29SHisping Lin 			if (ret < 0) {
521*df538e29SHisping Lin 				printf("TEEC: clean usedflags section failed!!! ret: %d.\n", ret);
522*df538e29SHisping Lin 				return TEEC_ERROR_GENERIC;
523*df538e29SHisping Lin 			}
524*df538e29SHisping Lin 
525*df538e29SHisping Lin 			return TEEC_SUCCESS;
526*df538e29SHisping Lin 		}
527*df538e29SHisping Lin 	}
528*df538e29SHisping Lin 	debug("TEEC: rkss_verify_usedflags: sucess.\n");
529*df538e29SHisping Lin 	return TEEC_SUCCESS;
530*df538e29SHisping Lin }
531*df538e29SHisping Lin 
532*df538e29SHisping Lin static int rkss_get_fileinfo_by_index(int fd, struct rkss_file_info *pfileinfo)
533*df538e29SHisping Lin {
534*df538e29SHisping Lin 	int i = fd / RKSS_EACH_SECTION_FILECOUNT;
535*df538e29SHisping Lin 	int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i);
536*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
537*df538e29SHisping Lin 	int ret;
538*df538e29SHisping Lin 	void *pdata;
539*df538e29SHisping Lin 	struct rkss_file_info *p;
540*df538e29SHisping Lin 
541*df538e29SHisping Lin 	rkss.index = i;
542*df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
543*df538e29SHisping Lin 	if (ret < 0) {
544*df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
545*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
546*df538e29SHisping Lin 	}
547*df538e29SHisping Lin 
548*df538e29SHisping Lin 	pdata = rkss.data;
549*df538e29SHisping Lin 	p = (struct rkss_file_info *)pdata;
550*df538e29SHisping Lin 	p += n;
551*df538e29SHisping Lin 
552*df538e29SHisping Lin 	if (p->used != 1) {
553*df538e29SHisping Lin 		debug("TEEC: error: unused section!\n");
554*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
555*df538e29SHisping Lin 	}
556*df538e29SHisping Lin 	debug("TEEC: rkss_get_fileinfo_by_index p->used = %d p->name=%s p->index=%d p->size=%d\n",
557*df538e29SHisping Lin 		p->used, p->name, p->index, p->size);
558*df538e29SHisping Lin 	memcpy(pfileinfo, p, sizeof(struct rkss_file_info));
559*df538e29SHisping Lin 
560*df538e29SHisping Lin 	return TEEC_SUCCESS;
561*df538e29SHisping Lin }
562*df538e29SHisping Lin 
563*df538e29SHisping Lin static int rkss_get_fileinfo_by_name(
564*df538e29SHisping Lin 		char *filename, struct rkss_file_info *pfileinfo)
565*df538e29SHisping Lin {
566*df538e29SHisping Lin 	int i, ret;
567*df538e29SHisping Lin 	uint8_t n = 0;
568*df538e29SHisping Lin 	unsigned int len;
569*df538e29SHisping Lin 	unsigned char *table_data;
570*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
571*df538e29SHisping Lin 	void *pdata;
572*df538e29SHisping Lin 	struct rkss_file_info *p;
573*df538e29SHisping Lin 	const char *split = "/";
574*df538e29SHisping Lin 	char *last_inpos;
575*df538e29SHisping Lin 	char *last_svpos;
576*df538e29SHisping Lin 	char *cur_inpos;
577*df538e29SHisping Lin 	char *cur_svpos;
578*df538e29SHisping Lin 	int size_in, size_sv;
579*df538e29SHisping Lin 
580*df538e29SHisping Lin 	len = strlen(filename);
581*df538e29SHisping Lin 	if (len > RKSS_MAX_NAME_LENGTH - 1) {
582*df538e29SHisping Lin 		printf("TEEC: filename is too long. length:%u\n", len);
583*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
584*df538e29SHisping Lin 	}
585*df538e29SHisping Lin 
586*df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
587*df538e29SHisping Lin 	if (table_data == NULL) {
588*df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
589*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
590*df538e29SHisping Lin 	}
591*df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
592*df538e29SHisping Lin 	if (ret < 0) {
593*df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
594*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
595*df538e29SHisping Lin 	}
596*df538e29SHisping Lin 
597*df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
598*df538e29SHisping Lin 		rkss.index = i;
599*df538e29SHisping Lin 		memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN);
600*df538e29SHisping Lin 
601*df538e29SHisping Lin 		for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) {
602*df538e29SHisping Lin 			pdata = rkss.data;
603*df538e29SHisping Lin 			p = (struct rkss_file_info *)pdata;
604*df538e29SHisping Lin 			p += n;
605*df538e29SHisping Lin 
606*df538e29SHisping Lin 			if (p->used == 0)
607*df538e29SHisping Lin 				continue;
608*df538e29SHisping Lin 
609*df538e29SHisping Lin 			/* Full Matching*/
610*df538e29SHisping Lin 			if (!strcmp(p->name, filename)) {
611*df538e29SHisping Lin 				debug("TEEC: rkss_get_fileinfo_by_name: hit table[%d/%d], index[%d/%d]\n",
612*df538e29SHisping Lin 						i, RKSS_PARTITION_TABLE_COUNT, n, RKSS_EACH_SECTION_FILECOUNT);
613*df538e29SHisping Lin 				memcpy(pfileinfo, p, sizeof(struct rkss_file_info));
614*df538e29SHisping Lin 				free(table_data);
615*df538e29SHisping Lin 				return i * RKSS_EACH_SECTION_FILECOUNT + n;
616*df538e29SHisping Lin 			}
617*df538e29SHisping Lin 
618*df538e29SHisping Lin 			/* Folder Matching*/
619*df538e29SHisping Lin 			last_inpos = filename;
620*df538e29SHisping Lin 			last_svpos = p->name;
621*df538e29SHisping Lin 			cur_inpos = NULL;
622*df538e29SHisping Lin 			cur_svpos = NULL;
623*df538e29SHisping Lin 			do {
624*df538e29SHisping Lin 				cur_inpos = strstr(last_inpos, split);
625*df538e29SHisping Lin 				cur_svpos = strstr(last_svpos, split);
626*df538e29SHisping Lin 				size_in = cur_inpos == NULL ?
627*df538e29SHisping Lin 						(int)strlen(last_inpos) : cur_inpos - last_inpos;
628*df538e29SHisping Lin 				size_sv = cur_svpos == NULL ?
629*df538e29SHisping Lin 						(int)strlen(last_svpos) : cur_svpos - last_svpos;
630*df538e29SHisping Lin 
631*df538e29SHisping Lin 				ret = memcmp(last_inpos, last_svpos, size_in);
632*df538e29SHisping Lin 				last_inpos = cur_inpos + 1;
633*df538e29SHisping Lin 				last_svpos = cur_svpos + 1;
634*df538e29SHisping Lin 
635*df538e29SHisping Lin 				if (size_in != size_sv || ret)
636*df538e29SHisping Lin 					goto UNMATCHFOLDER;
637*df538e29SHisping Lin 
638*df538e29SHisping Lin 			} while (cur_inpos && cur_svpos);
639*df538e29SHisping Lin 
640*df538e29SHisping Lin 			debug("TEEC: Matched folder: %s\n", p->name);
641*df538e29SHisping Lin 			free(table_data);
642*df538e29SHisping Lin 			return TEEC_ERROR_GENERIC;
643*df538e29SHisping Lin UNMATCHFOLDER:
644*df538e29SHisping Lin 			debug("TEEC: Unmatched ...\n");
645*df538e29SHisping Lin 		}
646*df538e29SHisping Lin 	}
647*df538e29SHisping Lin 	debug("TEEC: rkss_get_fileinfo_by_name: file or dir no found!\n");
648*df538e29SHisping Lin 	free(table_data);
649*df538e29SHisping Lin 	return TEEC_ERROR_GENERIC;
650*df538e29SHisping Lin }
651*df538e29SHisping Lin 
652*df538e29SHisping Lin static int rkss_get_dirs_by_name(char *filename)
653*df538e29SHisping Lin {
654*df538e29SHisping Lin 	int i, ret;
655*df538e29SHisping Lin 	uint8_t n = 0;
656*df538e29SHisping Lin 	unsigned int len;
657*df538e29SHisping Lin 	unsigned char *table_data;
658*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
659*df538e29SHisping Lin 	void *pdata;
660*df538e29SHisping Lin 	struct rkss_file_info *p;
661*df538e29SHisping Lin 	char *chk, *file, *subdir;
662*df538e29SHisping Lin 
663*df538e29SHisping Lin 	len = strlen(filename);
664*df538e29SHisping Lin 	if (len > RKSS_MAX_NAME_LENGTH - 1) {
665*df538e29SHisping Lin 		printf("TEEC: filename is too long. length:%u\n", len);
666*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
667*df538e29SHisping Lin 	}
668*df538e29SHisping Lin 
669*df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
670*df538e29SHisping Lin 	if (table_data == NULL) {
671*df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
672*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
673*df538e29SHisping Lin 	}
674*df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
675*df538e29SHisping Lin 	if (ret < 0) {
676*df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
677*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
678*df538e29SHisping Lin 	}
679*df538e29SHisping Lin 
680*df538e29SHisping Lin 	dir_num = 0;
681*df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
682*df538e29SHisping Lin 		rkss.index = i;
683*df538e29SHisping Lin 		memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN);
684*df538e29SHisping Lin 
685*df538e29SHisping Lin 		for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) {
686*df538e29SHisping Lin 			pdata = rkss.data;
687*df538e29SHisping Lin 			p = (struct rkss_file_info *)pdata;
688*df538e29SHisping Lin 			p += n;
689*df538e29SHisping Lin 
690*df538e29SHisping Lin 			if (p->used == 0)
691*df538e29SHisping Lin 				continue;
692*df538e29SHisping Lin 
693*df538e29SHisping Lin 			/* Full Matching*/
694*df538e29SHisping Lin 			ret = memcmp(p->name, filename, strlen(filename));
695*df538e29SHisping Lin 			debug("TEEC: comparing [fd:%d] : %s ?= %s , ret:%d\n",
696*df538e29SHisping Lin 					i*RKSS_EACH_SECTION_FILECOUNT+n, p->name, filename, ret);
697*df538e29SHisping Lin 			if (!ret && strlen(p->name) > strlen(filename)) {
698*df538e29SHisping Lin 				chk = p->name + strlen(filename);
699*df538e29SHisping Lin 				if (*chk == '/') {
700*df538e29SHisping Lin 					file = p->name + strlen(filename) + 1;
701*df538e29SHisping Lin 					subdir = strtok(file, "/");
702*df538e29SHisping Lin 					debug("TEEC: found: %s\n", subdir);
703*df538e29SHisping Lin 					strcpy(dir_cache[dir_num], subdir);
704*df538e29SHisping Lin 					++dir_num;
705*df538e29SHisping Lin 				}
706*df538e29SHisping Lin 			}
707*df538e29SHisping Lin 		}
708*df538e29SHisping Lin 	}
709*df538e29SHisping Lin 	free(table_data);
710*df538e29SHisping Lin 	return dir_num;
711*df538e29SHisping Lin }
712*df538e29SHisping Lin 
713*df538e29SHisping Lin static int rkss_get_empty_section_from_usedflags(int section_size)
714*df538e29SHisping Lin {
715*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
716*df538e29SHisping Lin 	int i, ret;
717*df538e29SHisping Lin 	int count0 = 0;
718*df538e29SHisping Lin 	uint8_t *flag;
719*df538e29SHisping Lin 	uint8_t value;
720*df538e29SHisping Lin 
721*df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
722*df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
723*df538e29SHisping Lin 	if (ret < 0) {
724*df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
725*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
726*df538e29SHisping Lin 	}
727*df538e29SHisping Lin 
728*df538e29SHisping Lin 	for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) {
729*df538e29SHisping Lin 		flag = (uint8_t *)rkss.data + (int)i/2;
730*df538e29SHisping Lin 		value = i & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4;
731*df538e29SHisping Lin 
732*df538e29SHisping Lin 		if (value == 0x0) {
733*df538e29SHisping Lin 			if (++count0 == section_size) {
734*df538e29SHisping Lin 				return (i + 1 - section_size);
735*df538e29SHisping Lin 			}
736*df538e29SHisping Lin 		} else {
737*df538e29SHisping Lin 			count0 = 0;
738*df538e29SHisping Lin 		}
739*df538e29SHisping Lin 	}
740*df538e29SHisping Lin 
741*df538e29SHisping Lin 	printf("TEEC: Not enough space available in secure storage !\n");
742*df538e29SHisping Lin 	return TEEC_ERROR_GENERIC;
743*df538e29SHisping Lin }
744*df538e29SHisping Lin 
745*df538e29SHisping Lin static int rkss_incref_multi_usedflags_sections(unsigned int index, unsigned int num)
746*df538e29SHisping Lin {
747*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
748*df538e29SHisping Lin 	int ret, value, i;
749*df538e29SHisping Lin 	uint8_t *flag;
750*df538e29SHisping Lin 
751*df538e29SHisping Lin 	if ((index + num) >= RKSS_DATA_SECTION_COUNT) {
752*df538e29SHisping Lin 		printf("TEEC: index[%d] out of range.\n", index);
753*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
754*df538e29SHisping Lin 	}
755*df538e29SHisping Lin 
756*df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
757*df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
758*df538e29SHisping Lin 	if (ret < 0) {
759*df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
760*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
761*df538e29SHisping Lin 	}
762*df538e29SHisping Lin 
763*df538e29SHisping Lin 	for (i = 0; i < num; i++, index++) {
764*df538e29SHisping Lin 		flag = (uint8_t *)rkss.data + (int)index/2;
765*df538e29SHisping Lin 		value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4;
766*df538e29SHisping Lin 		if (++value > 0xF) {
767*df538e29SHisping Lin 			printf("TEEC: reference out of data: %d\n", value);
768*df538e29SHisping Lin 			value = 0xF;
769*df538e29SHisping Lin 		}
770*df538e29SHisping Lin 		*flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) :
771*df538e29SHisping Lin 				(*flag & 0x0F) | (value << 4);
772*df538e29SHisping Lin 	}
773*df538e29SHisping Lin 	ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
774*df538e29SHisping Lin 	if (ret < 0) {
775*df538e29SHisping Lin 		printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
776*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
777*df538e29SHisping Lin 	}
778*df538e29SHisping Lin 	return TEEC_SUCCESS;
779*df538e29SHisping Lin }
780*df538e29SHisping Lin 
781*df538e29SHisping Lin static int rkss_decref_multi_usedflags_sections(unsigned int index, unsigned int num)
782*df538e29SHisping Lin {
783*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
784*df538e29SHisping Lin 	int ret, value, i;
785*df538e29SHisping Lin 	uint8_t *flag;
786*df538e29SHisping Lin 
787*df538e29SHisping Lin 	if ((index + num) >= RKSS_DATA_SECTION_COUNT) {
788*df538e29SHisping Lin 		printf("TEEC: index[%d] out of range.\n", index);
789*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
790*df538e29SHisping Lin 	}
791*df538e29SHisping Lin 
792*df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
793*df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
794*df538e29SHisping Lin 	if (ret < 0) {
795*df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
796*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
797*df538e29SHisping Lin 	}
798*df538e29SHisping Lin 	for (i = 0; i < num; i++, index++) {
799*df538e29SHisping Lin 		flag = (uint8_t *)rkss.data + (int)index/2;
800*df538e29SHisping Lin 		value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4;
801*df538e29SHisping Lin 		if (--value < 0) {
802*df538e29SHisping Lin 			printf("TEEC: reference out of data: %d\n", value);
803*df538e29SHisping Lin 			value = 0x0;
804*df538e29SHisping Lin 		}
805*df538e29SHisping Lin 		*flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) :
806*df538e29SHisping Lin 				(*flag & 0x0F) | (value << 4);
807*df538e29SHisping Lin 	}
808*df538e29SHisping Lin 	ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
809*df538e29SHisping Lin 	if (ret < 0) {
810*df538e29SHisping Lin 		printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
811*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
812*df538e29SHisping Lin 	}
813*df538e29SHisping Lin 	return TEEC_SUCCESS;
814*df538e29SHisping Lin }
815*df538e29SHisping Lin 
816*df538e29SHisping Lin static int rkss_write_empty_ptable(struct rkss_file_info *pfileinfo)
817*df538e29SHisping Lin {
818*df538e29SHisping Lin 	unsigned char *table_data;
819*df538e29SHisping Lin 	int ret, i, n;
820*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
821*df538e29SHisping Lin 	void *pdata;
822*df538e29SHisping Lin 	struct rkss_file_info *p;
823*df538e29SHisping Lin 
824*df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
825*df538e29SHisping Lin 	if (table_data == NULL) {
826*df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
827*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
828*df538e29SHisping Lin 	}
829*df538e29SHisping Lin 
830*df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
831*df538e29SHisping Lin 	if (ret < 0) {
832*df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
833*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
834*df538e29SHisping Lin 	}
835*df538e29SHisping Lin 
836*df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
837*df538e29SHisping Lin 		rkss.index = i;
838*df538e29SHisping Lin 		memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN);
839*df538e29SHisping Lin 		for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) {
840*df538e29SHisping Lin 			pdata = rkss.data;
841*df538e29SHisping Lin 			p = (struct rkss_file_info *)pdata;
842*df538e29SHisping Lin 			p += n;
843*df538e29SHisping Lin 			if (p->used == 0) {
844*df538e29SHisping Lin 				debug("TEEC: write ptable in [%d][%d] .\n", i, n);
845*df538e29SHisping Lin 				memcpy(p, pfileinfo, sizeof(struct rkss_file_info));
846*df538e29SHisping Lin 				p->used = 1;
847*df538e29SHisping Lin 				p->id = n;
848*df538e29SHisping Lin 				debug("TEEC: write emt ptable : [%d,%d] name:%s, index:%d,\n",
849*df538e29SHisping Lin 					i, n, p->name, p->index);
850*df538e29SHisping Lin 				debug("TEEC: size:%d, used:%d\n",  p->size, p->used);
851*df538e29SHisping Lin 				ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
852*df538e29SHisping Lin 				if (ret < 0) {
853*df538e29SHisping Lin 					printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
854*df538e29SHisping Lin 					free(table_data);
855*df538e29SHisping Lin 					return TEEC_ERROR_GENERIC;
856*df538e29SHisping Lin 				}
857*df538e29SHisping Lin 
858*df538e29SHisping Lin 				free(table_data);
859*df538e29SHisping Lin 				return i * RKSS_EACH_SECTION_FILECOUNT + n;
860*df538e29SHisping Lin 			}
861*df538e29SHisping Lin 		}
862*df538e29SHisping Lin 	}
863*df538e29SHisping Lin 	debug("TEEC: No enough ptable space available in secure storage.\n");
864*df538e29SHisping Lin 	free(table_data);
865*df538e29SHisping Lin 	return TEEC_ERROR_GENERIC;
866*df538e29SHisping Lin }
867*df538e29SHisping Lin 
868*df538e29SHisping Lin static int rkss_write_back_ptable(int fd, struct rkss_file_info *pfileinfo)
869*df538e29SHisping Lin {
870*df538e29SHisping Lin 	int i = fd / RKSS_EACH_SECTION_FILECOUNT;
871*df538e29SHisping Lin 	int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i);
872*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
873*df538e29SHisping Lin 	int ret;
874*df538e29SHisping Lin 	void *pdata;
875*df538e29SHisping Lin 	struct rkss_file_info *p;
876*df538e29SHisping Lin 
877*df538e29SHisping Lin 	rkss.index = i;
878*df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
879*df538e29SHisping Lin 	if (ret < 0) {
880*df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
881*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
882*df538e29SHisping Lin 	}
883*df538e29SHisping Lin 
884*df538e29SHisping Lin 	pdata = rkss.data;
885*df538e29SHisping Lin 	p = (struct rkss_file_info *)pdata;
886*df538e29SHisping Lin 	p += n;
887*df538e29SHisping Lin 
888*df538e29SHisping Lin 	memcpy(p, pfileinfo, sizeof(struct rkss_file_info));
889*df538e29SHisping Lin 	debug("TEEC: write ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n",
890*df538e29SHisping Lin 			i, n, p->name, p->index, p->size, p->used);
891*df538e29SHisping Lin 
892*df538e29SHisping Lin 	ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
893*df538e29SHisping Lin 	if (ret < 0) {
894*df538e29SHisping Lin 		printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
895*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
896*df538e29SHisping Lin 	}
897*df538e29SHisping Lin #ifdef DEBUG_RKFSS
898*df538e29SHisping Lin 	rkss_dump_ptable();
899*df538e29SHisping Lin #endif
900*df538e29SHisping Lin 
901*df538e29SHisping Lin 	return TEEC_SUCCESS;
902*df538e29SHisping Lin }
903*df538e29SHisping Lin 
904*df538e29SHisping Lin static uint32_t ree_fs_new_open(size_t num_params,
905*df538e29SHisping Lin 				   struct tee_ioctl_param *params)
906*df538e29SHisping Lin {
907*df538e29SHisping Lin 	char *filename;
908*df538e29SHisping Lin 	int fd;
909*df538e29SHisping Lin 	struct rkss_file_info p = {0};
910*df538e29SHisping Lin 
911*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
912*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
913*df538e29SHisping Lin 
914*df538e29SHisping Lin 	filename = (char *)(size_t)params[1].u.memref.shm_id;
915*df538e29SHisping Lin 	if (!filename)
916*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
917*df538e29SHisping Lin 
918*df538e29SHisping Lin 	if (strlen(filename) > RKSS_MAX_NAME_LENGTH) {
919*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_open: file name too long. %s\n", filename);
920*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
921*df538e29SHisping Lin 	}
922*df538e29SHisping Lin 
923*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_open open file: %s, len: %zu\n", filename, strlen(filename));
924*df538e29SHisping Lin 	fd = rkss_get_fileinfo_by_name(filename, &p);
925*df538e29SHisping Lin 	if (fd < 0) {
926*df538e29SHisping Lin 		debug("TEEC: ree_fs_new_open : no such file. %s\n", filename);
927*df538e29SHisping Lin 		return TEEC_ERROR_ITEM_NOT_FOUND;
928*df538e29SHisping Lin 	}
929*df538e29SHisping Lin 
930*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_open! %s, fd: %d\n", filename, fd);
931*df538e29SHisping Lin 
932*df538e29SHisping Lin 	params[2].u.value.a = fd;
933*df538e29SHisping Lin 	return TEEC_SUCCESS;
934*df538e29SHisping Lin }
935*df538e29SHisping Lin 
936*df538e29SHisping Lin static TEEC_Result ree_fs_new_create(size_t num_params,
937*df538e29SHisping Lin 				     struct tee_ioctl_param *params)
938*df538e29SHisping Lin {
939*df538e29SHisping Lin 	char *filename;
940*df538e29SHisping Lin 	int fd;
941*df538e29SHisping Lin 	int ret, num;
942*df538e29SHisping Lin 	struct rkss_file_info p = {0};
943*df538e29SHisping Lin 	/* file open flags: O_RDWR | O_CREAT | O_TRUNC
944*df538e29SHisping Lin 	 * if file exists, we must remove it first.
945*df538e29SHisping Lin 	 */
946*df538e29SHisping Lin 	ret = rkss_begin_commit();
947*df538e29SHisping Lin 	if (ret < 0) {
948*df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
949*df538e29SHisping Lin 		return -1;
950*df538e29SHisping Lin 	}
951*df538e29SHisping Lin 
952*df538e29SHisping Lin 	filename = (char *)(size_t)params[1].u.memref.shm_id;
953*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
954*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
955*df538e29SHisping Lin 	if (!filename)
956*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
957*df538e29SHisping Lin 
958*df538e29SHisping Lin 	if (strlen(filename) > RKSS_MAX_NAME_LENGTH) {
959*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_create: file name too long. %s\n", filename);
960*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
961*df538e29SHisping Lin 	}
962*df538e29SHisping Lin 
963*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_create create file: %s, len: %zu\n", filename, strlen(filename));
964*df538e29SHisping Lin 	fd = rkss_get_fileinfo_by_name(filename, &p);
965*df538e29SHisping Lin 	if (fd >= 0) {
966*df538e29SHisping Lin 		debug("TEEC: ree_fs_new_create : file exist, clear it. %s\n", filename);
967*df538e29SHisping Lin 		/* decrease ref from usedflags */
968*df538e29SHisping Lin 		num = p.size / RKSS_DATA_SECTION_LEN + 1;
969*df538e29SHisping Lin 		ret = rkss_decref_multi_usedflags_sections(p.index, num);
970*df538e29SHisping Lin 		if (ret < 0) {
971*df538e29SHisping Lin 			printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
972*df538e29SHisping Lin 			return TEEC_ERROR_GENERIC;
973*df538e29SHisping Lin 		}
974*df538e29SHisping Lin 
975*df538e29SHisping Lin 		/* rm from ptable */
976*df538e29SHisping Lin 		memset(&p, 0, sizeof(struct rkss_file_info));
977*df538e29SHisping Lin 		ret = rkss_write_back_ptable(fd, &p);
978*df538e29SHisping Lin 		if (ret < 0) {
979*df538e29SHisping Lin 			printf("TEEC: ree_fs_new_create : write back error %d\n", ret);
980*df538e29SHisping Lin 			return TEEC_ERROR_GENERIC;
981*df538e29SHisping Lin 		}
982*df538e29SHisping Lin 	}
983*df538e29SHisping Lin 
984*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_create create new file: %s\n", filename);
985*df538e29SHisping Lin 	strcpy(p.name, filename);
986*df538e29SHisping Lin 	p.index = 0;
987*df538e29SHisping Lin 	p.size = 0;
988*df538e29SHisping Lin 	p.used = 1;
989*df538e29SHisping Lin 	p.flags = RK_FS_R | RK_FS_W;
990*df538e29SHisping Lin 	fd = rkss_write_empty_ptable(&p);
991*df538e29SHisping Lin 	if (fd < 0) {
992*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_create : write empty ptable error. %s\n", filename);
993*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
994*df538e29SHisping Lin 	}
995*df538e29SHisping Lin 
996*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_create ! %s, fd: %d.\n", filename, fd);
997*df538e29SHisping Lin 
998*df538e29SHisping Lin 	params[2].u.value.a = fd;
999*df538e29SHisping Lin 
1000*df538e29SHisping Lin 	ret = rkss_finish_commit();
1001*df538e29SHisping Lin 	if (ret < 0) {
1002*df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1003*df538e29SHisping Lin 		return -1;
1004*df538e29SHisping Lin 	}
1005*df538e29SHisping Lin 	return TEEC_SUCCESS;
1006*df538e29SHisping Lin }
1007*df538e29SHisping Lin 
1008*df538e29SHisping Lin static TEEC_Result ree_fs_new_close(size_t num_params,
1009*df538e29SHisping Lin 				    struct tee_ioctl_param *params)
1010*df538e29SHisping Lin {
1011*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_close !\n");
1012*df538e29SHisping Lin 	UNREFERENCED_PARAMETER(params);
1013*df538e29SHisping Lin 	UNREFERENCED_PARAMETER(num_params);
1014*df538e29SHisping Lin 	return TEEC_SUCCESS;
1015*df538e29SHisping Lin }
1016*df538e29SHisping Lin 
1017*df538e29SHisping Lin static TEEC_Result ree_fs_new_read(size_t num_params,
1018*df538e29SHisping Lin 				   struct tee_ioctl_param *params)
1019*df538e29SHisping Lin {
1020*df538e29SHisping Lin 	uint8_t *data;
1021*df538e29SHisping Lin 	size_t len;
1022*df538e29SHisping Lin 	off_t offs;
1023*df538e29SHisping Lin 	int fd;
1024*df538e29SHisping Lin 	int ret;
1025*df538e29SHisping Lin 	struct rkss_file_info p = {0};
1026*df538e29SHisping Lin 	int di, section_num;
1027*df538e29SHisping Lin 	uint8_t *temp_file_data;
1028*df538e29SHisping Lin 
1029*df538e29SHisping Lin 	fd = params[0].u.value.b;
1030*df538e29SHisping Lin 	offs = params[0].u.value.c;
1031*df538e29SHisping Lin 
1032*df538e29SHisping Lin 	data = (uint8_t *)(size_t)params[1].u.memref.shm_id;
1033*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1034*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1035*df538e29SHisping Lin 
1036*df538e29SHisping Lin 	if (!data)
1037*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1038*df538e29SHisping Lin 	len = params[1].u.memref.size;
1039*df538e29SHisping Lin 
1040*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_read! fd:%d, len:%zu, offs:%ld\n", fd, len, offs);
1041*df538e29SHisping Lin 
1042*df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_index(fd, &p);
1043*df538e29SHisping Lin 	if (ret < 0) {
1044*df538e29SHisping Lin 		debug("TEEC: unavailable fd: %d!\n", fd);
1045*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1046*df538e29SHisping Lin 	}
1047*df538e29SHisping Lin 
1048*df538e29SHisping Lin 	if (offs >= p.size)
1049*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1050*df538e29SHisping Lin 
1051*df538e29SHisping Lin 	section_num = p.size / RKSS_DATA_SECTION_LEN + 1;
1052*df538e29SHisping Lin 	temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN);
1053*df538e29SHisping Lin 	ret = rkss_read_multi_sections(temp_file_data, p.index, section_num);
1054*df538e29SHisping Lin 	if (ret < 0) {
1055*df538e29SHisping Lin 		printf("TEEC: unavailable file index!\n");
1056*df538e29SHisping Lin 		free(temp_file_data);
1057*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1058*df538e29SHisping Lin 	}
1059*df538e29SHisping Lin 	di = (offs + len) > p.size ? (p.size - offs) : len;
1060*df538e29SHisping Lin 	memcpy(data, temp_file_data + offs, di);
1061*df538e29SHisping Lin 	free(temp_file_data);
1062*df538e29SHisping Lin 	temp_file_data = 0;
1063*df538e29SHisping Lin 	params[1].u.memref.size = di;
1064*df538e29SHisping Lin 
1065*df538e29SHisping Lin 	return TEEC_SUCCESS;
1066*df538e29SHisping Lin }
1067*df538e29SHisping Lin 
1068*df538e29SHisping Lin static TEEC_Result ree_fs_new_write(size_t num_params,
1069*df538e29SHisping Lin 				    struct tee_ioctl_param *params)
1070*df538e29SHisping Lin {
1071*df538e29SHisping Lin 	uint8_t *data;
1072*df538e29SHisping Lin 	size_t len;
1073*df538e29SHisping Lin 	off_t offs;
1074*df538e29SHisping Lin 	struct rkss_file_info p = {0};
1075*df538e29SHisping Lin 	int ret, fd, new_size;
1076*df538e29SHisping Lin 	int section_num;
1077*df538e29SHisping Lin 	uint8_t *file_data = 0, *temp_file_data = 0;
1078*df538e29SHisping Lin 
1079*df538e29SHisping Lin 	ret = rkss_begin_commit();
1080*df538e29SHisping Lin 	if (ret < 0) {
1081*df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1082*df538e29SHisping Lin 		return -1;
1083*df538e29SHisping Lin 	}
1084*df538e29SHisping Lin 
1085*df538e29SHisping Lin 	fd = params[0].u.value.b;
1086*df538e29SHisping Lin 	offs = params[0].u.value.c;
1087*df538e29SHisping Lin 
1088*df538e29SHisping Lin 	data = (uint8_t *)(size_t)params[1].u.memref.shm_id;
1089*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1090*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1091*df538e29SHisping Lin 	if (!data)
1092*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1093*df538e29SHisping Lin 	len = params[1].u.memref.size;
1094*df538e29SHisping Lin 
1095*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_write ! fd:%d, len:%zu, offs:%ld \n", fd, len, offs);
1096*df538e29SHisping Lin 
1097*df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_index(fd, &p);
1098*df538e29SHisping Lin 	if (ret < 0) {
1099*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_write: fd:%d unvailable!\n", fd);
1100*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1101*df538e29SHisping Lin 	}
1102*df538e29SHisping Lin 
1103*df538e29SHisping Lin 	new_size = offs + len > p.size ? offs + len : p.size;
1104*df538e29SHisping Lin 	file_data = malloc(new_size);
1105*df538e29SHisping Lin 	if (!file_data)
1106*df538e29SHisping Lin 		return TEEC_ERROR_OUT_OF_MEMORY;
1107*df538e29SHisping Lin 
1108*df538e29SHisping Lin 	if (p.size != 0) {
1109*df538e29SHisping Lin 		/* Read old file data out */
1110*df538e29SHisping Lin 		section_num = p.size / RKSS_DATA_SECTION_LEN + 1;
1111*df538e29SHisping Lin 		temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN);
1112*df538e29SHisping Lin 		ret = rkss_read_multi_sections(temp_file_data, p.index, section_num);
1113*df538e29SHisping Lin 		if (ret < 0) {
1114*df538e29SHisping Lin 			printf("TEEC: unavailable file index %d section_num %d\n", p.index, section_num);
1115*df538e29SHisping Lin 			ret = TEEC_ERROR_GENERIC;
1116*df538e29SHisping Lin 			goto out;
1117*df538e29SHisping Lin 		}
1118*df538e29SHisping Lin 		memcpy(file_data, temp_file_data, p.size);
1119*df538e29SHisping Lin 		free(temp_file_data);
1120*df538e29SHisping Lin 		temp_file_data = 0;
1121*df538e29SHisping Lin 		ret = rkss_decref_multi_usedflags_sections(p.index, section_num);
1122*df538e29SHisping Lin 		if (ret < 0) {
1123*df538e29SHisping Lin 			printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
1124*df538e29SHisping Lin 			ret = TEEC_ERROR_GENERIC;
1125*df538e29SHisping Lin 			goto out;
1126*df538e29SHisping Lin 		}
1127*df538e29SHisping Lin 	}
1128*df538e29SHisping Lin 
1129*df538e29SHisping Lin 	/* update new file info */
1130*df538e29SHisping Lin 	memcpy(file_data + offs, data, len);
1131*df538e29SHisping Lin 	p.size = new_size;
1132*df538e29SHisping Lin 	section_num = new_size / RKSS_DATA_SECTION_LEN + 1;
1133*df538e29SHisping Lin 	p.index = rkss_get_empty_section_from_usedflags(section_num);
1134*df538e29SHisping Lin 	debug("TEEC: Get Empty section in %d\n", p.index);
1135*df538e29SHisping Lin 	p.used = 1;
1136*df538e29SHisping Lin 	ret = rkss_incref_multi_usedflags_sections(p.index, section_num);
1137*df538e29SHisping Lin 	if (ret < 0) {
1138*df538e29SHisping Lin 		printf("TEEC: rkss_incref_multi_usedflags_sections error !\n");
1139*df538e29SHisping Lin 		ret = TEEC_ERROR_GENERIC;
1140*df538e29SHisping Lin 		goto out;
1141*df538e29SHisping Lin 	}
1142*df538e29SHisping Lin 
1143*df538e29SHisping Lin 	ret = rkss_write_back_ptable(fd, &p);
1144*df538e29SHisping Lin 	if (ret < 0) {
1145*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_write: write ptable error!\n");
1146*df538e29SHisping Lin 		ret = TEEC_ERROR_GENERIC;
1147*df538e29SHisping Lin 		goto out;
1148*df538e29SHisping Lin 	}
1149*df538e29SHisping Lin 
1150*df538e29SHisping Lin 	/* write new file data */
1151*df538e29SHisping Lin 	temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN);
1152*df538e29SHisping Lin 	memset(temp_file_data, 0, section_num * RKSS_DATA_SECTION_LEN);
1153*df538e29SHisping Lin 	memcpy(temp_file_data, file_data, p.size);
1154*df538e29SHisping Lin 	rkss_write_multi_sections(temp_file_data, p.index, section_num);
1155*df538e29SHisping Lin 	free(temp_file_data);
1156*df538e29SHisping Lin 	temp_file_data = 0;
1157*df538e29SHisping Lin 
1158*df538e29SHisping Lin #ifdef DEBUG_RKFSS
1159*df538e29SHisping Lin 	rkss_dump_usedflags();
1160*df538e29SHisping Lin #endif
1161*df538e29SHisping Lin 
1162*df538e29SHisping Lin out:
1163*df538e29SHisping Lin 	if (file_data)
1164*df538e29SHisping Lin 		free(file_data);
1165*df538e29SHisping Lin 	if (temp_file_data) {
1166*df538e29SHisping Lin 		free(temp_file_data);
1167*df538e29SHisping Lin 		temp_file_data = 0;
1168*df538e29SHisping Lin 	}
1169*df538e29SHisping Lin 	ret = rkss_finish_commit();
1170*df538e29SHisping Lin 	if (ret < 0) {
1171*df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1172*df538e29SHisping Lin 		return -1;
1173*df538e29SHisping Lin 	}
1174*df538e29SHisping Lin 
1175*df538e29SHisping Lin 	return TEEC_SUCCESS;
1176*df538e29SHisping Lin }
1177*df538e29SHisping Lin 
1178*df538e29SHisping Lin /* TODO: update file data space */
1179*df538e29SHisping Lin static TEEC_Result ree_fs_new_truncate(size_t num_params,
1180*df538e29SHisping Lin 				       struct tee_ioctl_param *params)
1181*df538e29SHisping Lin {
1182*df538e29SHisping Lin 	size_t len;
1183*df538e29SHisping Lin 	int fd, ret;
1184*df538e29SHisping Lin 	struct rkss_file_info p = {0};
1185*df538e29SHisping Lin 	unsigned int section_num_old, section_num_new;
1186*df538e29SHisping Lin 
1187*df538e29SHisping Lin 	ret = rkss_begin_commit();
1188*df538e29SHisping Lin 	if (ret < 0) {
1189*df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1190*df538e29SHisping Lin 		return -1;
1191*df538e29SHisping Lin 	}
1192*df538e29SHisping Lin 
1193*df538e29SHisping Lin 	fd = params[0].u.value.b;
1194*df538e29SHisping Lin 	len = params[0].u.value.c;
1195*df538e29SHisping Lin 
1196*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_truncate: fd:%d, lenth:%zu\n", fd, len);
1197*df538e29SHisping Lin 
1198*df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_index(fd, &p);
1199*df538e29SHisping Lin 	if (ret < 0) {
1200*df538e29SHisping Lin 		printf("TEEC: fd:%d unvailable!\n", fd);
1201*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1202*df538e29SHisping Lin 	}
1203*df538e29SHisping Lin 	if (len > p.size) {
1204*df538e29SHisping Lin 		printf("TEEC: truncate error!\n");
1205*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1206*df538e29SHisping Lin 	}
1207*df538e29SHisping Lin 	section_num_old = p.size / RKSS_DATA_SECTION_LEN + 1;
1208*df538e29SHisping Lin 	section_num_new = len / RKSS_DATA_SECTION_LEN + 1;
1209*df538e29SHisping Lin 	ret = rkss_decref_multi_usedflags_sections(p.index + section_num_new, section_num_old - section_num_new);
1210*df538e29SHisping Lin 	if (ret < 0) {
1211*df538e29SHisping Lin 		printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
1212*df538e29SHisping Lin 		ret = TEEC_ERROR_GENERIC;
1213*df538e29SHisping Lin 	}
1214*df538e29SHisping Lin 	p.size = len;
1215*df538e29SHisping Lin 	ret = rkss_write_back_ptable(fd, &p);
1216*df538e29SHisping Lin 	if (ret < 0) {
1217*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_truncate: write ptable error!\n");
1218*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1219*df538e29SHisping Lin 	}
1220*df538e29SHisping Lin 	ret = rkss_finish_commit();
1221*df538e29SHisping Lin 	if (ret < 0) {
1222*df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1223*df538e29SHisping Lin 		return -1;
1224*df538e29SHisping Lin 	}
1225*df538e29SHisping Lin 
1226*df538e29SHisping Lin 	return TEEC_SUCCESS;
1227*df538e29SHisping Lin }
1228*df538e29SHisping Lin 
1229*df538e29SHisping Lin static TEEC_Result ree_fs_new_remove(size_t num_params,
1230*df538e29SHisping Lin 				     struct tee_ioctl_param *params)
1231*df538e29SHisping Lin {
1232*df538e29SHisping Lin 	char *filename;
1233*df538e29SHisping Lin 	struct rkss_file_info p = {0};
1234*df538e29SHisping Lin 	int ret, fd, num;
1235*df538e29SHisping Lin 
1236*df538e29SHisping Lin 	ret = rkss_begin_commit();
1237*df538e29SHisping Lin 	if (ret < 0) {
1238*df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1239*df538e29SHisping Lin 		return -1;
1240*df538e29SHisping Lin 	}
1241*df538e29SHisping Lin 
1242*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1243*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1244*df538e29SHisping Lin 
1245*df538e29SHisping Lin 	filename = (char *)(size_t)params[1].u.memref.shm_id;
1246*df538e29SHisping Lin 	if (!filename)
1247*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1248*df538e29SHisping Lin 
1249*df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_name(filename, &p);
1250*df538e29SHisping Lin 	if (ret < 0) {
1251*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_remove: no such file. %s\n", filename);
1252*df538e29SHisping Lin 		return 0;
1253*df538e29SHisping Lin 	}
1254*df538e29SHisping Lin 	fd = ret;
1255*df538e29SHisping Lin 
1256*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_remove! %s fd:%d index:%d size:%d\n", filename, fd, p.index, p.size);
1257*df538e29SHisping Lin 
1258*df538e29SHisping Lin 	/* decrease ref from usedflags */
1259*df538e29SHisping Lin 	num = p.size / RKSS_DATA_SECTION_LEN + 1;
1260*df538e29SHisping Lin 	ret = rkss_decref_multi_usedflags_sections(p.index, num);
1261*df538e29SHisping Lin 	if (ret < 0) {
1262*df538e29SHisping Lin 		printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
1263*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1264*df538e29SHisping Lin 	}
1265*df538e29SHisping Lin 
1266*df538e29SHisping Lin 	/* rm from ptable */
1267*df538e29SHisping Lin 	memset(&p, 0, sizeof(struct rkss_file_info));
1268*df538e29SHisping Lin 	ret = rkss_write_back_ptable(fd, &p);
1269*df538e29SHisping Lin 	if (ret < 0) {
1270*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_remove: write back error %d\n", ret);
1271*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1272*df538e29SHisping Lin 	}
1273*df538e29SHisping Lin 
1274*df538e29SHisping Lin #ifdef DEBUG_RKFSS
1275*df538e29SHisping Lin 	rkss_dump_ptable();
1276*df538e29SHisping Lin 	rkss_dump_usedflags();
1277*df538e29SHisping Lin #endif
1278*df538e29SHisping Lin 	ret = rkss_finish_commit();
1279*df538e29SHisping Lin 	if (ret < 0) {
1280*df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1281*df538e29SHisping Lin 		return -1;
1282*df538e29SHisping Lin 	}
1283*df538e29SHisping Lin 
1284*df538e29SHisping Lin 	return TEEC_SUCCESS;
1285*df538e29SHisping Lin }
1286*df538e29SHisping Lin 
1287*df538e29SHisping Lin static TEEC_Result ree_fs_new_rename(size_t num_params,
1288*df538e29SHisping Lin 				     struct tee_ioctl_param *params)
1289*df538e29SHisping Lin {
1290*df538e29SHisping Lin 	char *old_fname;
1291*df538e29SHisping Lin 	char *new_fname;
1292*df538e29SHisping Lin 	struct rkss_file_info p = {0};
1293*df538e29SHisping Lin 	int ret;
1294*df538e29SHisping Lin 
1295*df538e29SHisping Lin 	ret = rkss_begin_commit();
1296*df538e29SHisping Lin 	if (ret < 0) {
1297*df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1298*df538e29SHisping Lin 		return -1;
1299*df538e29SHisping Lin 	}
1300*df538e29SHisping Lin 
1301*df538e29SHisping Lin 	old_fname = (char *)(size_t)params[1].u.memref.shm_id;
1302*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1303*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1304*df538e29SHisping Lin 	if (!old_fname)
1305*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1306*df538e29SHisping Lin 
1307*df538e29SHisping Lin 	new_fname = (char *)(size_t)params[2].u.memref.shm_id;
1308*df538e29SHisping Lin 	debug("TEEC: params[2].u.memref.shm_id = 0x%llx params[2].u.memref.shm_offs = 0x%llx\n",
1309*df538e29SHisping Lin 		params[2].u.memref.shm_id, params[2].u.memref.shm_offs);
1310*df538e29SHisping Lin 	if (!new_fname)
1311*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1312*df538e29SHisping Lin 
1313*df538e29SHisping Lin 	if (strlen(new_fname) > RKSS_MAX_NAME_LENGTH) {
1314*df538e29SHisping Lin 		printf("TEEC: new file name too long. %s\n", new_fname);
1315*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1316*df538e29SHisping Lin 	}
1317*df538e29SHisping Lin 
1318*df538e29SHisping Lin 	debug("TEEC: rename: %s -> %s\n", old_fname, new_fname);
1319*df538e29SHisping Lin 
1320*df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_name(old_fname, &p);
1321*df538e29SHisping Lin 	if (ret < 0) {
1322*df538e29SHisping Lin 		printf("TEEC: filename: %s no found.\n", old_fname);
1323*df538e29SHisping Lin 		return TEEC_ERROR_ITEM_NOT_FOUND;
1324*df538e29SHisping Lin 	}
1325*df538e29SHisping Lin 
1326*df538e29SHisping Lin 	strcpy(p.name, new_fname);
1327*df538e29SHisping Lin 
1328*df538e29SHisping Lin 	ret = rkss_write_back_ptable(ret, &p);
1329*df538e29SHisping Lin 	if (ret < 0) {
1330*df538e29SHisping Lin 		printf("TEEC: write ptable error!\n");
1331*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1332*df538e29SHisping Lin 	}
1333*df538e29SHisping Lin 	ret = rkss_finish_commit();
1334*df538e29SHisping Lin 	if (ret < 0) {
1335*df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1336*df538e29SHisping Lin 		return -1;
1337*df538e29SHisping Lin 	}
1338*df538e29SHisping Lin 
1339*df538e29SHisping Lin 	return TEEC_SUCCESS;
1340*df538e29SHisping Lin }
1341*df538e29SHisping Lin 
1342*df538e29SHisping Lin static TEEC_Result ree_fs_new_opendir(size_t num_params,
1343*df538e29SHisping Lin 				      struct tee_ioctl_param *params)
1344*df538e29SHisping Lin {
1345*df538e29SHisping Lin 	char *dirname;
1346*df538e29SHisping Lin 	int ret;
1347*df538e29SHisping Lin 
1348*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1349*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1350*df538e29SHisping Lin 
1351*df538e29SHisping Lin 	dirname = (char *)(size_t)params[1].u.memref.shm_id;
1352*df538e29SHisping Lin 	if (!dirname)
1353*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1354*df538e29SHisping Lin 
1355*df538e29SHisping Lin 	dir_seek = 0;
1356*df538e29SHisping Lin 	ret = rkss_get_dirs_by_name(dirname);
1357*df538e29SHisping Lin 	if (ret < 0) {
1358*df538e29SHisping Lin 		printf("TEEC: ree_fs_new_opendir: error\n");
1359*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1360*df538e29SHisping Lin 	}
1361*df538e29SHisping Lin 
1362*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_opendir: %s, seek/num:%d/%d\n", dirname, dir_seek, dir_num);
1363*df538e29SHisping Lin 	return TEEC_SUCCESS;
1364*df538e29SHisping Lin }
1365*df538e29SHisping Lin 
1366*df538e29SHisping Lin static TEEC_Result ree_fs_new_closedir(size_t num_params,
1367*df538e29SHisping Lin 				       struct tee_ioctl_param *params)
1368*df538e29SHisping Lin {
1369*df538e29SHisping Lin 	if (num_params != 1 ||
1370*df538e29SHisping Lin 	    (params[0].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) !=
1371*df538e29SHisping Lin 			TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT)
1372*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1373*df538e29SHisping Lin 
1374*df538e29SHisping Lin 	dir_seek = 0;
1375*df538e29SHisping Lin 	dir_num = 0;
1376*df538e29SHisping Lin 
1377*df538e29SHisping Lin 	return TEEC_SUCCESS;
1378*df538e29SHisping Lin }
1379*df538e29SHisping Lin 
1380*df538e29SHisping Lin static TEEC_Result ree_fs_new_readdir(size_t num_params,
1381*df538e29SHisping Lin 				      struct tee_ioctl_param *params)
1382*df538e29SHisping Lin {
1383*df538e29SHisping Lin 	char *dirname;
1384*df538e29SHisping Lin 	size_t len;
1385*df538e29SHisping Lin 	size_t dirname_len;
1386*df538e29SHisping Lin 
1387*df538e29SHisping Lin 	dirname = (char *)(size_t)params[1].u.memref.shm_id;
1388*df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1389*df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1390*df538e29SHisping Lin 	if (!dirname)
1391*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1392*df538e29SHisping Lin 	len = params[1].u.memref.size;
1393*df538e29SHisping Lin 
1394*df538e29SHisping Lin 	debug("TEEC: seek/num:%d/%d\n", dir_seek, dir_num);
1395*df538e29SHisping Lin 	if (dir_seek == dir_num) {
1396*df538e29SHisping Lin 		params[1].u.memref.size = 0;
1397*df538e29SHisping Lin 		debug("ree_fs_new_readdir: END \n");
1398*df538e29SHisping Lin 		return TEEC_ERROR_BAD_STATE;
1399*df538e29SHisping Lin 	}
1400*df538e29SHisping Lin 
1401*df538e29SHisping Lin 	dirname_len = strlen(dir_cache[dir_seek]) + 1;
1402*df538e29SHisping Lin 	params[1].u.memref.size = dirname_len;
1403*df538e29SHisping Lin 	if (dirname_len > len)
1404*df538e29SHisping Lin 		return TEEC_ERROR_SHORT_BUFFER;
1405*df538e29SHisping Lin 
1406*df538e29SHisping Lin 	strcpy(dirname, dir_cache[dir_seek]);
1407*df538e29SHisping Lin 	++dir_seek;
1408*df538e29SHisping Lin 
1409*df538e29SHisping Lin 	debug("TEEC: ree_fs_new_readdir: %s\n", dirname);
1410*df538e29SHisping Lin 
1411*df538e29SHisping Lin 	return TEEC_SUCCESS;
1412*df538e29SHisping Lin }
1413*df538e29SHisping Lin 
1414*df538e29SHisping Lin int tee_supp_rk_fs_init_v1(void)
1415*df538e29SHisping Lin {
1416*df538e29SHisping Lin 	assert(sizeof(struct rkss_file_info) == 126);
1417*df538e29SHisping Lin 	assert(512 / sizeof(struct rkss_file_info) == RKSS_EACH_SECTION_FILECOUNT);
1418*df538e29SHisping Lin 
1419*df538e29SHisping Lin 	int ret;
1420*df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
1421*df538e29SHisping Lin 	unsigned char *table_data;
1422*df538e29SHisping Lin 
1423*df538e29SHisping Lin 	if (check_security_exist(0) < 0)
1424*df538e29SHisping Lin 		return 0;
1425*df538e29SHisping Lin 
1426*df538e29SHisping Lin 	ret = rkss_resume();
1427*df538e29SHisping Lin 	if (ret < 0) {
1428*df538e29SHisping Lin 		printf("rkss_resume failed!");
1429*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1430*df538e29SHisping Lin 	}
1431*df538e29SHisping Lin 
1432*df538e29SHisping Lin 	/* clean secure storage*/
1433*df538e29SHisping Lin #ifdef DEBUG_CLEAN_RKSS
1434*df538e29SHisping Lin 	int i = 0;
1435*df538e29SHisping Lin 	for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) {
1436*df538e29SHisping Lin 		memset(rkss.data, 0, RKSS_DATA_SECTION_LEN);
1437*df538e29SHisping Lin 		rkss.index = i;
1438*df538e29SHisping Lin 		rkss_write_multi_sections(rkss.data, rkss.index, 1);
1439*df538e29SHisping Lin 		printf("TEEC: cleaned [%d]", i);
1440*df538e29SHisping Lin 	}
1441*df538e29SHisping Lin #endif
1442*df538e29SHisping Lin 	ret = rkss_begin_commit();
1443*df538e29SHisping Lin 	if (ret < 0) {
1444*df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1445*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1446*df538e29SHisping Lin 	}
1447*df538e29SHisping Lin 
1448*df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
1449*df538e29SHisping Lin 	if (table_data == NULL) {
1450*df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
1451*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1452*df538e29SHisping Lin 	}
1453*df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
1454*df538e29SHisping Lin 	if (ret < 0) {
1455*df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
1456*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1457*df538e29SHisping Lin 	}
1458*df538e29SHisping Lin 
1459*df538e29SHisping Lin 	/* Verify Partition Table*/
1460*df538e29SHisping Lin 	rkss_verify_ptable(table_data);
1461*df538e29SHisping Lin 	free(table_data);
1462*df538e29SHisping Lin 	table_data = NULL;
1463*df538e29SHisping Lin 
1464*df538e29SHisping Lin 	/* Verify Usedflags Section*/
1465*df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
1466*df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
1467*df538e29SHisping Lin 	if (ret < 0) {
1468*df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
1469*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1470*df538e29SHisping Lin 	}
1471*df538e29SHisping Lin 	ret = rkss_verify_usedflags(&rkss);
1472*df538e29SHisping Lin 	if (ret < 0) {
1473*df538e29SHisping Lin 		printf("TEEC: rkss_verify_usedflags fail ! ret: %d.\n", ret);
1474*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1475*df538e29SHisping Lin 	}
1476*df538e29SHisping Lin 
1477*df538e29SHisping Lin #ifdef DEBUG_RKFSS
1478*df538e29SHisping Lin 	rkss_dump_ptable();
1479*df538e29SHisping Lin 	rkss_dump_usedflags();
1480*df538e29SHisping Lin #endif
1481*df538e29SHisping Lin 
1482*df538e29SHisping Lin 	ret = rkss_finish_commit();
1483*df538e29SHisping Lin 	if (ret < 0) {
1484*df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1485*df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1486*df538e29SHisping Lin 	}
1487*df538e29SHisping Lin 
1488*df538e29SHisping Lin 	return TEEC_SUCCESS;
1489*df538e29SHisping Lin }
1490*df538e29SHisping Lin 
1491*df538e29SHisping Lin static bool tee_supp_param_is_value(struct tee_ioctl_param *param)
1492*df538e29SHisping Lin {
1493*df538e29SHisping Lin 	switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
1494*df538e29SHisping Lin 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
1495*df538e29SHisping Lin 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
1496*df538e29SHisping Lin 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
1497*df538e29SHisping Lin 		return true;
1498*df538e29SHisping Lin 	default:
1499*df538e29SHisping Lin 		return false;
1500*df538e29SHisping Lin 	}
1501*df538e29SHisping Lin }
1502*df538e29SHisping Lin 
1503*df538e29SHisping Lin static int rkss_step;
1504*df538e29SHisping Lin int tee_supp_rk_fs_process_v1(size_t num_params,
1505*df538e29SHisping Lin 			struct tee_ioctl_param *params)
1506*df538e29SHisping Lin {
1507*df538e29SHisping Lin 	if (!num_params || !tee_supp_param_is_value(params))
1508*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1509*df538e29SHisping Lin 
1510*df538e29SHisping Lin 	switch (params->u.value.a) {
1511*df538e29SHisping Lin 	case OPTEE_MRF_OPEN:
1512*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_OPEN!\n", rkss_step++);
1513*df538e29SHisping Lin 		return ree_fs_new_open(num_params, params);
1514*df538e29SHisping Lin 	case OPTEE_MRF_CREATE:
1515*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_CREATE!\n", rkss_step++);
1516*df538e29SHisping Lin 		return ree_fs_new_create(num_params, params);
1517*df538e29SHisping Lin 	case OPTEE_MRF_CLOSE:
1518*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_CLOSE!\n", rkss_step++);
1519*df538e29SHisping Lin 		return ree_fs_new_close(num_params, params);
1520*df538e29SHisping Lin 	case OPTEE_MRF_READ:
1521*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_READ!\n", rkss_step++);
1522*df538e29SHisping Lin 		return ree_fs_new_read(num_params, params);
1523*df538e29SHisping Lin 	case OPTEE_MRF_WRITE:
1524*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_WRITE!\n", rkss_step++);
1525*df538e29SHisping Lin 		return ree_fs_new_write(num_params, params);
1526*df538e29SHisping Lin 	case OPTEE_MRF_TRUNCATE:
1527*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_TRUNCATE!\n", rkss_step++);
1528*df538e29SHisping Lin 		return ree_fs_new_truncate(num_params, params);
1529*df538e29SHisping Lin 	case OPTEE_MRF_REMOVE:
1530*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_REMOVE!\n", rkss_step++);
1531*df538e29SHisping Lin 		return ree_fs_new_remove(num_params, params);
1532*df538e29SHisping Lin 	case OPTEE_MRF_RENAME:
1533*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_RENAME!\n", rkss_step++);
1534*df538e29SHisping Lin 		return ree_fs_new_rename(num_params, params);
1535*df538e29SHisping Lin 	case OPTEE_MRF_OPENDIR:
1536*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_OPENDIR!\n", rkss_step++);
1537*df538e29SHisping Lin 		return ree_fs_new_opendir(num_params, params);
1538*df538e29SHisping Lin 	case OPTEE_MRF_CLOSEDIR:
1539*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_CLOSEDIR!\n", rkss_step++);
1540*df538e29SHisping Lin 		return ree_fs_new_closedir(num_params, params);
1541*df538e29SHisping Lin 	case OPTEE_MRF_READDIR:
1542*df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_READDIR!\n", rkss_step++);
1543*df538e29SHisping Lin 		return ree_fs_new_readdir(num_params, params);
1544*df538e29SHisping Lin 	default:
1545*df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1546*df538e29SHisping Lin 	}
1547*df538e29SHisping Lin }
1548