- cleaned up str7, str9 and stm32 flash drivers
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 8 Oct 2007 13:12:39 +0000 (13:12 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 8 Oct 2007 13:12:39 +0000 (13:12 +0000)
- str7 flash driver now checks correct busy bits depending on device
- str9 flash driver now disables ITCM order as per st programming manual
- added str7 disable_jtag command
- added gdb_detach command
- updated arm966e cp15 support
- fix crash on mingw build when enabling target_request debugmsgs

git-svn-id: svn://svn.berlios.de/openocd/trunk@209 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/flash/flash.c
src/flash/stm32x.c
src/flash/str7x.c
src/flash/str7x.h
src/flash/str9x.c
src/server/gdb_server.c
src/target/arm966e.c
src/target/arm966e.h
src/target/target.c
src/target/target.h

index 9ab34e7b67fc933f5dead9882a7eeabebe593427..7dc7f1bb837676e7aa01ebbe63ae524807cf345f 100644 (file)
@@ -574,6 +574,7 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm
        {
                command_print(cmd_ctx, "failed writing image %s: %s", args[0], error_str);
                free(error_str);
+               free(failed);
        }
        
        for (i = 0; i < image.num_sections; i++)
@@ -589,7 +590,9 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm
        command_print(cmd_ctx, "wrote %u byte from file %s in %s (%f kb/s)",
                written, args[0], duration_text,
                (float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
+
        free(duration_text);
+       free(failed);
 
        image_close(&image);
        
index 15cbb74cd9a2d6062efef565e03f691e2246764f..885f2cf0dd0796961566dc25dcc75446e96a7bf1 100644 (file)
@@ -291,7 +291,7 @@ int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 co
        u32 buffer_size = 8192;
        working_area_t *source;
        u32 address = bank->base + offset;
-       reg_param_t reg_params[6];
+       reg_param_t reg_params[4];
        armv7m_algorithm_t armv7m_info;
        int retval = ERROR_OK;
        
@@ -318,16 +318,13 @@ int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 co
        };
        
        /* flash write code */
-       if (!stm32x_info->write_algorithm)
+       if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code), &stm32x_info->write_algorithm) != ERROR_OK)
        {
-               if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code), &stm32x_info->write_algorithm) != ERROR_OK)
-               {
-                       WARNING("no working area available, can't do block memory writes");
-                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-               };
-               
-               target_write_buffer(target, stm32x_info->write_algorithm->address, sizeof(stm32x_flash_write_code), stm32x_flash_write_code);
-       }
+               WARNING("no working area available, can't do block memory writes");
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       };
+       
+       target_write_buffer(target, stm32x_info->write_algorithm->address, sizeof(stm32x_flash_write_code), stm32x_flash_write_code);
 
        /* memory buffer */
        while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
@@ -352,8 +349,6 @@ int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 co
        init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
        init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
        init_reg_param(&reg_params[3], "r3", 32, PARAM_IN);
