319 lines
7.8 KiB
ArmAsm
319 lines
7.8 KiB
ArmAsm
/*
|
|
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
|
|
*/
|
|
/******************************************************************************
|
|
* @file vectors.S
|
|
* @brief define default vector handlers. Should use with
|
|
* GCC for CSKY Embedded Processors
|
|
* @version V1.0
|
|
* @date 28. Nove 2017
|
|
******************************************************************************/
|
|
#define __ASSEMBLY__
|
|
#include "irq_ctx.h"
|
|
|
|
/* Enable interrupts when returning from the handler */
|
|
#define MSTATUS_PRV1 0x1880
|
|
|
|
.section .bss.g_trap_stack
|
|
|
|
.align 4
|
|
.global g_trap_sp_base
|
|
.global g_trap_sp
|
|
g_trap_sp_base:
|
|
#if defined(__riscv_flen)
|
|
.space 1024
|
|
#else
|
|
.space 512
|
|
#endif
|
|
g_trap_sp:
|
|
#if 0
|
|
.section .bss.g_irq_stack
|
|
.align 4
|
|
.global g_irq_sp_base
|
|
.global g_irq_sp
|
|
g_irq_sp_base:
|
|
.space 1024
|
|
g_irq_sp:
|
|
#endif
|
|
/******************************************************************************
|
|
* Functions:
|
|
* void default_interrupt_handler(void);
|
|
* default handler for all the vector mode IRQs
|
|
******************************************************************************/
|
|
|
|
.section .text.vectors.default_interrupt_handler, "ax", %progbits
|
|
.align 6
|
|
.global default_interrupt_handler
|
|
.weak default_interrupt_handler
|
|
/* FreeRTOS will define tspend_handler for context switch */
|
|
.type default_interrupt_handler, %function
|
|
default_interrupt_handler:
|
|
/* ipush */
|
|
addi sp, sp, -76
|
|
|
|
/* save x5 x6 then save mepc mcause */
|
|
sw x5, 4(sp)
|
|
sw x6, 8(sp)
|
|
csrr t0, mepc
|
|
csrr t1, mcause
|
|
sw t1, 64(sp)
|
|
sw t0, 68(sp)
|
|
csrr t0, mscratch
|
|
sw t0, 72(sp)
|
|
/* save regs */
|
|
sw x1, 0(sp)
|
|
sw x7, 12(sp)
|
|
sw x10, 16(sp)
|
|
sw x11, 20(sp)
|
|
sw x12, 24(sp)
|
|
sw x13, 28(sp)
|
|
sw x14, 32(sp)
|
|
sw x15, 36(sp)
|
|
sw x16, 40(sp)
|
|
sw x17, 44(sp)
|
|
sw x28, 48(sp)
|
|
sw x29, 52(sp)
|
|
sw x30, 56(sp)
|
|
sw x31, 60(sp)
|
|
|
|
/*
|
|
* IRQ stack contents after ipush:
|
|
* ~mem addr high:
|
|
* + 0: <--- init IRQ sp (mscratch)
|
|
* - 4: mepc
|
|
* - 8: mcause
|
|
* - 12: x1 (ra)
|
|
* - 16: x5 (t0)
|
|
* - 20: x6 (t1)
|
|
* - 24: x7 (t2)
|
|
* - 28: x10 (a0)
|
|
* - 32: x11 (a1)
|
|
* - 36: x12 (a2)
|
|
* - 40: x13 (a3)
|
|
* - 44: x14 (a4)
|
|
* - 48: x15 (a5)
|
|
* - 52: x16 (a6)
|
|
* - 56: x17 (a7)
|
|
* - 60: x28 (t3)
|
|
* - 64: x29 (t4)
|
|
* - 68: x30 (t5)
|
|
* - 72: x31 (t6) <--- current IRQ sp
|
|
* ~mem addr low:
|
|
*/
|
|
/* WARNING: global IRQ enabled by ipush */
|
|
|
|
/* keep stack 16bytes aligned */
|
|
addi sp, sp, -88
|
|
|
|
/* - 76: mstatus */
|
|
csrr t1, mstatus
|
|
sw t1, 84(sp)
|
|
srli t2, t1, 13
|
|
andi t2, t2, 0x3
|
|
li t0, 0x3
|
|
bne t2, t0, .F_RegNotSave1
|
|
|
|
fsw ft0, 0(sp)
|
|
fsw ft1, 4(sp)
|
|
fsw ft2, 8(sp)
|
|
fsw ft3, 12(sp)
|
|
fsw ft4, 16(sp)
|
|
fsw ft5, 20(sp)
|
|
fsw ft6, 24(sp)
|
|
fsw ft7, 28(sp)
|
|
fsw fa0, 32(sp)
|
|
fsw fa1, 36(sp)
|
|
fsw fa2, 40(sp)
|
|
fsw fa3, 44(sp)
|
|
fsw fa4, 48(sp)
|
|
fsw fa5, 52(sp)
|
|
fsw fa6, 56(sp)
|
|
fsw fa7, 60(sp)
|
|
fsw ft8, 64(sp)
|
|
fsw ft9, 68(sp)
|
|
fsw ft10,72(sp)
|
|
fsw ft11,76(sp)
|
|
.F_RegNotSave1:
|
|
|
|
csrr a0, mcause
|
|
andi t1, a0, 0x3FF
|
|
/* get ISR */
|
|
la t2, interrupt_entry
|
|
jalr t2
|
|
|
|
lw t1, 84(sp)
|
|
srli t2, t1, 13
|
|
andi t2, t2, 0x3
|
|
li t0, 0x3
|
|
bne t2, t0, .F_RegNotLoad
|
|
|
|
flw ft0, 0(sp)
|
|
flw ft1, 4(sp)
|
|
flw ft2, 8(sp)
|
|
flw ft3, 12(sp)
|
|
flw ft4, 16(sp)
|
|
flw ft5, 20(sp)
|
|
flw ft6, 24(sp)
|
|
flw ft7, 28(sp)
|
|
flw fa0, 32(sp)
|
|
flw fa1, 36(sp)
|
|
flw fa2, 40(sp)
|
|
flw fa3, 44(sp)
|
|
flw fa4, 48(sp)
|
|
flw fa5, 52(sp)
|
|
flw fa6, 56(sp)
|
|
flw fa7, 60(sp)
|
|
flw ft8, 64(sp)
|
|
flw ft9, 68(sp)
|
|
flw ft10,72(sp)
|
|
flw ft11,76(sp)
|
|
|
|
.F_RegNotLoad:
|
|
addi sp, sp, 88
|
|
/* mret included, and IRQ tail-chain may happen */
|
|
/* ipop */
|
|
|
|
csrc mstatus, 8
|
|
/* restore mepc mcause mscrath */
|
|
lw t0, 68(sp)
|
|
csrw mepc, t0
|
|
lw t0, 64(sp)
|
|
csrw mcause, t0
|
|
lw t0, 72(sp)
|
|
csrw mscratch, t0
|
|
/* restore regs */
|
|
lw x1, 0(sp)
|
|
lw x5, 4(sp)
|
|
lw x6, 8(sp)
|
|
lw x7, 12(sp)
|
|
lw x10, 16(sp)
|
|
lw x11, 20(sp)
|
|
lw x12, 24(sp)
|
|
lw x13, 28(sp)
|
|
lw x14, 32(sp)
|
|
lw x15, 36(sp)
|
|
lw x16, 40(sp)
|
|
lw x17, 44(sp)
|
|
lw x28, 48(sp)
|
|
lw x29, 52(sp)
|
|
lw x30, 56(sp)
|
|
lw x31, 60(sp)
|
|
|
|
addi sp, sp, 76
|
|
mret
|
|
|
|
.size default_interrupt_handler, . - default_interrupt_handler
|
|
|
|
/******************************************************************************
|
|
* Functions:
|
|
* void trap(void);
|
|
* default handler for exceptions and non-vector mode IRQs
|
|
******************************************************************************/
|
|
.section .text.vectors.default_trap_handler, "ax", %progbits
|
|
.align 6
|
|
.global trap
|
|
.type trap, %function
|
|
.weak default_trap_handler
|
|
.global default_trap_handler
|
|
.type default_trap_handler, %function
|
|
default_trap_handler:
|
|
trap:
|
|
/* Check for interrupt */
|
|
sw t0, -4(sp)
|
|
csrr t0, mcause
|
|
|
|
/* IRQ, but in non-vector mode */
|
|
blt t0, x0, .Lirq
|
|
|
|
la t0, g_trap_sp
|
|
addi t0, t0, -XCPTCONTEXT_SIZE
|
|
sw x1, REG_X1(t0)
|
|
sw x2, REG_X2(t0)
|
|
sw x3, REG_X3(t0)
|
|
sw x4, REG_X4(t0)
|
|
sw x6, REG_X6(t0)
|
|
sw x7, REG_X7(t0)
|
|
sw x8, REG_X8(t0)
|
|
sw x9, REG_X9(t0)
|
|
sw x10, REG_X10(t0)
|
|
sw x11, REG_X11(t0)
|
|
sw x12, REG_X12(t0)
|
|
sw x13, REG_X13(t0)
|
|
sw x14, REG_X14(t0)
|
|
sw x15, REG_X15(t0)
|
|
sw x16, REG_X16(t0)
|
|
sw x17, REG_X17(t0)
|
|
sw x18, REG_X18(t0)
|
|
sw x19, REG_X19(t0)
|
|
sw x20, REG_X20(t0)
|
|
sw x21, REG_X21(t0)
|
|
sw x22, REG_X22(t0)
|
|
sw x23, REG_X23(t0)
|
|
sw x24, REG_X24(t0)
|
|
sw x25, REG_X25(t0)
|
|
sw x26, REG_X26(t0)
|
|
sw x27, REG_X27(t0)
|
|
sw x28, REG_X28(t0)
|
|
sw x29, REG_X29(t0)
|
|
sw x30, REG_X30(t0)
|
|
sw x31, REG_X31(t0)
|
|
csrr a0, mepc
|
|
sw a0, REG_EPC(t0)
|
|
csrr a0, mstatus
|
|
sw a0, REG_INT_CTX(t0)
|
|
|
|
mv a0, t0
|
|
lw t0, -4(sp)
|
|
mv sp, a0
|
|
sw t0, REG_X5(sp)
|
|
|
|
jal exception_entry
|
|
|
|
lw t0, REG_INT_CTX(sp)
|
|
csrw mstatus, t0
|
|
lw t0, REG_EPC(sp)
|
|
csrw mepc, t0
|
|
|
|
lw x31, REG_X31(sp)
|
|
lw x30, REG_X30(sp)
|
|
lw x29, REG_X29(sp)
|
|
lw x28, REG_X28(sp)
|
|
lw x27, REG_X27(sp)
|
|
lw x26, REG_X26(sp)
|
|
lw x25, REG_X25(sp)
|
|
lw x24, REG_X24(sp)
|
|
lw x23, REG_X23(sp)
|
|
lw x22, REG_X22(sp)
|
|
lw x21, REG_X21(sp)
|
|
lw x20, REG_X20(sp)
|
|
lw x19, REG_X19(sp)
|
|
lw x18, REG_X18(sp)
|
|
lw x17, REG_X17(sp)
|
|
lw x16, REG_X16(sp)
|
|
lw x15, REG_X15(sp)
|
|
lw x14, REG_X14(sp)
|
|
lw x13, REG_X13(sp)
|
|
lw x12, REG_X12(sp)
|
|
lw x11, REG_X11(sp)
|
|
lw x10, REG_X10(sp)
|
|
lw x9, REG_X9(sp)
|
|
lw x8, REG_X8(sp)
|
|
lw x7, REG_X7(sp)
|
|
lw x6, REG_X6(sp)
|
|
lw x5, REG_X5(sp)
|
|
lw x4, REG_X4(sp)
|
|
lw x3, REG_X3(sp)
|
|
lw x1, REG_X1(sp)
|
|
lw x2, REG_X2(sp)
|
|
|
|
mret
|
|
|
|
.Lirq:
|
|
lw t0, -4(sp)
|
|
/* MSOFT IRQ for FreeRTOS context switch
|
|
* Config MSOFT IRQ to non-vector mode
|
|
* tspend_handler is a weak alias to default_interrupt_handler
|
|
*/
|
|
j default_interrupt_handler
|
|
|
|
.size default_trap_handler, . - default_trap_handler |