blob: 6d1eb7e7da15939daa2456c9a571ecfd711f938c [file] [log] [blame]
/*******************************************************************************
* 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 <xtensa/coreasm.h>
#include <xtensa/simcall.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa/config/core.h>
#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