OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Source/] [portable/] [Softune/] [MB91460/] [port.c] - Blame information for rev 599

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 572 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
#include "FreeRTOS.h"
55
#include "task.h"
56
#include "mb91467d.h"
57
 
58
/*-----------------------------------------------------------*/
59
 
60
/* We require the address of the pxCurrentTCB variable, but don't want to know
61
any details of its type. */
62
typedef void tskTCB;
63
extern volatile tskTCB * volatile pxCurrentTCB;
64
 
65
/*-----------------------------------------------------------*/
66
 
67
#pragma asm
68
#macro  SaveContext
69
         ORCCR #0x20                                                            ;Switch to user stack
70
         ST RP,@-R15                                                            ;Store RP
71
         STM0 (R7,R6,R5,R4,R3,R2,R1,R0)                         ;Store R7-R0
72
         STM1 (R14,R13,R12,R11,R10,R9,R8)                       ;Store R14-R8
73
         ST MDH, @-R15                                                          ;Store MDH
74
         ST MDL, @-R15                                                          ;Store MDL
75
 
76
         ANDCCR #0xDF                                                           ;Switch back to system stack
77
         LD @R15+,R0                                                            ;Store PC to R0
78
         ORCCR #0x20                                                            ;Switch to user stack
79
         ST R0,@-R15                                                            ;Store PC to User stack
80
 
81
         ANDCCR #0xDF                                                           ;Switch back to system stack
82
         LD @R15+,R0                                                            ;Store PS to R0
83
         ORCCR #0x20                                                            ;Switch to user stack
84
         ST R0,@-R15                                                            ;Store PS to User stack
85
 
86
         LDI #_pxCurrentTCB, R0                                         ;Get pxCurrentTCB address
87
         LD @R0, R0                                                                     ;Get the pxCurrentTCB->pxTopOfStack address
88
         ST R15,@R0                                                                     ;Store USP to pxCurrentTCB->pxTopOfStack
89
 
90
         ANDCCR #0xDF                                                           ;Switch back to system stack for the rest of tick ISR
91
#endm
92
 
93
#macro RestoreContext
94
         LDI #_pxCurrentTCB, R0                                         ;Get pxCurrentTCB address
95
         LD @R0, R0                                                                     ;Get the pxCurrentTCB->pxTopOfStack address
96
         ORCCR #0x20                                                            ;Switch to user stack
97
         LD @R0, R15                                                            ;Restore USP from pxCurrentTCB->pxTopOfStack
98
 
99
         LD @R15+,R0                                                            ;Store PS to R0
100
         ANDCCR #0xDF                                                           ;Switch to system stack
101
         ST R0,@-R15                                                            ;Store PS to system stack
102
 
103
         ORCCR #0x20                                                            ;Switch to user stack
104
         LD @R15+,R0                                                            ;Store PC to R0
105
         ANDCCR #0xDF                                                           ;Switch to system stack
106
         ST R0,@-R15                                                            ;Store PC to system stack
107
 
108
         ORCCR #0x20                                                            ;Switch back to retrieve the remaining context
109
 
110
         LD @R15+, MDL                                                          ;Restore MDL
111
         LD @R15+, MDH                                                          ;Restore MDH
112
         LDM1 (R14,R13,R12,R11,R10,R9,R8)                       ;Restore R14-R8
113
         LDM0 (R7,R6,R5,R4,R3,R2,R1,R0)                         ;Restore R7-R0
114
         LD @R15+, RP                                                           ;Restore RP
115
 
116
         ANDCCR #0xDF                                                           ;Switch back to system stack for the rest of tick ISR
117
#endm
118
#pragma endasm
119
 
120
/*-----------------------------------------------------------*/
121
 
122
/*
123
 * Perform hardware setup to enable ticks from timer 1,
124
 */
125
static void prvSetupTimerInterrupt( void );
126
/*-----------------------------------------------------------*/
127
 
128
/*
129
 * Initialise the stack of a task to look exactly as if a call to
130
 * portSAVE_CONTEXT had been called.
131
 *
132
 * See the header file portable.h.
133
 */
