[PATCH v2 04/11] platform: andes: Add Andes custom PMU support

Anup Patel anup at brainfault.org
Wed Nov 15 22:41:59 PST 2023


On Thu, Oct 19, 2023 at 5:10 PM Yu Chien Peter Lin
<peterlin at andestech.com> wrote:
>
> Before the ratification of Sscofpmf, the Andes PMU extension
> was designed to support the sampling and filtering with hardware
> performance counters, it works with the current SBI PMU extension
> and Linux SBI PMU driver.
>
> This patch implements the PMU device callbacks that update the
> corresponding bits on custom CSRs.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin at andestech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang at andestech.com>

Looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Regards,
Anup

> ---
> Changes v1 -> v2:
>   - Fix mode filtering in andes_hw_counter_filter_mode()
>   - Return early if pmu is not supported in andes_pmu_init() (suggested by Prabhakar)
>   - Don't grant write permissions via CSR_MCOUNTERWEN as not needed
> ---
>  platform/generic/andes/Kconfig             |  4 ++
>  platform/generic/andes/andes_pmu.c         | 81 ++++++++++++++++++++++
>  platform/generic/andes/objects.mk          |  1 +
>  platform/generic/include/andes/andes_pmu.h |  8 +++
>  4 files changed, 94 insertions(+)
>  create mode 100644 platform/generic/andes/andes_pmu.c
>  create mode 100644 platform/generic/include/andes/andes_pmu.h
>
> diff --git a/platform/generic/andes/Kconfig b/platform/generic/andes/Kconfig
> index a91fb9c..555e4fe 100644
> --- a/platform/generic/andes/Kconfig
> +++ b/platform/generic/andes/Kconfig
> @@ -7,3 +7,7 @@ config ANDES45_PMA
>  config ANDES_SBI
>         bool "Andes SBI support"
>         default n
> +
> +config ANDES_PMU
> +       bool "Andes custom PMU extension support"
> +       default n
> diff --git a/platform/generic/andes/andes_pmu.c b/platform/generic/andes/andes_pmu.c
> new file mode 100644
> index 0000000..0f6ecc0
> --- /dev/null
> +++ b/platform/generic/andes/andes_pmu.c
> @@ -0,0 +1,81 @@
> +// SPDX-License-Identifier: BSD-2-Clause
> +/*
> + * Copyright (C) 2023 Andes Technology Corporation
> + */
> +#include <andes/andes45.h>
> +#include <andes/andes_pmu.h>
> +#include <sbi/riscv_asm.h>
> +#include <sbi/sbi_bitops.h>
> +#include <sbi/sbi_error.h>
> +#include <sbi/sbi_hart.h>
> +#include <sbi/sbi_pmu.h>
> +#include <sbi/sbi_scratch.h>
> +
> +static void andes_hw_counter_enable_irq(uint32_t ctr_idx)
> +{
> +       unsigned long mip_val;
> +
> +       if (ctr_idx >= SBI_PMU_HW_CTR_MAX)
> +               return;
> +
> +       mip_val = csr_read(CSR_MIP);
> +       if (!(mip_val & MIP_PMOVI))
> +               csr_clear(CSR_MCOUNTEROVF, BIT(ctr_idx));
> +
> +       csr_set(CSR_MCOUNTERINTEN, BIT(ctr_idx));
> +}
> +
> +static void andes_hw_counter_disable_irq(uint32_t ctr_idx)
> +{
> +       csr_clear(CSR_MCOUNTERINTEN, BIT(ctr_idx));
> +}
> +
> +static void andes_hw_counter_filter_mode(unsigned long flags, int ctr_idx)
> +{
> +       if (flags & SBI_PMU_CFG_FLAG_SET_UINH)
> +               csr_set(CSR_MCOUNTERMASK_U, BIT(ctr_idx));
> +       else
> +               csr_clear(CSR_MCOUNTERMASK_U, BIT(ctr_idx));
> +
> +       if (flags & SBI_PMU_CFG_FLAG_SET_SINH)
> +               csr_set(CSR_MCOUNTERMASK_S, BIT(ctr_idx));
> +       else
> +               csr_clear(CSR_MCOUNTERMASK_S, BIT(ctr_idx));
> +}
> +
> +static struct sbi_pmu_device andes_pmu = {
> +       .name = "andes_pmu",
> +       .hw_counter_enable_irq  = andes_hw_counter_enable_irq,
> +       .hw_counter_disable_irq = andes_hw_counter_disable_irq,
> +       /*
> +        * We set delegation of supervisor local interrupts via
> +        * 18th bit on mslideleg instead of mideleg, so leave
> +        * hw_counter_irq_bit() callback unimplemented.
> +        */
> +       .hw_counter_irq_bit     = NULL,
> +       .hw_counter_filter_mode = andes_hw_counter_filter_mode
> +};
> +
> +int andes_pmu_init(void)
> +{
> +       if (!has_andes_pmu())
> +               return SBI_ENOTSUPP;
> +
> +       /*
> +        * It is not reasonable for an Andes CPU to support
> +        * both Andes PMU and standard Sscofpmf, as they
> +        * serve the same purpose.
> +        */
> +       if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
> +                                  SBI_HART_EXT_SSCOFPMF))
> +               sbi_hart_hang();
> +
> +       /* Inhibit HPM counter in M-mode */
> +       csr_write(CSR_MCOUNTERMASK_M, 0xfffffffd);
> +       /* Delegate S-mode local interrupt to S-mode */
> +       csr_write(CSR_MSLIDELEG, MIP_PMOVI);
> +
> +       sbi_pmu_set_device(&andes_pmu);
> +
> +       return 0;
> +}
> diff --git a/platform/generic/andes/objects.mk b/platform/generic/andes/objects.mk
> index e8f86ea..6a8c66c 100644
> --- a/platform/generic/andes/objects.mk
> +++ b/platform/generic/andes/objects.mk
> @@ -7,3 +7,4 @@ platform-objs-$(CONFIG_PLATFORM_ANDES_AE350) += andes/ae350.o andes/sleep.o
>
>  platform-objs-$(CONFIG_ANDES45_PMA) += andes/andes45-pma.o
>  platform-objs-$(CONFIG_ANDES_SBI) += andes/andes_sbi.o
> +platform-objs-$(CONFIG_ANDES_PMU) += andes/andes_pmu.o
> diff --git a/platform/generic/include/andes/andes_pmu.h b/platform/generic/include/andes/andes_pmu.h
> new file mode 100644
> index 0000000..70b3a12
> --- /dev/null
> +++ b/platform/generic/include/andes/andes_pmu.h
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: BSD-2-Clause
> +
> +#ifndef _RISCV_ANDES_PMU_H
> +#define _RISCV_ANDES_PMU_H
> +
> +int andes_pmu_init(void);
> +
> +#endif /* _RISCV_ANDES_PMU_H */
> --
> 2.34.1
>



More information about the opensbi mailing list