esp-hal/esp32c3-hal/ld/bl-riscv-link.x
sethp 171e66e87a
feat(riscv): relocate .trap machinery to RAM (#541)
* feat: relocate riscv isr to iram

Previously, the trap vector itself and its immediate callees
(`_start_trap` and `_start_trap_rust_hal`) were located in the mapped
instruction flash range `0x420..`, increasing cache pressure and adding
variable latency to the very beginning of the interrupt/exception
service flow.

This change places those routines in iram directly:

```
   Num:    Value  Size Type    Bind   Vis      Ndx Name
 48177: 40380280  2428 FUNC    GLOBAL DEFAULT    6 _start_trap_rust_hal
 48197: 40380bfc    54 FUNC    GLOBAL DEFAULT    6 _start_trap_rust
 48265: 40380200     0 FUNC    GLOBAL DEFAULT    6 _vector_table
 48349: 40380100     0 NOTYPE  GLOBAL DEFAULT    6 default_start_trap
 48350: 40380100     0 NOTYPE  GLOBAL DEFAULT    6 _start_trap
```

As seen via `readelf -W -s -C ./target/riscv32imc-unknown-none-elf/debug/examples/gpio_interrupt | grep -E _start_trap\|_vector\|Ndx`

* feat(riscv): place .trap in RAM

This change follows through on relocating the `_vector_table`,
`_start_trap`, and `_start_trap_rust` functions for all present
build/link modes for the 'c2, 'c3, 'c6, and 'h2.

It has been tested by running the `software_interrupts` example for the
'c3 in direct-boot and esp-bootloader contexts, but I wasn't able to
identify how to run the `mcu-boot` mode for the 'c3, nor do I have
present access to any of the other devices for testing.

* docs: Update CHANGELOG.md
2023-05-26 20:48:49 +01:00

115 lines
3.0 KiB
Plaintext

ENTRY(_start)
PROVIDE(_stext = ORIGIN(ROTEXT));
PROVIDE(_stack_start = ORIGIN(RWDATA) + LENGTH(RWDATA));
PROVIDE(_max_hart_id = 0);
PROVIDE(_hart_stack_size = 2K);
PROVIDE(_heap_size = 0);
PROVIDE(UserSoft = DefaultHandler);
PROVIDE(SupervisorSoft = DefaultHandler);
PROVIDE(MachineSoft = DefaultHandler);
PROVIDE(UserTimer = DefaultHandler);
PROVIDE(SupervisorTimer = DefaultHandler);
PROVIDE(MachineTimer = DefaultHandler);
PROVIDE(UserExternal = DefaultHandler);
PROVIDE(SupervisorExternal = DefaultHandler);
PROVIDE(MachineExternal = DefaultHandler);
PROVIDE(DefaultHandler = DefaultInterruptHandler);
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
PROVIDE(__post_init = default_post_init);
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
PROVIDE(_setup_interrupts = default_setup_interrupts);
/* # Multi-processing hook function
fn _mp_hook() -> bool;
This function is called from all the harts and must return true only for one hart,
which will perform memory initialization. For other harts it must return false
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
*/
PROVIDE(_mp_hook = default_mp_hook);
/* # Start trap function override
By default uses the riscv crates default trap handler
but by providing the `_start_trap` symbol external crates can override.
*/
PROVIDE(_start_trap = default_start_trap);
/* esp32c3 fixups */
SECTIONS {
.text.dummy (NOLOAD) :
{
/* This section is intended to make _stext address work */
. = ABSOLUTE(_stext);
} > ROTEXT
}
INSERT BEFORE .text_init;
SECTIONS {
/* These symbols/functions need to be near eachother, group them together at the start of text */
.text_init _stext : ALIGN(4)
{
KEEP(*(.init));
KEEP(*(.init.rust));
KEEP(*(.text.abort));
} > ROTEXT
}
INSERT BEFORE .text;
SECTIONS {
.trap : ALIGN(4)
{
KEEP(*(.trap));
*(.trap.*);
} > RWTEXT
}
INSERT AFTER .rwtext;
SECTIONS {
/**
* This dummy section represents the .text section but in rodata.
* Thus, it must have its alignement and (at least) its size.
*/
.text_dummy (NOLOAD):
{
/* Start at the same alignement constraint than .text */
. = ALIGN(4);
/* Create an empty gap as big as .text section */
. = . + SIZEOF(.text) + SIZEOF(.text_init);
/* Prepare the alignement of the section above. Few bytes (0x20) must be
* added for the mapping header. */
. = ALIGN(0x10000) + 0x20;
} > RODATA
}
INSERT BEFORE .rodata;
SECTIONS {
/* similar as text_dummy */
.rwdata_dummy (NOLOAD) : {
. = ALIGN(ALIGNOF(.rwtext));
. = . + SIZEOF(.rwtext);
. = . + SIZEOF(.rwtext.wifi);
. = . + SIZEOF(.trap);
} > RWDATA
}
INSERT BEFORE .data;
/* Must be called __global_pointer$ for linker relaxations to work. */
PROVIDE(__global_pointer$ = _data_start + 0x800);
/* end of esp32c3 fixups */
/* Shared sections - ordering matters */
INCLUDE "text.x"
INCLUDE "rodata.x"
INCLUDE "rwtext.x"
INCLUDE "rwdata.x"
INCLUDE "rtc_fast.x"
/* End of Shared sections */
INCLUDE "debug.x"