Refactored, consolidated, and cleaned up RV32/RV64 ports#536
Merged
Conversation
…85 GNU (eclipse-threadx#452) (eclipse-threadx#514) The Cortex-M33, M55, and M85 GNU ports incorrectly include tx_initialize_low_level.S as a library source in CMakeLists.txt. This file is board-specific initialization code that users must customize for their hardware, and including it in the library causes linker conflicts when users provide their own implementation (e.g., via CMake FetchContent). This change aligns these ports with the established pattern used by Cortex-M0/M3/M4/M7 GNU ports: - Move tx_initialize_low_level.S from src/ to example_build/ - Remove it from CMakeLists.txt target_sources - Add sample_threadx.c to example_build/ for consistency Signed-off-by: An Dao <webmaster@taktflow-systems.com>
Phase 1a — Clang port: use GNU assembly sources
- Delete ports/risc-v32/clang/src/ (all 8 .S files had no Clang-specific
directives; diverged only due to missing bug fixes)
- Update clang/CMakeLists.txt to compile from ../gnu/src/
- Change .global -> .weak for _tx_initialize_low_level in gnu/src/
(allows BSP override without linker conflicts; adopted from Clang port)
Phase 2a — tx_port.h consolidation
- Create ports/risc-v32/common/tx_port_riscv32_common.h with all
definitions shared between GNU and Clang ports
- Reduce risc-v32/gnu/inc/tx_port.h to a thin wrapper (adds regression
test extension block + version string)
- Reduce risc-v32/clang/inc/tx_port.h to a thin wrapper (version string
only, no regression test block)
Phase 2b — RV64 LONG/ULONG documentation
- Add prominent comment in risc-v64/gnu/inc/tx_port.h explaining why
LONG/ULONG are intentionally 32-bit on RV64 (ThreadX ABI requirement)
Phase 3a — Shared CMake helper
- Create cmake/threadx_riscv_port.cmake with threadx_add_riscv_port()
- Reduce all three port CMakeLists.txt to ~8 lines each
Phase 4a/b/c/d — Shared example-build drivers
- Create canonical files in ports/risc-v_common/:
inc/csr.h (uintptr_t, works RV32+RV64)
example_build/plic/ (plic.c, plic.h)
example_build/uart/ (uart_qemu_ns16550.c/h; static inline putc_nolock)
example_build/trap/ (trap_qemu.c; XLEN-portable mcause constants)
- Replace per-example copies with symlinks in all qemu_virt dirs and cva6_ariane
- Fix OS_IS_INTERRUPT typo (was OS_IS_INTERUPT) in shared trap_qemu.c
- Gate print_hex() behind TX_RISCV_TRAP_DEBUG
Phase 5a — RV64 QEMU CI test
- Add ports/risc-v64/gnu/example_build/qemu_virt/test/
threadx_test_tx_gnu_riscv64_qemu.py
Phase 6a — entry.s → entry.S rename
- Normalize case on all 4 example entry point files
Housekeeping
- Rename azrtos_test_* → threadx_test_* (eliminate Azure RTOS branding)
- Update CMakeLists.txt reference to match renamed test script
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fix two pre-existing bugs in the RV32 GNU port assembly: 1. tx_thread_schedule.S: Solicited return path restores mstatus from slot 14 before csrw to avoid clobbering mstatus with the fcsr value that t0 held after the FP register restore block. 2. tx_thread_system_return.S: FP callee-saved registers were saved unconditionally before checking mstatus.FS, causing an illegal instruction trap (mcause=0x2) when a thread with FS=Off (lazy FPU, thread has never used FP) voluntarily yielded. Apply the same mstatus.FS guard pattern used in tx_thread_context_save.S: read mstatus first, isolate FS[1:0] bits, and skip fsw/fsd instructions if FS == Off. Also fix cmake include path in all three port CMakeLists.txt files (risc-v32/gnu, risc-v32/clang, risc-v64/gnu) to use a path relative to CMAKE_CURRENT_LIST_DIR so the shared threadx_riscv_port.cmake helper is found correctly whether ports are built standalone or as a subdirectory of the test framework. Disable -Wconversion for the RV64 test configuration: ULONG = unsigned int (32-bit) is intentional for ThreadX ABI compatibility, but causes spurious conversion warnings when sizeof() (size_t, 8 bytes on RV64) is used in arithmetic with ULONG throughout common/src/. Verified: 95/95 RV32 regression tests pass with QEMU virt. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment out the riscv job in the regression workflow and remove it from the deploy job's needs list. The job definition is preserved in-place for easy re-enablement. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…64 merge ports/risc-v64/gnu/inc/tx_port.h: - Add TX_TIMER_INTERNAL_EXTENSION, TX_THREAD_CREATE_TIMEOUT_SETUP, and TX_THREAD_TIMEOUT_POINTER_SETUP to store the thread timeout pointer in a VOID * extension field rather than truncating it into a 32-bit ULONG. Mirrors the win64 port pattern. Also silences -Wunused-parameter in _tx_thread_timeout via TX_PARAMETER_NOT_USED. - Define TX_TIMER_EXTENSION_PTR_DEFINED as a portable sentinel so test code can detect this mechanism without checking _WIN64. test/tx/regression/threadx_thread_basic_execution_test.c: - Replace #if defined(_WIN64) guard with the portable #if defined(_WIN64) || defined(TX_TIMER_EXTENSION_PTR_DEFINED) so the extension-pointer path is taken on RV64 as well. test/tx/cmake/riscv/regression/CMakeLists.txt: - Include testcontrol_weak_defaults.c (added by the win64 merge) as an OBJECT library so the weak symbol definitions are always linked into every test binary, avoiding link failures against the new weak symbols in testcontrol.c (abort_all_threads_suspended_on_mutex, etc.). Verified: 95/95 tests pass for both RV32 and RV64 with QEMU virt. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
052333b to
a8b2656
Compare
…ssion builds testcontrol_weak_defaults.c provides __attribute__((weak)) definitions for abort_all_threads_suspended_on_mutex, suspend_lowest_priority, and abort_and_resume_byte_allocating_thread. These are called from libthreadx when TX_REGRESSION_TEST is defined. GNU ld does not extract objects from a static archive to satisfy undefined strong references using weak symbols, so bundling testcontrol_weak_defaults.c in the test_utility OBJECT library was not sufficient for the standalone threadx_initialize_kernel_setup_test (which doesn't link test_utility). Fix: build testcontrol_weak_defaults.c as a separate OBJECT library (test_weak_defaults) and include it via $<TARGET_OBJECTS:test_weak_defaults> in every test executable, including the standalone one. Applied the same fix to both test/tx and test/smp regression cmake. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The riscv-collab riscv64-unknown-elf toolchain (installed to /opt/riscv
by install_riscv.sh) is built without multilib and does not ship an
rv32im/ilp32 libgcc. When -nodefaultlibs is used, -lgcc resolves to
the rv64 libgcc.a which does not define rv32-only helpers such as
__clzsi2, causing linker errors in fll.c.
The Ubuntu gcc-riscv64-unknown-elf package is built with full multilib
support and correctly resolves -lgcc to rv32im/ilp32/libgcc.a for
-march=rv32imc_zicsr -mabi=ilp32 targets.
Fix: hard-code /usr/bin/riscv64-unknown-elf-{gcc,g++,...} in the
toolchain file so the multilib Ubuntu compiler is always used regardless
of PATH order, and update the comment to document the requirement.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…olchain The riscv-collab toolchain (/opt/riscv) is built without rv32 multilib, so its libgcc does not define __clzsi2 — the helper GCC emits for __builtin_clz() on targets lacking a hardware CLZ instruction (fll.c). Add bsp/clz.c with a weak __attribute__((weak)) __clzsi2 implementation so the build is self-contained regardless of which riscv64-unknown-elf toolchain is in use. The weak attribute ensures a libgcc-provided strong symbol (e.g. from the Ubuntu gcc-riscv64-unknown-elf multilib) takes precedence when available. Also update cmake/riscv64-gcc-rv32imc.cmake to resolve riscv64-unknown-elf-gcc via PATH (dropping the hard-coded /usr/bin prefix), so the riscv-collab toolchain in /opt/riscv/bin is picked up when it appears first in PATH. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CMake consumes CMAKE_TOOLCHAIN_FILE internally before the project runs, so it never appears in any CMakeLists.txt read() call, triggering the "Manually-specified variables were not used by the project" warning. Reference the variable explicitly via message(STATUS ...) to suppress the warning and provide useful diagnostic output during configuration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1a — Clang port: use GNU assembly sources
Phase 2a — tx_port.h consolidation
Phase 2b — RV64 LONG/ULONG documentation
Phase 3a — Shared CMake helper
Phase 4a/b/c/d — Shared example-build drivers
inc/csr.h (uintptr_t, works RV32+RV64)
example_build/plic/ (plic.c, plic.h)
example_build/uart/ (uart_qemu_ns16550.c/h; static inline putc_nolock)
example_build/trap/ (trap_qemu.c; XLEN-portable mcause constants)
Phase 5a — RV64 QEMU CI test
Phase 6a — entry.s → entry.S rename
Housekeeping