Skip to content

Tero

A C++20 functional emulator for the LEON3 / LEON4 SPARC V8 processors, designed to boot the RTEMS testsuite and to be wrapped as an SMP2 simulation model for the European space industry.

Tero emulates the GR712RC (dual-core LEON3FT) and GR740 (quad-core LEON4FT) System-on-Chips at the functional level: the CPU, memory, bus, interrupt controller, timers, UART and FPU are modelled with bit-accurate register semantics. SRMMU and cache control are deliberately deferred — see the roadmap for the rationale.


Choose your manual

  • User Manual


    Install, build, boot an RTEMS image, embed tero_runtime, configure every knob, use the UART console, and attach GDB — without needing the internals.

    Open the User Manual

  • Developer Manual


    How the emulator is conceived: the layer graph, execution model, arch-neutral IR + LLVM JIT, traps and register windows, SMP and timing, the peripheral framework — and how to extend each.

    Open the Developer Manual

What is this hardware?

If you are new to the LEON/GRLIB ecosystem, here is the one-paragraph context:

Cobham Gaisler (part of Frontgrade) designs radiation-hardened 32-bit processors for space applications. The LEON3 and LEON4 cores implement the SPARC V8 instruction set — a classic, well-specified RISC ISA. The GR712RC (dual-core LEON3FT) and GR740 (quad-core LEON4FT) are SoC families used in real satellites and launchers across the European space industry. They run RTEMS — the Real-Time Executive for Multiprocessor Systems, the standard open-source RTOS for safety-critical embedded applications. Developing software for these targets normally requires either physical hardware (expensive, shared, often flight-locked) or Gaisler's own SIS simulator (closed-source, limited scripting). Tero fills that gap: an open-source, embeddable, RTEMS-validated functional emulator for the same silicon.


Where Tero fits

Tero targets a specific point in the LEON-simulator space: functional accuracy at the register level, open-source, embeddable as a C++ library, and architected for SMP2 wrapping. The reference oracle for correctness is Gaisler's SIS simulator — Tero matches it instruction- and register-by-register where they can be compared.

It boots RTEMS to completion across uniprocessor (N=1), GR712RC SMP (N=2) and GR740 SMP (N=4) configurations, under both the Switch interpreter and the LLVM JIT, and supports custom peripherals via a single-file IPeripheral implementation. See Testing for current pass rates and the known-failures breakdown.


Capabilities

  • SPARC V8 integer ISA


    Register windows (overlapping per-call register frames), traps, privileged instructions, PSR write-back, branch annul, RETT (return-from-trap).

    Execution model

  • GR712RC peripherals


    IRQMP (multi-core), GPTimer (4 sub-timers + watchdog), APBUART (FIFO + IRQ), MemCtrl (FTMCTRL stub).

    Peripherals

  • Extension by IPeripheral


    Implement IPeripheral, declare it as a PeripheralSpec (factory + IRQ lines + ports). DMA, IRQs and timed events all work out of the box.

    Custom peripherals

  • GDB remote stub


    RSP over TCP with late-binding attach, RTEMS-aware info threads (executing thread per core by Objects_Id and name), and automatic stop-on-ErrorMode with TT-mapped signals.

    Debugging with GDB

  • Tested against SIS, 0 warnings


    A large Catch2 unit + integration suite plus the real RTEMS sptests, fptests and smptests in CTest, scored with the official RTEMS algorithm and cross-checked against the SIS oracle. -Werror, strict warnings.

    Testing

  • SMP2-ready boundaries


    Every external dependency is an injected interface (ILogger, ITimeSource, ICharacterDevice, …) ready to be mapped to SMP2 services.

    Architecture


Quick example

#include "tero/runtime/emulator.hpp"
#include "tero/runtime/emulator_config.hpp"

int main() {
    auto cfg = tero::compose::gr712rc_config();
    cfg.num_cores = 2;
    cfg.ram_size  = 16 * 1024 * 1024;

    auto emu = tero::runtime::Emulator::create(cfg).value();
    emu->initialize();
    emu->load_elf("rtems_hello.elf");

    auto result = emu->run_for(tero::SimTimeNs{5'000'000'000ULL});
    // UART output already written via the injected ICharacterDevice.
}

Or from the shell:

./build/src/app/tero-emu --image rtems_hello.elf --cores 2 --budget 5000000000

Get started in 5 minutes Read the architecture


Project status

The MVP (Phases 0–6) and most follow-up scope (FPU, GDB stub, SMP validation, Save/Restore, PROM) are complete, plus the Phase 9–15 work toward 1:1 real-time GR740 (arch-neutral IR, tiered LLVM JIT, MultiThread execution). The full CTest suite passes, RTEMS hello-world boots cleanly through the APBUART, sptests / fptests / smptests are exercised in CI, and the GDB stub speaks RTEMS-aware thread queries against live guests.

Area Status
Integer ISA, traps, register windows Done
Peripherals (IRQMP / GPTimer / APBUART / MemCtrl) Done
RTEMS 5 boot, sptests, fptests, smptests Done
Berkeley SoftFloat 3e FPU Done
GDB remote stub (RSP, late-binding, RTEMS-aware) Done
SMP validation (N=2 GR712RC, N=4 GR740, + MultiThread) Done
Arch-neutral IR + tiered LLVM JIT Done
Save / Restore lifecycle Done
PROM (mkprom2 boot ROM) Done
SRMMU, cache control Deferred
GPIO / Flash / CAN / SpaceWire Phase 8

Roadmap Detailed status


SMP2 readiness

The architecture follows the ECSS-E-ST-40-07 lifecycle:

Publish() → Configure() → Connect() → Initialize() → Run() → Hold() → Store() → Restore()

…even though the SMP2 wrapper itself is not part of the MVP. Every external service the core needs is injected through an interface, so the wrapper is an adapter layer rather than a refactor of the core.

Tero interface Default impl SMP2 mapping
ILogger StdoutLogger Smp::Services::ILogger
ITimeSource Internal SimTimeNs Smp::Services::ITimeKeeper
IPublisher DebugPublisher (JSON) Smp::IPublication
IFaultInjector NullFaultInjector Custom SMP2 ops
ICharacterDevice StdoutCharDevice SMP2 output field
IEntryPoint Direct calls Smp::IEntryPoint
IExternalPort Loopback Smp::LinkRegistry

SMP2 design notes


License

Tero source code is released under the Apache License 2.0. Vendored third-party components retain their upstream licenses (see THIRD_PARTY_LICENSES.txt).