Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / magpie_1_1 / sboot / athos / src / xtos / exc-syscall-c-handler.c
1 /* exc-syscall-c-handler.c - SYSCALL instruction XTOS handler in C */
2
3 /*
4  * Copyright (c) 1999-2006 Tensilica Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 #include <xtensa/config/core.h>
27 #include "xtos-internal.h"
28
29
30 /*
31  *  User vector mode exception handler for the SYSCALL cause.
32  *
33  *  NOTE:  This function is NOT used by default.  The assembly-level
34  *  handler version of this function is normally used instead.
35  *  This function is provided as an example only.
36  *  To use it instead of the default assembly-level version,
37  *  you can register it using _xtos_set_exception_handler().
38  *  For example:
39  *
40  *      #include <xtensa/xtruntime.h>
41  *      #include <xtensa/corebits.h>
42  *      _xtos_set_exception_handler( EXCCAUSE_SYSCALL,
43  *                      (_xtos_handler)_xtos_p_syscall_handler );
44  */
45 UserFrame* _xtos_p_syscall_handler( UserFrame *uf /*, int cause */ )
46 {
47     uf->pc += 3;        /* skip SYSCALL instruction */
48
49 #if XCHAL_HAVE_LOOPS
50     /*
51      *  If the SYSCALL instruction was the last instruction in the body
52      *  of a zero-overhead loop, then we should decrement the loop count
53      *  and resume execution at the head of the loop.
54      */
55
56     if( uf->pc == uf->lend && uf->lcount != 0 )
57     {
58         uf->lcount--;
59         uf->pc = uf->lbeg;
60     }
61 #endif /*XCHAL_HAVE_LOOP*/
62
63     /*
64      *  Handle the system call.
65      *
66      *  A typical SYSCALL handler uses code such as this to handle
67      *  the system call, where the operation to be done is determined
68      *  by the a2 register.  Parameters to the operation are typically
69      *  passed in address registers a3 and up.  Results are typically
70      *  returned in a2.  (See Linux source code for example.)
71      */
72     switch( uf->a2 ) {
73         case 0:
74             /*  Spill register windows to the stack.  */
75             /*
76              *  The Xtensa architecture reserves the a2==0 condition as a request
77              *  to flush (spill) register windows to the stack.  The current exception
78              *  handling implementation never spills windows to the stack (it used
79              *  to always spill, not true anymore), so we have to spill windows
80              *  explicitly here.  (Note that xthal_window_spill() spills windows
81              *  that are part of the interrupt handling context, that don't
82              *  really need to be spilled, but that's harmless other than being
83              *  less than optimally efficient.)
84              *
85              *  Also, be nice to programmers here.  If they're
86              *  building for Call0 ABI, silently do nothing for
87              *  syscall a2==0.
88              */
89 #ifdef __XTENSA_WINDOWED_ABI__
90             xthal_window_spill();
91 #endif
92             break;
93
94         default:
95             uf->a2 = -1 /*ENOSYS*/;     /* system call not supported */
96             break;
97     }
98
99     return( uf );
100 }
101