[PATCH 4/5] lib: sbi: Extend hart protection abstraction to allow ID configuration

Anup Patel anup at brainfault.org
Mon Jul 20 03:49:10 PDT 2026


On Mon, Jul 20, 2026 at 3:40 PM Yu-Chien Peter Lin <peter.lin at sifive.com> wrote:
>
> Hi Anup and Raymond,
>
> On Fri, Jul 17, 2026 at 01:14:12PM +0530, Anup Patel wrote:
> > There are various ID configuration ISA extensions such as RISC-V Worlds,
> > Supervisor domain ID, QoS ID, etc which need to be re-configured upon
> > domain context switch on a hart. Extend hart protection abstraction to
> > support both memory protection and ID configuration ISA extensions.
>
> I will rework my "[RFC,00/12] Add RISC-V Worlds ISA support to OpenSBI"
> series based on this series.

Thanks Peter!

The RISC-V world DT property parsing can be done at the
time of parsing domains from FDT (like already done in this
series). The hart platform abstraction will be only for configuring
the RISC-V world CSRs.

May be you can add sbi_hart_worlds.c (just like sbi_hart_pmp.c) ?

For RISC-V world checkers, we can have separate FDT based driver
under lib/utils which will register sbi_domain_data instance upon probe
of each RISC-V world checker instance. The domain_setup() and
domain_cleanup() callbacks of the RISC-V worlds checker driver will
program the RISC-V world checker MMIO registers.

Regards,
Anup

