FeatMgr
FeatMgr is a configuration dataclass for Riescue. It contains all configuration needed for RiescueD to generate a test.
It specifies the enabled features, environment, and generation options.
Note
Generally, users will not need to construct a FeatMgr directly. Instead, they will use the FeatMgrBuilder to construct a FeatMgr.
from riescue import FeatMgr
featmgr = FeatMgr() # build default FeatMgr
- class riescue.FeatMgr
Configuration manager; aata structure containing configuration for test generation.
FeatMgrBuilderclass provides interface for constructingFeatMgrobjects. Users can choose to override any fields after construction.- eot_print_htif_console: bool = False
When True, Riescue-D injects RVCP FAIL lines (with banners) via HTIF tohost putchar before ;#test_failed().
- print_rvcp_passes: bool = False
When True, Riescue-D injects RVCP PASSED lines via HTIF tohost putchar before ;#test_passed() and at final ALL PASSED.
- get_summary() dict[str, bool | int]
Returns an array representation of feature presence.
- is_feature_supported(feature: str) bool
Check if a feature is supported - delegate to FeatureDiscovery
- is_feature_enabled(feature: str) bool
Check if a feature is enabled - delegate to FeatureDiscovery
- get_feature_randomize(feature: str) int
Get the randomization probability for a feature - delegate to FeatureDiscovery
- get_misa_bits() int
Get MISA bits based on enabled features
- get_compiler_march_string() str
Generate a compiler march string from enabled features
- register_default_handler(vec: int, label: str, assembly: Callable[[FeatMgr], str]) None
Override the default interrupt handler for a vector.
Replaces the framework’s built-in handler for
vecwith a user-supplied label and assembly body for the entire test. The handler is active for all discrete_tests that do not install a per-segment handler viaadd_custom_intr_handler().Called from
riescue.dtest_framework.config.conf.Conf.add_hooks().- Parameters:
vec – Interrupt vector number (e.g. 1 for SSI, 3 for MSI, 25 for ZKR).
label – Assembly label for the handler (must be unique in the test).
assembly – Callable
(featmgr: FeatMgr) -> strreturning the handler body. The body should end with the appropriatexret(mretfor M-mode vectors).
from riescue import Conf, FeatMgr def my_msi_handler(featmgr: FeatMgr) -> str: return """ csrci mip, 8 # clear MSIP mret """ class MyConf(Conf): def add_hooks(self, featmgr: FeatMgr) -> None: featmgr.register_default_handler(3, "my_msi_handler", my_msi_handler) def setup() -> Conf: return MyConf()
- register_hook(hook_point: HookPoint, hook: Callable[[FeatMgr], str])
Register a hook for a given hook point Multiple hooks can be registered for the same hook point. The order of hooks registered is preserved.
- Parameters:
hook_point – The
riescue.lib.enums.HookPointenum value to register the hook.hook – Callable hook function to register; returns a string of assembly code
def hook(featmgr: FeatMgr) -> str: return "nop" featmgr.register_hook(RV.HookPoint.PRE_PASS, hook)
Hooks
Hooks are available for inserting additional code at different points in the code.
Hooks take an instance of the riescue.FeatMgr class as an argument and return a string of assembly code.
This can be used to add additional code at different points in the Runtime.
E.g.
def hook(featmgr: FeatMgr) -> str:
return "nop"
featmgr.register_hook(RV.HookPoint.PRE_PASS, hook)
The available hooks are defined in the riescue.lib.enums.HookPoint enum.
- class riescue.lib.enums.HookPoint(value)
Bases:
MyEnumEnumerated hooks for runtime code.
These are all the available hooks, they allow for inserting code at specific points in the Runtime. They append or replace code at the hook point.
This describes the name of the hook; behavior of the hook is defined where the hook is used.
- PRE_LOADER = 'pre_loader'
Insert code before the loader. Can be used to insert code for custom CSRs, platform intialization code. GPRs, and changes to tvec, status, and satp will be overwritten by loader.
- M_LOADER = 'm_loader'
Insert additional M-level configuration needed before the runtime may jump to a less privileged or virtualized mode. Code should avoid modifying trap handling or paging registers, e.g. tvec, satp, or vsatp.
- POST_LOADER = 'post_loader'
Insert code after the loader but before the test jumps to the scheduler, inside
loader__donelabel.
- PRE_DISPATCH = 'pre_dispatch'
Insert code before the scheduler loads the next test into a0.
- POST_DISPATCH = 'post_dispatch'
Insert code after the scheduler loads the next test into a0. Should not modify a0
- POST_TRAP = 'post_trap'
Insert code after a trap is taken. Useful for logging/bookkeeping traps. Code should resume to return code after to continue execution.
tpis initialized here - push and pop any registers used by post-trap code.
- PRE_FAIL = 'pre_fail'
Insert code before the test is marked as failed.
- POST_FAIL = 'post_fail'
Insert code after the test is marked as failed.
- PRE_PASS = 'pre_pass'
Insert code before the test is marked as passed.
- POST_PASS = 'post_pass'
Insert code after the test is marked as passed.
- PRE_HALT = 'pre_halt'
Insert code before the test is halted.
Hooks can be added using the riescue.FeatMgr.register_hook() method with a valid enum value.
Multiple hooks can be registered for the same hook point. The order of hooks registered is preserved.
Hooks can also be added using the riescue.dtest_framework.config.Conf class.
See the Conf reference for more information on how to use the Conf class.
Default Interrupt Handler Override
The register_default_handler method lets a Conf override the
test-wide default handler for a specific interrupt vector. The replacement handler is
active for the whole test and does not require the per-segment PROLOGUE/EPILOGUE
pointer-swap mechanism.
from riescue import Conf, FeatMgr
def my_ssi_handler(featmgr: FeatMgr) -> str:
"""Custom handler for SSI (vec 1). Clears SSIP and returns."""
return """
csrci mip, 2 # clear SSIP (bit 1)
mret
"""
class MyConf(Conf):
def add_hooks(self, featmgr: FeatMgr) -> None:
featmgr.register_default_handler(
vec=1,
label="my_ssi_handler",
assembly=my_ssi_handler,
)
def setup() -> Conf:
return MyConf()
The handler assembly callable receives the FeatMgr instance and returns a raw
assembly string. The string must end with the appropriate return instruction
(mret for machine-mode vectors, sret for supervisor-mode vectors).
The framework emits the handler body into the .runtime section and wires the
vector into the M-mode vector dispatch table. S-mode delegated vector overrides
are not yet supported.
See riescue/dtest_framework/tests/non_instr_tests/default_handler_override.s
and default_handler_override_conf.py for a complete working example.