[PATCH v2 3/5] riscv: sifive: Add SiFive alternative ports

Anup Patel anup at brainfault.org
Mon Mar 22 06:08:16 GMT 2021


On Mon, Mar 22, 2021 at 11:10 AM Vincent Chen <vincent.chen at sifive.com> wrote:
>
> On Mon, Mar 22, 2021 at 8:26 AM Vincent Chen <vincent.chen at sifive.com> wrote:
> >
> > On Wed, Mar 17, 2021 at 7:43 PM Anup Patel <anup at brainfault.org> wrote:
> > >
> > > On Wed, Mar 17, 2021 at 3:04 PM Vincent Chen <vincent.chen at sifive.com> wrote:
> > > >
> > > > Add required ports of the Alternative scheme for SiFive.
> > > >
> > > > Signed-off-by: Vincent Chen <vincent.chen at sifive.com>
> > > > ---
> > > >  arch/riscv/Kconfig.erratas           | 11 ++++++
> > > >  arch/riscv/Kconfig.socs              |  1 +
> > > >  arch/riscv/errata/Makefile           |  1 +
> > > >  arch/riscv/errata/alternative.c      |  5 +++
> > > >  arch/riscv/errata/sifive/Makefile    |  1 +
> > > >  arch/riscv/errata/sifive/errata.c    | 68 ++++++++++++++++++++++++++++++++++++
> > > >  arch/riscv/include/asm/alternative.h |  3 ++
> > > >  7 files changed, 90 insertions(+)
> > > >  create mode 100644 arch/riscv/errata/sifive/Makefile
> > > >  create mode 100644 arch/riscv/errata/sifive/errata.c
> > > >
> > > > diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
> > > > index 4d0bafc536df..e50ab67f4830 100644
> > > > --- a/arch/riscv/Kconfig.erratas
> > > > +++ b/arch/riscv/Kconfig.erratas
> > > > @@ -9,4 +9,15 @@ config RISCV_ERRATA_ALTERNATIVE
> > > >           code patching is performed once in the boot stages. It means
> > > >           that the overhead from this mechanism is just taken once.
> > > >
> > > > +config ERRATA_SIFIVE
> > > > +       bool "SiFive errata"
> > > > +       depends on RISCV_ERRATA_ALTERNATIVE
> > > > +       default y
> > >
> > > Remove the "default y" here.
> > >
> > > Let the ERRATA Kconfig be explicitly selected from riscv/Kconfig.socs
> > >
> > This is a good suggestion. I will modify it in my next version patch.
> > Thank you,
> >
> Sorry, I found the "default y" may not be removed here. It is because
> SiFive's customers possibly only license our Core IP. In this case, it
> does not enable CONFIG_SOC_SIFIVE. Therefore, I prefer to keep the
> "default y" feature. (In this patch, I have made the CONFIG_SOC_SIFIVE
> select the CONFIG_SOC_SIFIVE )

If you are using SiFive IP for your <xyz> SOC then your
CONFIG_SOC_<xyz> in Kconfig option should select
ERRATA_SIFIVE

Basically, SOC Kconfig options should explicitly select required
ERRATA configs so that if someone wants to disable ERRATs from
menuconfig then it can be easily done without knowledge of which
SOCs need which ERRATAs.

Regards,
Anup

