diff options
Diffstat (limited to 'hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey')
-rw-r--r-- | hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/arch_hifi330.S | 468 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/cpu_c.c | 152 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_comm.c | 75 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_debug.c | 468 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/int_vector.S | 830 | ||||
-rw-r--r-- | hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/reset.S | 460 |
6 files changed, 2453 insertions, 0 deletions
diff --git a/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/arch_hifi330.S b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/arch_hifi330.S new file mode 100644 index 00000000..6d1eb7e7 --- /dev/null +++ b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/arch_hifi330.S @@ -0,0 +1,468 @@ +/******************************************************************************* +* 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 + + diff --git a/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/cpu_c.c b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/cpu_c.c new file mode 100644 index 00000000..12ce8b71 --- /dev/null +++ b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/cpu_c.c @@ -0,0 +1,152 @@ +/******************************************************************************* +* 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. + +******************************************************************************/ + + +#include "cpu_c.h" +#include <xtensa/config/specreg.h> +#include <xtensa/config/core.h> +#include <xtensa/simcall.h> +#include "arch_hifi330.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/*lint -e838 -e835 -e750 -e529 -e533 -e40*/ + +//#define DSP_TRACES_TO_MEM_SIZE (0x800) + +void *g_pfVosHookFuncTable[OS_HOOK_TYPE_BUTT]; + +void *g_pfVosIntrFuncTable[OS_INTR_CONNECT_BUTT]; + +//unsigned int g_uwSoftIntInfo = 0; + +/* Interrupt nesting level */ +unsigned char g_ucVosIntNesting; + +/* Priority of current task */ +unsigned char g_ucVosPrioCur; + +/* Priority of highest priority task */ +unsigned char g_ucVosPrioHighRdy; + +/* Flag indicating that kernel is running */ +unsigned short g_bVosRunning; + +/* Pointer to highest priority TCB R-to-R */ +unsigned int *g_pstVosTCBHighRdy; + +/* Pointer to currently running TCB*/ +unsigned int *g_pstVosTCBCur; + +#define _XTSTR(x) #x +#define XTSTR(x) _XTSTR(x) + +void OS_EnterIntHook(unsigned int uhwIntrNo) +{ + INTR_HOOK_FUN_TYPE pfIntrHook = (INTR_HOOK_FUN_TYPE)g_pfVosHookFuncTable[OS_HOOK_TYPE_ENTER_INTR];/*lint !e611*/ + + if (0 != pfIntrHook) + { + pfIntrHook(uhwIntrNo); + } +} + +void OS_ExitIntHook(unsigned int uhwIntrNo) +{ + INTR_HOOK_FUN_TYPE pfIntrHook = (INTR_HOOK_FUN_TYPE)g_pfVosHookFuncTable[OS_HOOK_TYPE_EXIT_INTR];/*lint !e611*/ + + if (0 != pfIntrHook) + { + pfIntrHook(uhwIntrNo); + } +} + +void OS_UserexecHandler(unsigned int uwExecCauseNo, unsigned int psAddr) +{ + VOS_EXCEPTION_HOOK_FUNC pfIntrHook = (VOS_EXCEPTION_HOOK_FUNC)g_pfVosHookFuncTable[OS_HOOK_TYPE_EXCEPTION];/*lint !e611*/ + + if (0 != pfIntrHook) + { + pfIntrHook(uwExecCauseNo); + } + else + { + extern void OS_Panic(void); + OS_Panic(); + } +} + +void OS_InterruptHandler(unsigned int uhwIntrNo) +{ + HOOK_FUN_TYPE pfIntrHook = (HOOK_FUN_TYPE)g_pfVosIntrFuncTable[uhwIntrNo]; + + if (0 != pfIntrHook) + //pfIntrHook(); + pfIntrHook(0); +} + +void OS_NmiHook(unsigned int uwExecCauseNo, unsigned int psAddr) +{ + HOOK_FUN_TYPE pfNmiHook = (HOOK_FUN_TYPE)g_pfVosHookFuncTable[OS_HOOK_TYPE_NMI];/*lint !e611*/ + + if (0 != pfNmiHook) + { + //pfNmiHook(); + pfNmiHook(0); + } + + //wait for hifi reset + UCOM_SET_WFI_NMI(5); +} + +void VOS_ConnectInterrupt(unsigned int uwIntrNo, HOOK_FUN_TYPE pfnInterruptHook) +{ + g_pfVosIntrFuncTable[uwIntrNo] = (void *)pfnInterruptHook;/*lint !e611*/ +} + +void VOS_EnableInterrupt(unsigned int uwIntNo) +{ + unsigned int uwBitEnable; + + uwBitEnable = xthal_get_intenable(); + xthal_set_intenable(uwBitEnable | (((unsigned int)1) << uwIntNo )); + +} +void VOS_DisableInterrupt(unsigned int uwIntNo) +{ + unsigned int uwBitEnable; + + uwBitEnable = xthal_get_intenable(); + xthal_set_intenable(uwBitEnable | (((unsigned int)0) << uwIntNo )); + +} + +#ifdef __cplusplus + #if __cplusplus + } + #endif +#endif + diff --git a/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_comm.c b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_comm.c new file mode 100644 index 00000000..290ca9dd --- /dev/null +++ b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_comm.c @@ -0,0 +1,75 @@ +/******************************************************************************* +* 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. + +******************************************************************************/ + +#include "dsp_comm.h" + +void dsp_memcpy(void *d, void *s, unsigned int size) +{ + unsigned char *dest = (unsigned char*)d; + unsigned char *src = (unsigned char*)s; + + if (s == d) { + return; + } else if (src > dest) { + for (; dest < ((unsigned char*)d + size); dest++) { + *dest = *src; + src++; + } + } else { + src = src + (size - 1); + for (dest = dest + (size - 1); dest >= (unsigned char*)d; dest--) { + *dest = *src; + src--; + } + } +} + + +void dsp_memset(void *d, unsigned char ucData, unsigned int size) +{ + unsigned int i; + unsigned char *dest = (unsigned char*)d; + + for(i = 0; i < size; i++) + *dest++ = ucData; +} +int division(int a, int b) +{ + const int bits_in_word_m1 = (int)(sizeof(int) * 8) - 1; + int s_a = a >> bits_in_word_m1; /* s_a = a < 0 ? -1 : 0 */ + int s_b = b >> bits_in_word_m1; /* s_b = b < 0 ? -1 : 0 */ + a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ + b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ + s_a ^= s_b; /* sign of quotient */ + /* + * On CPUs without unsigned hardware division support, + * this calls __udivsi3 (notice the cast to su_int). + * On CPUs with unsigned hardware division support, + * this uses the unsigned division instruction. + */ + return ((int)a/(int)b ^ s_a) - s_a; /* negate if s_a == -1 */ + +} + + + + diff --git a/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_debug.c b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_debug.c new file mode 100644 index 00000000..a74308e4 --- /dev/null +++ b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/dsp_debug.c @@ -0,0 +1,468 @@ +/******************************************************************************* +* 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. + +******************************************************************************/ + +#include <stdarg.h> +#include <stdlib.h> +#include "dsp_debug.h" +#include "dsp_memory_config.h" +#include "dsp_driver_mailbox.h" +#include "dsp_comm.h" +#include "dsp_pcm_gain.h" +extern int g_pcm_gain; +extern int MsgFlag; +extern int InpBuf[HOLD_BUF_SIZE]; // assumes 32 bit samples. +extern int OutBuf[HOLD_BUF_SIZE]; // assumes 32 bit samples. + +static int hex2asc(int n) +{ + n &= 15; + if(n > 9){ + return ('a' - 10) + n; + } else { + return '0' + n; + } +} + +static void xputs(const char *s, void (*xputc)(unsigned n, void *cookie), void *cookie) +{ + while (*s) { + xputc(*s++, cookie); + } +} + +void __xprintf(const char *fmt, va_list ap,void (*xputc)(unsigned n, void *cookie), void *cookie) +{ + char scratch[32]; + for(;;){ + switch(*fmt){ + case 0: + va_end(ap); + return; + case '%': + switch(fmt[1]) { + case 'c': { + unsigned n = va_arg(ap, unsigned); + xputc(n, cookie); + fmt += 2; + continue; + } + case 'h': { + unsigned n = va_arg(ap, unsigned); + xputc(hex2asc(n >> 12), cookie); + xputc(hex2asc(n >> 8), cookie); + xputc(hex2asc(n >> 4), cookie); + xputc(hex2asc(n >> 0), cookie); + fmt += 2; + continue; + } + case 'b': { + unsigned n = va_arg(ap, unsigned); + xputc(hex2asc(n >> 4), cookie); + xputc(hex2asc(n >> 0), cookie); + fmt += 2; + continue; + } + case 'p': + case 'X': + case 'x': { + unsigned n = va_arg(ap, unsigned); + char *p = scratch + 15; + *p = 0; + do { + *--p = hex2asc(n); + n = n >> 4; + } while(n != 0); + while(p > (scratch + 7)) *--p = '0'; + xputs(p, xputc, cookie); + fmt += 2; + continue; + } + case 'd': { + int n = va_arg(ap, int); + char *p = scratch + 15; + *p = 0; + if(n < 0) { + xputc('-', cookie); + n = -n; + } + do { + *--p = (n % 10) + '0'; + n /= 10; + } while(n != 0); + xputs(p, xputc, cookie); + fmt += 2; + continue; + } + + case 'f': { + double fnum = va_arg(ap, double); + unsigned long long ipart, fpart; + int i=4; + char *p = scratch + 31; + *p = '\0'; + + if(fnum < 0.0) + { + xputc('-', cookie); + fnum = -fnum; + } + ipart = (unsigned long long)fnum; + fpart = ((fnum-ipart)*10000); //10^i = 10000 + + while(i>0) + { + *--p = (fpart % 10) + '0'; + fpart /= 10; + i--; + } + *--p = '.'; + while(ipart > 0) + { + *--p = (ipart % 10) + '0'; + ipart /= 10; + } + + xputs(p, xputc, cookie); + fmt += 2; + continue; + } + + case 'u': { + unsigned n = va_arg(ap, unsigned); + char *p = scratch + 15; + *p = 0; + do { + *--p = (n % 10) + '0'; + n /= 10; + } while(n != 0); + xputs(p, xputc, cookie); + fmt += 2; + continue; + } + case 's': { + char *s = (char *)va_arg(ap, char*); + if(s == 0) s = "(null)"; + xputs(s, xputc, cookie); + fmt += 2; + continue; + } + case 'l': { + if (fmt[2] == 'x') { + unsigned long long n = va_arg(ap, unsigned long long); + char *p = scratch + 23; + *p = 0; + do { + *--p = hex2asc((int)n); + n = n >> 4; + } while(n != 0); + while(p > (scratch + 7)) *--p = '0'; + xputs(p, xputc, cookie); + fmt += 3; + continue; + } + } + } + xputc(*fmt++, cookie); + break; + case '\n': + xputc('\r', cookie); + default: + xputc(*fmt++, cookie); + } + } +} + +static char* log_to_mem_head = 0; +void dsp_debug_init() +{ + log_to_mem_head = (char *)(*((unsigned int *)DRV_DSP_UART_TO_MEM_CUR_ADDR) + DRV_DSP_UART_TO_MEM); + +} + +static void log_write_to_mem(const char c_data) +{ + *log_to_mem_head = c_data; + + log_to_mem_head++; + if ((unsigned int)log_to_mem_head >= (DRV_DSP_UART_TO_MEM + DRV_DSP_UART_TO_MEM_SIZE - 1)) + log_to_mem_head = (char *)DRV_DSP_UART_TO_MEM + DRV_DSP_UART_TO_MEM_RESERVE_SIZE; + + *((unsigned int *)DRV_DSP_UART_TO_MEM_CUR_ADDR) = (unsigned int)log_to_mem_head - DRV_DSP_UART_TO_MEM; +} + + +static void print_char(const char c_data) +{ + if (c_data == '\n') + log_write_to_mem('\r'); + log_write_to_mem(c_data); +} + +typedef void (*xputc_type)(unsigned n, void *cookie); + +void print_log(const char *fmt, ...) +{ + va_list args; +va_start(args, fmt); + __xprintf(fmt, args, (xputc_type)print_char, 0); + va_end(args); +} +#ifdef HIKEY_XAF_IPC_COMMENT_OUT +#define ISSPACE(c) (c == ' ' || c == 0x09 || c == 0x0A || c == 0x0D || c == 0) + +char* dsp_om_trim_zero(char* str) +{ + char *str_begin = 0; + char *str_end = 0; + + if (!str) + return 0; + + str_begin = str; + str_end = str + strlen(str); + + while (str_begin < str_end) { + if (ISSPACE(*str_begin)) { + *str_begin = 0; + str_begin++; + } else { + break; + } + } + while (str_begin < str_end) { + if (ISSPACE(*str_end)) { + *str_end = 0; + str_end--; + } else { + break; + } + } + + return str_begin; +} + +char * dsp_om_split_str(char* str, char** split_str) +{ + char *str_begin = 0; + char *str_end = 0; + + if ((!str) || (!split_str)) { + DSP_LOGE("input param is null\n"); + return str; + } + + str_end = str + strlen(str); + str_begin = dsp_om_trim_zero(str); + + if (str_begin == str_end) { + DSP_LOGE("input str all space\n"); + return 0; + } + + *split_str = dsp_om_trim_zero(strchr(str_begin, ' ')); + + return str_begin; +} + +#ifdef GJB_CHANGE +void send_msg_data_to_ap() +{ + + struct hikey_msg_with_content hikey_msg; + DSP_LOGE("%s\n", __func__); + hikey_msg.msg_info.msg_id=HIKEY_AUDIO_DSP_AP_OM_CMD; + hikey_msg.msg_info.msg_len=HIKEY_AP_DSP_MSG_MAX_LEN; + strncpy(hikey_msg.msg_info.msg_content,"pcm_gain",HIKEY_AP_DSP_MSG_MAX_LEN); + dsp_mailbox_write(&hikey_msg); + DSP_LOGE("Exit %s\n", __func__); +} + +void send_pcm_data_to_ap() +{ + struct hikey_ap_dsp_msg_body msg_info; + DSP_LOGE("Enter %s\n", __func__); + msg_info.msg_id = ID_XAF_DSP_TO_AP; + msg_info.msg_len = sizeof(msg_info); + msg_info.xf_dsp_msg.id= 0; + msg_info.xf_dsp_msg.opcode = 0xc; + msg_info.xf_dsp_msg.length = 0x400; + msg_info.xf_dsp_msg.address = 0x8B432000; + dsp_mailbox_write(&msg_info); + DSP_LOGE("Exit %s\n", __func__); +} +#else +void send_msg_data_to_ap() +{ + xf_proxy_message_t hikey_msg; + DSP_LOGE("%s\n", __func__); + hikey_msg.id=HIKEY_AUDIO_DSP_AP_OM_CMD; + hikey_msg.length=HIKEY_AP_DSP_MSG_MAX_LEN; + strncpy(hikey_msg.address,"pcm_gain",HIKEY_AP_DSP_MSG_MAX_LEN); + dsp_mailbox_write(&hikey_msg); + DSP_LOGE("Exit %s\n", __func__); +} + +void send_pcm_data_to_ap() +{ + xf_proxy_message_t msg_info; + DSP_LOGE("Enter %s\n", __func__); + msg_info.id = ID_XAF_DSP_TO_AP; + msg_info.opcode = 0xc; + msg_info.length = 0x400; + msg_info.address = 0x8B432000; + dsp_mailbox_write(&msg_info); + DSP_LOGE("Exit %s\n", __func__); +} +#endif +static void dsp_om_read_mem(char *str) +{ + unsigned int addr = 0; + unsigned int val = 0; + if (!str) { + DSP_LOGE("str is null\n"); + return; + } + + addr = strtoul(str, 0, 16); + DSP_LOGD("str:%s addr:0x%x\n", str, addr); + + val = *(unsigned int*)addr; + send_pcm_data_to_ap(); +//send_msg_data_to_ap(); + dsp_ipc_send_irq_to_ap(); + DSP_LOGI("read addr:0x%x value:0x%x\n", addr, val); + return; +} + +static void dsp_om_write_mem(char *str) +{ + char* str_addr = 0; + char* str_val = 0; + unsigned int addr = 0; + unsigned int val = 0; + if (!str) { + DSP_LOGE("str is null\n"); + return; + } + + str_addr = dsp_om_split_str(str, &str_val); + + if(!str_addr || !str_val) { + DSP_LOGE("str:%s str_addr:%s strValue:%s\n", str, str_addr ? str_addr : "null", str_val ? str_val : "null"); + return; + } + addr = strtoul(str_addr, 0, 16); + val= strtoul(str_val, 0, 16); + DSP_LOGI("str_addr:%s addr:%x str_val:%s val:%x\n", str_addr ? str_addr : "null", addr, str_val ? str_val : "null", val); + + *(unsigned int *)addr = val; + + return; + +} + +static void dsp_om_pcm_gain(char *str) +{ + char* str_addr = 0; + char* str_val = 0; + unsigned int addr = 0; + unsigned int val = 0; + if (!str) { + DSP_LOGE("str is null\n"); + return; + } + str_addr = dsp_om_split_str(str, &str_val); + if(!str_addr || !str_val) { + DSP_LOGE("str:%s str_addr:%s strValue:%s\n", str, str_addr ? str_addr : "null", str_val ? str_val : "null"); + return; + } + addr = strtoul(str_addr, 0, 16); + val= strtoul(str_val, 0, 16); + DSP_LOGI("str_addr:%s addr:%x str_val:%s val:%x\n", str_addr ? str_addr : "null", addr, str_val ? str_val : "null", val); + if(ReadData((char*)InpBuf, val) ){ + processAudio(OutBuf, InpBuf, (val/4)); + if(WriteData((char*)OutBuf, val)) { + MsgFlag = MSG_PROC; // indicate that the msg is processed. + DSP_LOGI("PCM gain processed\n"); + send_msg_data_to_ap(); + dsp_ipc_send_irq_to_ap(); // Indicate data is ready to pickup... Maybe you need to send a msg to AP. + } + else { + DSP_LOGI("PCM gain Write error\n"); + MsgFlag = MSG_INCOMP; + dsp_ipc_send_irq_to_ap();// Report error.. + } + } + else { + DSP_LOGI("PCM gain Read error\n"); + MsgFlag = MSG_INCOMP; + dsp_ipc_send_irq_to_ap(); + } + return; +} +typedef void (*om_proc_func)(char *str); + +struct om_proc_info { + char *om_proc_name; + om_proc_func func; +}; + +struct om_proc_info om_proc_table[] = { + {"read_mem", dsp_om_read_mem}, + {"write_mem", dsp_om_write_mem}, + {"pcm_gain", dsp_om_pcm_gain}, +}; + +om_proc_func dsp_om_get_func_by_name(char *name) +{ + unsigned int i = 0; + unsigned int func_num = sizeof(om_proc_table) / sizeof(om_proc_table[0]); + + if (!name) { + DSP_LOGE("name is null\n"); + return 0; + } + + for (i = 0; i < func_num; i++) + if (!strncmp((char *)om_proc_table[i].om_proc_name, name, strlen((char *)om_proc_table[i].om_proc_name))) + return om_proc_table[i].func; + + return 0; +} + +void dsp_om_func_proc(char *om_str, unsigned int str_len) +{ + char * cmd_name = 0; + char * str_param = 0; + om_proc_func proc_func = 0; + + cmd_name = dsp_om_split_str((char *)om_str, &str_param); + + DSP_LOGI("cmd_name:%s\n", cmd_name); + proc_func = dsp_om_get_func_by_name(cmd_name); + if (proc_func) + proc_func(str_param); + else + DSP_LOGE("do not find func\n"); +} +#endif + diff --git a/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/int_vector.S b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/int_vector.S new file mode 100644 index 00000000..d579a55e --- /dev/null +++ b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/int_vector.S @@ -0,0 +1,830 @@ +/******************************************************************************* +* 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. + +******************************************************************************/ +/****************************************************************************** + int_vector.S +******************************************************************************/ +#include <xtensa/coreasm.h> +#include <xtensa/corebits.h> +#include <xtensa/config/system.h> +#include <xtensa/simcall.h> +#include "arch_hifi330.h" + +// .data + .section .dram0.data, "aw" +/* CP */ + .type g_awVosCoprocSaOffset,@object + .align 16 /* minimize crossing cache boundaries */ +g_awVosCoprocSaOffset: + .word XT_CP0_SA, XT_CP1_SA, XT_CP2_SA, XT_CP3_SA + .word XT_CP4_SA, XT_CP5_SA, XT_CP6_SA, XT_CP7_SA + +/* CP n's CPENABLE bit. */ + .type g_bVosCoprocMask,@object + .align 16,,8 /* try to keep it all in one cache line */ +g_bVosCoprocMask: + .byte 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + +/* Owner of CP (0 = unowned). */ + .global g_awVosCoprocOwnerSa + .type g_awVosCoprocOwnerSa,@object + .align 16,,XCHAL_CP_MAX<<2 /* minimize crossing cache boundaries */ +g_awVosCoprocOwnerSa: + .space XCHAL_CP_MAX << 2,0 + + .global g_strVosPanicMessage + .align 4 +g_strVosPanicMessage: + .string "\npanic at addr 0x%08x.\n" + + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .global OS_Panic + .type OS_Panic,@function + .align 4 +/***************************************************************************** + OS_Panic +*****************************************************************************/ +OS_Panic: + +#ifdef ZOS_SIM + /*panic at addr*/ + addi a4, a0, -3 /* point to call0 */ + movi a3, g_strVosPanicMessage + movi a2, SYS_log_msg + simcall + movi a2, SYS_gdb_abort + simcall +#else + /*low & med*/ + rsil a2, XCHAL_EXCM_LEVEL /* disable all low & med ints */ +1: j 1b /* loop infinitely */ +#endif + + .end literal_prefix + + .begin literal_prefix .DebugExceptionVector + .section .DebugExceptionVector.text, "ax" + .global OS_DebugExceptionVector + .align 4 +/***************************************************************************** +_DebugExceptionVector +*****************************************************************************/ +OS_DebugExceptionVector: +#ifdef ZOS_SIM + wsr a2, EXCSAVE+XCHAL_DEBUGLEVEL + movi a2, SYS_gdb_enter_sktloop + simcall +#else + wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL + call0 OS_Panic + rfi XCHAL_DEBUGLEVEL +#endif + + .end literal_prefix + + + .begin literal_prefix .DoubleExceptionVector + .section .DoubleExceptionVector.text, "ax" + .global OS_DoubleExceptionVector + .align 4 +/***************************************************************************** + OS_DoubleExceptionVector +*****************************************************************************/ +OS_DoubleExceptionVector: + call0 OS_Panic /* does not return */ + rfde /* make a0 point here not later */ + + .end literal_prefix + + + .begin literal_prefix .KernelExceptionVector + .section .KernelExceptionVector.text, "ax" + .global OS_KernelExceptionVector + .align 4 +/***************************************************************************** + _KernelExceptionVector +*****************************************************************************/ +OS_KernelExceptionVector: + call0 OS_Panic /* does not return */ + rfe /* make a0 point here not later */ + + .end literal_prefix + + + .begin literal_prefix .UserExceptionVector + .section .UserExceptionVector.text, "ax" + .global OS_UserExceptionVector + .type OS_UserExceptionVector,@function + .align 4 +/***************************************************************************** + _UserExceptionVector +*****************************************************************************/ +OS_UserExceptionVector: + wsr a0, EXCSAVE_1 /* preserve a0 */ + call0 OS_UserExc /* user exception handler */ + /* never returns here - call0 is used as a jump (see note at top) */ + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + + .align 4 +OS_CoProcessorExc: + s32i a5, sp, XT_STK_A5 /* save a5 */ + addi a5, a0, -EXCCAUSE_CP0_DISABLED /* a0 = CP index */ + bgei a5, XCHAL_CP_MAX, .L_xt_user_exc_not_coproc + call0 OS_CoProcessorException /* in window vectors section */ + /* never returns here - call0 is used as a jump (see note at top) */ + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .align 4 +OS_AllocExc: + call0 OS_AllocaException /* in window vectors section */ + /* never returns here - call0 is used as a jump (see note at top) */ + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .align 4 +OS_SyscallExc: + call0 OS_SyscallException + /* never returns here - call0 is used as a jump (see note at top) */ + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .global OS_UserExc + .type OS_UserExc,@function + .align 4 +OS_UserExc: + rsr a0, EXCCAUSE + beqi a0, EXCCAUSE_ALLOCA, OS_AllocExc + beqi a0, EXCCAUSE_SYSCALL, OS_SyscallExc + + mov a0, sp /* sp == a1 */ + addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ + s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ + rsr a0, PS /* save interruptee's PS */ + s32i a0, sp, XT_STK_PS + rsr a0, EPC_1 /* save interruptee's PC */ + s32i a0, sp, XT_STK_PC + rsr a0, EXCSAVE_1 /* save interruptee's a0 */ + s32i a0, sp, XT_STK_A0 + movi a0, OS_UserExit /* save exit point for dispatch */ + s32i a0, sp, XT_STK_EXIT + + rsr a0, EXCCAUSE + bgeui a0, EXCCAUSE_CP0_DISABLED, OS_CoProcessorExc + +.L_xt_user_exc_not_coproc: + + + call0 XT_RTOS_INT_ENTER + + + movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE + wsr a0, PS + rsync + + rsr a2, EXCCAUSE + beqi a2, EXCCAUSE_LEVEL1INTERRUPT, .L_xt_user_int + mov a6,a2 + mov a7,a1 + /*User exception*/ + call4 OS_UserexecHandler + j .L_xt_user_done + +.L_xt_user_int: + /* level 1 int */ + rsr a2, INTENABLE + rsr a3, INTERRUPT + movi a4, XCHAL_INTLEVEL1_MASK + and a2, a2, a3 + and a2, a2, a4 + beqz a2, .L_int_done1 + + neg a3,a2 + and a3,a3,a2 + wsr a3,INTCLEAR + + find_ls_one a2, a3 + mov a6,a2 + call4 OS_EnterIntHook + + mov a6,a2 + call4 OS_InterruptHandler + + mov a6,a2 + call4 OS_ExitIntHook + j .L_xt_user_int + +.L_int_done1: + + +.L_xt_user_done: + call0 XT_RTOS_INT_EXIT + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .global OS_UserExit + .type OS_UserExit,@function + .align 4 +OS_UserExit: + l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ + wsr a0, PS + l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ + wsr a0, EPC_1 + l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ + l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ + rsync /* ensure PS and EPC written */ + rfe /* PS.EXCM is cleared */ + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .type OS_SyscallException,@function + .align 4 +/***************************************************************************** + OS_SyscallException +*****************************************************************************/ +OS_SyscallException: + addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ + s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ + s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ + call0 OS_ContextSave + + + /* + 2)update PC*/ + rsr a2, EPC_1 + addi a3, a2, 3 + + rsr a0, LEND + bne a3, a0, 1f + rsr a0, LCOUNT + beqz a0, 1f + addi a0, a0, -1 + rsr a3, LBEG + wsr a0, LCOUNT + +1: wsr a3, EPC_1 + + /* Restore context,exception */ + call0 OS_ContextRestore + addi sp, sp, XT_STK_FRMSZ + + movi a0, -1 + movnez a2, a0, a2 /* return -1 if not syscall 0 */ + rsr a0, EXCSAVE_1 + rfe + + + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .type OS_CoProcessorException,@function + .align 4 +/***************************************************************************** + OS_CoProcessorException +*****************************************************************************/ +OS_CoProcessorException: /* a5 = CP index */ + + s32i a2, sp, XT_STK_A2 + s32i a3, sp, XT_STK_A3 + s32i a4, sp, XT_STK_A4 + s32i a15, sp, XT_STK_A15 + + + /* co-processor old owner new owner. */ + call0 XT_RTOS_CP_STATE /* a15 = new owner's save area */ + beqz a15, .L_xt_coproc_invalid /* not in a thread (invalid) */ + + mov a0, a5 /* a0 = CP index */ + movi a3, g_awVosCoprocOwnerSa + addx4 a3, a0, a3 /* a3 = &g_awVosCoprocOwnerSa[CP] */ + l32i a2, a3, 0 /* a2 = old owner's save area */ + + /* Enable the co-processor's bit in CPENABLE. */ + movi a4, g_bVosCoprocMask + rsr a5, CPENABLE /* a5 = CPENABLE */ + add a4, a4, a0 + l8ui a4, a4, 0 /* a4 = bitmask from CP index */ + or a5, a5, a4 /* a5 = CPENABLE + CP */ + wsr a5, CPENABLE + + + beq a15, a2, .L_xt_coproc_done /* new owner == old, we're done */ + + s32i a15, a3, 0 /* g_awVosCoprocOwnerSa[CP] = new */ + + l8ui a5, a15, XT_CPSTORED /* a5 = new owner's old CPSTORED */ + neg a3, a4 + addi a3, a3, -1 /* a3 = ~a4 (bitmask for CP) */ + and a3, a5, a3 /* clr CP in new owner's CPSTORED */ + s8i a3, a15, XT_CPSTORED /* update new owner's CPSTORED */ + + /* Adjust new owner's save area pointers to area for CP n. */ + movi a3, g_awVosCoprocSaOffset + and a5, a5, a4 /* a5 = new owner's CP is stored */ + addx4 a3, a0, a3 /* a3 = &OS_CoprocSaOffset[CP] */ + l32i a3, a3, 0 /* a3 = XT_CP[CP]_SA */ + add a15, a15, a3 /* a15 = new owner's area for CP */ + moveqz a15, a5, a5 /* a15 = 0 if state not stored */ + + rsync /* ensure wsr.CPENABLE is complete */ + beqz a2, .L_xt_coproc_new /* no old owner to save */ + + /* If old owner still needs CP, clear CP in CPENABLE and set in CPSTORED. */ + l8ui a5, a2, XT_CPENABLE /* a5 = old owner's CPENABLE */ + and a4, a5, a4 /* a4 = CP in old owner CPENABLE */ + beqz a4, .L_xt_coproc_new /* discard old owner's CP state */ + + sub a5, a5, a4 /* clr CP in old owner's CPENABLE */ + s8i a5, a2, XT_CPENABLE /* update old owner's CPENABLE */ + l8ui a5, a2, XT_CPSTORED /* a5 = old owner's CPSTORED */ + or a5, a5, a4 /* set CP in old owner's CPSTORED */ + s8i a5, a2, XT_CPSTORED /* update old owner's CPSTORED */ + + /* Save co-processor state of old owner. */ +.Ln_xt_coproc_old: + add a2, a2, a3 /* a2 = old owner's area for CP */ + mov a3, a0 /* a3 = CP index */ + /* + The config-specific HAL macro invoked below destroys a2-5, preserves a0-1. + It is theoretically possible for Xtensa processor designers to write TIE + that causes more address registers to be affected, but it is generally + unlikely. If that ever happens, more registers needs to be saved/restored + around this macro invocation, and the value in a15 needs to be recomputed. + */ + xchal_cpi_store_funcbody + + /* Restore co-processor state of new owner. */ +.L_xt_coproc_new: + beqz a15, .L_xt_coproc_done /* no valid state to restore */ + mov a2, a15 /* a2 = new owner's area for CP */ + mov a3, a0 /* a3 = CP index */ + + xchal_cpi_load_funcbody + + +.L_xt_coproc_done: + l32i a15, sp, XT_STK_A15 + l32i a5, sp, XT_STK_A5 + l32i a4, sp, XT_STK_A4 + l32i a3, sp, XT_STK_A3 + l32i a2, sp, XT_STK_A2 + call0 OS_UserExit + +.L_xt_coproc_invalid: + call0 OS_Panic /* not in a thread (invalid) */ + .end literal_prefix + + .begin literal_prefix .Level2InterruptVector + .section .Level2InterruptVector.text, "ax" + .global OS_Level2Vector + .type OS_Level2Vector,@function + .align 4 +/***************************************************************************** + _Level2Vector +*****************************************************************************/ +OS_Level2Vector: + wsr a0, EXCSAVE_2 /* preserve a0 */ + call0 OS_Medint2 /* load interrupt handler */ + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .extern OS_InterruptHandler + .type OS_Medint2,@function + .align 4 +OS_Medint2: + +#movi a1, 0xdeadbeef + movi a1, 0xe8075000 + movi a2, 0xe8075e30 /*HIFI_RESERVE1_LOCATION*/ + s32i a1, a2, 0 + + mov a0, sp /* sp == a1 */ + addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ + s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ + rsr a0, EPS_2 /* save interruptee's PS */ + s32i a0, sp, XT_STK_PS + rsr a0, EPC_2 /* save interruptee's PC */ + s32i a0, sp, XT_STK_PC + rsr a0, EXCSAVE_2 /* save interruptee's a0 */ + s32i a0, sp, XT_STK_A0 + movi a0, OS_Medint2Exit /* save exit point for dispatch */ + s32i a0, sp, XT_STK_EXIT + + call0 XT_RTOS_INT_ENTER + + movi a0, PS_INTLEVEL(2) | PS_UM | PS_WOE + wsr a0, PS + rsync + + +.L_ProcAllInt2: + rsr a2, INTENABLE + rsr a3, INTERRUPT + movi a4, XCHAL_INTLEVEL2_MASK + and a2, a2, a3 + and a2, a2, a4 + beqz a2, .L_int_done2 + + neg a3,a2 + and a3,a3,a2 + wsr a3,INTCLEAR + + find_ls_one a2, a3 + mov a6,a2 + call4 OS_EnterIntHook + + mov a6,a2 + call4 OS_InterruptHandler + + mov a6,a2 + call4 OS_ExitIntHook + j .L_ProcAllInt2 + +.L_int_done2: + call0 XT_RTOS_INT_EXIT + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .global OS_Medint2Exit + .type OS_Medint2Exit,@function + .align 4 +OS_Medint2Exit: + /* Restore only level-specific regs (the rest were already restored) */ + l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ + wsr a0, EPS_2 + l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ + wsr a0, EPC_2 + l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ + l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ + rsync /* ensure EPS and EPC written */ + rfi 2 + .end literal_prefix + + + .begin literal_prefix .Level3InterruptVector + .section .Level3InterruptVector.text, "ax" + .global OS_Level3Vector + .type OS_Level3Vector,@function + .align 4 +/***************************************************************************** + _Level3Vector +*****************************************************************************/ +OS_Level3Vector: + wsr a0, EXCSAVE_3 /* preserve a0 */ + call0 OS_MedInt3 /* load interrupt handler */ + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .extern OS_InterruptHandler + .type OS_MedInt3,@function + .align 4 +OS_MedInt3: + + mov a0, sp /* sp == a1 */ + addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ + s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ + rsr a0, EPS_3 /* save interruptee's PS */ + s32i a0, sp, XT_STK_PS + rsr a0, EPC_3 /* save interruptee's PC */ + s32i a0, sp, XT_STK_PC + rsr a0, EXCSAVE_3 /* save interruptee's a0 */ + s32i a0, sp, XT_STK_A0 + movi a0, OS_Medint3Exit /* save exit point for dispatch */ + s32i a0, sp, XT_STK_EXIT + + call0 XT_RTOS_INT_ENTER + + movi a0, PS_INTLEVEL(3) | PS_UM | PS_WOE + wsr a0, PS + rsync + + +.L_ProcAllInt3: + rsr a2, INTENABLE + rsr a3, INTERRUPT + movi a4, XCHAL_INTLEVEL3_MASK + and a2, a2, a3 + and a2, a2, a4 + beqz a2, .L_int_done3 + + neg a3,a2 + and a3,a3,a2 + wsr a3,INTCLEAR + + find_ls_one a2, a3 + mov a6,a2 + call4 OS_EnterIntHook + + mov a6,a2 + call4 OS_InterruptHandler + + mov a6,a2 + call4 OS_ExitIntHook + j .L_ProcAllInt3 + +.L_int_done3: + + call0 XT_RTOS_INT_EXIT + + .end literal_prefix + + .begin literal_prefix .iram0 + .section .iram0.text, "ax" + .global OS_Medint3Exit + .type OS_Medint3Exit,@function + .align 4 +OS_Medint3Exit: + /* Restore only level-specific regs (the rest were already restored) */ + l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ + wsr a0, EPS_3 + l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ + wsr a0, EPC_3 + l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ + l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ + rsync /* ensure EPS and EPC written */ + rfi 3 + .end literal_prefix + + + .begin literal_prefix .NMIExceptionVector + .section .NMIExceptionVector.text, "ax" + .global OS_NMIExceptionVector + .align 8 +/***************************************************************************** + OS_NMIExceptionVector +*****************************************************************************/ +OS_NMIExceptionVector: + /*wsr a3, 213 + wsr a4, 214*/ + + /*movi a3, 0x0 + movi a4, 0xf711a510 + s32i a3, a4, 0*/ + + /*rsr a3, 213 + rsr a4, 214*/ + + movi a0, PS_INTLEVEL(3) | PS_UM | PS_WOE + wsr a0, PS + rsync + rsr a2, EXCCAUSE + mov a6,a2 + mov a7,a1 + call4 OS_NmiHook + + rfi XCHAL_NMILEVEL + + .end literal_prefix + + .section .WindowVectors.text, "ax" + +/* +-------------------------------------------------------------------------------- +Window Overflow Exception for Call4. + +Invoked if a call[i] referenced a register (a4-a15) +that contains data from ancestor call[j]; +call[j] had done a call4 to call[j+1]. +On entry here: + window rotated to call[j] start point; + a0-a3 are registers to be saved; + a4-a15 must be preserved; + a5 is call[j+1]'s stack pointer. +-------------------------------------------------------------------------------- +*/ + + .org 0x0 + .global _WindowOverflow4 +_WindowOverflow4: + + s32e a0, a5, -16 /* save a0 to call[j+1]'s stack frame */ + s32e a1, a5, -12 /* save a1 to call[j+1]'s stack frame */ + s32e a2, a5, -8 /* save a2 to call[j+1]'s stack frame */ + s32e a3, a5, -4 /* save a3 to call[j+1]'s stack frame */ + rfwo /* rotates back to call[i] position */ + +/* +-------------------------------------------------------------------------------- +Window Underflow Exception for Call4 + +Invoked by RETW returning from call[i+1] to call[i] +where call[i]'s registers must be reloaded (not live in ARs); +where call[i] had done a call4 to call[i+1]. +On entry here: + window rotated to call[i] start point; + a0-a3 are undefined, must be reloaded with call[i].reg[0..3]; + a4-a15 must be preserved (they are call[i+1].reg[0..11]); + a5 is call[i+1]'s stack pointer. +-------------------------------------------------------------------------------- +*/ + + .org 0x40 + .global _WindowUnderflow4 +_WindowUnderflow4: + + l32e a0, a5, -16 /* restore a0 from call[i+1]'s stack frame */ + l32e a1, a5, -12 /* restore a1 from call[i+1]'s stack frame */ + l32e a2, a5, -8 /* restore a2 from call[i+1]'s stack frame */ + l32e a3, a5, -4 /* restore a3 from call[i+1]'s stack frame */ + rfwu + + .global OS_AllocaException + .align 4 +/***************************************************************************** + OS_AllocaException +*****************************************************************************/ +OS_AllocaException: + + rsr a0, WINDOWBASE /* grab WINDOWBASE before rotw changes it */ + rotw -1 /* WINDOWBASE goes to a4, new a0-a3 are scratch */ + rsr a2, PS + extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS + xor a3, a3, a4 /* bits changed from old to current windowbase */ + rsr a4, EXCSAVE_1 /* restore original a0 (now in a4) */ + slli a3, a3, XCHAL_PS_OWB_SHIFT + xor a2, a2, a3 /* flip changed bits in old window base */ + wsr a2, PS /* update PS.OWB to new window base */ + rsync + + _bbci.l a4, 31, _WindowUnderflow4 + rotw -1 /* original a0 goes to a8 */ + _bbci.l a8, 30, _WindowUnderflow8 + rotw -1 + j _WindowUnderflow12 + + + +/* +-------------------------------------------------------------------------------- +Window Overflow Exception for Call8 + +Invoked if a call[i] referenced a register (a4-a15) +that contains data from ancestor call[j]; +call[j] had done a call8 to call[j+1]. +On entry here: + window rotated to call[j] start point; + a0-a7 are registers to be saved; + a8-a15 must be preserved; + a9 is call[j+1]'s stack pointer. +-------------------------------------------------------------------------------- +*/ + + .org 0x80 + .global _WindowOverflow8 +_WindowOverflow8: + + s32e a0, a9, -16 /* save a0 to call[j+1]'s stack frame */ + l32e a0, a1, -12 /* a0 <- call[j-1]'s sp + (used to find end of call[j]'s frame) */ + s32e a1, a9, -12 /* save a1 to call[j+1]'s stack frame */ + s32e a2, a9, -8 /* save a2 to call[j+1]'s stack frame */ + s32e a3, a9, -4 /* save a3 to call[j+1]'s stack frame */ + s32e a4, a0, -32 /* save a4 to call[j]'s stack frame */ + s32e a5, a0, -28 /* save a5 to call[j]'s stack frame */ + s32e a6, a0, -24 /* save a6 to call[j]'s stack frame */ + s32e a7, a0, -20 /* save a7 to call[j]'s stack frame */ + rfwo /* rotates back to call[i] position */ + +/* +-------------------------------------------------------------------------------- +Window Underflow Exception for Call8 + +Invoked by RETW returning from call[i+1] to call[i] +where call[i]'s registers must be reloaded (not live in ARs); +where call[i] had done a call8 to call[i+1]. +On entry here: + window rotated to call[i] start point; + a0-a7 are undefined, must be reloaded with call[i].reg[0..7]; + a8-a15 must be preserved (they are call[i+1].reg[0..7]); + a9 is call[i+1]'s stack pointer. +-------------------------------------------------------------------------------- +*/ + + .org 0xC0 + .global _WindowUnderflow8 +_WindowUnderflow8: + + l32e a0, a9, -16 /* restore a0 from call[i+1]'s stack frame */ + l32e a1, a9, -12 /* restore a1 from call[i+1]'s stack frame */ + l32e a2, a9, -8 /* restore a2 from call[i+1]'s stack frame */ + l32e a7, a1, -12 /* a7 <- call[i-1]'s sp + (used to find end of call[i]'s frame) */ + l32e a3, a9, -4 /* restore a3 from call[i+1]'s stack frame */ + l32e a4, a7, -32 /* restore a4 from call[i]'s stack frame */ + l32e a5, a7, -28 /* restore a5 from call[i]'s stack frame */ + l32e a6, a7, -24 /* restore a6 from call[i]'s stack frame */ + l32e a7, a7, -20 /* restore a7 from call[i]'s stack frame */ + rfwu + +/* +-------------------------------------------------------------------------------- +Window Overflow Exception for Call12 + +Invoked if a call[i] referenced a register (a4-a15) +that contains data from ancestor call[j]; +call[j] had done a call12 to call[j+1]. +On entry here: + window rotated to call[j] start point; + a0-a11 are registers to be saved; + a12-a15 must be preserved; + a13 is call[j+1]'s stack pointer. +-------------------------------------------------------------------------------- +*/ + + .org 0x100 + .global _WindowOverflow12 +_WindowOverflow12: + + s32e a0, a13, -16 /* save a0 to call[j+1]'s stack frame */ + l32e a0, a1, -12 /* a0 <- call[j-1]'s sp + (used to find end of call[j]'s frame) */ + s32e a1, a13, -12 /* save a1 to call[j+1]'s stack frame */ + s32e a2, a13, -8 /* save a2 to call[j+1]'s stack frame */ + s32e a3, a13, -4 /* save a3 to call[j+1]'s stack frame */ + s32e a4, a0, -48 /* save a4 to end of call[j]'s stack frame */ + s32e a5, a0, -44 /* save a5 to end of call[j]'s stack frame */ + s32e a6, a0, -40 /* save a6 to end of call[j]'s stack frame */ + s32e a7, a0, -36 /* save a7 to end of call[j]'s stack frame */ + s32e a8, a0, -32 /* save a8 to end of call[j]'s stack frame */ + s32e a9, a0, -28 /* save a9 to end of call[j]'s stack frame */ + s32e a10, a0, -24 /* save a10 to end of call[j]'s stack frame */ + s32e a11, a0, -20 /* save a11 to end of call[j]'s stack frame */ + rfwo /* rotates back to call[i] position */ + +/* +-------------------------------------------------------------------------------- +Window Underflow Exception for Call12 + +Invoked by RETW returning from call[i+1] to call[i] +where call[i]'s registers must be reloaded (not live in ARs); +where call[i] had done a call12 to call[i+1]. +On entry here: + window rotated to call[i] start point; + a0-a11 are undefined, must be reloaded with call[i].reg[0..11]; + a12-a15 must be preserved (they are call[i+1].reg[0..3]); + a13 is call[i+1]'s stack pointer. +-------------------------------------------------------------------------------- +*/ + + .org 0x140 + .global _WindowUnderflow12 +_WindowUnderflow12: + + l32e a0, a13, -16 /* restore a0 from call[i+1]'s stack frame */ + l32e a1, a13, -12 /* restore a1 from call[i+1]'s stack frame */ + l32e a2, a13, -8 /* restore a2 from call[i+1]'s stack frame */ + l32e a11, a1, -12 /* a11 <- call[i-1]'s sp + (used to find end of call[i]'s frame) */ + l32e a3, a13, -4 /* restore a3 from call[i+1]'s stack frame */ + l32e a4, a11, -48 /* restore a4 from end of call[i]'s stack frame */ + l32e a5, a11, -44 /* restore a5 from end of call[i]'s stack frame */ + l32e a6, a11, -40 /* restore a6 from end of call[i]'s stack frame */ + l32e a7, a11, -36 /* restore a7 from end of call[i]'s stack frame */ + l32e a8, a11, -32 /* restore a8 from end of call[i]'s stack frame */ + l32e a9, a11, -28 /* restore a9 from end of call[i]'s stack frame */ + l32e a10, a11, -24 /* restore a10 from end of call[i]'s stack frame */ + l32e a11, a11, -20 /* restore a11 from end of call[i]'s stack frame */ + rfwu + + + diff --git a/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/reset.S b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/reset.S new file mode 100644 index 00000000..b2cb2688 --- /dev/null +++ b/hifi/xaf/hifi-dpf/ipc/xt-shmem/hikey/reset.S @@ -0,0 +1,460 @@ +/******************************************************************************* +* 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. + +******************************************************************************/ +/****************************************************************************** + reset.S + reset vector for BALONGV7R1 architechure,Any problem pls refer + to the Xtensa Microprocessor Programmer's Guide. +******************************************************************************/ + +#include <xtensa/coreasm.h> +#include <xtensa/simcall.h> +#include "reset.h" + + .begin literal_prefix .ResetVector + .section .ResetVector.text, "ax" + .global _ResetVector + .align 4 + +_ResetVector: + j _Reset + + .end literal_prefix + + /***************************************************************************** + Reset + *****************************************************************************/ + .begin literal_prefix .Reset + .section .Reset.text, "ax" + .global _Reset + .align 4 + +_Reset: + /* clear all of interrupts*/ + movi a0, 0 + wsr a0, INTENABLE + + wsr a0, IBREAKA_0 + wsr a0, IBREAKA_1 + wsr a0, DBREAKA_0 + wsr a0, DBREAKA_1 + wsr a0, DBREAKC_0 + wsr a0, DBREAKC_1 + wsr a0, IBREAKENABLE + + /* ICOUNT,ICOUNTLEVEL,ICOUNTexception clear ICOUNT and ICOUNTLEVEL*/ + wsr a0, ICOUNT + wsr a0, ICOUNTLEVEL + isync + + /*debug disable XCHAL_DEBUGLEVEL*/ + rsil a1, XCHAL_DEBUGLEVEL - 1 + +// write windowbase and windowstart, then do rsync. +// reload a0 with 0, because registers may have moved after +// writing windowbase/windowstart. + wsr a0, CCOUNT + /* init register windows*/ + wsr a0, WINDOWBASE + rsync + movi a1, 1 + wsr a1, WINDOWSTART + + ssai 0 + + /*Level-1 init EXCSAVE_1 level-1 interrupt*/ + wsr a0, EXCSAVE_1 + wsr a0, EPC_1 + wsr a0, EXCCAUSE + + /*Level-2 init EXCSAVE_1 level-2 interrupt*/ + wsr a0, EPC_2 + wsr a0, EPS_2 + wsr a0, EXCSAVE_2 + + /*Level-3 init EXCSAVE_1 level-3 interrupt*/ + wsr a0, EPC_3 + wsr a0, EPS_3 + wsr a0, EXCSAVE_3 + + /*Level-4 init EXCSAVE_1 level-4 interrupt*/ + wsr a0, EPC_4 + wsr a0, EPS_4 + wsr a0, EXCSAVE_4 + + /*Level-5(DEBUG) init EXCSAVE_1 level-5 interrupt*/ + wsr a0, EPC_5 + wsr a0, EPS_5 + wsr a0, EXCSAVE_5 + + /*NMI init EXCSAVE_1 level-6(NMI) interrupt */ + wsr a0, EPC_6 + wsr a0, EPS_6 + wsr a0, EXCSAVE_6 + + + /*0/1/2 init timer 0&1 */ + wsr a0, CCOMPARE_0 + wsr a0, CCOMPARE_1 + //wsr a0, CCOMPARE_2 //hifi3 CCOMPARE_0 CCOMPARE_1 + + /* clear all of */ + movi a2, XCHAL_INTTYPE_MASK_EXTERN_EDGE | XCHAL_INTTYPE_MASK_SOFTWARE + wsr a2, INTCLEAR + + wsr a0, BR + + /* disable coprocessor */ + /*wsr a0, CPENABLE*/ + + movi a2, XCHAL_DEBUGLEVEL - 1 + wsr a2, PS + rsync + + + /*icache init icache */ +#if (XCHAL_ICACHE_SIZE != 0) + #if (XCHAL_ICACHE_SIZE == 8192) //212GP and 330HiFi + movi a2, 64 + #elif (XCHAL_ICACHE_SIZE == 16384) //232L and 570T + movi a2, 128 + #elif (XCHAL_ICACHE_SIZE == 32768) //BALONGV7R1 + movi a2, 256 + #elif (XCHAL_ICACHE_SIZE == 65536) //CHICAGO HIFI + movi a2, 256 + #endif + + /*icache unlock icache */ + #if (XCHAL_ICACHE_LINESIZE == 128) + movi a3, 0 + loop a2, .L0 + iiu a3, 0 + iiu a3, XCHAL_ICACHE_LINESIZE + addi a3, a3, XCHAL_ICACHE_LINESIZE*2 + + iiu a3, 0 + iiu a3, XCHAL_ICACHE_LINESIZE + addi a3, a3, XCHAL_ICACHE_LINESIZE*2 +.L0: + + #else + movi a3, 0 + loop a2, .L0 + iiu a3, 0 + iiu a3, XCHAL_ICACHE_LINESIZE + iiu a3, XCHAL_ICACHE_LINESIZE*2 + iiu a3, XCHAL_ICACHE_LINESIZE*3 + addi a3, a3, XCHAL_ICACHE_LINESIZE*4 +.L0: + #endif + + + #if (XCHAL_ICACHE_SIZE == 8192) //212GP and 330HiFi + movi a2, 64 + #elif (XCHAL_ICACHE_SIZE == 16384) //232L and 570T + movi a2, 128 + #elif (XCHAL_ICACHE_SIZE == 32768) //BALONGV7R1 + movi a2, 256 + #elif (XCHAL_ICACHE_SIZE == 65536) //CHICAGO HIFI + movi a2, 256 + #endif + + /*icache disable icache */ + movi a3, 0 + loop a2, .L1 + iii a3, 0 + iii a3, XCHAL_ICACHE_LINESIZE + iii a3, XCHAL_ICACHE_LINESIZE*2 + iii a3, XCHAL_ICACHE_LINESIZE*3 + addi a3, a3, XCHAL_ICACHE_LINESIZE*4 +.L1: + isync +#endif + + + + + /*dcache init dcache */ +#if (XCHAL_DCACHE_SIZE != 0) + #if (XCHAL_DCACHE_SIZE == 8192) //212GP and 330HiFi + movi a2, 64 + #elif (XCHAL_DCACHE_SIZE == 16384) //232L and 570T + movi a2, 128 + #elif (XCHAL_DCACHE_SIZE == 32768) //BALONGV7R1 + movi a2, 256 + #elif (XCHAL_DCACHE_SIZE == 65536) //CHICAGO HIFI + movi a2, 256 + #endif + + /*dcache unlock dcache */ + #if (XCHAL_DCACHE_LINESIZE == 128) + movi a3, 0 + loop a2, .L2 + diu a3, 0 + diu a3, XCHAL_DCACHE_LINESIZE + addi a3, a3, XCHAL_DCACHE_LINESIZE*2 + + diu a3, 0 + diu a3, XCHAL_DCACHE_LINESIZE + addi a3, a3, XCHAL_DCACHE_LINESIZE*2 +.L2: + + #else + movi a3, 0 + loop a2, .L2 + diu a3, 0 + diu a3, XCHAL_DCACHE_LINESIZE + diu a3, XCHAL_DCACHE_LINESIZE*2 + diu a3, XCHAL_DCACHE_LINESIZE*3 + addi a3, a3, XCHAL_DCACHE_LINESIZE*4 +.L2: + #endif + #if (XCHAL_DCACHE_SIZE == 8192) //212GP and 330HiFi + movi a2, 64 + #elif (XCHAL_DCACHE_SIZE == 16384) //232L and 570T + movi a2, 128 + #elif (XCHAL_DCACHE_SIZE == 32768) //BALONGV7R1 + movi a2, 256 + #elif (XCHAL_DCACHE_SIZE == 65536) //CHICAGO HIFI + movi a2, 256 + #endif + + + /*dcache disable dcache */ + movi a3, 0 + loop a2, .L3 + dii a3, 0 + dii a3, XCHAL_DCACHE_LINESIZE + dii a3, XCHAL_DCACHE_LINESIZE*2 + dii a3, XCHAL_DCACHE_LINESIZE*3 + addi a3, a3, XCHAL_DCACHE_LINESIZE*4 +.L3: + dsync +#endif + + /* + 0x00000000-0x1fffffff : caches off(bypass) + 0x20000000-0x3fffffff : caches off(bypass) + 0x40000000-0x5fffffff : caches off(bypass) + 0x60000000-0x7fffffff : caches off(bypass) + 0x80000000-0x9fffffff : caches off(bypass) + 0xa0000000-0xbfffffff : caches off(bypass) + 0xc0000000-0xdfffffff : caches on,0x00000000-0x1fffffff + 0xe0000000-0xffffffff : caches off(bypass),:0xe0000000~0xefffffff 0x20000000~0x2fffffff + */ + /* config the memory access right */ + movi a3, 0x00000000 /*0x00000000-0x1fffffff*/ + set_access_mode PIF_BYPASS /*can not access*/ + + movi a3, 0x20000000 /*0x20000000-0x3fffffff*/ + set_access_mode PIF_BYPASS + + movi a3, 0x40000000 /*0x40000000-0x5fffffff*/ +#if (XCHAL_DCACHE_LINESIZE == 128) + set_access_mode PIF_BYPASS +#else + set_access_mode PIF_BYPASS +#endif + + movi a3, 0x60000000 /*0x60000000-0x7fffffff*/ + set_access_mode PIF_BYPASS + + movi a3, 0x80000000 /*0x80000000-0x9fffffff*/ + #if (XCHAL_DCACHE_LINESIZE == 128) + set_access_mode PIF_BYPASS + #else + set_access_mode PIF_BYPASS + #endif + + movi a3, 0xa0000000 /*0xa0000000-0xbfffffff*/ + set_access_mode PIF_BYPASS + + movi a3, 0xc0000000 /*0xc0000000-0xdfffffff*/ + set_access_mode PIF_CACHED_WBA /*PIF_CACHED*/ + + movi a3, 0xe0000000 /*0xe0000000-0xffffffff*/ + set_access_mode PIF_BYPASS + + /* 0x40000000 0xe0000000, 0x50000000 0xf0000000,*/ + /*movi a2, 0x40000000 //vpn + movi a3, 0xe0000000 //ppn + movi a5, 0xE0000000 // tlb mask, upper 3 bits + and a4, a3, a5 // upper 3 bits of PPN area + and a7, a2, a5 // upper 3 bits of VPN area + + ritlb1 a5, a7 // get current PPN+AM of segment for I + rdtlb1 a6, a7 // get current PPN+AM of segment for D + extui a5, a5, 0, 4 // keep only AM for I + extui a6, a6, 0, 4 // keep only AM for D + add a2, a4, a5 // combine new PPN with orig AM for I + add a3, a4, a6 // combine new PPN with orig AM for D + witlb a2, a7 // write new tlb mapping for I + wdtlb a3, a7 // write new tlb mapping for D + */ + isync + dsync + + /* + prepare the environment of run C code + */ + movi sp, __stack + + movi a2, PS_WOE_MASK | PS_PROGSTACK_MASK + wsr a2, PS + rsync + + movi a8, _bss_start + movi a10, _bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone: + + movi a8, _ulpp_bss_start + movi a10, _ulpp_bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone1 + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone1: + +#ifdef HIFI_DTS_V3 + movi a8, _dtsv3_bss_start + movi a10, _dtsv3_bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone2 + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone2: +#endif + +#ifdef HIFI_DTS_V4 + movi a8, _dtsv4_bss_start + movi a10, _dtsv4_bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone3 + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone3: +#endif + +#ifdef HIFI_VLP + movi a8, _efr_fr_hr_vlpd_bss_start + movi a10, _efr_fr_hr_vlpd_bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone4 + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone4: + + movi a8, _amr_vlpd_bss_start + movi a10, _amr_vlpd_bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone5 + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone5: + + movi a8, _vlpd_bss_start + movi a10, _vlpd_bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone6 + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone6: + + movi a8, _amrwb_vlpd_bss_start + movi a10, _amrwb_vlpd_bss_end + sub a11, a10, a8 + srli a11, a11, 2 + + movi a9, 0 + loopnez a11, zerodone7 + s32i a9, a8, 0 + addi a8, a8, 4 +zerodone7: +#endif + +callmain: + +// Do NOT modify a1 here, it is the stack pointer. +// Use another register instead (a3?) +// Not sure why the NOPs are present. +#movi a1, 0xdeadbeef + movi a1, 0xe8073000 + movi a2, 0xe8075e10 /*HIFI_RESERVE1_LOCATION*/ + s32i a1, a2, 0 + + movi a0, 0 + movi a6, 0 /* clear argc*/ + movi a7, 0 /* clear argv*/ + movi a8, 0 /* clear envp*/ + movi a4, main + nop + nop + callx4 a4 + +reset_exit: + movi a2, SYS_exit +// Where does it go from here ? execution will fall through into +// whatever happens to follow. Either halt here or jump to some +// specific code. + + .end literal_prefix + +#ifdef VOS_VENUS_TEST_STUB + .text + .global sim_call + .type sim_call,@function + .align 4 +sim_call: + entry sp, 64 + addi a4, a3,-3 + movi a3, g_auwVosTestMessageBuf + movi a2, SYS_log_msg + simcall + retw + +#endif + + |