1/* 2 * File : context_gcc.S 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2006, RT-Thread Development Team 5 * 6 * The license and distribution terms for this file may be 7 * found in the file LICENSE in this distribution or at 8 * http://www.rt-thread.org/license/LICENSE 9 * 10 * Change Logs: 11 * Date Author Notes 12 * 2011-12-17 nl1031 first implementation for MicroBlaze. 13 * 14 */ 15 16#include "microblaze.inc" 17 18 .text 19 .globl rt_interrupt_enter 20 .globl rt_interrupt_leave 21 22/* 23 * rt_base_t rt_hw_interrupt_disable() 24 * copy from ucos-ii 25 */ 26 27 .globl rt_hw_interrupt_disable 28 .ent rt_hw_interrupt_disable 29 .align 2 30rt_hw_interrupt_disable: 31 ADDIK r1, r1, -4 32 SW r4, r1, r0 33 34 MFS r3, RMSR 35 ANDNI r4, r3, IE_BIT 36 MTS RMSR, r4 37 38 LW r4, r1, r0 39 ADDIK r1, r1, 4 40 41 AND r0, r0, r0 /* NO-OP - pipeline flush */ 42 AND r0, r0, r0 /* NO-OP - pipeline flush */ 43 AND r0, r0, r0 /* NO-OP - pipeline flush */ 44 45 RTSD r15, 8 46 AND r0, r0, r0 47 .end rt_hw_interrupt_disable 48 49/* 50 * void rt_hw_interrupt_enable(rt_base_t level) 51 * copy from ucos-ii 52 */ 53 .globl rt_hw_interrupt_enable 54 .ent rt_hw_interrupt_enable 55 .align 2 56rt_hw_interrupt_enable: 57 RTSD r15, 8 58 MTS rMSR, r5 /* Move the saved status from r5 into rMSR */ 59 .end rt_hw_interrupt_enable 60 61/* 62 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) 63 * r5 --> from 64 * r6 --> to 65 */ 66 67 .globl rt_interrupt_from_thread 68 .globl rt_interrupt_to_thread 69 .globl rt_hw_context_switch 70 .ent rt_hw_context_switch 71 .align 2 72rt_hw_context_switch: 73 PUSH_ALL 74 MFS r3, RMSR /* save the MSR */ 75 SWI r3, r1, STACK_RMSR 76 SWI r1, r5, 0 /* store sp in preempted tasks TCB */ 77 LWI r1, r6, 0 /* get new task stack pointer */ 78 79 LWI r3, r1, STACK_RMSR 80 ANDI r3, r3, IE_BIT 81 BNEI r3, rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */ 82 83 LWI r3, r1, STACK_RMSR 84 MTS RMSR,r3 85 POP_ALL 86 ADDIK r1, r1, STACK_SIZE 87 RTSD r15, 8 88 AND r0, r0, r0 89 90rt_hw_context_switch_ie: 91 92 LWI r3, r1, STACK_RMSR 93 ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/ 94 MTS RMSR,r3 95 LWI r3, r1, STACK_R03 96 POP_ALL 97 ADDIK r1, r1, STACK_SIZE 98 RTID r14, 0 /* IE bit will be set automatically */ 99 AND r0, r0, r0 100 .end rt_hw_context_switch 101 102/* 103 * void rt_hw_context_switch_to(rt_uint32 to) 104 * r5 --> to 105 */ 106 .globl rt_hw_context_switch_to 107 .ent rt_hw_context_switch_to 108 .align 2 109rt_hw_context_switch_to: 110 LWI r1, r5, 0 /* get new task stack pointer */ 111 LWI r3, r1, STACK_RMSR 112 ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/ 113 MTS RMSR,r3 114 POP_ALL 115 ADDIK r1, r1, STACK_SIZE 116 RTID r14, 0 /* IE bit will be set automatically */ 117 AND r0, r0, r0 118 119 .end rt_hw_context_switch_to 120 121/* 122 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to) 123 */ 124 .globl rt_thread_switch_interrupt_flag 125 .globl rt_hw_context_switch_interrupt 126 .ent rt_hw_context_switch_interrupt 127 .align 2 128rt_hw_context_switch_interrupt: 129 LA r3, r0, rt_thread_switch_interrupt_flag 130 LWI r4, r3, 0 /* load rt_thread_switch_interrupt_flag into r4 */ 131 132 ANDI r4, r4, 1 133 BNEI r4, _reswitch /* if rt_thread_switch_interrupt_flag = 1 */ 134 135 ADDIK r4, r0, 1 /* set rt_thread_switch_interrupt_flag to 1 */ 136 SWI r4, r3, 0 137 138 LA r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ 139 SWI r5, r3, 0 /* rt_interrupt_from_thread = from */ 140_reswitch: 141 LA r3, r0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ 142 SWI r6, r3, 0 /* rt_interrupt_to_thread = to */ 143 RTSD r15, 8 144 AND r0, r0, r0 145 .end rt_hw_context_switch_interrupt 146 147 148 .globl _interrupt_handler 149 .section .text 150 .align 2 151 .ent _interrupt_handler 152 .type _interrupt_handler, @function 153 154_interrupt_handler: 155 PUSH_ALL 156 MFS r3, RMSR 157 ORI r3, r3, IE_BIT 158 SWI r3, r1, STACK_RMSR /* push MSR */ 159 160 BRLID r15, rt_interrupt_enter 161 AND r0, r0, r0 162 163 BRLID r15, rt_hw_trap_irq 164 AND r0, r0, r0 165 166 BRLID r15, rt_interrupt_leave 167 AND r0, r0, r0 168 169 /* 170 * if rt_thread_switch_interrupt_flag set, jump to 171 * rt_hw_context_switch_interrupt_do and don't return 172 */ 173 LA r3, r0, rt_thread_switch_interrupt_flag 174 LWI r4, r3, 0 175 176 ANDI r4, r4, 1 177 BNEI r4, rt_hw_context_switch_interrupt_do 178 179 LWI r3, r1, STACK_RMSR 180 ANDNI r3, r3, IE_BIT 181 MTS RMSR,r3 182 POP_ALL 183 ADDIK r1, r1, STACK_SIZE 184 185 RTID r14, 0 186 AND r0, r0, r0 187 188/* 189 * void rt_hw_context_switch_interrupt_do(rt_base_t flag) 190 */ 191rt_hw_context_switch_interrupt_do: 192 SWI r0, r3, 0 /* clear rt_thread_switch_interrupt_flag */ 193 194 LA r3, r0, rt_interrupt_from_thread 195 LW r4, r0, r3 196 SWI r1, r4, 0 /* store sp in preempted tasks's TCB */ 197 198 LA r3, r0, rt_interrupt_to_thread 199 LW r4, r0, r3 200 LWI r1, r4, 0 /* get new task's stack pointer */ 201 202 LWI r3, r1, STACK_RMSR 203 ANDI r3, r3, IE_BIT 204 BNEI r3, return_with_ie /*if IE bit set,should be use RTID (return from interrupt). */ 205 206 LWI r3, r1, STACK_RMSR 207 MTS RMSR,r3 208 POP_ALL 209 ADDIK r1, r1, STACK_SIZE 210 RTSD r15, 8 211 AND r0, r0, r0 212 213return_with_ie: 214 215 LWI r3, r1, STACK_RMSR 216 ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/ 217 MTS RMSR,r3 218 LWI r3, r1, STACK_R03 219 POP_ALL 220 ADDIK r1, r1, STACK_SIZE 221 RTID r14, 0 /* IE bit will be set automatically */ 222 AND r0, r0, r0 223 224.end _interrupt_handler 225 226