1/* 2 * File : context_gcc.S 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2006-2011, 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-02-14 aozima first implementation for Nios II. 13 * 2011-02-20 aozima fix context&switch bug. 14 */ 15 16/** 17 * @addtogroup NIOS_II 18 */ 19/*@{*/ 20 21.text 22 23.set noat 24 25/* 26 * rt_base_t rt_hw_interrupt_disable(); 27 */ 28.global rt_hw_interrupt_disable 29.type rt_hw_interrupt_disable, %function 30rt_hw_interrupt_disable: 31 rdctl r2, status /* return status */ 32 wrctl status, zero /* disable interrupt */ 33 ret 34 35/* 36 * void rt_hw_interrupt_enable(rt_base_t level); 37 */ 38.global rt_hw_interrupt_enable 39.type rt_hw_interrupt_enable, %function 40rt_hw_interrupt_enable: 41 wrctl status, r4 /* enable interrupt by argument */ 42 ret 43 44/* void rt_hw_context_switch_interrupt_do(void) */ 45.global rt_hw_context_switch_interrupt_do 46.type rt_hw_context_switch_interrupt_do, %function 47rt_hw_context_switch_interrupt_do: 48 /* save from thread */ 49 addi sp,sp,-72 50 51 /* frist save r2,so that save status */ 52 stw r2, 4(sp) 53 54 /* save status */ 55 /* when the interrupt happen,the interrupt is enable */ 56 movi r2, 1 57 stw r2, 68(sp) /* status */ 58 59 stw r3, 8(sp) 60 stw r4, 12(sp) 61 62 /* get & save from thread pc */ 63 ldw r4,%gprel(rt_current_thread_entry)(gp) 64 stw r4, 0(sp) /* thread pc */ 65 66 stw r5, 16(sp) 67 stw r6, 20(sp) 68 stw r7, 24(sp) 69 70 stw r16, 28(sp) 71 stw r17, 32(sp) 72 stw r18, 36(sp) 73 stw r19, 40(sp) 74 stw r20, 44(sp) 75 stw r21, 48(sp) 76 stw r22, 52(sp) 77 stw r23, 56(sp) 78 79 stw fp, 60(sp) 80 stw ra, 64(sp) 81 82 /* save from thread sp */ 83 /* rt_interrupt_from_thread = &from_thread->sp */ 84 ldw r4, %gprel(rt_interrupt_from_thread)(gp) 85 /* *r4(from_thread->sp) = sp */ 86 stw sp, (r4) 87 88 /* clear rt_thread_switch_interrupt_flag */ 89 /* rt_thread_switch_interrupt_flag = 0 */ 90 stw zero,%gprel(rt_thread_switch_interrupt_flag)(gp) 91 92 /* load to thread sp */ 93 /* r4 = rt_interrupt_to_thread(&to_thread->sp) */ 94 ldw r4, %gprel(rt_interrupt_to_thread)(gp) 95 /* sp = to_thread->sp */ 96 ldw sp, (r4) 97 98 ldw r2, 68(sp) /* status */ 99 wrctl estatus, r2 100 101 ldw ea, 0(sp) /* thread pc */ 102 ldw r2, 4(sp) 103 ldw r3, 8(sp) 104 ldw r4, 12(sp) 105 ldw r5, 16(sp) 106 ldw r6, 20(sp) 107 ldw r7, 24(sp) 108 109 ldw r16, 28(sp) 110 ldw r17, 32(sp) 111 ldw r18, 36(sp) 112 ldw r19, 40(sp) 113 ldw r20, 44(sp) 114 ldw r21, 48(sp) 115 ldw r22, 52(sp) 116 ldw r23, 56(sp) 117 118 ldw fp, 60(sp) 119 ldw ra, 64(sp) 120 121 addi sp, sp, 72 122 123 /* estatus --> status,ea --> pc */ 124 eret 125 126/* 127 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); 128 * r4: from 129 * r5: to 130 */ 131.global rt_hw_context_switch 132.type rt_hw_context_switch, %function 133rt_hw_context_switch: 134 /* save from thread */ 135 addi sp,sp,-72 136 137 /* frist save r2,so that save status */ 138 stw r2, 4(sp) 139 140 /* save status */ 141 rdctl r2, status 142 stw r2, 68(sp) /* status */ 143 144 stw ra, 0(sp) /* return from rt_hw_context_switch */ 145 stw r3, 8(sp) 146 stw r4, 12(sp) 147 stw r5, 16(sp) 148 stw r6, 20(sp) 149 stw r7, 24(sp) 150 151 stw r16, 28(sp) 152 stw r17, 32(sp) 153 stw r18, 36(sp) 154 stw r19, 40(sp) 155 stw r20, 44(sp) 156 stw r21, 48(sp) 157 stw r22, 52(sp) 158 stw r23, 56(sp) 159 160 stw fp, 60(sp) 161 stw ra, 64(sp) 162 163 /* save form thread sp */ 164 /* from_thread->sp(r4) = sp */ 165 stw sp, (r4) 166 167 /* update rt_interrupt_from_thread */ 168 /* rt_interrupt_from_thread = r4(from_thread->sp) */ 169 stw r4,%gprel(rt_interrupt_from_thread)(gp) 170 171 /* update rt_interrupt_to_thread */ 172 /* rt_interrupt_to_thread = r5 */ 173 stw r5,%gprel(rt_interrupt_to_thread)(gp) 174 175 /* get to thread sp */ 176 /* sp = rt_interrupt_to_thread(r5:to_thread->sp) */ 177 ldw sp, (r5) 178 179 ldw r2, 68(sp) /* status */ 180 wrctl estatus, r2 181 182 ldw ea, 0(sp) /* thread pc */ 183 184 ldw r2, 4(sp) 185 ldw r3, 8(sp) 186 ldw r4, 12(sp) 187 ldw r5, 16(sp) 188 ldw r6, 20(sp) 189 ldw r7, 24(sp) 190 191 ldw r16, 28(sp) 192 ldw r17, 32(sp) 193 ldw r18, 36(sp) 194 ldw r19, 40(sp) 195 ldw r20, 44(sp) 196 ldw r21, 48(sp) 197 ldw r22, 52(sp) 198 ldw r23, 56(sp) 199 200 ldw fp, 60(sp) 201 ldw ra, 64(sp) 202 203 addi sp, sp, 72 204 205 /* estatus --> status,ea --> pc */ 206 eret 207 208/* 209 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); 210 * r4: from 211 * r5: to 212 */ 213.global rt_hw_context_switch_interrupt 214.type rt_hw_context_switch_interrupt, %function 215rt_hw_context_switch_interrupt: 216 /* if( rt_thread_switch_interrupt_flag != 0 ) _from_thread_not_change */ 217 ldw r2,%gprel(rt_thread_switch_interrupt_flag)(gp) 218 bne r2,zero,_from_thread_not_change 219 220_from_thread_change: 221 /* save ea -> rt_current_thread_entry */ 222 addi ea,ea,-4 223 stw ea,%gprel(rt_current_thread_entry)(gp) 224 225 /* set rt_thread_switch_interrupt_flag to 1 */ 226 movi r2, 1 227 stw r2,%gprel(rt_thread_switch_interrupt_flag)(gp) 228 229 /* update rt_interrupt_from_thread */ 230 stw r4,%gprel(rt_interrupt_from_thread)(gp) 231 232_from_thread_not_change: 233 /* update rt_interrupt_to_thread */ 234 stw r5,%gprel(rt_interrupt_to_thread)(gp) 235 236 ret 237 238/* 239 * void rt_hw_context_switch_to(rt_uint32 to); 240 * r4: to 241 */ 242.global rt_hw_context_switch_to 243.type rt_hw_context_switch_to, %function 244rt_hw_context_switch_to: 245 /* save to thread */ 246 stw r4,%gprel(rt_interrupt_to_thread)(gp) 247 248 /* get sp */ 249 ldw sp, (r4) // sp = *r4 250 251 ldw r2, 68(sp) /* status */ 252 wrctl estatus, r2 253 254 ldw ea, 0(sp) /* thread entry */ 255 256 ldw r2, 4(sp) 257 ldw r3, 8(sp) 258 ldw r4, 12(sp) 259 ldw r5, 16(sp) 260 ldw r6, 20(sp) 261 ldw r7, 24(sp) 262 263 ldw r16, 28(sp) 264 ldw r17, 32(sp) 265 ldw r18, 36(sp) 266 ldw r19, 40(sp) 267 ldw r20, 44(sp) 268 ldw r21, 48(sp) 269 ldw r22, 52(sp) 270 ldw r23, 56(sp) 271 272 ldw fp, 60(sp) 273 ldw ra, 64(sp) 274 275 addi sp, sp, 72 276 277 /* estatus --> status,ea --> pc */ 278 eret 279 280/*@}*/ 281