You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Developing a minimal, reusable M-mode firmware runner to execute ACT4 ELF binaries on real RISC-V silicon with full privilege access, UART-based result reporting, and an automated multi-board compliance pipeline.
The ACT4 framework has excellent simulation coverage (Spike, QEMU, Sail, RTL). What is missing is a path to run M-mode compliance tests on real Linux-capable RISC-V boards. The root cause is structural - not a config gap but a boot chain conflict.
By the time U-Boot runs, OpenSBI has already claimed M-mode. Any binary launched from U-Boot runs in S-mode. ACT tests that rely on rvtest_mtrap_routine, PMP configuration, mstatus, mie, mtvec, or FPU state will either trap incorrectly or return wrong CSR values. There is no workaround without entering the boot chain above OpenSBI.
Problem Inventory
#
Problem
Impact
1
OpenSBI claims M-mode before any user binary runs
All M-mode ACT tests untestable on hardware
2
No M-mode ELF loader exists for these SoCs
ACT ELFs cannot be placed and executed at correct privilege
3
tohost has no host-side monitor on real hardware
PASS/FAIL unobservable - simulation-only contract
4
No config/cores/ entry enables M-mode on any Linux-capable SBC
No community reference for hardware M-mode testing
5
Milk-V Jupiter B/V extensions have zero hardware ACT coverage
Zba, Zbb, Zbs, RVV 1.0 tests never validated on silicon
6
No multi-test automation or report generation for hardware runs
RVI20 suite is impractical to execute and report without tooling
The OpenSBI domain approach (primary) keeps the production boot chain intact with no reflashing required. An opensbi_domain.dts fragment carves a reserved DRAM region and grants it M-mode privilege. U-Boot pre-loads the ACT ELF into that region via tftpboot; the runner picks it up at a known address.
The fw_payload approach (fallback) replaces OpenSBI entirely for test-only boot scenarios. Used for QEMU and fully controlled environments where board reflashing is acceptable.
Architecture - M-Mode Runner
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%%
flowchart TD
subgraph Entry["Entry - start.S"]
direction TB
S1["Set mtvec (vectored mode)"]
S2["Set mstatus.MIE + mstatus.FS = Initial"]
S3["Configure PMP\nRWX for test region + UART MMIO"]
S4["Set up stack pointer"]
S1 --> S2 --> S3 --> S4
end
subgraph Load["ELF Loading - elf_loader.c"]
direction TB
L1["Read Elf64_Ehdr\nValidate magic + e_machine = 0xF3"]
L2["Iterate PT_LOAD segments"]
L3["memcpy p_filesz bytes to p_paddr"]
L4["Zero BSS region\np_memsz - p_filesz"]
L5["Return e_entry\nrvtest_entry_point"]
L1 --> L2 --> L3 --> L4 --> L5
end
subgraph Exec["Execution and Monitoring"]
direction TB
E1["jalr to entry_point"]
E2["trap.c fires on any exception\nLog mcause, mepc, mtval over UART"]
E3["tohost.c polls tohost\naddress in M-mode"]
E4{"tohost value?"}
E5["RVCP-SUMMARY: PASS"]
E6["RVCP-SUMMARY: FAIL\n+ mcause dump"]
E7["mcycle timeout\nconfigurable limit"]
E1 --> E3 --> E4
E1 -.->|"on trap"| E2
E4 -->|"0x1"| E5
E4 -->|"0x3"| E6
E4 -->|"timeout"| E7
end
Entry --> Load --> Exec
Loading
Runner Components
The runner is a small, self-contained firmware written in C and RISC-V assembly with no standard library dependency. It is composed of six focused modules:
Module
Responsibility
Assembly entry point
Sets up the M-mode environment before any C code runs: trap vector, interrupt enable, FPU state, and stack
ELF64 loader
Parses the test binary, copies each loadable segment to its correct physical address in DRAM, and returns the entry point
Trap handler
Catches any exception the test generates, logs the cause and faulting address over UART, and recovers to continue the run
Result reporter
Writes to the tohost address and simultaneously prints a RVCP-SUMMARY: line over UART so results are visible from both channels
PMP configurator
Grants read/write/execute access to the test memory region and the UART MMIO range before handing off to the test
Board UART drivers
Separate drivers for the NS16550 (VisionFive 2) and 8250-compatible (Milk-V Jupiter) controllers; selected at compile time
Board-specific linker scripts place the runner itself at a fixed DRAM address and reserve the region above it for the incoming test binary, with no overlap with OpenSBI or U-Boot memory regions.
Deliverables
Board 1 - StarFive VisionFive 2 (JH7110, RV64GC)
Parameter
Value
Source
DRAM base
0x40000000
JH7110 TRM
UART
NS16550 @ 0x10000000
JH7110 TRM
PMP grain
4 bytes
JH7110 TRM
Runner base
0x47000000
Above OpenSBI + U-Boot
ELF base
0x47200000
Above runner
Boot chain
SPL + OpenSBI + U-Boot
Standard JH7110
Files under config/cores/starfive/visionfive2/:
rvmodel_macros.h - RVMODEL_BOOT initialises NS16550 UART and M-mode runner handshake; RVMODEL_HALT_PASS / RVMODEL_HALT_FAIL write tohost and print RVCP-SUMMARY: over UART simultaneously
link.ld - ELF base 0x47200000, above runner and OpenSBI/U-Boot regions
README.md - Full bring-up walkthrough: toolchain, build, U-Boot flow, UART, result parsing
Board 2 - Milk-V Jupiter (SpacemiT K1, RV64GCB+V)
The K1 is the only widely available SBC with B and V extensions, making it the first hardware target for Zba/Zbb/Zbs and RVV 1.0 compliance tests that currently have no silicon coverage in ACT4.
Parameter
Value
Source
DRAM base
0x00000000
SpacemiT K1 Datasheet
UART
8250 @ 0x0D090000
SpacemiT K1 Datasheet
Extensions
RV64GC + Zba/Zbb/Zbs + RVV 1.0
K1 ISA spec
Runner base
0x07000000
Above OpenSBI region
ELF base
0x07200000
Above runner
Files under config/cores/milkv/jupiter/:
rvmodel_macros.h - 8250 UART init; mstatus.VS = Initial set before V-extension tests
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%%
flowchart LR
GH["GitHub Actions\nCI trigger"]
subgraph Run["QEMU virt M-mode Run"]
direction LR
QC["QEMU virt machine\nfw_payload boot + ACT ELF"]
HTIF["HTIF tohost\nnative QEMU support"]
QC --> HTIF
end
RPT2["Compliance report\nas CI artifact"]
GH --> Run --> RPT2
Loading
Enables full M-mode ACT runs in CI without physical hardware. Mirrors the VisionFive 2 memory layout for parity. A GitHub Actions workflow YAML is included.
Host-Side Tooling (tools/)
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%%
flowchart TD
BOARD["Board UART\n/dev/ttyUSB0"]
subgraph Loop["run_act_suite.sh"]
direction TB
FOR["for each ELF in rvi20u64 profile"]
LOAD["U-Boot: tftpboot ELF to DRAM"]
TRIG["Trigger domain / go addr"]
FOR --> LOAD --> TRIG --> FOR
end
subgraph Capture["uart_capture.py"]
direction TB
RECV["Read UART until RVCP-SUMMARY line"]
PARSE["Parse result + mcause + cycle count"]
JSON["Emit structured JSON per test"]
RECV --> PARSE --> JSON
end
subgraph Report["generate_report.py"]
direction TB
AGG["Aggregate all JSON results"]
MD["Markdown summary table"]
RISCOF["riscof-compatible report"]
EXIT["exit 0 all pass / exit 1 any fail"]
AGG --> MD --> RISCOF --> EXIT
end
BOARD --> Capture
Loop --> Capture
Capture --> Report
Loading
For each test, uart_capture.py records the board name, test name, pass or fail result, any trap cause code observed during execution, and the cycle count. This structured output is what generate_report.py consumes to produce the final compliance report.
tohost Strategy - Resolved
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%%
flowchart LR
TEST["ACT ELF\nwrites tohost"]
CH1["Channel A\ntohost DRAM address\nHost reads via /dev/mem"]
CH2["Channel B\nUART RVCP-SUMMARY\nuart_capture.py"]
CHECK["Cross-check\nBoth channels must agree"]
TEST --> CH1 --> CHECK
TEST --> CH2 --> CHECK
Loading
UART is the primary channel (works on all boards, no Linux required). The /dev/mem channel is a secondary cross-check available when Linux is running on the same board. Both are implemented in uart_capture.py.
OpenSBI domain DTS integration - should opensbi_domain.dts ship as a patch against the vendor OpenSBI tree or as a standalone overlay users apply manually? Is there a preferred pattern across existing config/ entries?
rvi20u64 profile declaration in test_config.yaml - following @karabambus's suggestion, should the profile be declared explicitly in the YAML, or is it intended to be passed only at the riscof invocation layer?
V-extension test readiness on Milk-V Jupiter - the K1's RVV 1.0 support makes it a strong first hardware target for vector compliance. Is there an existing or planned V-extension test suite in ACT4, or should a minimal set be scoped into this work?
Boot flow refactor coordination - @jordancarlin mentioned the refactor completing soon. Is there a tracking issue or branch to follow so the runner can be designed with the new flow in mind from the start?
PMP grain confirmation for JH7110 - from the TRM, pmpgranularity = 4. Can a maintainer with hardware access confirm this, or should the runner detect it dynamically via a pmpcfg probe at boot?
Hardware Reference
Board
SoC
ISA
Boot Chain
UART
DRAM Base
StarFive VisionFive 2
JH7110
RV64GC
SPL + OpenSBI + U-Boot
NS16550 @ 0x10000000
0x40000000
Milk-V Jupiter
SpacemiT K1
RV64GCB_Zba_Zbb_Zbs_V
SPL + OpenSBI + U-Boot
8250 @ 0x0D090000
0x00000000
Boards will be arranged by mentors upon selection. All development prior to hardware access uses QEMU virt with the fw_payload boot path.
Related Issues
Document trap handler #1206 - Trap handler documentation (prerequisite for correct M-mode trap setup in runner)
M-Mode ACT4 Firmware Runner & Hardware Validation - VisionFive 2 + Milk-V Jupiter
Overview
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% flowchart TD subgraph Boards["Target Hardware"] VF2["StarFive VisionFive 2\nJH7110 · RV64GC"] MV["Milk-V Jupiter\nSpacemiT K1 · RV64GCB+V"] end subgraph Dev["CI / Development"] Q["QEMU virt-rv64\nM-mode proxy"] end subgraph Runner["M-Mode Firmware Runner"] direction LR ELF["ELF64 Loader"] --> TRAP["Trap Handler\nmtvec · PMP · FPU"] --> TH["tohost Monitor"] end subgraph Host["Host Tooling"] direction LR CAP["uart_capture.py"] --> SUITE["run_act_suite.sh"] --> RPT["generate_report.py"] end Boards --> Runner Dev --> Runner Runner --> Host Host --> OUT["riscof-compatible\nCompliance Report"]The Problem
The ACT4 framework has excellent simulation coverage (Spike, QEMU, Sail, RTL). What is missing is a path to run M-mode compliance tests on real Linux-capable RISC-V boards. The root cause is structural - not a config gap but a boot chain conflict.
Boot Chain Conflict
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% flowchart LR ROM["ROM / ZSBL"] SPL["SPL\nM-mode"] OSBI["OpenSBI\nM-mode claimed here"] UB["U-Boot\nS-mode only"] LIN["Linux"] ACT["ACT ELF via 'go'\nRuns in S-mode\nM-mode CSRs inaccessible"] ROM --> SPL --> OSBI --> UB --> LIN UB -->|"go 0xaddr"| ACTBy the time U-Boot runs, OpenSBI has already claimed M-mode. Any binary launched from U-Boot runs in S-mode. ACT tests that rely on
rvtest_mtrap_routine, PMP configuration,mstatus,mie,mtvec, or FPU state will either trap incorrectly or return wrong CSR values. There is no workaround without entering the boot chain above OpenSBI.Problem Inventory
tohosthas no host-side monitor on real hardwareconfig/cores/entry enables M-mode on any Linux-capable SBCProposed Solution
Boot Chain Redesign for ACT Runs
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% flowchart TD subgraph Normal["Production Boot (unchanged)"] direction LR N1["ROM"] --> N2["SPL"] --> N3["OpenSBI"] --> N4["U-Boot"] --> N5["Linux"] end subgraph ACTBoot["ACT Test Boot - OpenSBI Domain (primary)"] direction LR A1["ROM"] --> A2["SPL"] --> A3["OpenSBI +\nDomain Config"] A3 -->|"S-mode domain"| A4["U-Boot\npre-loads ACT ELF\nvia tftpboot / fatload"] A3 -->|"M-mode domain\nnext-mode = 0x3"| A5["act_mmode_runner\n0x47000000"] A5 --> A6["ACT ELF\n0x47200000\nFull M-mode"] A6 --> A7["UART\nRVCP-SUMMARY"] end subgraph Fallback["fw_payload Fallback - QEMU / clean env"] direction LR F1["ROM"] --> F2["SPL"] --> F3["fw_payload.bin\nrunner = firmware"] --> F4["ACT ELF\nM-mode"] --> F5["HTIF tohost\n+ UART"] endThe OpenSBI domain approach (primary) keeps the production boot chain intact with no reflashing required. An
opensbi_domain.dtsfragment carves a reserved DRAM region and grants it M-mode privilege. U-Boot pre-loads the ACT ELF into that region viatftpboot; the runner picks it up at a known address.The
fw_payloadapproach (fallback) replaces OpenSBI entirely for test-only boot scenarios. Used for QEMU and fully controlled environments where board reflashing is acceptable.Architecture - M-Mode Runner
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% flowchart TD subgraph Entry["Entry - start.S"] direction TB S1["Set mtvec (vectored mode)"] S2["Set mstatus.MIE + mstatus.FS = Initial"] S3["Configure PMP\nRWX for test region + UART MMIO"] S4["Set up stack pointer"] S1 --> S2 --> S3 --> S4 end subgraph Load["ELF Loading - elf_loader.c"] direction TB L1["Read Elf64_Ehdr\nValidate magic + e_machine = 0xF3"] L2["Iterate PT_LOAD segments"] L3["memcpy p_filesz bytes to p_paddr"] L4["Zero BSS region\np_memsz - p_filesz"] L5["Return e_entry\nrvtest_entry_point"] L1 --> L2 --> L3 --> L4 --> L5 end subgraph Exec["Execution and Monitoring"] direction TB E1["jalr to entry_point"] E2["trap.c fires on any exception\nLog mcause, mepc, mtval over UART"] E3["tohost.c polls tohost\naddress in M-mode"] E4{"tohost value?"} E5["RVCP-SUMMARY: PASS"] E6["RVCP-SUMMARY: FAIL\n+ mcause dump"] E7["mcycle timeout\nconfigurable limit"] E1 --> E3 --> E4 E1 -.->|"on trap"| E2 E4 -->|"0x1"| E5 E4 -->|"0x3"| E6 E4 -->|"timeout"| E7 end Entry --> Load --> ExecRunner Components
The runner is a small, self-contained firmware written in C and RISC-V assembly with no standard library dependency. It is composed of six focused modules:
tohostaddress and simultaneously prints aRVCP-SUMMARY:line over UART so results are visible from both channelsBoard-specific linker scripts place the runner itself at a fixed DRAM address and reserve the region above it for the incoming test binary, with no overlap with OpenSBI or U-Boot memory regions.
Deliverables
Board 1 - StarFive VisionFive 2 (JH7110, RV64GC)
0x400000000x100000000x470000000x47200000Files under
config/cores/starfive/visionfive2/:rvmodel_macros.h-RVMODEL_BOOTinitialises NS16550 UART and M-mode runner handshake;RVMODEL_HALT_PASS/RVMODEL_HALT_FAILwritetohostand printRVCP-SUMMARY:over UART simultaneouslylink.ld- ELF base0x47200000, above runner and OpenSBI/U-Boot regionstest_config.yaml-include_priv_tests: true, profilervi20u64rvtest_config.h- RV64GC + Zba/Zbb/Zbs + Sv39/48 flagsvisionfive2-rv64gc.yaml- Full UDB description with JH7110 memory map, PMP grain = 4sail.json- Sail reference config (DRAM0x40000000, UART0x10000000)opensbi_domain.dts- Domain config fragment granting M-mode to the runner regionuboot_load.sh-tftpboot+ domain trigger + UART capture scripted flowREADME.md- Full bring-up walkthrough: toolchain, build, U-Boot flow, UART, result parsingBoard 2 - Milk-V Jupiter (SpacemiT K1, RV64GCB+V)
The K1 is the only widely available SBC with B and V extensions, making it the first hardware target for Zba/Zbb/Zbs and RVV 1.0 compliance tests that currently have no silicon coverage in ACT4.
0x000000000x0D0900000x070000000x07200000Files under
config/cores/milkv/jupiter/:rvmodel_macros.h- 8250 UART init;mstatus.VS = Initialset before V-extension testslink.ld- Runner0x07000000, ELF0x07200000test_config.yaml-include_priv_tests: true; profilervi20u64+ Zba/Zbb/Zbs; V-extension tests staged separatelyrvtest_config.h-RVMODEL_ZBA,RVMODEL_ZBB,RVMODEL_ZBS,RVMODEL_Vflagsmilkv-jupiter-rv64gcbv.yaml- UDB description with K1 UART, CLINT, PLIC, memory mapREADME.md- K1 bring-up notes;vtype/vlCSR handling in trap handlerQEMU CI Proxy -
config/cores/qemu/virt-rv64/%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% flowchart LR GH["GitHub Actions\nCI trigger"] subgraph Run["QEMU virt M-mode Run"] direction LR QC["QEMU virt machine\nfw_payload boot + ACT ELF"] HTIF["HTIF tohost\nnative QEMU support"] QC --> HTIF end RPT2["Compliance report\nas CI artifact"] GH --> Run --> RPT2Enables full M-mode ACT runs in CI without physical hardware. Mirrors the VisionFive 2 memory layout for parity. A GitHub Actions workflow YAML is included.
Host-Side Tooling (
tools/)%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% flowchart TD BOARD["Board UART\n/dev/ttyUSB0"] subgraph Loop["run_act_suite.sh"] direction TB FOR["for each ELF in rvi20u64 profile"] LOAD["U-Boot: tftpboot ELF to DRAM"] TRIG["Trigger domain / go addr"] FOR --> LOAD --> TRIG --> FOR end subgraph Capture["uart_capture.py"] direction TB RECV["Read UART until RVCP-SUMMARY line"] PARSE["Parse result + mcause + cycle count"] JSON["Emit structured JSON per test"] RECV --> PARSE --> JSON end subgraph Report["generate_report.py"] direction TB AGG["Aggregate all JSON results"] MD["Markdown summary table"] RISCOF["riscof-compatible report"] EXIT["exit 0 all pass / exit 1 any fail"] AGG --> MD --> RISCOF --> EXIT end BOARD --> Capture Loop --> Capture Capture --> ReportFor each test,
uart_capture.pyrecords the board name, test name, pass or fail result, any trap cause code observed during execution, and the cycle count. This structured output is whatgenerate_report.pyconsumes to produce the final compliance report.tohost Strategy - Resolved
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% flowchart LR TEST["ACT ELF\nwrites tohost"] CH1["Channel A\ntohost DRAM address\nHost reads via /dev/mem"] CH2["Channel B\nUART RVCP-SUMMARY\nuart_capture.py"] CHECK["Cross-check\nBoth channels must agree"] TEST --> CH1 --> CHECK TEST --> CH2 --> CHECKUART is the primary channel (works on all boards, no Linux required). The
/dev/memchannel is a secondary cross-check available when Linux is running on the same board. Both are implemented inuart_capture.py.Implementation Timeline
%%{init: {"theme": "base", "themeVariables": {"darkMode": true, "primaryColor": "#1e3558", "primaryTextColor": "#e2eeff", "primaryBorderColor": "#3d6aad", "secondaryColor": "#0d1f3c", "tertiaryColor": "#162b4d", "lineColor": "#5b8dd9", "edgeLabelBackground": "#0d1f3c", "clusterBkg": "#0d1f3c", "titleColor": "#93b4e8"}}}%% gantt title 12-Week Implementation Plan dateFormat YYYY-MM-DD axisFormat W%W section Phase 1 - Foundation ACT4 framework study + riscof flow :2026-06-01, 7d QEMU bare-metal M-mode baseline :2026-06-08, 7d section Phase 2 - M-Mode Runner start.S + elf_loader + trap + UART :2026-06-15, 14d tohost integration + QEMU virt config :2026-06-29, 7d section Phase 3 - Hardware Ports VisionFive 2 port + OpenSBI domain :2026-07-06, 14d VisionFive 2 full rvi20u64 validation :2026-07-20, 7d Milk-V Jupiter port + B/V extensions :2026-07-27, 14d section Phase 4 - Tooling and Docs uart_capture + run_suite + report gen :2026-08-10, 7d Boot flow refactor integration :2026-08-17, 7d Documentation + upstream PR :2026-08-24, 7dOpen Questions for Maintainers
OpenSBI domain DTS integration - should
opensbi_domain.dtsship as a patch against the vendor OpenSBI tree or as a standalone overlay users apply manually? Is there a preferred pattern across existingconfig/entries?rvi20u64 profile declaration in
test_config.yaml- following @karabambus's suggestion, should the profile be declared explicitly in the YAML, or is it intended to be passed only at theriscofinvocation layer?V-extension test readiness on Milk-V Jupiter - the K1's RVV 1.0 support makes it a strong first hardware target for vector compliance. Is there an existing or planned V-extension test suite in ACT4, or should a minimal set be scoped into this work?
Boot flow refactor coordination - @jordancarlin mentioned the refactor completing soon. Is there a tracking issue or branch to follow so the runner can be designed with the new flow in mind from the start?
PMP grain confirmation for JH7110 - from the TRM,
pmpgranularity = 4. Can a maintainer with hardware access confirm this, or should the runner detect it dynamically via apmpcfgprobe at boot?Hardware Reference
0x100000000x400000000x0D0900000x00000000Boards will be arranged by mentors upon selection. All development prior to hardware access uses QEMU
virtwith thefw_payloadboot path.Related Issues
RVMODEL_ACCESS_FAULT_ADDRESShandling (relevant for K1's fully populated memory map)I'll track the boot flow refactor branch and design the runner to adapt cleanly once it lands.