söndag 11 maj 2014

About once a year, I'm at some conference to present the OpenRISC project for a new audience. One part of the presentation is often a quick rundown of all the things that has happened since the year before. Problem is that there's just too much stuff going on as the project continues to grow. To remedy this, I'm planning to write a small summary every month, or every quarter (time will tell), both to remind myself of what we are doing, and to make it more visible to the casual observer that there is pretty cool stuff going on with this nifty little CPU and the things around it. As this is the first installment, I would really have to present everything that has happened over the last 15 years to give a complete picture. I will not do that. You will have to settle with a back log from last year's OpenRISC conference.

While writing this article, I had to constantly ask for help explaining
some of the concepts. This once again showed me how large this project
has become and how much in-depth expertise that is shared by the
participants. It also shows how fast things are moving, since most of
the above items are things that has happened only during the last six
months! I probably need to write a bit more often to avoid having to
write a novel each time, but enough introduction. I will now leave the stage to OpenRISC and it's friends...

Debian for OpenRISC

Perhaps the news item that has had the most coverage is the work done mainly by Christian Svensson to create a Debian port for OpenRISC. While OpenRISC, or rather the or1k architecture to be more precise, has been a supported target in the official Linux kernel since version 3.1, users have had very little support for creating a complete OpenRISC-based system. With the Debian port, things should be much simpler, and once the basic system is installed, your favorite package is just an apt-get install away. Naturally all packages aren't supported yet, and the package creation process has uncovered several bugs and missing features in the OpenRISC toolchain. The upside of this is that most of these bugs were fixed extremely fast, mostly by Stefan Kristiansson and Christian Svensson. As of now roughly 5000 packages have been built and packaged so far, thanks to Manuel A. Fernandez Montecelo. Many of the packages have been tested both in qemu and on a Digilent Atlys board with mor1kx. Apart from a multitude of library dependencies, the package list includes X.org, qt, scummvm, irssi and Fluxbox which means that you can now play games and chat somewhat comfortably on an OpenRISC system.

Atomic operations

When running multiple cores, or multiple threads on the same CPU, each thread or core needs to know if someone else is currently trying to access an exclusive resource, such as an UART or a part of a shared memory. Normally this is done in software with mutex operation, such as semaphores or spinlocks, and the requirement for implementing a mutex is that an mutex operation is never allowed to be interrupted. Previously on OpenRISC this was done by making a syscall that disabled all interrupts as it's first instructions. That way it could make sure it wasn't interrupted by something else while it was busy doing it's work. Unfortunately this method is quite slow, and just doing ls generates about 1700 system calls of which roughly 90% are mutex operations. Also, the syscall method won't work at all for multiple cores.

To improve the situation, Stefan Kristiansson has added two completely new instructions to the OpenRISC instruction called l.lwa (Load Word Atomic) and l.swa (Store Word Atomic). These two instructions form a load-link/store-conditional atomic operation, which can be read about in further detail on Wikipedia.
Apart from the updates to the architecture specification, Stefan has implemented the operations in cgen CPU description in binutils so that the toolchain knows about them and can use them, the instruction set
simulator or1ksim and in the RTL implementation mor1kx together with
test cases.

An interesting side note is that while no OpenRISC implementation has ever had atomic operations before, Stefan found mentions of a pair of operations in a very early version of the architecture specification, and decided to reuse these names.

Multicore

OpenRISC has traditionally been used as a single core CPU in a SoC, but there is an increasing demand for spreading workloads over several cores in a system. Of course, it has always been possible to instantiate as many OpenRISC cores as you can fit in an FPGA or ASIC. The problems arise when they need to cooperate to share resources like main memory or peripherals (exclusive accesses), spread a workload evenly between them (load balancing) and making sure that their local caches are kept in sync with each others (cache coherency).

For several years, Stefan Wallentowitz has been working on the necessary
hardware and software additions required for multicore OpenRISC as part of his research project OpTiMSoC. A few weeks ago he made an announcement that there now was a multicore OpenRISC demo SoC based on mor1kx running under FuseSoC. The required changes have been added to mor1kx, and apart from a special version of the newlib toolchain it uses unmodified versions of the software and hardware IP cores.

