mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 11:09:01 +01:00 
			
		
		
		
	ESP GCC port -- Added LoadStore Exception handlers.
https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/9 -- Handles LoadStoreErrorCause and LoadStoreAlignmentCause allowing to use 32-bit memory region (IRAM) as 8-bit or 16-bit memory region
This commit is contained in:
		
							parent
							
								
									9fdfbf33e9
								
							
						
					
					
						commit
						d319bb0c71
					
				
							
								
								
									
										559
									
								
								FreeRTOS/Source/portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_loadstore_handler.S
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										559
									
								
								FreeRTOS/Source/portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_loadstore_handler.S
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,559 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright 2019 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
 | 
			
		||||
 Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 you may not use this file except in compliance with the License.
 | 
			
		||||
 You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
 Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 See the License for the specific language governing permissions and
 | 
			
		||||
 limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  LoadStoreErrorCause:     Occurs when trying to access 32 bit addressable memory region as 8 bit or 16 bit
 | 
			
		||||
 *  LoadStoreAlignmentCause: Occurs when trying to access in an unaligned manner
 | 
			
		||||
 *
 | 
			
		||||
 *          xxxx xxxx = imm8 field
 | 
			
		||||
 *               yyyy = imm4 field
 | 
			
		||||
 *               ssss = s field
 | 
			
		||||
 *               tttt = t field
 | 
			
		||||
 *
 | 
			
		||||
 *                            16                0
 | 
			
		||||
 *                            -------------------
 | 
			
		||||
 *          L32I.N            yyyy ssss tttt 1000
 | 
			
		||||
 *          S32I.N            yyyy ssss tttt 1001
 | 
			
		||||
 *
 | 
			
		||||
 *                  23                          0
 | 
			
		||||
 *                  -----------------------------
 | 
			
		||||
 *          L8UI    xxxx xxxx 0000 ssss tttt 0010               <- LoadStoreError
 | 
			
		||||
 *          L16UI   xxxx xxxx 0001 ssss tttt 0010               <- LoadStoreError, LoadStoreAlignment
 | 
			
		||||
 *          L16SI   xxxx xxxx 1001 ssss tttt 0010               <- LoadStoreError, LoadStoreAlignment
 | 
			
		||||
 *          L32I    xxxx xxxx 0010 ssss tttt 0010               <- LoadStoreAlignment
 | 
			
		||||
 *
 | 
			
		||||
 *          S8I     xxxx xxxx 0100 ssss tttt 0010               <- LoadStoreError
 | 
			
		||||
 *          S16I    xxxx xxxx 0101 ssss tttt 0010               <- LoadStoreError, LoadStoreAlignment
 | 
			
		||||
 *          S32I    xxxx xxxx 0110 ssss tttt 0010               <- LoadStoreAlignment
 | 
			
		||||
 *
 | 
			
		||||
 *                   ******* UNSUPPORTED *******
 | 
			
		||||
 *
 | 
			
		||||
 *          L32E    0000 1001 rrrr ssss tttt 0000
 | 
			
		||||
 *          S32E    0100 1001 rrrr ssss tttt 0000
 | 
			
		||||
 *                  -----------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "xtensa_rtos.h"
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "soc/soc.h"
 | 
			
		||||
 | 
			
		||||
#define LOADSTORE_HANDLER_STACK_SZ      8
 | 
			
		||||
    .section .bss, "aw"
 | 
			
		||||
    .balign 16
 | 
			
		||||
LoadStoreHandlerStack:
 | 
			
		||||
    .rept LOADSTORE_HANDLER_STACK_SZ
 | 
			
		||||
    .word 0
 | 
			
		||||
    .endr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* LoadStoreErrorCause handler:
 | 
			
		||||
 *
 | 
			
		||||
 * Completes 8-bit or 16-bit load/store instructions from 32-bit aligned memory region
 | 
			
		||||
 * Called from UserExceptionVector if EXCCAUSE is LoadStoreErrorCause
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
    .global   LoadStoreErrorHandler
 | 
			
		||||
    .section .iram1, "ax"
 | 
			
		||||
 | 
			
		||||
    .literal_position
 | 
			
		||||
 | 
			
		||||
    .balign 4
 | 
			
		||||