-       init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
-       init_reg_param(&reg_params[5], "r5", 32, PARAM_IN);
        
        while (count > 0)
        {
@@ -365,7 +360,7 @@ int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 co
                buf_set_u32(reg_params[1].value, 0, 32, address);
                buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
                
-               if ((retval = target->type->run_algorithm(target, 0, NULL, 6, reg_params, stm32x_info->write_algorithm->address, \
+               if ((retval = target->type->run_algorithm(target, 0, NULL, 4, reg_params, stm32x_info->write_algorithm->address, \
                                stm32x_info->write_algorithm->address + (sizeof(stm32x_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK)
                {
                        ERROR("error executing str7x flash write algorithm");
@@ -384,13 +379,12 @@ int stm32x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 co
        }
        
        target_free_working_area(target, source);
+       target_free_working_area(target, stm32x_info->write_algorithm);
        
        destroy_reg_param(&reg_params[0]);
        destroy_reg_param(&reg_params[1]);
        destroy_reg_param(&reg_params[2]);
        destroy_reg_param(&reg_params[3]);
-       destroy_reg_param(&reg_params[4]);
-       destroy_reg_param(&reg_params[5]);
        
        return retval;
 }
index 6771506a0436d9f16c3838f9b7264aabe84bfd88..2b3e47fd15c8a8a9e3d71cce7a60d1c5dd849ea5 100644 (file)
@@ -59,6 +59,8 @@ int str7x_protect_check(struct flash_bank_s *bank);
 int str7x_erase_check(struct flash_bank_s *bank);
 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size);
 
+int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
 flash_driver_t str7x_flash =
 {
        .name = "str7x",
@@ -75,7 +77,11 @@ flash_driver_t str7x_flash =
 
 int str7x_register_commands(struct command_context_s *cmd_ctx)
 {
-
+       command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x", NULL, COMMAND_ANY, NULL);
+       
+       register_command(cmd_ctx, str7x_cmd, "disable_jtag", str7x_handle_disable_jtag_command, COMMAND_EXEC,
+                                        "disable jtag access");
+                                        
        return ERROR_OK;
 }
 
@@ -165,9 +171,13 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char
        str7x_info = malloc(sizeof(str7x_flash_bank_t));
        bank->driver_priv = str7x_info;
        
+       /* set default bits for str71x flash */
+       str7x_info->bank1 = 1;
+       str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA1|FLASH_BSYA0);
+       str7x_info->disable_bit = (1<<1);
+       
        if (strcmp(args[6], "STR71x") == 0)
        {
-               str7x_info->bank1 = 1;
                if (bank->base != 0x40000000)
                {
                        WARNING("overriding flash base address for STR71x device with 0x40000000");
@@ -177,6 +187,8 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char
        else if (strcmp(args[6], "STR73x") == 0)
        {
                str7x_info->bank1 = 0;
+               str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA0);
+               
                if (bank->base != 0x80000000)
                {
                        WARNING("overriding flash base address for STR73x device with 0x80000000");
@@ -185,7 +197,8 @@ int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char
        }
        else if (strcmp(args[6], "STR75x") == 0)
        {
-               str7x_info->bank1 = 1;
+               str7x_info->disable_bit = (1<<0);
+               
                if (bank->base != 0x20000000)
                {
                        WARNING("overriding flash base address for STR75x device with 0x20000000");
@@ -331,7 +344,7 @@ int str7x_erase(struct flash_bank_s *bank, int first, int last)
                cmd = FLASH_SER|FLASH_WMS;
                target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
                
-               while (((retval = str7x_status(bank)) & (FLASH_BSYA1|FLASH_BSYA2))){
+               while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
                        usleep(1000);
                }
                
@@ -360,7 +373,7 @@ int str7x_erase(struct flash_bank_s *bank, int first, int last)
                cmd = FLASH_SER|FLASH_WMS;
                target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
                
-               while (((retval = str7x_status(bank)) & (FLASH_BSYA1|FLASH_BSYA2))){
+               while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
                        usleep(1000);
                }
                
@@ -416,7 +429,7 @@ int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
        cmd = FLASH_SPR|FLASH_WMS;
        target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
        
-       while (((retval = str7x_status(bank)) & (FLASH_BSYA1|FLASH_BSYA2))){
+       while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
                usleep(1000);
        }
        
@@ -439,7 +452,7 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
        u32 buffer_size = 8192;
        working_area_t *source;
        u32 address = bank->base + offset;
-       reg_param_t reg_params[5];
+       reg_param_t reg_params[6];
        armv4_5_algorithm_t armv4_5_info;
        int retval = ERROR_OK;
        
@@ -456,7 +469,7 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
                0xe5824000, /*  str r4, [r2, #0x0]      */
                            /* busy:                            */
                0xe5924000, /*  ldr r4, [r2, #0x0]      */
-               0xe3140016, /*  tst r4, #0x16           */
+               0xe1140005,     /*      tst r4, r5                      */
                0x1afffffc, /*  bne busy                        */
                0xe5924014, /*  ldr r4, [r2, #0x14]     */
                0xe31400ff, /*  tst r4, #0xff           */
@@ -469,24 +482,14 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
                0xeafffffe, /*  b exit                          */
        };
        
-       u8 str7x_flash_write_code_buf[80];
-       int i;
-       
        /* flash write code */
-       if (!str7x_info->write_algorithm)
+       if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
        {
-               if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
-               {
-                       WARNING("no working area available, can't do block memory writes");
-                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-               };
-
-               /* convert flash writing code into a buffer in target endianness */
-               for (i = 0; i < 20; i++)
-                       target_buffer_set_u32(target, str7x_flash_write_code_buf + i*4, str7x_flash_write_code[i]);
-                       
-               target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, str7x_flash_write_code_buf);
-       }
+               WARNING("no working area available, can't do block memory writes");
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       };
+       
+       target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (u8*)str7x_flash_write_code);
 
        /* memory buffer */
        while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
@@ -501,7 +504,7 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
                        WARNING("no large enough working area available, can't do block memory writes");
                        return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
-       };
+       }
        
        armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
        armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
@@ -512,6 +515,7 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
        init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
        init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
        init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
+       init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
        
        while (count > 0)
        {
@@ -523,8 +527,9 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
                buf_set_u32(reg_params[1].value, 0, 32, address);
                buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
                buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
+               buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
        
-               if ((retval = target->type->run_algorithm(target, 0, NULL, 5, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
+               if ((retval = target->type->run_algorithm(target, 0, NULL, 6, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
                {
                        ERROR("error executing str7x flash write algorithm");
                        break;
@@ -542,12 +547,14 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
        }
        
        target_free_working_area(target, source);
+       target_free_working_area(target, str7x_info->write_algorithm);
        
        destroy_reg_param(&reg_params[0]);
        destroy_reg_param(&reg_params[1]);
        destroy_reg_param(&reg_params[2]);
        destroy_reg_param(&reg_params[3]);
        destroy_reg_param(&reg_params[4]);
+       destroy_reg_param(&reg_params[5]);
        
        return retval;
 }
@@ -555,6 +562,7 @@ int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
 {
        target_t *target = bank->target;
+       str7x_flash_bank_t *str7x_info = bank->driver_priv;
        u32 dwords_remaining = (count / 8);
        u32 bytes_remaining = (count & 0x00000007);
        u32 address = bank->base + offset;
@@ -647,7 +655,7 @@ int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
                cmd = FLASH_DWPG | FLASH_WMS;
                target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
                
-               while (((retval = str7x_status(bank)) & (FLASH_BSYA1 | FLASH_BSYA2)))
+               while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
                {
                        usleep(1000);
                }
@@ -694,7 +702,7 @@ int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
                cmd = FLASH_DWPG | FLASH_WMS;
                target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
                
-               while (((retval = str7x_status(bank)) & (FLASH_BSYA1 | FLASH_BSYA2)))
+               while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
                {
                        usleep(1000);
                }
@@ -730,3 +738,76 @@ int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
        snprintf(buf, buf_size, "str7x flash driver info" );
        return ERROR_OK;
 }
+
+int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       flash_bank_t *bank;
+       target_t *target = NULL;
+       str7x_flash_bank_t *str7x_info = NULL;
+       
+       u32 flash_cmd;
+       u32 retval;
+       u16 ProtectionLevel = 0;
+       u16 ProtectionRegs;
+       
+       if (argc < 1)
+       {
+               command_print(cmd_ctx, "str7x disable_jtag <bank>");
+               return ERROR_OK;        
+       }
+       
+       bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+       if (!bank)
+       {
+               command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
+               return ERROR_OK;
+       }
+       
+       str7x_info = bank->driver_priv;
+       
+       target = bank->target;
+       
+       if (target->state != TARGET_HALTED)
+       {
+               return ERROR_TARGET_NOT_HALTED;
+       }
+       
+       /* first we get protection status */
+       target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
+
+       if (!(retval & str7x_info->disable_bit))
+       {
+               ProtectionLevel = 1;
+       }
+       
+       target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
+       ProtectionRegs = ~(retval >> 16);
+
+       while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
+       {
+               ProtectionRegs >>= 1;
+               ProtectionLevel++;
+       }
+       
+       if (ProtectionLevel == 0)
+       {
+               flash_cmd = FLASH_SPR;
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
+               flash_cmd = FLASH_SPR | FLASH_WMS;
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
+       }
+       else
+       {
+               flash_cmd = FLASH_SPR;
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1<<(15+ProtectionLevel)));
+               flash_cmd = FLASH_SPR | FLASH_WMS;
+               target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
+       }
+       
+       return ERROR_OK;
+}
+
index a823bb80f50b47471e6e4e1fb73d49249c90958c..bbb64eb9f39fb8654be84043f21f4b618211516e 100644 (file)
@@ -28,6 +28,8 @@ typedef struct str7x_flash_bank_s
        int bank1;
        u32 *sector_bank;
        u32 *sector_bits;
+       u32 disable_bit;
+       u32 busy_bits;
        working_area_t *write_algorithm;
 } str7x_flash_bank_t;
 
@@ -69,8 +71,9 @@ enum str7x_status_codes
 #define FLASH_SPR              0x01000000
 #define FLASH_BER              0x04000000
 #define FLASH_MER              0x02000000
-#define FLASH_BSYA1            0x00000002
-#define FLASH_BSYA2            0x00000004
+#define FLASH_LOCK             0x00000010
+#define FLASH_BSYA1            0x00000004
+#define FLASH_BSYA0            0x00000002
 
 /* FLASH_CR1 regsiter bits */
 
index 66b27036d35456ba734b0ad2e4b79ed980b65948..fcbca89bbbf156c259c16c46f5dcef5a8570fde6 100644 (file)
@@ -28,6 +28,7 @@
 #include "target.h"
 #include "log.h"
 #include "armv4_5.h"
+#include "arm966e.h"
 #include "algorithm.h"
 #include "binarybuffer.h"
 
@@ -351,24 +352,14 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
                0xeafffffe,     /*      b exit                          */
        };
        
-       u8 str9x_flash_write_code_buf[76];
-       int i;
-       
        /* flash write code */
-       if (!str9x_info->write_algorithm)
+       if (target_alloc_working_area(target, 4 * 19, &str9x_info->write_algorithm) != ERROR_OK)
        {
-               if (target_alloc_working_area(target, 4 * 19, &str9x_info->write_algorithm) != ERROR_OK)
-               {
-                       WARNING("no working area available, can't do block memory writes");
-                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-               };
-
-               /* convert flash writing code into a buffer in target endianness */
-               for (i = 0; i < 19; i++)
-                       target_buffer_set_u32(target, str9x_flash_write_code_buf + i*4, str9x_flash_write_code[i]);
-                       
-               target_write_buffer(target, str9x_info->write_algorithm->address, 19 * 4, str9x_flash_write_code_buf);
-       }
+               WARNING("no working area available, can't do block memory writes");
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       };
+               
+       target_write_buffer(target, str9x_info->write_algorithm->address, 19 * 4, (u8*)str9x_flash_write_code);
 
        /* memory buffer */
        while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
@@ -383,7 +374,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
                        WARNING("no large enough working area available, can't do block memory writes");
                        return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
-       };
+       }
        
        armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
        armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
@@ -406,6 +397,8 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
 
                if ((retval = target->type->run_algorithm(target, 0, NULL, 4, reg_params, str9x_info->write_algorithm->address, str9x_info->write_algorithm->address + (18 * 4), 10000, &armv4_5_info)) != ERROR_OK)
                {
+                       target_free_working_area(target, source);
+                       target_free_working_area(target, str9x_info->write_algorithm);
                        ERROR("error executing str9x flash write algorithm");
                        return ERROR_FLASH_OPERATION_FAILED;
                }
@@ -420,6 +413,9 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou
                count -= thisrun_count;
        }
        
+       target_free_working_area(target, source);
+       target_free_working_area(target, str9x_info->write_algorithm);
+       
        destroy_reg_param(&reg_params[0]);
        destroy_reg_param(&reg_params[1]);
        destroy_reg_param(&reg_params[2]);
@@ -615,10 +611,13 @@ int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, char *c
        /* config flash controller */
        target_write_u32(target, FLASH_BBSR, strtoul(args[0], NULL, 0));
        target_write_u32(target, FLASH_NBBSR, strtoul(args[1], NULL, 0));
-    target_write_u32(target, FLASH_BBADR, (strtoul(args[2], NULL, 0) >> 2));
-    target_write_u32(target, FLASH_NBBADR, (strtoul(args[3], NULL, 0) >> 2));
+       target_write_u32(target, FLASH_BBADR, (strtoul(args[2], NULL, 0) >> 2));
+       target_write_u32(target, FLASH_NBBADR, (strtoul(args[3], NULL, 0) >> 2));
 
+       /* set b18 instruction TCM order as per flash programming manual */
+       arm966e_write_cp15(target, 62, 0x40000);
+       
        /* enable flash bank 1 */
-    target_write_u32(target, FLASH_CR, 0x18);
+       target_write_u32(target, FLASH_CR, 0x18);
        return ERROR_OK;
 }
