]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/NiosII/port_asm.S
212859fdedcfaf733b4f9ea74010eb26cfc7f977
[freertos] / FreeRTOS / Source / portable / GCC / NiosII / port_asm.S
1 /*\r
2     FreeRTOS V7.5.3 - Copyright (C) 2013 Real Time Engineers Ltd. \r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS provides completely free yet professionally developed,    *\r
10      *    robust, strictly quality controlled, supported, and cross          *\r
11      *    platform software that has become a de facto standard.             *\r
12      *                                                                       *\r
13      *    Help yourself get started quickly and support the FreeRTOS         *\r
14      *    project by purchasing a FreeRTOS tutorial book, reference          *\r
15      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
16      *                                                                       *\r
17      *    Thank you!                                                         *\r
18      *                                                                       *\r
19     ***************************************************************************\r
20 \r
21     This file is part of the FreeRTOS distribution.\r
22 \r
23     FreeRTOS is free software; you can redistribute it and/or modify it under\r
24     the terms of the GNU General Public License (version 2) as published by the\r
25     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
26 \r
27     >>! NOTE: The modification to the GPL is included to allow you to distribute\r
28     >>! a combined work that includes FreeRTOS without being obliged to provide\r
29     >>! the source code for proprietary components outside of the FreeRTOS\r
30     >>! kernel.\r
31 \r
32     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
33     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
34     FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
35     link: http://www.freertos.org/a00114.html\r
36 \r
37     1 tab == 4 spaces!\r
38 \r
39     ***************************************************************************\r
40      *                                                                       *\r
41      *    Having a problem?  Start by reading the FAQ "My application does   *\r
42      *    not run, what could be wrong?"                                     *\r
43      *                                                                       *\r
44      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
49     license and Real Time Engineers Ltd. contact details.\r
50 \r
51     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
52     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
53     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
54 \r
55     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
56     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
57     licenses offer ticketed support, indemnification and middleware.\r
58 \r
59     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
60     engineered and independently SIL3 certified version for use in safety and\r
61     mission critical applications that require provable dependability.\r
62 \r
63     1 tab == 4 spaces!\r
64 */\r
65 \r
66 .extern         vTaskSwitchContext\r
67         \r
68 .set noat\r
69 \r
70 # Exported to start the first task.\r
71 .globl restore_sp_from_pxCurrentTCB             \r
72         \r
73 # Entry point for exceptions.\r
74 .section .exceptions.entry, "xa"                \r
75 \r
76 # Save the entire context of a task.\r
77 save_context:\r
78         addi    ea, ea, -4                      # Point to the next instruction.\r
79         addi    sp,     sp, -116                # Create space on the stack.\r
80         stw             ra, 0(sp)\r
81                                                                 # Leave a gap for muldiv 0\r
82         stw             at, 8(sp)                \r
83         stw             r2, 12(sp)\r
84         stw             r3, 16(sp)\r
85         stw             r4, 20(sp)\r
86         stw             r5, 24(sp) \r
87         stw             r6, 28(sp) \r
88         stw             r7, 32(sp) \r
89         stw             r8, 36(sp) \r
90         stw             r9, 40(sp) \r
91         stw             r10, 44(sp)\r
92         stw             r11, 48(sp)\r
93         stw             r12, 52(sp)\r
94         stw             r13, 56(sp)\r
95         stw             r14, 60(sp)\r
96         stw             r15, 64(sp)\r
97         rdctl   r5, estatus             # Save the eStatus\r
98         stw             r5, 68(sp)\r
99         stw             ea, 72(sp)                      # Save the PC\r
100         stw             r16, 76(sp)                     # Save the remaining registers\r
101         stw             r17, 80(sp)\r
102         stw             r18, 84(sp)\r
103         stw             r19, 88(sp)\r
104         stw             r20, 92(sp)\r
105         stw             r21, 96(sp)\r
106         stw             r22, 100(sp)\r
107         stw             r23, 104(sp)\r
108         stw             gp, 108(sp)\r
109         stw             fp, 112(sp)\r
110 \r
111 save_sp_to_pxCurrentTCB:\r
112         movia   et, pxCurrentTCB        # Load the address of the pxCurrentTCB pointer\r
113         ldw             et, (et)                        # Load the value of the pxCurrentTCB pointer\r
114         stw             sp, (et)                        # Store the stack pointer into the top of the TCB\r
115         \r
116         .section .exceptions.irqtest, "xa"      \r
117 hw_irq_test:\r
118         /*\r
119      * Test to see if the exception was a software exception or caused \r
120      * by an external interrupt, and vector accordingly.\r
121      */\r
122     rdctl       r4, ipending            # Load the Pending Interrupts indication\r
123         rdctl   r5, estatus             # Load the eStatus (enabled interrupts).\r
124     andi        r2, r5, 1                       # Are interrupts enabled globally.\r
125     beq         r2, zero, soft_exceptions               # Interrupts are not enabled.\r
126     beq         r4, zero, soft_exceptions               # There are no interrupts triggered.\r
127 \r
128         .section .exceptions.irqhandler, "xa"\r
129 hw_irq_handler:\r
130         call    alt_irq_handler                                 # Call the alt_irq_handler to deliver to the registered interrupt handler.\r
131 \r
132     .section .exceptions.irqreturn, "xa"\r
133 restore_sp_from_pxCurrentTCB:\r
134         movia   et, pxCurrentTCB                # Load the address of the pxCurrentTCB pointer\r
135         ldw             et, (et)                                # Load the value of the pxCurrentTCB pointer\r
136         ldw             sp, (et)                                # Load the stack pointer with the top value of the TCB\r
137 \r
138 restore_context:\r
139         ldw             ra, 0(sp)               # Restore the registers.\r
140                                                         # Leave a gap for muldiv 0.\r
141         ldw             at, 8(sp)\r
142         ldw             r2, 12(sp)\r
143         ldw             r3, 16(sp)\r
144         ldw             r4, 20(sp)\r
145         ldw             r5, 24(sp) \r
146         ldw             r6, 28(sp) \r
147         ldw             r7, 32(sp) \r
148         ldw             r8, 36(sp) \r
149         ldw             r9, 40(sp) \r
150         ldw             r10, 44(sp)\r
151         ldw             r11, 48(sp)\r
152         ldw             r12, 52(sp)\r
153         ldw             r13, 56(sp)\r
154         ldw             r14, 60(sp)\r
155         ldw             r15, 64(sp)\r
156         ldw             et, 68(sp)              # Load the eStatus\r
157         wrctl   estatus, et     # Write the eStatus\r
158         ldw             ea, 72(sp)              # Load the Program Counter\r
159         ldw             r16, 76(sp)\r
160         ldw             r17, 80(sp)\r
161         ldw             r18, 84(sp)\r
162         ldw             r19, 88(sp)\r
163         ldw             r20, 92(sp)\r
164         ldw             r21, 96(sp)\r
165         ldw             r22, 100(sp)\r
166         ldw             r23, 104(sp)\r
167         ldw             gp, 108(sp)\r
168         ldw             fp, 112(sp)\r
169         addi    sp,     sp, 116         # Release stack space\r
170 \r
171     eret                                        # Return to address ea, loading eStatus into Status.\r
172    \r
173         .section .exceptions.soft, "xa"\r
174 soft_exceptions:\r
175         ldw             et, 0(ea)                               # Load the instruction where the interrupt occured.\r
176         movhi   at, %hi(0x003B683A)             # Load the registers with the trap instruction code\r
177         ori             at, at, %lo(0x003B683A)\r
178         cmpne   et, et, at                              # Compare the trap instruction code to the last excuted instruction\r
179         beq             et, r0, call_scheduler  # its a trap so switchcontext\r
180         break                                                   # This is an un-implemented instruction or muldiv problem.\r
181         br              restore_context                 # its something else\r
182 \r
183 call_scheduler:\r
184         addi    ea, ea, 4                                               # A trap was called, increment the program counter so it is not called again.\r
185         stw             ea, 72(sp)                                              # Save the new program counter to the context.\r
186         call    vTaskSwitchContext                              # Pick the next context.\r
187         br              restore_sp_from_pxCurrentTCB    # Switch in the task context and restore. \r