LoadStoreErrorHandler:
 | 
			
		||||
    .type   LoadStoreErrorHandler, @function
 | 
			
		||||
 | 
			
		||||
    wsr     a0, depc                            // Save return address in depc
 | 
			
		||||
    mov     a0, sp
 | 
			
		||||
    movi    sp, LoadStoreHandlerStack
 | 
			
		||||
    s32i    a0, sp, 0x04                        // Since a0 contains value of a1
 | 
			
		||||
    s32i    a2, sp, 0x08
 | 
			
		||||
    s32i    a3, sp, 0x0c
 | 
			
		||||
    s32i    a4, sp, 0x10
 | 
			
		||||
 | 
			
		||||
    rsr     a0, sar                             // Save SAR in a0 to restore later
 | 
			
		||||
 | 
			
		||||
    /* Check whether the address lies in the valid range */
 | 
			
		||||
    rsr     a3, excvaddr
 | 
			
		||||
    movi    a4, _iram_end                       // End of code section of IRAM
 | 
			
		||||
    bge     a3, a4, 1f
 | 
			
		||||
    movi    a4, SOC_CACHE_APP_LOW               // Check if in APP cache region
 | 
			
		||||
    blt     a3, a4, .LS_wrong_opcode
 | 
			
		||||
    movi    a4, SOC_CACHE_APP_HIGH
 | 
			
		||||
    bge     a3, a4, .LS_wrong_opcode
 | 
			
		||||
    j       2f
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    movi    a4, SOC_IRAM_HIGH                   // End of IRAM address range
 | 
			
		||||
    bge     a3, a4, .LS_wrong_opcode
 | 
			
		||||
 | 
			
		||||
2:
 | 
			
		||||
    /* Examine the opcode which generated the exception */
 | 
			
		||||
    /* Note: Instructions are in this order to avoid pipeline stalls. */
 | 
			
		||||
    rsr     a2, epc1
 | 
			
		||||
    movi    a4, ~3
 | 
			
		||||
    ssa8l   a2                                  // sar is now correct shift for aligned read
 | 
			
		||||
    and     a2, a2, a4                          // a2 now 4-byte aligned address of instruction
 | 
			
		||||
    l32i    a4, a2, 0
 | 
			
		||||
    l32i    a2, a2, 4
 | 
			
		||||
 | 
			
		||||
    src     a2, a2, a4                          // a2 now instruction that failed
 | 
			
		||||
    bbci    a2, 1, .LS_wrong_opcode
 | 
			
		||||
    bbsi    a2, 14, .LSE_store_op               // Store instruction
 | 
			
		||||
 | 
			
		||||
    /* l8/l16ui/l16si */
 | 
			
		||||
    movi    a4, ~3
 | 
			
		||||
    and     a4, a3, a4                          // a4 now word aligned read address
 | 
			
		||||
 | 
			
		||||
    ssa8l   a3                                  // sar is now shift to extract a3's byte
 | 
			
		||||
    l32i    a4, a4, 0                           // perform the actual read
 | 
			
		||||
    srl     a4, a4                              // shift right correct distance
 | 
			
		||||
    extui   a3, a2, 12, 4
 | 
			
		||||
    bnez    a3, 1f                              // l16ui/l16si
 | 
			
		||||
    extui   a4, a4, 0, 8                        // mask off bits needed for an l8
 | 
			
		||||
    j       2f
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    extui   a4, a4, 0, 16
 | 
			
		||||
    bbci    a2, 15, 2f                          // l16ui
 | 
			
		||||
 | 
			
		||||
    /* Sign adjustment */
 | 
			
		||||
    slli    a4, a4, 16
 | 
			
		||||
    srai    a4, a4, 16                          // a4 contains the value
 | 
			
		||||
 | 
			
		||||
2:
 | 
			
		||||
    /* a4 contains the value */
 | 
			
		||||
    rsr     a3, epc1
 | 
			
		||||
    addi    a3, a3, 3
 | 
			
		||||
    wsr     a3, epc1
 | 
			
		||||
    wsr     a0, sar
 | 
			
		||||
    rsr     a0, excsave1
 | 
			
		||||
 | 
			
		||||
    extui   a2, a2, 3, 5
 | 
			
		||||
    blti    a2, 10, .LSE_stack_reg
 | 
			
		||||
 | 
			
		||||
    movi    a3, .LS_jumptable_base
 | 
			
		||||
    addx8   a2, a2, a3                          // a2 is now the address to jump to
 | 
			
		||||
    l32i    a3, sp, 0x0c
 | 
			
		||||
    jx      a2
 | 
			
		||||
 | 
			
		||||
.LSE_stack_reg:
 | 
			
		||||
    addx2   a2, a2, sp
 | 
			
		||||
    s32i    a4, a2, 0
 | 
			
		||||
 | 
			
		||||
    /* Restore all values */
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a3, sp, 0x0c
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
.LSE_store_op:
 | 
			
		||||
    s32i    a5, a1, 0x14
 | 
			
		||||
    s32i    a6, a1, 0x18
 | 
			
		||||
 | 
			
		||||
    /* a2 -> instruction that caused the error */
 | 
			
		||||
    /* a3 -> unaligned address */
 | 
			
		||||
    extui   a4, a2, 4, 4
 | 
			
		||||
    blti    a4, 7, 1f
 | 
			
		||||
    movi    a5, .LSE_store_reg
 | 
			
		||||
    addx8   a5, a4, a5
 | 
			
		||||
    jx      a5
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    addx4   a4, a4, sp
 | 
			
		||||
    l32i    a4, a4, 0
 | 
			
		||||
 | 
			
		||||
.LSE_store_data:
 | 
			
		||||
    /* a4 contains the value */
 | 
			
		||||
    rsr     a6, epc1
 | 
			
		||||
    addi    a6, a6, 3
 | 
			
		||||
    wsr     a6, epc1
 | 
			
		||||
 | 
			
		||||
    ssa8b   a3
 | 
			
		||||
    movi    a5, -1
 | 
			
		||||
    bbsi    a2, 12, 1f                          // s16
 | 
			
		||||
    extui   a4, a4, 0, 8
 | 
			
		||||
    movi    a6, 0xff
 | 
			
		||||
    j       2f
 | 
			
		||||
1:
 | 
			
		||||
    extui   a4, a4, 0, 16
 | 
			
		||||
    movi    a6, 0xffff
 | 
			
		||||
2:
 | 
			
		||||
    sll     a4, a4                              // shift the value to proper offset
 | 
			
		||||
    sll     a6, a6
 | 
			
		||||
    xor     a5, a5, a6                          // a5 contains the mask
 | 
			
		||||
 | 
			
		||||
    movi    a6, ~3
 | 
			
		||||
    and     a3, a3, a6                          // a3 has the aligned address
 | 
			
		||||
    l32i    a6, a3, 0                           // a6 contains the data at the aligned address
 | 
			
		||||
    and     a6, a6, a5
 | 
			
		||||
    or      a4, a6, a4
 | 
			
		||||
    s32i    a4, a3, 0
 | 
			
		||||
 | 
			
		||||
    /* Restore registers */
 | 
			
		||||
    wsr     a0, sar
 | 
			
		||||
 | 
			
		||||
    l32i    a6, sp, 0x18
 | 
			
		||||
    l32i    a5, sp, 0x14
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a3, sp, 0x0c
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rsr     a0, excsave1
 | 
			
		||||
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
.LSE_store_reg:
 | 
			
		||||
    .org .LSE_store_reg + (7 * 8)
 | 
			
		||||
    mov     a4, a7
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (8 * 8)
 | 
			
		||||
    mov     a4, a8
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (9 * 8)
 | 
			
		||||
    mov     a4, a9
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (10 * 8)
 | 
			
		||||
    mov     a4, a10
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (11 * 8)
 | 
			
		||||
    mov     a4, a11
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (12 * 8)
 | 
			
		||||
    mov     a4, a12
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (13 * 8)
 | 
			
		||||
    mov     a4, a13
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (14 * 8)
 | 
			
		||||
    mov     a4, a14
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSE_store_reg + (15 * 8)
 | 
			
		||||
    mov     a4, a15
 | 
			
		||||
    j .LSE_store_data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* LoadStoreAlignmentCause handler:
 | 
			
		||||
 *
 | 
			
		||||
 * Completes unaligned 16-bit and 32-bit load/store instructions from 32-bit aligned memory region
 | 
			
		||||
 * Called from UserExceptionVector if EXCCAUSE is LoadStoreAlignmentCause
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
    .global   AlignmentErrorHandler
 | 
			
		||||
    .section .iram1, "ax"
 | 
			
		||||
 | 
			
		||||
    .literal_position
 | 
			
		||||
 | 
			
		||||
    .balign 4
 | 
			
		||||