index f579de1c4c92a1af999efe7223521f6d09010e01..74928c876853d56351ccb815161f9567778488e9 100644 (file)
 
 static unsigned short gdb_port;
 
+enum gdb_detach_mode
+{
+       GDB_DETACH_RESUME,
+       GDB_DETACH_RESET,
+       GDB_DETACH_HALT,
+       GDB_DETACH_NOTHING
+};
+
+enum gdb_detach_mode detach_mode = GDB_DETACH_RESUME;
+
 int gdb_last_signal(target_t *target)
 {
        switch (target->debug_reason)
@@ -172,7 +182,6 @@ int gdb_put_packet(connection_t *connection, char *buffer, int len)
 
        while (1)
        {
-
                debug_buffer = malloc(len + 1);
                memcpy(debug_buffer, buffer, len);
                debug_buffer[len] = 0;
@@ -1304,6 +1313,31 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
        return ERROR_OK;
 }
 
+int gdb_detach(connection_t *connection, target_t *target)
+{
+       switch( detach_mode )
+       {
+               case GDB_DETACH_RESUME:
+                       target->type->resume(target, 1, 0, 1, 0);
+                       break;
+               
+               case GDB_DETACH_RESET:
+                       target_process_reset(connection->cmd_ctx);
+                       break;
+               
+               case GDB_DETACH_HALT:
+                       target->type->halt(target);
+                       break;
+               
+               case GDB_DETACH_NOTHING:
+                       break;
+       }
+       
+       gdb_put_packet(connection, "OK", 2);
+       
+       return ERROR_OK;
+}
+
 int gdb_input(connection_t *connection)
 {
        gdb_service_t *gdb_service = connection->service->priv;
@@ -1383,8 +1417,7 @@ int gdb_input(connection_t *connection)
                                        retval = gdb_v_packet(connection, target, packet, packet_size);
                                        break;
                                case 'D':
-                                       target->type->resume(target, 1, 0, 1, 0);
-                                       gdb_put_packet(connection, "OK", 2);
+                                       retval = gdb_detach(connection, target);
                                        break;
                                case 'X':
                                        if ((retval = gdb_write_memory_binary_packet(connection, target, packet, packet_size)) != ERROR_OK)
@@ -1470,10 +1503,42 @@ int handle_gdb_port_command(struct command_context_s *cmd_ctx, char *cmd, char *
        return ERROR_OK;
 }
 
+int handle_gdb_detach_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc == 1)
+       {
+               if (strcmp(args[0], "resume") == 0)
+               {
+                       detach_mode = GDB_DETACH_RESUME;
+                       return ERROR_OK;
+               }
+               else if (strcmp(args[0], "reset") == 0)
+               {
+                       detach_mode = GDB_DETACH_RESET;
+                       return ERROR_OK;
+               }
+               else if (strcmp(args[0], "halt") == 0)
+               {
+                       detach_mode = GDB_DETACH_HALT;
+                       return ERROR_OK;
+               }
+               else if (strcmp(args[0], "nothing") == 0)
+               {
+                       detach_mode = GDB_DETACH_NOTHING;
+                       return ERROR_OK;
+               }
+       }
+       
+       WARNING("invalid gdb_detach configuration directive: %s", args[0]);
+       return ERROR_OK;
+}
+
 int gdb_register_commands(command_context_t *command_context)
 {
        register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
                        COMMAND_CONFIG, "");
