/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "arm.h"
#include "etm.h"
#include "etb.h"
#include "image.h"
#include "arm_disassembler.h"
#include "register.h"
#include "etm_dummy.h"
#if BUILD_OOCD_TRACE == 1
#include "oocd_trace.h"
#endif
/*
* 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
*/
enum {
RO, /* read/only */
WO, /* write/only */
RW, /* read/write */
};
struct etm_reg_info {
uint8_t addr;
uint8_t size; /* low-N of 32 bits */
uint8_t mode; /* RO, WO, RW */
uint8_t bcd_vers; /* 1.0, 2.0, etc */
const char *name;
};
/*
* Registers 0..0x7f are JTAG-addressable using scanchain 6.
* (Or on some processors, through coprocessor operations.)
* Newer versions of ETM make some W/O registers R/W, and
* provide definitions for some previously-unused bits.
*/
/* core registers used to version/configure the ETM */
static const struct etm_reg_info etm_core[] = {
/* NOTE: we "know" the order here ... */
{ ETM_CONFIG, 32, RO, 0x10, "ETM_config", },
{ ETM_ID, 32, RO, 0x20, "ETM_id", },
};
/* basic registers that are always there given the right ETM version */
static const struct etm_reg_info etm_basic[] = {
/* ETM Trace Registers */
{ ETM_CTRL, 32, RW, 0x10, "ETM_ctrl", },
{ ETM_TRIG_EVENT, 17, WO, 0x10, "ETM_trig_event", },
{ ETM_ASIC_CTRL, 8, WO, 0x10, "ETM_asic_ctrl", },
{ ETM_STATUS, 3, RO, 0x11, "ETM_status", },
{ ETM_SYS_CONFIG, 9, RO, 0x12, "ETM_sys_config", },
/* TraceEnable configuration */
{ ETM_TRACE_RESOURCE_CTRL, 32, WO, 0x12, "ETM_trace_resource_ctrl", },
{ ETM_TRACE_EN_CTRL2, 16, WO, 0x12, "ETM_trace_en_ctrl2", },
{ ETM_TRACE_EN_EVENT, 17, WO, 0x10, "ETM_trace_en_event", },
{ ETM_TRACE_EN_CTRL1, 26, WO, 0x10, "ETM_trace_en_ctrl1", },
/* ViewData configuration (data trace) */
{ ETM_VIEWDATA_EVENT, 17, WO, 0x10, "ETM_viewdata_event", },
{ ETM_VIEWDATA_CTRL1, 32, WO, 0x10, "ETM_viewdata_ctrl1", },
{ ETM_VIEWDATA_CTRL2, 32, WO, 0x10, "ETM_viewdata_ctrl2", },
{ ETM_VIEWDATA_CTRL3, 17, WO, 0x10, "ETM_viewdata_ctrl3", },
/* REVISIT exclude VIEWDATA_CTRL2 when it's not there */
{ 0x78, 12, WO, 0x20, "ETM_sync_freq", },
{ 0x7a, 22, RO, 0x31, "ETM_config_code_ext", },
{ 0x7b, 32, WO, 0x31, "ETM_ext_input_select", },
{ 0x7c, 32, WO, 0x34, "ETM_trace_start_stop", },
{ 0x7d, 8, WO, 0x34, "ETM_behavior_control", },
};
static const struct etm_reg_info etm_fifofull[] = {
/* FIFOFULL configuration */
{ ETM_FIFOFULL_REGION, 25, WO, 0x10, "ETM_fifofull_region", },
{ ETM_FIFOFULL_LEVEL, 8, WO, 0x10, "ETM_fifofull_level", },
};
static const struct etm_reg_info etm_addr_comp[] = {
/* Address comparator register pairs */
#define ADDR_COMPARATOR(i) \
{ ETM_ADDR_COMPARATOR_VALUE + (i) - 1, 32, WO, 0x10, \
"ETM_addr_" #i "_comparator_value", }, \
{ ETM_ADDR_ACCESS_TYPE + (i) - 1, 7, WO, 0x10, \
"ETM_addr_" #i "_access_type", }
ADDR_COMPARATOR(1),
ADDR_COMPARATOR(2),
ADDR_COMPARATOR(3),
ADDR_COMPARATOR(4),
ADDR_COMPARATOR(5),
ADDR_COMPARATOR(6),
ADDR_COMPARATOR(7),
ADDR_COMPARATOR(8),
ADDR_COMPARATOR(9),
ADDR_COMPARATOR(10),
ADDR_COMPARATOR(11),
ADDR_COMPARATOR(12),
ADDR_COMPARATOR(13),
ADDR_COMPARATOR(14),
ADDR_COMPARATOR(15),
ADDR_COMPARATOR(16),
{ 0, 0, 0, 0, NULL }
#undef ADDR_COMPARATOR
};
static const struct etm_reg_info etm_data_comp[] = {
/* Data Value Comparators (NOTE: odd addresses are reserved) */
#define DATA_COMPARATOR(i) \
{ ETM_DATA_COMPARATOR_VALUE + 2*(i) - 1, 32, WO, 0x10, \
"ETM_data_" #i "_comparator_value", }, \
{ ETM_DATA_COMPARATOR_MASK + 2*(i) - 1, 32, WO, 0x10, \
"ETM_data_" #i "_comparator_mask", }
DATA_COMPARATOR(1),
DATA_COMPARATOR(2),
DATA_COMPARATOR(3),
DATA_COMPARATOR(4),
DATA_COMPARATOR(5),
DATA_COMPARATOR(6),
DATA_COMPARATOR(7),
DATA_COMPARATOR(8),
|