AlignmentErrorHandler:
 | 
			
		||||
    .type   AlignmentErrorHandler, @function
 | 
			
		||||
 | 
			
		||||
    wsr     a0, depc                            // Save return address in depc
 | 
			
		||||
    mov     a0, sp
 | 
			
		||||
    movi    sp, LoadStoreHandlerStack
 | 
			
		||||
    s32i    a0, sp, 0x04                        // Since a0 contains value of a1
 | 
			
		||||
    s32i    a2, sp, 0x08
 | 
			
		||||
    s32i    a3, sp, 0x0c
 | 
			
		||||
    s32i    a4, sp, 0x10
 | 
			
		||||
 | 
			
		||||
    rsr     a0, sar                             // Save SAR in a0 to restore later
 | 
			
		||||
 | 
			
		||||
    /* Check whether the address lies in the valid range */
 | 
			
		||||
    rsr     a3, excvaddr
 | 
			
		||||
    movi    a4, _iram_end                       // End of code section of IRAM
 | 
			
		||||
    bge     a3, a4, 1f
 | 
			
		||||
    movi    a4, SOC_CACHE_APP_LOW               // Check if in APP cache region
 | 
			
		||||
    blt     a3, a4, .LS_wrong_opcode
 | 
			
		||||
    movi    a4, SOC_CACHE_APP_HIGH
 | 
			
		||||
    bge     a3, a4, .LS_wrong_opcode
 | 
			
		||||
    j       2f
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    movi    a4, SOC_IRAM_HIGH                   // End of IRAM address range
 | 
			
		||||
    bge     a3, a4, .LS_wrong_opcode
 | 
			
		||||
 | 
			
		||||
2:
 | 
			
		||||
    /* Examine the opcode which generated the exception */
 | 
			
		||||
    /* Note: Instructions are in this order to avoid pipeline stalls. */
 | 
			
		||||
    rsr     a2, epc1
 | 
			
		||||
    movi    a4, ~3
 | 
			
		||||
    ssa8l   a2                                  // sar is now correct shift for aligned read
 | 
			
		||||
    and     a2, a2, a4                          // a2 now 4-byte aligned address of instruction
 | 
			
		||||
    l32i    a4, a2, 0
 | 
			
		||||
    l32i    a2, a2, 4
 | 
			
		||||
 | 
			
		||||
    /* a2 has the instruction that caused the error */
 | 
			
		||||
    src     a2, a2, a4
 | 
			
		||||
    extui   a4, a2, 0, 4
 | 
			
		||||
    addi    a4, a4, -9
 | 
			
		||||
    beqz    a4, .LSA_store_op
 | 
			
		||||
    bbsi    a2, 14, .LSA_store_op
 | 
			
		||||
 | 
			
		||||
    ssa8l   a3                                  // a3 contains the unaligned address
 | 
			
		||||
    movi    a4, ~3
 | 
			
		||||
    and     a4, a3, a4                          // a4 has the aligned address
 | 
			
		||||
    l32i    a3, a4, 0
 | 
			
		||||
    l32i    a4, a4, 4
 | 
			
		||||
    src     a4, a4, a3
 | 
			
		||||
 | 
			
		||||
    rsr     a3, epc1
 | 
			
		||||
    addi    a3, a3, 2
 | 
			
		||||
    bbsi    a2, 3, 1f                           // l32i.n
 | 
			
		||||
    bbci    a2, 1, .LS_wrong_opcode
 | 
			
		||||
    addi    a3, a3, 1
 | 
			
		||||
 | 
			
		||||
    bbsi    a2, 13, 1f                          // l32
 | 
			
		||||
    extui   a4, a4, 0, 16
 | 
			
		||||
    bbci    a2, 15, 1f                          // l16ui
 | 
			
		||||
 | 
			
		||||
    /* Sign adjustment */
 | 
			
		||||
    slli    a4, a4, 16
 | 
			
		||||
    srai    a4, a4, 16                          // a4 contains the value
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    wsr     a3, epc1
 | 
			
		||||
    wsr     a0, sar
 | 
			
		||||
    rsr     a0, excsave1
 | 
			
		||||
 | 
			
		||||
    extui   a2, a2, 4, 4
 | 
			
		||||
    blti    a2, 5, .LSA_stack_reg               // a3 contains the target register
 | 
			
		||||
 | 
			
		||||
    movi    a3, .LS_jumptable_base
 | 
			
		||||
    slli    a2, a2, 4
 | 
			
		||||
    add     a2, a2, a3                          // a2 is now the address to jump to
 | 
			
		||||
    l32i    a3, sp, 0x0c
 | 
			
		||||
    jx      a2
 | 
			
		||||
 | 
			
		||||
