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