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