Skip to content

arch/risc-v64: Add lazy FPU stacking and QEMU functional tests for GNU port#549

Open
Winstonllllai wants to merge 3 commits into
eclipse-threadx:devfrom
Winstonllllai:rv64-fix-feature
Open

arch/risc-v64: Add lazy FPU stacking and QEMU functional tests for GNU port#549
Winstonllllai wants to merge 3 commits into
eclipse-threadx:devfrom
Winstonllllai:rv64-fix-feature

Conversation

@Winstonllllai

Copy link
Copy Markdown
Contributor

This PR adds functional enhancements for the ThreadX RISC-V 64-bit (RV64) GNU port, mirroring the improvements delivered for RV32 in #513.

Lazy FPU Stacking:

  • Updated _tx_thread_context_save and _tx_thread_context_restore to save mstatus/sstatus and skip FP register save/restore when the FS field (bits 14:13) is Off.
  • Applied to nested save, non-nested save, nested restore, no-preempt restore, and preempt restore paths.
  • Supports TX_RISCV_SMODE (reads sstatus vs mstatus as appropriate).
  • Reduces context switch overhead for threads that do not use floating point.

Automated Testing Framework:

  • Introduced a Python-based E2E test harness using QEMU + GDB (azrtos_test_tx_gnu_riscv64_qemu.py).
  • Added qemu_virt/CMakeLists.txt and registered the check-functional-riscv64 target.
  • Validates multitasking, timer interrupts, FPU context preservation, and priority-based preemption.
  • Extended demo_threadx.c with fpu_test_val and adjusted thread timing for GDB-driven verification.
    QEMU Boot & Link Fixes:
  • Placed _start in a .text.boot section and added KEEP(*(.text.boot)) to link.lds so the entry point is pinned at 0x80000000 (QEMU virt reset PC).
  • Linked kernel.elf with --whole-archive to ensure all ThreadX symbols resolve on RV64.

How to Run Tests

cmake -B build_qemu -DCMAKE_TOOLCHAIN_FILE=cmake/riscv64_gnu.cmake
cd build_qemu
make check-functional-riscv64

Tested on QEMU virt machine (rv64gc).
Please let me know if there is anything I should improve or if I missed anything.

Save mstatus/sstatus to stack slot 29 and skip floating-point register
save/restore when FS is Off (bits 14:13). This avoids unnecessary FP
context work for threads that do not use the FPU.

- context_save: check FS in nested and first-level interrupt paths
- context_restore: gate FP restore on nested, no-preempt, and preempt paths
- use sstatus when TX_RISCV_SMODE is defined, otherwise mstatus
Wire the QEMU virt demo into the CMake build system and add a
Python/GDB functional test runner, mirroring the risc-v32/gnu port.
- Add qemu_virt/CMakeLists.txt to build kernel.elf and register the
  check-functional-riscv64 target (requires Python3; skipped if absent)
- Link kernel.elf with --whole-archive so all ThreadX symbols resolve
- Pin _start at 0x80000000 via .text.boot in entry.s and
  KEEP(*(.text.boot)) in link.lds
- Extend demo_threadx.c with fpu_test_val and shorten thread_0 sleep
  for GDB-driven FPU, timer, and preemption checks
- Add test/azrtos_test_tx_gnu_riscv64_qemu.py; verified passing on
  QEMU virt (FPU, timer interrupt, preemption)
@fdesbiens fdesbiens requested review from akifejaz and fdesbiens June 16, 2026 14:27
@fdesbiens fdesbiens self-assigned this Jun 16, 2026
@fdesbiens fdesbiens moved this to In review in ThreadX Roadmap Jun 16, 2026
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Winstonllllai.

Thank you for this contribution. @akifejaz and I will review it.

@Winstonllllai

Copy link
Copy Markdown
Contributor Author

Hi @fdesbiens and @akifejaz ,
Thank you both for taking the time to review this contribution. I appreciate it and look forward to your feedback.

@akifejaz

akifejaz commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Hi @Winstonllllai please see comments below

@akifejaz akifejaz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Winstonllllai I see multiple issue at first glance some of those I already pointed in your previous PR : #513

and

  • i see no significance for test/ dir & *.py script you can keep it for local testing. -- please also remove from RV32 port (PR : #513)
  • the "TX_RISCV_SMODE" is obviously from some other PR, seems like merging issue, you should not be adding these changes
  • There are multiple new empty asm symbols in there, I'm not sure why you've added those if you chose to keep them empty.
  • also please change the comments carefully, I see you updated the comments wrongly, the earlier versions were fine.
  • the file name is entry.S but your cmake calls it `entry.s' (small s), it should give build fails, please double check changes when submit PR

Also AI generated code should be marked properly. @fdesbiens when you get time, please also share the AI coding guidelines (if we have any) to him.

Revert accidental RV64 qemu_virt test/CMake integration changes and keep this branch
focused on lazy FPU context handling only. Also remove unintended TX_RISCV_SMODE-based
mstatus/sstatus save path and align comments/logic to mstatus-only behavior.
@Winstonllllai

Copy link
Copy Markdown
Contributor Author

Hi @akifejaz . Thanks for the review — I've addressed the points below:

  1. test/ & .py — Removed from this PR; kept locally only. Will do the same for RV32 (arch/risc-v32: Implement lazy FPU, GP relaxation, and QEMU automation for GNU port #513).
  2. TX_RISCV_SMODE — Removed the unintended sstatus branches; lazy FPU now uses mstatus only, aligned with RV32.
  3. Empty asm labels — These are branch targets for the lazy FPU skip path (FS == Off), not standalone empty symbols.
  4. Comments — Reverted incorrect changes; now reference mstatus only.
  5. entry.s — QEMU CMake integration removed, so that issue is gone.
  6. AI-generated code — Only the QEMU test script was AI-assisted; it has been removed from this PR.

The PR is now scoped to lazy FPU context save/restore only.

@Winstonllllai

Copy link
Copy Markdown
Contributor Author

For the RV32 cleanup requested in review, I opened a separate follow-up PR: #552. It removes the local-only QEMU test script and related CMake/test-only changes from the RV32 port.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

3 participants