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