>
> > > > +       help
> > > > +         All SiFive errata Kconfig depend on this Kconfig. Disabling
> > > > +         this Kconfig will disable all SiFive errata. Please say "Y"
> > > > +         here if your platform uses SiFive CPU cores.
> > > > +
> > > > +         Otherwise, please say "N" here to avoid unnecessary overhead.
> > > > +
> > > >  endmenu
> > > > diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
> > > > index 7efcece8896c..b9eda857fc87 100644
> > > > --- a/arch/riscv/Kconfig.socs
> > > > +++ b/arch/riscv/Kconfig.socs
> > > > @@ -7,6 +7,7 @@ config SOC_SIFIVE
> > > >         select CLK_SIFIVE
> > > >         select CLK_SIFIVE_PRCI
> > > >         select SIFIVE_PLIC
> > > > +       select ERRATA_SIFIVE
> > > >         help
> > > >           This enables support for SiFive SoC platform hardware.
> > > >
> > > > diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
> > > > index 43e6d5424367..b8f8740a3e44 100644
> > > > --- a/arch/riscv/errata/Makefile
> > > > +++ b/arch/riscv/errata/Makefile
> > > > @@ -1 +1,2 @@
> > > >  obj-y  += alternative.o
> > > > +obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
> > > > diff --git a/arch/riscv/errata/alternative.c b/arch/riscv/errata/alternative.c
> > > > index 8efa60ad69b7..3b15885db70b 100644
> > > > --- a/arch/riscv/errata/alternative.c
> > > > +++ b/arch/riscv/errata/alternative.c
> > > > @@ -42,6 +42,11 @@ static void __init init_alternative(void)
> > > >         riscv_fill_cpu_mfr_info();
> > > >
> > > >         switch (cpu_mfr_info.vendor_id) {
> > > > +#ifdef CONFIG_ERRATA_SIFIVE
> > > > +       case SIFIVE_VENDOR_ID:
> > > > +               vendor_patch_func = sifive_errata_patch_func;
> > > > +               break;
> > > > +#endif
> > > >         default:
> > > >                 vendor_patch_func = NULL;
> > > >         }
> > > > diff --git a/arch/riscv/errata/sifive/Makefile b/arch/riscv/errata/sifive/Makefile
> > > > new file mode 100644
> > > > index 000000000000..2d644e19caef
> > > > --- /dev/null
> > > > +++ b/arch/riscv/errata/sifive/Makefile
> > > > @@ -0,0 +1 @@
> > > > +obj-y += errata.o
> > > > diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c
> > > > new file mode 100644
> > > > index 000000000000..826cd391fc55
> > > > --- /dev/null
> > > > +++ b/arch/riscv/errata/sifive/errata.c
> > > > @@ -0,0 +1,68 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > +/*
> > > > + * Copyright (C) 2021 Sifive.
> > > > + */
> > > > +
> > > > +#include <linux/kernel.h>
> > > > +#include <linux/string.h>
> > > > +#include <linux/bug.h>
> > > > +#include <asm/patch.h>
> > > > +#include <asm/alternative.h>
> > > > +#include <asm/vendorid_list.h>
> > > > +#include <asm/errata_list.h>
> > > > +
> > > > +struct errata_info_t {
> > > > +       char name[ERRATA_STRING_LENGTH_MAX];
> > > > +       bool (*check_func)(unsigned long  arch_id, unsigned long impid);
> > > > +};
> > > > +
> > > > +static u32 __init sifive_errata_probe(unsigned long archid, unsigned long impid)
> > > > +{
> > > > +       int idx;
> > > > +       u32 cpu_req_errata = 0;
> > > > +
> > > > +       for (idx = 0; idx < ERRATA_SIFIVE_NUMBER; idx++)
> > > > +               if (errata_list[idx].check_func(archid, impid))
> > > > +                       cpu_req_errata |= (1U << idx);
> > > > +
> > > > +       return cpu_req_errata;
> > > > +}
> > > > +
> > > > +static void __init warn_miss_errata(u32 miss_errata)
> > > > +{
> > > > +       int i;
> > > > +
> > > > +       pr_warn("----------------------------------------------------------------\n");
> > > > +       pr_warn("WARNING: Missing the following errata may cause potential issues\n");
> > > > +       for (i = 0; i < ERRATA_SIFIVE_NUMBER; i++)
> > > > +               if (miss_errata & 0x1 << i)
> > > > +                       pr_warn("\tSiFive Errata[%d]:%s\n", i, errata_list[i].name);
> > > > +       pr_warn("Please enable the corresponding Kconfig to apply them\n");
> > > > +       pr_warn("----------------------------------------------------------------\n");
> > > > +}
> > > > +
> > > > +void __init sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
> > > > +                                    unsigned long archid, unsigned long impid)
> > > > +{
> > > > +       struct alt_entry *alt;
> > > > +       u32 cpu_req_errata = sifive_errata_probe(archid, impid);
> > > > +       u32 cpu_apply_errata = 0;
> > > > +       u32 tmp;
> > > > +
> > > > +       for (alt = begin; alt < end; alt++) {
> > > > +               if (alt->vendor_id != SIFIVE_VENDOR_ID)
> > > > +                       continue;
> > > > +               if (alt->errata_id >= ERRATA_SIFIVE_NUMBER) {
> > > > +                       WARN(1, "This errata id:%d is not in kernel errata list", alt->errata_id);
> > > > +                       continue;
> > > > +               }
> > > > +
> > > > +               tmp = (1U << alt->errata_id);
> > > > +               if (cpu_req_errata & tmp) {
> > > > +                       patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
> > > > +                       cpu_apply_errata |= tmp;
> > > > +               }
> > > > +       }
> > > > +       if (cpu_apply_errata != cpu_req_errata)
> > > > +               warn_miss_errata(cpu_req_errata - cpu_apply_errata);
> > > > +}
> > > > diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
> > > > index 430bc4fea133..e625d3cafbed 100644
> > > > --- a/arch/riscv/include/asm/alternative.h
> > > > +++ b/arch/riscv/include/asm/alternative.h
> > > > @@ -32,5 +32,8 @@ struct errata_checkfunc_id {
> > > >         bool (*func)(struct alt_entry *alt);
> > > >  };
> > > >
> > > > +void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
> > > > +                             unsigned long archid, unsigned long impid);
> > > > +
> > > >  #endif
> > > >  #endif
> > > > --
> > > > 2.7.4
> > > >
> > > >
> > > > _______________________________________________
> > > > linux-riscv mailing list
> > > > linux-riscv at lists.infradead.org
> > > > http://lists.infradead.org/mailman/listinfo/linux-riscv
> > >
> > > Apart from the minor comment above, this patch looks good to me.
> > >
> > > Reviewed-by: Anup Patel <anup at brainfault.org>
> > >
> > > Regards,
> > > Anup



More information about the linux-riscv mailing list