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