Skip to content

Add ARM semihosting SYS_WRITE (0x05) operation support#184

Open
millerjef wants to merge 1 commit intorenode:masterfrom
millerjef:feature/arm-semihosting-sys-write
Open

Add ARM semihosting SYS_WRITE (0x05) operation support#184
millerjef wants to merge 1 commit intorenode:masterfrom
millerjef:feature/arm-semihosting-sys-write

Conversation

@millerjef
Copy link
Copy Markdown

Summary

Implements the missing SYS_WRITE (0x05) semihosting operation to complete ARM semihosting support in Renode.

This enables printf() and other standard I/O functions to work correctly for ARM firmware compiled with newlib's rdimon.specs semihosting support.

Background

ARM semihosting allows embedded firmware to perform I/O operations by making supervisor calls that the debugger/emulator handles. Renode already has partial semihosting support with SemihostingUart, implementing:

  • ✓ SYS_READC (0x07) - Read single character
  • ✓ SYS_WRITEC (0x03) - Write single character
  • ✓ SYS_WRITE0 (0x04) - Write null-terminated string

However, when firmware uses standard newlib functions like printf(), the C library's _write() implementation calls SYS_WRITE (0x05) instead of the simpler operations above. Without this operation, printf-based output doesn't work.

Changes

File: src/Emulator/Cores/Arm/Arm.cs

Added case 5 (SYS_WRITE) handler in the DoSemihosting() method:

  • Uses TryTranslateAddress() with proper error handling for robustness
  • Reads ARM semihosting parameter block from memory containing:
    • word[0]: File handle (1 = stdout, 2 = stderr)
    • word[1]: Data pointer (memory address of buffer)
    • word[2]: Byte count (number of bytes to write)
  • Transfers data from emulated memory to SemihostingUart
  • Returns 0 (success) to firmware indicating all bytes were written
  • Also improved error handling for existing SYS_WRITEC/SYS_WRITE0 operations

Testing

Tested with STM32 firmware using FreeRTOS and semihosting-based console output. Printf statements now appear correctly in Renode's UART output.

Related Issues

  • Addresses #681 - ARM Semihosting support request
  • Related to #699 - Rust semihosting UART access

ARM Semihosting Specification

Per ARM Semihosting Documentation, SYS_WRITE (0x05) writes to a file descriptor or stream, with register r1 pointing to a parameter block containing file handle, data pointer, and length.

🤖 Generated with Claude Code

Implements SYS_WRITE semihosting operation to enable printf() output
from ARM firmware using newlib's rdimon.specs semihosting support.

Changes:
- Added case 5 (SYS_WRITE) handler in DoSemihosting()
- Uses TryTranslateAddress with proper error handling for robustness
- Reads parameter block: file handle, data pointer, byte count
- Transfers data from memory to SemihostingUart
- Returns 0 (success) to firmware
- Also improves error handling for existing SYS_WRITEC/SYS_WRITE0 cases

This completes the semihosting operations needed for firmware testing,
complementing existing SYS_READC, SYS_WRITEC, and SYS_WRITE0.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Jeff Miller seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants