Skip to content

Conversation

@jwise
Copy link
Contributor

@jwise jwise commented Jul 30, 2025

In FIRM-198, we planned to introduce a simple XIP "hello world" demo, with "concepts of a plan" for how to make the core of it mergeable, but in a form that is not necessarily mergeable in and of itself; this is that demo. This demo shows that XIP of C compiled code is possible at least once on Asterix hardware, using the xip hello world command that gets the in-flash address of a precompiled XIP stub, turns on the QSPI hardware, jumps to the stub, and then turns off the hardware after the stub is done. The expected output is approximately as follows:

> xip hello world
xip_data mapped at 0x1225880c, first bytes are 10 b5 04 46
Hello world
from a -fPIC XIP stub
xip_fn returned 42

To enable this, we add support for the MAPPABLE_FLASH capability on nRF5 / Asterix. Unfortunately, nRF52840's QSPI controller is pretty broken -- it has a brutal erratum that means that it is not safe to actually use QSPI mapped memory when executing from microflash or SRAM. In fact, this happens to come up in our use: when upng tries to decode memory-mapped PNGs, depending on the alignment of the upng code, it will either succeed or fail, claiming that the PNG in question is unsupported (!). In this PR, I show two ways to permute this outcome (when MAPPABLE_FLASH_IS_FOR_CODE_ONLY is not enabled): if you remove the usleep(0) in flash_impl_use, then upng will fail to decode a system PNG and the system will assert on boot. But if you remove the + 1 in command_xip_hello_world after that, then upng will happily decode the PNG again! (Of course, `command_xip_hello_world will not work anymore if you do that.)

However, Nordic hints that it is legal to (or maybe, it happens to work to?) execute code from QSPI flash -- just as long as you don't hand any pointers in QSPI flash back to the system that runs in microflash. So we introduce CAPABILITY_MAPPABLE_FLASH_IS_FOR_CODE_ONLY, as a pinky-swear that you definitely are only going to execute that thing that you just mapped in, and you promise not to read from it without branching to it. (A dark irony is that this xip stub actually does hand a pointer back to the system illegally! But it doesn't seem to have any of the instruction sequence that causes this particular catastrophe.)

Although the final state of this particular thing works well -- well enough for me to consider FIRM-198 to be complete, anyway -- the bad news is that there are a bunch of extremely careful things done in this demo to make it work -- and solving each of these for something more "industrial-strength" might be nontrivial. Accordingly, I'll file Linear tickets for each of these.

jwise added 3 commits July 29, 2025 17:13
This still has stability issues, probably related to nRF52840 Erratum
216.

Signed-off-by: Joshua Wise <[email protected]>
…s affected by nRF52840 erratum 216

Signed-off-by: Joshua Wise <[email protected]>
@jwise jwise requested a review from gmarull July 30, 2025 07:28
@mkellner
Copy link

There seems to be a file missing xip_stub.lds which prevents building the stub.

@gmarull gmarull force-pushed the main branch 4 times, most recently from 1e462ba to df895f0 Compare September 23, 2025 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants