diff --git a/src/fs/file.c b/src/fs/file.c index c501e67..68c04d3 100644 --- a/src/fs/file.c +++ b/src/fs/file.c @@ -279,8 +279,8 @@ void scan_flash() { if (base == 0x0) //all is empty break; - uint16_t fid = flash_read_uint16(base+sizeof(uintptr_t)); - printf("scan fid %x\r\n",fid); + uint16_t fid = flash_read_uint16(base+sizeof(uintptr_t)+sizeof(uintptr_t)); + printf("[%x] scan fid %x, len %d\r\n",base,fid,flash_read_uint16(base+sizeof(uintptr_t)+sizeof(uintptr_t)+sizeof(uint16_t))); file_t *file = (file_t *)search_by_fid(fid, NULL, SPECIFY_EF); if (!file) { file = file_new(fid); @@ -301,7 +301,7 @@ void scan_flash() { continue; } } - file->data = (uint8_t *)(base+sizeof(uintptr_t)+sizeof(uint16_t)); + file->data = (uint8_t *)(base+sizeof(uintptr_t)+sizeof(uintptr_t)+sizeof(uint16_t)); if (flash_read_uintptr(base) == 0x0) { break; } diff --git a/src/fs/flash.c b/src/fs/flash.c index 9a1dd0e..0646ac4 100644 --- a/src/fs/flash.c +++ b/src/fs/flash.c @@ -8,10 +8,17 @@ #include "file.h" #include "sc_hsm.h" +/* + * ------------------------------------------------------ + * | | + * | next_addr | prev_addr | fid | data (len + payload) | + * | | + * ------------------------------------------------------ + */ #define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES >> 1) // DATA starts at the mid of flash #define FLASH_DATA_HEADER_SIZE (sizeof(uintptr_t)+sizeof(uint32_t)) -//To avoid possible future allocations, data region starts at the begining of flash and goes upwards to the center region +//To avoid possible future allocations, data region starts at the end of flash and goes upwards to the center region const uintptr_t start_data_pool = (XIP_BASE + FLASH_TARGET_OFFSET); const uintptr_t end_data_pool = (XIP_BASE + PICO_FLASH_SIZE_BYTES)-FLASH_DATA_HEADER_SIZE; //This is a fixed value. DO NOT CHANGE @@ -25,33 +32,10 @@ extern uint16_t flash_read_uint16(uintptr_t addr); extern void low_flash_available(); -/* - * Flash data pool managenent - * - * Flash data pool consists of two parts: - * 2-byte header - * contents - * - * Flash data pool objects: - * Data Object (DO) (of smart card) - * Internal objects: - * NONE (0x0000) - * 123-counter - * 14-bit counter - * bool object - * small enum - * - * Format of a Data Object: - * NR: 8-bit tag_number - * LEN: 8-bit length - * DATA: data * LEN - * PAD: optional byte for 16-bit alignment - */ - uintptr_t allocate_free_addr(uint16_t size) { if (size > FLASH_SECTOR_SIZE) return 0x0; //ERROR - size_t real_size = size+sizeof(uint16_t)+sizeof(uintptr_t)+sizeof(uint16_t); //len+len size+next address+fid + size_t real_size = size+sizeof(uint16_t)+sizeof(uintptr_t)+sizeof(uint16_t)+sizeof(uintptr_t); //len+len size+next address+fid+prev_addr size uintptr_t next_base = 0x0; for (uintptr_t base = end_data_pool; base >= start_data_pool; base = next_base) { uintptr_t addr_alg = base & -FLASH_SECTOR_SIZE; //start address of sector @@ -64,20 +48,23 @@ uintptr_t allocate_free_addr(uint16_t size) { if (addr_alg <= potential_addr) //it fits in the current sector { flash_program_uintptr(potential_addr, 0x0); + flash_program_uintptr(potential_addr+sizeof(uintptr_t), base); flash_program_uintptr(base, potential_addr); return potential_addr; } else if (addr_alg-FLASH_SECTOR_SIZE >= start_data_pool) { //check whether it fits in the next sector, so we take addr_aligned as the base potential_addr = addr_alg-real_size; flash_program_uintptr(potential_addr, 0x0); + flash_program_uintptr(potential_addr+sizeof(uintptr_t), base); flash_program_uintptr(base, potential_addr); return potential_addr; } return 0x0; } //we check if |base-(next_addr+size_next_addr)| > |base-potential_addr| only if fid != 1xxx (not size blocked) - else if (addr_alg <= potential_addr && base-(next_base+flash_read_uint16(next_base+sizeof(uintptr_t)+sizeof(uint16_t))+2*sizeof(uint16_t)) > base-potential_addr && flash_read_uint16(next_base+sizeof(uintptr_t)) & 0x1000 != 0x1000) { + else if (addr_alg <= potential_addr && base-(next_base+flash_read_uint16(next_base+sizeof(uintptr_t)+sizeof(uintptr_t)+sizeof(uint16_t))+2*sizeof(uint16_t)+2*sizeof(uintptr_t)) > base-potential_addr && flash_read_uint16(next_base+sizeof(uintptr_t)) & 0x1000 != 0x1000) { flash_program_uintptr(potential_addr, next_base); + flash_program_uintptr(potential_addr+sizeof(uintptr_t), base); flash_program_uintptr(base, potential_addr); return potential_addr; } @@ -86,13 +73,16 @@ uintptr_t allocate_free_addr(uint16_t size) { } int flash_clear_file(file_t *file) { - uintptr_t prev_addr = (uintptr_t)(file->data+flash_read_uint16((uintptr_t)file->data)+sizeof(uint16_t)); - uintptr_t base_addr = (uintptr_t)(file->data-sizeof(uintptr_t)-sizeof(uint16_t)); + uintptr_t base_addr = (uintptr_t)(file->data-sizeof(uintptr_t)-sizeof(uint16_t)-sizeof(uintptr_t)); + uintptr_t prev_addr = flash_read_uintptr(base_addr+sizeof(uintptr_t)); uintptr_t next_addr = flash_read_uintptr(base_addr); - //printf("nc %x %x %x\r\n",prev_addr,base_addr,next_addr); + //printf("nc %x->%x %x->%x\r\n",prev_addr,flash_read_uintptr(prev_addr),base_addr,next_addr); flash_program_uintptr(prev_addr, next_addr); flash_program_halfword((uintptr_t)file->data, 0); - return 0; + if (next_addr > 0) + flash_program_uintptr(next_addr+sizeof(uintptr_t), prev_addr); + //printf("na %x->%x\r\n",prev_addr,flash_read_uintptr(prev_addr)); + return HSM_OK; } int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) { @@ -116,8 +106,8 @@ int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) { //printf("na %x\r\n",new_addr); if (new_addr == 0x0) return HSM_ERR_NO_MEMORY; - file->data = (uint8_t *)new_addr+sizeof(uintptr_t)+sizeof(uint16_t); //next addr+fid - flash_program_halfword(new_addr+sizeof(uintptr_t), file->fid); + file->data = (uint8_t *)new_addr+sizeof(uintptr_t)+sizeof(uint16_t)+sizeof(uintptr_t); //next addr+fid+prev addr + flash_program_halfword(new_addr+sizeof(uintptr_t)+sizeof(uintptr_t), file->fid); flash_program_halfword((uintptr_t)file->data, len); if (data) flash_program_block((uintptr_t)file->data+sizeof(uint16_t), data, len);