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