summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sbi/sbi_hart_protection.h100
-rw-r--r--lib/sbi/objects.mk1
-rw-r--r--lib/sbi/sbi_hart_protection.c96
-rw-r--r--lib/sbi/sbi_init.c5
4 files changed, 202 insertions, 0 deletions
diff --git a/include/sbi/sbi_hart_protection.h b/include/sbi/sbi_hart_protection.h
new file mode 100644
index 00000000..d65f32ca
--- /dev/null
+++ b/include/sbi/sbi_hart_protection.h
@@ -0,0 +1,100 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Ventana Micro Systems Inc.
+ */
+
+#ifndef __SBI_HART_PROTECTION_H__
+#define __SBI_HART_PROTECTION_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_list.h>
+
+struct sbi_scratch;
+
+/** Representation of hart protection mechanism */
+struct sbi_hart_protection {
+ /** List head */
+ struct sbi_dlist head;
+
+ /** Name of the hart protection mechanism */
+ char name[32];
+
+ /** Ratings of the hart protection mechanism (higher is better) */
+ unsigned long rating;
+
+ /** Configure protection for current HART (Mandatory) */
+ int (*configure)(struct sbi_scratch *scratch);
+
+ /** Unconfigure protection for current HART (Mandatory) */
+ void (*unconfigure)(struct sbi_scratch *scratch);
+
+ /** Create temporary mapping to access address range on current HART (Optional) */
+ int (*map_range)(struct sbi_scratch *scratch,
+ unsigned long base, unsigned long size);
+
+ /** Destroy temporary mapping on current HART (Optional) */
+ int (*unmap_range)(struct sbi_scratch *scratch,
+ unsigned long base, unsigned long size);
+};
+
+/**
+ * Get the best hart protection mechanism
+ *
+ * @return pointer to best hart protection mechanism
+ */
+struct sbi_hart_protection *sbi_hart_protection_best(void);
+
+/**
+ * Register a hart protection mechanism
+ *
+ * @param hprot pointer to hart protection mechanism
+ *
+ * @return 0 on success and negative error code on failure
+ */
+int sbi_hart_protection_register(struct sbi_hart_protection *hprot);
+
+/**
+ * Unregister a hart protection mechanism
+ *
+ * @param hprot pointer to hart protection mechanism
+ */
+void sbi_hart_protection_unregister(struct sbi_hart_protection *hprot);
+
+/**
+ * Configure protection for current HART
+ *
+ * @param scratch pointer to scratch space of current HART
+ *
+ * @return 0 on success and negative error code on failure
+ */
+int sbi_hart_protection_configure(struct sbi_scratch *scratch);
+
+/**
+ * Unconfigure protection for current HART
+ *
+ * @param scratch pointer to scratch space of current HART
+ */
+void sbi_hart_protection_unconfigure(struct sbi_scratch *scratch);
+
+/**
+ * Create temporary mapping to access address range on current HART
+ *
+ * @param base base address of the temporary mapping
+ * @param size size of the temporary mapping
+ *
+ * @return 0 on success and negative error code on failure
+ */
+int sbi_hart_protection_map_range(unsigned long base, unsigned long size);
+
+/**
+ * Destroy temporary mapping to access address range on current HART
+ *
+ * @param base base address of the temporary mapping
+ * @param size size of the temporary mapping
+ *
+ * @return 0 on success and negative error code on failure
+ */
+int sbi_hart_protection_unmap_range(unsigned long base, unsigned long size);
+
+#endif /* __SBI_HART_PROTECTION_H__ */
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index 8abe1e8e..51588cd1 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -75,6 +75,7 @@ libsbi-objs-y += sbi_emulate_csr.o
libsbi-objs-y += sbi_fifo.o
libsbi-objs-y += sbi_fwft.o
libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hart_protection.o
libsbi-objs-y += sbi_heap.o
libsbi-objs-y += sbi_math.o
libsbi-objs-y += sbi_hfence.o
diff --git a/lib/sbi/sbi_hart_protection.c b/lib/sbi/sbi_hart_protection.c
new file mode 100644
index 00000000..306f5afb
--- /dev/null
+++ b/lib/sbi/sbi_hart_protection.c
@@ -0,0 +1,96 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Ventana Micro Systems Inc.
+ */
+
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_hart_protection.h>
+#include <sbi/sbi_scratch.h>
+
+static SBI_LIST_HEAD(hart_protection_list);
+
+struct sbi_hart_protection *sbi_hart_protection_best(void)
+{
+ if (sbi_list_empty(&hart_protection_list))
+ return NULL;
+
+ return sbi_list_first_entry(&hart_protection_list, struct sbi_hart_protection, head);
+}
+
+int sbi_hart_protection_register(struct sbi_hart_protection *hprot)
+{
+ struct sbi_hart_protection *pos = NULL;
+ bool found_pos = false;
+
+ if (!hprot)
+ return SBI_EINVAL;
+
+ sbi_list_for_each_entry(pos, &hart_protection_list, head) {
+ if (hprot->rating > pos->rating) {
+ found_pos = true;
+ break;
+ }
+ }
+
+ if (found_pos)
+ sbi_list_add_tail(&hprot->head, &pos->head);
+ else
+ sbi_list_add_tail(&hprot->head, &hart_protection_list);
+
+ return 0;
+}
+
+void sbi_hart_protection_unregister(struct sbi_hart_protection *hprot)
+{
+ if (!hprot)
+ return;
+
+ sbi_list_del(&hprot->head);
+}
+
+int sbi_hart_protection_configure(struct sbi_scratch *scratch)
+{
+ struct sbi_hart_protection *hprot = sbi_hart_protection_best();
+
+ if (!hprot)
+ return SBI_EINVAL;
+ if (!hprot->configure)
+ return SBI_ENOSYS;
+
+ return hprot->configure(scratch);
+}
+
+void sbi_hart_protection_unconfigure(struct sbi_scratch *scratch)
+{
+ struct sbi_hart_protection *hprot = sbi_hart_protection_best();
+
+ if (!hprot || !hprot->unconfigure)
+ return;
+
+ hprot->unconfigure(scratch);
+}
+
+int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
+{
+ struct sbi_hart_protection *hprot = sbi_hart_protection_best();
+
+ if (!hprot)
+ return SBI_EINVAL;
+ if (!hprot->map_range)
+ return 0;
+
+ return hprot->map_range(sbi_scratch_thishart_ptr(), base, size);
+}
+
+int sbi_hart_protection_unmap_range(unsigned long base, unsigned long size)
+{
+ struct sbi_hart_protection *hprot = sbi_hart_protection_best();
+
+ if (!hprot)
+ return SBI_EINVAL;
+ if (!hprot->unmap_range)
+ return 0;
+
+ return hprot->unmap_range(sbi_scratch_thishart_ptr(), base, size);
+}
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 663b486b..b161d1c1 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -18,6 +18,7 @@
#include <sbi/sbi_fwft.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_hart_protection.h>
#include <sbi/sbi_heap.h>
#include <sbi/sbi_hsm.h>
#include <sbi/sbi_ipi.h>
@@ -74,6 +75,7 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
const struct sbi_hsm_device *hdev;
const struct sbi_ipi_device *idev;
const struct sbi_timer_device *tdev;
+ const struct sbi_hart_protection *hprot;
const struct sbi_console_device *cdev;
const struct sbi_system_reset_device *srdev;
const struct sbi_system_suspend_device *susp_dev;
@@ -90,6 +92,9 @@ 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();
+ sbi_printf("Platform HART Protection : %s\n",
+ (hprot) ? hprot->name : "---");
idev = sbi_ipi_get_device();
sbi_printf("Platform IPI Device : %s\n",
(idev) ? idev->name : "---");