coresight: add etm3 device support

Signed-off-by: liaoao <liaoao@xiaomi.com>
This commit is contained in:
liaoao 2023-09-15 21:33:00 +08:00 committed by Xiang Xiao
parent e3e23f7eaf
commit 71e4267a7a
10 changed files with 914 additions and 19 deletions

View File

@ -21,6 +21,10 @@
if(CONFIG_CORESIGHT)
set(SRCS coresight_core.c coresight_common.c)
if(CONFIG_CORESIGHT_ETM_VERSION STREQUAL "v3")
list(APPEND SRCS coresight_etm3.c)
endif()
if(CONFIG_CORESIGHT_FUNNEL)
list(APPEND SRCS coresight_funnel.c)
endif()

View File

@ -19,6 +19,22 @@ config CORESIGHT_TIMEOUT
int "Timeout us for waiting register state change"
default 100
config CORESIGHT_ETM
bool "ETM coresight device support"
default n
if CORESIGHT_ETM
config CORESIGHT_ETM_VERSION
string "Coresight ETM version"
default "v3"
config CORESIGHT_ETM_USE_COPROCESSOR
bool "Whether use coprocessor to access ETM registers"
default n
endif # CORESIGHT_ETM
config CORESIGHT_FUNNEL
bool "Funnel coresight device support"
default n

View File

@ -24,6 +24,10 @@ ifeq ($(CONFIG_CORESIGHT),y)
CSRCS += coresight_core.c coresight_common.c
ifeq ($(CONFIG_CORESIGHT_ETM_VERSION),"v3")
CSRCS += coresight_etm3.c
endif
ifeq ($(CONFIG_CORESIGHT_FUNNEL),y)
CSRCS += coresight_funnel.c
endif

View File

@ -272,15 +272,14 @@ void coresight_put_system_trace_id(int traceid)
*
****************************************************************************/
int coresight_timeout(uintptr_t addr, uint32_t off,
uint32_t bitmask, uint32_t val)
int coresight_timeout(uint32_t val, uint32_t mask, uintptr_t addr)
{
int i;
for (i = CONFIG_CORESIGHT_TIMEOUT; i > 0; i--)
{
uint32_t value = coresight_get32(addr + off);
if ((value & bitmask) == val)
uint32_t value = coresight_get32(addr);
if ((value & mask) == val)
{
return 0;
}

View File

@ -183,8 +183,7 @@ void coresight_put_system_trace_id(int traceid);
*
****************************************************************************/
int coresight_timeout(uintptr_t addr, uint32_t off,
uint32_t bitmask, uint32_t val);
int coresight_timeout(uint32_t val, uint32_t mask, uintptr_t addr);
/****************************************************************************
* Name: coresight_insert_barrier_packet

View File

@ -0,0 +1,733 @@
/****************************************************************************
* drivers/coresight/coresight_etm3.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <errno.h>
#include <debug.h>
#include <nuttx/bits.h>
#include <nuttx/kmalloc.h>
#include <nuttx/coresight/coresight_etm.h>
#include "coresight_common.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Device registers:
* 0x000 - 0x2FC: Trace registers
* 0x300 - 0x314: Management registers
* 0x318 - 0xEFC: Trace registers
*
* Coresight registers
* 0xF00 - 0xF9C: Management registers
* 0xFA0 - 0xFA4: Management registers in PFTv1.0
* Trace registers in PFTv1.1
* 0xFA8 - 0xFFC: Management registers
*/
#define ETM_CR 0x000
#define ETM_CCR 0x004
#define ETM_TRIGGER 0x008
#define ETM_SR 0x010
#define ETM_SCR 0x014
#define ETM_TSSCR 0x018
#define ETM_TECR2 0x01c
#define ETM_TEEVR 0x020
#define ETM_TECR1 0x024
#define ETM_FFLR 0x02c
#define ETM_ACVR(n) (0x040 + (n * 4))
#define ETM_ACTR(n) (0x080 + (n * 4))
#define ETM_CNTRLDVR(n) (0x140 + (n * 4))
#define ETM_CNTENR(n) (0x150 + (n * 4))
#define ETM_CNTRLDEVR(n) (0x160 + (n * 4))
#define ETM_CNTVR(n) (0x170 + (n * 4))
#define ETM_SQ12EVR 0x180
#define ETM_SQ21EVR 0x184
#define ETM_SQ23EVR 0x188
#define ETM_SQ31EVR 0x18c
#define ETM_SQ32EVR 0x190
#define ETM_SQ13EVR 0x194
#define ETM_SQR 0x19c
#define ETM_EXTOUTEVR(n) (0x1a0 + (n * 4))
#define ETM_CIDCVR(n) (0x1b0 + (n * 4))
#define ETM_CIDCMR 0x1bc
#define ETM_IMPSPEC0 0x1c0
#define ETM_IMPSPEC1 0x1c4
#define ETM_IMPSPEC2 0x1c8
#define ETM_IMPSPEC3 0x1cc
#define ETM_IMPSPEC4 0x1d0
#define ETM_IMPSPEC5 0x1d4
#define ETM_IMPSPEC6 0x1d8
#define ETM_IMPSPEC7 0x1dc
#define ETM_SYNCFR 0x1e0
#define ETM_IDR 0x1e4
#define ETM_CCER 0x1e8
#define ETM_EXTINSELR 0x1ec
#define ETM_TESSEICR 0x1f0
#define ETM_EIBCR 0x1f4
#define ETM_TSEVR 0x1f8
#define ETM_AUXCR 0x1fc
#define ETM_TRACEIDR 0x200
#define ETM_VMIDCVR 0x240
/* Management registers (0x300-0x314) */
#define ETM_OSLAR 0x300
#define ETM_OSLSR 0x304
#define ETM_OSSRR 0x308
#define ETM_PDCR 0x310
#define ETM_PDSR 0x314
/* Register definition */
/* ETMCR - 0x00 */
#define ETM_CR_PWD_DWN BIT(0)
#define ETM_CR_STALL_MODE BIT(7)
#define ETM_CR_BRANCH_BROADCAST BIT(8)
#define ETM_CR_ETM_PRG BIT(10)
#define ETM_CR_ETM_EN BIT(11)
#define ETM_CR_CYC_ACC BIT(12)
#define ETM_CR_CTXID_SIZE (BIT(14) | BIT(15))
#define ETM_CR_TIMESTAMP_EN BIT(28)
/* ETM_CR_RETURN_STACK is supported by PTM, ETM not support it */
#define ETM_CR_RETURN_STACK BIT(29)
/* ETMCCR - 0x04 */
#define ETM_CCR_FIFOFULL BIT(23)
/* ETMPDCR - 0x310 */
#define ETM_PDCR_PWD_UP BIT(3)
/* ETMTECR1 - 0x024 */
#define ETM_TECR1_ADDR_COMP_1 BIT(0)
#define ETM_TECR1_INC_EXC BIT(24)
#define ETM_TECR1_START_STOP BIT(25)
/* ETMCCER - 0x1E8 */
#define ETM_CCER_TIMESTAMP BIT(22)
#define ETM_CCER_RETSTACK BIT(23)
#define ETM_MODE_EXCLUDE BIT(0)
#define ETM_MODE_CYCACC BIT(1)
#define ETM_MODE_STALL BIT(2)
#define ETM_MODE_TIMESTAMP BIT(3)
#define ETM_MODE_CTXID BIT(4)
#define ETM_MODE_BBROAD BIT(5)
#define ETM_MODE_RET_STACK BIT(6)
#define ETM_MODE_EXCL_KERN BIT(30)
#define ETM_MODE_EXCL_USER BIT(31)
#define ETM_MODE_ALL \
(ETM_MODE_EXCLUDE | ETM_MODE_CYCACC | ETM_MODE_STALL | \
ETM_MODE_TIMESTAMP | ETM_MODE_CTXID | ETM_MODE_BBROAD | \
ETM_MODE_RET_STACK | ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER)
#define ETM_SQR_MASK 0x3
#define ETM_TRACEID_MASK 0x3f
#define ETM_EVENT_MASK 0x1ffff
#define ETM_SYNC_MASK 0xfff
#define ETM_ALL_MASK 0xffffffff
#define ETM_SR_PROGRAM BIT(1)
#define ETM_SEQ_STATE_MAX_VAL 0x2
#define ETM_PORT_SIZE_MASK (GENMASK(21, 21) | GENMASK(6, 4))
#define ETM_ARCH_V3_3 0x23
#define ETM_ARCH_V3_5 0x25
#define PFT_ARCH_V1_0 0x30
#define PFT_ARCH_V1_1 0x31
/* Hard wired, always true */
#define ETM_HARD_WIRE_RES_A ((0x0f << 0) | (0x06 << 4))
/* Single addr comparator 1 */
#define ETM_ADD_COMP_0 ((0x00 << 7) | (0x00 << 11))
/* NOT(A) */
#define ETM_EVENT_NOT_A BIT(14)
#define ETM_DEFAULT_EVENT_VAL \
(ETM_HARD_WIRE_RES_A | ETM_ADD_COMP_0 | ETM_EVENT_NOT_A)
#define ETM3X_SUPPORTED_OPTIONS \
(ETM_CR_CYC_ACC | ETM_CR_TIMESTAMP_EN | ETM_CR_RETURN_STACK)
/****************************************************************************
* Private Functions Prototypes
****************************************************************************/
static int etm_enable(FAR struct coresight_dev_s *csdev);
static void etm_disable(FAR struct coresight_dev_s *csdev);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct coresight_source_ops_s g_etm_source_ops =
{
.enable = etm_enable,
.disable = etm_disable,
};
static const struct coresight_ops_s g_etm_ops =
{
.source_ops = &g_etm_source_ops,
};
/****************************************************************************
* Private Functions
****************************************************************************/
#ifndef CONFIG_CORESIGHT_ETM_USE_COPROCESSOR
static inline void etm_write_reg(FAR struct coresight_etm_dev_s *etmdev,
uint32_t val, uint32_t off)
{
coresight_put32(val, etmdev->csdev.addr + off);
}
static inline uint32_t etm_read_reg(FAR struct coresight_etm_dev_s *etmdev,
uint32_t off)
{
return coresight_get32(etmdev->csdev.addr + off);
}
#endif
/****************************************************************************
* Name: etm_modify_reg32
*
* Description:
* Set a bitmask of register to specific value.
*
****************************************************************************/
static void etm_modify_reg32(FAR struct coresight_etm_dev_s *etmdev,
uint32_t val, uint32_t mask, uint32_t off)
{
uint32_t temp = etm_read_reg(etmdev, off);
etm_write_reg(etmdev, (temp & ~mask) | (val & mask), off);
}
/****************************************************************************
* Name: etm_os_unlock
*
* Description:
* When the ETM trace registers are locked, any attempt to access the
* locked registers returns a slave-generated error response.In ETMv3.5,
* the OS Lock is always set from an ETM reset. ARM recommends that, after
* programming the ETM registers, you always execute an ISB instruction to
* ensure that all updates are committed to the ETM before you restart
* normal code execution.
*
****************************************************************************/
static void etm_os_unlock(FAR struct coresight_etm_dev_s *etmdev)
{
etm_write_reg(etmdev, 0x0, ETM_OSLAR);
}
/****************************************************************************
* Name: etm_clr_pwrdwn
*
* Description:
* When pwrdown bit is set to 1, the ETM must be powered down and disabled,
* and then operated in a low power mode with all clocks stopped. When this
* bit is set to 1, writes to some registers and fields might be ignored.
* ARM recommends that you use a read-modify-write procedure when modifying
* the ETMCR.
*
****************************************************************************/
static void etm_clr_pwrdwn(FAR struct coresight_etm_dev_s *etmdev)
{
etm_modify_reg32(etmdev, 0, ETM_CR_PWD_DWN, ETM_CR);
}
/****************************************************************************
* Name: etm_set_pwrdwn
****************************************************************************/
static void etm_set_pwrdwn(FAR struct coresight_etm_dev_s *etmdev)
{
etm_modify_reg32(etmdev, ETM_CR_PWD_DWN, ETM_CR_PWD_DWN, ETM_CR);
}
/****************************************************************************
* Name: etm_set_pwrup
*
* Description:
* Power is provided to the ETM trace registers. This register can only be
* accessed using a memory-mapped interface or from an external debugger.
*
****************************************************************************/
static void etm_set_pwrup(FAR struct coresight_etm_dev_s *etmdev)
{
coresight_modify32(ETM_PDCR_PWD_UP, ETM_PDCR_PWD_UP,
etmdev->csdev.addr + ETM_PDCR);
}
/****************************************************************************
* Name: etm_clr_pwrup
****************************************************************************/
static void etm_clr_pwrup(FAR struct coresight_etm_dev_s *etmdev)
{
coresight_modify32(0, ETM_PDCR_PWD_UP, etmdev->csdev.addr + ETM_PDCR);
}
/****************************************************************************
* Name: etm_timeout
*
* Description:
* Loop until a bitmask of register has changed to a specific value.
*
****************************************************************************/
static int etm_timeout(FAR struct coresight_etm_dev_s *etmdev,
uint32_t val, uint32_t mask, uint32_t off)
{
int i;
for (i = CONFIG_CORESIGHT_TIMEOUT; i > 0; i--)
{
uint32_t value = etm_read_reg(etmdev, off);
if ((value & mask) == val)
{
return 0;
}
up_udelay(1);
}
return -EAGAIN;
}
/****************************************************************************
* Name: etm_set_program
*
* Description:
* Set ETM Programming bit to disable all operations during programming.
* When programming the ETM registers you must enable all the changes at
* the same time.
*
****************************************************************************/
static void etm_set_program(FAR struct coresight_etm_dev_s *etmdev)
{
etm_modify_reg32(etmdev, ETM_CR_ETM_PRG, ETM_CR_ETM_PRG, ETM_CR);
if (etm_timeout(etmdev, ETM_SR_PROGRAM, ETM_SR_PROGRAM, ETM_SR) < 0)
{
cserr("timeout observed at setting ETM_SR_PROGRAM\n");
}
}
/****************************************************************************
* Name: etm_clr_program
****************************************************************************/
static void etm_clr_program(FAR struct coresight_etm_dev_s *etmdev)
{
etm_modify_reg32(etmdev, 0, ETM_CR_ETM_PRG, ETM_CR);
if (etm_timeout(etmdev, 0, ETM_SR_PROGRAM, ETM_SR) < 0)
{
cserr("timeout observed at clearing ETM_SR_PROGRAM\n");
}
}
/****************************************************************************
* Name: etm_init_arch_data
*
* Description:
* Get capabilities of current ETM architecture version.
*
****************************************************************************/
static void etm_init_arch_data(FAR struct coresight_etm_dev_s *etmdev)
{
uint32_t etmccr;
coresight_unlock(etmdev->csdev.addr);
etm_os_unlock(etmdev);
etm_clr_pwrdwn(etmdev);
etm_set_pwrup(etmdev);
etm_set_program(etmdev);
etmdev->arch = BMVAL(etm_read_reg(etmdev, ETM_IDR), 4, 11);
etmdev->port_size = etm_read_reg(etmdev, ETM_CR) & ETM_PORT_SIZE_MASK;
etmccr = etm_read_reg(etmdev, ETM_CCR);
etmdev->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
etmdev->nr_cntr = BMVAL(etmccr, 13, 15);
etmdev->nr_ext_inp = BMVAL(etmccr, 17, 19);
etmdev->nr_ext_out = BMVAL(etmccr, 20, 22);
etmdev->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
etm_clr_program(etmdev);
etm_clr_pwrup(etmdev);
etm_set_pwrdwn(etmdev);
coresight_lock(etmdev->csdev.addr);
}
/****************************************************************************
* Name: etm_arch_supported
*
* Description:
* If ETM/PTM implement is supported by current driver.
*
****************************************************************************/
static bool etm_arch_supported(uint8_t arch)
{
switch (arch)
{
case ETM_ARCH_V3_3:
case ETM_ARCH_V3_5:
case PFT_ARCH_V1_0:
case PFT_ARCH_V1_1:
return true;
default:
return false;
}
}
/****************************************************************************
* Name: etm_set_default
*
* Description:
* Setup default ETM config.
*
****************************************************************************/
void etm_set_default(struct etm_config_s *config)
{
int i;
/* Trace all memory, set according to spec */
config->enable_ctrl1 = BIT(24);
config->enable_ctrl2 = 0x0;
config->enable_event = ETM_HARD_WIRE_RES_A;
/* Disable all other event */
config->trigger_event = ETM_DEFAULT_EVENT_VAL;
config->seq_12_event = ETM_DEFAULT_EVENT_VAL;
config->seq_21_event = ETM_DEFAULT_EVENT_VAL;
config->seq_23_event = ETM_DEFAULT_EVENT_VAL;
config->seq_31_event = ETM_DEFAULT_EVENT_VAL;
config->seq_32_event = ETM_DEFAULT_EVENT_VAL;
config->seq_13_event = ETM_DEFAULT_EVENT_VAL;
config->timestamp_event = ETM_DEFAULT_EVENT_VAL;
for (i = 0; i < ETM_MAX_CNTR; i++)
{
config->cntr_event[i] = ETM_DEFAULT_EVENT_VAL;
config->cntr_rld_event[i] = ETM_DEFAULT_EVENT_VAL;
}
config->sync_freq = 0x400;
}
/****************************************************************************
* Name: etm_hw_enable
****************************************************************************/
static int etm_hw_enable(FAR struct coresight_etm_dev_s *etmdev)
{
FAR struct etm_config_s *config = &etmdev->cfg;
uint32_t etmcr;
int ret;
int i;
ret = coresight_claim_device(etmdev->csdev.addr);
if (ret < 0)
{
return ret;
}
coresight_unlock(etmdev->csdev.addr);
etm_os_unlock(etmdev);
etm_set_pwrup(etmdev);
etm_clr_pwrdwn(etmdev);
etm_set_program(etmdev);
etmcr = etm_read_reg(etmdev, ETM_CR);
etmcr &= ~ETM3X_SUPPORTED_OPTIONS;
etmcr |= ETM_CR_ETM_EN;
etm_write_reg(etmdev, config->ctrl | etmcr, ETM_CR);
etm_write_reg(etmdev, config->trigger_event, ETM_TRIGGER);
etm_write_reg(etmdev, config->startstop_ctrl, ETM_TSSCR);
etm_write_reg(etmdev, config->enable_event, ETM_TEEVR);
etm_write_reg(etmdev, config->enable_ctrl1, ETM_TECR1);
etm_write_reg(etmdev, config->fifofull_level, ETM_FFLR);
for (i = 0; i < etmdev->nr_addr_cmp; i++)
{
etm_write_reg(etmdev, config->addr_val[i], ETM_ACVR(i));
etm_write_reg(etmdev, config->addr_acctype[i], ETM_ACTR(i));
}
for (i = 0; i < etmdev->nr_cntr; i++)
{
etm_write_reg(etmdev, config->cntr_rld_val[i], ETM_CNTRLDVR(i));
etm_write_reg(etmdev, config->cntr_event[i], ETM_CNTENR(i));
etm_write_reg(etmdev, config->cntr_rld_event[i], ETM_CNTRLDEVR(i));
etm_write_reg(etmdev, config->cntr_val[i], ETM_CNTVR(i));
}
etm_write_reg(etmdev, config->seq_12_event, ETM_SQ12EVR);
etm_write_reg(etmdev, config->seq_21_event, ETM_SQ21EVR);
etm_write_reg(etmdev, config->seq_23_event, ETM_SQ23EVR);
etm_write_reg(etmdev, config->seq_31_event, ETM_SQ31EVR);
etm_write_reg(etmdev, config->seq_32_event, ETM_SQ32EVR);
etm_write_reg(etmdev, config->seq_13_event, ETM_SQ13EVR);
etm_write_reg(etmdev, config->seq_curr_state, ETM_SQR);
for (i = 0; i < etmdev->nr_ext_out; i++)
{
etm_write_reg(etmdev, ETM_DEFAULT_EVENT_VAL, ETM_EXTOUTEVR(i));
}
for (i = 0; i < etmdev->nr_ctxid_cmp; i++)
{
etm_write_reg(etmdev, config->ctxid_pid[i], ETM_CIDCVR(i));
}
etm_write_reg(etmdev, config->ctxid_mask, ETM_CIDCMR);
etm_write_reg(etmdev, config->sync_freq, ETM_SYNCFR);
/* No external input selected */
etm_write_reg(etmdev, 0x0, ETM_EXTINSELR);
etm_write_reg(etmdev, config->timestamp_event, ETM_TSEVR);
/* No auxiliary control selected */
etm_write_reg(etmdev, 0x0, ETM_AUXCR);
etm_write_reg(etmdev, etmdev->traceid, ETM_TRACEIDR);
/* No VMID comparator value selected */
etm_write_reg(etmdev, 0x0, ETM_VMIDCVR);
etm_clr_program(etmdev);
coresight_lock(etmdev->csdev.addr);
return ret;
}
/****************************************************************************
* Name: etm_hw_disable
****************************************************************************/
static void etm_hw_disable(FAR struct coresight_etm_dev_s *etmdev)
{
FAR struct etm_config_s *config = &etmdev->cfg;
int i;
coresight_unlock(etmdev->csdev.addr);
etm_set_program(etmdev);
/* Read back sequencer and counters for post trace analysis */
config->seq_curr_state = etm_read_reg(etmdev, ETM_SQR) & ETM_SQR_MASK;
for (i = 0; i < etmdev->nr_cntr; i++)
{
config->cntr_val[i] = etm_read_reg(etmdev, ETM_CNTVR(i));
}
etm_set_pwrdwn(etmdev);
coresight_lock(etmdev->csdev.addr);
coresight_disclaim_device(etmdev->csdev.addr);
}
/****************************************************************************
* Name: etm_enable
****************************************************************************/
static int etm_enable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_etm_dev_s *etmdev =
(FAR struct coresight_etm_dev_s *)csdev;
int ret = 0;
if (etmdev->refcnt++ == 0)
{
ret = etm_hw_enable(etmdev);
if (ret < 0)
{
etmdev->refcnt--;
cserr("%s enabled\n", csdev->name);
}
}
return ret;
}
/****************************************************************************
* Name: etm_enable
****************************************************************************/
static void etm_disable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_etm_dev_s *etmdev =
(FAR struct coresight_etm_dev_s *)csdev;
if (--etmdev->refcnt == 0)
{
etm_hw_disable(etmdev);
csinfo("etm %s disabled\n", csdev->name);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: etm_config
*
* Description:
* Configure the etm device.
*
* Input Parameters:
* etmdev - Pointer to the ETM device to config.
* config - Configuration need to be set to ETM device.
*
* Returned Value:
* Zero on success; a negative value on failure.
*
****************************************************************************/
int etm_config(FAR struct coresight_etm_dev_s *etmdev,
FAR const struct etm_config_s *config)
{
coresight_unlock(etmdev->csdev.addr);
etm_os_unlock(etmdev);
etm_clr_pwrdwn(etmdev);
etm_set_pwrup(etmdev);
etm_set_program(etmdev);
memcpy(&etmdev->cfg, config, sizeof(struct etm_config_s));
if ((etmdev->cfg.ctrl & ETM_CR_RETURN_STACK) &&
!(etm_read_reg(etmdev, ETM_CCER) & ETM_CCER_RETSTACK))
{
etmdev->cfg.ctrl &= ~ETM_CR_RETURN_STACK;
}
etm_clr_program(etmdev);
etm_clr_pwrup(etmdev);
etm_set_pwrdwn(etmdev);
coresight_lock(etmdev->csdev.addr);
return 0;
}
/****************************************************************************
* Name: etm_register
*
* Description:
* Register an ETM/PTM devices.
*
* Input Parameters:
* desc - A description of this coresight device.
*
* Returned Value:
* Pointer to an ETM device on success; NULL on failure.
*
****************************************************************************/
FAR struct coresight_etm_dev_s *
etm_register(FAR const struct coresight_desc_s *desc)
{
FAR struct coresight_etm_dev_s *etmdev;
FAR struct coresight_dev_s *csdev;
int ret;
etmdev = kmm_zalloc(sizeof(struct coresight_etm_dev_s));
if (etmdev == NULL)
{
cserr("%s:malloc failed!\n", desc->name);
return NULL;
}
etmdev->cpu = desc->cpu;
etmdev->csdev.addr = desc->addr;
etm_init_arch_data(etmdev);
if (!etm_arch_supported(etmdev->arch))
{
kmm_free(etmdev);
cserr("%s:current implement version is not supported\n", desc->name);
return NULL;
}
etmdev->traceid = coresight_get_cpu_trace_id(etmdev->cpu);
etm_set_default(&etmdev->cfg);
csdev = &etmdev->csdev;
csdev->ops = &g_etm_ops;
ret = coresight_register(csdev, desc);
if (ret < 0)
{
kmm_free(etmdev);
cserr("%s:register failed\n", desc->name);
return NULL;
}
return etmdev;
}
/****************************************************************************
* Name: etm_unregister
*
* Description:
* Unregister an EMT/PTM device.
*
****************************************************************************/
void etm_unregister(FAR struct coresight_etm_dev_s *etmdev)
{
coresight_unregister(&etmdev->csdev);
kmm_free(etmdev);
}

View File

@ -150,8 +150,8 @@ static void stm_hw_disable(FAR struct coresight_stm_dev_s *stmdev)
coresight_put32(0x0, stmdev->csdev.addr + STM_HEER);
coresight_put32(0x0, stmdev->csdev.addr + STM_HETER);
if (coresight_timeout(stmdev->csdev.addr, STM_TCSR,
STM_TCSR_BUSY, 0) < 0)
if (coresight_timeout(0x0, STM_TCSR_BUSY,
stmdev->csdev.addr + STM_TCSR) < 0)
{
cserr("timeout waiting for STM stopped\n");
}

View File

@ -107,25 +107,22 @@ static int tpiu_hw_enable(FAR struct coresight_tpiu_dev_s *tpiudev)
static void tpiu_hw_disable(FAR struct coresight_tpiu_dev_s *tpiudev)
{
uint32_t ffcr;
coresight_unlock(tpiudev->csdev.addr);
/* Trigger a formatter stop event. */
ffcr = coresight_get32(tpiudev->csdev.addr + TPIU_FFCR);
ffcr |= TPIU_FFCR_STOP_FI;
coresight_put32(ffcr, tpiudev->csdev.addr + TPIU_FFCR);
ffcr |= TPIU_FFCR_FON_MAN;
coresight_put32(ffcr, tpiudev->csdev.addr + TPIU_FFCR);
if (coresight_timeout(tpiudev->csdev.addr, TPIU_FFCR,
TPIU_FFCR_FON_MAN, 0) < 0)
coresight_modify32(TPIU_FFCR_STOP_FI, TPIU_FFCR_STOP_FI,
tpiudev->csdev.addr + TPIU_FFCR);
coresight_modify32(TPIU_FFCR_FON_MAN, TPIU_FFCR_FON_MAN,
tpiudev->csdev.addr + TPIU_FFCR);
if (coresight_timeout(0, TPIU_FFCR_FON_MAN,
tpiudev->csdev.addr + TPIU_FFCR) < 0)
{
cserr("timeout while waiting for completion of Manual Flush\n");
}
if (coresight_timeout(tpiudev->csdev.addr, TPIU_FFSR,
TPIU_FFSR_FT_STOPPED, TPIU_FFSR_FT_STOPPED) < 0)
if (coresight_timeout(TPIU_FFSR_FT_STOPPED, TPIU_FFSR_FT_STOPPED,
tpiudev->csdev.addr + TPIU_FFSR) < 0)
{
cserr("timeout while waiting for Formatter to Stop\n");
}

View File

@ -122,6 +122,10 @@ struct coresight_desc_s
enum coresight_dev_type_e type;
union coresight_dev_subtype_u subtype;
/* Used in ETM device. */
uint8_t cpu;
/* Used in funnel devices. */
int inport_num;

View File

@ -0,0 +1,139 @@
/****************************************************************************
* include/nuttx/coresight/coresight_etm.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_CORESIGHT_CORESIGHT_ETM_H
#define __INCLUDE_NUTTX_CORESIGHT_CORESIGHT_ETM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/coresight/coresight.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define ETM_MAX_ADDR_CMP 16
#define ETM_MAX_CNTR 4
#define ETM_MAX_CTXID_CMP 3
/****************************************************************************
* Public Types
****************************************************************************/
struct etm_config_s
{
uint32_t ctrl; /* ETMCR */
uint32_t trigger_event; /* ETMTRIGGER */
uint32_t startstop_ctrl; /* ETMTSSCR */
uint32_t enable_event; /* ETMTEEVR */
uint32_t enable_ctrl1; /* ETMTECR1 */
uint32_t enable_ctrl2; /* ETMTECR2 */
uint32_t fifofull_level; /* ETMFFLR */
uint8_t addr_idx; /* Index for the address comparator selection. */
uint32_t addr_val[ETM_MAX_ADDR_CMP]; /* Value for address comparator register. */
uint32_t addr_acctype[ETM_MAX_ADDR_CMP]; /* Access type for address comparator register. */
uint32_t addr_type[ETM_MAX_ADDR_CMP]; /* Current status of the comparator register. */
uint8_t cntr_idx; /* Index for the counter register selection */
uint32_t cntr_rld_val[ETM_MAX_CNTR]; /* Reload value of a counter register. */
uint32_t cntr_event[ETM_MAX_CNTR]; /* Control for counter enable register. */
uint32_t cntr_rld_event[ETM_MAX_CNTR]; /* Value for counter reload event register. */
uint32_t cntr_val[ETM_MAX_CNTR]; /* Counter value register. */
uint32_t seq_12_event; /* Event causing the transition from 1 to 2 */
uint32_t seq_21_event; /* Event causing the transition from 2 to 1 */
uint32_t seq_23_event; /* Event causing the transition from 2 to 3 */
uint32_t seq_31_event; /* Event causing the transition from 3 to 1 */
uint32_t seq_32_event; /* Event causing the transition from 3 to 2 */
uint32_t seq_13_event; /* Event causing the transition from 1 to 3 */
uint32_t seq_curr_state; /* Current value of the sequencer register. */
uint8_t ctxid_idx; /* Index for the context ID registers. */
uint32_t ctxid_pid[ETM_MAX_CTXID_CMP]; /* Value for the context ID to trigger on */
uint32_t ctxid_mask; /* Mask applicable to all the context IDs. */
uint32_t sync_freq; /* Synchronisation frequency. */
uint32_t timestamp_event; /* ETMTSEVR */
};
struct coresight_etm_dev_s
{
struct coresight_dev_s csdev;
struct etm_config_s cfg;
uint8_t refcnt;
int cpu; /* The cpu this component is affined to */
int port_size; /* Out port size */
int traceid; /* Trace id */
uint8_t arch; /* ETM/PTM version number */
uint8_t nr_addr_cmp; /* Number of pairs of address comparators */
uint8_t nr_cntr; /* Number of counters */
uint8_t nr_ext_inp; /* Number of external input */
uint8_t nr_ext_out; /* Number of external output */
uint8_t nr_ctxid_cmp; /* Number of contextID comparators */
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: etm_register
*
* Description:
* Register an ETM/PTM devices.
*
* Input Parameters:
* desc - A description of this coresight device.
*
* Returned Value:
* Pointer to an ETM device on success; NULL on failure.
*
****************************************************************************/
FAR struct coresight_etm_dev_s *
etm_register(FAR const struct coresight_desc_s *desc);
/****************************************************************************
* Name: etm_unregister
*
* Description:
* Unregister an EMT/PTM device.
*
****************************************************************************/
void etm_unregister(FAR struct coresight_etm_dev_s *etmdev);
/****************************************************************************
* Name: etm_config
*
* Description:
* Configure the etm device.
*
* Input Parameters:
* etmdev - Pointer to the ETM device to config.
* config - Configuration need to be set to ETM device.
*
* Returned Value:
* Zero on success; a negative value on failure.
*
****************************************************************************/
int etm_config(FAR struct coresight_etm_dev_s *etmdev,
FAR const struct etm_config_s *config);
#endif //__INCLUDE_NUTTX_CORESIGHT_CORESIGHT_ETM_H