/******************************************************************************* * Copyright (C) 2018 Cadence Design Systems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to use this Software with Cadence processor cores only and * not with any other processors and platforms, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ /****************************************************************************** arch_hifi330.S ******************************************************************************/ #include #include #include #include #include #include "arch_hifi330.h" .global OSStartHighRdy .global OSTaskSwHook .global g_pstVosTCBHighRdy .global g_bVosRunning // .data .section .dram0.data, "aw" .type OSIntCtxSw_Occur,@object OSIntCtxSw_Occur: .byte 0 .begin literal_prefix .iram0 .section .iram0.text, "ax" .align 4 .globl VOSStartHighRdy .type VOSStartHighRdy,@function .align 4 /***************************************************************************** VOSStartHighRdy *****************************************************************************/ VOSStartHighRdy: ENTRY(16) /*OSIntCtxSw_Occur*/ movi a2, OSIntCtxSw_Occur movi a3, 0 s8i a3, a2, 0 movi a2, g_bVosRunning movi a3, 1 s8i a3, a2, 0 #if 0 /*OS_TaskSwHook */ movi a2, OS_TaskSwHook callx4 a2 #endif call0 OS_TaskSwitch .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .globl VOSCtxSw .type VOSCtxSw,@function .align 4 /***************************************************************************** OSCtxSw *****************************************************************************/ VOSCtxSw: entry sp, XT_SOL_FRMSZ rsr a2, PS s32i a0, sp, XT_SOL_PC s32i a2, sp, XT_SOL_PS movi a2, g_pstVosTCBCur movi a3, 0 l32i a2, a2, 0 s32i a3, sp, XT_SOL_EXIT s32i sp, a2, OSTCBStkPtr /* g_pstVosTCBCur->OSTCBStkPtr = SP; */ call4 xthal_window_spill #if 0 /*OS_TaskSwHook */ movi a2, OS_TaskSwHook callx4 a2 #endif /* CPENABLE, co-processor state. */ movi a3, g_pstVosTCBCur l32i a3, a3, 0 l32i a2, a3, OSTCBStkBottom movi a3, 0 wsr a3, CPENABLE /* disable all co-processors */ s8i a3, a2, XT_CPENABLE /* cp_state->cpenable = 0; */ call0 OS_TaskSwitch .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .globl VOSIntCtxSw .type VOSIntCtxSw,@function .align 4 /***************************************************************************** OSIntCtxSw *****************************************************************************/ VOSIntCtxSw: ENTRY(16) #if 0 /*OS_TaskSwHook */ movi a2, OS_TaskSwHook callx4 a2 #endif /*CPENABLE task co-processor, CPENABLE. */ movi a3, g_pstVosTCBCur l32i a3, a3, 0 l32i a2, a3, OSTCBStkBottom rsr a3, CPENABLE s8i a3, a2, XT_CPENABLE movi a3, 0 wsr a3, CPENABLE movi a2, OSIntCtxSw_Occur movi a3, 1 s8i a3, a2, 0 RET(16) .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .global OSCPUSaveSR .type OSCPUSaveSR,@function .align 4 /***************************************************************************** OSCPUSaveSR *****************************************************************************/ OSCPUSaveSR: entry a1,32 rsil a2,15 esync retw .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .global OSCPURestoreSR .type OSCPURestoreSR,@function .align 4 /***************************************************************************** OSCPURestoreSR *****************************************************************************/ OSCPURestoreSR: entry a1,32 wsr.ps a2 esync retw .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .global OS_TaskSwitch .type OS_TaskSwitch,@function .align 4 /***************************************************************************** OS_TaskSwitch *****************************************************************************/ OS_TaskSwitch: /*1) g_ucVosPrioCur = g_ucVosPrioHighRdy; g_pstVosTCBCur = g_pstVosTCBHighRdy; SP = g_pstVosTCBHighRdy->OSTCBStkPtr; */ movi a2, g_ucVosPrioHighRdy movi a3, g_ucVosPrioCur l8ui a2, a2, 0 movi a4, g_pstVosTCBHighRdy s8i a2, a3, 0 movi a2, g_pstVosTCBCur l32i a3, a4, 0 l32i sp, a3, OSTCBStkPtr s32i a3, a2, 0 l32i a2, sp, XT_STK_EXIT bnez a2, .L_in_int l32i a3, sp, XT_SOL_PS l32i a0, sp, XT_SOL_PC rsync wsr a3, PS retw .L_in_int: /* co-processor CPENABLE*/ movi a3, g_pstVosTCBCur l32i a3, a3, 0 l32i a2, a3, OSTCBStkBottom l8ui a3, a2, XT_CPENABLE wsr a3, CPENABLE call0 OS_ContextRestore rsync l32i a0, sp, XT_STK_EXIT ret .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .globl OS_ContextSave .type OS_ContextSave,@function .align 4 /***************************************************************************** OS_ContextSave *****************************************************************************/ OS_ContextSave: /*1): A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 SAR,LBENG,LEND,LCOUNT*/ s32i a2, sp, XT_STK_A2 s32i a3, sp, XT_STK_A3 s32i a4, sp, XT_STK_A4 s32i a5, sp, XT_STK_A5 s32i a6, sp, XT_STK_A6 s32i a7, sp, XT_STK_A7 s32i a8, sp, XT_STK_A8 s32i a9, sp, XT_STK_A9 s32i a10, sp, XT_STK_A10 s32i a11, sp, XT_STK_A11 s32i a14, sp, XT_STK_A14 s32i a15, sp, XT_STK_A15 rsr a3, SAR s32i a3, sp, XT_STK_SAR rsr a3, LBEG s32i a3, sp, XT_STK_LBEG rsr a3, LEND s32i a3, sp, XT_STK_LEND rsr a3, LCOUNT s32i a3, sp, XT_STK_LCOUNT /*2)*/ mov a9, a0 s32i a12, sp, XT_STK_TMP+0 s32i a13, sp, XT_STK_TMP+4 s32i a9, sp, XT_STK_TMP+8 l32i a12, sp, XT_STK_A12 l32i a13, sp, XT_STK_A13 l32i a9, sp, XT_STK_A9 addi sp, sp, XT_STK_FRMSZ call0 xthal_window_spill_nw addi sp, sp, -XT_STK_FRMSZ l32i a12, sp, XT_STK_TMP+0 l32i a13, sp, XT_STK_TMP+4 l32i a9, sp, XT_STK_TMP+8 addi a2, sp, XT_STK_EXTRA call0 xthal_save_extra_nw mov a0, a9 ret .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .global OS_ContextRestore .type OS_ContextRestore,@function .align 4 /***************************************************************************** OS_ContextRestore *****************************************************************************/ OS_ContextRestore: /* 1) xthal_restore_extra_nw*/ mov a13, a0 addi a2, sp, XT_STK_EXTRA call0 xthal_restore_extra_nw mov a0, a13 /*2): LBEG LEND LCOUNT A2 SAR A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15*/ l32i a2, sp, XT_STK_LBEG l32i a3, sp, XT_STK_LEND wsr a2, LBEG l32i a2, sp, XT_STK_LCOUNT wsr a3, LEND wsr a2, LCOUNT l32i a3, sp, XT_STK_SAR l32i a2, sp, XT_STK_A2 wsr a3, SAR l32i a3, sp, XT_STK_A3 l32i a4, sp, XT_STK_A4 l32i a5, sp, XT_STK_A5 l32i a6, sp, XT_STK_A6 l32i a7, sp, XT_STK_A7 l32i a8, sp, XT_STK_A8 l32i a9, sp, XT_STK_A9 l32i a10, sp, XT_STK_A10 l32i a11, sp, XT_STK_A11 l32i a12, sp, XT_STK_A12 l32i a13, sp, XT_STK_A13 l32i a14, sp, XT_STK_A14 l32i a15, sp, XT_STK_A15 ret .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .globl OS_IntEnter .type OS_IntEnter,@function .align 4 OS_IntEnter: /* Save a12-13 in the stack frame as required by _xt_context_save. */ s32i a12, sp, XT_STK_A12 s32i a13, sp, XT_STK_A13 /* Save return address in a safe place (free a0). */ mov a12, a0 /* Save the rest of the interrupted context (preserves A12-13). */ call0 OS_ContextSave /* Save interrupted task's SP in TCB only if not nesting. Manage nesting directly rather than call the generic OSIntEnter() (in windowed ABI we can't call a C function here anyway because PS.EXCM is still set). */ movi a2, g_bVosRunning movi a3, g_ucVosIntNesting l8ui a2, a2, 0 /* if (g_bVosRunning == OS_TRUE) { */ beqz a2, 2f l8ui a2, a3, 0 /* if (g_ucVosIntNesting == 0) { */ bnez a2, 1f movi a4, g_pstVosTCBCur l32i a4, a4, 0 s32i sp, a4, OSTCBStkPtr /* g_pstVosTCBCur->OSTCBStkPtr = SP; */ 1: /* } */ addi a2, a2, 1 /* if (g_ucVosIntNesting < 255u) { */ bgeui a2, 256, 2f /* g_ucVosIntNesting++; */ s8i a2, a3, 0 /* } */ 2: /* } */ /* Retrieve the return address and return to interrupt handler. */ mov a0, a12 ret .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .globl OS_IntExit .type OS_IntExit,@function .align 4 OS_IntExit: #if 0 /* Call VOSIntExit() to deal with nesting and call the scheduler. */ movi a2, VOSIntExit rsil a0, XCHAL_EXCM_LEVEL /* enter critical section */ callx4 a2 /* VOSIntExit() */ #endif /* Context-switch deferred from OSIntCtxSw(). Still in critical section. */ movi a2, OSIntCtxSw_Occur l8ui a3, a2, 0 beqz a3, 1f /* if (OSIntCtxSw_Occur) { */ movi a3, 0 /* OSIntCtxSw_Occur = false; */ s8i a3, a2, 0 call0 OS_TaskSwitch /* tail-call dispatcher; */ /* Never returns here. */ /* } */ 1: /* We come here only if there was no context switch, that is if this is a nested interrupt or the interrupted task was not preempted. We are still on the same stack so there's no need to load the SP. */ /* Restore full context from interrupt stack frame and return to exit dispatcher. */ call0 OS_ContextRestore /* Must return via the exit dispatcher corresponding to the entrypoint from which this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt stack frame is deallocated in the exit dispatcher. */ l32i a0, sp, XT_STK_EXIT ret .end literal_prefix .begin literal_prefix .iram0 .section .iram0.text, "ax" .globl OS_GetTaskCoprocState .type OS_GetTaskCoprocState,@function .align 4 OS_GetTaskCoprocState: movi a2, g_bVosRunning movi a3, g_ucVosIntNesting l8ui a2, a2, 0 l8ui a3, a3, 0 beqz a2, 1f bnez a3, 1f movi a15, g_pstVosTCBCur l32i a15, a15, 0 beqz a15, 2f l32i a15, a15, OSTCBStkBottom ret 1: movi a15, 0 2: ret .end literal_prefix