The C906 ORs the internal CLINT's hardware supervisor-timer line into mip.STIP (aq_cp0_trap_csr.v: st_int && CLINTEE || stip_reg) and the RTL resets mxstatus.CLINTEE to 1. Nothing ever programmed STIMECMP, and the compare registers' 0xFFFF_FFFF reset values are not guaranteed to be applied (the HP hold-reset produces no async negedge in Verilator, so the regs stay zero), so st_int fires from the first cycle: the moment the kernel enables sie.STIE in time_init, it falls into an infinite supervisor-timer storm and the boot thread starves right after the sched_clock print. (M-mode firmware is immune, which is why RT-Thread and OpenSBI were unaffected.) Probe evidence after the fix: MTIMECMP arms exactly one jiffy out (mtime+3979 at HZ=250) and MTIP fires exactly at the compare value on a healthy 288K-cycle cadence; the kernel boots through console init, BogoMIPS, devtmpfs, and switches to the riscv_clocksource. Park both compare registers explicitly at cold boot so the state is deterministic on silicon and in simulation.
retroSoC Applications
app/ contains the firmware applications and the components assembled by those
applications. It builds on the freestanding SDK in ../crt and keeps
application policy separate from common runtime and HAL code.
Layout
| Path | Purpose |
|---|---|
apps/ |
Selectable application profiles. Each profile owns main.c and an app.mk source manifest. |
board/ |
Board-specific device drivers and public board headers. |
media/ |
WAV, video, and visual-demo components with public media headers. |
middleware/ |
Application middleware configuration and integration, including FatFs. |
network/ |
Optional network or user-IP integration. |
ports/ |
Ports and configuration for external libraries, including LVGL and the HP Linux/OpenSBI platform. |
benchmark/ |
Project integration for benchmark workloads, including CoreMark. |
asm/ |
Standalone assembly firmware used by low-level simulation self-tests. |
Versioned third-party source trees are managed by the setup flow. Do not reformat or treat them as ordinary application code: use their integration directory and setup tooling when updating FatFs, CoreMark, or LVGL.
Application Profiles
The build selects an application with APP=<name>. The supported profiles are:
| Profile | Description |
|---|---|
benchmark |
Fixed-workload memory and DMA baseline with machine-readable wait counters and readback checksums. |
bringup |
Manual startup diagnostic with architecture details and crypto AES/SHA known-answer self-test. |
ci_smoke |
Fast deterministic CI smoke test for UART, ARCHINFO V2, LP external IRQ dispatch when CSR-enabled, RNG, crypto AES/SHA, SDRAM mapped access, and test-status completion. |
coremark |
SRAM-resident Hazard3 CoreMark measurement; use the committed quick or standard profile. |
debug |
Minimal SRAM image used only by the Hazard3 OpenOCD/GDB acceptance flow. |
hp_boot |
SRAM-resident LP loader that validates typed V2 Linux, smoke or RT-Thread bundles, loads SDRAM, releases HP, and monitors the workload-specific mailbox verdict. |
apu_release |
PSRAM-resident LP/HP APU evidence flow: LP-only microcode/KWS model load, ownership handoff to RV64 HP, HP-submitted WAV/KWS jobs with T-Head XTheadCmo dcache maintenance, and LP-only register fault probe. |
shell |
Interactive application that adds shell services, board drivers, media, FatFs, CoreMark, and UserIP integration. |
xpi_flash_loader |
SRAM-resident, GDB-called service image for sector-preserving JTAG programming of the qualified NSS0 NOR. |
The application manifest is loaded from app/apps/<name>/app.mk. It appends
APP_SRCS and, when necessary, APP_INC_DIRS to the SDK sources selected by
the central build.
NPU-P5 acceptance extends existing compositions rather than adding an APP.
NPU_P5_ACCEPTANCE=YES is valid only with ci_smoke or hp_boot and is part
of the reproducible variant key. The LP path links the generated KWS plan into
ci_smoke, uses the real LP completion interrupt, and writes the normal
SYSCTRL verdict. The RV64 HP smoke bundle assigns resource 9 to hart 1, runs
the same plan with polling and 64-byte T-Head XTheadCmo dcache maintenance, then returns
ownership before LP publishes the final verdict. The option defaults to NO,
preserving normal PR firmware size and behavior.
HP_JTAG_DEBUG=YES is an hp_boot debug aid: the LP selects the HP
(OpenC906) JTAG target before releasing the HP core, so a debugger can attach
from the first HP instruction. It defaults to NO and is behavior-neutral
when off. It is deliberately excluded from the variant key because debug runs
are not qualification evidence; toggling it requires touching an app source
to trigger a rebuild.
NPU-P6 likewise reuses APP=hp_boot; it does not add an application profile
or public ABI. NPU_P6_ACCEPTANCE=YES selects a private qualification payload,
and NPU_P6_WORKLOAD=kws|vww selects one frozen generated plan. The payload
reads a CRC-protected 100-case shard from the existing HP Image slot, runs
the portable C and production NPU paths through CPU Softmax, measures both
with HP rdcycle, and emits fail-closed per-case records. The first ten global
cases also overlap an identical GA2D DMA copy with both measured paths.
Normal and P5 builds remain unchanged because P5 and P6 acceptance flags are
mutually exclusive and both default to NO.
Build and simulate the supported profiles from the repository root:
# Bringup firmware and Verilator simulation
make CONFIG=configs/ci/ihp130.mk SIMU=VERILATOR firmware sim
# Explicitly run the CI smoke firmware used by regressions
make CONFIG=configs/ci/ihp130.mk APP=ci_smoke SIMU=VERILATOR firmware sim
# Shell firmware and Verilator simulation
make CONFIG=configs/ci/ihp130-shell.mk SIMU=VERILATOR firmware sim
# IHP130/Hazard3 Verilator baseline; result is written below build/*/meta/
make CONFIG=configs/benchmark/ihp130-hazard3.mk SIMU=VERILATOR benchmark-report
# IHP130/Hazard3 fixed-workload CoreMark; result is written to meta/coremark.json
make CONFIG=configs/benchmark/ihp130-hazard3-coremark.mk \
SIMU=VERILATOR SOC_SIM_TIME=7200 coremark-report
# Hazard3 remote-bitbang, OpenOCD, and GDB acceptance flow
make CONFIG=configs/ci/ihp130-debug.mk SIMU=VERILATOR debug-sim
# Build the locked OpenSBI/Linux/initramfs set and LP/HP flash bundle
make setup-hp-linux
make CONFIG=configs/ci/ihp130-hp.mk hp-bundle
# Build and test the pinned RV64 M-mode RT-Thread payload on HP hart 1
make setup-hp-rtthread
make CONFIG=configs/ci/ihp130-rtthread.mk SIMU=VERILATOR hp-rtthread-sim
# Build the SRAM-resident XPI NOR loader used by the host JTAG tool
make CONFIG=configs/ci/ihp130-xpi-flash-loader.mk firmware
For a firmware-only build, omit SIMU=VERILATOR sim.
The Verilator harness uses a zero-delay SDRAM protocol model so that memory and DMA readback are checked in the fast emulator. The Icarus testbench keeps the Micron SDRAM timing model and remains the timing-oriented behavioral flow.
Adding an Application
- Create
app/apps/<name>/main.candapp/apps/<name>/app.mk. - List the application-owned sources in
APP_SRCSand export only required include directories throughAPP_INC_DIRS. - Add
<name>to the allowedAPPvalues in the top-levelMakefile; this keeps profile selection explicit and rejects misspellings. - Add a committed configuration profile under
configs/that selectsAPP := <name>and the required ISA, CSR, and linker options. - Add host tests for deterministic parsing or utility code, and add a regression command when the application must execute in simulation.
Applications should consume public SDK headers through <retrosoc/...>.
Application-specific public headers belong below their own component include
directory, such as board/include/retrosoc/board/ or
media/include/retrosoc/media/.
The shell's user-IP integration follows the same boundary under
network/userip: its public demo entry point is namespaced below
include/retrosoc/network/, while the slot 1 timer and slot 2 GPIO register
tables remain private to the component. Generic slot selection and checked
APB-window access come from <retrosoc/hal/user_ip.h>.
DMA users must select an explicit SDK channel. UART0 owns channel 0, I2C0 channel 1, I2C1 channel 2, media/benchmark clients serialize on bulk channel 3, and crypto reserves channels 4/5. See DMA MVP before adding a concurrent DMA client.
The SD/SDIO HAL exposes rs_sd_memory_* for SD Memory v2 block devices and
rs_sdio_function_* for SDIO functions; these APIs must not be conflated.
Bring-up can run the controller ID/capability/IRQ self-test without a card.
The delivered software is limited to fixed-present 3.3 V SDR, 1/4-bit
operation, aligned SG DMA buffers, and the validated 72 MHz 24/36 MHz versus
>=100 MHz 50 MHz clock boundary. It makes no filesystem, hotplug,
compliance, or vendor Wi-Fi claim.
Self-owned application C/H code follows the project
MISRA C:2012 Amendment 2 policy. Managed upstream
sources and exclusions listed in quality/embedded_c_policy.json are outside
that scope; project glue must not be presented as evidence of upstream MISRA
conformance.
Quality Checks
Run the shared checks from the repository root before submitting changes:
make sw-format-check
make sw-policy-check
make sw-host-test
python3 -m pytest -q
The embedded-C checks apply to self-owned code and deliberately exclude managed
third-party source trees. Required-rule deviations need a reviewed entry in
quality/misra/deviations.md. Use the
repository regression suites for end-to-end
firmware, RTL, netlist, synthesis, and timing coverage:
make regress-pr
make regress-nightly
See the repository README for prerequisites, supported configurations, and build artifact locations.
For SOC=TINY, bringup and ci_smoke use the MCU acceptance composition. It
boots through XPI into SRAM, checks CPU C/A behavior and bus exceptions, DMA
(including UART requests), interrupts, RTC, GPIO, UART1 and I2C error completion,
then verifies watchdog reset by completing after the next NOR boot. It uses
SYSCTRL terminal status. The small asm/tiny_boot.S image separately qualifies
the synthesized SRAM/pad path; it is not a replacement for the full RTL test.