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