altos: Stop doing pointer arith on void *
[fw/altos] / src / kernel / ao_storage.c
index bee9293e8d1bb1dc7f2a76a9986433b6a5e81a0c..cfd116f9791bc536ae2e5709ddc066a3d84f3d8e 100644 (file)
@@ -20,8 +20,9 @@
 #include <ao_storage.h>
 
 uint8_t
-ao_storage_read(ao_pos_t pos, __xdata void *buf, uint16_t len) __reentrant
+ao_storage_read(ao_pos_t pos, void *v_buf, uint16_t len) 
 {
+       uint8_t *buf = v_buf;
        uint16_t this_len;
        uint16_t this_off;
 
@@ -50,8 +51,9 @@ ao_storage_read(ao_pos_t pos, __xdata void *buf, uint16_t len) __reentrant
 }
 
 uint8_t
-ao_storage_write(ao_pos_t pos, __xdata void *buf, uint16_t len) __reentrant
+ao_storage_write(ao_pos_t pos, void *v_buf, uint16_t len) 
 {
+       uint8_t *buf = v_buf;
        uint16_t this_len;
        uint16_t this_off;
 
@@ -79,20 +81,21 @@ ao_storage_write(ao_pos_t pos, __xdata void *buf, uint16_t len) __reentrant
        return 1;
 }
 
-static __xdata uint8_t storage_data[8];
+static uint8_t storage_data[128];
 
 static void
-ao_storage_dump(void) __reentrant
+ao_storage_dump(void) 
 {
+       uint32_t block;
        uint8_t i, j;
 
-       ao_cmd_hex();
+       block = ao_cmd_hex();
        if (ao_cmd_status != ao_cmd_success)
                return;
        for (i = 0; ; i += 8) {
-               if (ao_storage_read(((uint32_t) (ao_cmd_lex_i) << 8) + i,
-                                 storage_data,
-                                 8)) {
+               if (ao_storage_read((block << 8) + i,
+                                   storage_data,
+                                   8)) {
                        ao_cmd_put16((uint16_t) i);
                        for (j = 0; j < 8; j++) {
                                putchar(' ');
@@ -110,45 +113,41 @@ ao_storage_dump(void) __reentrant
 /* not enough space for this today
  */
 static void
-ao_storage_store(void) __reentrant
+ao_storage_store(void) 
 {
        uint16_t block;
        uint8_t i;
        uint16_t len;
-       static __xdata uint8_t b;
+       uint8_t b;
        uint32_t addr;
 
-       ao_cmd_hex();
-       block = ao_cmd_lex_i;
-       ao_cmd_hex();
-       i = ao_cmd_lex_i;
+       block = ao_cmd_hex();
+       i = ao_cmd_hex();
        addr = ((uint32_t) block << 8) | i;
-       ao_cmd_hex();
-       len = ao_cmd_lex_i;
+       len = ao_cmd_hex();
        if (ao_cmd_status != ao_cmd_success)
                return;
        while (len--) {
-               ao_cmd_hex();
+               b = ao_cmd_hexbyte();
                if (ao_cmd_status != ao_cmd_success)
                        return;
-               b = ao_cmd_lex_i;
                ao_storage_write(addr, &b, 1);
                addr++;
        }
 }
 #endif
 
-void
-ao_storage_zap(void) __reentrant
+static void
+ao_storage_zap(void) 
 {
-       ao_cmd_hex();
+       uint32_t v = ao_cmd_hex();
        if (ao_cmd_status != ao_cmd_success)
                return;
-       ao_storage_erase((uint32_t) ao_cmd_lex_i << 8);
+       ao_storage_erase((uint32_t) v << 8);
 }
 
-void
-ao_storage_zapall(void) __reentrant
+static void
+ao_storage_zapall(void) 
 {
        uint32_t        pos;
 
@@ -159,8 +158,156 @@ ao_storage_zapall(void) __reentrant
                ao_storage_erase(pos);
 }
 
-void
-ao_storage_info(void) __reentrant
+#if AO_STORAGE_TEST
+
+static void
+ao_storage_failure(uint32_t pos, char *format, ...)
+{
+       va_list a;
+       printf("TEST FAILURE AT %08x: ", pos);
+       va_start(a, format);
+       vprintf(format, a);
+       va_end(a);
+}
+
+static uint8_t
+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))) {
+                       ao_storage_failure(pos + offset, "read failed\n");
+                       return 0;
+               }
+               for (byte = 0; byte < sizeof (storage_data); byte++)
+                       if (storage_data[byte] != value) {
+                               ao_storage_failure(pos + offset + byte,
+                                                  "want %02x got %02x\n",
+                                                  value, storage_data[byte]);
+                               return 0;
+                       }
+       }
+       return 1;
+}
+
+static uint8_t
+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))) {
+                       ao_storage_failure(pos + offset, "write failed\n");
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+static uint8_t
+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))) {
+                       ao_storage_failure(pos + offset, "read failed\n");
+                       return 0;
+               }
+               for (byte = 0; byte < sizeof (storage_data); byte++) {
+                       uint8_t value = offset + byte;
+                       if (storage_data[byte] != value) {
+                               ao_storage_failure(pos + offset + byte,
+                                                  "want %02x got %02x\n",
+                                                  value, storage_data[byte]);
+                               return 0;
+                       }
+               }
+       }
+       return 1;
+}
+
+static uint8_t
+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))) {
+                       ao_storage_failure(pos + offset, "write failed\n");
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+static uint8_t
+ao_storage_fill_check_block(uint32_t pos, uint8_t value)
+{
+       return ao_storage_fill_block(pos, value) && ao_storage_check_block(pos, value);
+}
+
+static uint8_t
+ao_storage_incr_check_block(uint32_t pos)
+{
+       return ao_storage_fill_incr_block(pos) && ao_storage_check_incr_block(pos);
+}
+
+static uint8_t
+ao_storage_test_block(uint32_t pos) 
+{
+       ao_storage_erase(pos);
+       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);
+       printf(" 0xaa"); flush();
+       if (!ao_storage_fill_check_block(pos, 0xaa))
+               return 0;
+       ao_storage_erase(pos);
+       printf(" 0x55"); flush();
+       if (!ao_storage_fill_check_block(pos, 0x55))
+               return 0;
+       ao_storage_erase(pos);
+       printf(" increment"); flush();
+       if (!ao_storage_incr_check_block(pos))
+               return 0;
+       ao_storage_erase(pos);
+       printf(" pass\n"); flush();
+       return 1;
+}
+
+static void
+ao_storage_test(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) {
+               printf("Testing block 0x%08x:", pos); flush();
+               if (!ao_storage_test_block(pos))
+                       break;
+       }
+       printf("Test complete\n");
+}
+#endif /* AO_STORAGE_TEST */
+
+static void
+ao_storage_info(void) 
 {
        ao_storage_setup();
        printf("Storage size: %ld\n", (long) ao_storage_total);
@@ -168,7 +315,7 @@ ao_storage_info(void) __reentrant
        ao_storage_device_info();
 }
 
-__code struct ao_cmds ao_storage_cmds[] = {
+const struct ao_cmds ao_storage_cmds[] = {
        { ao_storage_info, "f\0Show storage" },
        { ao_storage_dump, "e <block>\0Dump flash" },
 #if HAS_STORAGE_DEBUG
@@ -176,6 +323,9 @@ __code struct ao_cmds ao_storage_cmds[] = {
 #endif
        { ao_storage_zap, "z <block>\0Erase <block>" },
        { ao_storage_zapall,"Z <key>\0Erase all. <key> is doit with D&I" },
+#if AO_STORAGE_TEST
+       { ao_storage_test, "V <key>\0Validate flash (destructive). <key> is doit with D&I" },
+#endif
        { 0, NULL },
 };