Of course it runs NetBSD

(and OpenBSD too)

The first release could only boot Linux. Now we can also run NetBSD (5.1) and OpenBSD (5.3).


And what about FreeBSD ?

FreeBSD does not support Sparc32, only Sparc64

How does Solaris fares ?

Need some work. I have not even managed to install Solaris8 with QEMU.

But I want NextSTEP !

Dream on.



For 32bits Sparcs, OSes must use different code paths for each CPU model, particularly for MMU and cache management : There are coherent and non coherent caches, split and shared instruction and data TLBs, and a variety of bugs which makes actual memory management a bit different than what is described by the « Sparc Reference MMU » standard.


We emulate the MicroSparcII a.k.a. Fujitsu MB86904 “swift” CPU. This CPU was used in uniprocessor workstations like the SS5. It is also the CPU used as default with QEMU.

The MicroSparcII is a V8 CPU (with integer multiply and divide) has non dma-coherent split instruction and data caches, and shared instruction and data TLBs.

Whenever a page mapping is updated, typically after a page fault, the TLBs must be made coherent with the new mapping :

  • According to the standard, one should issue “TLB flush” instructions. The MMU will afterwards automatically update a TLB with the new virtual to physical mapping. Linux does that.
  • NetBSD (and OpenBSD) does a MMU probe which happens to load a TLB with the new mapping. As the MicroSparcII has shared TLBs, it works both for instruction and data faults.

This manual loading of TLBs is a normal procedure for CPUs doing software based tablewalking and TLB management, not for the hardware based SparcV8.

Our CPU has separate instruction and data TLBs (and it will not change). As it would be quite difficult to update and load both TLB arrays, to support the BSD method, probing a MMU mapping actually flushes all TLBs.

This mechanism is enabled by the “BSD_MODE” constant in cpu_conf_pack.vhd, this unnatural behaviour could slightly degrade Linux performance.


The “BSD_MODE” constant also activates a fix for a bug in the following code in NetBSD (sys/arch/sparc/sparc/locore.s) :

wr %g2,0xb20,%psr
ldd [%g5],%fp

Here, the wr %g2,0xb20,%psr instruction changes the current window. The following instruction, ldd, uses the %fp register which depends on the current register window. The SparcV8 standard indicates that the three instructions following a WRPSR must not depend on the changed bits.

I wonder how that code can run on actual SparcStations…


Linux Cache

Linux does sensible TLB management, but does ackward things for the cache: Instead of flushing it, it zeroes the tags, whereas NetBSD properly flushes cache lines. Maybe it is related to hardware bugs in the MicroSparcII. Support for these CPUs was added almost 20 years ago, finding the rationales now is probably impossible.

The Linux method has a negative impact on performance as we use multiple ways caches (and the MS2 used direct map) and all ways are flushed simultaneously, whereas with a proper cache flush, only the offending line could be discarded.


One of the goals of re-creating old hardware was to be able to run existing software and avoid developing simultaneously both the hardware and software. Working with NetBSD and OpenBSD also revealed a few bugs in our code. Being able to run several different operating systems enhance code coverage…


Our CPU is not exactly similar to any of the ‘90’s SPARCs. For optimal performance, the OSes should be adapted, using sane TLB and cache management.

Leave a Reply

Your email address will not be published. Required fields are marked *