armv8: allow halt on exception 79/4479/10
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>
Thu, 5 Apr 2018 11:42:21 +0000 (13:42 +0200)
committerMatthias Welwarsky <matthias@welwarsky.de>
Mon, 4 Mar 2019 11:53:00 +0000 (11:53 +0000)
add command 'catch_exc' to halt a core on entering any of Secure EL1 or
EL3 or Non-Secure EL1 or EL2.

Change-Id: I0c68e247af68dd96616855a9bc1063c277d222e5
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
Reviewed-on: http://openocd.zylin.com/4479
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
doc/openocd.texi
src/server/gdb_server.c
src/target/armv8.c
src/target/armv8.h
src/target/armv8_dpm.c
src/target/target.c
src/target/target.h

index 8b03b80b68fb56f83977243e1df81ab2a6139433..2e04182b3c7eae7eb034e40da9da43e40f7a8a18 100644 (file)
@@ -9345,6 +9345,14 @@ be copied to an in-memory buffer identified by the @option{address} and
 @option{size} options using DMA.
 @end deffn
 
 @option{size} options using DMA.
 @end deffn
 
+@deffn Command {$target_name catch_exc} [@option{off}|@option{sec_el1}|@option{sec_el3}|@option{nsec_el1}|@option{nsec_el2}]+
+Cause @command{$target_name} to halt when an exception is taken. Any combination of
+Secure (sec) EL1/EL3 or Non-Secure (nsec) EL1/EL2 is valid. The target
+@command{$target_name} will halt before taking the exception. In order to resume
+the target, the exception catch must be disabled again with @command{$target_name catch_exc off}.
+Issuing the command without options prints the current configuration.
+@end deffn
+
 @section Intel Architecture
 
 Intel Quark X10xx is the first product in the Quark family of SoCs. It is an IA-32
 @section Intel Architecture
 
 Intel Quark X10xx is the first product in the Quark family of SoCs. It is an IA-32
index 13e5aca6a482b1b36060a187ecf933da832346a8..ef2ead44f3837be943c9928dbc6434743f851c04 100644 (file)
@@ -153,6 +153,8 @@ static int gdb_last_signal(struct target *target)
                        return 0x05;    /* SIGTRAP */
                case DBG_REASON_SINGLESTEP:
                        return 0x05;    /* SIGTRAP */
                        return 0x05;    /* SIGTRAP */
                case DBG_REASON_SINGLESTEP:
                        return 0x05;    /* SIGTRAP */
+               case DBG_REASON_EXC_CATCH:
+                       return 0x05;
                case DBG_REASON_NOTHALTED:
                        return 0x0;             /* no signal... shouldn't happen */
                default:
                case DBG_REASON_NOTHALTED:
                        return 0x0;             /* no signal... shouldn't happen */
                default:
index cee837f584b25d4d64a31786b0e96b01eef0d86f..76a2d98af8c9639765beb9017da5a2ada110bddf 100644 (file)
@@ -1013,6 +1013,72 @@ int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
        return retval;
 }
 
        return retval;
 }
 
+COMMAND_HANDLER(armv8_handle_exception_catch_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct armv8_common *armv8 = target_to_armv8(target);
+       uint32_t edeccr = 0;
+       unsigned int argp = 0;
+       int retval;
+
+       static const Jim_Nvp nvp_ecatch_modes[] = {
+               { .name = "off",       .value = 0 },
+               { .name = "nsec_el1",  .value = (1 << 5) },
+               { .name = "nsec_el2",  .value = (2 << 5) },
+               { .name = "nsec_el12", .value = (3 << 5) },
+               { .name = "sec_el1",   .value = (1 << 1) },
+               { .name = "sec_el3",   .value = (4 << 1) },
+               { .name = "sec_el13",  .value = (5 << 1) },
+               { .name = NULL, .value = -1 },
+       };
+       const Jim_Nvp *n;
+
+       if (CMD_ARGC == 0) {
+               const char *sec = NULL, *nsec = NULL;
+
+               retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+                                       armv8->debug_base + CPUV8_DBG_ECCR, &edeccr);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0x0f);
+               if (n->name != NULL)
+                       sec = n->name;
+
+               n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0xf0);
+               if (n->name != NULL)
+                       nsec = n->name;
+
+               if (sec == NULL || nsec == NULL) {
+                       LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02x", edeccr & 0xff);
+                       return ERROR_FAIL;
+               }
+
+               command_print(CMD_CTX, "Exception Catch: Secure: %s, Non-Secure: %s", sec, nsec);
+               return ERROR_OK;
+       }
+
+       while (CMD_ARGC > argp) {
+               n = Jim_Nvp_name2value_simple(nvp_ecatch_modes, CMD_ARGV[argp]);
+               if (n->name == NULL) {
+                       LOG_ERROR("Unknown option: %s", CMD_ARGV[argp]);
+                       return ERROR_FAIL;
+               }
+
+               LOG_DEBUG("found: %s", n->name);
+
+               edeccr |= n->value;
+               argp++;
+       }
+
+       retval = mem_ap_write_atomic_u32(armv8->debug_ap,
+                               armv8->debug_base + CPUV8_DBG_ECCR, edeccr);
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
 int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
        struct armv8_cache_common *armv8_cache)
 {
 int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
        struct armv8_cache_common *armv8_cache)
 {
@@ -1675,6 +1741,13 @@ void armv8_free_reg_cache(struct target *target)
 }
 
 const struct command_registration armv8_command_handlers[] = {
 }
 
 const struct command_registration armv8_command_handlers[] = {
+       {
+               .name = "catch_exc",
+               .handler = armv8_handle_exception_catch_command,
+               .mode = COMMAND_EXEC,
+               .help = "configure exception catch",
+               .usage = "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
+       },
        COMMAND_REGISTRATION_DONE
 };
 
        COMMAND_REGISTRATION_DONE
 };
 
