Updated 7 November 2026

Memory for plugins

A console plugin runs on the STM32H743 (Cortex-M7, 480 MHz). This page lists the memory a plugin may use and the cache rules that keep CPU and DMA data consistent. The full console memory map is on the Memory map page.

Contents

Plugin memory regions

Region Address range Size How to get it Cache Notes
Plugin slot (SDRAM) 0xC1620000–0xC1B9FFFF 5 632 KB Linked there by plugin.ld Write-back, executable Image, .bss and heap.
Plugin ITCM 0x00000800–0x0000FFFF 62 KB .itcm_hot, copied at startup Not cached, executable With overlays: 0x800–0xBFFF resident, 0xC000–0xFFFF overlay window.
Plugin DTCM 0x20016000–0x2001FFFF 40 KB .dtcm_hot, .dtcm_bss Not cached, not executable No DMA can reach DTCM.
FastBuffer (D2 SRAM) 0x30027740–0x3004773F 128 KB get_fast_buffer() Write-through, executable The last 30 KB from 0x3003FF40 hold .d2_hot in DATA_PLUS_CODE mode. Also used by system image drawing.
Depth strip (AXI SRAM) 0x2402C4C0–0x240378BF 46 080 B get_depth_strip() (v6) Write-back 480 × 48 uint16_t. Do not write past its end.
Framebuffer (AXI SRAM) 0x24040000–0x2407FBFF 261 120 B get_framebuffer() Write-back 480 × 272 RGB565. Can be used as scratch before drawing the frame (frame_scratch_prefetch_to, v5).
Asset pool (SDRAM) inside 0xC0092400–0xC14923FF 20 MB, shared alloc() Write-back Up to 256 blocks per plugin, freed at cleanup.

The heap set up by startup.cpp grows from the end of .bss up to 4 KB below 0xC1BA0000. A plugin that needs more memory than fits in the slot can take one large block with alloc and run its heap inside it.

Reserved memory

All other memory belongs to the system. In particular, never write to:

  • 0x24038000–0x2403FFFF, directly after the depth strip;
  • 0xC1BA0000 and above (system buffers and the Lua heap);
  • ITCM below 0x800 and DTCM below 0x20016000.

Fixed addresses

These addresses are part of the plugin ABI:

Item Value
Plugin slot start 0xC1620000
Plugin slot end 0xC1BA0000
Plugin ITCM 0x800; overlay window 0xC000
Plugin DTCM 0x20016000, 40 KB
FastBuffer 0x30027740, 128 KB
D2 code tail 0x3003FF40 (C8B_D2_CODE_VMA)

Cache and DMA rules

Cache lines are 32 bytes. ITCM and DTCM are never cached.

  1. Code copied to ITCM: run dsb; isb after the copy (the startup code does). For overlays use load_itcm_overlay, which handles this itself.
  2. Code copied to D2 or generated in SDRAM (for example by a JIT): call invalidate_icache(addr, size) before running it.
  3. Your own buffers read by DMA: blit_indexed8, blit_indexed8_blend and the frame present already write back the data cache for their source. Before handing any other buffer to a DMA master, write it back with SCB_CleanDCache_by_Addr.
  4. API transfers (fast_buffer_prefetch*, frame_scratch_prefetch_to) handle the cache for source and destination. Do not read or write the destination until fast_buffer_wait() returns.
  5. Write-through memory (FastBuffer): CPU writes reach memory immediately, but after a DMA write the range must be invalidated before the CPU reads it. The API transfers do this for you.
  6. DTCM: never point a DMA transfer at DTCM (0x2000xxxx) and never put DMA buffers in the plugin DTCM area.
  7. Async present (v7): after present_set_async(1) the frame is copied while the next frame runs. Call present_wait() or get_framebuffer() before touching the framebuffer.
  8. FastBuffer sharing: get_fast_buffer() and fast_buffer_wait() wait for any system transfer still running. If Lua draws images while the plugin keeps data in the FastBuffer, that data can be overwritten.

Memory map at a glance

ITCM   0x00000000 system | 0x00000800 plugin resident (46 or 62 KB) | 0x0000C000 plugin overlay window (16 KB)
DTCM   0x20000000 system data and stack | 0x20016000 plugin (40 KB)
AXI    0x24000000 system | 0x2402C4C0 depth strip (45 KB) | 0x24038000 reserved | 0x24040000 framebuffer (255 KB)
D2     0x30000000 system | 0x30027740 FastBuffer (128 KB)
SDRAM  0xC0000000 display buffers and system pools (asset pool 20 MB at 0xC0092400) | 0xC1620000 plugin slot (5.5 MB) | 0xC1BA0000 system | 0xC1C00000 Lua heap (4 MB)