summaryrefslogtreecommitdiff
path: root/ports/risc-v64/gnu/example_build/erbium/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'ports/risc-v64/gnu/example_build/erbium/README.md')
-rw-r--r--ports/risc-v64/gnu/example_build/erbium/README.md140
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)