Commit Graph

13 Commits

Author SHA1 Message Date
deadprogram aee0581a32 esp32: fix XIP boot crash caused by LLVM 22 / lld l32r relocation bug
Work around an lld (LLVM 22) bug where l32r PC-relative offsets are
miscalculated when auto-generated .literal.* sections are prepended to
.text.* sections by the linker script. The assembler emits .literal
entries for movi instructions whose constants exceed the 12-bit signed
range; lld then resolves the l32r relocations with incorrect offsets,
causing every l32r in the boot code to load from the wrong literal
pool entry.

The symptom was a TG0WDT_SYS_RESET boot loop: the watchdog disable
code loaded wrong register addresses via l32r and silently wrote to
the wrong peripheral registers, leaving the watchdog running.

Fix by constructing PS_WOE_MASK (0x40000) with movi+slli instead of a
single large-constant movi, eliminating all auto-generated .literal
section entries. This is compatible with both LLVM 20 and LLVM 22.

Also revert DRAM origin to 0x3FFAE000 (200K) and remove rom_phyFuns
symbols that belong in a separate WiFi commit.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-07-22 23:52:21 +02:00
deadprogram 0c17b918fb esp32: implement flash XIP (execute-in-place) support
Add full flash XIP support for ESP32, enabling code and read-only data to
execute/load directly from flash via the MMU cache rather than consuming
precious SRAM. This increases available RAM from ~328KB to effectively
unlimited for code/rodata, while keeping ~121KB for the Go heap.

Changes:
- src/device/esp/esp32.S: Add MMU initialization in call_start_cpu0
  - Call ROM bootloader mmu_init() and cache_flash_mmu_set() to map DROM/IROM
  - Enable flash cache via ROM Cache_Read_Enable()
  - Fix tinygo_scanCurrentStack to spill all register windows for GC

- targets/esp32-interrupts.S: Add exception diagnostics

- targets/esp32.ld: Major linker script restructure for XIP
  - Add DROM (4MB @ 0x3F400000) and IROM (4MB @ 0x400D0000) regions
  - Move .rodata to DROM, main .text to IROM (both flash-mapped)
  - Keep boot code, vectors, and WiFi blob IRAM sections in SRAM0
  - Create WiFi arena in SRAM1 pool 7/6 (64KB @ 0x3FFF0000)
  - Move .bss and heap to SRAM2 (200KB @ 0x3FFAE000), avoiding ROM/MAC regions
  - Add _drom_flash_addr variable (patched by builder with flash offset)

- targets/esp32.json: Add linker wrap flags for malloc/free and WiFi functions

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-07-22 23:52:21 +02:00
deadprogram babdfc9e10 esp32s3: fix boot crash caused by LLVM 22 / lld l32r relocation bug
Replace movi instructions with constants outside the 12-bit signed
range (-2048..2047) with movi+slli sequences. Large constants cause
the assembler to emit auto-generated .literal section entries, which
triggers an lld bug where l32r PC-relative offsets are miscalculated
when .literal.* sections are merged with .text.* sections.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-07-20 16:45:34 +02:00
deadprogram 5f66260c3a machine,targets: add minimal esp32c6 implementation
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>
2026-06-25 19:30:24 +02:00
deadprogram 709349e24b device/esp: fix tinygo_scanCurrentStack to spill register windows
The previous implementation was a bare tail-jump to tinygo_scanstack
without spilling any registers or passing an sp argument.  On Xtensa
windowed ABI, heap pointers held in physical registers were invisible
to the conservative GC, causing it to collect live objects and leading
to nil pointer dereferences under allocation pressure.

Flush all register windows to the stack using recursive call4 (15
levels for NAREG=64), then pass the current sp to tinygo_scanstack so
the GC scan from sp to stackTop covers every live value.  Interrupts
are briefly masked during the spill to prevent window-overflow
exceptions from interfering.

