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

Anup Patel anup.patel at oss.qualcomm.com
Sun Jul 26 21:25:03 PDT 2026


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 <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     | 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




More information about the opensbi mailing list