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