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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Source/] [portable/] [GCC/] [PPC440_Xilinx/] [port.c] - Blame information for rev 579

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
/*-----------------------------------------------------------
55
 * Implementation of functions defined in portable.h for the PPC440 port.
56
 *----------------------------------------------------------*/
57
 
58
 
59
/* Scheduler includes. */
60
#include "FreeRTOS.h"
61
#include "task.h"
62
 
63
/* Library includes. */
64
#include "xtime_l.h"
65
#include "xintc.h"
66
#include "xintc_i.h"
67
 
68
/*-----------------------------------------------------------*/
69
 
70
/* Definitions to set the initial MSR of each task. */
71
#define portCRITICAL_INTERRUPT_ENABLE   ( 1UL << 17UL )
72
#define portEXTERNAL_INTERRUPT_ENABLE   ( 1UL << 15UL )
73
#define portMACHINE_CHECK_ENABLE                ( 1UL << 12UL )
74
 
75
#if configUSE_FPU == 1
76
        #define portAPU_PRESENT                         ( 1UL << 25UL )
77
        #define portFCM_FPU_PRESENT                     ( 1UL << 13UL )
78
#else
79
        #define portAPU_PRESENT                         ( 0UL )
80
        #define portFCM_FPU_PRESENT                     ( 0UL )
81
#endif
82
 
83
#define portINITIAL_MSR         ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE | portAPU_PRESENT | portFCM_FPU_PRESENT )
84
 
85
 
86
extern const unsigned _SDA_BASE_;
87
extern const unsigned _SDA2_BASE_;
88
 
89
/*-----------------------------------------------------------*/
90
 
91
/*
92
 * Setup the system timer to generate the tick interrupt.
93
 */
94
static void prvSetupTimerInterrupt( void );
95
 
96
/*
97
 * The handler for the tick interrupt - defined in portasm.s.
98
 */
99
extern void vPortTickISR( void );
100
 
101
/*
102
 * The handler for the yield function - defined in portasm.s.
103
 */
104
extern void vPortYield( void );
105
 
106
/*
107
 * Function to start the scheduler running by starting the highest
108
 * priority task that has thus far been created.
109
 */
110
extern void vPortStartFirstTask( void );
111
 
112
/*-----------------------------------------------------------*/
113
 
114
/* Structure used to hold the state of the interrupt controller. */
115
static XIntc xInterruptController;
116
 
117
/*-----------------------------------------------------------*/
118
 
119
/*
120
 * Initialise the stack of a task to look exactly as if the task had been
121
 * interrupted.
122
 *
123
 * See the header file portable.h.
124
 */
125
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
126
{
127
        /* Place a known value at the bottom of the stack for debugging. */
128
        *pxTopOfStack = 0xDEADBEEF;
129
        pxTopOfStack--;
130
 
131
        /* EABI stack frame. */
132
        pxTopOfStack -= 20;     /* Previous backchain and LR, R31 to R4 inclusive. */
133
 
134
        /* Parameters in R13. */
135
        *pxTopOfStack = ( portSTACK_TYPE ) &_SDA_BASE_; /* address of the first small data area */
136
        pxTopOfStack -= 10;
137
 
138
        /* Parameters in R3. */
139
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
140
        pxTopOfStack--;
141
 
142
        /* Parameters in R2. */
143
        *pxTopOfStack = ( portSTACK_TYPE ) &_SDA2_BASE_;        /* address of the second small data area */
144
        pxTopOfStack--;
145
 
146
        /* R1 is the stack pointer so is omitted. */
147
 
148
        *pxTopOfStack = 0x10000001UL;;  /* R0. */
149
        pxTopOfStack--;
150
        *pxTopOfStack = 0x00000000UL;   /* USPRG0. */
151
        pxTopOfStack--;
152
        *pxTopOfStack = 0x00000000UL;   /* CR. */
153
        pxTopOfStack--;
154
        *pxTopOfStack = 0x00000000UL;   /* XER. */
155
        pxTopOfStack--;
156
        *pxTopOfStack = 0x00000000UL;   /* CTR. */
157
        pxTopOfStack--;
158
        *pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;   /* LR. */
159
        pxTopOfStack--;
160
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* SRR0. */
161
        pxTopOfStack--;
162
        *pxTopOfStack = portINITIAL_MSR;/* SRR1. */
163
        pxTopOfStack--;
164
        *pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;/* Next LR. */
165
        pxTopOfStack--;
166
        *pxTopOfStack = 0x00000000UL;/* Backchain. */
167
 
168
        return pxTopOfStack;
169
}
170
/*-----------------------------------------------------------*/
171
 