134
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
135
{
136
        /* Place a few bytes of known values on the bottom of the stack.
137
        This is just useful for debugging. */
138
 
139
        *pxTopOfStack = 0x11111111;
140
        pxTopOfStack--;
141
        *pxTopOfStack = 0x22222222;
142
        pxTopOfStack--;
143
        *pxTopOfStack = 0x33333333;
144
        pxTopOfStack--;
145
 
146
        /* This is a redundant push to the stack, it may be required if
147
        in some implementations of the compiler the parameter to the task
148
        is passed on to the stack rather than in R4 register. */
149
        *pxTopOfStack = (portSTACK_TYPE)(pvParameters);
150
        pxTopOfStack--;
151
 
152
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;  /* RP */
153
        pxTopOfStack--;
154
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00007777;  /* R7 */
155
        pxTopOfStack--;
156
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00006666;  /* R6 */
157
        pxTopOfStack--;
158
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00005555;  /* R5 */
159
        pxTopOfStack--;
160
 
161
        /* In the current implementation of the compiler the first
162
        parameter to the task (or function) is passed via R4 parameter
163
        to the task, hence the pvParameters pointer is copied into the R4
164
        register. See compiler manual section 4.6.2 for more information. */
165
        *pxTopOfStack = ( portSTACK_TYPE ) (pvParameters);      /* R4 */
166
        pxTopOfStack--;
167
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00003333;  /* R3 */
168
        pxTopOfStack--;
169
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00002222;  /* R2 */
170
        pxTopOfStack--;
171
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00001111;  /* R1 */
172
        pxTopOfStack--;
173
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00000001;  /* R0 */
174
        pxTopOfStack--;
175
        *pxTopOfStack = ( portSTACK_TYPE ) 0x0000EEEE;  /* R14 */
176
        pxTopOfStack--;
177
        *pxTopOfStack = ( portSTACK_TYPE ) 0x0000DDDD;  /* R13 */
178
        pxTopOfStack--;
179
        *pxTopOfStack = ( portSTACK_TYPE ) 0x0000CCCC;  /* R12 */
180
        pxTopOfStack--;
181
        *pxTopOfStack = ( portSTACK_TYPE ) 0x0000BBBB;  /* R11 */
182
        pxTopOfStack--;
183
        *pxTopOfStack = ( portSTACK_TYPE ) 0x0000AAAA;  /* R10 */
184
        pxTopOfStack--;
185
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00009999;  /* R9 */
186
        pxTopOfStack--;
187
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00008888;  /* R8 */
188
        pxTopOfStack--;
189
        *pxTopOfStack = ( portSTACK_TYPE ) 0x11110000;  /* MDH */
190
        pxTopOfStack--;
191
        *pxTopOfStack = ( portSTACK_TYPE ) 0x22220000;  /* MDL */
192
        pxTopOfStack--;
193
 
194
        /* The start of the task code. */
195
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* PC */
196
        pxTopOfStack--;
197
 
198
    /* PS - User Mode, USP, ILM=31, Interrupts enabled */
199
        *pxTopOfStack = ( portSTACK_TYPE ) 0x001F0030;  /* PS */
200
 
201
        return pxTopOfStack;
202
}
203
/*-----------------------------------------------------------*/
204
 
205
portBASE_TYPE xPortStartScheduler( void )
206
{
207
        /* Setup the hardware to generate the tick. */
208
        prvSetupTimerInterrupt();
209
 
210
        /* Restore the context of the first task that is going to run. */
211
        #pragma asm
212
                RestoreContext
213
        #pragma endasm
214
 
215
        /* Simulate a function call end as generated by the compiler.  We will now
216
        jump to the start of the task the context of which we have just restored. */
217
        __asm(" reti ");
218
 
219
        /* Should not get here. */
220
        return pdFAIL;
221
}
222
/*-----------------------------------------------------------*/
223
 
224
void vPortEndScheduler( void )
225
{
226
        /* Not implemented - unlikely to ever be required as there is nothing to
227
        return to. */
228
}
229
/*-----------------------------------------------------------*/
230
 
