Skip to content

Force 4-byte alignment on the embedded firmware array#1

Open
neilrackett wants to merge 1 commit into
sidecartridge:mainfrom
neilrackett:fix/firmware-array-alignment
Open

Force 4-byte alignment on the embedded firmware array#1
neilrackett wants to merge 1 commit into
sidecartridge:mainfrom
neilrackett:fix/firmware-array-alignment

Conversation

@neilrackett

Copy link
Copy Markdown

Problem

COPY_FIRMWARE_TO_RAM_DMA (in rp/src/include/memfunc.h) streams the generated firmware array into ROM_IN_RAM using the RP2040 XIP stream engine. The XIP STREAM_ADDR register truncates its source address to a 32-bit word boundary.

target/atarist/firmware.py generates the image as a bare const 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 in ROM_IN_RAM shifted 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 memcpy fallback path in the same macro does a plain uint16_t* copy and is alignment-safe, so only the DMA path is affected.)

Fix

Emit the array with __attribute__((aligned(4))) so the STREAM_ADDR truncation is always a no-op:

const uint16_t __attribute__((aligned(4))) target_firmware[] = { ... };

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.

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.
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.

1 participant