mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 02:27:26 -07:00
chg: wiping / reading / writing flashmem
This commit is contained in:
parent
409c7b1029
commit
f5718fb448
3 changed files with 109 additions and 53 deletions
|
@ -1121,7 +1121,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
// Trigger a finish downloading signal with an ACK frame
|
||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
|
@ -1137,8 +1136,40 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
break;
|
||||
}
|
||||
case CMD_UPLOAD_FLASH_MEM:
|
||||
case CMD_DOWNLOAND_FLASH_MEM:
|
||||
LED_B_ON();
|
||||
|
||||
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
case CMD_DOWNLOAND_FLASH_MEM: {
|
||||
|
||||
LED_B_ON();
|
||||
uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE);
|
||||
bool isok = false;
|
||||
size_t len = 0;
|
||||
uint32_t startidx = c->arg[0];
|
||||
uint32_t numofbytes = c->arg[1];
|
||||
// arg0 = startindex
|
||||
// arg1 = length bytes to transfer
|
||||
// arg2 = RFU
|
||||
//Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, c->arg[2]);
|
||||
|
||||
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
||||
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
||||
|
||||
isok = Flash_ReadData(startidx + i, mem, len);
|
||||
if (!isok )
|
||||
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
|
||||
|
||||
isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len);
|
||||
if (!isok)
|
||||
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CMD_SET_LF_DIVISOR:
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
|
|
@ -146,7 +146,7 @@ uint8_t Flash_ReadStat2(void) {
|
|||
}
|
||||
|
||||
// determine whether FLASHMEM is busy
|
||||
bool Flash_CheckBusy(uint16_t times){
|
||||
bool Flash_CheckBusy(uint16_t times) {
|
||||
bool ret = (Flash_ReadStat1() & BUSY);
|
||||
|
||||
if (!ret || !times || !(times--))
|
||||
|
@ -166,7 +166,7 @@ bool Flash_CheckBusy(uint16_t times){
|
|||
// read ID out
|
||||
uint8_t Flash_ReadID(void) {
|
||||
|
||||
if (Flash_CheckBusy(1000)) return 0;
|
||||
if (Flash_CheckBusy(100)) return 0;
|
||||
|
||||
// Manufacture ID / device ID
|
||||
FlashSendByte(ID);
|
||||
|
@ -188,7 +188,7 @@ uint8_t Flash_ReadID(void) {
|
|||
// read unique id for chip.
|
||||
void Flash_UniqueID(uint8_t *uid) {
|
||||
|
||||
if (Flash_CheckBusy(1000)) return;
|
||||
if (Flash_CheckBusy(100)) return;
|
||||
|
||||
// reading unique serial number
|
||||
FlashSendByte(UNIQUE_ID);
|
||||
|
@ -214,7 +214,7 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
|||
Flash_ReadStat1();
|
||||
|
||||
// length should never be zero
|
||||
if (!len || Flash_CheckBusy(1000)) return 0;
|
||||
if (!len || Flash_CheckBusy(100)) return 0;
|
||||
|
||||
FlashSendByte(READDATA);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
|
@ -231,42 +231,36 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
|||
return len;
|
||||
}
|
||||
|
||||
// Write data
|
||||
// Write data can only program one page. A page has 256 bytes.
|
||||
// if len > 256, it might wrap around and overwrite pos 0.
|
||||
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||
|
||||
// length should never be zero
|
||||
if (!len) {
|
||||
Dbprintf("Flash_WriteData len is zero error");
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
// Max 256 bytes write
|
||||
if (((address & 255) + len) > 256) {
|
||||
Dbprintf("Flash_WriteData 256 fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// out-of-range
|
||||
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||
Dbprintf("Flash_WriteData, block out-of-range");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if 256b, empty out lower index.
|
||||
if (len == 256)
|
||||
address &= 0xFFFF00;
|
||||
|
||||
if (!FlashInit()) {
|
||||
Dbprintf("Flash_WriteData init fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Flash_ReadStat1();
|
||||
|
||||
Flash_WriteEnable();
|
||||
|
||||
if ( len < 0x1000 )
|
||||
Flash_Erase4k(0x00);
|
||||
else if ( len >= 0x1000 && len < 0x7FFF )
|
||||
Flash_Erase32k(0x00);
|
||||
else
|
||||
Flash_Erase64k(0x00);
|
||||
|
||||
// busy after erasing
|
||||
if (Flash_CheckBusy(1000)) {
|
||||
Dbprintf("Flash_WriteData check busy");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ²»ÄÜ¿çÔ½ 256 ×ֽڱ߽ç
|
||||
if (((address & 255) + len) > 256) {
|
||||
Dbprintf("Flash_WriteData 256 fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Flash_WriteEnable();
|
||||
|
||||
|
@ -285,6 +279,25 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
|||
return len;
|
||||
}
|
||||
|
||||
// Wipes flash memory completely, fills with 0xFF
|
||||
bool Flash_WipeMemory() {
|
||||
if (!FlashInit()) {
|
||||
Dbprintf("Flash_WriteData init fail");
|
||||
return false;
|
||||
}
|
||||
Flash_ReadStat1();
|
||||
|
||||
// Each block is 64Kb. Four blocks
|
||||
// one block erase takes 1s ( 1000ms )
|
||||
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(1000);
|
||||
Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(1000);
|
||||
Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(1000);
|
||||
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(1000);
|
||||
|
||||
FlashStop();
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable the flash write
|
||||
void Flash_WriteEnable() {
|
||||
FlashSendLastByte(WRITEENABLE);
|
||||
|
@ -292,20 +305,21 @@ void Flash_WriteEnable() {
|
|||
}
|
||||
|
||||
// erase 4K at one time
|
||||
bool Flash_Erase4k(uint32_t address) {
|
||||
if (address & (4096 - 1)) {
|
||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase4k : Address is not align at 4096");
|
||||
return false;
|
||||
}
|
||||
// execution time: 0.8ms / 800us
|
||||
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
||||
|
||||
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
|
||||
|
||||
FlashSendByte(SECTORERASE);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendLastByte((address >> 0) & 0xFF);
|
||||
FlashSendByte(block);
|
||||
FlashSendByte(sector << 4);
|
||||
FlashSendLastByte(00);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
// erase 32K at one time
|
||||
// execution time: 0,3s / 300ms
|
||||
bool Flash_Erase32k(uint32_t address) {
|
||||
if (address & (32*1024 - 1)) {
|
||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
||||
|
@ -317,17 +331,24 @@ bool Flash_Erase32k(uint32_t address) {
|
|||
FlashSendLastByte((address >> 0) & 0xFF);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// erase 64k at one time
|
||||
bool Flash_Erase64k(uint32_t address) {
|
||||
if (address & (64*1024 - 1)) {
|
||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase64k : Address is not align at 4096");
|
||||
return false;
|
||||
}
|
||||
// erase 64k at one time
|
||||
// since a block is 64kb, and there is four blocks.
|
||||
// we only need block number, as MSB
|
||||
// execution time: 1s / 1000ms
|
||||
// 0x00 00 00 -- 0x 00 FF FF == block 0
|
||||
// 0x01 00 00 -- 0x 01 FF FF == block 1
|
||||
// 0x02 00 00 -- 0x 02 FF FF == block 2
|
||||
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
||||
bool Flash_Erase64k(uint8_t block) {
|
||||
|
||||
if (block > MAX_BLOCKS) return false;
|
||||
|
||||
FlashSendByte(BLOCK64ERASE);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendLastByte((address >> 0) & 0xFF);
|
||||
FlashSendByte(block);
|
||||
FlashSendByte(0x00);
|
||||
FlashSendLastByte(0x00);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -342,7 +363,7 @@ bool FlashInit(void) {
|
|||
|
||||
StartTicks();
|
||||
|
||||
if (Flash_CheckBusy(1000)) {
|
||||
if (Flash_CheckBusy(100)) {
|
||||
StopTicks();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -89,8 +89,6 @@
|
|||
#define NO_CONTINUE 0x00
|
||||
#define PASS 0x01
|
||||
#define FAIL 0x00
|
||||
#define arrayLen(x) (sizeof(x) / sizeof(*x))
|
||||
#define lengthOf(x) (sizeof(x))/sizeof(byte)
|
||||
#define maxAddress capacity
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
@ -108,6 +106,11 @@
|
|||
#define NOSUSPEND 0x09
|
||||
#define UNKNOWNERROR 0xFF
|
||||
|
||||
// List of blocks
|
||||
#define MAX_BLOCKS 4
|
||||
#define MAX_SECTORS 16
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
extern void Dbprintf(const char *fmt, ...);
|
||||
|
||||
|
@ -119,9 +122,10 @@ uint8_t Flash_ReadStat2(void);
|
|||
uint16_t FlashSendByte(uint32_t data);
|
||||
|
||||
void Flash_WriteEnable();
|
||||
bool Flash_Erase4k(uint32_t address);
|
||||
bool Flash_Erase32k(uint32_t address);
|
||||
bool Flash_Erase64k(uint32_t address);
|
||||
bool Flash_WipeMemory();
|
||||
bool Flash_Erase4k(uint8_t block, uint8_t sector);
|
||||
//bool Flash_Erase32k(uint32_t address);
|
||||
bool Flash_Erase64k(uint8_t block);
|
||||
|
||||
bool FlashInit();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue