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 +#include + +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 +#include +#include + +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 #include #include +#include #include #include #include @@ -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 : "---");