diff options
Diffstat (limited to 'ports/risc-v64/gnu/example_build/erbium/README.md')
| -rw-r--r-- | ports/risc-v64/gnu/example_build/erbium/README.md | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/ports/risc-v64/gnu/example_build/erbium/README.md b/ports/risc-v64/gnu/example_build/erbium/README.md new file mode 100644 index 00000000..8cfa2828 --- /dev/null +++ b/ports/risc-v64/gnu/example_build/erbium/README.md @@ -0,0 +1,140 @@ +# ThreadX example for Erbium + +This directory runs the standard ThreadX demo on one hart of Erbium, the +16-hart RISC-V platform of the OpenHW Foundation CORE-ET project, using the +RISC-V64 GNU port in machine mode. The public `et-platform` functional +simulator, `erbium_emu`, is the reference target. + +## Hardware used + +| Item | Address | Notes | +|------|---------|-------| +| Hart 0 | - | RV64IMC, machine mode; other harts are parked | +| MRAM | `0x4000_0200` | 16 MiB window; the first 512 bytes belong to the boot flow | +| System registers | `0x0200_0000` | `SystemConfig` bit 6 enables the UART | +| UART0 | `0x0200_4000` | Original Shakti integration, polling, 115200 8N1 | +| Machine timer | `0x80F4_0200` | `mtime`, with `mtimecmp` at `+0x08` | +| PLIC | `0xA000_0000` | Machine-mode context of hart 0; sources 1 to 6 | + +## Port notes + +* **Soft float.** Erbium implements only part of the F extension: divide, + square root and conversions between single precision and 64-bit integers + raise an emulation exception. The example and the ThreadX library are + built for `rv64imc_zicsr_zifencei` with the `lp64` ABI, so the port saves + no FP state. `csr.h` rejects a build with F enabled. +* **No C library.** The `riscv64-unknown-elf` toolchain installed by + `scripts/install_riscv.sh` ships `lp64d` libraries only, so the example + links with `-nostdlib` and `board.c` provides `memset`. A missing runtime + helper shows up as a link error, not as a mix of ABIs. +* **No WFI.** The example never executes `wfi`, like the Zephyr Erbium + port. `TX_USE_WFI_IDLE` stays undefined, so the scheduler spins while + idle, and parked harts and fatal-trap halts spin as well. +* **Trap vector.** Erbium ignores `mtvec` base bits 11:1, so the trap + vector must be 4 KiB aligned. `trap_entry` is placed in its own 4 KiB + aligned section and used in direct mode. +* **PLIC.** The silicon hardwires source priorities to 1 and thresholds to + 0. The simulator models them as writable registers that reset to 0, so + `plic_init()` writes the hardwired values. Drivers register a callback and + enable their source with `plic_irq_enable()`. +* **Clocks.** The UART divisor assumes a 400 MHz input clock and the tick + assumes a 2 MHz `mtime` rate, the values used by the Zephyr and NuttX + Erbium ports. If the boot firmware programs other rates, define + `ERBIUM_UART_CLOCK_HZ` and `ERBIUM_MTIME_FREQ_HZ` when you build. +* **UART.** The console only polls. `uart_init()` sets the UART enable bit + in `SystemConfig` with a read-modify-write, which leaves the watchdog + setting as the boot flow left it. + +## Building + +Install the toolchain with `scripts/install_riscv.sh`, or put another +`riscv64-unknown-elf` GCC on `PATH`, then run: + +```bash +./build.sh +``` + +This configures `CMakeLists.txt` with `erbium_gnu.cmake`, builds +`libthreadx.a` for the soft-float ABI and links `build/demo_threadx.elf`. +Set `BUILD_DIR` to build elsewhere. + +## Running on the simulator + +Build `erbium_emu` from +[et-platform](https://github.com/aifoundry-org/et-platform). The example was +tested at revision `836a4ab600e93c3059bb58c898edbc37744cd8d0`: + +```bash +git clone https://github.com/aifoundry-org/et-platform.git +cd et-platform +git checkout 836a4ab600e93c3059bb58c898edbc37744cd8d0 +cmake -S erbium-hal -B build-hal -DCMAKE_INSTALL_PREFIX="$PWD/install" +cmake --build build-hal --target install +cmake -S sw-sysemu -B build-emu -GNinja -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_FLAGS=-Wno-error=unused-result \ + -DCMAKE_PREFIX_PATH="$PWD/install" +cmake --build build-emu --target erbium_emu +``` + +At that revision a release build with a distribution GCC that enables +`_FORTIFY_SOURCE` stops on an unused `write()` result in the UART model; +the `CMAKE_CXX_FLAGS` setting above keeps that warning from being an error. + +Load the ELF and start hart 0 at the MRAM load address, bypassing the boot +ROM: + +```bash +erbium_emu -elf_load build/demo_threadx.elf -reset_pc 0x40000200 \ + -minions 1 -single_thread -max_cycles 100000000 \ + -uart_rx_file /dev/null -uart_tx_file uart.log +cat uart.log +``` + +The log starts with `[UART0] : Erbium UART initialized`, followed by lines +from all eight demo threads. The simulator ends with a `max cycles reached` +error once the cycle budget is spent; judge the run by the UART log, not by +the exit status. With the default clocks one ThreadX tick is 2,000,000 +simulated cycles, so the 100,000,000-cycle run shows `thread_0` five times. + +The simulator verifies register accesses, the trap flow and the console. +It does not verify baud timing or the timer rate of real silicon. + +## Simulator regression tests + +With `erbium_emu` on `PATH`, run: + +```bash +ERBIUM_EMU=erbium_emu ./test/run_simulator_tests.sh +``` + +The UART test checks that a long polling write does not lose ThreadX ticks. +The PLIC test changes one source in timer context while a thread changes +another, and checks that neither update is lost. The runner builds both +images with CMake and Ninja and reports a failure if either check fails. +These tests use the simulator's UART drain rate, not physical baud timing. + +## Files + +| File | Purpose | +|------|---------| +| `entry.S` | Reset entry: parks other harts, sets `gp`, stack and `.bss` | +| `tx_initialize_low_level.S` | Trap vector and `_tx_initialize_low_level` | +| `trap.c` | Dispatches the timer, the PLIC and fatal exceptions | +| `board.c` | `board_init()` and `memset` | +| `plic.c`, `plic.h` | PLIC driver for the hart's machine-mode context | +| `hwtimer.c`, `hwtimer.h` | Periodic tick from `mtime` and `mtimecmp` | +| `uart.c`, `uart.h` | Polling console | +| `demo_threadx.c` | The standard ThreadX demo | +| `link.lds` | MRAM layout | +| `erbium_gnu.cmake` | Toolchain file: `rv64imc_zicsr_zifencei`, `lp64` | +| `CMakeLists.txt`, `build.sh` | Build of the library and the demo | +| `test/` | Simulator tests for UART timekeeping and PLIC updates | + +## References + +* [Erbium processor](https://github.com/openhwfoundation/core-et-erbium) +* [UART registers](https://github.com/openhwfoundation/core-et-erbium/blob/325b32b7efaa2c2ab9c91001c89d3f49a4740826/doc/uart.md) +* [CPU memory map](https://github.com/openhwfoundation/core-et-erbium/blob/325b32b7efaa2c2ab9c91001c89d3f49a4740826/doc/cpu_mm.md) +* [Platform interrupts](https://github.com/openhwfoundation/core-et-erbium/blob/325b32b7efaa2c2ab9c91001c89d3f49a4740826/doc/interrupts.md) +* [CPU subsystem](https://github.com/openhwfoundation/core-et-erbium/blob/325b32b7efaa2c2ab9c91001c89d3f49a4740826/doc/cpu_subsystem.md) +* [et-platform simulator](https://github.com/aifoundry-org/et-platform) |
