1/*
2 * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8#include <xtensa/coreasm.h>
9#include <xtensa/corebits.h>
10#include <xtensa/config/system.h>
11#include "freertos/xtensa_context.h"
12#include "esp_private/panic_reason.h"
13#include "sdkconfig.h"
14#include "soc/soc.h"
15#include "soc/dport_reg.h"
16#include "soc/soc_caps.h"
17
18/*
19
20Interrupt , a high-priority interrupt, is used for several things:
21- IPC_ISR handler
22- Cache error panic handler
23- Interrupt watchdog panic handler
24
25*/
26
27#define L4_INTR_STACK_SIZE  12
28#define L4_INTR_A2_OFFSET   0
29#define L4_INTR_A3_OFFSET   4
30#define L4_INTR_A4_OFFSET   8
31.data
32_l4_intr_stack:
33    .space      L4_INTR_STACK_SIZE*SOC_CPU_CORES_NUM /* This allocates stacks for each individual CPU. */
34    .section .iram1,"ax"
35    .global     xt_highint4
36    .type       xt_highint4,@function
37    .align      4
38xt_highint4:
39
40#ifndef CONFIG_FREERTOS_UNICORE
41    /* See if we're here for the IPC_ISR interrupt */
42    rsr     a0, INTERRUPT
43    extui   a0, a0, ETS_IPC_ISR_INUM, 1
44    bnez    a0, jump_to_esp_ipc_isr_handler
45#endif // not CONFIG_FREERTOS_UNICORE
46
47    /* Allocate exception frame and save minimal context. */
48    mov     a0, sp
49    addi    sp, sp, -XT_STK_FRMSZ
50    s32i    a0, sp, XT_STK_A1
51    #if XCHAL_HAVE_WINDOWED
52    s32e    a0, sp, -12                     /* for debug backtrace */
53    #endif
54    rsr     a0, PS                          /* save interruptee's PS */
55    s32i    a0, sp, XT_STK_PS
56    rsr     a0, EPC_4                       /* save interruptee's PC */
57    s32i    a0, sp, XT_STK_PC
58    rsr     a0, EXCSAVE_4                   /* save interruptee's a0 */
59    s32i    a0, sp, XT_STK_A0
60    #if XCHAL_HAVE_WINDOWED
61    s32e    a0, sp, -16                     /* for debug backtrace */
62    #endif
63    s32i    a12, sp, XT_STK_A12             /* _xt_context_save requires A12- */
64    s32i    a13, sp, XT_STK_A13             /* A13 to have already been saved */
65    call0   _xt_context_save
66
67    /* Save vaddr into exception frame */
68    rsr     a0, EXCVADDR
69    s32i    a0, sp, XT_STK_EXCVADDR
70
71    /* Figure out reason, save into EXCCAUSE reg */
72
73    rsr     a0, INTERRUPT
74    extui   a0, a0, ETS_CACHEERR_INUM, 1 /* get cacheerr int bit */
75    beqz    a0, 1f
76    /* Kill this interrupt; we cannot reset it. */
77    rsr     a0, INTENABLE
78    movi    a4, ~(1<<ETS_CACHEERR_INUM)
79    and     a0, a4, a0
80    wsr     a0, INTENABLE
81    movi    a0, PANIC_RSN_CACHEERR
82    j 9f
83
841:
85#if CONFIG_ESP_INT_WDT_CHECK_CPU1
86    /* Check if the cause is the app cpu failing to tick.*/
87    movi    a0, int_wdt_cpu1_ticked
88    l32i    a0, a0, 0
89    bnez    a0, 2f
90    /* It is. Modify cause. */
91    movi    a0,PANIC_RSN_INTWDT_CPU1
92    j 9f
932:
94#endif
95
96    /* Set EXCCAUSE to reflect cause of the wdt int trigger */
97    movi    a0,PANIC_RSN_INTWDT_CPU0
989:
99    /* Found the reason, now save it. */
100    s32i    a0, sp, XT_STK_EXCCAUSE
101
102    /* Set up PS for C, disable all interrupts except NMI and debug, and clear EXCM. */
103    movi    a0, PS_INTLEVEL(5) | PS_UM | PS_WOE
104    wsr     a0, PS
105
106    //Call panic handler
107    mov     a6,sp
108    call4   panicHandler
109
110    call0   _xt_context_restore
111    l32i    a0, sp, XT_STK_PS               /* retrieve interruptee's PS */
112    wsr     a0, PS
113    l32i    a0, sp, XT_STK_PC               /* retrieve interruptee's PC */
114    wsr     a0, EPC_4
115    l32i    a0, sp, XT_STK_A0               /* retrieve interruptee's A0 */
116    l32i    sp, sp, XT_STK_A1               /* remove exception frame */
117    rsync                                   /* ensure PS and EPC written */
118
119    rsr     a0, EXCSAVE_4                   /* restore a0 */
120    rfi     4
121
122#ifdef CONFIG_ESP_IPC_ISR_ENABLE
123jump_to_esp_ipc_isr_handler:
124    /* Address of `esp_ipc_isr_handler_address` will always be in `movi` range
125     * as it is defined right above. */
126    movi    a0, esp_ipc_isr_handler
127    jx      a0
128#endif
129
130/* The linker has no reason to link in this file; all symbols it exports are already defined
131   (weakly!) in the default int handler. Define a symbol here so we can use it to have the
132   linker inspect this anyway. */
133
134    .global ld_include_highint_hdl
135ld_include_highint_hdl:
136