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