blob: 108986228584696b4c6a235fecd0760f8b4c2ca7 [file] [log] [blame]
/*
* state_asm.S - assembly language processor management routines
*/
/*
* Copyright (c) 2005-2010 Tensilica Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, 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 <xtensa/coreasm.h>
.text
//----------------------------------------------------------------------
// save the extra processor state.
//----------------------------------------------------------------------
#if defined(__SPLIT__save_extra) ||\
defined(__SPLIT__save_extra_nw)
// void xthal_save_extra(void *base)
DECLFUNC(xthal_save_extra)
abi_entry
xchal_extra_store_funcbody
abi_return
endfunc
//----------------------------------------------------------------------
// restore the extra processor state.
//----------------------------------------------------------------------
#elif defined(__SPLIT__restore_extra) ||\
defined(__SPLIT__restore_extra_nw)
// void xthal_restore_extra(void *base)
DECLFUNC(xthal_restore_extra)
abi_entry
xchal_extra_load_funcbody
abi_return
endfunc
//----------------------------------------------------------------------
// save the TIE COPROCESSORS state
//----------------------------------------------------------------------
#elif defined(__SPLIT__save_cpregs) ||\
defined(__SPLIT__save_cpregs_nw)
// void xthal_save_cpregs(void *base, int)
DECLFUNC(xthal_save_cpregs)
abi_entry
xchal_cpi_store_funcbody
abi_return
endfunc
#elif defined(__SPLIT__save_cp0) ||\
defined(__SPLIT__save_cp0_nw)
// void xthal_save_cp0(void *base)
DECLFUNC(xthal_save_cp0)
abi_entry
xchal_cp0_store_a2
abi_return
endfunc
#elif defined(__SPLIT__save_cp1) ||\
defined(__SPLIT__save_cp1_nw)
// void xthal_save_cp1(void *base)
DECLFUNC(xthal_save_cp1)
abi_entry
xchal_cp1_store_a2
abi_return
endfunc
#elif defined(__SPLIT__save_cp2) ||\
defined(__SPLIT__save_cp2_nw)
// void xthal_save_cp2(void *base)
DECLFUNC(xthal_save_cp2)
abi_entry
xchal_cp2_store_a2
abi_return
endfunc
#elif defined(__SPLIT__save_cp3) ||\
defined(__SPLIT__save_cp3_nw)
// void xthal_save_cp3(void *base)
DECLFUNC(xthal_save_cp3)
abi_entry
xchal_cp3_store_a2
abi_return
endfunc
#elif defined(__SPLIT__save_cp4) ||\
defined(__SPLIT__save_cp4_nw)
// void xthal_save_cp4(void *base)
DECLFUNC(xthal_save_cp4)
abi_entry
xchal_cp4_store_a2
abi_return
endfunc
#elif defined(__SPLIT__save_cp5) ||\
defined(__SPLIT__save_cp5_nw)
// void xthal_save_cp5(void *base)
DECLFUNC(xthal_save_cp5)
abi_entry
xchal_cp5_store_a2
abi_return
endfunc
#elif defined(__SPLIT__save_cp6) || \
defined(__SPLIT__save_cp6_nw)
// void xthal_save_cp6(void *base)
DECLFUNC(xthal_save_cp6)
abi_entry
xchal_cp6_store_a2
abi_return
endfunc
#elif defined(__SPLIT__save_cp7) ||\
defined(__SPLIT__save_cp7_nw)
// void xthal_save_cp7(void *base)
DECLFUNC(xthal_save_cp7)
abi_entry
xchal_cp7_store_a2
abi_return
endfunc
//----------------------------------------------------------------------
// restore the TIE coprocessor state
//----------------------------------------------------------------------
#elif defined(__SPLIT__restore_cpregs) ||\
defined(__SPLIT__restore_cpregs_nw)
// void xthal_restore_cpregs(void *base, int)
DECLFUNC(xthal_restore_cpregs)
abi_entry
xchal_cpi_load_funcbody
abi_return
endfunc
#elif defined(__SPLIT__restore_cp0) ||\
defined(__SPLIT__restore_cp0_nw)
// void xthal_restore_cp0(void *base)
DECLFUNC(xthal_restore_cp0)
abi_entry
xchal_cp0_load_a2
abi_return
endfunc
#elif defined(__SPLIT__restore_cp1) ||\
defined(__SPLIT__restore_cp1_nw)
// void xthal_restore_cp1(void *base)
DECLFUNC(xthal_restore_cp1)
abi_entry
xchal_cp1_load_a2
abi_return
endfunc
#elif defined(__SPLIT__restore_cp2) ||\
defined(__SPLIT__restore_cp2_nw)
// void xthal_restore_cp2(void *base)
DECLFUNC(xthal_restore_cp2)
abi_entry
xchal_cp2_load_a2
abi_return
endfunc
#elif defined(__SPLIT__restore_cp3) || \
defined(__SPLIT__restore_cp3_nw)
// void xthal_restore_cp3(void *base)
DECLFUNC(xthal_restore_cp3)
abi_entry
xchal_cp3_load_a2
abi_return
endfunc
#elif defined(__SPLIT__restore_cp4) || \
defined(__SPLIT__restore_cp4_nw)
// void xthal_restore_cp4(void *base)
DECLFUNC(xthal_restore_cp4)
abi_entry
xchal_cp4_load_a2
abi_return
endfunc
#elif defined(__SPLIT__restore_cp5) || \
defined(__SPLIT__restore_cp5_nw)
// void xthal_restore_cp5(void *base)
DECLFUNC(xthal_restore_cp5)
abi_entry
xchal_cp5_load_a2
abi_return
endfunc
#elif defined(__SPLIT__restore_cp6) || \
defined(__SPLIT__restore_cp6_nw)
// void xthal_restore_cp6(void *base)
DECLFUNC(xthal_restore_cp6)
abi_entry
xchal_cp6_load_a2
abi_return
endfunc
#elif defined(__SPLIT__restore_cp7) || \
defined(__SPLIT__restore_cp7_nw)
// void xthal_restore_cp7(void *base)
DECLFUNC(xthal_restore_cp7)
abi_entry
xchal_cp7_load_a2
abi_return
endfunc
#elif defined(__SPLIT__cpregs_save_fn)
.section .rodata, "a"
_SYM(Xthal_cpregs_save_fn)
# ifdef __XTENSA_CALL0_ABI__
_SYM(Xthal_cpregs_save_nw_fn)
# endif
.long xthal_save_cp0
.long xthal_save_cp1
.long xthal_save_cp2
.long xthal_save_cp3
.long xthal_save_cp4
.long xthal_save_cp5
.long xthal_save_cp6
.long xthal_save_cp7
endfunc
.text
#elif defined(__SPLIT__cpregs_save_nw_fn)
# ifndef __XTENSA_CALL0_ABI__
.section .rodata, "a"
_SYM(Xthal_cpregs_save_nw_fn)
.long xthal_save_cp0_nw
.long xthal_save_cp1_nw
.long xthal_save_cp2_nw
.long xthal_save_cp3_nw
.long xthal_save_cp4_nw
.long xthal_save_cp5_nw
.long xthal_save_cp6_nw
.long xthal_save_cp7_nw
endfunc
.text
# endif
#elif defined(__SPLIT__cpregs_restore_fn)
.section .rodata, "a"
_SYM(Xthal_cpregs_restore_fn)
# ifdef __XTENSA_CALL0_ABI__
_SYM(Xthal_cpregs_restore_nw_fn)
# endif
.long xthal_restore_cp0
.long xthal_restore_cp1
.long xthal_restore_cp2
.long xthal_restore_cp3
.long xthal_restore_cp4
.long xthal_restore_cp5
.long xthal_restore_cp6
.long xthal_restore_cp7
endfunc
.text
#elif defined(__SPLIT__cpregs_restore_nw_fn)
# ifndef __XTENSA_CALL0_ABI__
.section .rodata, "a"
_SYM(Xthal_cpregs_restore_nw_fn)
.long xthal_restore_cp0_nw
.long xthal_restore_cp1_nw
.long xthal_restore_cp2_nw
.long xthal_restore_cp3_nw
.long xthal_restore_cp4_nw
.long xthal_restore_cp5_nw
.long xthal_restore_cp6_nw
.long xthal_restore_cp7_nw
endfunc
.text
# endif
//----------------------------------------------------------------------
// coprocessor enable/disable
//----------------------------------------------------------------------
#elif defined(__SPLIT__validate_cp) ||\
defined(__SPLIT__validate_cp_nw)
// validate the register file.
// void xthal_validate_cp(int)
DECLFUNC(xthal_validate_cp)
abi_entry
#if XCHAL_HAVE_CP
rsr.cpenable a3
movi a4, 1
ssl a2
sll a4, a4
or a3, a3, a4
wsr.cpenable a3
#endif
abi_return
endfunc
#elif defined(__SPLIT__invalidate_cp) || \
defined(__SPLIT__invalidate_cp_nw)
// invalidate the register file.
// void xthal_invalidate_cp(int)
DECLFUNC(xthal_invalidate_cp)
abi_entry
#if XCHAL_HAVE_CP
rsr.cpenable a3
movi a4, 1
ssl a2
sll a4, a4
and a4, a3, a4
xor a3, a3, a4
wsr.cpenable a3
#endif
abi_return
endfunc
//----------------------------------------------------------------------
// Access the CPENABLE register
//----------------------------------------------------------------------
#elif defined(__SPLIT__get_cpenable) || \
defined(__SPLIT__get_cpenable_nw)
// unsigned xthal_get_cpenable(void);
DECLFUNC(xthal_get_cpenable)
abi_entry
#if XCHAL_HAVE_CP
rsr.cpenable a2
#else
movi a2, 0 // if no CPENABLE (no coprocessors), none is ever enabled
#endif
abi_return
endfunc
#elif defined(__SPLIT__set_cpenable) ||\
defined(__SPLIT__set_cpenable_nw)
// void xthal_set_cpenable(unsigned);
//
// Note: to help asm code performance (eg. OS task switch),
// this routine returns the previous value of CPENABLE in a3
// (not a2, because that could require an extra mov instruction).
// This return value is not shown in the prototype, because
// C code won't see it.
// [Perhaps this should go in an RTOS-specific Core HAL or BSP. TBD.]
DECLFUNC(xthal_set_cpenable)
abi_entry
#if XCHAL_HAVE_CP
//rsr.cpenable a3 // return previous CPENABLE
movi a3, 0 // for now, always return 0 (VxWorks currently done that way)
wsr.cpenable a2
#else
movi a3, 0 // if no CPENABLE (no coprocessors), none is ever enabled
#endif
abi_return
endfunc
#endif
/* Nothing implemented below this point. */
/************************************************************************/
#if 0
//----------------------------------------------------------------------
// initialize the processor state
//----------------------------------------------------------------------
// void xthal_init_extra_nw()
.global xthal_init_extra_nw
.align 4
xthal_init_extra_nw:
//addi sp, sp, 0
... NOT IMPLEMENTED ...
ret
//----------------------------------------------------------------------
// initialize the TIE coprocessor
//----------------------------------------------------------------------
// void xthal_init_cp_nw(int)
.global xthal_init_cp_nw
.align 4
xthal_init_cp_nw:
//addi sp, sp, 0
... NOT IMPLEMENTED ...
ret
//----------------------------------------------------------------------
//
//----------------------------------------------------------------------
// initialize the extra processor
// void xthal_init_mem_extra_nw()
.global xthal_init_mem_extra_nw
.align 4
xthal_init_mem_extra_nw:
//addi sp, sp, 0
... NOT IMPLEMENTED ...
ret
//----------------------------------------------------------------------
//
//----------------------------------------------------------------------
// initialize the TIE coprocessor
// void xthal_init_mem_cp_nw(int)
.global xthal_init_mem_cp_nw
.align 4
xthal_init_mem_cp_nw:
//addi sp, sp, 0
... NOT IMPLEMENTED ...
ret
#endif /*0*/