Skip to content

Instantly share code, notes, and snippets.

@cyring
Last active May 9, 2024 18:57
Show Gist options
  • Save cyring/14556fc52e5bea5a564bdda5a0852f09 to your computer and use it in GitHub Desktop.
Save cyring/14556fc52e5bea5a564bdda5a0852f09 to your computer and use it in GitHub Desktop.
ARM PMU
Orange Pi 5+ (DTS)
@cyring
Copy link
Author

cyring commented Dec 30, 2023

static __cpuidle int psci_enter_idle_state(struct cpuidle_device *dev,
                                           struct cpuidle_driver *drv, int idx)
{
        u32 *state = __this_cpu_read(psci_cpuidle_data.psci_states);

        return CPU_PM_CPU_IDLE_ENTER_PARAM_RCU(psci_cpu_suspend_enter, idx, state[idx]);
}
int psci_cpu_suspend_enter(u32 state)
{
    if ( smc(PSCI_1_0_FN_PSCI_FEATURES /* = 0x84000000+10 */) & (0x1 << 1) ) {
        /* PSCI_1_0_EXT_POWER_STATE_TYPE_MASK (0x1 << 30) */

        psci_ops.cpu_suspend() -> cpu_suspend()
    }
    else
    {
        /* PSCI_0_2_POWER_STATE_TYPE_MASK (0x1 << 16) */

        cpu_suspend()
    }
}
cpu_suspend() -> __cpu_suspend_enter() -> " br	x8 " -> _cpu_resume -> cpu_do_resume

@cyring
Copy link
Author

cyring commented Dec 31, 2023

Comment on the disablement of PMU and AMU

#ifdef CONFIG_CPU_PM

SYM_FUNC_START(cpu_do_resume)

/*	reset_pmuserenr_el0 x0			** Disable PMU access from EL0 */
/*	reset_amuserenr_el0 x0			** Disable AMU access from EL0 */

	isb
	ret
SYM_FUNC_END(cpu_do_resume)
#endif
	.macro	reset_pmuserenr_el0, tmpreg
	mrs	\tmpreg, id_aa64dfr0_el1
	sbfx	\tmpreg, \tmpreg, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
	cmp	\tmpreg, #1			// Skip if no PMU present
	b.lt	9000f
	msr	pmuserenr_el0, xzr		// Disable PMU access from EL0
9000:
	.endm
	.macro	reset_amuserenr_el0, tmpreg
	mrs	\tmpreg, id_aa64pfr0_el1	// Check ID_AA64PFR0_EL1
	ubfx	\tmpreg, \tmpreg, #ID_AA64PFR0_EL1_AMU_SHIFT, #4
	cbz	\tmpreg, .Lskip_\@		// Skip if no AMU present
	msr_s	SYS_AMUSERENR_EL0, xzr		// Disable AMU access from EL0
.Lskip_\@:
	.endm

@cyring
Copy link
Author

cyring commented Dec 31, 2023

  • Disable CONFIG_ARM_PMUV3 w/ kernel 6
  • Disable CONFIG_ARM_PMU w/ kernel 5
  • Disable CONFIG_PERF_EVENTS
  • Disable CONFIG_KVM
  • drivers/perf/arm_pmuv3.c
static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
{
	armv8pmu_stop(cpu_pmu);

	armv8pmu_start(cpu_pmu);

	return IRQ_HANDLED;
}
armv8pmu_stop() -> armv8pmu_pmcr_write() -> write_pmcr() -> write_sysreg() -> __write_sysreg() -> pmcr_el0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment