[PATCH 5/7] test: add generic hwiso SBI unit coverage
Raymond Mao <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <[email protected]> |
From: Raymond Mao <[email protected]> Add a generic HWISO SBI unit suite that exercises boot-time initialization and domain-switch hook sequencing without embedding one platform mechanism's policy directly into the core test driver. Provide a small test registration layer so each HWISO mechanism can supply its own state and quiesce assertions. Signed-off-by: Raymond Mao <[email protected]> --- include/sbi/sbi_hwiso_test.h | 33 +++++++ lib/sbi/objects.mk | 3 + lib/sbi/sbi_hwiso_test.c | 167 +++++++++++++++++++++++++++++++++++ lib/sbi/sbi_hwiso_testlib.c | 108 ++++++++++++++++++++++ 4 files changed, 311 insertions(+) create mode 100644 include/sbi/sbi_hwiso_test.h create mode 100644 lib/sbi/sbi_hwiso_test.c create mode 100644 lib/sbi/sbi_hwiso_testlib.c diff --git a/include/sbi/sbi_hwiso_test.h b/include/sbi/sbi_hwiso_test.h new file mode 100644 index 00000000..3970df5a --- /dev/null +++ b/include/sbi/sbi_hwiso_test.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2026 RISCstar Solutions Corporation. + * + * Author: Raymond Mao <[email protected]> + */ + +#ifndef __SBI_HWISO_TEST_H__ +#define __SBI_HWISO_TEST_H__ + +#include <sbi/sbi_domain.h> +#include <sbi/sbi_hwiso.h> +#include <sbi/sbi_unit_test.h> + +#ifdef CONFIG_SBIUNIT +struct sbi_hwiso_test_ops { + void (*boot_test)(struct sbiunit_test_case *test); + void (*domain_state_test)(struct sbiunit_test_case *test, + const struct sbi_domain *dom, void *ctx); + void (*domain_quiesce_test)(struct sbiunit_test_case *test, + const struct sbi_domain *dom, void *ctx); +}; + +int sbi_hwiso_test_register(const struct sbi_hwiso_ops *ops, + const struct sbi_hwiso_test_ops *test_ops); +void sbi_hwiso_test_boot(struct sbiunit_test_case *test); +void sbi_hwiso_test_domain_state(struct sbiunit_test_case *test, + const struct sbi_domain *dom); +void sbi_hwiso_test_domain_quiesced(struct sbiunit_test_case *test, + const struct sbi_domain *dom); +#endif + +#endif diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk index 6091499a..8839d13c 100644 --- a/lib/sbi/objects.mk +++ b/lib/sbi/objects.mk @@ -13,9 +13,12 @@ libsbi-objs-y += riscv_hardfp.o libsbi-objs-y += riscv_locks.o libsbi-objs-$(CONFIG_SBIUNIT) += sbi_unit_test.o libsbi-objs-$(CONFIG_SBIUNIT) += sbi_unit_tests.o +libsbi-objs-$(CONFIG_SBIUNIT) += sbi_hwiso_testlib.o libsbi-objs-$(CONFIG_SBIUNIT) += sbi_bitmap_test.o +libsbi-objs-$(CONFIG_SBIUNIT) += sbi_hwiso_test.o carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += bitmap_test_suite +carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += hwiso_test_suite carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += console_test_suite libsbi-objs-y += sbi_ecall.o diff --git a/lib/sbi/sbi_hwiso_test.c b/lib/sbi/sbi_hwiso_test.c new file mode 100644 index 00000000..716596e2 --- /dev/null +++ b/lib/sbi/sbi_hwiso_test.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2026 RISCstar Solutions Corporation. + * + * Author: Raymond Mao <[email protected]> + */ +#include <sbi/riscv_encoding.h> +#include <sbi/sbi_domain.h> +#include <sbi/sbi_domain_context.h> +#include <sbi/sbi_hart.h> +#include <sbi/sbi_heap.h> +#include <sbi/sbi_hwiso.h> +#include <sbi/sbi_hwiso_test.h> +#include <sbi/sbi_scratch.h> +#include <sbi/sbi_trap.h> +#include <sbi/sbi_unit_test.h> + +static u32 hwiso_collect_switch_domains(struct sbi_domain *current, + struct sbi_domain **targets, + u32 max_targets) +{ + u32 i; + u32 count = 0; + struct sbi_domain *dom; + + if (!targets || !max_targets) + return 0; + + sbi_domain_for_each(i, dom) { + if (dom == current || dom == &root) + continue; + + targets[count++] = dom; + if (count == max_targets) + return count; + } + + if (current != &root && count < max_targets) + targets[count++] = &root; + + return count; +} + +static void hwiso_snapshot_context(struct sbi_context *ctx) +{ + struct sbi_trap_regs *trap_regs; + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + + trap_regs = (struct sbi_trap_regs *)(csr_read(CSR_MSCRATCH) - + SBI_TRAP_REGS_SIZE); + ctx->regs = *trap_regs; + ctx->sstatus = csr_read(CSR_SSTATUS); + ctx->sie = csr_read(CSR_SIE); + ctx->stvec = csr_read(CSR_STVEC); + ctx->sscratch = csr_read(CSR_SSCRATCH); + ctx->sepc = csr_read(CSR_SEPC); + ctx->scause = csr_read(CSR_SCAUSE); + ctx->stval = csr_read(CSR_STVAL); + ctx->sip = csr_read(CSR_SIP); + ctx->satp = csr_read(CSR_SATP); + ctx->scounteren = 0; + ctx->senvcfg = 0; + if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10) + ctx->scounteren = csr_read(CSR_SCOUNTEREN); + if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_12) + ctx->senvcfg = csr_read(CSR_SENVCFG); + ctx->initialized = true; +} + +static struct sbi_context *hwiso_ensure_context(struct sbiunit_test_case *test, + struct sbi_domain *dom, + struct sbi_context *tmpl, + u32 hartindex) +{ + struct sbi_context *dom_ctx; + + dom_ctx = sbi_hartindex_to_domain_context(hartindex, dom); + if (!dom_ctx) { + dom_ctx = sbi_zalloc(sizeof(*dom_ctx)); + SBIUNIT_ASSERT_NE(test, dom_ctx, NULL); + dom_ctx->dom = dom; + dom->hartindex_to_context_table[hartindex] = dom_ctx; + } + + if (tmpl) { + *dom_ctx = *tmpl; + dom_ctx->dom = dom; + dom->hartindex_to_context_table[hartindex] = dom_ctx; + } + + return dom_ctx; +} + +static void hwiso_boot_test(struct sbiunit_test_case *test) +{ + sbi_hwiso_test_boot(test); +} + +static void hwiso_domain_switch_test(struct sbiunit_test_case *test) +{ + struct sbi_domain *cur_dom = sbi_domain_thishart_ptr(); + struct sbi_context *ctx = sbi_domain_context_thishart_ptr(); + struct sbi_domain *switch_doms[2]; + struct sbi_context *cur_ctx; + struct sbi_context tmpl_ctx; + u32 switch_count; + u32 i; + u32 hartindex = sbi_hartid_to_hartindex(current_hartid()); + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + bool debug_on = false; + + SBIUNIT_ASSERT_NE(test, cur_dom, NULL); + + if (scratch->options & SBI_SCRATCH_DEBUG_PRINTS) + debug_on = true; + else + scratch->options |= SBI_SCRATCH_DEBUG_PRINTS; + + if (!ctx) { + cur_ctx = sbi_zalloc(sizeof(*cur_ctx)); + SBIUNIT_ASSERT_NE(test, cur_ctx, NULL); + cur_ctx->dom = cur_dom; + cur_dom->hartindex_to_context_table[hartindex] = cur_ctx; + ctx = cur_ctx; + } + + hwiso_snapshot_context(ctx); + tmpl_ctx = *ctx; + switch_count = hwiso_collect_switch_domains(cur_dom, switch_doms, 2); + + (void)hwiso_ensure_context(test, cur_dom, NULL, hartindex); + for (i = 0; i < switch_count; i++) + (void)hwiso_ensure_context(test, switch_doms[i], &tmpl_ctx, + hartindex); + + if (!switch_count) + goto out; + + sbi_hwiso_domain_exit(cur_dom, switch_doms[0]); + sbi_hwiso_test_domain_quiesced(test, cur_dom); + sbi_hwiso_domain_enter(switch_doms[0], cur_dom); + sbi_hwiso_test_domain_state(test, switch_doms[0]); + sbi_hwiso_domain_exit(switch_doms[0], cur_dom); + sbi_hwiso_test_domain_quiesced(test, switch_doms[0]); + sbi_hwiso_domain_enter(cur_dom, switch_doms[0]); + sbi_hwiso_test_domain_state(test, cur_dom); + + for (i = 0; i < switch_count; i++) { + SBIUNIT_ASSERT_EQ(test, sbi_domain_context_enter(switch_doms[i]), 0); + sbi_hwiso_test_domain_state(test, switch_doms[i]); + } + + SBIUNIT_ASSERT_EQ(test, sbi_domain_context_enter(cur_dom), 0); + sbi_hwiso_test_domain_state(test, cur_dom); + +out: + if (!debug_on) + scratch->options &= ~SBI_SCRATCH_DEBUG_PRINTS; +} + +static struct sbiunit_test_case hwiso_test_cases[] = { + SBIUNIT_TEST_CASE(hwiso_boot_test), + SBIUNIT_TEST_CASE(hwiso_domain_switch_test), + SBIUNIT_END_CASE, +}; + +SBIUNIT_TEST_SUITE(hwiso_test_suite, hwiso_test_cases); diff --git a/lib/sbi/sbi_hwiso_testlib.c b/lib/sbi/sbi_hwiso_testlib.c new file mode 100644 index 00000000..2a988088 --- /dev/null +++ b/lib/sbi/sbi_hwiso_testlib.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2026 RISCstar Solutions Corporation. + * + * Author: Raymond Mao <[email protected]> + */ + +#include <sbi/sbi_error.h> +#include <sbi/sbi_heap.h> +#include <sbi/sbi_hwiso_test.h> +#include <sbi/sbi_list.h> + +struct sbi_hwiso_test_node { + const struct sbi_hwiso_ops *ops; + const struct sbi_hwiso_test_ops *test_ops; + struct sbi_dlist node; +}; + +static SBI_LIST_HEAD(hwiso_test_ops_list); + +static const struct sbi_hwiso_test_ops * +sbi_hwiso_find_test_ops(const struct sbi_hwiso_ops *ops) +{ + struct sbi_hwiso_test_node *entry; + + sbi_list_for_each_entry(entry, &hwiso_test_ops_list, node) { + if (entry->ops == ops) + return entry->test_ops; + } + + return NULL; +} + +int sbi_hwiso_test_register(const struct sbi_hwiso_ops *ops, + const struct sbi_hwiso_test_ops *test_ops) +{ + struct sbi_hwiso_test_node *node; + + if (!ops || !test_ops) + return SBI_EINVAL; + if (sbi_hwiso_find_test_ops(ops)) + return SBI_EALREADY; + + node = sbi_zalloc(sizeof(*node)); + if (!node) + return SBI_ENOMEM; + + node->ops = ops; + node->test_ops = test_ops; + SBI_INIT_LIST_HEAD(&node->node); + sbi_list_add_tail(&node->node, &hwiso_test_ops_list); + + return 0; +} + +void sbi_hwiso_test_boot(struct sbiunit_test_case *test) +{ + struct sbi_hwiso_test_node *entry; + + sbi_list_for_each_entry(entry, &hwiso_test_ops_list, node) { + if (!entry->test_ops->boot_test) + continue; + entry->test_ops->boot_test(test); + } +} + +void sbi_hwiso_test_domain_state(struct sbiunit_test_case *test, + const struct sbi_domain *dom) +{ + const struct sbi_hwiso_test_ops *test_ops; + u32 i; + + if (!dom || !dom->hwiso_ctxs) + return; + + for (i = 0; i < dom->hwiso_ctx_count; i++) { + if (!dom->hwiso_ctxs[i].ops) + continue; + + test_ops = sbi_hwiso_find_test_ops(dom->hwiso_ctxs[i].ops); + if (!test_ops || !test_ops->domain_state_test) + continue; + + test_ops->domain_state_test(test, dom, dom->hwiso_ctxs[i].ctx); + } +} + +void sbi_hwiso_test_domain_quiesced(struct sbiunit_test_case *test, + const struct sbi_domain *dom) +{ + const struct sbi_hwiso_test_ops *test_ops; + u32 i; + + if (!dom || !dom->hwiso_ctxs) + return; + + for (i = 0; i < dom->hwiso_ctx_count; i++) { + if (!dom->hwiso_ctxs[i].ops) + continue; + + test_ops = sbi_hwiso_find_test_ops(dom->hwiso_ctxs[i].ops); + if (!test_ops || !test_ops->domain_quiesce_test) + continue; + + test_ops->domain_quiesce_test(test, dom, + dom->hwiso_ctxs[i].ctx); + } +} -- 2.25.1 -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi