| /* 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 */ |
| |