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