gdb: connect will now fail if flash autoprobe fails
authorØyvind Harboe <oyvind.harboe@zylin.com>
Tue, 4 May 2010 11:26:52 +0000 (13:26 +0200)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Wed, 5 May 2010 13:24:24 +0000 (15:24 +0200)
This stops GDB from launching with an empty memory map,
making gdb load w/flashing fail for no obvious reason.

The error message points in the direction of the gdb-attach
event that can be set up to issue a halt or "reset init"
which will put GDB in a well defined stated upon attach
and thus have a robust flash autoprobe.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
src/flash/nor/core.c
src/flash/nor/core.h
src/flash/nor/tcl.c
src/server/gdb_server.c

index e6c0eeb2ea2eaf8260668529c3325f4cd69eac7d..232d503714fb8ffb38c5dbe28279a9132584c684 100644 (file)
@@ -220,22 +220,25 @@ struct flash_bank *get_flash_bank_by_name(const char *name)
        return NULL;
 }
 
-struct flash_bank *get_flash_bank_by_num(int num)
+int get_flash_bank_by_num(int num, struct flash_bank **bank)
 {
        struct flash_bank *p = get_flash_bank_by_num_noprobe(num);
        int retval;
 
        if (p == NULL)
-               return NULL;
+       {
+               return ERROR_FAIL;
+       }
 
        retval = p->driver->auto_probe(p);
 
        if (retval != ERROR_OK)
        {
                LOG_ERROR("auto_probe failed %d\n", retval);
-               return NULL;
+               return retval;
        }
-       return p;
+       *bank = p;
+       return ERROR_OK;
 }
 
 /* lookup flash bank by address */
index 68220afe21e6f1c53d04a00bcac7c48d06b78c2f..797cf68681aea87890f570a1aeb46f0e67fe02e7 100644 (file)
@@ -157,9 +157,10 @@ struct flash_bank *get_flash_bank_by_name(const char *name);
 /**
  * Returns a flash bank by the specified flash_bank_s bank_number, @a num.
  * @param num The flash bank number.
- * @returns A struct flash_bank for flash bank @a num, or NULL
+ * @param bank returned bank if fn returns ERROR_OK
+ * @returns ERROR_OK if successful
  */
-struct flash_bank *get_flash_bank_by_num(int num);
+int get_flash_bank_by_num(int num, struct flash_bank **bank);
 /**
  * Retreives @a bank from a command argument, reporting errors parsing
  * the bank identifier or retreiving the specified bank.  The bank
index aed55c05afc342c710b2b1eddc4598f4605b9136..66b8ac3402634a6574308da71839bd1d1dbe550c 100644 (file)
@@ -42,13 +42,7 @@ COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
        unsigned bank_num;
        COMMAND_PARSE_NUMBER(uint, name, bank_num);
 
-       *bank = get_flash_bank_by_num(bank_num);
-       if (!*bank)
-       {
-               command_print(CMD_CTX, "flash bank '%s' not found", name);
-               return ERROR_INVALID_ARGUMENTS;
-       }
-       return ERROR_OK;
+       return get_flash_bank_by_num(bank_num, bank);
 }
 
 
@@ -310,9 +304,12 @@ COMMAND_HANDLER(handle_flash_erase_command)
        uint32_t last;
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], bank_nr);
-       struct flash_bank *p = get_flash_bank_by_num(bank_nr);
-       if (!p)
-               return ERROR_OK;
+
+       struct flash_bank *p;
+       int retval;
+       retval = get_flash_bank_by_num(bank_nr, &p);
+       if (retval != ERROR_OK)
+               return retval;
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
        if (strcmp(CMD_ARGV[2], "last") == 0)
@@ -320,7 +317,6 @@ COMMAND_HANDLER(handle_flash_erase_command)
        else
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
 
-       int retval;
        if ((retval = flash_check_sector_parameters(CMD_CTX,
                        first, last, p->num_sectors)) != ERROR_OK)
                return retval;
@@ -350,9 +346,10 @@ COMMAND_HANDLER(handle_flash_protect_command)
        uint32_t last;
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], bank_nr);
-       struct flash_bank *p = get_flash_bank_by_num(bank_nr);
-       if (!p)
-               return ERROR_OK;
+       struct flash_bank *p;
+       int retval = get_flash_bank_by_num(bank_nr, &p);
+       if (retval != ERROR_OK)
+               return retval;
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);
        if (strcmp(CMD_ARGV[2], "last") == 0)
@@ -363,7 +360,6 @@ COMMAND_HANDLER(handle_flash_protect_command)
        bool set;
        COMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);
 
-       int retval;
        if ((retval = flash_check_sector_parameters(CMD_CTX,
                        first, last, p->num_sectors)) != ERROR_OK)
                return retval;
index f46980e14f57c7c08a14fad758cec5dc3ecfb688..275d41468daa40597fb2ea40cd0d3506c9300be0 100644 (file)
@@ -855,6 +855,26 @@ static int gdb_new_connection(struct connection *connection)
                gdb_putback_char(connection, initial_ack);
        target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_ATTACH);
 
+       if (gdb_use_memory_map)
+       {
+               /* Connect must fail if the memory map can't be set up correctly.
+                *
+                * This will cause an auto_probe to be invoked, which is either
+                * a no-op or it will fail when the target isn't ready(e.g. not halted).
+                */
+               int i;
+               for (i = 0; i < flash_get_bank_count(); i++)
+               {
+                       struct flash_bank *p;
+                       retval = get_flash_bank_by_num(i, &p);
+                       if (retval != ERROR_OK)
+                       {
+                               LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect.");
+                               return retval;
+                       }
+               }
+       }
+
        gdb_actual_connections++;
        LOG_DEBUG("New GDB Connection: %d, Target %s, state: %s",
                  gdb_actual_connections,
@@ -1692,10 +1712,10 @@ static int gdb_memory_map(struct connection *connection,
        banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count());
 
        for (i = 0; i < flash_get_bank_count(); i++) {
-               p = get_flash_bank_by_num(i);
-               if (p == NULL) {
+               retval = get_flash_bank_by_num(i, &p);
+               if (retval != ERROR_OK)
+               {
                        free(banks);
-                       retval = ERROR_FAIL;
                        gdb_send_error(connection, retval);
                        return retval;
                }