Fixes crashes on ESP32-S3 observed when serving concurrent HTTP
requests.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-04-08 18:51:42 +01:00
deadprogram 5b7a2c73db esp32s3: update linker script and boot assembly for multi-page flash XIP mapping
Extend the linker script with proper IROM/DROM section layout for flash
execute-in-place. Update the boot assembly MMU init to dynamically map
all required flash pages based on _irom_end/_drom_end symbols instead
of hardcoding a single page.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-04-07 16:27:02 +02:00
deadprogram aaf6a36c55 esp32s3: add flash XIP boot assembly with cache/MMU init
The ESP32-S3 ROM bootloader loads IRAM/DRAM into SRAM but does not
configure the flash cache or MMU. Previously the target incorrectly
reused the ESP32 boot assembly (esp32.S) which lacks flash XIP support.

Add a dedicated esp32s3.S boot assembly that:
- Sets up windowed-ABI registers, stack, and FPU
- Disables all watchdog timers (RTC, TIMG0, TIMG1, Super WDT)
- Configures VECBASE and clears PS.EXCM before any callx4
- Calls ROM functions to configure cache modes:
  rom_config_instruction_cache_mode (16KB, 8-way, 32B line)
  rom_config_data_cache_mode (32KB, 8-way, 32B line)
- Initializes MMU, maps flash page 0 for IROM and DROM,
  clears bus-shut bits, and enables both caches
- Jumps to runtime.main in IROM (flash)

Update the linker script (esp32s3.ld) to place .text and .rodata in
flash-mapped regions (IROM/DROM) with proper alignment for the MMU
page size. Update esp32s3-interrupts.S with proper exception vector
handlers. Point esp32s3.json at the new esp32s3.S instead of esp32.S.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-04-07 16:27:02 +02:00
Dmitriy 43efe94041 add support for CPU interrupts for ESP32-C3 2021-10-23 03:31:37 +02:00
Ayke van Laethem cb147b9475 esp32c3: add support for this chip
This change adds support for the ESP32-C3, a new chip from Espressif. It
is a RISC-V core so porting was comparatively easy.

Most peripherals are shared with the (original) ESP32 chip, but with
subtle differences. Also, the SVD file I've used gives some
peripherals/registers a different name which makes sharing code harder.
Eventually, when an official SVD file for the ESP32 is released, I
expect that a lot of code can be shared between the two chips.

More information: https://www.espressif.com/en/products/socs/esp32-c3

TODO:
  - stack scheduler
  - interrupts
  - most peripherals (SPI, I2C, PWM, etc)
2021-09-16 20:13:04 +02:00
Ayke van Laethem ae92ea149c esp32: enable the FPU
This allows working with float32 values, for example it allows
testdata/float.go to work correctly (assuming an Xtensa backend bug is
fixed, see https://github.com/espressif/llvm-project/issues/41).
2020-12-11 12:11:46 +01:00
Ayke van Laethem caf35cfc41 esp32: implement task based scheduler
This has been a *lot* of work, trying to understand the Xtensa windowed
registers ABI. But in the end I managed to come up with a very simple
implementation that so far seems to work very well.

I tested this with both blinky examples (with blinky2 slightly edited)
and ./testdata/coroutines.go to verify that it actually works.
Most development happened on the ESP32 QEMU fork from Espressif
(https://github.com/espressif/qemu/wiki) but I also verified that it
works on a real ESP32.
2020-12-05 09:02:11 +01:00
Ayke van Laethem 2ce17a1892 esp8266: add support for this chip
Many thanks to cnlohr for the nosdk8266 project:
    https://github.com/cnlohr/nosdk8266
2020-09-09 19:17:11 +02:00
Ayke van Laethem 3ee47a9c1b esp: add support for the Espressif ESP32 chip
This is only very minimal support. More support (such as tinygo flash,
or peripheral access) should be added in later commits, to keep this one
focused.

Importantly, this commit changes the LLVM repo from llvm/llvm-project to
tinygo-org/llvm-project. This provides a little bit of versioning in
case something changes in the Espressif fork. If we want to upgrade to
LLVM 11 it's easy to switch back to llvm/llvm-project until Espressif
has updated their fork.
2020-08-31 09:02:23 +02:00