mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Check for sifficient flashsize before applying an update
This commit is contained in:
+6
-26
@@ -803,47 +803,27 @@ void cmd_parser(void) __banked
|
|||||||
}
|
}
|
||||||
} else if (cmd_compare(0, "stat")) {
|
} else if (cmd_compare(0, "stat")) {
|
||||||
port_stats_print();
|
port_stats_print();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'r') {
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 's') {
|
||||||
print_string("\nPRINT SECURITY REGISTERS\n");
|
print_string("\nSECURITY REGISTERS\n");
|
||||||
// The following will only show something else than 0xff if it was programmed for a managed switch
|
// The following will only show something else than 0xff if it was programmed for a managed switch
|
||||||
|
print_string("Region 1: ");
|
||||||
flash_region.addr = 0x0001000;
|
flash_region.addr = 0x0001000;
|
||||||
flash_region.len = 40;
|
flash_region.len = 40;
|
||||||
flash_read_security();
|
flash_read_security();
|
||||||
|
print_string("\nRegion 2: ");
|
||||||
flash_region.addr = 0x0002000;
|
flash_region.addr = 0x0002000;
|
||||||
flash_region.len = 40;
|
flash_region.len = 40;
|
||||||
flash_read_security();
|
flash_read_security();
|
||||||
|
print_string("\nRegion 3: ");
|
||||||
flash_region.addr = 0x0003000;
|
flash_region.addr = 0x0003000;
|
||||||
flash_region.len = 40;
|
flash_region.len = 40;
|
||||||
flash_read_security();
|
flash_read_security();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'd') {
|
|
||||||
print_string("\nDUMPING FLASH\n");
|
|
||||||
flash_region.addr = 0;
|
|
||||||
flash_region.len = 255;
|
|
||||||
flash_dump(255);
|
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'j') {
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'j') {
|
||||||
print_string("\nJEDEC ID\n");
|
print_string("\nJEDEC ID\n");
|
||||||
flash_read_jedecid();
|
flash_read_jedecid();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'u') {
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'u') {
|
||||||
print_string("\nUNIQUE ID\n");
|
print_string("\nUNIQUE ID (note: only 4 bytes are likely correct here!)\n");
|
||||||
flash_read_uid();
|
flash_read_uid();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 's') {
|
|
||||||
print_string("\nFLASH FAST MODE\n"); // Switch to flash 62.5 MHz mode
|
|
||||||
flash_init(1);
|
|
||||||
print_string("\nNow dumping flash\n");
|
|
||||||
flash_region.addr = 0;
|
|
||||||
flash_region.len = 255;
|
|
||||||
flash_dump(255);
|
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'e') {
|
|
||||||
print_string("\nFLASH erase\n");
|
|
||||||
flash_region.addr = 0x20000;
|
|
||||||
flash_sector_erase();
|
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'w') {
|
|
||||||
print_string("\nFLASH write\n");
|
|
||||||
for (uint8_t i = 0; i < 20; i++)
|
|
||||||
flash_buf[i] = greeting[i];
|
|
||||||
flash_region.addr = 0x200000;
|
|
||||||
flash_region.len = 20;
|
|
||||||
flash_write_bytes(flash_buf);
|
|
||||||
} else if (cmd_compare(0, "port") && cmd_words_b[1] > 0) {
|
} else if (cmd_compare(0, "port") && cmd_words_b[1] > 0) {
|
||||||
parse_port();
|
parse_port();
|
||||||
} else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) {
|
} else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ extern __code uint8_t * __code hex;
|
|||||||
extern __code struct f_data f_data[];
|
extern __code struct f_data f_data[];
|
||||||
extern __code char * __code mime_strings[];
|
extern __code char * __code mime_strings[];
|
||||||
extern __xdata struct flash_region_t flash_region;
|
extern __xdata struct flash_region_t flash_region;
|
||||||
|
extern __xdata uint32_t flash_size;
|
||||||
|
|
||||||
// Flash buffer to optimize flash writing speed, write_len is the current filling position
|
// Flash buffer to optimize flash writing speed, write_len is the current filling position
|
||||||
extern __xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
extern __xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
||||||
@@ -426,6 +427,12 @@ void handle_post(void)
|
|||||||
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
||||||
|
|
||||||
if (is_word(request_path, "upload")) {
|
if (is_word(request_path, "upload")) {
|
||||||
|
if (flash_size < FIRMWARE_UPLOAD_START*2)
|
||||||
|
{
|
||||||
|
print_string("Flash too small for firmware upload!\n");
|
||||||
|
send_bad_request();
|
||||||
|
return;
|
||||||
|
}
|
||||||
print_string("Firmware upload started.");
|
print_string("Firmware upload started.");
|
||||||
uptr = FIRMWARE_UPLOAD_START;
|
uptr = FIRMWARE_UPLOAD_START;
|
||||||
verify_crc = 1;
|
verify_crc = 1;
|
||||||
|
|||||||
+15
-56
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
__xdata uint8_t dio_enabled;
|
__xdata uint8_t dio_enabled;
|
||||||
__xdata struct flash_region_t flash_region;
|
__xdata struct flash_region_t flash_region;
|
||||||
|
__xdata uint32_t flash_size;
|
||||||
|
|
||||||
// For the flash commands, see e.g. Windbond W25Q32JV datasheet
|
// For the flash commands, see e.g. Windbond W25Q32JV datasheet
|
||||||
#define CMD_WRITE_STATUS 0x01
|
#define CMD_WRITE_STATUS 0x01
|
||||||
@@ -17,6 +17,7 @@ __xdata struct flash_region_t flash_region;
|
|||||||
// Don't use command `READ 0x03`, because on many device this command can't run at maximum SPI-clock speed.
|
// Don't use command `READ 0x03`, because on many device this command can't run at maximum SPI-clock speed.
|
||||||
// Use `Fast READ 0x0b` instead!
|
// Use `Fast READ 0x0b` instead!
|
||||||
//#define CMD_READ 0x03
|
//#define CMD_READ 0x03
|
||||||
|
#define CMD_READ_STATUS 0x05
|
||||||
#define CMD_WRITE_ENABLE 0x06
|
#define CMD_WRITE_ENABLE 0x06
|
||||||
#define CMD_FREAD 0x0b
|
#define CMD_FREAD 0x0b
|
||||||
#define CMD_SECTOR_ERASE 0x20
|
#define CMD_SECTOR_ERASE 0x20
|
||||||
@@ -87,7 +88,7 @@ uint8_t flash_read_status(void)
|
|||||||
|
|
||||||
// setup status read command
|
// setup status read command
|
||||||
SFR_FLASH_TCONF = 0x11;
|
SFR_FLASH_TCONF = 0x11;
|
||||||
SFR_FLASH_CMD_R = 5;
|
SFR_FLASH_CMD_R = CMD_READ_STATUS;
|
||||||
|
|
||||||
// execute and wait for controller done
|
// execute and wait for controller done
|
||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
@@ -119,9 +120,10 @@ void flash_read_uid(void)
|
|||||||
print_byte(SFR_FLASH_DATA8);
|
print_byte(SFR_FLASH_DATA8);
|
||||||
print_byte(SFR_FLASH_DATA16);
|
print_byte(SFR_FLASH_DATA16);
|
||||||
print_byte(SFR_FLASH_DATA24);
|
print_byte(SFR_FLASH_DATA24);
|
||||||
|
write_char(' ');
|
||||||
|
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 24; // Doesn't seem to work; we get the same data as for the first transfer
|
||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
SFR_FLASH_DUMMYCYCLES = 24;
|
|
||||||
while(SFR_FLASH_EXEC_BUSY);
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
print_byte(SFR_FLASH_DATA0);
|
print_byte(SFR_FLASH_DATA0);
|
||||||
@@ -148,15 +150,17 @@ void flash_read_jedecid(void)
|
|||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
while(SFR_FLASH_EXEC_BUSY);
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
|
print_string("Maufacturer ID: 0x");
|
||||||
print_byte(SFR_FLASH_DATA0);
|
print_byte(SFR_FLASH_DATA0);
|
||||||
|
print_string("\nMemory Type: 0x");
|
||||||
print_byte(SFR_FLASH_DATA8);
|
print_byte(SFR_FLASH_DATA8);
|
||||||
print_byte(SFR_FLASH_DATA16);
|
print_string("\nCapacity: 0x");
|
||||||
print_byte(SFR_FLASH_DATA24);
|
uint8_t cap = SFR_FLASH_DATA16;
|
||||||
|
flash_size = 1UL << cap;
|
||||||
// Reset slow read mode
|
print_byte(cap);
|
||||||
SFR_FLASH_MODEB = 0x0;
|
print_string(" = ");
|
||||||
SFR_FLASH_CMD_R = CMD_FREAD;
|
print_long(flash_size);
|
||||||
SFR_FLASH_DUMMYCYCLES = 8;
|
print_string(" Bytes\n");
|
||||||
|
|
||||||
flash_configure_mmio();
|
flash_configure_mmio();
|
||||||
}
|
}
|
||||||
@@ -188,51 +192,6 @@ void flash_write_enable(void)
|
|||||||
} while (!(status & 0x2));
|
} while (!(status & 0x2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void flash_dump(uint8_t len)
|
|
||||||
{
|
|
||||||
short status;
|
|
||||||
do {
|
|
||||||
status = flash_read_status();
|
|
||||||
print_short(status);
|
|
||||||
} while (status & 0x1);
|
|
||||||
|
|
||||||
// Set fast read mode
|
|
||||||
if (dio_enabled) {
|
|
||||||
SFR_FLASH_MODEB = 0x18;
|
|
||||||
SFR_FLASH_CMD_R = CMD_FREAD_DIO;
|
|
||||||
SFR_FLASH_DUMMYCYCLES = 4;
|
|
||||||
} else {
|
|
||||||
SFR_FLASH_MODEB = 0x0;
|
|
||||||
SFR_FLASH_CMD_R = CMD_FREAD; // Fast read
|
|
||||||
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read?
|
|
||||||
}
|
|
||||||
// Read 4 bytes
|
|
||||||
SFR_FLASH_TCONF = 4;
|
|
||||||
while (len) {
|
|
||||||
SFR_FLASH_ADDR16 = flash_region.addr >> 16;
|
|
||||||
SFR_FLASH_ADDR8 = flash_region.addr >> 8;
|
|
||||||
SFR_FLASH_ADDR0 = flash_region.addr;
|
|
||||||
flash_region.addr += 4;
|
|
||||||
|
|
||||||
SFR_FLASH_EXEC_GO = 1;
|
|
||||||
while(SFR_FLASH_EXEC_BUSY);
|
|
||||||
|
|
||||||
print_short(SFR_FLASH_DATA0);
|
|
||||||
if (len == 1)
|
|
||||||
return;
|
|
||||||
print_short(SFR_FLASH_DATA8);
|
|
||||||
if (len == 2)
|
|
||||||
return;
|
|
||||||
print_short(SFR_FLASH_DATA16);
|
|
||||||
if (len == 3)
|
|
||||||
return;
|
|
||||||
print_short(SFR_FLASH_DATA24);
|
|
||||||
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads bulk data of length len from the flash memory starging at address src
|
* Reads bulk data of length len from the flash memory starging at address src
|
||||||
* and writes the data into a buffer pointed to by dst in XMEM
|
* and writes the data into a buffer pointed to by dst in XMEM
|
||||||
@@ -315,7 +274,7 @@ void flash_read_security(void)
|
|||||||
if (flash_region.len == 3)
|
if (flash_region.len == 3)
|
||||||
break;
|
break;
|
||||||
print_byte(SFR_FLASH_DATA24);
|
print_byte(SFR_FLASH_DATA24);
|
||||||
|
write_char(' ');
|
||||||
flash_region.len -= 4;
|
flash_region.len -= 4;
|
||||||
} while(flash_region.len);
|
} while(flash_region.len);
|
||||||
|
|
||||||
|
|||||||
+24
-25
@@ -24,9 +24,9 @@
|
|||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
|
||||||
extern __code const struct machine machine;
|
extern __code const struct machine machine;
|
||||||
|
extern __xdata uint32_t flash_size;
|
||||||
|
|
||||||
extern __xdata uint16_t crc_value;
|
extern __xdata uint16_t crc_value;
|
||||||
__xdata uint8_t crc_testbytes[10];
|
|
||||||
__xdata struct machine_runtime machine_detected;
|
__xdata struct machine_runtime machine_detected;
|
||||||
void crc16(__xdata uint8_t *v) __naked;
|
void crc16(__xdata uint8_t *v) __naked;
|
||||||
|
|
||||||
@@ -548,16 +548,6 @@ uint8_t read_flash(uint8_t bank, __code uint8_t *addr)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_long_x(__xdata uint8_t v[])
|
|
||||||
{
|
|
||||||
write_char('0'); write_char('x');
|
|
||||||
for (uint8_t i=0; i < 4; i++) {
|
|
||||||
write_char(hex[v[i] >> 4]);
|
|
||||||
write_char(hex[v[i] & 0xf]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a SerDes register in the SoC
|
* Read a SerDes register in the SoC
|
||||||
* Input must be: sds_id = 0/1, page < 128, reg <= 0xff
|
* Input must be: sds_id = 0/1, page < 128, reg <= 0xff
|
||||||
@@ -1869,6 +1859,19 @@ void setup_i2c(void)
|
|||||||
|
|
||||||
void check_and_flash_update_image(void)
|
void check_and_flash_update_image(void)
|
||||||
{
|
{
|
||||||
|
flash_read_jedecid(); // This initializes also __xdata flash_size variable
|
||||||
|
|
||||||
|
print_long(flash_size); print_string(" flash size detected.\n");
|
||||||
|
print_long(FIRMWARE_UPLOAD_START*2); print_string(" bytes needed for update.\n");
|
||||||
|
if (flash_size < FIRMWARE_UPLOAD_START*2) {
|
||||||
|
print_string("Flash too small for updating; skipping update check\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_string("Flash size ok.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check if an update image is in flash
|
// Check if an update image is in flash
|
||||||
flash_region.addr = FIRMWARE_UPLOAD_START;
|
flash_region.addr = FIRMWARE_UPLOAD_START;
|
||||||
flash_region.len = 0x100;
|
flash_region.len = 0x100;
|
||||||
@@ -1881,7 +1884,7 @@ void check_and_flash_update_image(void)
|
|||||||
__xdata uint16_t i = 0;
|
__xdata uint16_t i = 0;
|
||||||
__xdata uint16_t j = 0;
|
__xdata uint16_t j = 0;
|
||||||
__xdata uint8_t * __xdata bptr;
|
__xdata uint8_t * __xdata bptr;
|
||||||
print_string("Identified update image. Checking integrity...");
|
print_string("Identified update image. Checking integrity");
|
||||||
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail
|
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail
|
||||||
set_sys_led_state(SYS_LED_FAST);
|
set_sys_led_state(SYS_LED_FAST);
|
||||||
crc_value = 0x0000;
|
crc_value = 0x0000;
|
||||||
@@ -1894,25 +1897,20 @@ void check_and_flash_update_image(void)
|
|||||||
crc16(bptr++);
|
crc16(bptr++);
|
||||||
}
|
}
|
||||||
source += FLASH_BUF_SIZE;
|
source += FLASH_BUF_SIZE;
|
||||||
if (i%16 == 0)
|
if (i%16 == 0) write_char('.');
|
||||||
write_char('.');
|
|
||||||
}
|
}
|
||||||
if (crc_value == 0xb001) {
|
if (crc_value == 0xb001) {
|
||||||
print_string("\nChecksum OK\n");
|
print_string("Checksum OK.\nUpdate in progress, moving firmware to start of flash");
|
||||||
print_string("Update in progress, moving firmware to start of FLASH.");
|
|
||||||
source = FIRMWARE_UPLOAD_START;
|
source = FIRMWARE_UPLOAD_START;
|
||||||
// A 512kByte = 4MBit Flash has 128*8=1024 512byte blocks, we copy only 896
|
// Don't copy the config area at the end of flash
|
||||||
// (don't overwrite config @ 0x70000)
|
for (i = 0; i < CONFIG_START/FLASH_BUF_SIZE; i++) {
|
||||||
for (i = 0; i < 896; i++) {
|
|
||||||
// print_string("Writing block: ");
|
|
||||||
// print_short(dest);
|
|
||||||
flash_region.addr = source;
|
flash_region.addr = source;
|
||||||
flash_region.len = FLASH_BUF_SIZE;
|
flash_region.len = FLASH_BUF_SIZE;
|
||||||
flash_read_bulk(flash_buf);
|
flash_read_bulk(flash_buf);
|
||||||
if (!(i & 0x7)) {
|
if (i%8 == 0) {
|
||||||
flash_region.addr = dest;
|
flash_region.addr = dest;
|
||||||
flash_sector_erase();
|
flash_sector_erase();
|
||||||
write_char('.');
|
if (i%16 == 0) write_char('.');
|
||||||
}
|
}
|
||||||
flash_region.addr = dest;
|
flash_region.addr = dest;
|
||||||
flash_region.len = FLASH_BUF_SIZE;
|
flash_region.len = FLASH_BUF_SIZE;
|
||||||
@@ -1920,15 +1918,16 @@ void check_and_flash_update_image(void)
|
|||||||
dest += FLASH_BUF_SIZE;
|
dest += FLASH_BUF_SIZE;
|
||||||
source += FLASH_BUF_SIZE;
|
source += FLASH_BUF_SIZE;
|
||||||
}
|
}
|
||||||
print_string("\nDeleting uploaded flash image\n");
|
print_string("Done.\nDeleting uploaded flash image");
|
||||||
dest = FIRMWARE_UPLOAD_START;
|
dest = FIRMWARE_UPLOAD_START;
|
||||||
for (register uint8_t i=0; i < 128; i++) // TODO: Erasing the entire 512kByte upload area is probably not necessary
|
for (register uint8_t i=0; i < 128; i++) // TODO: Erasing the entire 512kByte upload area is probably not necessary
|
||||||
{
|
{
|
||||||
flash_region.addr = dest;
|
flash_region.addr = dest;
|
||||||
flash_sector_erase();
|
flash_sector_erase();
|
||||||
dest += 0x1000;
|
dest += 0x1000;
|
||||||
|
if (i%4 == 0) write_char('.');
|
||||||
}
|
}
|
||||||
print_string("Resetting now");
|
print_string("Done.\nResetting now");
|
||||||
delay(200);
|
delay(200);
|
||||||
reset_chip();
|
reset_chip();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user