Initial ETM cleanups. Most of these are cosmetic:
authordbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 23 Sep 2009 07:49:38 +0000 (07:49 +0000)
committerdbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 23 Sep 2009 07:49:38 +0000 (07:49 +0000)
 - Add a header comment
 - Line up the ETM context struct, pack it a bit
 - Remove unused context_id (this doesn't support ETMv2 yet)
 - Make most functions static
 - Remove unused string table and other needless lines of code
 - Correct "tracemode" helptext

Also provide and use an etm_reg_lookup() to find entries in the ETM
register cache.  This will help cope with corrected contents of that
cache, which doesn't include entires for non-existent registers.

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

src/target/etm.c
src/target/etm.h

index 2623ebe53fb41a77f31320fda155b01754346433..dfb104e72df84bedbcc797839c168f60840d3ae6 100644 (file)
 #include "arm_disassembler.h"
 
 
-/* ETM register access functionality
+/*
+ * ARM "Embedded Trace Macrocell" (ETM) support -- direct JTAG access.
  *
+ * ETM modules collect instruction and/or data trace information, compress
+ * it, and transfer it to a debugging host through either a (buffered) trace
+ * port (often a 38-pin Mictor connector) or an Embedded Trace Buffer (ETB).
+ *
+ * There are several generations of these modules.  Original versions have
+ * JTAG access through a dedicated scan chain.  Recent versions have added
+ * access via coprocessor instructions, memory addressing, and the ARM Debug
+ * Interface v5 (ADIv5); and phased out direct JTAG access.
+ *
+ * This code supports up to the ETMv1.3 architecture, as seen in ETM9 and
+ * most common ARM9 systems.  Note: "CoreSight ETM9" implements ETMv3.2,
+ * implying non-JTAG connectivity options.
+ *
+ * Relevant documentation includes:
+ *  ARM DDI 0157G ... ETM9 (r2p2) Technical Reference Manual
+ *  ARM DDI 0315B ... CoreSight ETM9 (r0p1) Technical Reference Manual
+ *  ARM IHI 0014O ... Embedded Trace Macrocell, Architecture Specification
  */
 
-#if 0
-static bitfield_desc_t etm_comms_ctrl_bitfield_desc[] =
-{
-       {"R", 1},
-       {"W", 1},
-       {"reserved", 26},
-       {"version", 4}
-};
-#endif
-
 static int etm_reg_arch_info[] =
 {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -196,10 +204,38 @@ static char* etm_reg_list[] =
 static int etm_reg_arch_type = -1;
 
 static int etm_get_reg(reg_t *reg);
+static int etm_read_reg_w_check(reg_t *reg,
+               uint8_t* check_value, uint8_t* check_mask);
+static int etm_register_user_commands(struct command_context_s *cmd_ctx);
+static int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf);
+static int etm_write_reg(reg_t *reg, uint32_t value);
+
+static command_t *etm_cmd;
 
-static command_t *etm_cmd = NULL;
 
-reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_context_t *etm_ctx)
+/* Look up register by ID ... most ETM instances only
+ * support a subset of the possible registers.
+ */
+static reg_t *etm_reg_lookup(etm_context_t *etm_ctx, unsigned id)
+{
+       reg_cache_t *cache = etm_ctx->reg_cache;
+       int i;
+
+       for (i = 0; i < cache->num_regs; i++) {
+               struct etm_reg_s *reg = cache->reg_list[i].arch_info;
+
+               if (reg->addr == (int) id)
+                       return &cache->reg_list[i];
+       }
+
+       /* caller asking for nonexistent register is a bug! */
+       /* REVISIT say which of the N targets was involved */
+       LOG_ERROR("ETM: register 0x%02x not available", id);
+       return NULL;
+}
+
+reg_cache_t *etm_build_reg_cache(target_t *target,
+               arm_jtag_t *jtag_info, etm_context_t *etm_ctx)
 {
        reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
        reg_t *reg_list = NULL;
@@ -226,10 +262,6 @@ reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_co
        {
                reg_list[i].name = etm_reg_list[i];
                reg_list[i].size = 32;
-               reg_list[i].dirty = 0;
-               reg_list[i].valid = 0;
-               reg_list[i].bitfield_desc = NULL;
-               reg_list[i].num_bitfields = 0;
                reg_list[i].value = calloc(1, 4);
                reg_list[i].arch_info = &arch_info[i];
                reg_list[i].arch_type = etm_reg_arch_type;
@@ -264,6 +296,16 @@ reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_co
        return reg_cache;
 }
 
+static int etm_read_reg(reg_t *reg)
+{
+       return etm_read_reg_w_check(reg, NULL, NULL);
+}
+
+static int etm_store_reg(reg_t *reg)
+{
+       return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
+}
+
 int etm_setup(target_t *target)
 {
        int retval;
@@ -271,7 +313,11 @@ int etm_setup(target_t *target)
        armv4_5_common_t *armv4_5 = target->arch_info;
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        etm_context_t *etm_ctx = arm7_9->etm_ctx;
-       reg_t *etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
+       reg_t *etm_ctrl_reg;
+
+       etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL);
+       if (!etm_ctrl_reg)
+               return ERROR_OK;
 
        /* initialize some ETM control register settings */
        etm_get_reg(etm_ctrl_reg);
@@ -299,7 +345,7 @@ int etm_setup(target_t *target)
        return ERROR_OK;
 }
 
