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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 572 jeremybenn
/*
2
    FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
3
    MCF5235 Port - Copyright (C) 2006 Christian Walter.
4
 
5
    This file is part of the FreeRTOS distribution.
6
 
7
    FreeRTOS is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License** as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version.
11
 
12
    FreeRTOS is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with FreeRTOS; if not, write to the Free Software
19
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
21
    A special exception to the GPL can be applied should you wish to distribute
22
    a combined work that includes FreeRTOS, without being obliged to provide
23
    the source code for any proprietary components.  See the licensing section
24
    of http://www.FreeRTOS.org for full details of how and when the exception
25
    can be applied.
26
 
27
    ***************************************************************************
28
    ***************************************************************************
29
    *                                                                         *
30
    * Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *
31
        *                                                                         *
32
        * This is a concise, step by step, 'hands on' guide that describes both   *
33
        * general multitasking concepts and FreeRTOS specifics. It presents and   *
34
        * explains numerous examples that are written using the FreeRTOS API.     *
35
        * Full source code for all the examples is provided in an accompanying    *
36
        * .zip file.                                                              *
37
    *                                                                         *
38
    ***************************************************************************
39
    ***************************************************************************
40
 
41
        Please ensure to read the configuration and relevant port sections of the
42
        online documentation.
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 <stdlib.h>
55
 
56
#include "FreeRTOS.h"
57
#include "FreeRTOSConfig.h"
58
#include "task.h"
59
 
60
/* ------------------------ Types ----------------------------------------- */
61
typedef volatile unsigned long vuint32;
62
typedef volatile unsigned short vuint16;
63
typedef volatile unsigned char vuint8;
64
 
65
/* ------------------------ Defines --------------------------------------- */
66
#define portVECTOR_TABLE                __RAMVEC
67
#define portVECTOR_SYSCALL              ( 32 + portTRAP_YIELD )
68
#define portVECTOR_TIMER                ( 64 + 36 )
69
 
70
#define MCF_PIT_PRESCALER               512UL
71
#define MCF_PIT_TIMER_TICKS             ( FSYS_2 / MCF_PIT_PRESCALER )
72
#define MCF_PIT_MODULUS_REGISTER(freq)  ( MCF_PIT_TIMER_TICKS / ( freq ) - 1UL)
73
 
74
#define MCF_PIT_PMR0                    ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150002 ] ) )
75
#define MCF_PIT_PCSR0                   ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150000 ] ) )
76
#define MCF_PIT_PCSR_PRE(x)             ( ( ( x ) & 0x000F ) << 8 )
77
#define MCF_PIT_PCSR_EN                 ( 0x0001 )
78
#define MCF_PIT_PCSR_RLD                ( 0x0002 )
79
#define MCF_PIT_PCSR_PIF                ( 0x0004 )
80
#define MCF_PIT_PCSR_PIE                ( 0x0008 )
81
#define MCF_PIT_PCSR_OVW                ( 0x0010 )
82
#define MCF_INTC0_ICR36                 ( *( vuint8 * )( void * )( &__IPSBAR[ 0x000C64 ] ) )
83
#define MCF_INTC0_IMRH                  ( *( vuint32 * )( void * )( &__IPSBAR[ 0x000C08 ] ) )
84
#define MCF_INTC0_IMRH_INT_MASK36       ( 0x00000010 )
85
#define MCF_INTC0_IMRH_MASKALL          ( 0x00000001 )
86
#define MCF_INTC0_ICRn_IP(x)            ( ( ( x ) & 0x07 ) << 0 )
87
#define MCF_INTC0_ICRn_IL(x)            ( ( ( x ) & 0x07 ) << 3 )
88
 
89
#define portNO_CRITICAL_NESTING         ( ( unsigned long ) 0 )
90
#define portINITIAL_CRITICAL_NESTING    ( ( unsigned long ) 10 )
91
 
