Over the last roughly two years, Open SoC Debug has grown into a reliable debugging tool for the needs of lowRISC and OpTiMSoC. A lot of effort went into fixing small bugs to improve reliability and to add some features such as the emulated UART device, UART-DEM. And it was worth the effort, as we’ve seen over the summer when we added Linux support to OpTiMSoC. Control flow traces generated by the CTM modules, as well as the UART-DEM module were major enablers for this work.
This work has also given us a better understanding of areas where our current design limits extensibility. Furthermore, we found some parts of the reference implementation to be tricky or fragile to use. To fix all this, we’ve started brainstorming and refactoring the spec and the reference implementation.
Previously, addresses used to identify debug modules were 10 bit wide, allowing up to 1024 modules to be present in a debug system. We’re extending addresses to 16 bit, addressing up to 65536 debug modules. (“65k should be enough for everybody.”) This change also requires modifications to the packet format the on-chip interconnect, and hence modifications to all debug modules which send and receive packets. 16 bit addresses enable us to address more debug modules, but they also enable us to reserve some parts of the address for special purposes. (More on that later.)
All debug modules in OSD conform to a common base register map. These registers describe the type of the module, its version, amongst other things. In order to be more extensible, we’ve split the module type into two fields (vendor and type identifier) and rearranged them in the register map. The specification is already updated to describe the new register map.
Currently the hardware portion of the OSD reference implementation is mainly tested using manual tests, together with system-level tests in OpTiMSoC and lowRISC. To make changes to the code base easier and the results more predictable, we’re adding unit tests to the reference implementation using the excellent Python-based cocotb unit testing framework.
The software running on the host is the main entry point for users to OSD. It must be as robust as possible to give a smooth debugging and tracing experience. But it also must be extensible to add new debug tools easily.
The current implementation has a couple of very nice properties:
We’ll keep these properties, but extend them in a couple ways:
inprocshared memory transport, but they can also live on different machines using the
tcptransport. All of that is fully transparent to the application.
Something which is mostly in our head right now are OSD Subnets. For now this only means: all debug tools on the host are part of one “subnet”, and all debug modules on the target device are another subnet. There’s more to it, but we’ll keep that for a later time.
A large rework like the one we’re currently attempting involves changing code in various places. Unfortunately, it’s not always possible to completely decouple the dependencies between these changes. This is especially true for the changes to the communication protocol, which require changes to both software and hardware parts.
So to keep OSD working and usable by downstream projects while we’re working on this major refactoring, we’ve decided to take the following approach:
masterbranches of the reference implementation in a working, stable state. All our refactoring will happen on a different branch, called
osd-next. If you’re currently using OSD in your designs (that’s most likely only true for OpTiMSoC and lowRISC), stay on the
masterbranch for now.
In addition to the upstream work at OSD, OpTiMSoC is maintaining an continuously updated branch
osd-rework in its repository.
This ensures that the changes in OSD fit well into the needs of our downstream projects.
Changes like the ones we’re attempting here present an excellent opportunity to get involved. Let us know on the mailing list what you think, or what your questions are.