.LSA_stack_reg:
 | 
			
		||||
    addx4   a2, a2, sp
 | 
			
		||||
    s32i    a4, a2, 0
 | 
			
		||||
 | 
			
		||||
    /* Restore all values */
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a3, sp, 0x0c
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
/* Store instruction */
 | 
			
		||||
.LSA_store_op:
 | 
			
		||||
    s32i    a5, sp, 0x14
 | 
			
		||||
    s32i    a6, sp, 0x18
 | 
			
		||||
    s32i    a7, sp, 0x1c
 | 
			
		||||
 | 
			
		||||
    /* a2 -> instruction that caused the error */
 | 
			
		||||
    /* a3 -> unaligned address */
 | 
			
		||||
    extui   a4, a2, 4, 4
 | 
			
		||||
    blti    a4, 8, 1f
 | 
			
		||||
    movi    a5, .LSA_store_reg
 | 
			
		||||
    addx8   a5, a4, a5
 | 
			
		||||
    jx      a5
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    addx4   a4, a4, sp
 | 
			
		||||
    l32i    a4, a4, 0                           // a4 contains the value
 | 
			
		||||
 | 
			
		||||
.LSA_store_data:
 | 
			
		||||
    movi    a6, 0
 | 
			
		||||
 | 
			
		||||
    rsr     a7, epc1
 | 
			
		||||
    addi    a7, a7 ,2
 | 
			
		||||
    bbsi    a2, 3, 1f                           // s32i.n
 | 
			
		||||
    bbci    a2, 1, .LS_wrong_opcode
 | 
			
		||||
 | 
			
		||||
    addi    a7, a7, 1
 | 
			
		||||
    bbsi    a2, 13, 1f                          // s32i
 | 
			
		||||
 | 
			
		||||
    movi    a5, -1
 | 
			
		||||
    extui   a4, a4, 0, 16
 | 
			
		||||
    slli    a6, a5, 16                          // 0xffff0000
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
    wsr     a7, epc1
 | 
			
		||||
    movi    a5, ~3
 | 
			
		||||
    and     a5, a3, a5                          // a5 has the aligned address
 | 
			
		||||
 | 
			
		||||
    ssa8b   a3
 | 
			
		||||
    movi    a3, -1
 | 
			
		||||
    src     a7, a6, a3
 | 
			
		||||
    src     a3, a3, a6
 | 
			
		||||
 | 
			
		||||
    /* Store data on lower address */
 | 
			
		||||
    l32i    a6, a5, 0
 | 
			
		||||
    and     a6, a6, a7
 | 
			
		||||
    sll     a7, a4
 | 
			
		||||
    or      a6, a6, a7
 | 
			
		||||
    s32i    a6, a5, 0
 | 
			
		||||
 | 
			
		||||
    /* Store data on higher address */
 | 
			
		||||
    l32i    a7, a5, 4
 | 
			
		||||
    srl     a6, a4
 | 
			
		||||
    and     a3, a7, a3
 | 
			
		||||
    or      a3, a3, a6
 | 
			
		||||
    s32i    a3, a5, 4
 | 
			
		||||
 | 
			
		||||
    /* Restore registers */
 | 
			
		||||
    wsr     a0, sar
 | 
			
		||||
    rsr     a0, excsave1
 | 
			
		||||
 | 
			
		||||
    l32i    a7, sp, 0x1c
 | 
			
		||||
    l32i    a6, sp, 0x18
 | 
			
		||||
    l32i    a5, sp, 0x14
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a3, sp, 0x0c
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
.LSA_store_reg:
 | 
			
		||||
    .org .LSA_store_reg + (8 * 8)
 | 
			
		||||
    mov     a4, a8
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSA_store_reg + (9 * 8)
 | 
			
		||||
    mov     a4, a9
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSA_store_reg + (10 * 8)
 | 
			
		||||
    mov     a4, a10
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSA_store_reg + (11 * 8)
 | 
			
		||||
    mov     a4, a11
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSA_store_reg + (12 * 8)
 | 
			
		||||
    mov     a4, a12
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSA_store_reg + (13 * 8)
 | 
			
		||||
    mov     a4, a13
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSA_store_reg + (14 * 8)
 | 
			
		||||
    mov     a4, a14
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
    .org .LSA_store_reg + (15 * 8)
 | 
			
		||||
    mov     a4, a15
 | 
			
		||||
    j       .LSA_store_data
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Common routines for both the exception handlers
 | 
			
		||||
 */
 | 
			
		||||
    .balign 4
 | 
			
		||||
