Files
retroSoC/app
maksyuki 4ce34734ce fix(hp/linux): park the C906 internal-CLINT STIMECMP at cold boot
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.
2026-10-12 22:32:26 +08:00
..

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

  1. Create app/apps/<name>/main.c and app/apps/<name>/app.mk.
  2. List the application-owned sources in APP_SRCS and export only required include directories through APP_INC_DIRS.
  3. Add <name> to the allowed APP values in the top-level Makefile; this keeps profile selection explicit and rejects misspellings.
  4. Add a committed configuration profile under configs/ that selects APP := <name> and the required ISA, CSR, and linker options.
  5. 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.