-
+       register_command(command_context, NULL, "gdb_detach", handle_gdb_detach_command,
+                       COMMAND_CONFIG, "");
+       
        return ERROR_OK;
 }
index 80ccd61404651d192246ee9d91e5f8b7db74a5a2..53627a5f5c4733b183fb45373b723ce8f849582d 100644 (file)
@@ -226,10 +226,16 @@ int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
        
        jtag_add_dr_scan(3, fields, -1, NULL);
 
-       fields[0].in_value = (u8*)value;
+       fields[0].in_handler_priv = value;
+       fields[0].in_handler = arm_jtag_buf_to_u32;
 
        jtag_add_dr_scan(3, fields, -1, NULL);
 
+#ifdef _DEBUG_INSTRUCTION_EXECUTION_
+       jtag_execute_queue();
+       DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
+#endif
+
        return ERROR_OK;
 }
 
@@ -241,6 +247,9 @@ int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
        scan_field_t fields[3];
        u8 reg_addr_buf = reg_addr & 0x3f;
        u8 nr_w_buf = 1;
+       u8 value_buf[4];
+       
+       buf_set_u32(value_buf, 0, 32, value);
        
        jtag_add_end_state(TAP_RTI);
        arm_jtag_scann(jtag_info, 0xf);
@@ -248,7 +257,7 @@ int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
 
        fields[0].device = jtag_info->chain_pos;
        fields[0].num_bits = 32;
