AFOliveira opened a new pull request, #20618:
URL: https://github.com/apache/nuttx/pull/20618
## Summary
Fixes a hang on Erbium: any conversion between `float` and a 64-bit integer,
such as `(int64_t)f`, `lroundf()` or `expf()`, stopped the system with no
output.
ET-Minion raises exception codes above 15: 25 and 26 (instruction bus and
ECC error), 27 and 28 (load and store split-page fault) and 30 (M-code
emulation). Code 30 is raised by `FDIV.S`, `FSQRT.S`, `FCVT.L.S`, `FCVT.LU.S`,
`FCVT.S.L`, `FCVT.S.LU`, `FENCE.I`, `SFENCE.VMA` and some ET packed
instructions, which have no hardware implementation. `riscv_dispatch_irq()`
uses the exception code as the IRQ number, so with the default
`RISCV_MAX_EXCEPTION` of 15, code 30 ran the UART0 interrupt handler, which
returned to the faulting instruction forever.
Five commits:
1. `test_emu.py`: fix false results. It required an ostest marker that only
nuttx-apps since 2026-09-15 prints, its failure pattern matched lowercase
"error" in lines that are not failures (the ostest watchdog latency warning),
and the reset PC was fixed instead of read from the ELF entry point.
2. Set `RISCV_MAX_EXCEPTION` to 31 for Erbium, name the ET-Minion codes with
`RISCV_CUSTOM_EXCEPTION_REASONS` and attach codes 16 to 31 to
`riscv_exception()`. Each is now reported once with its name, EPC and MTVAL and
the system stops. Interrupt IRQ numbers move up by 16 (UART0 from 30 to 46).
3. Docs: list the instructions that trap and the libm functions that use the
conversions.
4. Emulate `FCVT.L.S`, `FCVT.LU.S`, `FCVT.S.L` and `FCVT.S.LU`. With the FPU
enabled GCC uses them for every float/64-bit integer conversion and, unlike
`-mno-fdiv` for division, no option avoids them. New
`CONFIG_ERBIUM_MCODE_EMULATION` (default y with the FPU):
`riscv_dispatch_irq()` passes exception 30 to `erbium_mcode_emulate()`, which
makes the `mstatus.FS` and rounding-mode checks the hardware makes for a native
F instruction, converts with integer-only code (RISC-V rounding, saturation and
fflags rules; a subnormal input reads as zero and sets fflags bit 31, as
ET-Minion does for `FCVT.W.S`) and resumes after the instruction. The trap path
does not save F registers, so the result goes to the live register through a
table of `fmv` instructions. `FDIV.S`, `FSQRT.S`, `FENCE.I`, `SFENCE.VMA` and
the packed instructions still stop the system.
5. Docs: describe the emulation.
## Impact
- Erbium only. No common RISC-V code changes;
`RISCV_CUSTOM_EXCEPTION_REASONS` already exists for this.
- New files `arch/risc-v/src/erbium/erbium_mcode.c`, `erbium_mcode.h`,
`erbium_mcode_fpr.S`, built with `CONFIG_ERBIUM_MCODE_EMULATION`.
- Cost: about 260 extra instructions per conversion in `erbium_emu` (20,000
conversions: 26.85 ms against 0.90 ms for a native `fcvt.w.s` loop).
## Testing
Emulator only (`erbium_emu`, ET-platform `836a4ab600e9`); Erbium silicon is
not available yet. Host Ubuntu x86_64, xPack `riscv-none-elf-gcc` 14.3.0-1,
nuttx-apps master.
- `(int64_t)f` with the emulation disabled: one trap, then
```
riscv_exception: EXCEPTION: M-code emulation. MCAUSE: 000000000000001e, EPC:
000000004001b3ce, MTVAL: 00000000c02795d3
riscv_fault_handler: PANIC!!! Exception = 000000000000001e
```
Without these changes the emulator logs about 665,000 cause-30 traps in 8
s and the console stays silent.
- All four instructions in every rounding mode (static and dynamic) against
an exact reference model: 981/981 match, also with `CONFIG_ARCH_LAZYFPU`; a
second vector set 832/832.
- Saved-context cases (register classes, x0, sp, fflags accumulation,
conversion in an ISR, across a context switch): 15/15. 1000 conversions give
exactly 1000 traps.
- libm: `expf(1)`, `logf(10)`, `powf(2, 10)`, `sinhf(1)`, `rintf`,
`lroundf`, `llroundf` return correct values.
- Faults: reserved static rm, dynamic frm 5-7 and FS off report "Illegal
instruction"; `fdiv.s`, `fsqrt.s`, `fence.i` and a gp destination report
"M-code emulation"; each stops the system once.
- `erbium_mcode.o` contains no FP instruction; the `.S` table holds only 32
`fmv.x.w` and 32 `fmv.w.x`.
- `minion:ostest` Make and CMake: exit status 0. `minion:nsh` Make, CMake
with four emulator harts, and with the FPU disabled: pass (`test_emu.py`).
- `tools/testbuild.sh` for `minion:nsh`, `minion:ostest`, `rv-virt:nsh64`,
Make (`-Werror`) and CMake: pass.
- `tools/checkpatch.sh -c -u -m -g`: pass. `Documentation` `make html` (`-j
auto -W`, locked Pipfile): pass.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]