The ROM symbol tables were emitted entirely as PROVIDE(), which is right
for ROM functions but wrong for ROM data. Symbols like g_osi_funcs_p,
pTxRx, our_tx_eb and lmacConfMib_ptr are variables in RAM that mask ROM
code reads and writes at a fixed address; they are shared storage, not a
fallback implementation.
With PROVIDE(), a weak definition in the program wins and the program and
the mask ROM then use two different locations for the same variable.
g_osi_funcs_p hit exactly this: espradio declares it weak, so it resolved
to .bss while ROM code kept reading 0x4087ff6c, which nothing ever wrote.
Assign the 121 ROM data symbols unconditionally, as esp32c3.ld already
does for the same variables. Addresses verified identical to ESP-IDF's
esp32c6 ROM linker scripts.
Signed-off-by: Ron Evans <ron@hybridgroup.com>
The flash MMU maps 64kB pages, so a flash-mapped section is only read
correctly when its virtual address and its offset within the firmware
image agree modulo 64kB. targets/esp32c6.ld reproduces the image offset
in .rodata_dummy by accumulating the preceding segment sizes and headers,
which works only if the linker inserts no alignment padding between the
dummy and .rodata -- padding moves the virtual address without moving the
image offset.
lld gives .rodata 8-byte alignment, but the accumulated offset is only
4-byte aligned, so whenever the preceding segments happened to leave the
running offset at a 4-mod-8 boundary the whole of .rodata was mapped 4
bytes off. Every read of constant data then returned neighbouring bytes.
This is silent and looks like arbitrary memory corruption rather than a
mapping bug. It was found while bringing up WiFi: the blob rejected its
init config because the first field of a const struct read back as a code
pointer, and whether a given build was affected depended on unrelated code
size changes.
Pad .data, .iram and .text to a multiple of 8 so the running image offset
stays 8-aligned and matches, and add ASSERTs for both flash-mapped
sections so this cannot regress silently.
Signed-off-by: Ron Evans <ron@hybridgroup.com>
The ESP32-C6 target was never built with a radio blob in mind. Three gaps
in targets/esp32c6.ld prevented espradio from linking or running:
- The Espressif WiFi/PHY libraries resolve ~245 internal symbols against
the mask ROM. Only seven ROM symbols were defined. Add the ESP-IDF
generated ROM interface tables (1201 symbols), all as PROVIDE() so any
real definition in the program wins over the ROM copy.
- The .iram output section did not collect the blob IRAM sections
(.wifi0iram, .wifirxiram, .wifislpiram, .wifislprxiram, .wifiextrairam,
.wifiorslpiram, .coexiram, .iram1). Without them that code lands in
flash and crashes when called from an interrupt.
- _heap_end ran to the end of SRAM at 0x40880000, over the mask ROM stack
and ROM data. phy_param_rom sits at 0x4087fce8, inside that range, so a
growing Go heap would corrupt the PHY. Cap the heap at 0x4087C610.
Also add the espradio build tag to esp32c6.json, matching esp32c3.json
and esp32s3.json.
Signed-off-by: Ron Evans <ron@hybridgroup.com>
This adds a minimal esp32c6 implementation, currently only
supporting the examples/serial and examples/blinky1 programs.
It does correctly output the expected "Hello, World" via the
serial port, as well as blink the onboard LED.
In addition, it adds support for the PLIC based IRQ handling
as used on the ESP32C6 processor.
Some parts of this code are loosely based on PR #5252 and #5248
Signed-off-by: deadprogram <ron@hybridgroup.com>