-int etm_get_reg(reg_t *reg)
+static int etm_get_reg(reg_t *reg)
 {
        int retval;
 
@@ -318,7 +364,8 @@ int etm_get_reg(reg_t *reg)
        return ERROR_OK;
 }
 
-int etm_read_reg_w_check(reg_t *reg, uint8_t* check_value, uint8_t* check_mask)
+static int etm_read_reg_w_check(reg_t *reg,
+               uint8_t* check_value, uint8_t* check_mask)
 {
        etm_reg_t *etm_reg = reg->arch_info;
        uint8_t reg_addr = etm_reg->addr & 0x7f;
@@ -367,12 +414,7 @@ int etm_read_reg_w_check(reg_t *reg, uint8_t* check_value, uint8_t* check_mask)
        return ERROR_OK;
 }
 
-int etm_read_reg(reg_t *reg)
-{
-       return etm_read_reg_w_check(reg, NULL, NULL);
-}
-
-int etm_set_reg(reg_t *reg, uint32_t value)
+static int etm_set_reg(reg_t *reg, uint32_t value)
 {
        int retval;
 
@@ -389,7 +431,7 @@ int etm_set_reg(reg_t *reg, uint32_t value)
        return ERROR_OK;
 }
 
-int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf)
+static int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf)
 {
        int retval;
 
@@ -403,7 +445,7 @@ int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf)
        return ERROR_OK;
 }
 
-int etm_write_reg(reg_t *reg, uint32_t value)
+static int etm_write_reg(reg_t *reg, uint32_t value)
 {
        etm_reg_t *etm_reg = reg->arch_info;
        uint8_t reg_addr = etm_reg->addr & 0x7f;
@@ -441,10 +483,6 @@ int etm_write_reg(reg_t *reg, uint32_t value)
        return ERROR_OK;
 }
 
-int etm_store_reg(reg_t *reg)
-{
-       return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
-}
 
 /* ETM trace analysis functionality
  *
@@ -464,18 +502,6 @@ static etm_capture_driver_t *etm_capture_drivers[] =
        NULL
 };
 
-char *etmv1v1_branch_reason_strings[] =
-{
-       "normal PC change",
-       "tracing enabled",
-       "trace restarted after overflow",
-       "exit from debug",
-       "periodic synchronization",
-       "reserved",
-       "reserved",
-       "reserved",
-};
-
 static int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instruction)
 {
        int i;
@@ -1172,7 +1198,11 @@ static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char
        /* only update ETM_CTRL register if tracemode changed */
        if (arm7_9->etm_ctx->tracemode != tracemode)
        {
-               reg_t *etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
+               reg_t *etm_ctrl_reg;
+
+               etm_ctrl_reg = etm_reg_lookup(arm7_9->etm_ctx, ETM_CTRL);
+               if (!etm_ctrl_reg)
+                       return ERROR_OK;
 
                etm_get_reg(etm_ctrl_reg);
 
@@ -1319,7 +1349,6 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cm
        etm_ctx->last_branch_reason = 0x0;
        etm_ctx->last_ptr = 0x0;
        etm_ctx->ptr_ok = 0x0;
-       etm_ctx->context_id = 0x0;
        etm_ctx->last_instruction = 0;
 
        arm7_9->etm_ctx = etm_ctx;
@@ -1327,7 +1356,8 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cm
        return etm_register_user_commands(cmd_ctx);
 }
 
-int handle_etm_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_etm_info_command(struct command_context_s *cmd_ctx,
+               char *cmd, char **args, int argc)
 {
        target_t *target;
        armv4_5_common_t *armv4_5;
@@ -1351,8 +1381,12 @@ int handle_etm_info_command(struct command_context_s *cmd_ctx, char *cmd, char *
                return ERROR_OK;
        }
 
-       etm_config_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CONFIG];
-       etm_sys_config_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_SYS_CONFIG];
+       etm_config_reg = etm_reg_lookup(arm7_9->etm_ctx, ETM_CONFIG);
+       if (!etm_config_reg)
+               return ERROR_OK;
+       etm_sys_config_reg = etm_reg_lookup(arm7_9->etm_ctx, ETM_SYS_CONFIG);
+       if (!etm_sys_config_reg)
+               return ERROR_OK;
 
        etm_get_reg(etm_config_reg);
        command_print(cmd_ctx, "pairs of address comparators: %i", (int)buf_get_u32(etm_config_reg->value, 0, 4));
@@ -1732,7 +1766,10 @@ static int handle_etm_start_command(struct command_context_s *cmd_ctx, char *cmd
        }
        arm7_9->etm_ctx->trace_depth = 0;
 
-       etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
+       etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL);
+       if (!etm_ctrl_reg)
+               return ERROR_OK;
+
        etm_get_reg(etm_ctrl_reg);
 
        /* Clear programming bit (10), set port selection bit (11) */
@@ -1768,7 +1805,10 @@ static int handle_etm_stop_command(struct command_context_s *cmd_ctx, char *cmd,
                return ERROR_OK;
        }
 
-       etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
+       etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL);
+       if (!etm_ctrl_reg)
+               return ERROR_OK;
+
        etm_get_reg(etm_ctrl_reg);
 
        /* Set programming bit (10), clear port selection bit (11) */
@@ -1835,10 +1875,11 @@ int etm_register_commands(struct command_context_s *cmd_ctx)
        return ERROR_OK;
 }
 
