Force 4-byte alignment on the embedded firmware array#1
Open
neilrackett wants to merge 1 commit into
Open
Conversation
COPY_FIRMWARE_TO_RAM_DMA streams the generated firmware array into ROM_IN_RAM through the RP2040 XIP stream engine, whose STREAM_ADDR register truncates the source address to a 32-bit word boundary. The array is generated as a bare const uint16_t[] (2-byte alignment), so when the linker places it on a 2-mod-4 address the stream starts two bytes early and the entire cartridge image lands in RAM shifted by two bytes -- crashing the m68k. The symptom varies per build (bombs, black screen, boot-to-desktop) because it depends only on linker layout, which makes it very hard to diagnose. Emit the array with __attribute__((aligned(4))) so the STREAM_ADDR truncation is always a no-op.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
COPY_FIRMWARE_TO_RAM_DMA(inrp/src/include/memfunc.h) streams the generated firmware array intoROM_IN_RAMusing the RP2040 XIP stream engine. The XIPSTREAM_ADDRregister truncates its source address to a 32-bit word boundary.target/atarist/firmware.pygenerates the image as a bareconst uint16_t[], which is only 2-byte aligned. When the linker happens to place it on a 2-mod-4 address, the stream starts reading two bytes early, so the entire cartridge image lands inROM_IN_RAMshifted by two bytes and the m68k executes garbage.Because it depends purely on linker layout, the symptom varies per build — bombs, a black screen, or booting straight to the desktop — and appears or vanishes with unrelated code changes, which makes it very hard to diagnose. (The
memcpyfallback path in the same macro does a plainuint16_t*copy and is alignment-safe, so only the DMA path is affected.)Fix
Emit the array with
__attribute__((aligned(4)))so theSTREAM_ADDRtruncation is always a no-op:A one-line change in the generator; the header is regenerated on every build. Verified in a downstream app that was hitting the intermittent crash — with the alignment forced, the cart image copies correctly on every build.