ao-tools: move 16/32-bit readers from ao-stmload to lib
[fw/altos] / ao-tools / ao-stmload / ao-stmload.c
index dd25f07f8e0cb6f2d355a15a72c1e09931a1c92e..7f521bbc58f02c83e52cd0213d9efe727fb797ce 100644 (file)
 #include <unistd.h>
 #include <getopt.h>
 #include <string.h>
+#include <stdbool.h>
 #include "stlink-common.h"
 #include "ao-elf.h"
 #include "ccdbg.h"
 #include "cc-usb.h"
 #include "cc.h"
 #include "ao-stmload.h"
+#include "ao-selfload.h"
+#include "ao-verbose.h"
 
 #define AO_USB_DESC_STRING             3
 
-struct sym ao_symbols[] = {
+struct ao_sym ao_symbols[] = {
 
        { 0, AO_BOOT_APPLICATION_BASE + 0x100,  "ao_romconfig_version", 1 },
 #define AO_ROMCONFIG_VERSION   (ao_symbols[0].addr)
@@ -53,16 +56,14 @@ struct sym ao_symbols[] = {
 };
 
 #define NUM_SYMBOLS            5
-#define NUM_REQUIRED_SYMBOLS   3
 
 int ao_num_symbols = NUM_SYMBOLS;
-int ao_num_required_symbols = NUM_REQUIRED_SYMBOLS;
 
 /*
  * Edit the to-be-written memory block
  */
 static int
-rewrite(struct hex_image *load, unsigned address, uint8_t *data, int length)
+rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length)
 {
        int             i;
 
@@ -79,40 +80,6 @@ rewrite(struct hex_image *load, unsigned address, uint8_t *data, int length)
        memcpy(load->data + address - load->address, data, length);
 }
 
-/*
- * Read a 16-bit value from the USB target
- */
-
-static uint16_t
-get_uint16_cc(struct cc_usb *cc, uint32_t addr)
-{
-       struct hex_image        *hex = ao_self_read(cc, addr, 2);
-       uint16_t                v;
-       uint8_t                 *data;
-
-       if (!hex)
-               return 0;
-       data = hex->data + addr - hex->address;
-       v = data[0] | (data[1] << 8);
-       free(hex);
-       return v;
-}
-
-static uint32_t
-get_uint32_cc(struct cc_usb *cc, uint32_t addr)
-{
-       struct hex_image        *hex = ao_self_read(cc, addr, 4);
-       uint32_t                v;
-       uint8_t                 *data;
-
-       if (!hex)
-               return 0;
-       data = hex->data + addr - hex->address;
-       v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
-       free(hex);
-       return v;
-}
-
 /*
  * Read a 16-bit value from the target device with arbitrary
  * alignment
@@ -145,7 +112,7 @@ get_uint16(stlink_t *sl, struct cc_usb *cc, uint32_t addr)
 {
        uint16_t        result;
        if (cc)
-               result = get_uint16_cc(cc, addr);
+               result = ao_self_get_uint16(cc, addr);
        else
                result = get_uint16_sl(sl, addr);
        printf ("read 0x%08x = 0x%04x\n", addr, result);
@@ -190,7 +157,7 @@ get_uint32(stlink_t *sl, struct cc_usb *cc, uint32_t addr)
        uint32_t        result;
 
        if (cc)
-               result = get_uint32_cc(cc, addr);
+               result = ao_self_get_uint32(cc, addr);
        else
                result = get_uint32_sl(sl, addr);
        printf ("read 0x%08x = 0x%08x\n", addr, result);
@@ -218,19 +185,43 @@ check_flashed(stlink_t *sl, struct cc_usb *cc)
        return 1;
 }
 
+/*
+ * Find the symbols needed to correctly load the program
+ */
+
+static bool
+find_symbols(struct ao_sym *file_symbols, int num_file_symbols,
+            struct ao_sym *symbols, int num_symbols)
+{
+       int     f, s;
+
+       for (f = 0; f < num_file_symbols; f++) {
+               for (s = 0; s < num_symbols; s++) {
+                       if (strcmp(symbols[s].name, file_symbols[f].name) == 0) {
+                               symbols[s].addr = file_symbols[f].addr;
+                               symbols[s].found = true;
+                       }
+               }
+       }
+       for (s = 0; s < num_symbols; s++)
+               if (!symbols[s].found && symbols[s].required)
+                       return false;
+       return true;
+}
+
 static const struct option options[] = {
        { .name = "stlink", .has_arg = 0, .val = 'S' },
        { .name = "tty", .has_arg = 1, .val = 'T' },
        { .name = "device", .has_arg = 1, .val = 'D' },
        { .name = "cal", .has_arg = 1, .val = 'c' },
        { .name = "serial", .has_arg = 1, .val = 's' },
-       { .name = "verbose", .has_arg = 0, .val = 'v' },
+       { .name = "verbose", .has_arg = 1, .val = 'v' },
        { 0, 0, 0, 0},
 };
 
 static void usage(char *program)
 {
-       fprintf(stderr, "usage: %s [--stlink] [--verbose] [--device=<device>] [-tty=<tty>] [--cal=<radio-cal>] [--serial=<serial>] file.{elf,ihx}\n", program);
+       fprintf(stderr, "usage: %s [--stlink] [--verbose=<verbose>] [--device=<device>] [-tty=<tty>] [--cal=<radio-cal>] [--serial=<serial>] file.{elf,ihx}\n", program);
        exit(1);
 }
 
@@ -281,15 +272,17 @@ main (int argc, char **argv)
        int                     c;
        stlink_t                *sl = NULL;
        int                     was_flashed = 0;
-       struct hex_image        *load;
+       struct ao_hex_image     *load;
        int                     tries;
        struct cc_usb           *cc = NULL;
        int                     use_stlink = 0;
        char                    *tty = NULL;
        int                     success;
        int                     verbose = 0;
+       struct ao_sym           *file_symbols;
+       int                     num_file_symbols;
 
-       while ((c = getopt_long(argc, argv, "T:D:c:s:Sv", options, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "T:D:c:s:Sv:", options, NULL)) != -1) {
                switch (c) {
                case 'T':
                        tty = optarg;
@@ -319,7 +312,7 @@ main (int argc, char **argv)
                }
        }
 
-       ao_self_verbose = verbose;
+       ao_verbose = verbose;
 
        if (verbose > 1)
                ccdbg_add_debug(CC_DEBUG_BITBANG);
@@ -329,15 +322,15 @@ main (int argc, char **argv)
                usage(argv[0]);
 
        if (ends_with (filename, ".elf")) {
-               load = ao_load_elf(filename);
+               load = ao_load_elf(filename, &file_symbols, &num_file_symbols);
        } else if (ends_with (filename, ".ihx")) {
-               int     i;
-               load = ccdbg_hex_load(filename);
-               for (i = 0; i < ao_num_symbols; i++)
-                       ao_symbols[i].addr = ao_symbols[i].default_addr;
+               load = ao_hex_load(filename, &file_symbols, &num_file_symbols);
        } else
                usage(argv[0]);
 
+       if (!find_symbols(file_symbols, num_file_symbols, ao_symbols, ao_num_symbols))
+               fprintf(stderr, "Cannot find required symbols\n");
+
        if (use_stlink) {
                /* Connect to the programming dongle
                 */