index dfd54edcba07263ba5177545bf573c3b6e9d09a4..af00e52d618571780c97fac7250a9c7a6d95b63a 100644 (file)
@@ -261,6 +261,7 @@ static inline bool is_armv8(struct armv8_common *armv8)
 #define CPUV8_DBG_WFAR1                0x34
 #define CPUV8_DBG_DSCR         0x088
 #define CPUV8_DBG_DRCR         0x090
 #define CPUV8_DBG_WFAR1                0x34
 #define CPUV8_DBG_DSCR         0x088
 #define CPUV8_DBG_DRCR         0x090
+#define CPUV8_DBG_ECCR         0x098
 #define CPUV8_DBG_PRCR         0x310
 #define CPUV8_DBG_PRSR         0x314
 
 #define CPUV8_DBG_PRCR         0x310
 #define CPUV8_DBG_PRSR         0x314
 
index a5d7d11f8d0352dbbd09097a49ebc0da6cfb9b73..081eed21ba21166ef5babadd78b9537f9a36dde8 100644 (file)
@@ -1381,13 +1381,15 @@ void armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
                case DSCRV8_ENTRY_BKPT: /* SW BKPT (?) */
                case DSCRV8_ENTRY_RESET_CATCH:  /* Reset catch */
                case DSCRV8_ENTRY_OS_UNLOCK:  /*OS unlock catch*/
                case DSCRV8_ENTRY_BKPT: /* SW BKPT (?) */
                case DSCRV8_ENTRY_RESET_CATCH:  /* Reset catch */
                case DSCRV8_ENTRY_OS_UNLOCK:  /*OS unlock catch*/
-               case DSCRV8_ENTRY_EXCEPTION_CATCH:  /*exception catch*/
                case DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/
                        target->debug_reason = DBG_REASON_BREAKPOINT;
                        break;
                case DSCRV8_ENTRY_WATCHPOINT:   /* asynch watchpoint */
                        target->debug_reason = DBG_REASON_WATCHPOINT;
                        break;
                case DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/
                        target->debug_reason = DBG_REASON_BREAKPOINT;
                        break;
                case DSCRV8_ENTRY_WATCHPOINT:   /* asynch watchpoint */
                        target->debug_reason = DBG_REASON_WATCHPOINT;
                        break;
+               case DSCRV8_ENTRY_EXCEPTION_CATCH:  /*exception catch*/
+                       target->debug_reason = DBG_REASON_EXC_CATCH;
+                       break;
                default:
                        target->debug_reason = DBG_REASON_UNDEFINED;
                        break;
                default:
                        target->debug_reason = DBG_REASON_UNDEFINED;
                        break;
index 9955a56554aa2068659c9861ae0cbb58d43a2d69..1f8e0bfc3c8c4cd67ddb0eac6ef791e4e4b64eda 100644 (file)
@@ -251,6 +251,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = {
        { .name = "single-step"              , .value = DBG_REASON_SINGLESTEP },
        { .name = "target-not-halted"        , .value = DBG_REASON_NOTHALTED  },
        { .name = "program-exit"             , .value = DBG_REASON_EXIT },
        { .name = "single-step"              , .value = DBG_REASON_SINGLESTEP },
        { .name = "target-not-halted"        , .value = DBG_REASON_NOTHALTED  },
        { .name = "program-exit"             , .value = DBG_REASON_EXIT },
+       { .name = "exception-catch"          , .value = DBG_REASON_EXC_CATCH },
        { .name = "undefined"                , .value = DBG_REASON_UNDEFINED },
        { .name = NULL, .value = -1 },
 };
        { .name = "undefined"                , .value = DBG_REASON_UNDEFINED },
        { .name = NULL, .value = -1 },
 };
index 36b131aa9f401e135edecaea30c516b8fbb13450..794ee833ecc81b4a9811a1f8fbe9c6f131959bcb 100644 (file)
@@ -84,7 +84,8 @@ enum target_debug_reason {
        DBG_REASON_SINGLESTEP = 4,
        DBG_REASON_NOTHALTED = 5,
        DBG_REASON_EXIT = 6,
        DBG_REASON_SINGLESTEP = 4,
        DBG_REASON_NOTHALTED = 5,
        DBG_REASON_EXIT = 6,
-       DBG_REASON_UNDEFINED = 7,
+       DBG_REASON_EXC_CATCH = 7,
+       DBG_REASON_UNDEFINED = 8,
 };
 
 enum target_endianness {
 };
 
 enum target_endianness {

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)