Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ISR_Support.h « PIC32MEC14xx « MPLAB « portable - github.com/FreeRTOS/FreeRTOS-Kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: afc431526f815aa9037a439a221aa8fdb672c451 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
 * FreeRTOS Kernel V10.4.3 LTS Patch 3
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * https://www.FreeRTOS.org
 * https://github.com/FreeRTOS
 *
 * 1 tab == 4 spaces!
 */

#include "FreeRTOSConfig.h"

#define portCONTEXT_SIZE 132
#define portEPC_STACK_LOCATION 124
#define portSTATUS_STACK_LOCATION 128

#ifdef __LANGUAGE_ASSEMBLY__

/******************************************************************/
.macro	portSAVE_CONTEXT

	/* Make room for the context. First save the current status so it can be
	manipulated, and the cause and EPC registers so their original values are
	captured. */
	mfc0	k0, _CP0_CAUSE
	addiu	sp, sp, -portCONTEXT_SIZE
	mfc0	k1, _CP0_STATUS

	/* Also save s6 and s5 so they can be used.  Any nesting interrupts should
	maintain the values of these registers across the ISR. */
	sw		s6, 44(sp)
	sw		s5, 40(sp)
	sw		k1, portSTATUS_STACK_LOCATION(sp)

	/* Prepare to enable interrupts above the current priority.
	k0 = k0 >> 10. Moves RIPL[17:10] to [7:0] */
	srl		k0, k0, 0xa

	/* Insert bit field. 7 bits k0[6:0] to k1[16:10] */
	ins		k1, k0, 10, 7

	/* Sets CP0.Status.IPL = CP0.Cause.RIPL
	Copy the MSB of the IPL, but it would be an error if it was set anyway. */
	srl		k0, k0, 0x7

	/* MSB of IPL is bit[18] of CP0.Status */
	ins		k1, k0, 18, 1

	/* CP0.Status[5:1] = 0 b[5]=Rsvd, b[4]=UM,
	   b[3]=Rsvd, b[2]=ERL, b[1]=EXL
	   Setting EXL=0 allows higher priority interrupts
	   to preempt this handler */
	ins		k1, zero, 1, 4


	/* s5 is used as the frame pointer. */
	add		s5, zero, sp

	/* Check the nesting count value. */
	la		k0, uxInterruptNesting
	lw		s6, (k0)

	/* If the nesting count is 0 then swap to the the system stack, otherwise
	the system stack is already being used. */
	bne		s6, zero, 1f
	nop

	/* Swap to the system stack. */
	la		sp, xISRStackTop
	lw		sp, (sp)

	/* Increment and save the nesting count. */
1:  addiu   s6, s6, 1
	sw		s6, 0(k0)

	/* s6 holds the EPC value, this is saved after interrupts are re-enabled. */
	mfc0	s6, _CP0_EPC

	/* Re-enable interrupts. */
	mtc0	k1, _CP0_STATUS

	/* Save the context into the space just created.  s6 is saved again
	here as it now contains the EPC value.  No other s registers need be
	saved. */
	sw		ra, 120(s5) /* Return address (RA=R31) */
	sw		s8, 116(s5) /* Frame Pointer (FP=R30) */
	sw		t9, 112(s5)
	sw		t8, 108(s5)
	sw		t7, 104(s5)
	sw		t6, 100(s5)
	sw		t5, 96(s5)
	sw		t4, 92(s5)
	sw		t3, 88(s5)
	sw		t2, 84(s5)
	sw		t1, 80(s5)
	sw		t0, 76(s5)
	sw		a3, 72(s5)
	sw		a2, 68(s5)
	sw		a1, 64(s5)
	sw		a0, 60(s5)
	sw		v1, 56(s5)
	sw		v0, 52(s5)
	sw		s6, portEPC_STACK_LOCATION(s5)
	sw		$1, 16(s5)

	/* MEC14xx does not have DSP, removed 7 words */
	mfhi	s6
	sw		s6, 12(s5)
	mflo	s6
	sw		s6, 8(s5)

	/* Update the task stack pointer value if nesting is zero. */
	la		s6, uxInterruptNesting
	lw		s6, (s6)
	addiu	s6, s6, -1
	bne		s6, zero, 1f
	nop

	/* Save the stack pointer. */
	la		s6, uxSavedTaskStackPointer
	sw		s5, (s6)
1:
	.endm

/******************************************************************/
.macro	portRESTORE_CONTEXT

	/* Restore the stack pointer from the TCB.  This is only done if the
	nesting count is 1. */
	la		s6, uxInterruptNesting
	lw		s6, (s6)
	addiu   s6, s6, -1
	bne		s6, zero, 1f
	nop
	la		s6, uxSavedTaskStackPointer
	lw		s5, (s6)

	/* Restore the context.
	MCHP MEC14xx does not include DSP */
1:
	lw		s6, 8(s5)
	mtlo	s6
	lw		s6, 12(s5)
	mthi	s6
	lw		$1, 16(s5)

	/* s6 is loaded as it was used as a scratch register and therefore saved
	as part of the interrupt context. */
	lw		s6, 44(s5)
	lw		v0, 52(s5)
	lw		v1, 56(s5)
	lw		a0, 60(s5)
	lw		a1, 64(s5)
	lw		a2, 68(s5)
	lw		a3, 72(s5)
	lw		t0, 76(s5)
	lw		t1, 80(s5)
	lw		t2, 84(s5)
	lw		t3, 88(s5)
	lw		t4, 92(s5)
	lw		t5, 96(s5)
	lw		t6, 100(s5)
	lw		t7, 104(s5)
	lw		t8, 108(s5)
	lw		t9, 112(s5)
	lw		s8, 116(s5)
	lw		ra, 120(s5)

	/* Protect access to the k registers, and others. */
	di
	ehb

	/* Decrement the nesting count. */
	la		k0, uxInterruptNesting
	lw		k1, (k0)
	addiu	k1, k1, -1
	sw		k1, 0(k0)

	lw		k0, portSTATUS_STACK_LOCATION(s5)
	lw		k1, portEPC_STACK_LOCATION(s5)

	/* Leave the stack in its original state.  First load sp from s5, then
	restore s5 from the stack. */
	add		sp, zero, s5
	lw		s5, 40(sp)
	addiu   sp, sp, portCONTEXT_SIZE

	mtc0	k0, _CP0_STATUS
	mtc0	k1, _CP0_EPC
	ehb
	eret
	nop

	.endm

#endif /* #ifdef __LANGUAGE_ASSEMBLY__ */