-int etm_register_user_commands(struct command_context_s *cmd_ctx)
+static int etm_register_user_commands(struct command_context_s *cmd_ctx)
 {
        register_command(cmd_ctx, etm_cmd, "tracemode", handle_etm_tracemode_command,
-               COMMAND_EXEC, "configure trace mode <none | data | address | all> "
+               COMMAND_EXEC, "configure/display trace mode: "
+                       "<none | data | address | all> "
                        "<context_id_bits> <cycle_accurate> <branch_output>");
 
        register_command(cmd_ctx, etm_cmd, "info", handle_etm_info_command,
index 14dda4fcee895e9722bce0e6cb8cbff8afdc86fe..43ec048fb7733076d2295721e7f3206cf3c92a5c 100644 (file)
@@ -139,29 +139,28 @@ typedef struct etmv1_trace_data_s
  */
 typedef struct etm_context_s
 {
-       target_t *target;                               /* target this ETM is connected to */
-       reg_cache_t *reg_cache;                 /* ETM register cache */
+       target_t *target;               /* target this ETM is connected to */
+       reg_cache_t *reg_cache;         /* ETM register cache */
        etm_capture_driver_t *capture_driver;   /* driver used to access ETM data */
-       void *capture_driver_priv;              /* capture driver private data */
-       uint32_t trigger_percent;                       /* percent of trace buffer to be filled after the trigger */
+       void *capture_driver_priv;      /* capture driver private data */
+       uint32_t trigger_percent;       /* how much trace buffer to fill after trigger */
        trace_status_t capture_status;  /* current state of capture run */
        etmv1_trace_data_t *trace_data; /* trace data */
-       uint32_t trace_depth;                           /* number of trace cycles to be analyzed, 0 if no trace data available */
-       etm_portmode_t portmode;                /* normal, multiplexed or demultiplexed */
-       etmv1_tracemode_t tracemode;    /* type of information the trace contains (data, addres, contextID, ...) */
-       armv4_5_state_t core_state;             /* current core state (ARM, Thumb, Jazelle) */
-       struct image_s *image;                                  /* source for target opcodes */
-       uint32_t pipe_index;                                    /* current trace cycle */
-       uint32_t data_index;                                    /* cycle holding next data packet */
-       int data_half;                                  /* port half on a 16 bit port */
-       uint32_t current_pc;                                    /* current program counter */
-       uint32_t pc_ok;                                         /* full PC has been acquired */
-       uint32_t last_branch;                           /* last branch address output */
-       uint32_t last_branch_reason;                    /* branch reason code for the last branch encountered */
-       uint32_t last_ptr;                                      /* address of the last data access */
-       uint32_t ptr_ok;                                                /* whether last_ptr is valid */
-       uint32_t context_id;                                    /* context ID of the code being traced */
-       uint32_t last_instruction;                      /* index of last instruction executed (to calculate cycle timings) */
+       uint32_t trace_depth;           /* number of cycles to be analyzed, 0 if no data available */
+       etm_portmode_t portmode;        /* normal, multiplexed or demultiplexed */
+       etmv1_tracemode_t tracemode;    /* type of info trace contains */
+       armv4_5_state_t core_state;     /* current core state */
+       struct image_s *image;          /* source for target opcodes */
+       uint32_t pipe_index;            /* current trace cycle */
+       uint32_t data_index;            /* cycle holding next data packet */
+       bool data_half;                 /* port half on a 16 bit port */
+       bool pc_ok;                     /* full PC has been acquired */
+       bool ptr_ok;                    /* whether last_ptr is valid */
+       uint32_t current_pc;            /* current program counter */
+       uint32_t last_branch;           /* last branch address output */
+       uint32_t last_branch_reason;    /* type of last branch encountered */
+       uint32_t last_ptr;              /* address of the last data access */
+       uint32_t last_instruction;      /* index of last executed (to calc timings) */
 } etm_context_t;
 
 /* PIPESTAT values */
@@ -190,20 +189,10 @@ typedef enum
        BR_RSVD7   = 0x7, /* reserved */
 } etmv1_branch_reason_t;
 
-extern char *etmv1v1_branch_reason_strings[];
-
 extern reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_context_t *etm_ctx);
-extern int etm_read_reg(reg_t *reg);
-extern int etm_write_reg(reg_t *reg, uint32_t value);
-extern int etm_read_reg_w_check(reg_t *reg, uint8_t* check_value, uint8_t* check_mask);
-extern int etm_store_reg(reg_t *reg);
-extern int etm_set_reg(reg_t *reg, uint32_t value);
-extern int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf);
 extern int etm_setup(target_t *target);
 
 int etm_register_commands(struct command_context_s *cmd_ctx);
-int etm_register_user_commands(struct command_context_s *cmd_ctx);
-extern etm_context_t* etm_create_context(etm_portmode_t portmode, char *capture_driver_name);
 
 #define ERROR_ETM_INVALID_DRIVER       (-1300)
 #define ERROR_ETM_PORTMODE_NOT_SUPPORTED       (-1301)

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)