92
/* ------------------------ Static variables ------------------------------ */
93
volatile unsigned long              ulCriticalNesting = portINITIAL_CRITICAL_NESTING;
94
 
95
/* ------------------------ Static functions ------------------------------ */
96
#if configUSE_PREEMPTION == 0
97
static void prvPortPreemptiveTick ( void ) __attribute__ ((interrupt_handler));
98
#else
99
static void prvPortPreemptiveTick ( void );
100
#endif
101
 
102
/* ------------------------ Start implementation -------------------------- */
103
 
104
portSTACK_TYPE *
105
pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode,
106
                       void *pvParameters )
107
{
108
    /* Place the parameter on the stack in the expected location. */
109
    *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
110
    pxTopOfStack--;
111
 
112
    /* Place dummy return address on stack. Tasks should never terminate so
113
     * we can set this to anything. */
114
    *pxTopOfStack = ( portSTACK_TYPE ) 0;
115
    pxTopOfStack--;
116
 
117
    /* Create a Motorola Coldfire exception stack frame. First comes the return
118
     * address. */
119
    *pxTopOfStack = ( portSTACK_TYPE ) pxCode;
120
    pxTopOfStack--;
121
 
122
    /* Format, fault-status, vector number for exception stack frame. Task
123
     * run in supervisor mode. */
124
    *pxTopOfStack = 0x40002000UL | ( portVECTOR_SYSCALL + 32 ) << 18;
125
    pxTopOfStack--;
126
 
127
    /* Set the initial critical section nesting counter to zero. This value
128
     * is used to restore the value of ulCriticalNesting. */
129
    *pxTopOfStack = 0;
130
    *pxTopOfStack--;
131
 
132
    *pxTopOfStack = ( portSTACK_TYPE ) 0xA6;    /* A6 / FP */
133
    pxTopOfStack--;
134
    *pxTopOfStack = ( portSTACK_TYPE ) 0xA5;    /* A5 */
135
    pxTopOfStack--;
136
    *pxTopOfStack = ( portSTACK_TYPE ) 0xA4;    /* A4 */
137
    pxTopOfStack--;
138
    *pxTopOfStack = ( portSTACK_TYPE ) 0xA3;    /* A3 */
139
    pxTopOfStack--;
140
    *pxTopOfStack = ( portSTACK_TYPE ) 0xA2;    /* A2 */
141
    pxTopOfStack--;
142
    *pxTopOfStack = ( portSTACK_TYPE ) 0xA1;    /* A1 */
143
    pxTopOfStack--;
144
    *pxTopOfStack = ( portSTACK_TYPE ) 0xA0;    /* A0 */
145
    pxTopOfStack--;
146
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD7;    /* D7 */
147
    pxTopOfStack--;
148
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD6;    /* D6 */
149
    pxTopOfStack--;
150
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD5;    /* D5 */
151
    pxTopOfStack--;
152
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD4;    /* D4 */
153
    pxTopOfStack--;
154
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD3;    /* D3 */
155
    pxTopOfStack--;
156
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD2;    /* D2 */
157
    pxTopOfStack--;
158
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD1;    /* D1 */
159
    pxTopOfStack--;
160
    *pxTopOfStack = ( portSTACK_TYPE ) 0xD0;    /* D0 */
161
 
162
    return pxTopOfStack;
163
}
164
 
165
/*
166
 * Called by portYIELD() or taskYIELD() to manually force a context switch.
167
 */
168
static void
169
prvPortYield( void )
170
{
171
    asm volatile ( "move.w  #0x2700, %sr\n\t" );
172
#if _GCC_USES_FP == 1
173
    asm volatile ( "unlk %fp\n\t" );
174
#endif
175
     /* Perform the context switch.  First save the context of the current task. */
176
    portSAVE_CONTEXT(  );
177
 
178
    /* Find the highest priority task that is ready to run. */
179
    vTaskSwitchContext(  );
180
 
181
    /* Restore the context of the new task. */
182
    portRESTORE_CONTEXT(  );
183
}
184
 
