An overview of SMASH: The Serenity MAnagement SHell

[edit this page]

SMASH, what and why?

SMASH is a framework for controlling hardware. And firmware. And software.

The usual problem in writing generic, reusable control software is the complex interdependence of different components: for example, to configure to an optical module you may first need to talk via I2C to a port-expander to read the module-present signal to check that the optical module is present; to then configure the port-expander via I2C to asset the optical module’s module-select line; to talk I2C to the optical module itself; and to reconfigure the port-expander via I2C to deassert the optical module’s module-select line. Yet the simple statement of “talk via I2C” may, itself, mask myriad complexities since this may be two independent I2C buses for the port-expander and the optical module; if our software is running on a device without embedded I2C controllers, we shall require an additional transport-layer to talk to a device which converts PCIe, USB or Ethernet to I2C. And if the I2C port-expander becomes deprecated, or we chose to drive the module-present and -select line from the GPIO of an FPGA or SOC, or your pesky hardware designer inserts an I2C bus-multiplexer on the I2C bus which itself requires its own layer of configuration, then there is typically nothing for it but to write completely new software, copying-and-pasting your old code, and hacking it around. If we start a new board, we start a new control software.

In the past, major structural changes to a board design and entirely new board designs happened on a sufficiently infrequent basis as to be manageable, albeit inefficient, way of working.

Serenity, however, is a different beast: its paradigm of structural reconfigurability and use of pluggable modules means that the same board revision may be being used simultaneously for use-cases with different types or counts of FPGAs, with or without a QSFP, and with different numbers, directions and speeds of serial links via passive-electrical, or uni- or bi-directional, 16G or 28G firefly optics. And with proposals for alternative form-factors and for different control modules (such as SOCs) this problem would only get worse.

This is the problem SMASH was intended to solve. Of course, if the system is sufficiently flexible to handle all these permutations, then it is a minimal leap to being sufficiently flexible for any hardware.

SMASH, how?

SMASH achieves this by building, in software, a mirror image of the hardware and firmware.

image0

Each type of hardware or firmware has a separate class representation, which is referred to as an “element”. Each element is a self-contained entity and has no dependence on any other element. Like physical components, which interact with each other by exposing interfaces, be that GPIO, I2C, SPI, JTAG, USB, GbE, PCIe or some other, so do SMASH elements.

SMASH elements do this through bound function calls, which in SMASH parlance are called “ports”. Any element which provides a service, such as an I2C master or a GPIO-driver, creates and exposes a port. Any element which uses a service, such as an I2C slave or a component configured by a GPIO, uses a copy of a bound function (not caring where it came from) as a tool to perform the required operation, without any knowledge of the mechanism by which it is implemented, maintaining the conceptual independence of the service provider and the service consumer.

Because of the diversity of hardware, firmware and software elements, all exposed interfaces other than the “ports” use strings as the interface mechanism, which has the additional advantage of making SMASH highly suitable for scripting and interactive use.

The heart of SMASH is the Smash class. This is a singleton class managing the entire system and is the only “core” infrastructure, everything else is a plug-in module, dynamically loaded at run-time.