mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-07 22:03:14 +00:00
coresight: ete: Add support for ETE tracing
Add ETE as one of the supported device types we support with ETM4x driver. The devices are named following the existing convention as ete<N>. ETE mandates that the trace resource status register is programmed before the tracing is turned on. For the moment simply write to it indicating TraceActive. Cc: Mike Leach <mike.leach@linaro.org> Reviewed-by: Mike Leach <mike.leach@linaro.org> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20210405164307.1720226-14-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
This commit is contained in:
parent
3e666ad0f8
commit
35e1c9163e
@ -97,15 +97,15 @@ config CORESIGHT_SOURCE_ETM3X
|
||||
module will be called coresight-etm3x.
|
||||
|
||||
config CORESIGHT_SOURCE_ETM4X
|
||||
tristate "CoreSight Embedded Trace Macrocell 4.x driver"
|
||||
tristate "CoreSight ETMv4.x / ETE driver"
|
||||
depends on ARM64
|
||||
select CORESIGHT_LINKS_AND_SINKS
|
||||
select PID_IN_CONTEXTIDR
|
||||
help
|
||||
This driver provides support for the ETM4.x tracer module, tracing the
|
||||
instructions that a processor is executing. This is primarily useful
|
||||
for instruction level tracing. Depending on the implemented version
|
||||
data tracing may also be available.
|
||||
This driver provides support for the CoreSight Embedded Trace Macrocell
|
||||
version 4.x and the Embedded Trace Extensions (ETE). Both are CPU tracer
|
||||
modules, tracing the instructions that a processor is executing. This is
|
||||
primarily useful for instruction level tracing.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called coresight-etm4x.
|
||||
|
@ -433,6 +433,13 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
|
||||
etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR);
|
||||
}
|
||||
|
||||
/*
|
||||
* ETE mandates that the TRCRSR is written to before
|
||||
* enabling it.
|
||||
*/
|
||||
if (etm4x_is_ete(drvdata))
|
||||
etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR);
|
||||
|
||||
/* Enable the trace unit */
|
||||
etm4x_relaxed_write32(csa, 1, TRCPRGCTLR);
|
||||
|
||||
@ -894,13 +901,24 @@ static bool etm4_init_sysreg_access(struct etmv4_drvdata *drvdata,
|
||||
* ETMs implementing sysreg access must implement TRCDEVARCH.
|
||||
*/
|
||||
devarch = read_etm4x_sysreg_const_offset(TRCDEVARCH);
|
||||
if ((devarch & ETM_DEVARCH_ID_MASK) != ETM_DEVARCH_ETMv4x_ARCH)
|
||||
switch (devarch & ETM_DEVARCH_ID_MASK) {
|
||||
case ETM_DEVARCH_ETMv4x_ARCH:
|
||||
*csa = (struct csdev_access) {
|
||||
.io_mem = false,
|
||||
.read = etm4x_sysreg_read,
|
||||
.write = etm4x_sysreg_write,
|
||||
};
|
||||
break;
|
||||
case ETM_DEVARCH_ETE_ARCH:
|
||||
*csa = (struct csdev_access) {
|
||||
.io_mem = false,
|
||||
.read = ete_sysreg_read,
|
||||
.write = ete_sysreg_write,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
*csa = (struct csdev_access) {
|
||||
.io_mem = false,
|
||||
.read = etm4x_sysreg_read,
|
||||
.write = etm4x_sysreg_write,
|
||||
};
|
||||
}
|
||||
|
||||
drvdata->arch = etm_devarch_to_arch(devarch);
|
||||
return true;
|
||||
@ -1841,6 +1859,8 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
|
||||
struct etmv4_drvdata *drvdata;
|
||||
struct coresight_desc desc = { 0 };
|
||||
struct etm4_init_arg init_arg = { 0 };
|
||||
u8 major, minor;
|
||||
char *type_name;
|
||||
|
||||
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
@ -1867,10 +1887,6 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
|
||||
if (drvdata->cpu < 0)
|
||||
return drvdata->cpu;
|
||||
|
||||
desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu);
|
||||
if (!desc.name)
|
||||
return -ENOMEM;
|
||||
|
||||
init_arg.drvdata = drvdata;
|
||||
init_arg.csa = &desc.access;
|
||||
init_arg.pid = etm_pid;
|
||||
@ -1887,6 +1903,22 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
|
||||
fwnode_property_present(dev_fwnode(dev), "qcom,skip-power-up"))
|
||||
drvdata->skip_power_up = true;
|
||||
|
||||
major = ETM_ARCH_MAJOR_VERSION(drvdata->arch);
|
||||
minor = ETM_ARCH_MINOR_VERSION(drvdata->arch);
|
||||
|
||||
if (etm4x_is_ete(drvdata)) {
|
||||
type_name = "ete";
|
||||
/* ETE v1 has major version == 0b101. Adjust this for logging.*/
|
||||
major -= 4;
|
||||
} else {
|
||||
type_name = "etm";
|
||||
}
|
||||
|
||||
desc.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s%d", type_name, drvdata->cpu);
|
||||
if (!desc.name)
|
||||
return -ENOMEM;
|
||||
|
||||
etm4_init_trace_id(drvdata);
|
||||
etm4_set_default(&drvdata->config);
|
||||
|
||||
@ -1914,9 +1946,8 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
|
||||
|
||||
etmdrvdata[drvdata->cpu] = drvdata;
|
||||
|
||||
dev_info(&drvdata->csdev->dev, "CPU%d: ETM v%d.%d initialized\n",
|
||||
drvdata->cpu, ETM_ARCH_MAJOR_VERSION(drvdata->arch),
|
||||
ETM_ARCH_MINOR_VERSION(drvdata->arch));
|
||||
dev_info(&drvdata->csdev->dev, "CPU%d: %s v%d.%d initialized\n",
|
||||
drvdata->cpu, type_name, major, minor);
|
||||
|
||||
if (boot_enable) {
|
||||
coresight_enable(drvdata->csdev);
|
||||
@ -2059,6 +2090,7 @@ static struct amba_driver etm4x_amba_driver = {
|
||||
|
||||
static const struct of_device_id etm4_sysreg_match[] = {
|
||||
{ .compatible = "arm,coresight-etm4x-sysreg" },
|
||||
{ .compatible = "arm,embedded-trace-extension" },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -2374,12 +2374,20 @@ static inline bool
|
||||
etm4x_register_implemented(struct etmv4_drvdata *drvdata, u32 offset)
|
||||
{
|
||||
switch (offset) {
|
||||
ETM4x_SYSREG_LIST_CASES
|
||||
ETM_COMMON_SYSREG_LIST_CASES
|
||||
/*
|
||||
* Registers accessible via system instructions are always
|
||||
* implemented.
|
||||
* Common registers to ETE & ETM4x accessible via system
|
||||
* instructions are always implemented.
|
||||
*/
|
||||
return true;
|
||||
|
||||
ETM4x_ONLY_SYSREG_LIST_CASES
|
||||
/*
|
||||
* We only support etm4x and ete. So if the device is not
|
||||
* ETE, it must be ETMv4x.
|
||||
*/
|
||||
return !etm4x_is_ete(drvdata);
|
||||
|
||||
ETM4x_MMAP_LIST_CASES
|
||||
/*
|
||||
* Registers accessible only via memory-mapped registers
|
||||
@ -2389,8 +2397,13 @@ etm4x_register_implemented(struct etmv4_drvdata *drvdata, u32 offset)
|
||||
* coresight_register() and the csdev is not initialized
|
||||
* until that is done. So rely on the drvdata->base to
|
||||
* detect if we have a memory mapped access.
|
||||
* Also ETE doesn't implement memory mapped access, thus
|
||||
* it is sufficient to check that we are using mmio.
|
||||
*/
|
||||
return !!drvdata->base;
|
||||
|
||||
ETE_ONLY_SYSREG_LIST_CASES
|
||||
return etm4x_is_ete(drvdata);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -128,6 +128,8 @@
|
||||
#define TRCCIDR2 0xFF8
|
||||
#define TRCCIDR3 0xFFC
|
||||
|
||||
#define TRCRSR_TA BIT(12)
|
||||
|
||||
/*
|
||||
* System instructions to access ETM registers.
|
||||
* See ETMv4.4 spec ARM IHI0064F section 4.3.6 System instructions
|
||||
@ -591,11 +593,14 @@
|
||||
((ETM_DEVARCH_MAKE_ARCHID_ARCH_VER(major)) | ETM_DEVARCH_ARCHID_ARCH_PART(0xA13))
|
||||
|
||||
#define ETM_DEVARCH_ARCHID_ETMv4x ETM_DEVARCH_MAKE_ARCHID(0x4)
|
||||
#define ETM_DEVARCH_ARCHID_ETE ETM_DEVARCH_MAKE_ARCHID(0x5)
|
||||
|
||||
#define ETM_DEVARCH_ID_MASK \
|
||||
(ETM_DEVARCH_ARCHITECT_MASK | ETM_DEVARCH_ARCHID_MASK | ETM_DEVARCH_PRESENT)
|
||||
#define ETM_DEVARCH_ETMv4x_ARCH \
|
||||
(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETMv4x | ETM_DEVARCH_PRESENT)
|
||||
#define ETM_DEVARCH_ETE_ARCH \
|
||||
(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | ETM_DEVARCH_PRESENT)
|
||||
|
||||
#define TRCSTATR_IDLE_BIT 0
|
||||
#define TRCSTATR_PMSTABLE_BIT 1
|
||||
@ -685,6 +690,8 @@
|
||||
#define ETM_ARCH_MINOR_VERSION(arch) ((arch) & 0xfU)
|
||||
|
||||
#define ETM_ARCH_V4 ETM_ARCH_VERSION(4, 0)
|
||||
#define ETM_ARCH_ETE ETM_ARCH_VERSION(5, 0)
|
||||
|
||||
/* Interpretation of resource numbers change at ETM v4.3 architecture */
|
||||
#define ETM_ARCH_V4_3 ETM_ARCH_VERSION(4, 3)
|
||||
|
||||
@ -993,4 +1000,9 @@ void etm4_config_trace_mode(struct etmv4_config *config);
|
||||
|
||||
u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit);
|
||||
void etm4x_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit);
|
||||
|
||||
static inline bool etm4x_is_ete(struct etmv4_drvdata *drvdata)
|
||||
{
|
||||
return drvdata->arch >= ETM_ARCH_ETE;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user