Xtensa: Branch and jump intructions referencing a relative label have been replaced

As branches/jumps on Xtensa have a maximum range for the destination, it is
unsafe to refer to a label to another compilation unit in a branch/jump instruction.
The labels have been replaced by absolute addresses.
This commit is contained in:
Omar Chebib
2021-09-13 19:20:51 +08:00
parent 75e2705269
commit 8048677b4c
2 changed files with 16 additions and 2 deletions

View File

@@ -173,7 +173,13 @@ xt_highintx:
rsr a0, INTERRUPT rsr a0, INTERRUPT
extui a0, a0, ETS_IPC_ISR_INUM, 1 extui a0, a0, ETS_IPC_ISR_INUM, 1
beqz a0, 1f beqz a0, 1f
j esp_ipc_isr_handler /* Jump to `esp_ipc_isr_handler` which is non-returning. We need to use `jx`
* because on Xtensa, `j` instruction can only refer to a label which
* is in the range [-131068;+131075]. If the destination is out of scope,
* linking will fail. So, to make sure we will always be able to jump to
* that subroutine, retrieve its address and store it in a register. */
movi a0, esp_ipc_isr_handler
jx a0
1: 1:
#endif /* not CONFIG_FREERTOS_UNICORE */ #endif /* not CONFIG_FREERTOS_UNICORE */

View File

@@ -49,7 +49,7 @@ xt_highint4:
/* See if we're here for the IPC_ISR interrupt */ /* See if we're here for the IPC_ISR interrupt */
rsr a0, INTERRUPT rsr a0, INTERRUPT
extui a0, a0, ETS_IPC_ISR_INUM, 1 extui a0, a0, ETS_IPC_ISR_INUM, 1
bnez a0, esp_ipc_isr_handler bnez a0, jump_to_esp_ipc_isr_handler
#endif // not CONFIG_FREERTOS_UNICORE #endif // not CONFIG_FREERTOS_UNICORE
/* Allocate exception frame and save minimal context. */ /* Allocate exception frame and save minimal context. */
@@ -130,6 +130,14 @@ xt_highint4:
rsr a0, EXCSAVE_4 /* restore a0 */ rsr a0, EXCSAVE_4 /* restore a0 */
rfi 4 rfi 4
#ifdef CONFIG_ESP_IPC_ISR_ENABLE
jump_to_esp_ipc_isr_handler:
/* Address of `esp_ipc_isr_handler_address` will always be in `movi` range
* as it is defined right above. */
movi a0, esp_ipc_isr_handler
jx a0
#endif
/* The linker has no reason to link in this file; all symbols it exports are already defined /* The linker has no reason to link in this file; all symbols it exports are already defined
(weakly!) in the default int handler. Define a symbol here so we can use it to have the (weakly!) in the default int handler. Define a symbol here so we can use it to have the
linker inspect this anyway. */ linker inspect this anyway. */