mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
use all spi flash v0.1
* introduced a new communication command CMD_FLASHMEM_PAGES64K to get the number of 64k pages * "the last page" is a special, holding the dicts and some other stuff, relocated to there * raised timeout when wiping a mem page (W25Q16 looks a bit slower than W25X20BV) * loop all pages in Flash_WipeMemory()
This commit is contained in:
parent
c9e751d27d
commit
48ec109a1e
10 changed files with 193 additions and 36 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Use all available space from the SPI flash (@ANTodorov)
|
||||||
- Fixed wrong size check in MifareSim (@iceman1001)
|
- Fixed wrong size check in MifareSim (@iceman1001)
|
||||||
- Fixed `hf mf sim` not to respond to authentication attempts for sectors out of bound for selected Mifare type (@piotrva)
|
- Fixed `hf mf sim` not to respond to authentication attempts for sectors out of bound for selected Mifare type (@piotrva)
|
||||||
- Added option to build against non-default python3 with CMake as well (@doegox)
|
- Added option to build against non-default python3 with CMake as well (@doegox)
|
||||||
|
|
|
@ -2789,7 +2789,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (page < 3) {
|
if (page < spi_flash_p64k-1) {
|
||||||
isok = Flash_WipeMemoryPage(page);
|
isok = Flash_WipeMemoryPage(page);
|
||||||
// let spiffs check and update its info post flash erase
|
// let spiffs check and update its info post flash erase
|
||||||
rdv40_spiffs_check();
|
rdv40_spiffs_check();
|
||||||
|
@ -2836,7 +2836,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
|
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
|
||||||
|
|
||||||
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN);
|
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_p64k), info->signature, FLASH_MEM_SIGNATURE_LEN);
|
||||||
|
|
||||||
if (FlashInit()) {
|
if (FlashInit()) {
|
||||||
Flash_UniqueID(info->flashid);
|
Flash_UniqueID(info->flashid);
|
||||||
|
@ -2845,6 +2845,23 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
reply_mix(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t));
|
reply_mix(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t));
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
|
||||||
|
LED_B_OFF();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_FLASHMEM_PAGES64K: {
|
||||||
|
|
||||||
|
LED_B_ON();
|
||||||
|
|
||||||
|
bool isok = false;
|
||||||
|
if (FlashInit()) {
|
||||||
|
isok = true;
|
||||||
|
if (g_dbglevel >= DBG_DEBUG) {
|
||||||
|
Dbprintf(" CMD_FLASHMEM_PAGE64K 0x%02x (%d 64k pages)", spi_flash_p64k, spi_flash_p64k);
|
||||||
|
}
|
||||||
|
FlashStop();
|
||||||
|
}
|
||||||
|
reply_mix(CMD_ACK, isok, 0, 0, &spi_flash_p64k, sizeof(uint8_t));
|
||||||
|
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
// SPIFFS api for RDV40 Integration
|
// SPIFFS api for RDV40 Integration
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#define SPIFFS_CFG_PHYS_SZ (1024 * 192)
|
|
||||||
#define SPIFFS_CFG_PHYS_ERASE_SZ (4 * 1024)
|
#define SPIFFS_CFG_PHYS_ERASE_SZ (4 * 1024)
|
||||||
#define SPIFFS_CFG_PHYS_ADDR (0)
|
#define SPIFFS_CFG_PHYS_ADDR (0)
|
||||||
#define SPIFFS_CFG_LOG_PAGE_SZ (256)
|
#define SPIFFS_CFG_LOG_PAGE_SZ (256)
|
||||||
|
|
|
@ -236,7 +236,7 @@ typedef uint8_t u8_t;
|
||||||
// Instead of giving parameters in config struct, singleton build must
|
// Instead of giving parameters in config struct, singleton build must
|
||||||
// give parameters in defines below.
|
// give parameters in defines below.
|
||||||
#ifndef SPIFFS_CFG_PHYS_SZ
|
#ifndef SPIFFS_CFG_PHYS_SZ
|
||||||
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*192)
|
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024 * 64 * (spi_flash_p64k - 1))
|
||||||
#endif
|
#endif
|
||||||
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ
|
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ
|
||||||
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024)
|
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024)
|
||||||
|
|
|
@ -50,6 +50,29 @@ static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int rdv4_get_flash_pages64k(uint8_t *pages64k) {
|
||||||
|
if (pages64k == NULL) {
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_FLASHMEM_PAGES64K, NULL, 0);
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "rdv4_get_flash_pages64k() timeout while waiting for reply");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t isok = resp.oldarg[0] & 0xFF;
|
||||||
|
if (isok == false) {
|
||||||
|
PrintAndLogEx(FAILED, "fail reading from flash (pages 64k)");
|
||||||
|
return PM3_EFLASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pages64k, (uint8_t *)resp.data.asBytes, sizeof(uint8_t));
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int rdv4_get_signature(rdv40_validation_t *out) {
|
int rdv4_get_signature(rdv40_validation_t *out) {
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
@ -98,8 +121,16 @@ int rdv4_validate(rdv40_validation_t *mem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rdv4_sign_write(uint8_t *signature, uint8_t slen) {
|
static int rdv4_sign_write(uint8_t *signature, uint8_t slen) {
|
||||||
|
|
||||||
|
uint8_t spi_flash_pages = 0;
|
||||||
|
int res = rdv4_get_flash_pages64k(&spi_flash_pages);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "failed to get flash pages (%x)", res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
flashmem_old_write_t payload = {
|
flashmem_old_write_t payload = {
|
||||||
.startidx = FLASH_MEM_SIGNATURE_OFFSET,
|
.startidx = FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages),
|
||||||
.len = FLASH_MEM_SIGNATURE_LEN,
|
.len = FLASH_MEM_SIGNATURE_LEN,
|
||||||
};
|
};
|
||||||
memcpy(payload.data, signature, slen);
|
memcpy(payload.data, signature, slen);
|
||||||
|
@ -201,15 +232,21 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "treating file as T55xx passwords");
|
PrintAndLogEx(INFO, "treating file as T55xx passwords");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t spi_flash_pages = 0;
|
||||||
|
int res = rdv4_get_flash_pages64k(&spi_flash_pages);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "failed to get flash pages count (%x)", res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
size_t datalen = 0;
|
size_t datalen = 0;
|
||||||
uint32_t keycount = 0;
|
uint32_t keycount = 0;
|
||||||
int res = 0;
|
|
||||||
uint8_t keylen = 0;
|
uint8_t keylen = 0;
|
||||||
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t));
|
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE_P(spi_flash_pages), sizeof(uint8_t));
|
||||||
|
|
||||||
switch (d) {
|
switch (d) {
|
||||||
case DICTIONARY_MIFARE:
|
case DICTIONARY_MIFARE:
|
||||||
offset = DEFAULT_MF_KEYS_OFFSET;
|
offset = DEFAULT_MF_KEYS_OFFSET_P(spi_flash_pages);
|
||||||
keylen = 6;
|
keylen = 6;
|
||||||
res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount);
|
res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount);
|
||||||
if (res || !keycount) {
|
if (res || !keycount) {
|
||||||
|
@ -227,7 +264,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
datalen += 2;
|
datalen += 2;
|
||||||
break;
|
break;
|
||||||
case DICTIONARY_T55XX:
|
case DICTIONARY_T55XX:
|
||||||
offset = DEFAULT_T55XX_KEYS_OFFSET;
|
offset = DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_pages);
|
||||||
keylen = 4;
|
keylen = 4;
|
||||||
res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount);
|
res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount);
|
||||||
if (res || !keycount) {
|
if (res || !keycount) {
|
||||||
|
@ -245,7 +282,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
datalen += 2;
|
datalen += 2;
|
||||||
break;
|
break;
|
||||||
case DICTIONARY_ICLASS:
|
case DICTIONARY_ICLASS:
|
||||||
offset = DEFAULT_ICLASS_KEYS_OFFSET;
|
offset = DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_pages);
|
||||||
res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount);
|
res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount);
|
||||||
if (res || !keycount) {
|
if (res || !keycount) {
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -268,7 +305,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (datalen > FLASH_MEM_MAX_SIZE) {
|
if (datalen > FLASH_MEM_MAX_SIZE_P(spi_flash_pages)) {
|
||||||
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
|
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
|
||||||
free(data);
|
free(data);
|
||||||
return PM3_EOVFLOW;
|
return PM3_EOVFLOW;
|
||||||
|
@ -351,8 +388,15 @@ static int CmdFlashMemDump(const char *Cmd) {
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
uint8_t spi_flash_pages = 0;
|
||||||
|
int res = rdv4_get_flash_pages64k(&spi_flash_pages);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "failed to get flash pages count (%x)", res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int offset = arg_get_int_def(ctx, 1, 0);
|
int offset = arg_get_int_def(ctx, 1, 0);
|
||||||
int len = arg_get_int_def(ctx, 2, FLASH_MEM_MAX_SIZE);
|
int len = arg_get_int_def(ctx, 2, FLASH_MEM_MAX_SIZE_P(spi_flash_pages));
|
||||||
bool view = arg_get_lit(ctx, 3);
|
bool view = arg_get_lit(ctx, 3);
|
||||||
int fnlen = 0;
|
int fnlen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
|
@ -409,15 +453,22 @@ static int CmdFlashMemWipe(const char *Cmd) {
|
||||||
// initialwipe = arg_get_lit(ctx, 2);
|
// initialwipe = arg_get_lit(ctx, 2);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (page < 0 || page > 2) {
|
uint8_t spi_flash_pages = 0;
|
||||||
PrintAndLogEx(WARNING, "page must be 0, 1 or 2");
|
int res = rdv4_get_flash_pages64k(&spi_flash_pages);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "failed to get flash pages count (%x)", res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page < 0 || page > (spi_flash_pages - 1)) {
|
||||||
|
PrintAndLogEx(WARNING, "page must be between 0 and %d", spi_flash_pages - 1);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_FLASHMEM_WIPE, page, initialwipe, 0, NULL, 0);
|
SendCommandMIX(CMD_FLASHMEM_WIPE, page, initialwipe, 0, NULL, 0);
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 8000)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 10000)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,4 +32,5 @@ typedef enum {
|
||||||
int CmdFlashMem(const char *Cmd);
|
int CmdFlashMem(const char *Cmd);
|
||||||
int rdv4_get_signature(rdv40_validation_t *out);
|
int rdv4_get_signature(rdv40_validation_t *out);
|
||||||
int rdv4_validate(rdv40_validation_t *mem);
|
int rdv4_validate(rdv40_validation_t *mem);
|
||||||
|
int rdv4_get_flash_pages64k(uint8_t *pages64k);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,6 +43,8 @@ static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
||||||
|
|
||||||
#ifndef AS_BOOTROM
|
#ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
uint8_t spi_flash_p64k = 0;
|
||||||
|
|
||||||
void FlashmemSetSpiBaudrate(uint32_t baudrate) {
|
void FlashmemSetSpiBaudrate(uint32_t baudrate) {
|
||||||
FLASHMEM_SPIBAUDRATE = baudrate;
|
FLASHMEM_SPIBAUDRATE = baudrate;
|
||||||
Dbprintf("Spi Baudrate : %dMHz", FLASHMEM_SPIBAUDRATE / 1000000);
|
Dbprintf("Spi Baudrate : %dMHz", FLASHMEM_SPIBAUDRATE / 1000000);
|
||||||
|
@ -144,14 +146,15 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// out-of-range
|
if (!FlashInit()) {
|
||||||
if (((address >> 16) & 0xFF) > MAX_BLOCKS) {
|
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
||||||
Dbprintf("Flash_WriteData, block out-of-range");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FlashInit()) {
|
// out-of-range
|
||||||
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
if (((address >> 16) & 0xFF) > spi_flash_p64k) {
|
||||||
|
Dbprintf("Flash_WriteData, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k);
|
||||||
|
FlashStop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,8 +190,8 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((address >> 16) & 0xFF) > MAX_BLOCKS) {
|
if (((address >> 16) & 0xFF) > spi_flash_p64k) {
|
||||||
Dbprintf("Flash_WriteDataCont, block out-of-range");
|
Dbprintf("Flash_WriteDataCont, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,18 +269,11 @@ bool Flash_WipeMemory(void) {
|
||||||
|
|
||||||
// Each block is 64Kb. Four blocks
|
// Each block is 64Kb. Four blocks
|
||||||
// one block erase takes 1s ( 1000ms )
|
// one block erase takes 1s ( 1000ms )
|
||||||
Flash_WriteEnable();
|
for (uint8_t i=0; i < spi_flash_p64k; i++) {
|
||||||
Flash_Erase64k(0);
|
Flash_WriteEnable();
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_Erase64k(i);
|
||||||
Flash_WriteEnable();
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_Erase64k(1);
|
}
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase64k(2);
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase64k(3);
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return true;
|
return true;
|
||||||
|
@ -293,7 +289,7 @@ void Flash_WriteEnable(void) {
|
||||||
// execution time: 0.8ms / 800us
|
// execution time: 0.8ms / 800us
|
||||||
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
||||||
|
|
||||||
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
|
if (block > spi_flash_p64k || sector > MAX_SECTORS) return false;
|
||||||
|
|
||||||
FlashSendByte(SECTORERASE);
|
FlashSendByte(SECTORERASE);
|
||||||
FlashSendByte(block);
|
FlashSendByte(block);
|
||||||
|
@ -328,7 +324,7 @@ bool Flash_Erase32k(uint32_t address) {
|
||||||
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
||||||
bool Flash_Erase64k(uint8_t block) {
|
bool Flash_Erase64k(uint8_t block) {
|
||||||
|
|
||||||
if (block > MAX_BLOCKS) return false;
|
if (block > spi_flash_p64k) return false;
|
||||||
|
|
||||||
FlashSendByte(BLOCK64ERASE);
|
FlashSendByte(BLOCK64ERASE);
|
||||||
FlashSendByte(block);
|
FlashSendByte(block);
|
||||||
|
@ -404,6 +400,7 @@ void Flashmem_print_status(void) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Dbprintf(" Flash pages (64k)....... " _YELLOW_("0x%02x (%u)"), spi_flash_p64k, spi_flash_p64k);
|
||||||
|
|
||||||
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
Flash_UniqueID(uid);
|
Flash_UniqueID(uid);
|
||||||
|
@ -457,6 +454,38 @@ void Flashmem_print_info(void) {
|
||||||
FlashStop();
|
FlashStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//read spi flash JEDEC ID and fill the global variable spi_flash_p64k
|
||||||
|
bool FlashDetect(bool flash_init) {
|
||||||
|
flash_device_type_t flash_device = {0};
|
||||||
|
|
||||||
|
if (flash_init) {
|
||||||
|
if (!FlashInit()) {
|
||||||
|
if (g_dbglevel > 3) Dbprintf("FlashDetect() FlashInit fail");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Flash_ReadID(&flash_device, true)) {
|
||||||
|
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t identifier = (flash_device.manufacturer_id <<16) + (flash_device.device_id <<8) + flash_device.device_id2;
|
||||||
|
int i = 0;
|
||||||
|
for (; i < ARRAYLEN(SpiFlashTable); i++) {
|
||||||
|
if (SpiFlashTable[i].identifier == identifier) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_flash_p64k = SpiFlashTable[i].pages64;
|
||||||
|
|
||||||
|
if (flash_init) {
|
||||||
|
FlashStop();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // #ifndef AS_BOOTROM
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
|
||||||
|
@ -471,6 +500,12 @@ bool FlashInit(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef AS_BOOTROM
|
||||||
|
if (spi_flash_p64k == 0){
|
||||||
|
if (!FlashDetect(false)) return 0;
|
||||||
|
}
|
||||||
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,37 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
void Flashmem_print_status(void);
|
void Flashmem_print_status(void);
|
||||||
void Flashmem_print_info(void);
|
void Flashmem_print_info(void);
|
||||||
|
|
||||||
|
typedef struct spi_flash_s {
|
||||||
|
const uint32_t identifier;
|
||||||
|
const uint8_t pages64;
|
||||||
|
const char *desc;
|
||||||
|
} spi_flash_t;
|
||||||
|
|
||||||
|
// spi_flash_t is expected to be NULL terminated
|
||||||
|
const static spi_flash_t SpiFlashTable[] = {
|
||||||
|
// Manufacturer: Puya
|
||||||
|
{ 0x856015, 32, "P25Q16H" },
|
||||||
|
// Manufacturer: Winbond
|
||||||
|
{ 0xEF3012, 4, "W25X20BV" },
|
||||||
|
{ 0xEF3013, 8, "W25X40BV" },
|
||||||
|
|
||||||
|
{ 0xEF4013, 8, "W25Q40BV" },
|
||||||
|
{ 0xEF4014, 16, "W25Q80BV" },
|
||||||
|
{ 0xEF4015, 32, "W25Q16BV" },
|
||||||
|
{ 0xEF4016, 64, "W25Q32BV" },
|
||||||
|
|
||||||
|
{ 0xEF7022, 4, "W25Q02JV" },
|
||||||
|
{ 0x000000, 4, "Unknown!" }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef ARRAYLEN
|
||||||
|
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern uint8_t spi_flash_p64k;
|
||||||
|
|
||||||
|
bool FlashDetect(bool);
|
||||||
|
|
||||||
#endif // #ifndef AS_BOOTROM
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -433,6 +433,7 @@ typedef struct {
|
||||||
#define CMD_FLASHMEM_DOWNLOADED 0x0124
|
#define CMD_FLASHMEM_DOWNLOADED 0x0124
|
||||||
#define CMD_FLASHMEM_INFO 0x0125
|
#define CMD_FLASHMEM_INFO 0x0125
|
||||||
#define CMD_FLASHMEM_SET_SPIBAUDRATE 0x0126
|
#define CMD_FLASHMEM_SET_SPIBAUDRATE 0x0126
|
||||||
|
#define CMD_FLASHMEM_PAGES64K 0x0127
|
||||||
|
|
||||||
// RDV40, High level flashmem SPIFFS Manipulation
|
// RDV40, High level flashmem SPIFFS Manipulation
|
||||||
// ALL function will have a lazy or Safe version
|
// ALL function will have a lazy or Safe version
|
||||||
|
|
|
@ -37,10 +37,16 @@
|
||||||
#ifndef FLASH_MEM_MAX_SIZE
|
#ifndef FLASH_MEM_MAX_SIZE
|
||||||
# define FLASH_MEM_MAX_SIZE 0x40000 // (262144)
|
# define FLASH_MEM_MAX_SIZE 0x40000 // (262144)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FLASH_MEM_MAX_SIZE_P
|
||||||
|
# define FLASH_MEM_MAX_SIZE_P(p64k) (1024 * 64 * p64k)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FLASH_MEM_MAX_4K_SECTOR
|
#ifndef FLASH_MEM_MAX_4K_SECTOR
|
||||||
# define FLASH_MEM_MAX_4K_SECTOR 0x3F000
|
# define FLASH_MEM_MAX_4K_SECTOR 0x3F000
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FLASH_MEM_MAX_4K_SECTOR_P
|
||||||
|
# define FLASH_MEM_MAX_4K_SECTOR_P(p64k) (FLASH_MEM_MAX_SIZE_P(p64k) - 4096)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FLASH_MEM_ID_LEN
|
#ifndef FLASH_MEM_ID_LEN
|
||||||
# define FLASH_MEM_ID_LEN 8
|
# define FLASH_MEM_ID_LEN 8
|
||||||
|
@ -54,6 +60,9 @@
|
||||||
// -1 for historical compatibility with already released Proxmark3 RDV4.0 devices
|
// -1 for historical compatibility with already released Proxmark3 RDV4.0 devices
|
||||||
# define FLASH_MEM_SIGNATURE_OFFSET (FLASH_MEM_MAX_SIZE - FLASH_MEM_SIGNATURE_LEN - 1)
|
# define FLASH_MEM_SIGNATURE_OFFSET (FLASH_MEM_MAX_SIZE - FLASH_MEM_SIGNATURE_LEN - 1)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FLASH_MEM_SIGNATURE_OFFSET_P
|
||||||
|
# define FLASH_MEM_SIGNATURE_OFFSET_P(p64k) (FLASH_MEM_MAX_SIZE_P(p64k) - FLASH_MEM_SIGNATURE_LEN - 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef T55XX_CONFIG_LEN
|
#ifndef T55XX_CONFIG_LEN
|
||||||
# define T55XX_CONFIG_LEN sizeof( t55xx_configurations_t )
|
# define T55XX_CONFIG_LEN sizeof( t55xx_configurations_t )
|
||||||
|
@ -62,6 +71,9 @@
|
||||||
#ifndef T55XX_CONFIG_OFFSET
|
#ifndef T55XX_CONFIG_OFFSET
|
||||||
# define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x2000)
|
# define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x2000)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef T55XX_CONFIG_OFFSET_P
|
||||||
|
# define T55XX_CONFIG_OFFSET_P(p64k) (FLASH_MEM_MAX_4K_SECTOR_P(p64k) - 0x2000)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Reserved space for T55XX PWD = 4 kb
|
// Reserved space for T55XX PWD = 4 kb
|
||||||
#ifndef DEFAULT_T55XX_KEYS_OFFSET
|
#ifndef DEFAULT_T55XX_KEYS_OFFSET
|
||||||
|
@ -69,6 +81,9 @@
|
||||||
# define DEFAULT_T55XX_KEYS_OFFSET (T55XX_CONFIG_OFFSET - DEFAULT_T55XX_KEYS_LEN)
|
# define DEFAULT_T55XX_KEYS_OFFSET (T55XX_CONFIG_OFFSET - DEFAULT_T55XX_KEYS_LEN)
|
||||||
# define DEFAULT_T55XX_KEYS_MAX ((DEFAULT_T55XX_KEYS_LEN - 2) / 4)
|
# define DEFAULT_T55XX_KEYS_MAX ((DEFAULT_T55XX_KEYS_LEN - 2) / 4)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DEFAULT_T55XX_KEYS_OFFSET_P
|
||||||
|
# define DEFAULT_T55XX_KEYS_OFFSET_P(p64k) (T55XX_CONFIG_OFFSET_P(p64k) - DEFAULT_T55XX_KEYS_LEN)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Reserved space for iClass keys = 4 kb
|
// Reserved space for iClass keys = 4 kb
|
||||||
#ifndef DEFAULT_ICLASS_KEYS_OFFSET
|
#ifndef DEFAULT_ICLASS_KEYS_OFFSET
|
||||||
|
@ -76,6 +91,9 @@
|
||||||
# define DEFAULT_ICLASS_KEYS_OFFSET (DEFAULT_T55XX_KEYS_OFFSET - DEFAULT_ICLASS_KEYS_LEN)
|
# define DEFAULT_ICLASS_KEYS_OFFSET (DEFAULT_T55XX_KEYS_OFFSET - DEFAULT_ICLASS_KEYS_LEN)
|
||||||
# define DEFAULT_ICLASS_KEYS_MAX ((DEFAULT_ICLASS_KEYS_LEN - 2) / 8)
|
# define DEFAULT_ICLASS_KEYS_MAX ((DEFAULT_ICLASS_KEYS_LEN - 2) / 8)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DEFAULT_ICLASS_KEYS_OFFSET_P
|
||||||
|
# define DEFAULT_ICLASS_KEYS_OFFSET_P(p64k) (DEFAULT_T55XX_KEYS_OFFSET_P(p64k) - DEFAULT_ICLASS_KEYS_LEN)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Reserved space for MIFARE Keys = 12 kb
|
// Reserved space for MIFARE Keys = 12 kb
|
||||||
#ifndef DEFAULT_MF_KEYS_OFFSET
|
#ifndef DEFAULT_MF_KEYS_OFFSET
|
||||||
|
@ -83,6 +101,9 @@
|
||||||
# define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN)
|
# define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN)
|
||||||
# define DEFAULT_MF_KEYS_MAX ((DEFAULT_MF_KEYS_LEN - 2) / 6)
|
# define DEFAULT_MF_KEYS_MAX ((DEFAULT_MF_KEYS_LEN - 2) / 6)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DEFAULT_MF_KEYS_OFFSET_P
|
||||||
|
# define DEFAULT_MF_KEYS_OFFSET_P(p64k) (DEFAULT_ICLASS_KEYS_OFFSET_P(p64k) - DEFAULT_MF_KEYS_LEN)
|
||||||
|
#endif
|
||||||
|
|
||||||
// RDV40, validation structure to help identifying that client/firmware is talking with RDV40
|
// RDV40, validation structure to help identifying that client/firmware is talking with RDV40
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue