coresight:add common api for coresight system
Signed-off-by: liaoao <liaoao@xiaomi.com>
This commit is contained in:
parent
24050ba59f
commit
8cc0c24318
@ -19,7 +19,7 @@
|
||||
# ##############################################################################
|
||||
|
||||
if(CONFIG_CORESIGHT)
|
||||
set(SRCS coresight_core.c)
|
||||
set(SRCS coresight_core.c coresight_common.c)
|
||||
|
||||
target_sources(drivers PRIVATE ${SRCS})
|
||||
endif()
|
||||
|
@ -15,4 +15,8 @@ config CORESIGHT_MAX_OUTPORT_NUM
|
||||
int "Max outport number of coresight device"
|
||||
default 2
|
||||
|
||||
config CORESIGHT_TIMEOUT
|
||||
int "Timeout us for waiting register state change"
|
||||
default 100
|
||||
|
||||
endif # CORESIGHT
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
ifeq ($(CONFIG_CORESIGHT),y)
|
||||
|
||||
CSRCS += coresight_core.c
|
||||
CSRCS += coresight_core.c coresight_common.c
|
||||
|
||||
DEPPATH += --dep-path coresight
|
||||
VPATH += :coresight
|
||||
|
313
drivers/coresight/coresight_common.c
Normal file
313
drivers/coresight/coresight_common.c
Normal file
@ -0,0 +1,313 @@
|
||||
/****************************************************************************
|
||||
* drivers/coresight/coresight_common.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 <string.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/bits.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "coresight_common.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define CORESIGHT_UNLOCK 0xc5acce55
|
||||
#define CORESIGHT_LOCK 0x0
|
||||
|
||||
#define CORESIGHT_CLAIM_SELF_HOSTED BIT(1)
|
||||
|
||||
#define CORESIGHT_SOURCE_BITMAP_SIZE 32
|
||||
|
||||
#define CORESIGHT_ETM_PMU_SEED 0x10
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static DECLARE_BITMAP(g_coresight_trace_id_bitmap,
|
||||
CORESIGHT_SOURCE_BITMAP_SIZE);
|
||||
static spinlock_t g_coresight_trace_id_lock = SP_UNLOCKED;
|
||||
|
||||
static const uint32_t g_coresight_barrier_pkt[4] =
|
||||
{
|
||||
0x7fffffff,
|
||||
0x7fffffff,
|
||||
0x7fffffff,
|
||||
0x7fffffff
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_lock
|
||||
*
|
||||
* Description:
|
||||
* To ensure that the software being debugged can never access an unlocked
|
||||
* CoreSight component, a software monitor that accesses debug registers
|
||||
* must unlock the component before accessing any registers, and lock the
|
||||
* component again before exiting the monitor.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_lock(uintptr_t addr)
|
||||
{
|
||||
coresight_put32(CORESIGHT_LOCK, addr + CORESIGHT_LAR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_unlock
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_unlock(uintptr_t addr)
|
||||
{
|
||||
coresight_put32(CORESIGHT_UNLOCK, addr + CORESIGHT_LAR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_claim_device
|
||||
*
|
||||
* Description:
|
||||
* Claim the device for self-hosted usage to prevent an external tool from
|
||||
* touching this device.Use Protocol 3: Set private bit and check for race.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_claim_device(uintptr_t addr)
|
||||
{
|
||||
int ret = -EBUSY;
|
||||
|
||||
coresight_unlock(addr);
|
||||
if (coresight_get32(addr + CORESIGHT_CLAIMCLR) != 0)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
coresight_put32(CORESIGHT_CLAIM_SELF_HOSTED, addr + CORESIGHT_CLAIMSET);
|
||||
if (coresight_get32(addr + CORESIGHT_CLAIMCLR) ==
|
||||
CORESIGHT_CLAIM_SELF_HOSTED)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There was a race setting the tags, clean up and fail */
|
||||
|
||||
coresight_put32(CORESIGHT_CLAIM_SELF_HOSTED,
|
||||
addr + CORESIGHT_CLAIMCLR);
|
||||
}
|
||||
|
||||
out:
|
||||
coresight_lock(addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_disclaim_device
|
||||
*
|
||||
* Description:
|
||||
* Disclaim the device, then an external tool can touch the device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_disclaim_device(uintptr_t addr)
|
||||
{
|
||||
coresight_unlock(addr);
|
||||
if (coresight_get32(addr + CORESIGHT_CLAIMCLR) ==
|
||||
CORESIGHT_CLAIM_SELF_HOSTED)
|
||||
{
|
||||
coresight_put32(CORESIGHT_CLAIM_SELF_HOSTED,
|
||||
addr + CORESIGHT_CLAIMCLR);
|
||||
}
|
||||
else
|
||||
{
|
||||
cserr("current device is not claimed or something wrong happend\n");
|
||||
}
|
||||
|
||||
coresight_lock(addr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_get_cpu_trace_id
|
||||
*
|
||||
* Description:
|
||||
* Used to get an unique trace id associated with cpu id of an ETM
|
||||
* coresight device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - CPU index to generate an unique trace id.
|
||||
*
|
||||
* Returned Value:
|
||||
* Unique trace id on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_get_cpu_trace_id(int cpu)
|
||||
{
|
||||
int traceid = CORESIGHT_ETM_PMU_SEED + cpu * 2;
|
||||
|
||||
if (traceid >= CORESIGHT_SOURCE_BITMAP_SIZE)
|
||||
{
|
||||
cserr("trace id is out of bounds\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return traceid;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_get_system_trace_id
|
||||
*
|
||||
* Description:
|
||||
* Used to get an unique trace id of a STM coresight device. The trace ID
|
||||
* value for *ETM* tracers start at CPU_ID * 2 + 0x10, and Trace ID 0x00
|
||||
* and anything equal to or higher than 0x70 is reserved.
|
||||
*
|
||||
* Returned Value:
|
||||
* Unique trace id on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_get_system_trace_id(void)
|
||||
{
|
||||
int max = CORESIGHT_SOURCE_BITMAP_SIZE / 2;
|
||||
irqstate_t flags;
|
||||
int traceid = 0;
|
||||
int i;
|
||||
|
||||
flags = spin_lock_irqsave(&g_coresight_trace_id_lock);
|
||||
for (i = 0; i < max - 1; i++)
|
||||
{
|
||||
if (test_bit(1 + 2 * i, g_coresight_trace_id_bitmap) == 0)
|
||||
{
|
||||
traceid = 1 + 2 * i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (traceid == 0)
|
||||
{
|
||||
cserr("get system trace id failed\n");
|
||||
spin_unlock_irqrestore(&g_coresight_trace_id_lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
__set_bit(traceid, g_coresight_trace_id_bitmap);
|
||||
spin_unlock_irqrestore(&g_coresight_trace_id_lock, flags);
|
||||
|
||||
return traceid;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_put_system_trace_id
|
||||
*
|
||||
* Description:
|
||||
* Release an allocated system trace ID.
|
||||
*
|
||||
* Input Parameters:
|
||||
* traceid - Traceid to be released.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_put_system_trace_id(int traceid)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&g_coresight_trace_id_lock);
|
||||
__clear_bit(traceid, g_coresight_trace_id_bitmap);
|
||||
spin_unlock_irqrestore(&g_coresight_trace_id_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_timeout
|
||||
*
|
||||
* Description:
|
||||
* Loop until a bitmask of register has changed to a specific value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
* off - Register offset of the coresight device.
|
||||
* bitmask - Bitmask to be checked.
|
||||
* val - Value to be matched.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_timeout(uintptr_t addr, uint32_t off,
|
||||
uint32_t bitmask, uint32_t val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = CONFIG_CORESIGHT_TIMEOUT; i > 0; i--)
|
||||
{
|
||||
uint32_t value = coresight_get32(addr + off);
|
||||
if ((value & bitmask) == val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
up_udelay(1);
|
||||
}
|
||||
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_insert_barrier_packet
|
||||
*
|
||||
* Description:
|
||||
* When losing synchronisation a new barrier packet needs to be inserted at
|
||||
* the beginning of the data collected in a buffer. That way the decoder
|
||||
* knows that it needs to look for another sync sequence.
|
||||
*
|
||||
* Input Parameters:
|
||||
* buf - buffer that a new barrier packet inserts to.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_insert_barrier_packet(FAR void *buf)
|
||||
{
|
||||
if (buf != NULL)
|
||||
{
|
||||
memcpy(buf, g_coresight_barrier_pkt, sizeof(g_coresight_barrier_pkt));
|
||||
}
|
||||
}
|
198
drivers/coresight/coresight_common.h
Normal file
198
drivers/coresight/coresight_common.h
Normal file
@ -0,0 +1,198 @@
|
||||
/****************************************************************************
|
||||
* drivers/coresight/coresight_common.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 __DRIVERS_CORESIGHT_CORESIGHT_COMMON_H
|
||||
#define __DRIVERS_CORESIGHT_CORESIGHT_COMMON_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Coresight registers
|
||||
* 0xF00 - 0xF9C: Management registers
|
||||
* 0xFA0 - 0xFA4: Management registers in PFTv1.0
|
||||
* Trace registers in PFTv1.1
|
||||
* 0xFA8 - 0xFFC: Management registers
|
||||
*/
|
||||
|
||||
#define CORESIGHT_ITCTRL 0xf00
|
||||
#define CORESIGHT_CLAIMSET 0xfa0
|
||||
#define CORESIGHT_CLAIMCLR 0xfa4
|
||||
#define CORESIGHT_LAR 0xfb0
|
||||
#define CORESIGHT_LSR 0xfb4
|
||||
#define CORESIGHT_DEVARCH 0xfbc
|
||||
#define CORESIGHT_AUTHSTATUS 0xfb8
|
||||
#define CORESIGHT_DEVID 0xfc8
|
||||
#define CORESIGHT_DEVTYPE 0xfcc
|
||||
|
||||
/* Register operations */
|
||||
|
||||
#define coresight_put8(val, addr) \
|
||||
(*(FAR volatile uint8_t *)(addr) = (val))
|
||||
#define coresight_put16(val, addr) \
|
||||
(*(FAR volatile uint16_t *)(addr) = (val))
|
||||
#define coresight_put32(val, addr) \
|
||||
(*(FAR volatile uint32_t *)(addr) = (val))
|
||||
#define coresight_get32(addr) \
|
||||
(*(FAR volatile uint32_t *)(addr))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_lock
|
||||
*
|
||||
* Description:
|
||||
* To ensure that the software being debugged can never access an unlocked
|
||||
* CoreSight component, a software monitor that accesses debug registers
|
||||
* must unlock the component before accessing any registers, and lock the
|
||||
* component again before exiting the monitor.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_lock(uintptr_t addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_unlock
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_unlock(uintptr_t addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_claim_device
|
||||
*
|
||||
* Description:
|
||||
* Claim the device for self-hosted usage to prevent an external tool from
|
||||
* touching this device.Use Protocol 3: Set private bit and check for race.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_claim_device(uintptr_t addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_disclaim_device
|
||||
*
|
||||
* Description:
|
||||
* Disclaim the device, then an external tool can touch the device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_disclaim_device(uintptr_t addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_get_cpu_trace_id
|
||||
*
|
||||
* Description:
|
||||
* Used to get an unique trace id associated with cpu id of an ETM
|
||||
* coresight device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - CPU index to generate an unique trace id.
|
||||
*
|
||||
* Returned Value:
|
||||
* Unique trace id on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_get_cpu_trace_id(int cpu);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_get_system_trace_id
|
||||
*
|
||||
* Description:
|
||||
* Used to get an unique trace id of a STM coresight device. The trace ID
|
||||
* value for *ETM* tracers start at CPU_ID * 2 + 0x10, and Trace ID 0x00
|
||||
* and anything equal to or higher than 0x70 is reserved.
|
||||
*
|
||||
* Returned Value:
|
||||
* Unique trace id on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_get_system_trace_id(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_put_system_trace_id
|
||||
*
|
||||
* Description:
|
||||
* Release an allocated system trace ID.
|
||||
*
|
||||
* Input Parameters:
|
||||
* traceid - Traceid to be released.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_put_system_trace_id(int traceid);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_timeout
|
||||
*
|
||||
* Description:
|
||||
* Loop until a bitmask of register has changed to a specific value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - Base addr of the coresight device.
|
||||
* off - Register offset of the coresight device.
|
||||
* bitmask - Bitmask to be checked.
|
||||
* val - Value to be matched.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negative value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int coresight_timeout(uintptr_t addr, uint32_t off,
|
||||
uint32_t bitmask, uint32_t val);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: coresight_insert_barrier_packet
|
||||
*
|
||||
* Description:
|
||||
* When losing synchronisation a new barrier packet needs to be inserted at
|
||||
* the beginning of the data collected in a buffer. That way the decoder
|
||||
* knows that it needs to look for another sync sequence.
|
||||
*
|
||||
* Input Parameters:
|
||||
* buf - buffer that a new barrier packet inserts to.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void coresight_insert_barrier_packet(FAR void *buf);
|
||||
|
||||
#endif /* __DRIVERS_CORESIGHT_CORESIGHT_COMMON_H */
|
@ -40,6 +40,10 @@
|
||||
# define BITS_PER_LONG (sizeof(unsigned long) * BITS_PER_BYTE)
|
||||
#endif
|
||||
|
||||
#ifndef BITS_TO_LONGS
|
||||
# define BITS_TO_LONGS(nr) (((nr) + BITS_PER_LONG - 1) / BITS_PER_LONG)
|
||||
#endif
|
||||
|
||||
#ifndef BITS_PER_LONG_LONG
|
||||
# define BITS_PER_LONG_LONG (sizeof(unsigned long long) * BITS_PER_BYTE)
|
||||
#endif
|
||||
@ -70,6 +74,25 @@
|
||||
#define GENMASK_ULL(h, l) \
|
||||
(BUILD_BUG_ON_ZERO((l) > (h)) + __GENMASK_ULL(h, l))
|
||||
|
||||
#define BMVAL(val, lsb, msb) (((val) & GENMASK(msb, lsb)) >> (lsb))
|
||||
|
||||
/* Bitmap operations */
|
||||
|
||||
#define DECLARE_BITMAP(name, bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
|
||||
#define __set_bit(nr, addr) \
|
||||
(*(((FAR unsigned long *)(addr)) + BIT_WORD(nr)) |= \
|
||||
BIT_WORD_MASK(nr))
|
||||
|
||||
#define __clear_bit(nr, addr) \
|
||||
(*(((FAR unsigned long *)(addr)) + BIT_WORD(nr)) &= \
|
||||
~BIT_WORD_MASK(nr))
|
||||
|
||||
#define test_bit(nr, addr) \
|
||||
(*(((FAR unsigned long *)(addr)) + BIT_WORD(nr)) & \
|
||||
BIT_WORD_MASK(nr))
|
||||
|
||||
/****************************************************************************
|
||||
* Type Definitions
|
||||
****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user