FuseSoC

During the last two or three years I have been working on a successor to the OpenRISC Reference Platform System on Chip (ORPSoC) that is used to run RTL simulations and provide a base for porting an OpenRISC SoC to a new FPGA board. The project was called ORPSoCv3 (to replace the old ORPSoCv2) and I did three releases before swiftly renaming it to FuseSoC. Why? you ask. Well, it turned out that there wasn't a single line of OpenRISC-specific code in FuseSoC, and I want it to be used as a general-purpose tool for building and simulating cores and SoCs for FPGA. This has become reality as it is now used for a SoC based on the eco32 CPU in addition to being the OpenRISC standard tool and other Open Source projects have shown interest as well.

Apart from the renaming and the never ending bug fixing, FuseSoC has gained many new features over the last six months. Some of the highlights include support for using SystemC in Verilator test benches, VHDL and using ISE to create images for Xilinx FPGAs. More detail can be found in the FuseSoC repository on github. The number of contributors continue to increase for every release which is a good indication that it is used by many people... or at least that many people find bugs.

ORPSoC Cores

The other part of the FuseSoC infrastructure is the collection of cores and systems that can be utilized by FuseSoC. The main repository is called orpsoc-cores and contains ready-made OpenRISC SoCs for different FPGA boards as well as the cores that are used on the boards.

Many new cores have been added as well, and there is currently 39 supported cores in total. For more details see the ORPSoC Cores repository on github.

Binutils

The de-facto standard open source toolchain for creating programs consist of two parts. The compiler (GCC, with LLVM getting more common as well) and binutils. Binutils can be summarized as everything but the compiler. This means the linker, assembler, archiver and tools for modifying ELF files. OpenRISC support in binutils was added 14 years ago, but since then, no improvements have been sent upstream.

There has been a huge amount of work over the last years to improve the OpenRISC binutils support, and earlier this year it was decided that these changes should be sent upstream. Having them in the official binutils distribution means that anyone who wants to make binutils for OpenRISC can now use the official binutils package.

In the OpenRISC case, sending the changes upstream wasn't completely trivial even though the code itself was in very good shape, as FSF (Free Software Foundation) who owns binutils need to have the written agreement of all contributors that they are OK with giving away to copyright of the code to FSF. That means that the first thing that had to be done was to go through all changes and hunt down all the people who have contributed.

I volunteered to take on this mind-numbing job, which wasn't made any easier as we switched VCS from SVN on OpenCores to GIT on github a few years ago, and renamed the architecture from or32 to or1k. Luckily, most people had been very good with updating changelogs, which made things a lot easier. In the meantime, Christian Svensson had split up the OpenRISC-specific changes to a set of patches that was sent in for review. When that was done, all contributors had to get a copyright assignment document mailed from FSF to sign and send back. As the patches were already reviewed, the rest of the process went quickly by when all the mails had been sent back.

Stefan Kristiansson and Christian Svensson are now the proud caretakers of the OpenRISC port which should be included in the next binutils release.

musl

While there are many things that most people agree on, there seem to be no such consensus when it comes to standard C libraries. Everyone seems to have their own specific use case that requires a brand new C library. OpenRISC already has support for glibc, uClibc and newlib, but the new kid on the block when it comes to embedded software is musl. musl is designed to be small and portable which suits the OpenRISC use case just fine. Stefan Kristiansson has prepared a musl port which is mostly done apart from some details about syscall handling that needs to be resolved first. Now we only need to port bionic and we're ready to take on Android.

mor1kx

The up-and-coming mor1kx OpenRISC RTL implementation is rapidly gaining new features, perhaps as a testament to it's more modular design compared to the original or1200 implementation. In addition to the atomic operations mentioned above and multiple bug fixes it now supports caches with more than two ways, and the ability to reading the GPRs through the debug port.

ORconf 2014

Last year's OpenRISC conference in Cambridge, England was a great success and attracted participants from both academia and the industry. As for this year, Stefan Wallentowitz has kindly offered to host the conference at Munich University. Initial planning has started and nothing is set in stone yet, but it will probably be carried out the weekend October 11-12. More information will become available at http://orconf.org over the coming months.