>
> Thanks,
> Peter Lin
>
> >
> > Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
> > ---
> >  include/sbi/sbi_hart_protection.h | 16 +++++-
> >  lib/sbi/sbi_hart_pmp.c            |  2 +
> >  lib/sbi/sbi_hart_protection.c     | 94 ++++++++++++++++++++++++++-----
> >  lib/sbi/sbi_init.c                |  2 +-
> >  platform/generic/eswin/eic770x.c  |  1 +
> >  5 files changed, 98 insertions(+), 17 deletions(-)
> >
> > diff --git a/include/sbi/sbi_hart_protection.h b/include/sbi/sbi_hart_protection.h
> > index 5e170f05..1358b5be 100644
> > --- a/include/sbi/sbi_hart_protection.h
> > +++ b/include/sbi/sbi_hart_protection.h
> > @@ -13,6 +13,13 @@
> >  struct sbi_scratch;
> >  struct sbi_domain;
> >
> > +/** Different types of hart protection mechanisms */
> > +enum sbi_hart_protection_type {
> > +     SBI_HART_PROTECTION_TYPE_MEMORY = 0,
> > +     SBI_HART_PROTECTION_TYPE_ID,
> > +     SBI_HART_PROTECTIOn_TYPE_MAX
> > +};
> > +
> >  /** Representation of hart protection mechanism */
> >  struct sbi_hart_protection {
> >       /** List head */
> > @@ -21,6 +28,9 @@ struct sbi_hart_protection {
> >       /** Name of the hart protection mechanism */
> >       char name[32];
> >
> > +     /** Type of the hart protection mechanism */
> > +     enum sbi_hart_protection_type type;
> > +
> >       /** Ratings of the hart protection mechanism (higher is better) */
> >       unsigned long rating;
> >
> > @@ -40,11 +50,11 @@ struct sbi_hart_protection {
> >  };
> >
> >  /**
> > - * Get the best hart protection mechanism
> > + * Get the best hart memory protection mechanism
> >   *
> > - * @return pointer to best hart protection mechanism
> > + * @return pointer to best hart memory protection mechanism
> >   */
> > -struct sbi_hart_protection *sbi_hart_protection_best(void);
> > +struct sbi_hart_protection *sbi_hart_memory_protection_best(void);
> >
> >  /**
> >   * Register a hart protection mechanism
> > diff --git a/lib/sbi/sbi_hart_pmp.c b/lib/sbi/sbi_hart_pmp.c
> > index 5ede3cc1..c0a4ce1b 100644
> > --- a/lib/sbi/sbi_hart_pmp.c
> > +++ b/lib/sbi/sbi_hart_pmp.c
> > @@ -425,6 +425,7 @@ static void sbi_hart_pmp_unconfigure(struct sbi_scratch *scratch,
> >  static struct sbi_hart_protection pmp_protection = {
> >       .name = "pmp",
> >       .rating = 100,
> > +     .type = SBI_HART_PROTECTION_TYPE_MEMORY,
> >       .configure = sbi_hart_oldpmp_configure,
> >       .unconfigure = sbi_hart_pmp_unconfigure,
> >  };
> > @@ -432,6 +433,7 @@ static struct sbi_hart_protection pmp_protection = {
> >  static struct sbi_hart_protection epmp_protection = {
> >       .name = "epmp",
> >       .rating = 200,
> > +     .type = SBI_HART_PROTECTION_TYPE_MEMORY,
> >       .configure = sbi_hart_smepmp_configure,
> >       .unconfigure = sbi_hart_pmp_unconfigure,
> >       .map_range = sbi_hart_smepmp_map_range,
> > diff --git a/lib/sbi/sbi_hart_protection.c b/lib/sbi/sbi_hart_protection.c
> > index fecefde8..d31e9938 100644
> > --- a/lib/sbi/sbi_hart_protection.c
> > +++ b/lib/sbi/sbi_hart_protection.c
> > @@ -10,12 +10,16 @@
> >
> >  static SBI_LIST_HEAD(hart_protection_list);
> >
> > -struct sbi_hart_protection *sbi_hart_protection_best(void)
> > +struct sbi_hart_protection *sbi_hart_memory_protection_best(void)
> >  {
> > -     if (sbi_list_empty(&hart_protection_list))
> > -             return NULL;
> > +     struct sbi_hart_protection *pos;
> >
> > -     return sbi_list_first_entry(&hart_protection_list, struct sbi_hart_protection, head);
> > +     sbi_list_for_each_entry(pos, &hart_protection_list, head) {
> > +             if (pos->type == SBI_HART_PROTECTION_TYPE_MEMORY)
> > +                     return pos;
> > +     }
> > +
> > +     return NULL;
> >  }
> >
> >  int sbi_hart_protection_register(struct sbi_hart_protection *hprot)
> > @@ -74,33 +78,97 @@ static void __hart_protection_unconfigure(struct sbi_scratch *scratch,
> >  int sbi_hart_protection_configure(struct sbi_scratch *scratch,
> >                                 struct sbi_domain *dom)
> >  {
> > -     return __hart_protection_configure(scratch, sbi_hart_protection_best(), dom);
> > +     bool do_configure, memory_protect_done = false;
> > +     struct sbi_hart_protection *hprot;
> > +     int ret;
> > +
> > +     sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
> > +             do_configure = false;
> > +             switch (hprot->type) {
> > +             case SBI_HART_PROTECTION_TYPE_MEMORY:
> > +                     do_configure = !memory_protect_done;
> > +                     memory_protect_done = true;
> > +                     break;
> > +             case SBI_HART_PROTECTION_TYPE_ID:
> > +                     do_configure = true;
> > +                     break;
> > +             default:
> > +                     break;
> > +             }
> > +             if (!do_configure)
> > +                     continue;
> > +
> > +             ret = __hart_protection_configure(scratch, hprot, dom);
> > +             if (ret)
> > +                     return ret;
> > +     }
> > +
> > +     return 0;
> >  }
> >
> >  void sbi_hart_protection_unconfigure(struct sbi_scratch *scratch,
> >                                    struct sbi_domain *dom)
> >  {
> > -     __hart_protection_unconfigure(scratch, sbi_hart_protection_best(), dom);
> > +
> > +     bool do_unconfigure, memory_protect_done = false;
> > +     struct sbi_hart_protection *hprot;
> > +
> > +     sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
> > +             do_unconfigure = false;
> > +             switch (hprot->type) {
> > +             case SBI_HART_PROTECTION_TYPE_MEMORY:
> > +                     do_unconfigure = !memory_protect_done;
> > +                     memory_protect_done = true;
> > +                     break;
> > +             case SBI_HART_PROTECTION_TYPE_ID:
> > +                     do_unconfigure = true;
> > +                     break;
> > +             default:
> > +                     break;
> > +             }
> > +             if (!do_unconfigure)
> > +                     continue;
> > +
> > +             __hart_protection_unconfigure(scratch, hprot, dom);
> > +     }
> >  }
> >
> >  int sbi_hart_protection_reconfigure(struct sbi_scratch *scratch,
> >                                   struct sbi_domain *current_dom,
> >                                   struct sbi_domain *next_dom)
> >  {
> > -     struct sbi_hart_protection *hprot = sbi_hart_protection_best();
> > +     bool do_reconfigure, memory_protect_done = false;
> > +     struct sbi_hart_protection *hprot;
> >       int ret;
> >
> > -     __hart_protection_unconfigure(scratch, hprot, current_dom);
> > -     ret = __hart_protection_configure(scratch, hprot, next_dom);
> > -     if (ret)
> > -             return ret;
> > +     sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
> > +             do_reconfigure = false;
> > +             switch (hprot->type) {
> > +             case SBI_HART_PROTECTION_TYPE_MEMORY:
> > +                     do_reconfigure = !memory_protect_done;
> > +                     memory_protect_done = true;
> > +                     break;
> > +             case SBI_HART_PROTECTION_TYPE_ID:
> > +                     do_reconfigure = true;
> > +                     break;
> > +             default:
> > +                     break;
> > +             }
> > +             if (!do_reconfigure)
> > +                     continue;
> > +
> > +             __hart_protection_unconfigure(scratch, hprot, current_dom);
> > +             ret = __hart_protection_configure(scratch, hprot, next_dom);
> > +             if (ret)
> > +                     return ret;
> > +     }
> >
> >       return 0;
> >  }
> >
> >  int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
> >  {
> > -     struct sbi_hart_protection *hprot = sbi_hart_protection_best();
> > +     struct sbi_hart_protection *hprot = sbi_hart_memory_protection_best();
> >
> >       if (!hprot || !hprot->map_range)
> >               return 0;
> > @@ -110,7 +178,7 @@ int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
> >
> >  int sbi_hart_protection_unmap_range(unsigned long base, unsigned long size)
> >  {
> > -     struct sbi_hart_protection *hprot = sbi_hart_protection_best();
> > +     struct sbi_hart_protection *hprot = sbi_hart_memory_protection_best();
> >
> >       if (!hprot || !hprot->unmap_range)
> >               return 0;
> > diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
> > index d74dc67c..3f1f136a 100644
> > --- a/lib/sbi/sbi_init.c
> > +++ b/lib/sbi/sbi_init.c
> > @@ -93,7 +93,7 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
> >       sbi_printf("Platform Features           : %s\n", str);
> >       sbi_printf("Platform HART Count         : %u\n",
> >                  sbi_platform_hart_count(plat));
> > -     hprot = sbi_hart_protection_best();
> > +     hprot = sbi_hart_memory_protection_best();
> >       sbi_printf("Platform HART Protection    : %s\n",
> >                  (hprot) ? hprot->name : "---");
> >       idev = sbi_ipi_get_device();
> > diff --git a/platform/generic/eswin/eic770x.c b/platform/generic/eswin/eic770x.c
> > index da4d0e34..c71198a8 100644
> > --- a/platform/generic/eswin/eic770x.c
> > +++ b/platform/generic/eswin/eic770x.c
> > @@ -470,6 +470,7 @@ static void eswin_eic7700_pmp_unconfigure(struct sbi_scratch *scratch,
> >  static struct sbi_hart_protection eswin_eic7700_pmp_protection = {
> >       .name = "eic7700_pmp",
> >       .rating = -1UL,
> > +     .type = SBI_HART_PROTECTION_TYPE_MEMORY,
> >       .configure = eswin_eic7700_pmp_configure,
> >       .unconfigure = eswin_eic7700_pmp_unconfigure,
> >  };



More information about the opensbi mailing list