]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/NiosII/port_asm.S
467dd25e1741d64b11e5e7747bd7320007d5b559
[freertos] / FreeRTOS / Source / portable / GCC / NiosII / port_asm.S
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2020 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.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 .extern         vTaskSwitchContext\r
29         \r
30 .set noat\r
31 \r
32 # Exported to start the first task.\r
33 .globl restore_sp_from_pxCurrentTCB             \r
34         \r
35 # Entry point for exceptions.\r
36 .section .exceptions.entry, "xa"                \r
37 \r
38 # Save the entire context of a task.\r
39 save_context:\r
40         addi    ea, ea, -4                      # Point to the next instruction.\r
41         addi    sp,     sp, -116                # Create space on the stack.\r
42         stw             ra, 0(sp)\r
43                                                                 # Leave a gap for muldiv 0\r
44         stw             at, 8(sp)                \r
45         stw             r2, 12(sp)\r
46         stw             r3, 16(sp)\r
47         stw             r4, 20(sp)\r
48         stw             r5, 24(sp) \r
49         stw             r6, 28(sp) \r
50         stw             r7, 32(sp) \r
51         stw             r8, 36(sp) \r
52         stw             r9, 40(sp) \r
53         stw             r10, 44(sp)\r
54         stw             r11, 48(sp)\r
55         stw             r12, 52(sp)\r
56         stw             r13, 56(sp)\r
57         stw             r14, 60(sp)\r
58         stw             r15, 64(sp)\r
59         rdctl   r5, estatus             # Save the eStatus\r
60         stw             r5, 68(sp)\r
61         stw             ea, 72(sp)                      # Save the PC\r
62         stw             r16, 76(sp)                     # Save the remaining registers\r
63         stw             r17, 80(sp)\r
64         stw             r18, 84(sp)\r
65         stw             r19, 88(sp)\r
66         stw             r20, 92(sp)\r
67         stw             r21, 96(sp)\r
68         stw             r22, 100(sp)\r
69         stw             r23, 104(sp)\r
70         stw             gp, 108(sp)\r
71         stw             fp, 112(sp)\r
72 \r
73 save_sp_to_pxCurrentTCB:\r
74         movia   et, pxCurrentTCB        # Load the address of the pxCurrentTCB pointer\r
75         ldw             et, (et)                        # Load the value of the pxCurrentTCB pointer\r
76         stw             sp, (et)                        # Store the stack pointer into the top of the TCB\r
77         \r
78         .section .exceptions.irqtest, "xa"      \r
79 hw_irq_test:\r
80         /*\r
81      * Test to see if the exception was a software exception or caused \r
82      * by an external interrupt, and vector accordingly.\r
83      */\r
84     rdctl       r4, ipending            # Load the Pending Interrupts indication\r
85         rdctl   r5, estatus             # Load the eStatus (enabled interrupts).\r
86     andi        r2, r5, 1                       # Are interrupts enabled globally.\r
87     beq         r2, zero, soft_exceptions               # Interrupts are not enabled.\r
88     beq         r4, zero, soft_exceptions               # There are no interrupts triggered.\r
89 \r
90         .section .exceptions.irqhandler, "xa"\r
91 hw_irq_handler:\r
92         call    alt_irq_handler                                 # Call the alt_irq_handler to deliver to the registered interrupt handler.\r
93 \r
94     .section .exceptions.irqreturn, "xa"\r
95 restore_sp_from_pxCurrentTCB:\r
96         movia   et, pxCurrentTCB                # Load the address of the pxCurrentTCB pointer\r
97         ldw             et, (et)                                # Load the value of the pxCurrentTCB pointer\r
98         ldw             sp, (et)                                # Load the stack pointer with the top value of the TCB\r
99 \r
100 restore_context:\r
101         ldw             ra, 0(sp)               # Restore the registers.\r
102                                                         # Leave a gap for muldiv 0.\r
103         ldw             at, 8(sp)\r
104         ldw             r2, 12(sp)\r
105         ldw             r3, 16(sp)\r
106         ldw             r4, 20(sp)\r
107         ldw             r5, 24(sp) \r
108         ldw             r6, 28(sp) \r
109         ldw             r7, 32(sp) \r
110         ldw             r8, 36(sp) \r
111         ldw             r9, 40(sp) \r
112         ldw             r10, 44(sp)\r
113         ldw             r11, 48(sp)\r
114         ldw             r12, 52(sp)\r
115         ldw             r13, 56(sp)\r
116         ldw             r14, 60(sp)\r
117         ldw             r15, 64(sp)\r
118         ldw             et, 68(sp)              # Load the eStatus\r
119         wrctl   estatus, et     # Write the eStatus\r
120         ldw             ea, 72(sp)              # Load the Program Counter\r
121         ldw             r16, 76(sp)\r
122         ldw             r17, 80(sp)\r
123         ldw             r18, 84(sp)\r
124         ldw             r19, 88(sp)\r
125         ldw             r20, 92(sp)\r
126         ldw             r21, 96(sp)\r
127         ldw             r22, 100(sp)\r
128         ldw             r23, 104(sp)\r
129         ldw             gp, 108(sp)\r
130         ldw             fp, 112(sp)\r
131         addi    sp,     sp, 116         # Release stack space\r
132 \r
133     eret                                        # Return to address ea, loading eStatus into Status.\r
134    \r
135         .section .exceptions.soft, "xa"\r
136 soft_exceptions:\r
137         ldw             et, 0(ea)                               # Load the instruction where the interrupt occured.\r
138         movhi   at, %hi(0x003B683A)             # Load the registers with the trap instruction code\r
139         ori             at, at, %lo(0x003B683A)\r
140         cmpne   et, et, at                              # Compare the trap instruction code to the last excuted instruction\r
141         beq             et, r0, call_scheduler  # its a trap so switchcontext\r
142         break                                                   # This is an un-implemented instruction or muldiv problem.\r
143         br              restore_context                 # its something else\r
144 \r
145 call_scheduler:\r
146         addi    ea, ea, 4                                               # A trap was called, increment the program counter so it is not called again.\r
147         stw             ea, 72(sp)                                              # Save the new program counter to the context.\r
148         call    vTaskSwitchContext                              # Pick the next context.\r
149         br              restore_sp_from_pxCurrentTCB    # Switch in the task context and restore. \r