1/* 2 * File : context_vdsp.S 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2009 - 2012, 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 * 2012-02-13 mojingxian First version 13 */ 14 15.global _rt_hw_interrupt_disable; 16.global _rt_hw_interrupt_enable; 17.global _interrupt_thread_switch; 18 19.extern _rt_interrupt_from_thread; 20.extern _rt_interrupt_to_thread; 21.extern _rt_thread_switch_interrupt_flag; 22 23.section/DOUBLE64 program; 24 25/* 26 * rt_base_t rt_hw_interrupt_disable(); 27 * return value in R0. 28 */ 29_rt_hw_interrupt_disable: 30 CLI R0; 31 32_rt_hw_interrupt_disable.end: 33 NOP; 34 NOP; 35 NOP; 36 RTS; 37 38/* 39 * void rt_hw_interrupt_enable(rt_base_t level); 40 * R0->level 41 */ 42_rt_hw_interrupt_enable: 43 STI R0; 44 45_rt_hw_interrupt_enable.end: 46 NOP; 47 NOP; 48 NOP; 49 RTS; 50 51_interrupt_thread_switch: 52 /* Save context, interrupts disabled by IPEND[4] bit */ 53 [ -- SP ] = R0; 54 [ -- SP ] = P1; 55 [ -- SP ] = RETS; 56 [ -- SP ] = R1; 57 [ -- SP ] = R2; 58 [ -- SP ] = P0; 59 [ -- SP ] = P2; 60 [ -- SP ] = ASTAT; 61 R1 = RETI; /* IPEND[4] is currently set, globally disabling interrupts */ 62 /* IPEND[4] will stay set when RETI is saved through R1 */ 63 64 [ -- SP ] = R1; 65 [ -- SP ] = (R7:3, P5:3); 66 [ -- SP ] = FP; 67 [ -- SP ] = I0; 68 [ -- SP ] = I1; 69 [ -- SP ] = I2; 70 [ -- SP ] = I3; 71 [ -- SP ] = B0; 72 [ -- SP ] = B1; 73 [ -- SP ] = B2; 74 [ -- SP ] = B3; 75 [ -- SP ] = L0; 76 [ -- SP ] = L1; 77 [ -- SP ] = L2; 78 [ -- SP ] = L3; 79 [ -- SP ] = M0; 80 [ -- SP ] = M1; 81 [ -- SP ] = M2; 82 [ -- SP ] = M3; 83 R1.L = A0.x; 84 [ -- SP ] = R1; 85 R1 = A0.w; 86 [ -- SP ] = R1; 87 R1.L = A1.x; 88 [ -- SP ] = R1; 89 R1 = A1.w; 90 [ -- SP ] = R1; 91 [ -- SP ] = LC0; 92 R3 = 0; 93 LC0 = R3; 94 [ -- SP ] = LC1; 95 R3 = 0; 96 LC1 = R3; 97 [ -- SP ] = LT0; 98 [ -- SP ] = LT1; 99 [ -- SP ] = LB0; 100 [ -- SP ] = LB1; 101 102 /* Context save done so save SP in the TCB */ 103 P1.h = _rt_interrupt_from_thread; 104 P1.l = _rt_interrupt_from_thread; 105 P2 = [ P1 ]; 106 [ P2 ] = SP; 107 108 /* clear rt_thread_switch_interrupt_flag to 0 */ 109 P1.h = _rt_thread_switch_interrupt_flag; 110 P1.l = _rt_thread_switch_interrupt_flag; 111 R0 = 0; 112 [ P1 ] = R0; 113 114 /* Get a pointer to the high ready task's TCB */ 115 P1.h = _rt_interrupt_to_thread; 116 P1.l = _rt_interrupt_to_thread; 117 P2 = [ P1 ]; 118 SP = [ P2 ]; 119 120 /* Restoring CPU context and return to task */ 121 LB1 = [ SP ++ ]; 122 LB0 = [ SP ++ ]; 123 LT1 = [ SP ++ ]; 124 LT0 = [ SP ++ ]; 125 LC1 = [ SP ++ ]; 126 LC0 = [ SP ++ ]; 127 R0 = [ SP ++ ]; 128 A1 = R0; 129 R0 = [ SP ++ ]; 130 A1.x = R0.L; 131 R0 = [ SP ++ ]; 132 A0 = R0; 133 R0 = [ SP ++ ]; 134 A0.x = R0.L; 135 M3 = [ SP ++ ]; 136 M2 = [ SP ++ ]; 137 M1 = [ SP ++ ]; 138 M0 = [ SP ++ ]; 139 L3 = [ SP ++ ]; 140 L2 = [ SP ++ ]; 141 L1 = [ SP ++ ]; 142 L0 = [ SP ++ ]; 143 B3 = [ SP ++ ]; 144 B2 = [ SP ++ ]; 145 B1 = [ SP ++ ]; 146 B0 = [ SP ++ ]; 147 I3 = [ SP ++ ]; 148 I2 = [ SP ++ ]; 149 I1 = [ SP ++ ]; 150 I0 = [ SP ++ ]; 151 FP = [ SP ++ ]; 152 (R7:3, P5:3) = [ SP ++ ]; 153 RETI = [ SP ++ ]; /* IPEND[4] will stay set when RETI popped from stack */ 154 ASTAT = [ SP ++ ]; 155 P2 = [ SP ++ ]; 156 P0 = [ SP ++ ]; 157 R2 = [ SP ++ ]; 158 R1 = [ SP ++ ]; 159 RETS = [ SP ++ ]; 160 P1 = [ SP ++ ]; 161 R0 = [ SP ++ ]; 162 163_interrupt_thread_switch.end: 164 RTI; 165 166