From 8048677b4c437989e48b55fbe6f984f1098cf6b0 Mon Sep 17 00:00:00 2001 From: Omar Chebib Date: Mon, 13 Sep 2021 19:20:51 +0800 Subject: [PATCH] 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. --- components/esp_system/port/soc/esp32/highint_hdl.S | 8 +++++++- components/esp_system/port/soc/esp32s3/highint_hdl.S | 10 +++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/components/esp_system/port/soc/esp32/highint_hdl.S b/components/esp_system/port/soc/esp32/highint_hdl.S index 3ae31686d2..51b963cce6 100644 --- a/components/esp_system/port/soc/esp32/highint_hdl.S +++ b/components/esp_system/port/soc/esp32/highint_hdl.S @@ -173,7 +173,13 @@ xt_highintx: rsr a0, INTERRUPT extui a0, a0, ETS_IPC_ISR_INUM, 1 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: #endif /* not CONFIG_FREERTOS_UNICORE */ diff --git a/components/esp_system/port/soc/esp32s3/highint_hdl.S b/components/esp_system/port/soc/esp32s3/highint_hdl.S index 91916e2cef..af0b2b31e7 100644 --- a/components/esp_system/port/soc/esp32s3/highint_hdl.S +++ b/components/esp_system/port/soc/esp32s3/highint_hdl.S @@ -49,7 +49,7 @@ xt_highint4: /* See if we're here for the IPC_ISR interrupt */ rsr a0, INTERRUPT 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 /* Allocate exception frame and save minimal context. */ @@ -130,6 +130,14 @@ xt_highint4: rsr a0, EXCSAVE_4 /* restore a0 */ 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 (weakly!) in the default int handler. Define a symbol here so we can use it to have the linker inspect this anyway. */