]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/NiosII/port.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Source / portable / GCC / NiosII / port.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /*-----------------------------------------------------------\r
30  * Implementation of functions defined in portable.h for the NIOS2 port.\r
31  *----------------------------------------------------------*/\r
32 \r
33 /* Standard Includes. */\r
34 #include <string.h>\r
35 #include <errno.h>\r
36 \r
37 /* Altera includes. */\r
38 #include "sys/alt_irq.h"\r
39 #include "altera_avalon_timer_regs.h"\r
40 #include "priv/alt_irq_table.h"\r
41 \r
42 /* Scheduler includes. */\r
43 #include "FreeRTOS.h"\r
44 #include "task.h"\r
45 \r
46 /* Interrupts are enabled. */\r
47 #define portINITIAL_ESTATUS     ( StackType_t ) 0x01 \r
48 \r
49 /*-----------------------------------------------------------*/\r
50 \r
51 /* \r
52  * Setup the timer to generate the tick interrupts.\r
53  */\r
54 static void prvSetupTimerInterrupt( void );\r
55 \r
56 /*\r
57  * Call back for the alarm function.\r
58  */\r
59 void vPortSysTickHandler( void * context, alt_u32 id );\r
60 \r
61 /*-----------------------------------------------------------*/\r
62 \r
63 static void prvReadGp( uint32_t *ulValue )\r
64 {\r
65         asm( "stw gp, (%0)" :: "r"(ulValue) );\r
66 }\r
67 /*-----------------------------------------------------------*/\r
68 \r
69 /* \r
70  * See header file for description. \r
71  */\r
72 StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )\r
73 {    \r
74 StackType_t *pxFramePointer = pxTopOfStack - 1;\r
75 StackType_t xGlobalPointer;\r
76 \r
77     prvReadGp( &xGlobalPointer ); \r
78 \r
79     /* End of stack marker. */\r
80     *pxTopOfStack = 0xdeadbeef;\r
81     pxTopOfStack--;\r
82     \r
83     *pxTopOfStack = ( StackType_t ) pxFramePointer; \r
84     pxTopOfStack--;\r
85     \r
86     *pxTopOfStack = xGlobalPointer; \r
87     \r
88     /* Space for R23 to R16. */\r
89     pxTopOfStack -= 9;\r
90 \r
91     *pxTopOfStack = ( StackType_t ) pxCode; \r
92     pxTopOfStack--;\r
93 \r
94     *pxTopOfStack = portINITIAL_ESTATUS; \r
95 \r
96     /* Space for R15 to R5. */    \r
97     pxTopOfStack -= 12;\r
98     \r
99     *pxTopOfStack = ( StackType_t ) pvParameters; \r
100 \r
101     /* Space for R3 to R1, muldiv and RA. */\r
102     pxTopOfStack -= 5;\r
103     \r
104     return pxTopOfStack;\r
105 }\r
106 /*-----------------------------------------------------------*/\r
107 \r
108 /* \r
109  * See header file for description. \r
110  */\r
111 BaseType_t xPortStartScheduler( void )\r
112 {\r
113         /* Start the timer that generates the tick ISR.  Interrupts are disabled\r
114         here already. */\r
115         prvSetupTimerInterrupt();\r
116         \r
117         /* Start the first task. */\r
118     asm volatile (  " movia r2, restore_sp_from_pxCurrentTCB        \n"\r
119                     " jmp r2                                          " );\r
120 \r
121         /* Should not get here! */\r
122         return 0;\r
123 }\r
124 /*-----------------------------------------------------------*/\r
125 \r
126 void vPortEndScheduler( void )\r
127 {\r
128         /* It is unlikely that the NIOS2 port will require this function as there\r
129         is nothing to return to.  */\r
130 }\r
131 /*-----------------------------------------------------------*/\r
132 \r
133 /*\r
134  * Setup the systick timer to generate the tick interrupts at the required\r
135  * frequency.\r
136  */\r
137 void prvSetupTimerInterrupt( void )\r
138 {\r
139         /* Try to register the interrupt handler. */\r
140         if ( -EINVAL == alt_irq_register( SYS_CLK_IRQ, 0x0, vPortSysTickHandler ) )\r
141         { \r
142                 /* Failed to install the Interrupt Handler. */\r
143                 asm( "break" );\r
144         }\r
145         else\r
146         {\r
147                 /* Configure SysTick to interrupt at the requested rate. */\r
148                 IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK );\r
149                 IOWR_ALTERA_AVALON_TIMER_PERIODL( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) & 0xFFFF );\r
150                 IOWR_ALTERA_AVALON_TIMER_PERIODH( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) >> 16 );\r
151                 IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_CONT_MSK | ALTERA_AVALON_TIMER_CONTROL_START_MSK | ALTERA_AVALON_TIMER_CONTROL_ITO_MSK );   \r
152         } \r
153 \r
154         /* Clear any already pending interrupts generated by the Timer. */\r
155         IOWR_ALTERA_AVALON_TIMER_STATUS( SYS_CLK_BASE, ~ALTERA_AVALON_TIMER_STATUS_TO_MSK );\r
156 }\r
157 /*-----------------------------------------------------------*/\r
158 \r
159 void vPortSysTickHandler( void * context, alt_u32 id )\r
160 {\r
161         /* Increment the kernel tick. */\r
162         if( xTaskIncrementTick() != pdFALSE )\r
163         {\r
164         vTaskSwitchContext();\r
165         }\r
166                 \r
167         /* Clear the interrupt. */\r
168         IOWR_ALTERA_AVALON_TIMER_STATUS( SYS_CLK_BASE, ~ALTERA_AVALON_TIMER_STATUS_TO_MSK );\r
169 }\r
170 /*-----------------------------------------------------------*/\r
171 \r
172 /** This function is a re-implementation of the Altera provided function.\r
173  * The function is re-implemented to prevent it from enabling an interrupt\r
174  * when it is registered. Interrupts should only be enabled after the FreeRTOS.org\r
175  * kernel has its scheduler started so that contexts are saved and switched \r
176  * correctly.\r
177  */\r
178 int alt_irq_register( alt_u32 id, void* context, void (*handler)(void*, alt_u32) )\r
179 {\r
180         int rc = -EINVAL;  \r
181         alt_irq_context status;\r
182 \r
183         if (id < ALT_NIRQ)\r
184         {\r
185                 /* \r
186                  * interrupts are disabled while the handler tables are updated to ensure\r
187                  * that an interrupt doesn't occur while the tables are in an inconsistent\r
188                  * state.\r
189                  */\r
190         \r
191                 status = alt_irq_disable_all ();\r
192         \r
193                 alt_irq[id].handler = handler;\r
194                 alt_irq[id].context = context;\r
195         \r
196                 rc = (handler) ? alt_irq_enable (id): alt_irq_disable (id);\r
197         \r
198                 /* alt_irq_enable_all(status); This line is removed to prevent the interrupt from being immediately enabled. */\r
199         }\r
200     \r
201         return rc; \r
202 }\r
203 /*-----------------------------------------------------------*/\r
204 \r