172
portBASE_TYPE xPortStartScheduler( void )
173
{
174
        prvSetupTimerInterrupt();
175
        XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );
176
        vPortStartFirstTask();
177
 
178
        /* Should not get here as the tasks are now running! */
179
        return pdFALSE;
180
}
181
/*-----------------------------------------------------------*/
182
 
183
void vPortEndScheduler( void )
184
{
185
        /* Not implemented. */
186
        for( ;; );
187
}
188
/*-----------------------------------------------------------*/
189
 
190
/*
191
 * Hardware initialisation to generate the RTOS tick.
192
 */
193
static void prvSetupTimerInterrupt( void )
194
{
195
const unsigned long ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
196
 
197
        XTime_DECClearInterrupt();
198
        XTime_FITClearInterrupt();
199
        XTime_WDTClearInterrupt();
200
        XTime_WDTDisableInterrupt();
201
        XTime_FITDisableInterrupt();
202
 
203
        XExc_RegisterHandler( XEXC_ID_DEC_INT, ( XExceptionHandler ) vPortTickISR, ( void * ) 0 );
204
 
205
        XTime_DECEnableAutoReload();
206
        XTime_DECSetInterval( ulInterval );
207
        XTime_DECEnableInterrupt();
208
}
209
/*-----------------------------------------------------------*/
210
 
211
void vPortISRHandler( void *pvNullDoNotUse )
212
{
213
unsigned long ulInterruptStatus, ulInterruptMask = 1UL;
214
portBASE_TYPE xInterruptNumber;
215
XIntc_Config *pxInterruptController;
216
XIntc_VectorTableEntry *pxTable;
217
 
218
        /* Just to remove compiler warning. */
219
        ( void ) pvNullDoNotUse;
220
 
221
        /* Get the configuration by using the device ID - in this case it is
222
        assumed that only one interrupt controller is being used. */
223
        pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
224
 
225
        /* Which interrupts are pending? */
226
        ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress );
227
 
228
        for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ )
229
        {
230
                if( ulInterruptStatus & 0x01UL )
231
                {
232
                        /* Clear the pending interrupt. */
233
                        XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask );
234
 
235
                        /* Call the registered handler. */
236
                        pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] );
237
                        pxTable->Handler( pxTable->CallBackRef );
238
                }
239
 
240
                /* Check the next interrupt. */
241
                ulInterruptMask <<= 0x01UL;
242
                ulInterruptStatus >>= 0x01UL;
243
 
244
                /* Have we serviced all interrupts? */
245
                if( ulInterruptStatus == 0UL )
246
                {
247
                        break;
248
                }
249
        }
250
}
251
/*-----------------------------------------------------------*/
252
 
253
void vPortSetupInterruptController( void )
254
{
255
extern void vPortISRWrapper( void );
256
 
257
        /* Perform all library calls necessary to initialise the exception table
258
        and interrupt controller.  This assumes only one interrupt controller is in
259
        use. */
260
        XExc_mDisableExceptions( XEXC_NON_CRITICAL );
261
        XExc_Init();
262
 
263
        /* The library functions save the context - we then jump to a wrapper to
264
        save the stack into the TCB.  The wrapper then calls the handler defined
265
        above. */
266
        XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
267
        XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
268
        XIntc_Start( &xInterruptController, XIN_REAL_MODE );
269
}
270
/*-----------------------------------------------------------*/
271
 
272
portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
273
{
274
portBASE_TYPE xReturn = pdFAIL;
275
 
276
        /* This function is defined here so the scope of xInterruptController can
277
        remain within this file. */
278
 
279
        if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
280
        {
281
                XIntc_Enable( &xInterruptController, ucInterruptID );
282
                xReturn = pdPASS;
283
        }
284
 
285
        return xReturn;
286
}

powered by: WebSVN 2.1.0

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