Code MRAM + Extra MRAM + Option-Setting driver – DANGEROUS, brick-capable.
- Tag
- [Ring 3 / HAL] {World: S}
On RA8D2 the "code flash" is MRAM, a non-volatile, byte-erasable magnetoresistive RAM array exposed at 0x02000000 for 1 MiB. The controller block (R_MRMS, secure base 0x4013_C000, HUM Ch 59.5.1 p 3551) presents a small write-buffer + status register window. Three independent write paths exist:
- Direct STR programming of the code-MRAM page through the MRCPC0 / MRCPC1 gate (HUM Ch 59.4.2 Figure 59.4 p 3548).
- MACI command sequencer for configuration-set, anti-rollback counters, status-clear, and forced-stop (HUM Ch 59.4.4 p 3550 + HUM Ch 7 p 278..299 for the OFS layout).
- Block-protection writes to MRCBPROT0 / MRCBPROT1 to permanently or temporarily lock individual pages.
This wave (Round 3) brings the driver to full HUM Ch 7 + Ch 59 coverage:
- Warning
- THIS DRIVER CAN PERMANENTLY BRICK THE MCU. A program that overwrites its own reset vectors, FSBL hash, the option-setting trust anchors at 0x0100_A100, the permanent block-protect bits, or the start-up area control register may be unrecoverable through SWD and require vendor RMA. NEVER call any write / erase / block_protect / config_set / startup / zeroize API with a destination inside the running image's .text section, the secure boot area, or the OFS region unless you are absolutely certain. The driver does not sanity-check the destination beyond enforcing the 1 MB MRAM window – caller is fully responsible.
-
ra8_flash_zeroize_huk is one-shot and permanent. Once fired, the silicon's wrapped HUK (W-HUK) is destroyed and every secret that was wrapped under it becomes irretrievable. The matching MREZS.WHUKZF flag latches forever. callers should keep this API behind a project-level policy gate.
-
ra8_flash_block_protect_set with the permanent flag set writes a one-shot fuse. Once set, the block can never be re-enabled without a new fuse cycle on the part. There is no undo.
-
The driver does not protect against power loss mid-write. A reset between the data store and the MRCFLR flush leaves the affected 32-byte page in an indeterminate state. For at-rest critical regions use a journaled two-bank scheme on top of this driver.
-
Programming must not run from MRAM that is being programmed. The HUM allows BGO (background read of the opposite memory while the other is programmed) but the code-MRAM path requires the write loop itself to live in SRAM. ra8_flash_write_block does not relocate itself – caller must ensure the call site is in SRAM (e.g. __attribute__((section(".sram_text")))) when targeting MRAM addresses.
- Copyright
- Copyright (c) 2026 Brighton Sikarskie SPDX-License-Identifier: MIT
Definition in file ra8_flash.h.