185
#if configUSE_PREEMPTION == 0
186
/*
187
 * The ISR used for the scheduler tick depends on whether the cooperative or
188
 * the preemptive scheduler is being used.
189
 */
190
static void
191
prvPortPreemptiveTick ( void )
192
{
193
    /* The cooperative scheduler requires a normal IRQ service routine to
194
     * simply increment the system tick.
195
     */
196
 
197
    vTaskIncrementTick(  );
198
    MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
199
}
200
 
201
#else
202
 
203
static void
204
prvPortPreemptiveTick( void )
205
{
206
    asm volatile ( "move.w  #0x2700, %sr\n\t" );
207
#if _GCC_USES_FP == 1
208
    asm volatile ( "unlk %fp\n\t" );
209
#endif
210
    portSAVE_CONTEXT(  );
211
    MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
212
    vTaskIncrementTick(  );
213
    vTaskSwitchContext(  );
214
    portRESTORE_CONTEXT(  );
215
}
216
#endif
217
 
218
void
219
vPortEnterCritical()
220
{
221
    /* FIXME: We should store the old IPL here - How are we supposed to do
222
     * this.
223
     */
224
    ( void )portSET_IPL( portIPL_MAX );
225
 
226
    /* Now interrupts are disabled ulCriticalNesting can be accessed
227
     * directly.  Increment ulCriticalNesting to keep a count of how many times
228
     * portENTER_CRITICAL() has been called. */
229
    ulCriticalNesting++;
230
}
231
 
232
void
233
vPortExitCritical()
234
{
235
    if( ulCriticalNesting > portNO_CRITICAL_NESTING )
236
    {
237
        /* Decrement the nesting count as we are leaving a critical section. */
238
        ulCriticalNesting--;
239
 
240
        /* If the nesting level has reached zero then interrupts should be
241
        re-enabled. */
242
        if( ulCriticalNesting == portNO_CRITICAL_NESTING )
243
        {
244
            ( void )portSET_IPL( 0 );
245
        }
246
    }
247
}
248
 
249
portBASE_TYPE
250
xPortStartScheduler( void )
251
{
252
    extern void     ( *portVECTOR_TABLE[  ] ) (  );
253
 
254
    /* Add entry in vector table for yield system call. */
255
    portVECTOR_TABLE[ portVECTOR_SYSCALL ] = prvPortYield;
256
    /* Add entry in vector table for periodic timer. */
257
    portVECTOR_TABLE[ portVECTOR_TIMER ] = prvPortPreemptiveTick;
258
 
259
    /* Configure the timer for the system clock. */
260
    if ( configTICK_RATE_HZ > 0)
261
    {
262
        /* Configure prescaler */
263
        MCF_PIT_PCSR0 = MCF_PIT_PCSR_PRE( 0x9 ) | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_OVW;
264
        /* Initialize the periodic timer interrupt. */
265
        MCF_PIT_PMR0 = MCF_PIT_MODULUS_REGISTER( configTICK_RATE_HZ );
266
        /* Configure interrupt priority and level and unmask interrupt. */
267
        MCF_INTC0_ICR36 = MCF_INTC0_ICRn_IL( 0x1 ) | MCF_INTC0_ICRn_IP( 0x1 );
268
        MCF_INTC0_IMRH &= ~( MCF_INTC0_IMRH_INT_MASK36 | MCF_INTC0_IMRH_MASKALL );
269
        /* Enable interrupts */
270
        MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_EN | MCF_PIT_PCSR_PIF;
271
    }
272
 
273
    /* Restore the context of the first task that is going to run. */
274
    portRESTORE_CONTEXT(  );
275
 
276
    /* Should not get here. */
277
    return pdTRUE;
278
}
279
 
280
void
281
vPortEndScheduler( void )
282
{
283
}

powered by: WebSVN 2.1.0

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