xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientRkNewFs_v1.c (revision adcf6ed65e7d4394e7ddd389166a5519e1ebbe64)
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 
check_security_exist(int print_flag)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  */
rkss_begin_commit(void)139df538e29SHisping Lin static int rkss_begin_commit(void)
140df538e29SHisping Lin {
1411f284470SHisping 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 
1531f284470SHisping Lin 	data = memalign(CONFIG_SYS_CACHELINE_SIZE, RKSS_DATA_SECTION_LEN);
1541f284470SHisping Lin 	if (!data) {
1551f284470SHisping Lin 		printf("TEEC: malloc data fail\n");
1561f284470SHisping Lin 		return -1;
1571f284470SHisping Lin 	}
1581f284470SHisping 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);
1621f284470SHisping 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 
rkss_finish_commit(void)170df538e29SHisping Lin static int rkss_finish_commit(void)
171df538e29SHisping Lin {
1721f284470SHisping 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__);
1791f284470SHisping Lin 	data = memalign(CONFIG_SYS_CACHELINE_SIZE, RKSS_DATA_SECTION_LEN);
1801f284470SHisping Lin 	if (!data) {
1811f284470SHisping Lin 		printf("TEEC: malloc data fail\n");
1821f284470SHisping Lin 		return -1;
1831f284470SHisping Lin 	}
1841f284470SHisping 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);
1871f284470SHisping 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 
rkss_backup_sections(unsigned long index,unsigned int num)195df538e29SHisping Lin static int rkss_backup_sections(unsigned long index, unsigned int num)
196df538e29SHisping Lin {
1971f284470SHisping 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 
2061f284470SHisping Lin 	data = memalign(CONFIG_SYS_CACHELINE_SIZE, RKSS_DATA_SECTION_LEN);
2071f284470SHisping Lin 	if (!data) {
2081f284470SHisping Lin 		printf("TEEC: malloc data fail\n");
2091f284470SHisping Lin 		goto error;
2101f284470SHisping 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");
2141f284470SHisping 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 
2441f284470SHisping 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");
2531f284470SHisping 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");
2601f284470SHisping 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");
2741f284470SHisping Lin 			goto error;
275df538e29SHisping Lin 		}
276df538e29SHisping Lin 	}
2771f284470SHisping Lin 	free(data);
278df538e29SHisping Lin 	return 0;
2791f284470SHisping Lin 
280df538e29SHisping Lin error:
2811f284470SHisping Lin 	if (data)
2821f284470SHisping Lin 		free(data);
283df538e29SHisping Lin 	if (backup_data)
284df538e29SHisping Lin 		free(backup_data);
285df538e29SHisping Lin 	return -1;
286df538e29SHisping Lin }
287df538e29SHisping Lin 
rkss_resume(void)288df538e29SHisping Lin static int rkss_resume(void)
289df538e29SHisping Lin {
2901f284470SHisping 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 
3001f284470SHisping Lin 	data = memalign(CONFIG_SYS_CACHELINE_SIZE, RKSS_DATA_SECTION_LEN);
3011f284470SHisping Lin 	if (!data) {
3021f284470SHisping Lin 		printf("TEEC: malloc data fail\n");
3031f284470SHisping Lin 		goto error;
3041f284470SHisping 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");
3081f284470SHisping 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 				}
3381f284470SHisping Lin 				backup_data = memalign(CONFIG_SYS_CACHELINE_SIZE,
3391f284470SHisping 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");
3511f284470SHisping 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");
3601f284470SHisping Lin 					goto error;
361df538e29SHisping Lin 				}
362df538e29SHisping Lin 				free(backup_data);
363df538e29SHisping Lin 			}
364df538e29SHisping Lin 		}
365df538e29SHisping Lin 	}
3661f284470SHisping 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");
3701f284470SHisping Lin 		goto error;
371df538e29SHisping Lin 	}
3721f284470SHisping Lin 	free(data);
373df538e29SHisping Lin 	return 0;
3741f284470SHisping Lin 
375df538e29SHisping Lin error:
3761f284470SHisping Lin 	if (data)
3771f284470SHisping Lin 		free(data);
378df538e29SHisping Lin 	if (backup_data)
379df538e29SHisping Lin 		free(backup_data);
380df538e29SHisping Lin 	return -1;
381df538e29SHisping Lin }
382df538e29SHisping Lin 
rkss_read_multi_sections(unsigned char * data,unsigned long index,unsigned int num)383df538e29SHisping Lin static int rkss_read_multi_sections(unsigned char *data, unsigned long index, unsigned int num)
384df538e29SHisping Lin {
3851f284470SHisping 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 
3911f284470SHisping Lin 	tmp_data = memalign(CONFIG_SYS_CACHELINE_SIZE, num * RKSS_DATA_SECTION_LEN);
3921f284470SHisping Lin 	if (!tmp_data) {
3931f284470SHisping Lin 		printf("TEEC: malloc tmp_data fail\n");
394df538e29SHisping Lin 		return -1;
395df538e29SHisping Lin 	}
3961f284470SHisping Lin 	ret = blk_dread(dev_desc, part_info.start + index, num, tmp_data);
3971f284470SHisping Lin 	if (ret != num) {
3981f284470SHisping Lin 		printf("TEEC: blk_dread fail\n");
3991f284470SHisping Lin 		free(tmp_data);
4001f284470SHisping Lin 		return -1;
4011f284470SHisping Lin 	}
4021f284470SHisping Lin 	memcpy(data, tmp_data, num * RKSS_DATA_SECTION_LEN);
4031f284470SHisping Lin 	free(tmp_data);
404df538e29SHisping Lin 	return 0;
405df538e29SHisping Lin }
406df538e29SHisping Lin 
rkss_write_multi_sections(unsigned char * data,unsigned long index,unsigned int num)407df538e29SHisping Lin static int rkss_write_multi_sections(unsigned char *data, unsigned long index, unsigned int num)
408df538e29SHisping Lin {
4091f284470SHisping 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 
4221f284470SHisping Lin 	tmp_data = memalign(CONFIG_SYS_CACHELINE_SIZE, num * RKSS_DATA_SECTION_LEN);
4231f284470SHisping Lin 	if (!tmp_data) {
4241f284470SHisping Lin 		printf("TEEC: malloc tmp_data fail\n");
4251f284470SHisping Lin 		return -1;
4261f284470SHisping Lin 	}
4271f284470SHisping Lin 	memcpy(tmp_data, data, num * RKSS_DATA_SECTION_LEN);
4281f284470SHisping Lin 	ret = blk_dwrite(dev_desc, part_info.start + index, num, tmp_data);
4291f284470SHisping 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 
rkss_read_patition_tables(unsigned char * data)437df538e29SHisping Lin static int rkss_read_patition_tables(unsigned char *data)
438df538e29SHisping Lin {
439df538e29SHisping Lin 	unsigned long ret;
4401f284470SHisping Lin 	unsigned char *table_data = NULL;
441df538e29SHisping Lin 
442df538e29SHisping Lin 	if (check_security_exist(1) < 0)
443df538e29SHisping Lin 		return -1;
444df538e29SHisping Lin 
4451f284470SHisping Lin 	table_data = memalign(CONFIG_SYS_CACHELINE_SIZE,
4461f284470SHisping Lin 			      RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
4471f284470SHisping Lin 	if (!table_data) {
4481f284470SHisping Lin 		printf("TEEC: malloc table_data fail\n");
449df538e29SHisping Lin 		return -1;
450df538e29SHisping Lin 	}
4511f284470SHisping Lin 	ret = blk_dread(dev_desc, part_info.start, RKSS_PARTITION_TABLE_COUNT, table_data);
4521f284470SHisping Lin 	if (ret != RKSS_PARTITION_TABLE_COUNT) {
4531f284470SHisping Lin 		printf("TEEC: blk_dread fail\n");
4541f284470SHisping Lin 		free(table_data);
4551f284470SHisping Lin 		return -1;
4561f284470SHisping Lin 	}
4571f284470SHisping Lin 	memcpy(data, table_data, RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
4581f284470SHisping Lin 	free(table_data);
459df538e29SHisping Lin 	return 0;
460df538e29SHisping Lin }
461df538e29SHisping Lin 
462df538e29SHisping Lin #ifdef DEBUG_RKFSS
rkss_dump(void * data,unsigned int len)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 
rkss_dump_ptable(void)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 
rkss_dump_usedflags(void)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 
rkss_verify_ptable(unsigned char * table_data)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;
531*adcf6ed6SHisping Lin 	int ret, i, write_table_flag = 0;
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;
544*adcf6ed6SHisping Lin 			write_table_flag = 1;
545df538e29SHisping Lin 		}
546df538e29SHisping Lin 	}
547*adcf6ed6SHisping Lin 	if (write_table_flag == 1) {
548df538e29SHisping Lin 		ret = rkss_write_multi_sections(table_data, 0, RKSS_PARTITION_TABLE_COUNT);
549df538e29SHisping Lin 		if (ret < 0) {
550df538e29SHisping Lin 			printf("TEEC: rkss_write_multi_sections failed!!! ret: %d.\n", ret);
551df538e29SHisping Lin 			return TEEC_ERROR_GENERIC;
552df538e29SHisping Lin 		}
553*adcf6ed6SHisping Lin 	}
554df538e29SHisping Lin 	debug("TEEC: verify ptable success.\n");
555df538e29SHisping Lin 	return TEEC_SUCCESS;
556df538e29SHisping Lin }
557df538e29SHisping Lin 
rkss_verify_usedflags(struct rk_secure_storage * rkss)558df538e29SHisping Lin static int rkss_verify_usedflags(struct rk_secure_storage *rkss)
559df538e29SHisping Lin {
560df538e29SHisping Lin 	uint8_t *flags = (uint8_t *)rkss->data;
561df538e29SHisping Lin 	int i, duel, flag, n, value, ret;
562df538e29SHisping Lin 	uint8_t *flagw;
563df538e29SHisping Lin 
564df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT + 1; i++) {
565df538e29SHisping Lin 		duel = *(flags + (int)i/2);
566df538e29SHisping Lin 		flag = i & 0x1 ? duel & 0x0F : (duel & 0xF0) >> 4;
567df538e29SHisping Lin 		if (flag != 0x1) {
568df538e29SHisping Lin 			debug("TEEC: init usedflags section ...\n");
569df538e29SHisping Lin 			memset(rkss->data, 0x00, RKSS_DATA_SECTION_LEN);
570df538e29SHisping Lin 			for (n = 0; n < RKSS_PARTITION_TABLE_COUNT + 1; n++) {
571df538e29SHisping Lin 				flagw = (uint8_t *)rkss->data + (int)n/2;
572df538e29SHisping Lin 				value = 0x1;
573df538e29SHisping Lin 				*flagw = n & 0x1 ? (*flagw & 0xF0) | (value & 0x0F) :
574df538e29SHisping Lin 						(*flagw & 0x0F) | (value << 4);
575df538e29SHisping Lin 			}
576df538e29SHisping Lin 			ret = rkss_write_multi_sections(rkss->data, rkss->index, 1);
577df538e29SHisping Lin 			if (ret < 0) {
578df538e29SHisping Lin 				printf("TEEC: clean usedflags section failed!!! ret: %d.\n", ret);
579df538e29SHisping Lin 				return TEEC_ERROR_GENERIC;
580df538e29SHisping Lin 			}
581df538e29SHisping Lin 
582df538e29SHisping Lin 			return TEEC_SUCCESS;
583df538e29SHisping Lin 		}
584df538e29SHisping Lin 	}
585df538e29SHisping Lin 	debug("TEEC: rkss_verify_usedflags: sucess.\n");
586df538e29SHisping Lin 	return TEEC_SUCCESS;
587df538e29SHisping Lin }
588df538e29SHisping Lin 
rkss_get_fileinfo_by_index(int fd,struct rkss_file_info * pfileinfo)589df538e29SHisping Lin static int rkss_get_fileinfo_by_index(int fd, struct rkss_file_info *pfileinfo)
590df538e29SHisping Lin {
591df538e29SHisping Lin 	int i = fd / RKSS_EACH_SECTION_FILECOUNT;
592df538e29SHisping Lin 	int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i);
593df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
594df538e29SHisping Lin 	int ret;
595df538e29SHisping Lin 	void *pdata;
596df538e29SHisping Lin 	struct rkss_file_info *p;
597df538e29SHisping Lin 
598df538e29SHisping Lin 	rkss.index = i;
599df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
600df538e29SHisping Lin 	if (ret < 0) {
601df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
602df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
603df538e29SHisping Lin 	}
604df538e29SHisping Lin 
605df538e29SHisping Lin 	pdata = rkss.data;
606df538e29SHisping Lin 	p = (struct rkss_file_info *)pdata;
607df538e29SHisping Lin 	p += n;
608df538e29SHisping Lin 
609df538e29SHisping Lin 	if (p->used != 1) {
610df538e29SHisping Lin 		debug("TEEC: error: unused section!\n");
611df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
612df538e29SHisping Lin 	}
613df538e29SHisping Lin 	debug("TEEC: rkss_get_fileinfo_by_index p->used = %d p->name=%s p->index=%d p->size=%d\n",
614df538e29SHisping Lin 		p->used, p->name, p->index, p->size);
615df538e29SHisping Lin 	memcpy(pfileinfo, p, sizeof(struct rkss_file_info));
616df538e29SHisping Lin 
617df538e29SHisping Lin 	return TEEC_SUCCESS;
618df538e29SHisping Lin }
619df538e29SHisping Lin 
rkss_get_fileinfo_by_name(char * filename,struct rkss_file_info * pfileinfo)620df538e29SHisping Lin static int rkss_get_fileinfo_by_name(
621df538e29SHisping Lin 		char *filename, struct rkss_file_info *pfileinfo)
622df538e29SHisping Lin {
623df538e29SHisping Lin 	int i, ret;
624df538e29SHisping Lin 	uint8_t n = 0;
625df538e29SHisping Lin 	unsigned int len;
626df538e29SHisping Lin 	unsigned char *table_data;
627df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
628df538e29SHisping Lin 	void *pdata;
629df538e29SHisping Lin 	struct rkss_file_info *p;
630df538e29SHisping Lin 	const char *split = "/";
631df538e29SHisping Lin 	char *last_inpos;
632df538e29SHisping Lin 	char *last_svpos;
633df538e29SHisping Lin 	char *cur_inpos;
634df538e29SHisping Lin 	char *cur_svpos;
635df538e29SHisping Lin 	int size_in, size_sv;
636df538e29SHisping Lin 
637df538e29SHisping Lin 	len = strlen(filename);
638df538e29SHisping Lin 	if (len > RKSS_MAX_NAME_LENGTH - 1) {
639df538e29SHisping Lin 		printf("TEEC: filename is too long. length:%u\n", len);
640df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
641df538e29SHisping Lin 	}
642df538e29SHisping Lin 
643df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
644df538e29SHisping Lin 	if (table_data == NULL) {
645df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
646df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
647df538e29SHisping Lin 	}
648df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
649df538e29SHisping Lin 	if (ret < 0) {
650df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
651df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
652df538e29SHisping Lin 	}
653df538e29SHisping Lin 
654df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
655df538e29SHisping Lin 		rkss.index = i;
656df538e29SHisping Lin 		memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN);
657df538e29SHisping Lin 
658df538e29SHisping Lin 		for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) {
659df538e29SHisping Lin 			pdata = rkss.data;
660df538e29SHisping Lin 			p = (struct rkss_file_info *)pdata;
661df538e29SHisping Lin 			p += n;
662df538e29SHisping Lin 
663df538e29SHisping Lin 			if (p->used == 0)
664df538e29SHisping Lin 				continue;
665df538e29SHisping Lin 
666df538e29SHisping Lin 			/* Full Matching*/
667df538e29SHisping Lin 			if (!strcmp(p->name, filename)) {
668df538e29SHisping Lin 				debug("TEEC: rkss_get_fileinfo_by_name: hit table[%d/%d], index[%d/%d]\n",
669df538e29SHisping Lin 						i, RKSS_PARTITION_TABLE_COUNT, n, RKSS_EACH_SECTION_FILECOUNT);
670df538e29SHisping Lin 				memcpy(pfileinfo, p, sizeof(struct rkss_file_info));
671df538e29SHisping Lin 				free(table_data);
672df538e29SHisping Lin 				return i * RKSS_EACH_SECTION_FILECOUNT + n;
673df538e29SHisping Lin 			}
674df538e29SHisping Lin 
675df538e29SHisping Lin 			/* Folder Matching*/
676df538e29SHisping Lin 			last_inpos = filename;
677df538e29SHisping Lin 			last_svpos = p->name;
678df538e29SHisping Lin 			cur_inpos = NULL;
679df538e29SHisping Lin 			cur_svpos = NULL;
680df538e29SHisping Lin 			do {
681df538e29SHisping Lin 				cur_inpos = strstr(last_inpos, split);
682df538e29SHisping Lin 				cur_svpos = strstr(last_svpos, split);
683df538e29SHisping Lin 				size_in = cur_inpos == NULL ?
684df538e29SHisping Lin 						(int)strlen(last_inpos) : cur_inpos - last_inpos;
685df538e29SHisping Lin 				size_sv = cur_svpos == NULL ?
686df538e29SHisping Lin 						(int)strlen(last_svpos) : cur_svpos - last_svpos;
687df538e29SHisping Lin 
688df538e29SHisping Lin 				ret = memcmp(last_inpos, last_svpos, size_in);
689df538e29SHisping Lin 				last_inpos = cur_inpos + 1;
690df538e29SHisping Lin 				last_svpos = cur_svpos + 1;
691df538e29SHisping Lin 
692df538e29SHisping Lin 				if (size_in != size_sv || ret)
693df538e29SHisping Lin 					goto UNMATCHFOLDER;
694df538e29SHisping Lin 
695df538e29SHisping Lin 			} while (cur_inpos && cur_svpos);
696df538e29SHisping Lin 
697df538e29SHisping Lin 			debug("TEEC: Matched folder: %s\n", p->name);
698df538e29SHisping Lin 			free(table_data);
699df538e29SHisping Lin 			return TEEC_ERROR_GENERIC;
700df538e29SHisping Lin UNMATCHFOLDER:
701df538e29SHisping Lin 			debug("TEEC: Unmatched ...\n");
702df538e29SHisping Lin 		}
703df538e29SHisping Lin 	}
704df538e29SHisping Lin 	debug("TEEC: rkss_get_fileinfo_by_name: file or dir no found!\n");
705df538e29SHisping Lin 	free(table_data);
706df538e29SHisping Lin 	return TEEC_ERROR_GENERIC;
707df538e29SHisping Lin }
708df538e29SHisping Lin 
rkss_get_dirs_by_name(char * filename)709df538e29SHisping Lin static int rkss_get_dirs_by_name(char *filename)
710df538e29SHisping Lin {
711df538e29SHisping Lin 	int i, ret;
712df538e29SHisping Lin 	uint8_t n = 0;
713df538e29SHisping Lin 	unsigned int len;
714df538e29SHisping Lin 	unsigned char *table_data;
715df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
716df538e29SHisping Lin 	void *pdata;
717df538e29SHisping Lin 	struct rkss_file_info *p;
718df538e29SHisping Lin 	char *chk, *file, *subdir;
719df538e29SHisping Lin 
720df538e29SHisping Lin 	len = strlen(filename);
721df538e29SHisping Lin 	if (len > RKSS_MAX_NAME_LENGTH - 1) {
722df538e29SHisping Lin 		printf("TEEC: filename is too long. length:%u\n", len);
723df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
724df538e29SHisping Lin 	}
725df538e29SHisping Lin 
726df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
727df538e29SHisping Lin 	if (table_data == NULL) {
728df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
729df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
730df538e29SHisping Lin 	}
731df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
732df538e29SHisping Lin 	if (ret < 0) {
733df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
734df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
735df538e29SHisping Lin 	}
736df538e29SHisping Lin 
737df538e29SHisping Lin 	dir_num = 0;
738df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
739df538e29SHisping Lin 		rkss.index = i;
740df538e29SHisping Lin 		memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN);
741df538e29SHisping Lin 
742df538e29SHisping Lin 		for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) {
743df538e29SHisping Lin 			pdata = rkss.data;
744df538e29SHisping Lin 			p = (struct rkss_file_info *)pdata;
745df538e29SHisping Lin 			p += n;
746df538e29SHisping Lin 
747df538e29SHisping Lin 			if (p->used == 0)
748df538e29SHisping Lin 				continue;
749df538e29SHisping Lin 
750df538e29SHisping Lin 			/* Full Matching*/
751df538e29SHisping Lin 			ret = memcmp(p->name, filename, strlen(filename));
752df538e29SHisping Lin 			debug("TEEC: comparing [fd:%d] : %s ?= %s , ret:%d\n",
753df538e29SHisping Lin 					i*RKSS_EACH_SECTION_FILECOUNT+n, p->name, filename, ret);
754df538e29SHisping Lin 			if (!ret && strlen(p->name) > strlen(filename)) {
755df538e29SHisping Lin 				chk = p->name + strlen(filename);
756df538e29SHisping Lin 				if (*chk == '/') {
757df538e29SHisping Lin 					file = p->name + strlen(filename) + 1;
758df538e29SHisping Lin 					subdir = strtok(file, "/");
759df538e29SHisping Lin 					debug("TEEC: found: %s\n", subdir);
760df538e29SHisping Lin 					strcpy(dir_cache[dir_num], subdir);
761df538e29SHisping Lin 					++dir_num;
762df538e29SHisping Lin 				}
763df538e29SHisping Lin 			}
764df538e29SHisping Lin 		}
765df538e29SHisping Lin 	}
766df538e29SHisping Lin 	free(table_data);
767df538e29SHisping Lin 	return dir_num;
768df538e29SHisping Lin }
769df538e29SHisping Lin 
rkss_get_empty_section_from_usedflags(int section_size)770df538e29SHisping Lin static int rkss_get_empty_section_from_usedflags(int section_size)
771df538e29SHisping Lin {
772df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
773df538e29SHisping Lin 	int i, ret;
774df538e29SHisping Lin 	int count0 = 0;
775df538e29SHisping Lin 	uint8_t *flag;
776df538e29SHisping Lin 	uint8_t value;
777df538e29SHisping Lin 
778df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
779df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
780df538e29SHisping Lin 	if (ret < 0) {
781df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
782df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
783df538e29SHisping Lin 	}
784df538e29SHisping Lin 
785df538e29SHisping Lin 	for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) {
786df538e29SHisping Lin 		flag = (uint8_t *)rkss.data + (int)i/2;
787df538e29SHisping Lin 		value = i & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4;
788df538e29SHisping Lin 
789df538e29SHisping Lin 		if (value == 0x0) {
790df538e29SHisping Lin 			if (++count0 == section_size) {
791df538e29SHisping Lin 				return (i + 1 - section_size);
792df538e29SHisping Lin 			}
793df538e29SHisping Lin 		} else {
794df538e29SHisping Lin 			count0 = 0;
795df538e29SHisping Lin 		}
796df538e29SHisping Lin 	}
797df538e29SHisping Lin 
798df538e29SHisping Lin 	printf("TEEC: Not enough space available in secure storage !\n");
799df538e29SHisping Lin 	return TEEC_ERROR_GENERIC;
800df538e29SHisping Lin }
801df538e29SHisping Lin 
rkss_incref_multi_usedflags_sections(unsigned int index,unsigned int num)802df538e29SHisping Lin static int rkss_incref_multi_usedflags_sections(unsigned int index, unsigned int num)
803df538e29SHisping Lin {
804df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
805df538e29SHisping Lin 	int ret, value, i;
806df538e29SHisping Lin 	uint8_t *flag;
807df538e29SHisping Lin 
808df538e29SHisping Lin 	if ((index + num) >= RKSS_DATA_SECTION_COUNT) {
809df538e29SHisping Lin 		printf("TEEC: index[%d] out of range.\n", index);
810df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
811df538e29SHisping Lin 	}
812df538e29SHisping Lin 
813df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
814df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
815df538e29SHisping Lin 	if (ret < 0) {
816df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
817df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
818df538e29SHisping Lin 	}
819df538e29SHisping Lin 
820df538e29SHisping Lin 	for (i = 0; i < num; i++, index++) {
821df538e29SHisping Lin 		flag = (uint8_t *)rkss.data + (int)index/2;
822df538e29SHisping Lin 		value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4;
823df538e29SHisping Lin 		if (++value > 0xF) {
824df538e29SHisping Lin 			printf("TEEC: reference out of data: %d\n", value);
825df538e29SHisping Lin 			value = 0xF;
826df538e29SHisping Lin 		}
827df538e29SHisping Lin 		*flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) :
828df538e29SHisping Lin 				(*flag & 0x0F) | (value << 4);
829df538e29SHisping Lin 	}
830df538e29SHisping Lin 	ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
831df538e29SHisping Lin 	if (ret < 0) {
832df538e29SHisping Lin 		printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
833df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
834df538e29SHisping Lin 	}
835df538e29SHisping Lin 	return TEEC_SUCCESS;
836df538e29SHisping Lin }
837df538e29SHisping Lin 
rkss_decref_multi_usedflags_sections(unsigned int index,unsigned int num)838df538e29SHisping Lin static int rkss_decref_multi_usedflags_sections(unsigned int index, unsigned int num)
839df538e29SHisping Lin {
840df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
841df538e29SHisping Lin 	int ret, value, i;
842df538e29SHisping Lin 	uint8_t *flag;
843df538e29SHisping Lin 
844df538e29SHisping Lin 	if ((index + num) >= RKSS_DATA_SECTION_COUNT) {
845df538e29SHisping Lin 		printf("TEEC: index[%d] out of range.\n", index);
846df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
847df538e29SHisping Lin 	}
848df538e29SHisping Lin 
849df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
850df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
851df538e29SHisping Lin 	if (ret < 0) {
852df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
853df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
854df538e29SHisping Lin 	}
855df538e29SHisping Lin 	for (i = 0; i < num; i++, index++) {
856df538e29SHisping Lin 		flag = (uint8_t *)rkss.data + (int)index/2;
857df538e29SHisping Lin 		value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4;
858df538e29SHisping Lin 		if (--value < 0) {
859df538e29SHisping Lin 			printf("TEEC: reference out of data: %d\n", value);
860df538e29SHisping Lin 			value = 0x0;
861df538e29SHisping Lin 		}
862df538e29SHisping Lin 		*flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) :
863df538e29SHisping Lin 				(*flag & 0x0F) | (value << 4);
864df538e29SHisping Lin 	}
865df538e29SHisping Lin 	ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
866df538e29SHisping Lin 	if (ret < 0) {
867df538e29SHisping Lin 		printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
868df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
869df538e29SHisping Lin 	}
870df538e29SHisping Lin 	return TEEC_SUCCESS;
871df538e29SHisping Lin }
872df538e29SHisping Lin 
rkss_write_empty_ptable(struct rkss_file_info * pfileinfo)873df538e29SHisping Lin static int rkss_write_empty_ptable(struct rkss_file_info *pfileinfo)
874df538e29SHisping Lin {
875df538e29SHisping Lin 	unsigned char *table_data;
876df538e29SHisping Lin 	int ret, i, n;
877df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
878df538e29SHisping Lin 	void *pdata;
879df538e29SHisping Lin 	struct rkss_file_info *p;
880df538e29SHisping Lin 
881df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
882df538e29SHisping Lin 	if (table_data == NULL) {
883df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
884df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
885df538e29SHisping Lin 	}
886df538e29SHisping Lin 
887df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
888df538e29SHisping Lin 	if (ret < 0) {
889df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
890df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
891df538e29SHisping Lin 	}
892df538e29SHisping Lin 
893df538e29SHisping Lin 	for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) {
894df538e29SHisping Lin 		rkss.index = i;
895df538e29SHisping Lin 		memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN);
896df538e29SHisping Lin 		for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) {
897df538e29SHisping Lin 			pdata = rkss.data;
898df538e29SHisping Lin 			p = (struct rkss_file_info *)pdata;
899df538e29SHisping Lin 			p += n;
900df538e29SHisping Lin 			if (p->used == 0) {
901df538e29SHisping Lin 				debug("TEEC: write ptable in [%d][%d] .\n", i, n);
902df538e29SHisping Lin 				memcpy(p, pfileinfo, sizeof(struct rkss_file_info));
903df538e29SHisping Lin 				p->used = 1;
904df538e29SHisping Lin 				p->id = n;
905df538e29SHisping Lin 				debug("TEEC: write emt ptable : [%d,%d] name:%s, index:%d,\n",
906df538e29SHisping Lin 					i, n, p->name, p->index);
907df538e29SHisping Lin 				debug("TEEC: size:%d, used:%d\n",  p->size, p->used);
908df538e29SHisping Lin 				ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
909df538e29SHisping Lin 				if (ret < 0) {
910df538e29SHisping Lin 					printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
911df538e29SHisping Lin 					free(table_data);
912df538e29SHisping Lin 					return TEEC_ERROR_GENERIC;
913df538e29SHisping Lin 				}
914df538e29SHisping Lin 
915df538e29SHisping Lin 				free(table_data);
916df538e29SHisping Lin 				return i * RKSS_EACH_SECTION_FILECOUNT + n;
917df538e29SHisping Lin 			}
918df538e29SHisping Lin 		}
919df538e29SHisping Lin 	}
920df538e29SHisping Lin 	debug("TEEC: No enough ptable space available in secure storage.\n");
921df538e29SHisping Lin 	free(table_data);
922df538e29SHisping Lin 	return TEEC_ERROR_GENERIC;
923df538e29SHisping Lin }
924df538e29SHisping Lin 
rkss_write_back_ptable(int fd,struct rkss_file_info * pfileinfo)925df538e29SHisping Lin static int rkss_write_back_ptable(int fd, struct rkss_file_info *pfileinfo)
926df538e29SHisping Lin {
927df538e29SHisping Lin 	int i = fd / RKSS_EACH_SECTION_FILECOUNT;
928df538e29SHisping Lin 	int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i);
929df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
930df538e29SHisping Lin 	int ret;
931df538e29SHisping Lin 	void *pdata;
932df538e29SHisping Lin 	struct rkss_file_info *p;
933df538e29SHisping Lin 
934df538e29SHisping Lin 	rkss.index = i;
935df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
936df538e29SHisping Lin 	if (ret < 0) {
937df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
938df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
939df538e29SHisping Lin 	}
940df538e29SHisping Lin 
941df538e29SHisping Lin 	pdata = rkss.data;
942df538e29SHisping Lin 	p = (struct rkss_file_info *)pdata;
943df538e29SHisping Lin 	p += n;
944df538e29SHisping Lin 
945df538e29SHisping Lin 	memcpy(p, pfileinfo, sizeof(struct rkss_file_info));
946df538e29SHisping Lin 	debug("TEEC: write ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n",
947df538e29SHisping Lin 			i, n, p->name, p->index, p->size, p->used);
948df538e29SHisping Lin 
949df538e29SHisping Lin 	ret = rkss_write_multi_sections(rkss.data, rkss.index, 1);
950df538e29SHisping Lin 	if (ret < 0) {
951df538e29SHisping Lin 		printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret);
952df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
953df538e29SHisping Lin 	}
954df538e29SHisping Lin #ifdef DEBUG_RKFSS
955df538e29SHisping Lin 	rkss_dump_ptable();
956df538e29SHisping Lin #endif
957df538e29SHisping Lin 
958df538e29SHisping Lin 	return TEEC_SUCCESS;
959df538e29SHisping Lin }
960df538e29SHisping Lin 
ree_fs_new_open(size_t num_params,struct tee_ioctl_param * params)961df538e29SHisping Lin static uint32_t ree_fs_new_open(size_t num_params,
962df538e29SHisping Lin 				   struct tee_ioctl_param *params)
963df538e29SHisping Lin {
964df538e29SHisping Lin 	char *filename;
965df538e29SHisping Lin 	int fd;
966df538e29SHisping Lin 	struct rkss_file_info p = {0};
967df538e29SHisping Lin 
968df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
969df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
970df538e29SHisping Lin 
971df538e29SHisping Lin 	filename = (char *)(size_t)params[1].u.memref.shm_id;
972df538e29SHisping Lin 	if (!filename)
973df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
974df538e29SHisping Lin 
975df538e29SHisping Lin 	if (strlen(filename) > RKSS_MAX_NAME_LENGTH) {
976df538e29SHisping Lin 		printf("TEEC: ree_fs_new_open: file name too long. %s\n", filename);
977df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
978df538e29SHisping Lin 	}
979df538e29SHisping Lin 
980df538e29SHisping Lin 	debug("TEEC: ree_fs_new_open open file: %s, len: %zu\n", filename, strlen(filename));
981df538e29SHisping Lin 	fd = rkss_get_fileinfo_by_name(filename, &p);
982df538e29SHisping Lin 	if (fd < 0) {
983df538e29SHisping Lin 		debug("TEEC: ree_fs_new_open : no such file. %s\n", filename);
984df538e29SHisping Lin 		return TEEC_ERROR_ITEM_NOT_FOUND;
985df538e29SHisping Lin 	}
986df538e29SHisping Lin 
987df538e29SHisping Lin 	debug("TEEC: ree_fs_new_open! %s, fd: %d\n", filename, fd);
988df538e29SHisping Lin 
989df538e29SHisping Lin 	params[2].u.value.a = fd;
990df538e29SHisping Lin 	return TEEC_SUCCESS;
991df538e29SHisping Lin }
992df538e29SHisping Lin 
ree_fs_new_create(size_t num_params,struct tee_ioctl_param * params)993df538e29SHisping Lin static TEEC_Result ree_fs_new_create(size_t num_params,
994df538e29SHisping Lin 				     struct tee_ioctl_param *params)
995df538e29SHisping Lin {
996df538e29SHisping Lin 	char *filename;
997df538e29SHisping Lin 	int fd;
998df538e29SHisping Lin 	int ret, num;
999df538e29SHisping Lin 	struct rkss_file_info p = {0};
1000df538e29SHisping Lin 	/* file open flags: O_RDWR | O_CREAT | O_TRUNC
1001df538e29SHisping Lin 	 * if file exists, we must remove it first.
1002df538e29SHisping Lin 	 */
1003df538e29SHisping Lin 	ret = rkss_begin_commit();
1004df538e29SHisping Lin 	if (ret < 0) {
1005df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1006df538e29SHisping Lin 		return -1;
1007df538e29SHisping Lin 	}
1008df538e29SHisping Lin 
1009df538e29SHisping Lin 	filename = (char *)(size_t)params[1].u.memref.shm_id;
1010df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1011df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1012df538e29SHisping Lin 	if (!filename)
1013df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1014df538e29SHisping Lin 
1015df538e29SHisping Lin 	if (strlen(filename) > RKSS_MAX_NAME_LENGTH) {
1016df538e29SHisping Lin 		printf("TEEC: ree_fs_new_create: file name too long. %s\n", filename);
1017df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1018df538e29SHisping Lin 	}
1019df538e29SHisping Lin 
1020df538e29SHisping Lin 	debug("TEEC: ree_fs_new_create create file: %s, len: %zu\n", filename, strlen(filename));
1021df538e29SHisping Lin 	fd = rkss_get_fileinfo_by_name(filename, &p);
1022df538e29SHisping Lin 	if (fd >= 0) {
1023df538e29SHisping Lin 		debug("TEEC: ree_fs_new_create : file exist, clear it. %s\n", filename);
1024df538e29SHisping Lin 		/* decrease ref from usedflags */
1025df538e29SHisping Lin 		num = p.size / RKSS_DATA_SECTION_LEN + 1;
1026df538e29SHisping Lin 		ret = rkss_decref_multi_usedflags_sections(p.index, num);
1027df538e29SHisping Lin 		if (ret < 0) {
1028df538e29SHisping Lin 			printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
1029df538e29SHisping Lin 			return TEEC_ERROR_GENERIC;
1030df538e29SHisping Lin 		}
1031df538e29SHisping Lin 
1032df538e29SHisping Lin 		/* rm from ptable */
1033df538e29SHisping Lin 		memset(&p, 0, sizeof(struct rkss_file_info));
1034df538e29SHisping Lin 		ret = rkss_write_back_ptable(fd, &p);
1035df538e29SHisping Lin 		if (ret < 0) {
1036df538e29SHisping Lin 			printf("TEEC: ree_fs_new_create : write back error %d\n", ret);
1037df538e29SHisping Lin 			return TEEC_ERROR_GENERIC;
1038df538e29SHisping Lin 		}
1039df538e29SHisping Lin 	}
1040df538e29SHisping Lin 
1041df538e29SHisping Lin 	debug("TEEC: ree_fs_new_create create new file: %s\n", filename);
1042df538e29SHisping Lin 	strcpy(p.name, filename);
1043df538e29SHisping Lin 	p.index = 0;
1044df538e29SHisping Lin 	p.size = 0;
1045df538e29SHisping Lin 	p.used = 1;
1046df538e29SHisping Lin 	p.flags = RK_FS_R | RK_FS_W;
1047df538e29SHisping Lin 	fd = rkss_write_empty_ptable(&p);
1048df538e29SHisping Lin 	if (fd < 0) {
1049df538e29SHisping Lin 		printf("TEEC: ree_fs_new_create : write empty ptable error. %s\n", filename);
1050df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1051df538e29SHisping Lin 	}
1052df538e29SHisping Lin 
1053df538e29SHisping Lin 	debug("TEEC: ree_fs_new_create ! %s, fd: %d.\n", filename, fd);
1054df538e29SHisping Lin 
1055df538e29SHisping Lin 	params[2].u.value.a = fd;
1056df538e29SHisping Lin 
1057df538e29SHisping Lin 	ret = rkss_finish_commit();
1058df538e29SHisping Lin 	if (ret < 0) {
1059df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1060df538e29SHisping Lin 		return -1;
1061df538e29SHisping Lin 	}
1062df538e29SHisping Lin 	return TEEC_SUCCESS;
1063df538e29SHisping Lin }
1064df538e29SHisping Lin 
ree_fs_new_close(size_t num_params,struct tee_ioctl_param * params)1065df538e29SHisping Lin static TEEC_Result ree_fs_new_close(size_t num_params,
1066df538e29SHisping Lin 				    struct tee_ioctl_param *params)
1067df538e29SHisping Lin {
1068df538e29SHisping Lin 	debug("TEEC: ree_fs_new_close !\n");
1069df538e29SHisping Lin 	UNREFERENCED_PARAMETER(params);
1070df538e29SHisping Lin 	UNREFERENCED_PARAMETER(num_params);
1071df538e29SHisping Lin 	return TEEC_SUCCESS;
1072df538e29SHisping Lin }
1073df538e29SHisping Lin 
ree_fs_new_read(size_t num_params,struct tee_ioctl_param * params)1074df538e29SHisping Lin static TEEC_Result ree_fs_new_read(size_t num_params,
1075df538e29SHisping Lin 				   struct tee_ioctl_param *params)
1076df538e29SHisping Lin {
1077df538e29SHisping Lin 	uint8_t *data;
1078df538e29SHisping Lin 	size_t len;
1079df538e29SHisping Lin 	off_t offs;
1080df538e29SHisping Lin 	int fd;
1081df538e29SHisping Lin 	int ret;
1082df538e29SHisping Lin 	struct rkss_file_info p = {0};
1083df538e29SHisping Lin 	int di, section_num;
1084df538e29SHisping Lin 	uint8_t *temp_file_data;
1085df538e29SHisping Lin 
1086df538e29SHisping Lin 	fd = params[0].u.value.b;
1087df538e29SHisping Lin 	offs = params[0].u.value.c;
1088df538e29SHisping Lin 
1089df538e29SHisping Lin 	data = (uint8_t *)(size_t)params[1].u.memref.shm_id;
1090df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1091df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1092df538e29SHisping Lin 
1093df538e29SHisping Lin 	if (!data)
1094df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1095df538e29SHisping Lin 	len = params[1].u.memref.size;
1096df538e29SHisping Lin 
1097df538e29SHisping Lin 	debug("TEEC: ree_fs_new_read! fd:%d, len:%zu, offs:%ld\n", fd, len, offs);
1098df538e29SHisping Lin 
1099df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_index(fd, &p);
1100df538e29SHisping Lin 	if (ret < 0) {
1101df538e29SHisping Lin 		debug("TEEC: unavailable fd: %d!\n", fd);
1102df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1103df538e29SHisping Lin 	}
1104df538e29SHisping Lin 
1105df538e29SHisping Lin 	if (offs >= p.size)
1106df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1107df538e29SHisping Lin 
1108df538e29SHisping Lin 	section_num = p.size / RKSS_DATA_SECTION_LEN + 1;
1109df538e29SHisping Lin 	temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN);
1110df538e29SHisping Lin 	ret = rkss_read_multi_sections(temp_file_data, p.index, section_num);
1111df538e29SHisping Lin 	if (ret < 0) {
1112df538e29SHisping Lin 		printf("TEEC: unavailable file index!\n");
1113df538e29SHisping Lin 		free(temp_file_data);
1114df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1115df538e29SHisping Lin 	}
1116df538e29SHisping Lin 	di = (offs + len) > p.size ? (p.size - offs) : len;
1117df538e29SHisping Lin 	memcpy(data, temp_file_data + offs, di);
1118df538e29SHisping Lin 	free(temp_file_data);
1119df538e29SHisping Lin 	temp_file_data = 0;
1120df538e29SHisping Lin 	params[1].u.memref.size = di;
1121df538e29SHisping Lin 
1122df538e29SHisping Lin 	return TEEC_SUCCESS;
1123df538e29SHisping Lin }
1124df538e29SHisping Lin 
ree_fs_new_write(size_t num_params,struct tee_ioctl_param * params)1125df538e29SHisping Lin static TEEC_Result ree_fs_new_write(size_t num_params,
1126df538e29SHisping Lin 				    struct tee_ioctl_param *params)
1127df538e29SHisping Lin {
1128df538e29SHisping Lin 	uint8_t *data;
1129df538e29SHisping Lin 	size_t len;
1130df538e29SHisping Lin 	off_t offs;
1131df538e29SHisping Lin 	struct rkss_file_info p = {0};
1132df538e29SHisping Lin 	int ret, fd, new_size;
1133df538e29SHisping Lin 	int section_num;
1134df538e29SHisping Lin 	uint8_t *file_data = 0, *temp_file_data = 0;
1135df538e29SHisping Lin 
1136df538e29SHisping Lin 	ret = rkss_begin_commit();
1137df538e29SHisping Lin 	if (ret < 0) {
1138df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1139df538e29SHisping Lin 		return -1;
1140df538e29SHisping Lin 	}
1141df538e29SHisping Lin 
1142df538e29SHisping Lin 	fd = params[0].u.value.b;
1143df538e29SHisping Lin 	offs = params[0].u.value.c;
1144df538e29SHisping Lin 
1145df538e29SHisping Lin 	data = (uint8_t *)(size_t)params[1].u.memref.shm_id;
1146df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1147df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1148df538e29SHisping Lin 	if (!data)
1149df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1150df538e29SHisping Lin 	len = params[1].u.memref.size;
1151df538e29SHisping Lin 
1152df538e29SHisping Lin 	debug("TEEC: ree_fs_new_write ! fd:%d, len:%zu, offs:%ld \n", fd, len, offs);
1153df538e29SHisping Lin 
1154df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_index(fd, &p);
1155df538e29SHisping Lin 	if (ret < 0) {
1156df538e29SHisping Lin 		printf("TEEC: ree_fs_new_write: fd:%d unvailable!\n", fd);
1157df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1158df538e29SHisping Lin 	}
1159df538e29SHisping Lin 
1160df538e29SHisping Lin 	new_size = offs + len > p.size ? offs + len : p.size;
1161df538e29SHisping Lin 	file_data = malloc(new_size);
1162df538e29SHisping Lin 	if (!file_data)
1163df538e29SHisping Lin 		return TEEC_ERROR_OUT_OF_MEMORY;
1164df538e29SHisping Lin 
1165df538e29SHisping Lin 	if (p.size != 0) {
1166df538e29SHisping Lin 		/* Read old file data out */
1167df538e29SHisping Lin 		section_num = p.size / RKSS_DATA_SECTION_LEN + 1;
1168df538e29SHisping Lin 		temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN);
1169df538e29SHisping Lin 		ret = rkss_read_multi_sections(temp_file_data, p.index, section_num);
1170df538e29SHisping Lin 		if (ret < 0) {
1171df538e29SHisping Lin 			printf("TEEC: unavailable file index %d section_num %d\n", p.index, section_num);
1172df538e29SHisping Lin 			ret = TEEC_ERROR_GENERIC;
1173df538e29SHisping Lin 			goto out;
1174df538e29SHisping Lin 		}
1175df538e29SHisping Lin 		memcpy(file_data, temp_file_data, p.size);
1176df538e29SHisping Lin 		free(temp_file_data);
1177df538e29SHisping Lin 		temp_file_data = 0;
1178df538e29SHisping Lin 		ret = rkss_decref_multi_usedflags_sections(p.index, section_num);
1179df538e29SHisping Lin 		if (ret < 0) {
1180df538e29SHisping Lin 			printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
1181df538e29SHisping Lin 			ret = TEEC_ERROR_GENERIC;
1182df538e29SHisping Lin 			goto out;
1183df538e29SHisping Lin 		}
1184df538e29SHisping Lin 	}
1185df538e29SHisping Lin 
1186df538e29SHisping Lin 	/* update new file info */
1187df538e29SHisping Lin 	memcpy(file_data + offs, data, len);
1188df538e29SHisping Lin 	p.size = new_size;
1189df538e29SHisping Lin 	section_num = new_size / RKSS_DATA_SECTION_LEN + 1;
1190df538e29SHisping Lin 	p.index = rkss_get_empty_section_from_usedflags(section_num);
1191df538e29SHisping Lin 	debug("TEEC: Get Empty section in %d\n", p.index);
1192df538e29SHisping Lin 	p.used = 1;
1193df538e29SHisping Lin 	ret = rkss_incref_multi_usedflags_sections(p.index, section_num);
1194df538e29SHisping Lin 	if (ret < 0) {
1195df538e29SHisping Lin 		printf("TEEC: rkss_incref_multi_usedflags_sections error !\n");
1196df538e29SHisping Lin 		ret = TEEC_ERROR_GENERIC;
1197df538e29SHisping Lin 		goto out;
1198df538e29SHisping Lin 	}
1199df538e29SHisping Lin 
1200df538e29SHisping Lin 	ret = rkss_write_back_ptable(fd, &p);
1201df538e29SHisping Lin 	if (ret < 0) {
1202df538e29SHisping Lin 		printf("TEEC: ree_fs_new_write: write ptable error!\n");
1203df538e29SHisping Lin 		ret = TEEC_ERROR_GENERIC;
1204df538e29SHisping Lin 		goto out;
1205df538e29SHisping Lin 	}
1206df538e29SHisping Lin 
1207df538e29SHisping Lin 	/* write new file data */
1208df538e29SHisping Lin 	temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN);
1209df538e29SHisping Lin 	memset(temp_file_data, 0, section_num * RKSS_DATA_SECTION_LEN);
1210df538e29SHisping Lin 	memcpy(temp_file_data, file_data, p.size);
1211df538e29SHisping Lin 	rkss_write_multi_sections(temp_file_data, p.index, section_num);
1212df538e29SHisping Lin 	free(temp_file_data);
1213df538e29SHisping Lin 	temp_file_data = 0;
1214df538e29SHisping Lin 
1215df538e29SHisping Lin #ifdef DEBUG_RKFSS
1216df538e29SHisping Lin 	rkss_dump_usedflags();
1217df538e29SHisping Lin #endif
1218df538e29SHisping Lin 
1219df538e29SHisping Lin out:
1220df538e29SHisping Lin 	if (file_data)
1221df538e29SHisping Lin 		free(file_data);
1222df538e29SHisping Lin 	if (temp_file_data) {
1223df538e29SHisping Lin 		free(temp_file_data);
1224df538e29SHisping Lin 		temp_file_data = 0;
1225df538e29SHisping Lin 	}
1226df538e29SHisping Lin 	ret = rkss_finish_commit();
1227df538e29SHisping Lin 	if (ret < 0) {
1228df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1229df538e29SHisping Lin 		return -1;
1230df538e29SHisping Lin 	}
1231df538e29SHisping Lin 
1232df538e29SHisping Lin 	return TEEC_SUCCESS;
1233df538e29SHisping Lin }
1234df538e29SHisping Lin 
1235df538e29SHisping Lin /* TODO: update file data space */
ree_fs_new_truncate(size_t num_params,struct tee_ioctl_param * params)1236df538e29SHisping Lin static TEEC_Result ree_fs_new_truncate(size_t num_params,
1237df538e29SHisping Lin 				       struct tee_ioctl_param *params)
1238df538e29SHisping Lin {
1239df538e29SHisping Lin 	size_t len;
1240df538e29SHisping Lin 	int fd, ret;
1241df538e29SHisping Lin 	struct rkss_file_info p = {0};
1242df538e29SHisping Lin 	unsigned int section_num_old, section_num_new;
1243df538e29SHisping Lin 
1244df538e29SHisping Lin 	ret = rkss_begin_commit();
1245df538e29SHisping Lin 	if (ret < 0) {
1246df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1247df538e29SHisping Lin 		return -1;
1248df538e29SHisping Lin 	}
1249df538e29SHisping Lin 
1250df538e29SHisping Lin 	fd = params[0].u.value.b;
1251df538e29SHisping Lin 	len = params[0].u.value.c;
1252df538e29SHisping Lin 
1253df538e29SHisping Lin 	debug("TEEC: ree_fs_new_truncate: fd:%d, lenth:%zu\n", fd, len);
1254df538e29SHisping Lin 
1255df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_index(fd, &p);
1256df538e29SHisping Lin 	if (ret < 0) {
1257df538e29SHisping Lin 		printf("TEEC: fd:%d unvailable!\n", fd);
1258df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1259df538e29SHisping Lin 	}
1260df538e29SHisping Lin 	if (len > p.size) {
1261df538e29SHisping Lin 		printf("TEEC: truncate error!\n");
1262df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1263df538e29SHisping Lin 	}
1264df538e29SHisping Lin 	section_num_old = p.size / RKSS_DATA_SECTION_LEN + 1;
1265df538e29SHisping Lin 	section_num_new = len / RKSS_DATA_SECTION_LEN + 1;
1266df538e29SHisping Lin 	ret = rkss_decref_multi_usedflags_sections(p.index + section_num_new, section_num_old - section_num_new);
1267df538e29SHisping Lin 	if (ret < 0) {
1268df538e29SHisping Lin 		printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
1269df538e29SHisping Lin 		ret = TEEC_ERROR_GENERIC;
1270df538e29SHisping Lin 	}
1271df538e29SHisping Lin 	p.size = len;
1272df538e29SHisping Lin 	ret = rkss_write_back_ptable(fd, &p);
1273df538e29SHisping Lin 	if (ret < 0) {
1274df538e29SHisping Lin 		printf("TEEC: ree_fs_new_truncate: write ptable error!\n");
1275df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1276df538e29SHisping Lin 	}
1277df538e29SHisping Lin 	ret = rkss_finish_commit();
1278df538e29SHisping Lin 	if (ret < 0) {
1279df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1280df538e29SHisping Lin 		return -1;
1281df538e29SHisping Lin 	}
1282df538e29SHisping Lin 
1283df538e29SHisping Lin 	return TEEC_SUCCESS;
1284df538e29SHisping Lin }
1285df538e29SHisping Lin 
ree_fs_new_remove(size_t num_params,struct tee_ioctl_param * params)1286df538e29SHisping Lin static TEEC_Result ree_fs_new_remove(size_t num_params,
1287df538e29SHisping Lin 				     struct tee_ioctl_param *params)
1288df538e29SHisping Lin {
1289df538e29SHisping Lin 	char *filename;
1290df538e29SHisping Lin 	struct rkss_file_info p = {0};
1291df538e29SHisping Lin 	int ret, fd, num;
1292df538e29SHisping Lin 
1293df538e29SHisping Lin 	ret = rkss_begin_commit();
1294df538e29SHisping Lin 	if (ret < 0) {
1295df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1296df538e29SHisping Lin 		return -1;
1297df538e29SHisping Lin 	}
1298df538e29SHisping Lin 
1299df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1300df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1301df538e29SHisping Lin 
1302df538e29SHisping Lin 	filename = (char *)(size_t)params[1].u.memref.shm_id;
1303df538e29SHisping Lin 	if (!filename)
1304df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1305df538e29SHisping Lin 
1306df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_name(filename, &p);
1307df538e29SHisping Lin 	if (ret < 0) {
1308df538e29SHisping Lin 		printf("TEEC: ree_fs_new_remove: no such file. %s\n", filename);
1309df538e29SHisping Lin 		return 0;
1310df538e29SHisping Lin 	}
1311df538e29SHisping Lin 	fd = ret;
1312df538e29SHisping Lin 
1313df538e29SHisping Lin 	debug("TEEC: ree_fs_new_remove! %s fd:%d index:%d size:%d\n", filename, fd, p.index, p.size);
1314df538e29SHisping Lin 
1315df538e29SHisping Lin 	/* decrease ref from usedflags */
1316df538e29SHisping Lin 	num = p.size / RKSS_DATA_SECTION_LEN + 1;
1317df538e29SHisping Lin 	ret = rkss_decref_multi_usedflags_sections(p.index, num);
1318df538e29SHisping Lin 	if (ret < 0) {
1319df538e29SHisping Lin 		printf("TEEC: rkss_decref_multi_usedflags_sections error !\n");
1320df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1321df538e29SHisping Lin 	}
1322df538e29SHisping Lin 
1323df538e29SHisping Lin 	/* rm from ptable */
1324df538e29SHisping Lin 	memset(&p, 0, sizeof(struct rkss_file_info));
1325df538e29SHisping Lin 	ret = rkss_write_back_ptable(fd, &p);
1326df538e29SHisping Lin 	if (ret < 0) {
1327df538e29SHisping Lin 		printf("TEEC: ree_fs_new_remove: write back error %d\n", ret);
1328df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1329df538e29SHisping Lin 	}
1330df538e29SHisping Lin 
1331df538e29SHisping Lin #ifdef DEBUG_RKFSS
1332df538e29SHisping Lin 	rkss_dump_ptable();
1333df538e29SHisping Lin 	rkss_dump_usedflags();
1334df538e29SHisping Lin #endif
1335df538e29SHisping Lin 	ret = rkss_finish_commit();
1336df538e29SHisping Lin 	if (ret < 0) {
1337df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1338df538e29SHisping Lin 		return -1;
1339df538e29SHisping Lin 	}
1340df538e29SHisping Lin 
1341df538e29SHisping Lin 	return TEEC_SUCCESS;
1342df538e29SHisping Lin }
1343df538e29SHisping Lin 
ree_fs_new_rename(size_t num_params,struct tee_ioctl_param * params)1344df538e29SHisping Lin static TEEC_Result ree_fs_new_rename(size_t num_params,
1345df538e29SHisping Lin 				     struct tee_ioctl_param *params)
1346df538e29SHisping Lin {
1347df538e29SHisping Lin 	char *old_fname;
1348df538e29SHisping Lin 	char *new_fname;
1349df538e29SHisping Lin 	struct rkss_file_info p = {0};
1350df538e29SHisping Lin 	int ret;
1351df538e29SHisping Lin 
1352df538e29SHisping Lin 	ret = rkss_begin_commit();
1353df538e29SHisping Lin 	if (ret < 0) {
1354df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1355df538e29SHisping Lin 		return -1;
1356df538e29SHisping Lin 	}
1357df538e29SHisping Lin 
1358df538e29SHisping Lin 	old_fname = (char *)(size_t)params[1].u.memref.shm_id;
1359df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1360df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1361df538e29SHisping Lin 	if (!old_fname)
1362df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1363df538e29SHisping Lin 
1364df538e29SHisping Lin 	new_fname = (char *)(size_t)params[2].u.memref.shm_id;
1365df538e29SHisping Lin 	debug("TEEC: params[2].u.memref.shm_id = 0x%llx params[2].u.memref.shm_offs = 0x%llx\n",
1366df538e29SHisping Lin 		params[2].u.memref.shm_id, params[2].u.memref.shm_offs);
1367df538e29SHisping Lin 	if (!new_fname)
1368df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1369df538e29SHisping Lin 
1370df538e29SHisping Lin 	if (strlen(new_fname) > RKSS_MAX_NAME_LENGTH) {
1371df538e29SHisping Lin 		printf("TEEC: new file name too long. %s\n", new_fname);
1372df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1373df538e29SHisping Lin 	}
1374df538e29SHisping Lin 
1375df538e29SHisping Lin 	debug("TEEC: rename: %s -> %s\n", old_fname, new_fname);
1376df538e29SHisping Lin 
1377df538e29SHisping Lin 	ret = rkss_get_fileinfo_by_name(old_fname, &p);
1378df538e29SHisping Lin 	if (ret < 0) {
1379df538e29SHisping Lin 		printf("TEEC: filename: %s no found.\n", old_fname);
1380df538e29SHisping Lin 		return TEEC_ERROR_ITEM_NOT_FOUND;
1381df538e29SHisping Lin 	}
1382df538e29SHisping Lin 
1383df538e29SHisping Lin 	strcpy(p.name, new_fname);
1384df538e29SHisping Lin 
1385df538e29SHisping Lin 	ret = rkss_write_back_ptable(ret, &p);
1386df538e29SHisping Lin 	if (ret < 0) {
1387df538e29SHisping Lin 		printf("TEEC: write ptable error!\n");
1388df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1389df538e29SHisping Lin 	}
1390df538e29SHisping Lin 	ret = rkss_finish_commit();
1391df538e29SHisping Lin 	if (ret < 0) {
1392df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1393df538e29SHisping Lin 		return -1;
1394df538e29SHisping Lin 	}
1395df538e29SHisping Lin 
1396df538e29SHisping Lin 	return TEEC_SUCCESS;
1397df538e29SHisping Lin }
1398df538e29SHisping Lin 
ree_fs_new_opendir(size_t num_params,struct tee_ioctl_param * params)1399df538e29SHisping Lin static TEEC_Result ree_fs_new_opendir(size_t num_params,
1400df538e29SHisping Lin 				      struct tee_ioctl_param *params)
1401df538e29SHisping Lin {
1402df538e29SHisping Lin 	char *dirname;
1403df538e29SHisping Lin 	int ret;
1404df538e29SHisping Lin 
1405df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1406df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1407df538e29SHisping Lin 
1408df538e29SHisping Lin 	dirname = (char *)(size_t)params[1].u.memref.shm_id;
1409df538e29SHisping Lin 	if (!dirname)
1410df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1411df538e29SHisping Lin 
1412df538e29SHisping Lin 	dir_seek = 0;
1413df538e29SHisping Lin 	ret = rkss_get_dirs_by_name(dirname);
1414df538e29SHisping Lin 	if (ret < 0) {
1415df538e29SHisping Lin 		printf("TEEC: ree_fs_new_opendir: error\n");
1416df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1417df538e29SHisping Lin 	}
1418df538e29SHisping Lin 
1419df538e29SHisping Lin 	debug("TEEC: ree_fs_new_opendir: %s, seek/num:%d/%d\n", dirname, dir_seek, dir_num);
1420df538e29SHisping Lin 	return TEEC_SUCCESS;
1421df538e29SHisping Lin }
1422df538e29SHisping Lin 
ree_fs_new_closedir(size_t num_params,struct tee_ioctl_param * params)1423df538e29SHisping Lin static TEEC_Result ree_fs_new_closedir(size_t num_params,
1424df538e29SHisping Lin 				       struct tee_ioctl_param *params)
1425df538e29SHisping Lin {
1426df538e29SHisping Lin 	if (num_params != 1 ||
1427df538e29SHisping Lin 	    (params[0].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) !=
1428df538e29SHisping Lin 			TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT)
1429df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1430df538e29SHisping Lin 
1431df538e29SHisping Lin 	dir_seek = 0;
1432df538e29SHisping Lin 	dir_num = 0;
1433df538e29SHisping Lin 
1434df538e29SHisping Lin 	return TEEC_SUCCESS;
1435df538e29SHisping Lin }
1436df538e29SHisping Lin 
ree_fs_new_readdir(size_t num_params,struct tee_ioctl_param * params)1437df538e29SHisping Lin static TEEC_Result ree_fs_new_readdir(size_t num_params,
1438df538e29SHisping Lin 				      struct tee_ioctl_param *params)
1439df538e29SHisping Lin {
1440df538e29SHisping Lin 	char *dirname;
1441df538e29SHisping Lin 	size_t len;
1442df538e29SHisping Lin 	size_t dirname_len;
1443df538e29SHisping Lin 
1444df538e29SHisping Lin 	dirname = (char *)(size_t)params[1].u.memref.shm_id;
1445df538e29SHisping Lin 	debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n",
1446df538e29SHisping Lin 		params[1].u.memref.shm_id, params[1].u.memref.shm_offs);
1447df538e29SHisping Lin 	if (!dirname)
1448df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1449df538e29SHisping Lin 	len = params[1].u.memref.size;
1450df538e29SHisping Lin 
1451df538e29SHisping Lin 	debug("TEEC: seek/num:%d/%d\n", dir_seek, dir_num);
1452df538e29SHisping Lin 	if (dir_seek == dir_num) {
1453df538e29SHisping Lin 		params[1].u.memref.size = 0;
1454df538e29SHisping Lin 		debug("ree_fs_new_readdir: END \n");
1455df538e29SHisping Lin 		return TEEC_ERROR_BAD_STATE;
1456df538e29SHisping Lin 	}
1457df538e29SHisping Lin 
1458df538e29SHisping Lin 	dirname_len = strlen(dir_cache[dir_seek]) + 1;
1459df538e29SHisping Lin 	params[1].u.memref.size = dirname_len;
1460df538e29SHisping Lin 	if (dirname_len > len)
1461df538e29SHisping Lin 		return TEEC_ERROR_SHORT_BUFFER;
1462df538e29SHisping Lin 
1463df538e29SHisping Lin 	strcpy(dirname, dir_cache[dir_seek]);
1464df538e29SHisping Lin 	++dir_seek;
1465df538e29SHisping Lin 
1466df538e29SHisping Lin 	debug("TEEC: ree_fs_new_readdir: %s\n", dirname);
1467df538e29SHisping Lin 
1468df538e29SHisping Lin 	return TEEC_SUCCESS;
1469df538e29SHisping Lin }
1470df538e29SHisping Lin 
tee_supp_rk_fs_init_v1(void)1471df538e29SHisping Lin int tee_supp_rk_fs_init_v1(void)
1472df538e29SHisping Lin {
1473df538e29SHisping Lin 	assert(sizeof(struct rkss_file_info) == 126);
1474df538e29SHisping Lin 	assert(512 / sizeof(struct rkss_file_info) == RKSS_EACH_SECTION_FILECOUNT);
1475df538e29SHisping Lin 
1476df538e29SHisping Lin 	int ret;
1477df538e29SHisping Lin 	struct rk_secure_storage rkss = {0};
1478df538e29SHisping Lin 	unsigned char *table_data;
1479df538e29SHisping Lin 
1480df538e29SHisping Lin 	if (check_security_exist(0) < 0)
1481df538e29SHisping Lin 		return 0;
1482df538e29SHisping Lin 
1483df538e29SHisping Lin 	ret = rkss_resume();
1484df538e29SHisping Lin 	if (ret < 0) {
1485df538e29SHisping Lin 		printf("rkss_resume failed!");
1486df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1487df538e29SHisping Lin 	}
1488df538e29SHisping Lin 
1489df538e29SHisping Lin 	/* clean secure storage*/
1490df538e29SHisping Lin #ifdef DEBUG_CLEAN_RKSS
1491df538e29SHisping Lin 	int i = 0;
1492df538e29SHisping Lin 	for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) {
1493df538e29SHisping Lin 		memset(rkss.data, 0, RKSS_DATA_SECTION_LEN);
1494df538e29SHisping Lin 		rkss.index = i;
1495df538e29SHisping Lin 		rkss_write_multi_sections(rkss.data, rkss.index, 1);
1496df538e29SHisping Lin 		printf("TEEC: cleaned [%d]", i);
1497df538e29SHisping Lin 	}
1498df538e29SHisping Lin #endif
1499df538e29SHisping Lin 	ret = rkss_begin_commit();
1500df538e29SHisping Lin 	if (ret < 0) {
1501df538e29SHisping Lin 		printf("TEEC: rkss_begin_commit failed!");
1502df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1503df538e29SHisping Lin 	}
1504df538e29SHisping Lin 
1505df538e29SHisping Lin 	table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT);
1506df538e29SHisping Lin 	if (table_data == NULL) {
1507df538e29SHisping Lin 		printf("TEEC: malloc table_data fail\n");
1508df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1509df538e29SHisping Lin 	}
1510df538e29SHisping Lin 	ret = rkss_read_patition_tables(table_data);
1511df538e29SHisping Lin 	if (ret < 0) {
1512df538e29SHisping Lin 		printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret);
1513df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1514df538e29SHisping Lin 	}
1515df538e29SHisping Lin 
1516df538e29SHisping Lin 	/* Verify Partition Table*/
1517df538e29SHisping Lin 	rkss_verify_ptable(table_data);
1518df538e29SHisping Lin 	free(table_data);
1519df538e29SHisping Lin 	table_data = NULL;
1520df538e29SHisping Lin 
1521df538e29SHisping Lin 	/* Verify Usedflags Section*/
1522df538e29SHisping Lin 	rkss.index = RKSS_USED_FLAGS_INDEX;
1523df538e29SHisping Lin 	ret = rkss_read_multi_sections(rkss.data, rkss.index, 1);
1524df538e29SHisping Lin 	if (ret < 0) {
1525df538e29SHisping Lin 		printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret);
1526df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1527df538e29SHisping Lin 	}
1528df538e29SHisping Lin 	ret = rkss_verify_usedflags(&rkss);
1529df538e29SHisping Lin 	if (ret < 0) {
1530df538e29SHisping Lin 		printf("TEEC: rkss_verify_usedflags fail ! ret: %d.\n", ret);
1531df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1532df538e29SHisping Lin 	}
1533df538e29SHisping Lin 
1534df538e29SHisping Lin #ifdef DEBUG_RKFSS
1535df538e29SHisping Lin 	rkss_dump_ptable();
1536df538e29SHisping Lin 	rkss_dump_usedflags();
1537df538e29SHisping Lin #endif
1538df538e29SHisping Lin 
1539df538e29SHisping Lin 	ret = rkss_finish_commit();
1540df538e29SHisping Lin 	if (ret < 0) {
1541df538e29SHisping Lin 		printf("TEEC: rkss_finish_commit failed!");
1542df538e29SHisping Lin 		return TEEC_ERROR_GENERIC;
1543df538e29SHisping Lin 	}
1544df538e29SHisping Lin 
1545df538e29SHisping Lin 	return TEEC_SUCCESS;
1546df538e29SHisping Lin }
1547df538e29SHisping Lin 
tee_supp_param_is_value(struct tee_ioctl_param * param)1548df538e29SHisping Lin static bool tee_supp_param_is_value(struct tee_ioctl_param *param)
1549df538e29SHisping Lin {
1550df538e29SHisping Lin 	switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
1551df538e29SHisping Lin 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
1552df538e29SHisping Lin 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
1553df538e29SHisping Lin 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
1554df538e29SHisping Lin 		return true;
1555df538e29SHisping Lin 	default:
1556df538e29SHisping Lin 		return false;
1557df538e29SHisping Lin 	}
1558df538e29SHisping Lin }
1559df538e29SHisping Lin 
1560df538e29SHisping Lin static int rkss_step;
tee_supp_rk_fs_process_v1(size_t num_params,struct tee_ioctl_param * params)1561df538e29SHisping Lin int tee_supp_rk_fs_process_v1(size_t num_params,
1562df538e29SHisping Lin 			struct tee_ioctl_param *params)
1563df538e29SHisping Lin {
1564df538e29SHisping Lin 	if (!num_params || !tee_supp_param_is_value(params))
1565df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1566df538e29SHisping Lin 
1567df538e29SHisping Lin 	switch (params->u.value.a) {
1568df538e29SHisping Lin 	case OPTEE_MRF_OPEN:
1569df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_OPEN!\n", rkss_step++);
1570df538e29SHisping Lin 		return ree_fs_new_open(num_params, params);
1571df538e29SHisping Lin 	case OPTEE_MRF_CREATE:
1572df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_CREATE!\n", rkss_step++);
1573df538e29SHisping Lin 		return ree_fs_new_create(num_params, params);
1574df538e29SHisping Lin 	case OPTEE_MRF_CLOSE:
1575df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_CLOSE!\n", rkss_step++);
1576df538e29SHisping Lin 		return ree_fs_new_close(num_params, params);
1577df538e29SHisping Lin 	case OPTEE_MRF_READ:
1578df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_READ!\n", rkss_step++);
1579df538e29SHisping Lin 		return ree_fs_new_read(num_params, params);
1580df538e29SHisping Lin 	case OPTEE_MRF_WRITE:
1581df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_WRITE!\n", rkss_step++);
1582df538e29SHisping Lin 		return ree_fs_new_write(num_params, params);
1583df538e29SHisping Lin 	case OPTEE_MRF_TRUNCATE:
1584df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_TRUNCATE!\n", rkss_step++);
1585df538e29SHisping Lin 		return ree_fs_new_truncate(num_params, params);
1586df538e29SHisping Lin 	case OPTEE_MRF_REMOVE:
1587df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_REMOVE!\n", rkss_step++);
1588df538e29SHisping Lin 		return ree_fs_new_remove(num_params, params);
1589df538e29SHisping Lin 	case OPTEE_MRF_RENAME:
1590df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_RENAME!\n", rkss_step++);
1591df538e29SHisping Lin 		return ree_fs_new_rename(num_params, params);
1592df538e29SHisping Lin 	case OPTEE_MRF_OPENDIR:
1593df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_OPENDIR!\n", rkss_step++);
1594df538e29SHisping Lin 		return ree_fs_new_opendir(num_params, params);
1595df538e29SHisping Lin 	case OPTEE_MRF_CLOSEDIR:
1596df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_CLOSEDIR!\n", rkss_step++);
1597df538e29SHisping Lin 		return ree_fs_new_closedir(num_params, params);
1598df538e29SHisping Lin 	case OPTEE_MRF_READDIR:
1599df538e29SHisping Lin 		debug(">>>>>>> [%d] OPTEE_MRF_READDIR!\n", rkss_step++);
1600df538e29SHisping Lin 		return ree_fs_new_readdir(num_params, params);
1601df538e29SHisping Lin 	default:
1602df538e29SHisping Lin 		return TEEC_ERROR_BAD_PARAMETERS;
1603df538e29SHisping Lin 	}
1604df538e29SHisping Lin }
1605