[PATCH 1/2] sbi: add hardware isolation abstraction framework
Raymond Mao <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <[email protected]> |
From: Raymond Mao <[email protected]> Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains. Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain. This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation. Signed-off-by: Raymond Mao <[email protected]> --- include/sbi/sbi_domain.h | 4 + include/sbi/sbi_hwiso.h | 56 +++++++++++++ lib/sbi/objects.mk | 1 + lib/sbi/sbi_hwiso.c | 175 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 include/sbi/sbi_hwiso.h create mode 100644 lib/sbi/sbi_hwiso.c diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h index 02765777..fc7330a6 100644 --- a/include/sbi/sbi_domain.h +++ b/include/sbi/sbi_domain.h @@ -14,6 +14,7 @@ #include <sbi/sbi_types.h> #include <sbi/sbi_hartmask.h> #include <sbi/sbi_domain_context.h> +#include <sbi/sbi_hwiso.h> #include <sbi/sbi_rpxy.h> struct sbi_scratch; @@ -199,6 +200,9 @@ struct sbi_domain { bool system_reset_allowed; /** Is domain allowed to suspend the system */ bool system_suspend_allowed; + /** Hardware isolation contexts for registered mechanisms */ + struct sbi_hwiso_domain_ctx *hwiso_ctxs; + u32 hwiso_ctx_count; /** Identifies whether to include the firmware region */ bool fw_region_inited; }; diff --git a/include/sbi/sbi_hwiso.h b/include/sbi/sbi_hwiso.h new file mode 100644 index 00000000..1efdb8c1 --- /dev/null +++ b/include/sbi/sbi_hwiso.h @@ -0,0 +1,56 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * System-level hardware isolation framework + * + * Copyright (c) 2026 RISCstar Solutions Corporation. + * + * Author: Raymond Mao <[email protected]> + */ + +#ifndef __SBI_HWISO_H__ +#define __SBI_HWISO_H__ + +#include <sbi/sbi_types.h> +#include <sbi/sbi_domain.h> + +struct sbi_hwiso_ops { + const char *name; + + /* Boot-time init */ + int (*init)(void *fdt); + + /* Per-domain init (domain_offset refers to domain instance node) */ + int (*domain_init)(void *fdt, int domain_offset, + struct sbi_domain *dom, void **ctx); + + /* Before switching away from a domain */ + void (*domain_exit)(const struct sbi_domain *src, + const struct sbi_domain *dst, void *ctx); + + /* After switching into a domain */ + void (*domain_enter)(const struct sbi_domain *dst, + const struct sbi_domain *src, void *ctx); + + /* Optional cleanup */ + void (*domain_cleanup)(struct sbi_domain *dom, void *ctx); +}; + +struct sbi_hwiso_domain_ctx { + const struct sbi_hwiso_ops *ops; + void *ctx; +}; + +int sbi_hwiso_register(const struct sbi_hwiso_ops *ops); + +int sbi_hwiso_init(void *fdt); +int sbi_hwiso_domain_init(void *fdt, int domain_offset, + struct sbi_domain *dom); + +void sbi_hwiso_domain_exit(const struct sbi_domain *src, + const struct sbi_domain *dst); +void sbi_hwiso_domain_enter(const struct sbi_domain *dst, + const struct sbi_domain *src); +void sbi_hwiso_domain_cleanup(struct sbi_domain *dom); + +#endif /* __SBI_HWISO_H__ */ diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk index ca312ee2..6091499a 100644 --- a/lib/sbi/objects.mk +++ b/lib/sbi/objects.mk @@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o libsbi-objs-y += sbi_emulate_csr.o libsbi-objs-y += sbi_fifo.o libsbi-objs-y += sbi_hart.o +libsbi-objs-y += sbi_hwiso.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_hwiso.c b/lib/sbi/sbi_hwiso.c new file mode 100644 index 00000000..6c96dc3e --- /dev/null +++ b/lib/sbi/sbi_hwiso.c @@ -0,0 +1,175 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * System-level hardware isolation framework + * + * Copyright (c) 2026 RISCstar Solutions Corporation. + * + * Author: Raymond Mao <[email protected]> + */ + +#include <libfdt.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_heap.h> +#include <sbi/sbi_hwiso.h> +#include <sbi/sbi_list.h> + +struct sbi_hwiso_node { + const struct sbi_hwiso_ops *ops; + struct sbi_dlist node; +}; + +static SBI_LIST_HEAD(hwiso_ops_list); +static u32 hwiso_ops_count; + +static bool hwiso_ops_registered(const struct sbi_hwiso_ops *ops) +{ + struct sbi_hwiso_node *entry; + + sbi_list_for_each_entry(entry, &hwiso_ops_list, node) { + if (entry->ops == ops) + return true; + } + + return false; +} + +int sbi_hwiso_register(const struct sbi_hwiso_ops *ops) +{ + struct sbi_hwiso_node *node; + + if (!ops || !ops->name) + return SBI_EINVAL; + + if (hwiso_ops_registered(ops)) + return SBI_EALREADY; + + node = sbi_zalloc(sizeof(*node)); + if (!node) + return SBI_ENOMEM; + + node->ops = ops; + SBI_INIT_LIST_HEAD(&node->node); + sbi_list_add_tail(&node->node, &hwiso_ops_list); + hwiso_ops_count++; + + return 0; +} + +int sbi_hwiso_init(void *fdt) +{ + struct sbi_hwiso_node *entry; + int rc; + + sbi_list_for_each_entry(entry, &hwiso_ops_list, node) { + if (!entry->ops->init) + continue; + + rc = entry->ops->init(fdt); + if (rc) + return rc; + } + + return 0; +} + +int sbi_hwiso_domain_init(void *fdt, int domain_offset, + struct sbi_domain *dom) +{ + struct sbi_hwiso_node *entry; + struct sbi_hwiso_domain_ctx *ctxs; + void *ctx; + u32 idx = 0; + int rc; + + if (!dom) + return 0; + + if (!hwiso_ops_count) + return 0; + + ctxs = sbi_calloc(sizeof(*ctxs), hwiso_ops_count); + if (!ctxs) + return SBI_ENOMEM; + + dom->hwiso_ctxs = ctxs; + dom->hwiso_ctx_count = hwiso_ops_count; + + sbi_list_for_each_entry(entry, &hwiso_ops_list, node) { + ctxs[idx].ops = entry->ops; + ctxs[idx].ctx = NULL; + ctx = NULL; + + if (entry->ops->domain_init) { + rc = entry->ops->domain_init(fdt, domain_offset, + dom, &ctx); + ctxs[idx].ctx = ctx; + if (rc) { + sbi_hwiso_domain_cleanup(dom); + return rc; + } + } + + ctxs[idx].ctx = ctx; + idx++; + } + + return 0; +} + +void sbi_hwiso_domain_exit(const struct sbi_domain *src, + const struct sbi_domain *dst) +{ + u32 i; + + if (!src || !src->hwiso_ctxs) + return; + + for (i = 0; i < src->hwiso_ctx_count; i++) { + if (!src->hwiso_ctxs[i].ops || + !src->hwiso_ctxs[i].ops->domain_exit) + continue; + + src->hwiso_ctxs[i].ops->domain_exit( + src, dst, src->hwiso_ctxs[i].ctx); + } +} + +void sbi_hwiso_domain_enter(const struct sbi_domain *dst, + const struct sbi_domain *src) +{ + u32 i; + + if (!dst || !dst->hwiso_ctxs) + return; + + for (i = 0; i < dst->hwiso_ctx_count; i++) { + if (!dst->hwiso_ctxs[i].ops || + !dst->hwiso_ctxs[i].ops->domain_enter) + continue; + + dst->hwiso_ctxs[i].ops->domain_enter( + dst, src, dst->hwiso_ctxs[i].ctx); + } +} + +void sbi_hwiso_domain_cleanup(struct sbi_domain *dom) +{ + u32 i; + + if (!dom || !dom->hwiso_ctxs) + return; + + for (i = 0; i < dom->hwiso_ctx_count; i++) { + if (!dom->hwiso_ctxs[i].ops || + !dom->hwiso_ctxs[i].ops->domain_cleanup) + continue; + + dom->hwiso_ctxs[i].ops->domain_cleanup( + dom, dom->hwiso_ctxs[i].ctx); + } + + sbi_free(dom->hwiso_ctxs); + dom->hwiso_ctxs = NULL; + dom->hwiso_ctx_count = 0; +} -- 2.25.1 -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi