lince_peripherals¶
The four GR712RC peripherals required to boot RTEMS. Each peripheral is
a IPeripheral subclass, and each has a dedicated reference page under
Peripherals covering register layouts and
behaviour bit by bit.
Source layout¶
src/peripherals/
├── include/lince/peripherals/
│ ├── irqmp.hpp
│ ├── gptimer.hpp
│ ├── apbuart.hpp
│ ├── memctrl.hpp
│ └── version.hpp
└── src/
├── irqmp.cpp
├── gptimer.cpp
├── apbuart.cpp
└── memctrl.cpp
Depends on lince_interfaces and lince_bus.
What lives here¶
| Class | MMIO base (GR712RC) | IRQ | Page |
|---|---|---|---|
IrqMP |
0x80000200 |
— | IRQMP |
GPTimer |
0x80000300 |
8 | GPTimer |
ApbUart |
0x80000100 |
3 | APBUART |
MemCtrl |
0x80000000 |
— | MemCtrl |
The base addresses are wired by Emulator::create_default_peripherals
during initialize(); they are not stored in EmulatorConfig.
Common patterns¶
All four peripherals follow the same skeleton:
class FooPeripheral final : public IPeripheral {
public:
explicit FooPeripheral(PhysAddr base);
std::string_view name() const override;
AddressRange mmio_range() const override;
void attach(const PeripheralContext&) override;
void reset() override;
Result<uint32_t> mmio_read (PhysAddr, AccessSize) override;
Result<void> mmio_write(PhysAddr, AccessSize, uint32_t) override;
void tick(SimTimeNs) override;
void publish(IPublisher&) override;
private:
PhysAddr base_;
PeripheralContext ctx_;
/* per-peripheral state */
};
The reset contract¶
reset() returns the peripheral to its power-on state. Per
peripheral:
- IRQMP — masks all interrupts, clears IPEND/IFR, stops asserting any IRQ.
- GPTimer — disables timers 1–3, but leaves timer 4 in watchdog-armed mode (EN=RS=IE=1, counter=reload=0xFFFF).
- APBUart — clears the FIFO, clears CTRL, drops any in-flight TX.
- MemCtrl — restores MCFG1–MCFG4 default values.
The tick contract¶
tick(SimTimeNs now) is called once per scheduling round. Concretely
that means quantum * num_cores * ns_per_insn simulated nanoseconds
between calls (default: 1000 × 1 × 20 = 20 µs). Two of the four
peripherals do real work in tick:
GPTimerdecrements its prescaler and sub-timers.MemCtrldoes nothing — the call is a no-op.IrqMPdoes nothing — it reacts to bus writes and external asserts, not to time.ApbUartpolls itsICharacterDevicefor incoming bytes and pushes them into the RX FIFO.
MMIO size policy¶
All four peripherals reject non-word accesses with
ErrorCode::AlignmentError. Byte and half-word reads/writes are not
supported in the MVP (Decision 20). This is stricter than the GR712RC
hardware but matches every access RTEMS actually performs.
Custom peripherals¶
Anything you build follows the same IPeripheral contract — the
runtime treats your peripheral exactly like the four built-ins. A
fully wired DMA-capable peripheral with an IRQ is shown in
examples/demo-dma/ and walked through in the custom
peripheral guide.