mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
arch/arm64: Supports cluster PMU
Summary: Some processors implement cluster PMUs, such as Cortex-R82. Signed-off-by: wangming9 <wangming9@xiaomi.com>
This commit is contained in:
@@ -156,6 +156,19 @@ config ARCH_HAVE_EL3
|
||||
runing at EL3 is not necessary and system register for EL3
|
||||
is not accessible
|
||||
|
||||
config ARCH_HAVE_CLUSTER_PMU
|
||||
bool
|
||||
default n
|
||||
---help---
|
||||
Some processors implement cluster PMUs, such as Cortex-R82
|
||||
|
||||
config ARCH_CLUSTER_PMU
|
||||
bool "Enable the cluster PMUs"
|
||||
default n
|
||||
depends on ARCH_HAVE_CLUSTER_PMU
|
||||
---help---
|
||||
If the processor supports cluster PMU, can configure cluster PMU
|
||||
|
||||
config ARCH_ARM64_EXCEPTION_LEVEL
|
||||
int "Exception level to operate"
|
||||
default 1
|
||||
@@ -253,6 +266,7 @@ config ARCH_CORTEX_R82
|
||||
select ARCH_ICACHE
|
||||
select ARCH_HAVE_MPU
|
||||
select ARCH_HAVE_FPU
|
||||
select ARCH_HAVE_CLUSTER_PMU
|
||||
select ARCH_HAVE_TESTSET
|
||||
select ARM64_HAVE_NEON
|
||||
|
||||
|
||||
@@ -96,6 +96,17 @@
|
||||
#define SCTLR_SA_BIT BIT(3)
|
||||
#define SCTLR_I_BIT BIT(12)
|
||||
|
||||
#define ACTLR_AUX_BIT BIT(9)
|
||||
#define ACTLR_CLPORTS_BIT BIT(8)
|
||||
#define ACTLR_CLPMU_BIT BIT(7)
|
||||
#define ACTLR_TESTR1_BIT BIT(6)
|
||||
#define ACTLR_CDBG_BIT BIT(5)
|
||||
#define ACTLR_PATCH_BIT BIT(4)
|
||||
#define ACTLR_BPRED_BIT BIT(3)
|
||||
#define ACTLR_POWER_BIT BIT(2)
|
||||
#define ACTLR_DIAGNOSTIC_BIT BIT(1)
|
||||
#define ACTLR_REGIONS_BIT BIT(0)
|
||||
|
||||
/* SPSR M[3:0] define
|
||||
*
|
||||
* Arm® Architecture Registers Armv8, for Armv8-A architecture profile
|
||||
|
||||
@@ -129,6 +129,12 @@ void arm64_boot_el2_init(void)
|
||||
SCTLR_SA_BIT); /* Enable SP alignment check */
|
||||
write_sysreg(reg, sctlr_el2);
|
||||
|
||||
#ifdef CONFIG_ARCH_CLUSTER_PMU
|
||||
reg = read_sysreg(actlr_el2);
|
||||
reg |= ACTLR_CLPMU_BIT;
|
||||
write_sysreg(reg, actlr_el2);
|
||||
#endif
|
||||
|
||||
reg = read_sysreg(hcr_el2);
|
||||
reg |= HCR_RW_BIT; /* EL1 Execution state is AArch64 */
|
||||
write_sysreg(reg, hcr_el2);
|
||||
|
||||
@@ -42,11 +42,19 @@ void up_perf_init(void *arg)
|
||||
{
|
||||
g_cpu_freq = (unsigned long)(uintptr_t)arg;
|
||||
|
||||
#ifdef CONFIG_ARCH_CLUSTER_PMU
|
||||
pmu_clucntr_control_config(CLUSTERPMCR_EL1_C | CLUSTERPMCR_EL1_P |
|
||||
CLUSTERPMCR_EL1_E);
|
||||
pmu_clucntr_ovsclr_config(CLUSTERPMOVSCLR_EL1_C);
|
||||
pmu_clucntr_irq_disable(CLUSTERPMINTENCLR_EL1_C);
|
||||
pmu_clucntr_enable(CLUSTERPMCNTENSET_EL1_C);
|
||||
#else
|
||||
pmu_ccntr_ccfiltr_config(PMCCFILTR_EL0_NSH);
|
||||
pmu_cntr_control_config(PMCR_EL0_C | PMCR_EL0_E);
|
||||
pmu_cntr_trap_control(PMUSERENR_EL0_EN);
|
||||
pmu_cntr_irq_disable(PMINTENCLR_EL1_C);
|
||||
pmu_cntr_enable(PMCNTENSET_EL0_C);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long up_perf_getfreq(void)
|
||||
@@ -56,7 +64,11 @@ unsigned long up_perf_getfreq(void)
|
||||
|
||||
unsigned long up_perf_gettime(void)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_CLUSTER_PMU
|
||||
return pmu_get_cluccntr();
|
||||
#else
|
||||
return pmu_get_ccntr();
|
||||
#endif
|
||||
}
|
||||
|
||||
void up_perf_convert(unsigned long elapsed, struct timespec *ts)
|
||||
|
||||
@@ -85,6 +85,41 @@
|
||||
#define PMUSERENR_EL0_SW (1ul << 1) /* Software Increment write trap control */
|
||||
#define PMUSERENR_EL0_EN (1ul << 0) /* Software can access all PMU registers at EL0 */
|
||||
|
||||
#ifdef CONFIG_ARCH_CLUSTER_PMU
|
||||
|
||||
/* The CORTEX-R82 processor implements the cluster PMU */
|
||||
|
||||
/* CLUSTERPMCR_EL1 */
|
||||
|
||||
#define CLUSTERPMCR_EL1_X (1ul << 4) /* Enable export of events */
|
||||
#define CLUSTERPMCR_EL1_C (1ul << 2) /* Cycle counter reset */
|
||||
#define CLUSTERPMCR_EL1_P (1ul << 1) /* Event counter reset */
|
||||
#define CLUSTERPMCR_EL1_E (1ul << 0) /* All counters that are accessible at Non-secure EL1 are enabled by PMCNTENSET_EL0 */
|
||||
|
||||
/* CLUSTERPMCNTENSET_EL1 */
|
||||
|
||||
#define CLUSTERPMCNTENSET_EL1_C (1ul << 31) /* Enables the cycle counter register */
|
||||
|
||||
/* CLUSTERPMOVSCLR_EL1 */
|
||||
|
||||
#define CLUSTERPMOVSCLR_EL1_C (1ul << 31) /* CLUSTERPMCCNTR_EL0 overflow bit */
|
||||
|
||||
/* CLUSTERPMSELR_EL1 */
|
||||
|
||||
#define CLUSTERPMSELR_EL1_SEL_C (0x1ful << 0) /* When CLUSTERPMSELR_EL0.SEL is 0b11111, it selects the cycle counter */
|
||||
|
||||
/* CLUSTERPMINTENCLR_EL1 */
|
||||
|
||||
#define CLUSTERPMINTENCLR_EL1_C (1ul << 31) /* CLUSTERPMCCNTR_EL0 overflow interrupt request disable bit */
|
||||
|
||||
#define clusterpmcr_el1 s3_0_c15_c5_0
|
||||
#define clusterpmcntenset_el1 s3_0_c15_c5_1
|
||||
#define clusterpmovsclr_el1 s3_0_c15_c5_4
|
||||
#define clusterpmintenclr_el1 s3_0_c15_c5_7
|
||||
#define clusterpmccntr_el1 s3_0_c15_c6_0
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
@@ -232,4 +267,162 @@ static inline void pmu_cntr_irq_disable(uint64_t mask)
|
||||
write_sysreg(mask, pmintenclr_el1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_CLUSTER_PMU
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_get_cluccntr
|
||||
*
|
||||
* Description:
|
||||
* Read cluster cycle counter.
|
||||
*
|
||||
* Return Value:
|
||||
* Cycle count.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint64_t pmu_get_cluccntr(void)
|
||||
{
|
||||
return read_sysreg(clusterpmccntr_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_cntr_control_config
|
||||
*
|
||||
* Description:
|
||||
* Config counters.
|
||||
*
|
||||
* Parameters:
|
||||
* mask - Configuration flags for counters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pmu_clucntr_control_config(uint64_t mask)
|
||||
{
|
||||
write_sysreg(mask, clusterpmcr_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_clucntr_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable counters.
|
||||
*
|
||||
* Parameters:
|
||||
* mask - Counters to enable.
|
||||
*
|
||||
* Note:
|
||||
* Enables one or more of the following:
|
||||
* event counters (0-30)
|
||||
* cycle counter
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pmu_clucntr_enable(uint64_t mask)
|
||||
{
|
||||
write_sysreg(mask, clusterpmcntenset_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_clucntr_ovsclr_config
|
||||
*
|
||||
* Description:
|
||||
* Clear counter overflow bits.
|
||||
*
|
||||
* Parameters:
|
||||
* mask - Corresponds to the counter overflow bit to clear.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pmu_clucntr_ovsclr_config(uint64_t mask)
|
||||
{
|
||||
write_sysreg(mask, clusterpmovsclr_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_clucntr_select
|
||||
*
|
||||
* Description:
|
||||
* Selects the current event counter or the cycle counter.
|
||||
*
|
||||
* Parameters:
|
||||
* mask - Select counter flag.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pmu_clucntr_select(uint64_t mask)
|
||||
{
|
||||
write_sysreg(mask, clusterpmselr_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_clucntr_irq_disable
|
||||
*
|
||||
* Description:
|
||||
* Disable counter overflow interrupt request.
|
||||
*
|
||||
* Parameters:
|
||||
* mask - Counter overflow interrupt request bits to clear.
|
||||
*
|
||||
* Note:
|
||||
* Sets overflow interrupt request bits for one or more of the following:
|
||||
* event counters (0-30)
|
||||
* cycle counter
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pmu_clucntr_irq_disable(uint64_t mask)
|
||||
{
|
||||
write_sysreg(mask, clusterpmintenclr_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_clucntr_get_xevtyper
|
||||
*
|
||||
* Description:
|
||||
* Gets the selected counter type.
|
||||
*
|
||||
* Return Value:
|
||||
* Select the value of the counter type.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint64_t pmu_clucntr_get_xevtyper(void)
|
||||
{
|
||||
return read_sysreg(clusterpmxevtyper_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_clucntr_set_xevtyper
|
||||
*
|
||||
* Description:
|
||||
* Sets the selected counter type.
|
||||
*
|
||||
* Parameters:
|
||||
* mask - The value of the type counter.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pmu_clucntr_set_xevtyper(uint64_t mask)
|
||||
{
|
||||
write_sysreg(mask, clusterpmxevtyper_el1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmu_clucntr_get_xevcntr
|
||||
*
|
||||
* Description:
|
||||
* Reads the value of the selected counter.
|
||||
*
|
||||
* Return Value:
|
||||
* Select the value of the counter.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint64_t pmu_clucntr_get_xevcntr(void)
|
||||
{
|
||||
return read_sysreg(clusterpmxevcntr_el1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM64_SRC_COMMON_ARM64_PMU_H */
|
||||
|
||||
Reference in New Issue
Block a user