blob: c70c0c82d6f4b807d7fd82c51895c7466c5d8202 [file] [log] [blame]
/* switch_contexts.S - setup for multiple contexts */
/*
* Copyright (c) 2003-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>
#include <xtensa/xtruntime-frames.h>
#if XCHAL_NUM_CONTEXTS > 1
/*
* void _xtos_setup_context(int context_num, StartInfo *info);
*/
.align 4
.global _xtos_setup_context
.type _xtos_setup_context,@function
_xtos_setup_context:
abi_entry
#if XCHAL_HAVE_INTERRUPTS
rsil a5, 15 /* disable interrupts so we can use EXCSAVE_1 */
#else
rsr a5, PS /* just read PS */
#endif
wsr a3, EXCSAVE_1 /* save pointer to new context info */
s32i a5, a3, INFO_prevps /* save previous PS */
movi a4, ~0x01F00000 /* mask out PS.CTXT */
slli a2, a2, 20 /* shift up new PS.CTXT value */
and a4, a5, a4
or a4, a4, a2 /* new PS value */
wsr a4, PS
rsync
/* We're now in the new context! */
movi a0, 0
movi a1, 1
wsr a1, WINDOWSTART
wsr a0, WINDOWBASE
rsync
rsr a9, EXCSAVE_1 /* get pointer to context info */
movi a0, 0 /* terminate call frames */
l32i a1, a9, INFO_sp /* get stack pointer */
l32i a10, a9, INFO_arg1 /* get start function's arguments... */
l32i a8, a9, INFO_funcpc /* get start function's address */
/* Okay, now switch back to context zero: */
l32i a9, a9, INFO_prevps /* retrieve previous PS */
wsr a9, PS
rsync
/* Back to original context! */
abi_return
.size _xtos_setup_context, . - _xtos_setup_context
/*
* This is the first thing to be executed in the new context
* by explicit setting of PC:
*/
.align 4
.global _xtos_start_context
_xtos_start_context:
#ifdef __XTENSA_CALL0_ABI__
Crash the assembler here: I think this is wrong.
callx0 a8
#else
callx8 a8
#endif
1: nop
j 1b /* do nothing until context 0 exits */
.size _xtos_start_context, . - _xtos_start_context
#endif /* XCHAL_NUM_CONTEXTS > 1 */