-       fields[0].out_value = (u8*)&value;
+       fields[0].out_value = value_buf;
        fields[0].out_mask = NULL;
        fields[0].in_value = NULL;
        fields[0].in_check_value = NULL;
@@ -278,6 +287,10 @@ int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
        
        jtag_add_dr_scan(3, fields, -1, NULL);
 
+#ifdef _DEBUG_INSTRUCTION_EXECUTION_
+       DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
+#endif
+
        return ERROR_OK;
 }
 
index d4624f6c66e8750f87d75291fee64884a5b18416..7169820bae2d93e08ff266e459e317c096127672 100644 (file)
@@ -35,4 +35,7 @@ typedef struct arm966e_common_s
        u32 cp15_control_reg;
 } arm966e_common_t;
 
+extern int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value);
+extern int arm966e_write_cp15(target_t *target, int reg_addr, u32 value);
+
 #endif /* ARM966E_H */
index 71ad1e425b7b70a62be40c6ace37f6d852924d11..f471167b3197675d332b3322e7758a78c8f73370 100644 (file)
@@ -1013,7 +1013,9 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                                (*last_target_p)->trace_info->trace_history = NULL;
                                (*last_target_p)->trace_info->trace_history_pos = 0;
                                (*last_target_p)->trace_info->trace_history_overflowed = 0;
-                                                               
+                               
+                               (*last_target_p)->dbgmsg = NULL;
+                               
                                (*last_target_p)->type->target_command(cmd_ctx, cmd, args, argc, *last_target_p);
                                
                                found = 1;
index f6c09c09a3f81b02cbdcbb772bb6b0615f7ca44c..ae5fbc431044227f2c9cb5dd35808ebdc2f18fbf 100644 (file)
@@ -201,6 +201,7 @@ extern int target_register_commands(struct command_context_s *cmd_ctx);
 extern int target_register_user_commands(struct command_context_s *cmd_ctx);
 extern int target_init(struct command_context_s *cmd_ctx);
 extern int handle_target(void *priv);
+extern int target_process_reset(struct command_context_s *cmd_ctx);
 
 extern int target_register_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv);
 extern int target_unregister_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv);

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)