.LS_jumptable:
 | 
			
		||||
    /*  The first 5 entries (80 bytes) of this table are unused (registers
 | 
			
		||||
        a0..a4 are handled separately above).  Rather than have a whole bunch
 | 
			
		||||
        of wasted space, just pretend that the table starts 80 bytes
 | 
			
		||||
        earlier in memory. */
 | 
			
		||||
    .set    .LS_jumptable_base, .LS_jumptable - (16 * 5)
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 5)
 | 
			
		||||
    mov     a5, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 6)
 | 
			
		||||
    mov     a6, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 7)
 | 
			
		||||
    mov     a7, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 8)
 | 
			
		||||
    mov     a8, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 9)
 | 
			
		||||
    mov     a9, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 10)
 | 
			
		||||
    mov     a10, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 11)
 | 
			
		||||
    mov     a11, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 12)
 | 
			
		||||
    mov     a12, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 13)
 | 
			
		||||
    mov     a13, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 14)
 | 
			
		||||
    mov     a14, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
    .org    .LS_jumptable_base + (16 * 15)
 | 
			
		||||
    mov     a15, a4
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rfe
 | 
			
		||||
 | 
			
		||||
.LS_wrong_opcode:
 | 
			
		||||
    /* Reaches here if the address is in invalid range or the opcode isn't supported.
 | 
			
		||||
     * Restore registers and jump back to _xt_user_exc
 | 
			
		||||
     */
 | 
			
		||||
    wsr     a0, sar
 | 
			
		||||
    l32i    a4, sp, 0x10
 | 
			
		||||
    l32i    a3, sp, 0x0c
 | 
			
		||||
    l32i    a2, sp, 0x08
 | 
			
		||||
    l32i    a1, sp, 0x04
 | 
			
		||||
    rsr     a0, depc
 | 
			
		||||
    ret                                         // Equivalent to jx a0
 | 
			
		||||
@ -581,6 +581,11 @@ _UserExceptionVector:
 | 
			
		||||
--------------------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
 | 
			
		||||
    .global   LoadStoreErrorHandler
 | 
			
		||||
    .global   AlignmentErrorHandler
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    .section .iram1,"ax"
 | 
			
		||||
 | 
			
		||||
    #if XCHAL_HAVE_WINDOWED
 | 
			
		||||
@ -602,6 +607,20 @@ _xt_to_coproc_exc:
 | 
			
		||||
    /* never returns here - call0 is used as a jump (see note at top) */
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
 | 
			
		||||
    .align      4
 | 
			
		||||
_call_loadstore_handler:
 | 
			
		||||
    call0   LoadStoreErrorHandler
 | 
			
		||||
    /* This will return only if wrong opcode or address out of range*/
 | 
			
		||||
    j       .LS_exit
 | 
			
		||||
 | 
			
		||||
    .align      4
 | 
			
		||||
_call_alignment_handler:
 | 
			
		||||
    call0   AlignmentErrorHandler
 | 
			
		||||
    /* This will return only if wrong opcode or address out of range*/
 | 
			
		||||
    addi    a0, a0, 1
 | 
			
		||||
    j       .LS_exit
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
--------------------------------------------------------------------------------
 | 
			
		||||
@ -631,6 +650,15 @@ _xt_user_exc:
 | 
			
		||||
    #endif
 | 
			
		||||
    beqi    a0, EXCCAUSE_SYSCALL, _xt_to_syscall_exc
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
 | 
			
		||||
    beqi    a0, EXCCAUSE_LOAD_STORE_ERROR, _call_loadstore_handler
 | 
			
		||||
 | 
			
		||||
    addi    a0, a0, -1
 | 
			
		||||
    beqi    a0, 8, _call_alignment_handler
 | 
			
		||||
    addi    a0, a0, 1
 | 
			
		||||
.LS_exit:
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Handle all other exceptions. All can have user-defined handlers. */
 | 
			
		||||
    /* NOTE: we'll stay on the user stack for exception handling.       */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user