[PATCH 2/2] platform: add thead-c9xx specific platform-overrides

Xiang W wxjstz at 126.com
Fri Apr 1 04:12:59 PDT 2022


在 2022-04-01星期五的 03:08 +0200,Heiko Stuebner写道:
> From: Guo Ren <guoren at linux.alibaba.com>
> 
> The PMU on T-Head C9xx SoCs works differently with additional
> CSRs and needs additional vendor ecalls to function correctly
> both for initializing and mapping events to counters.
> 
> Add a fdt-matched T-Head platform for this and
> disable the SBI PMU extension for it.
> 
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>  lib/sbi/sbi_ecall_pmu.c       |  7 +++
>  platform/generic/objects.mk   |  1 +
>  platform/generic/platform.c   |  2 +
>  platform/generic/thead_c9xx.c | 91
> +++++++++++++++++++++++++++++++++++
>  4 files changed, 101 insertions(+)
>  create mode 100644 platform/generic/thead_c9xx.c
> 
> diff --git a/lib/sbi/sbi_ecall_pmu.c b/lib/sbi/sbi_ecall_pmu.c
> index 9ee9e81..5f6f7c9 100644
> --- a/lib/sbi/sbi_ecall_pmu.c
> +++ b/lib/sbi/sbi_ecall_pmu.c
> @@ -76,6 +76,13 @@ static int sbi_ecall_pmu_probe(unsigned long extid,
> unsigned long *out_val)
>  {
>         /* PMU extension is always enabled */
>         *out_val = 1;
> +
> +       /* Some T-Head socs have a non-spec PMU */
> +       if (csr_read(CSR_MVENDORID) == 0x5b7 &&
> +           csr_read(CSR_MARCHID) == 0 &&
> +           csr_read(CSR_MIMPID) == 0)
> +               *out_val = 0;
> +
>         return 0;
>  }
>  
> diff --git a/platform/generic/objects.mk b/platform/generic/objects.mk
> index cb15a18..0d6c228 100644
> --- a/platform/generic/objects.mk
> +++ b/platform/generic/objects.mk
> @@ -10,3 +10,4 @@
>  platform-objs-y += platform.o
>  platform-objs-y += sifive_fu540.o
>  platform-objs-y += sifive_fu740.o
> +platform-objs-y += thead_c9xx.o
> diff --git a/platform/generic/platform.c b/platform/generic/platform.c
> index f05da8e..1a797dc 100644
> --- a/platform/generic/platform.c
> +++ b/platform/generic/platform.c
> @@ -25,10 +25,12 @@
>  
>  extern const struct platform_override sifive_fu540;
>  extern const struct platform_override sifive_fu740;
> +extern const struct platform_override thead_c9xx;
>  
>  static const struct platform_override *special_platforms[] = {
>         &sifive_fu540,
>         &sifive_fu740,
> +       &thead_c9xx,
>  };
>  
>  static const struct platform_override *generic_plat = NULL;
> diff --git a/platform/generic/thead_c9xx.c
> b/platform/generic/thead_c9xx.c
> new file mode 100644
> index 0000000..782d4e7
> --- /dev/null
> +++ b/platform/generic/thead_c9xx.c
> @@ -0,0 +1,91 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2022 Heiko Stuebner <heiko at sntech.de>
> + *
> + * Authors:
> + *   Heiko Stuebner <heiko at sntech.de>
> + */
> +
> +#include <platform_override.h>
> +#include <sbi/sbi_const.h>
> +#include <sbi/sbi_trap.h>
> +#include <sbi_utils/fdt/fdt_helper.h>
> +#include <sbi_utils/fdt/fdt_fixup.h>
> +
> +enum sbi_ext_thead_fid {
> +       SBI_EXT_THEAD_PMU_INIT = 0,
> +       SBI_EXT_THEAD_PMU_MAP,
> +};
> +
> +#define CSR_MCOUNTERWEN        0x7c9
> +
> +static void thead_c9xx_pmu_init(void)
> +{
> +       unsigned long interrupts;
> +
> +       interrupts = csr_read(CSR_MIDELEG) | (1 << 17);
> +       csr_write(CSR_MIDELEG, interrupts);
> +
> +       /* CSR_MCOUNTEREN has already been set in mstatus_init() */
> +       csr_write(CSR_MCOUNTERWEN, 0xffffffff);
> +       csr_write(CSR_MHPMEVENT3, 1);
> +       csr_write(CSR_MHPMEVENT4, 2);
> +       csr_write(CSR_MHPMEVENT5, 3);
> +       csr_write(CSR_MHPMEVENT6, 4);
> +       csr_write(CSR_MHPMEVENT7, 5);
> +       csr_write(CSR_MHPMEVENT8, 6);
> +       csr_write(CSR_MHPMEVENT9, 7);
> +       csr_write(CSR_MHPMEVENT10, 8);
> +       csr_write(CSR_MHPMEVENT11, 9);
> +       csr_write(CSR_MHPMEVENT12, 10);
> +       csr_write(CSR_MHPMEVENT13, 11);
> +       csr_write(CSR_MHPMEVENT14, 12);
> +       csr_write(CSR_MHPMEVENT15, 13);
> +       csr_write(CSR_MHPMEVENT16, 14);
> +       csr_write(CSR_MHPMEVENT17, 15);
> +       csr_write(CSR_MHPMEVENT18, 16);
> +       csr_write(CSR_MHPMEVENT19, 17);
> +       csr_write(CSR_MHPMEVENT20, 18);
> +       csr_write(CSR_MHPMEVENT21, 19);
> +       csr_write(CSR_MHPMEVENT22, 20);
> +       csr_write(CSR_MHPMEVENT23, 21);
> +       csr_write(CSR_MHPMEVENT24, 22);
> +       csr_write(CSR_MHPMEVENT25, 23);
> +       csr_write(CSR_MHPMEVENT26, 24);
> +       csr_write(CSR_MHPMEVENT27, 25);
> +       csr_write(CSR_MHPMEVENT28, 26);
> +}
> +
> +static void thead_c9xx_pmu_map(unsigned long idx, unsigned long
> event_id)
> +{
> +       if (idx >= 3 && idx <= 31)
> +               csr_write_num(CSR_MHPMEVENT3 + idx - 3, event_id);
> +}
> +
> +#include <sbi/sbi_console.h>
> +static int thead_c9xx_vendor_ext_provider(long extid, long funcid,
> +                                         const struct sbi_trap_regs
> *regs,
> +                                         unsigned long *out_value,
> +                                         struct sbi_trap_info
> *out_trap)
> +{
No need to check extid?

Regards,
Xiang W
> +       switch (funcid) {
> +       case SBI_EXT_THEAD_PMU_MAP:
> +               thead_c9xx_pmu_map(regs->a0, regs->a1);
> +               break;
> +       case SBI_EXT_THEAD_PMU_INIT:
> +               thead_c9xx_pmu_init();
> +               break;
> +       }
> +       return 0;
> +}
> +
> +static const struct fdt_match thead_c9xx_match[] = {
> +       { .compatible = "allwinner,sun20i-d1" },
> +       { },
> +};
> +
> +const struct platform_override thead_c9xx = {
> +       .match_table = thead_c9xx_match,
> +       .vendor_ext_provider = thead_c9xx_vendor_ext_provider,
> +};
> -- 
> 2.35.1
> 
> 





More information about the opensbi mailing list