Skip to content

MEMCTRL (FTMCTRL) — Memory controller stub

GRLIB FTMCTRL (GR712RC §5, Tables 28–32): the fault-tolerant PROM / SRAM / SDRAM memory controller with EDAC. In Tero this is a passive register stub — enough to satisfy the RTEMS BSP's early probes, with no timing, bank switching, refresh scheduling, or EDAC behaviour (Tero does not model memory latency).

Property Value
Class peripherals::MemCtrl
Default MMIO base 0x80000000 (GR712RC) / 0xFFE00000 (GR740)
MMIO window size 0x100
IRQ / DMA none
Source src/peripherals/src/memctrl.cpp

Using it

The four configuration registers are word-aligned, word-only (byte and half-word accesses return ErrorCode::AlignmentError). RTEMS reads them during early boot to determine memory width and presence, then never touches the FTMCTRL again — which is exactly why a stub suffices for the whole testsuite.

Register map

Offset Name Access Reset Description
0x00 MCFG1 R/W 0x00000F00 PROM configuration (wait states, width).
0x04 MCFG2 R/W 0x00000000 SRAM / SDRAM configuration.
0x08 MCFG3 R/W 0x08000000 EDAC / refresh control (bit 27 tied to 1).
0x0C MCFG4 R/W 0x00000000 RS-EDAC diagnostics.

Accesses outside 0x000x0C return ErrorCode::BusError (the default: arms in mmio_read/mmio_write, memctrl.cpp:29).

The one bit-level exception — MCFG3 bit 27

Bit Name Behaviour
27 Reserved (hardware tie-off) Read: always returns 1 (mcfg3_ \| Mcfg3Bit27). Write: masked to 0 on store (mcfg3_ = value & ~Mcfg3Bit27), so software can never clear it.

This matches GR712RC hardware where MCFG3 bit 27 is a reserved bit that reads as 1 regardless of what is written.


Internals / how it's modelled

The stub treats the four registers as opaque storage (memctrl.cpp:1846):

  • Writes store the value as-is (MCFG3 masks bit 27 off).
  • Reads return the last written value (MCFG3 ORs bit 27 in).
  • tick() is a no-op — no timed side effects.
  • No IRQ, no DMA, no IMemoryRegion — the FTMCTRL is registers-only. The memory it controls (RAM/PROM) is modelled by the SystemBus RAM regions and the Prom peripheral, not here.

Reset state

reset() (memctrl.cpp:11) restores all four registers to the reset values in the table above.

AMBA Plug and Play

MemCtrl does not implement PnP registers itself. The runtime fabricates the descriptors during Emulator::initialize() via write_pnp_entries (src/runtime/src/pnp_table.cpp) so RTEMS' ambapp_scan discovers it:

  • Vendor ID: 0x01 (Gaisler, VendorGaisler).
  • Device ID: 0x054 (FTMCTRL, DevFtMemCtrl).
  • On GR712RC the FTMCTRL is an AHB slave (PnP slot 1, covering the 0x40000000 RAM/PROM area) — pnp_table.cpp:129.
  • On GR740 the FTMCTRL is on the APB side (APB PnP slot 3) and has no AHB slave entry — pnp_table.cpp:179.

The device ID was corrected from the placeholder 0x00F (plain MCTRL) during the 2026-04-24 hardware audit (Decision 33).

Tests

  • tests/unit/test_memctrl.cpp — reset values, read/write round-trips, the MCFG3 bit-27 tie-off, non-word access rejection, out-of-range offsets, and reset-after-write.
  • Integration tests exercise the stub implicitly through the RTEMS boot path.

See also