231
static void prvSetupTimerInterrupt( void )
232
{
233
/* The peripheral clock divided by 32 is used by the timer. */
234
const unsigned short usReloadValue = ( unsigned short ) ( ( ( configPER_CLOCK_HZ / configTICK_RATE_HZ ) / 32UL ) - 1UL );
235
 
236
        /* Setup RLT0 to generate a tick interrupt. */
237
 
238
        TMCSR0_CNTE = 0;         /* Count Disable */
239
    TMCSR0_CSL = 0x2;           /* CLKP/32 */
240
    TMCSR0_MOD = 0;                      /* Software trigger */
241
    TMCSR0_RELD = 1;            /* Reload */
242
 
243
    TMCSR0_UF = 0;                       /* Clear underflow flag */
244
        TMRLR0 = usReloadValue;
245
        TMCSR0_INTE = 1;                /* Interrupt Enable */
246
        TMCSR0_CNTE = 1;                /* Count Enable */
247
        TMCSR0_TRG = 1;                 /* Trigger */
248
 
249
    PORTEN = 0x3;                       /* Port Enable */
250
}
251
/*-----------------------------------------------------------*/
252
 
253
#if configUSE_PREEMPTION == 1
254
 
255
        /*
256
         * Tick ISR for preemptive scheduler. The tick count is incremented
257
         * after the context is saved. Then the context is switched if required,
258
         * and last the context of the task which is to be resumed is restored.
259
         */
260
 
261
        #pragma asm
262
 
263
        .global _ReloadTimer0_IRQHandler
264
        _ReloadTimer0_IRQHandler:
265
 
266
        ANDCCR #0xEF                                                    ;Disable Interrupts
267
        SaveContext                                                             ;Save context
268
        ORCCR #0x10                                                             ;Re-enable Interrupts
269
 
270
        LDI #0xFFFB,R1
271
        LDI #_tmcsr0, R0
272
        AND R1,@R0                                                              ;Clear RLT0 interrupt flag
273
 
274
        CALL32   _vTaskIncrementTick,R12                ;Increment Tick
275
        CALL32   _vTaskSwitchContext,R12                ;Switch context if required
276
 
277
        ANDCCR #0xEF                                                    ;Disable Interrupts
278
        RestoreContext                                                  ;Restore context
279
        ORCCR #0x10                                                             ;Re-enable Interrupts
280
 
281
        RETI
282
 
283
        #pragma endasm
284
 
285
#else
286
 
287
        /*
288
         * Tick ISR for the cooperative scheduler.  All this does is increment the
289
         * tick count.  We don't need to switch context, this can only be done by
290
         * manual calls to taskYIELD();
291
         */
292
        __interrupt void ReloadTimer0_IRQHandler( void )
293
        {
294
                /* Clear RLT0 interrupt flag */
295
                TMCSR0_UF = 0;
296
                vTaskIncrementTick();
297
        }
298
 
299
#endif
300
 
301
/*
302
 * Manual context switch. We can use a __nosavereg attribute  as the context
303
 * would be saved by PortSAVE_CONTEXT().  The context is switched and then
304
 * the context of the new task is restored saved.
305
 */
306
#pragma asm
307
 
308
        .global _vPortYieldDelayed
309
        _vPortYieldDelayed:
310
 
311
        ANDCCR #0xEF                                                    ;Disable Interrupts
312
        SaveContext                                                             ;Save context
313
        ORCCR #0x10                                                             ;Re-enable Interrupts
314
 
315
        LDI #_dicr, R0
316
        BANDL #0x0E, @R0                                                ;Clear Delayed interrupt flag
317
 
318
        CALL32   _vTaskSwitchContext,R12                ;Switch context if required
319
 
320
        ANDCCR #0xEF                                                    ;Disable Interrupts
321
        RestoreContext                                                  ;Restore context
322
        ORCCR #0x10                                                             ;Re-enable Interrupts
323
 
324
        RETI
325
 
326
#pragma endasm
327
/*-----------------------------------------------------------*/
328
 
329
/*
330
 * Manual context switch. We can use a __nosavereg attribute  as the context
331
 * would be saved by PortSAVE_CONTEXT().  The context is switched and then
332
 * the context of the new task is restored saved.
333
 */
334
#pragma asm
335
 
336
        .global _vPortYield
337
        _vPortYield:
338
 
339
        SaveContext                                                             ;Save context
340
        CALL32   _vTaskSwitchContext,R12                ;Switch context if required
341
        RestoreContext                                                  ;Restore context
342
 
343
        RETI
344
 
345
#pragma endasm
346
/*-----------------------------------------------------------*/
347
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.