diff --git a/src/flash.c b/src/flash.c index 89955e9..ee761ba 100644 --- a/src/flash.c +++ b/src/flash.c @@ -5,6 +5,8 @@ #include "flash.h" +#include + #include #include #include @@ -17,7 +19,7 @@ static int percent_complete; static uint32_t bytes_processed; static uint32_t total_bytes; -static void progress(uint32_t nbytes) +static void progress(int32_t nbytes) { bytes_processed += nbytes; @@ -28,13 +30,40 @@ static void progress(uint32_t nbytes) } } +/* slow but no table overhead ;-) */ +uint32_t crc32(const uint8_t *data, uint32_t len) +{ + uint32_t crc = 0xffffffff; + + for (int i=0; i> 1) ^ (0xedb88320 & -(crc & 1)); + } + return ~crc; +} + +static uint32_t check_segment(const struct segment *sg) +{ + uint32_t sz = sg->end - sg->start; + + if (sg->crc32 != crc32(sg->data, sz)) + panic(); + + return sz; +} + static void flash_segment(const struct segment *sg) { uint32_t pagesz = nrfx_nvmc_flash_page_size_get(); + uint32_t sz = sg->end - sg->start; + int retries = 5; + +retry: /* TODO: Haven't got code to handle the UICR yet */ if (sg->start >= 0x1000000) { - progress(sg->end - sg->start); + progress(2 * sz); return; } @@ -50,6 +79,17 @@ static void flash_segment(const struct segment *sg) ((uint32_t *) sg->data)[(addr - sg->start) / 4]); progress(4); } + + if (0 != memcmp((void *) sg->start, sg->data, sz)) { + progress(-(2 * sz)); + if (retries--) + goto retry; + + // We're in big trouble... the system is probably bricked but we + // don't seem to be able to do anything about it. Better to reboot + // and hope than to sit here wearing out the flash! + panic(); + } } void flash_all(void) @@ -61,7 +101,7 @@ void flash_all(void) report_progress(0); for (int i=0; i= (165-percent_complete)) { + if (percent_complete >= 1 && y >= (165-percent_complete)) { fg = 0xffff; } diff --git a/src/util.h b/src/util.h index b5dcc64..52f3639 100644 --- a/src/util.h +++ b/src/util.h @@ -8,6 +8,8 @@ #define lengthof(x) (sizeof(x) / sizeof((x)[0])) +void panic(void); +void reboot(void); void report_progress(int percent); #endif /* RELOADER_UTIL_H__ */