* 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
114 lines
3.0 KiB
Plaintext
114 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);
|
|
|
|
/* esp32c2 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 esp32c2 fixups */
|
|
|
|
/* Shared sections - ordering matters */
|
|
INCLUDE "text.x"
|
|
INCLUDE "rodata.x"
|
|
INCLUDE "rwtext.x"
|
|
INCLUDE "rwdata.x"
|
|
/* End of Shared sections */
|
|
|
|
INCLUDE "debug.x"
|
|
|