]> begriffs open source - cmsis-freertos/blob - Source/portable/MPLAB/PIC32MEC14xx/ISR_Support.h
Initial commit
[cmsis-freertos] / Source / portable / MPLAB / PIC32MEC14xx / ISR_Support.h
1 /*
2     FreeRTOS V9.0.0 - Copyright (C) 2016 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     This file is part of the FreeRTOS distribution.
8
9     FreeRTOS is free software; you can redistribute it and/or modify it under
10     the terms of the GNU General Public License (version 2) as published by the
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
12
13     ***************************************************************************
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<
16     >>!   obliged to provide the source code for proprietary components     !<<
17     >>!   outside of the FreeRTOS kernel.                                   !<<
18     ***************************************************************************
19
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following
23     link: http://www.freertos.org/a00114.html
24
25     ***************************************************************************
26      *                                                                       *
27      *    FreeRTOS provides completely free yet professionally developed,    *
28      *    robust, strictly quality controlled, supported, and cross          *
29      *    platform software that is more than just the market leader, it     *
30      *    is the industry's de facto standard.                               *
31      *                                                                       *
32      *    Help yourself get started quickly while simultaneously helping     *
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *
34      *    tutorial book, reference manual, or both:                          *
35      *    http://www.FreeRTOS.org/Documentation                              *
36      *                                                                       *
37     ***************************************************************************
38
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
40     the FAQ page "My application does not run, what could be wrong?".  Have you
41     defined configASSERT()?
42
43     http://www.FreeRTOS.org/support - In return for receiving this top quality
44     embedded software for free we request you assist our global community by
45     participating in the support forum.
46
47     http://www.FreeRTOS.org/training - Investing in training allows your team to
48     be as productive as possible as early as possible.  Now you can receive
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
50     Ltd, and the world's leading authority on the world's leading RTOS.
51
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.
55
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
58
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
61     licenses offer ticketed support, indemnification and commercial middleware.
62
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety
64     engineered and independently SIL3 certified version for use in safety and
65     mission critical applications that require provable dependability.
66
67     1 tab == 4 spaces!
68 */
69
70 #include "FreeRTOSConfig.h"
71
72 #define portCONTEXT_SIZE 132
73 #define portEPC_STACK_LOCATION 124
74 #define portSTATUS_STACK_LOCATION 128
75
76 #ifdef __LANGUAGE_ASSEMBLY__
77
78 /******************************************************************/
79 .macro  portSAVE_CONTEXT
80
81         /* Make room for the context. First save the current status so it can be
82         manipulated, and the cause and EPC registers so their original values are
83         captured. */
84         mfc0    k0, _CP0_CAUSE
85         addiu   sp, sp, -portCONTEXT_SIZE
86         mfc0    k1, _CP0_STATUS
87
88         /* Also save s6 and s5 so they can be used.  Any nesting interrupts should
89         maintain the values of these registers across the ISR. */
90         sw              s6, 44(sp)
91         sw              s5, 40(sp)
92         sw              k1, portSTATUS_STACK_LOCATION(sp)
93
94         /* Prepare to enable interrupts above the current priority.
95         k0 = k0 >> 10. Moves RIPL[17:10] to [7:0] */
96         srl             k0, k0, 0xa
97
98         /* Insert bit field. 7 bits k0[6:0] to k1[16:10] */
99         ins             k1, k0, 10, 7
100
101         /* Sets CP0.Status.IPL = CP0.Cause.RIPL
102         Copy the MSB of the IPL, but it would be an error if it was set anyway. */
103         srl             k0, k0, 0x7
104
105         /* MSB of IPL is bit[18] of CP0.Status */
106         ins             k1, k0, 18, 1
107
108         /* CP0.Status[5:1] = 0 b[5]=Rsvd, b[4]=UM,
109            b[3]=Rsvd, b[2]=ERL, b[1]=EXL
110            Setting EXL=0 allows higher priority interrupts
111            to preempt this handler */
112         ins             k1, zero, 1, 4
113
114
115         /* s5 is used as the frame pointer. */
116         add             s5, zero, sp
117
118         /* Check the nesting count value. */
119         la              k0, uxInterruptNesting
120         lw              s6, (k0)
121
122         /* If the nesting count is 0 then swap to the the system stack, otherwise
123         the system stack is already being used. */
124         bne             s6, zero, 1f
125         nop
126
127         /* Swap to the system stack. */
128         la              sp, xISRStackTop
129         lw              sp, (sp)
130
131         /* Increment and save the nesting count. */
132 1:  addiu   s6, s6, 1
133         sw              s6, 0(k0)
134
135         /* s6 holds the EPC value, this is saved after interrupts are re-enabled. */
136         mfc0    s6, _CP0_EPC
137
138         /* Re-enable interrupts. */
139         mtc0    k1, _CP0_STATUS
140
141         /* Save the context into the space just created.  s6 is saved again
142         here as it now contains the EPC value.  No other s registers need be
143         saved. */
144         sw              ra, 120(s5) /* Return address (RA=R31) */
145         sw              s8, 116(s5) /* Frame Pointer (FP=R30) */
146         sw              t9, 112(s5)
147         sw              t8, 108(s5)
148         sw              t7, 104(s5)
149         sw              t6, 100(s5)
150         sw              t5, 96(s5)
151         sw              t4, 92(s5)
152         sw              t3, 88(s5)
153         sw              t2, 84(s5)
154         sw              t1, 80(s5)
155         sw              t0, 76(s5)
156         sw              a3, 72(s5)
157         sw              a2, 68(s5)
158         sw              a1, 64(s5)
159         sw              a0, 60(s5)
160         sw              v1, 56(s5)
161         sw              v0, 52(s5)
162         sw              s6, portEPC_STACK_LOCATION(s5)
163         sw              $1, 16(s5)
164
165         /* MEC14xx does not have DSP, removed 7 words */
166         mfhi    s6
167         sw              s6, 12(s5)
168         mflo    s6
169         sw              s6, 8(s5)
170
171         /* Update the task stack pointer value if nesting is zero. */
172         la              s6, uxInterruptNesting
173         lw              s6, (s6)
174         addiu   s6, s6, -1
175         bne             s6, zero, 1f
176         nop
177
178         /* Save the stack pointer. */
179         la              s6, uxSavedTaskStackPointer
180         sw              s5, (s6)
181 1:
182         .endm
183
184 /******************************************************************/
185 .macro  portRESTORE_CONTEXT
186
187         /* Restore the stack pointer from the TCB.  This is only done if the
188         nesting count is 1. */
189         la              s6, uxInterruptNesting
190         lw              s6, (s6)
191         addiu   s6, s6, -1
192         bne             s6, zero, 1f
193         nop
194         la              s6, uxSavedTaskStackPointer
195         lw              s5, (s6)
196
197         /* Restore the context.
198         MCHP MEC14xx does not include DSP */
199 1:
200         lw              s6, 8(s5)
201         mtlo    s6
202         lw              s6, 12(s5)
203         mthi    s6
204         lw              $1, 16(s5)
205
206         /* s6 is loaded as it was used as a scratch register and therefore saved
207         as part of the interrupt context. */
208         lw              s6, 44(s5)
209         lw              v0, 52(s5)
210         lw              v1, 56(s5)
211         lw              a0, 60(s5)
212         lw              a1, 64(s5)
213         lw              a2, 68(s5)
214         lw              a3, 72(s5)
215         lw              t0, 76(s5)
216         lw              t1, 80(s5)
217         lw              t2, 84(s5)
218         lw              t3, 88(s5)
219         lw              t4, 92(s5)
220         lw              t5, 96(s5)
221         lw              t6, 100(s5)
222         lw              t7, 104(s5)
223         lw              t8, 108(s5)
224         lw              t9, 112(s5)
225         lw              s8, 116(s5)
226         lw              ra, 120(s5)
227
228         /* Protect access to the k registers, and others. */
229         di
230         ehb
231
232         /* Decrement the nesting count. */
233         la              k0, uxInterruptNesting
234         lw              k1, (k0)
235         addiu   k1, k1, -1
236         sw              k1, 0(k0)
237
238         lw              k0, portSTATUS_STACK_LOCATION(s5)
239         lw              k1, portEPC_STACK_LOCATION(s5)
240
241         /* Leave the stack in its original state.  First load sp from s5, then
242         restore s5 from the stack. */
243         add             sp, zero, s5
244         lw              s5, 40(sp)
245         addiu   sp, sp, portCONTEXT_SIZE
246
247         mtc0    k0, _CP0_STATUS
248         mtc0    k1, _CP0_EPC
249         ehb
250         eret
251         nop
252
253         .endm
254
255 #endif /* #ifdef __LANGUAGE_ASSEMBLY__ */
256