uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ISR_Support.h
Go to the documentation of this file.
1 /*
2  FreeRTOS V7.5.3 - Copyright (C) 2013 Real Time Engineers Ltd.
3  All rights reserved
4 
5  VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
6 
7  ***************************************************************************
8  * *
9  * FreeRTOS provides completely free yet professionally developed, *
10  * robust, strictly quality controlled, supported, and cross *
11  * platform software that has become a de facto standard. *
12  * *
13  * Help yourself get started quickly and support the FreeRTOS *
14  * project by purchasing a FreeRTOS tutorial book, reference *
15  * manual, or both from: http://www.FreeRTOS.org/Documentation *
16  * *
17  * Thank you! *
18  * *
19  ***************************************************************************
20 
21  This file is part of the FreeRTOS distribution.
22 
23  FreeRTOS is free software; you can redistribute it and/or modify it under
24  the terms of the GNU General Public License (version 2) as published by the
25  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
26 
27  >>! NOTE: The modification to the GPL is included to allow you to distribute
28  >>! a combined work that includes FreeRTOS without being obliged to provide
29  >>! the source code for proprietary components outside of the FreeRTOS
30  >>! kernel.
31 
32  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
33  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34  FOR A PARTICULAR PURPOSE. Full license text is available from the following
35  link: http://www.freertos.org/a00114.html
36 
37  1 tab == 4 spaces!
38 
39  ***************************************************************************
40  * *
41  * Having a problem? Start by reading the FAQ "My application does *
42  * not run, what could be wrong?" *
43  * *
44  * http://www.FreeRTOS.org/FAQHelp.html *
45  * *
46  ***************************************************************************
47 
48  http://www.FreeRTOS.org - Documentation, books, training, latest versions,
49  license and Real Time Engineers Ltd. contact details.
50 
51  http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
52  including FreeRTOS+Trace - an indispensable productivity tool, a DOS
53  compatible FAT file system, and our tiny thread aware UDP/IP stack.
54 
55  http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
56  Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
57  licenses offer ticketed support, indemnification and middleware.
58 
59  http://www.SafeRTOS.com - High Integrity Systems also provide a safety
60  engineered and independently SIL3 certified version for use in safety and
61  mission critical applications that require provable dependability.
62 
63  1 tab == 4 spaces!
64 */
65 
66 #include "FreeRTOSConfig.h"
67 
68 #define portCONTEXT_SIZE 132
69 #define portEPC_STACK_LOCATION 124
70 #define portSTATUS_STACK_LOCATION 128
71 
72 /******************************************************************/
73 .macro portSAVE_CONTEXT
74 
75  /* Make room for the context. First save the current status so we can
76  manipulate it, and the cause and EPC registers so we capture their
77  original values in case of interrupt nesting. */
78  mfc0 k0, _CP0_CAUSE
79  addiu sp, sp, -portCONTEXT_SIZE
80  mfc0 k1, _CP0_STATUS
81 
82  /* Also save s6 and s5 so we can use them during this interrupt. Any
83  nesting interrupts should maintain the values of these registers
84  across the ISR. */
85  sw s6, 44(sp)
86  sw s5, 40(sp)
88 
89  /* Enable interrupts above the current priority. */
90  srl k0, k0, 0xa
91  ins k1, k0, 10, 6
92  ins k1, zero, 1, 4
93 
94  /* s5 is used as the frame pointer. */
95  add s5, zero, sp
96 
97  /* Check the nesting count value. */
98  la k0, uxInterruptNesting
99  lw s6, (k0)
100 
101  /* If the nesting count is 0 then swap to the the system stack, otherwise
102  the system stack is already being used. */
103  bne s6, zero, .+20
104  nop
105 
106  /* Swap to the system stack. */
107  la sp, xISRStackTop
108  lw sp, (sp)
109 
110  /* Increment and save the nesting count. */
111  addiu s6, s6, 1
112  sw s6, 0(k0)
113 
114  /* s6 holds the EPC value, this is saved after interrupts are re-enabled. */
115  mfc0 s6, _CP0_EPC
116 
117  /* Re-enable interrupts. */
118  mtc0 k1, _CP0_STATUS
119 
120  /* Save the context into the space just created. s6 is saved again
121  here as it now contains the EPC value. No other s registers need be
122  saved. */
123  sw ra, 120(s5)
124  sw s8, 116(s5)
125  sw t9, 112(s5)
126  sw t8, 108(s5)
127  sw t7, 104(s5)
128  sw t6, 100(s5)
129  sw t5, 96(s5)
130  sw t4, 92(s5)
131  sw t3, 88(s5)
132  sw t2, 84(s5)
133  sw t1, 80(s5)
134  sw t0, 76(s5)
135  sw a3, 72(s5)
136  sw a2, 68(s5)
137  sw a1, 64(s5)
138  sw a0, 60(s5)
139  sw v1, 56(s5)
140  sw v0, 52(s5)
141  sw s6, portEPC_STACK_LOCATION(s5)
142  sw $1, 16(s5)
143 
144  /* s6 is used as a scratch register. */
145  mfhi s6
146  sw s6, 12(s5)
147  mflo s6
148  sw s6, 8(s5)
149 
150  /* Update the task stack pointer value if nesting is zero. */
151  la s6, uxInterruptNesting
152  lw s6, (s6)
153  addiu s6, s6, -1
154  bne s6, zero, .+20
155  nop
156 
157  /* Save the stack pointer. */
159  sw s5, (s6)
160 
161  .endm
162 
163 /******************************************************************/
164 .macro portRESTORE_CONTEXT
165 
166  /* Restore the stack pointer from the TCB. This is only done if the
167  nesting count is 1. */
168  la s6, uxInterruptNesting
169  lw s6, (s6)
170  addiu s6, s6, -1
171  bne s6, zero, .+20
172  nop
174  lw s5, (s6)
175 
176  /* Restore the context. */
177  lw s6, 8(s5)
178  mtlo s6
179  lw s6, 12(s5)
180  mthi s6
181  lw $1, 16(s5)
182  /* s6 is loaded as it was used as a scratch register and therefore saved
183  as part of the interrupt context. */
184  lw s6, 44(s5)
185  lw v0, 52(s5)
186  lw v1, 56(s5)
187  lw a0, 60(s5)
188  lw a1, 64(s5)
189  lw a2, 68(s5)
190  lw a3, 72(s5)
191  lw t0, 76(s5)
192  lw t1, 80(s5)
193  lw t2, 84(s5)
194  lw t3, 88(s5)
195  lw t4, 92(s5)
196  lw t5, 96(s5)
197  lw t6, 100(s5)
198  lw t7, 104(s5)
199  lw t8, 108(s5)
200  lw t9, 112(s5)
201  lw s8, 116(s5)
202  lw ra, 120(s5)
203 
204  /* Protect access to the k registers, and others. */
205  di
206 
207  /* Decrement the nesting count. */
208  la k0, uxInterruptNesting
209  lw k1, (k0)
210  addiu k1, k1, -1
211  sw k1, 0(k0)
212 
213  lw k0, portSTATUS_STACK_LOCATION(s5)
214  lw k1, portEPC_STACK_LOCATION(s5)
215 
216  /* Leave the stack how we found it. First load sp from s5, then restore
217  s5 from the stack. */
218  add sp, zero, s5
219  lw s5, 40(sp)
220  addiu sp, sp, portCONTEXT_SIZE
221 
222  mtc0 k0, _CP0_STATUS
223  mtc0 k1, _CP0_EPC
224  eret
225  nop
226 
227  .endm
228