[PATCH v2 4/5] lib: sbi: Extend hart protection abstraction to allow ID configuration
Anup Patel <[email protected]> Mon, 27 Jul 2026 09:55:03 +0530
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <[email protected]> |
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. Signed-off-by: Anup Patel <[email protected]> --- include/sbi/sbi_hart_protection.h | 16 ++++- lib/sbi/sbi_hart_pmp.c | 2 + lib/sbi/sbi_hart_protection.c | 97 +++++++++++++++++++++++++++---- lib/sbi/sbi_init.c | 2 +- platform/generic/eswin/eic770x.c | 1 + 5 files changed, 103 insertions(+), 15 deletions(-) diff --git a/include/sbi/sbi_hart_protection.h b/include/sbi/sbi_hart_protection.h index 5e170f05..de5f2f89 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 36880a9c..d607ed74 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) @@ -25,6 +29,8 @@ int sbi_hart_protection_register(struct sbi_hart_protection *hprot) if (!hprot) return SBI_EINVAL; + if (hprot->type >= SBI_HART_PROTECTION_TYPE_MAX) + return SBI_EINVAL; sbi_list_for_each_entry(pos, &hart_protection_list, head) { if (hprot->rating > pos->rating) { @@ -74,28 +80,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; + + 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); - return __hart_protection_configure(scratch, hprot, next_dom); + __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; @@ -105,7 +180,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 02e26924..388f3ecb 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, }; -- 2.43.0 -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi