For many of us, open-source very sounds like ‘Linux’.
RISC-V is no exception, and the whole tooling ecosystem is built around Linux, GNU Compiler Collection (gcc), GNU Debugger (gdb), GNU binutils, etc…
Unfortunately, in a corporate environment, Windows market share is still fairly significant, so that nowadays, there is a good chance that the dev’s doing embedded firmware might well be using Windows7 or Windows10.
Hence the need for tools running on Windows platforms.
This blog post wraps up my findings, porting Whisper -the Western Digital RISC-V Instruction Set Simulator- to Windows.
Grab a Toolchain
The hardest part of the journey.
Obvious choice under Windows, Visual Studio does not fit the bill : Whisper implements both rv32 and rv64 ISA’s, meaning 128bits arithmetic (sign extensions) in this latter case. As Visual Studio does not support int128_t, this came to a dead-end.
Cygwin is not a good choice either, as it would drag in cygwin1.dll, causing a licensing issue.
Then comes MinGW. Weirdly, I’ve encountered many problems downloading it from osdn/SourceForge (corporate proxy?), but was fortunate enough to find it already pre-installed & bundled from Stephan T. Lavavej website. Icing on the cake ? It comes with Boost libraries pre-build !
About the Libraries
Whisper comes with some dependencies, which must be resolved in order to get ported to Win32 / Win64.
As I previously mentioned, Boost comes pre-built with Stephan T. Lavavej excellent MinGW distro. Check!
Whisper uses linenoise as its line editor. Linenoise itself is not Win32-friendly, but was ported by Yuji Hirose (cf. GitHub). Check!
Whisper uses JSON configuration files, parsing these using JSON for ModernC++. As Niels Lohmann mentions, ” Trivial integration. Single header file json.hpp. No library, no subproject, no dependencies, no complex build system. Vanilla C++11.” Check!
Then comes the porting of the Swerv-ISS itself.
The header <inttypes.h> now provides appropriate macros to print integer in a formatted manner.
Whereas gcc barks on %ld formatting strings used in conjunction with 64b integers, this porting issue was easy to spot and fix.
Windows provides it’s own <winsock2.h> to handle sockets. Easy fix.
MinGW comes with signal() in. Some rewriting, turning sigaction() calls into signal() calls. Easy fix.
Some of the system calls supported by the Linux emulation are definitely not straightforward to port to Windows.
However, in the scope of this porting, I was solely interested in Newlib emulation.
In ended up commenting out all the unnecessary system calls, keeping only those implemented in the Newlib.
mmap vs. malloc
Last but not least, Swerv-ISS emulates the main memory of the CPU via a call to mmap().
Fortunately, it does not request any specific address for this memory segment, so that this can be replaced by a simple malloc().
To sum up, porting Swerv-ISS to Windows represented a moderate effort, mostly because it’s a simple interpreter, with little software dependencies, and also because MinGW has become mature.