X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fkernel%2Fao_storage.c;h=ca5fcb464d9129508098394870b2568bdb724be9;hb=b08a793fb6e6167d635bfbd31605a43db1f5ac5d;hp=132431e2b34f84f91024e414fe24b71e6f92631d;hpb=c11427819ca24bb77523496309b5b6f699d126c5;p=fw%2Faltos diff --git a/src/kernel/ao_storage.c b/src/kernel/ao_storage.c index 132431e2..ca5fcb46 100644 --- a/src/kernel/ao_storage.c +++ b/src/kernel/ao_storage.c @@ -19,12 +19,14 @@ #include #include +#define AO_STORAGE_DATA_SIZE 128 + +static uint8_t storage_data[AO_STORAGE_DATA_SIZE]; + uint8_t -ao_storage_read(ao_pos_t pos, void *buf, uint16_t len) +ao_storage_read(ao_pos_t pos, void *v_buf, uint16_t len) { -#ifdef CC1111 - return ao_storage_device_read(pos, buf, len); -#else + uint8_t *buf = v_buf; uint16_t this_len; uint16_t this_off; @@ -50,15 +52,12 @@ ao_storage_read(ao_pos_t pos, void *buf, uint16_t len) pos += this_len; } return 1; -#endif } uint8_t -ao_storage_write(ao_pos_t pos, void *buf, uint16_t len) +ao_storage_write(ao_pos_t pos, void *v_buf, uint16_t len) { -#ifdef CC1111 - return ao_storage_device_write(pos, buf, len); -#else + uint8_t *buf = v_buf; uint16_t this_len; uint16_t this_off; @@ -84,10 +83,62 @@ ao_storage_write(ao_pos_t pos, void *buf, uint16_t len) pos += this_len; } return 1; -#endif } -static uint8_t storage_data[128]; +uint8_t +ao_storage_is_erased(uint32_t pos) +{ + uint32_t read_pos; + uint32_t read_len; + uint32_t i; + + read_pos = pos; + read_len = ao_storage_block; + while (read_len) { + uint32_t this_time = AO_STORAGE_DATA_SIZE; + if (this_time > read_len) + this_time = read_len; + if (!ao_storage_read(read_pos, storage_data, this_time)) + return 0; + for (i = 0; i < this_time; i++) + if (storage_data[i] != 0xff) + return 0; + read_pos += this_time; + read_len -= this_time; + } + return 1; +} + +uint8_t +ao_storage_erase(uint32_t start_pos, uint32_t len) +{ + /* Round 'len' up to ao_storage_block units */ + len = ((len + ao_storage_block - 1) / ao_storage_block) * ao_storage_block; + + /* + * Start at the end of the area to erase so that the + * last block cleared is the first block; this will ensure + * that partially erased flight logs still appear in the list + * and can be re-erased. + */ + uint32_t pos = start_pos + len - ao_storage_block; + while (len) { + int tries; + +#define MAX_TRIES 4 /* needs to be at least 2 */ + for (tries = 0; tries < MAX_TRIES; tries++) { + if (ao_storage_is_erased(pos)) + break; + if (!ao_storage_device_erase(pos)) + return 0; + } + if (tries == MAX_TRIES) + return 0; + pos -= ao_storage_block; + len -= ao_storage_block; + } + return 1; +} static void ao_storage_dump(void) @@ -149,23 +200,23 @@ ao_storage_zap(void) uint32_t v = ao_cmd_hex(); if (ao_cmd_status != ao_cmd_success) return; - ao_storage_erase((uint32_t) v << 8); + ao_storage_erase((uint32_t) v << 8, ao_storage_block); } static void ao_storage_zapall(void) { - uint32_t pos; - ao_cmd_white(); if (!ao_match_word("DoIt")) return; - for (pos = 0; pos < ao_storage_log_max; pos += ao_storage_block) - ao_storage_erase(pos); + ao_storage_erase(0, ao_storage_log_max); } #if AO_STORAGE_TEST +#define AO_STORAGE_TEST_SIZE 256 +static uint8_t storage_test[AO_STORAGE_TEST_SIZE]; + static void ao_storage_failure(uint32_t pos, char *format, ...) { @@ -182,16 +233,16 @@ ao_storage_check_block(uint32_t pos, uint8_t value) uint32_t offset; uint32_t byte; - for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) { - if (!ao_storage_read(pos + offset, storage_data, sizeof (storage_data))) { + for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) { + if (!ao_storage_read(pos + offset, storage_test, sizeof (storage_test))) { ao_storage_failure(pos + offset, "read failed\n"); return 0; } - for (byte = 0; byte < sizeof (storage_data); byte++) - if (storage_data[byte] != value) { + for (byte = 0; byte < sizeof (storage_test); byte++) + if (storage_test[byte] != value) { ao_storage_failure(pos + offset + byte, "want %02x got %02x\n", - value, storage_data[byte]); + value, storage_test[byte]); return 0; } } @@ -204,10 +255,10 @@ ao_storage_fill_block(uint32_t pos, uint8_t value) uint32_t offset; uint32_t byte; - for (byte = 0; byte < sizeof (storage_data); byte++) - storage_data[byte] = value; - for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) { - if (!ao_storage_write(pos + offset, storage_data, sizeof (storage_data))) { + for (byte = 0; byte < sizeof (storage_test); byte++) + storage_test[byte] = value; + for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) { + if (!ao_storage_write(pos + offset, storage_test, sizeof (storage_test))) { ao_storage_failure(pos + offset, "write failed\n"); return 0; } @@ -221,17 +272,17 @@ ao_storage_check_incr_block(uint32_t pos) uint32_t offset; uint32_t byte; - for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) { - if (!ao_storage_read(pos + offset, storage_data, sizeof (storage_data))) { + for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) { + if (!ao_storage_read(pos + offset, storage_test, sizeof (storage_test))) { ao_storage_failure(pos + offset, "read failed\n"); return 0; } - for (byte = 0; byte < sizeof (storage_data); byte++) { + for (byte = 0; byte < sizeof (storage_test); byte++) { uint8_t value = offset + byte; - if (storage_data[byte] != value) { + if (storage_test[byte] != value) { ao_storage_failure(pos + offset + byte, "want %02x got %02x\n", - value, storage_data[byte]); + value, storage_test[byte]); return 0; } } @@ -245,10 +296,10 @@ ao_storage_fill_incr_block(uint32_t pos) uint32_t offset; uint32_t byte; - for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) { - for (byte = 0; byte < sizeof (storage_data); byte++) - storage_data[byte] = offset + byte; - if (!ao_storage_write(pos + offset, storage_data, sizeof (storage_data))) { + for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_test)) { + for (byte = 0; byte < sizeof (storage_test); byte++) + storage_test[byte] = offset + byte; + if (!ao_storage_write(pos + offset, storage_test, sizeof (storage_test))) { ao_storage_failure(pos + offset, "write failed\n"); return 0; } @@ -271,26 +322,26 @@ ao_storage_incr_check_block(uint32_t pos) static uint8_t ao_storage_test_block(uint32_t pos) { - ao_storage_erase(pos); + ao_storage_erase(pos, ao_storage_block); printf(" erase"); flush(); if (!ao_storage_check_block(pos, 0xff)) return 0; printf(" zero"); flush(); if (!ao_storage_fill_check_block(pos, 0x00)) return 0; - ao_storage_erase(pos); + ao_storage_erase(pos, ao_storage_block); printf(" 0xaa"); flush(); if (!ao_storage_fill_check_block(pos, 0xaa)) return 0; - ao_storage_erase(pos); + ao_storage_erase(pos, ao_storage_block); printf(" 0x55"); flush(); if (!ao_storage_fill_check_block(pos, 0x55)) return 0; - ao_storage_erase(pos); + ao_storage_erase(pos, ao_storage_block); printf(" increment"); flush(); if (!ao_storage_incr_check_block(pos)) return 0; - ao_storage_erase(pos); + ao_storage_erase(pos, ao_storage_block); printf(" pass\n"); flush(); return 1; } @@ -310,6 +361,27 @@ ao_storage_test(void) } printf("Test complete\n"); } + +static void +ao_storage_fill(void) +{ + uint32_t pos; + + ao_cmd_white(); + if (!ao_match_word("DoIt")) + return; + printf("erase "); flush(); + ao_storage_erase(0, ao_storage_log_max); + for (pos = 0; pos < sizeof (storage_test); pos++) + storage_test[pos] = (uint8_t) pos; + for (pos = 0; pos < ao_storage_log_max; pos += sizeof (storage_test)) { + if ((pos & 0xffff) == 0) { + printf("Fill 0x%x\n", pos); flush(); + } + ao_storage_write(pos, storage_test, sizeof (storage_test)); + } + printf("Fill complete\n"); +} #endif /* AO_STORAGE_TEST */ static void @@ -331,6 +403,7 @@ const struct ao_cmds ao_storage_cmds[] = { { ao_storage_zapall,"Z \0Erase all. is doit with D&I" }, #if AO_STORAGE_TEST { ao_storage_test, "V \0Validate flash (destructive). is doit with D&I" }, + { ao_storage_fill, "F \0Fill flash with data. is doit with D&I" }, #endif { 0, NULL }, };