1*10465441SEvalZero/* 2*10465441SEvalZero * File : context.S 3*10465441SEvalZero * This file is part of RT-Thread RTOS 4*10465441SEvalZero * COPYRIGHT (C) 2010, 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 * 2010-03-27 Kyle First version 13*10465441SEvalZero */ 14*10465441SEvalZero 15*10465441SEvalZero#define AVR32_SR 0 16*10465441SEvalZero#define AVR32_SR_GM_OFFSET 16 17*10465441SEvalZero 18*10465441SEvalZero.text 19*10465441SEvalZero 20*10465441SEvalZero/* 21*10465441SEvalZero * rt_base_t rt_hw_interrupt_disable() 22*10465441SEvalZero */ 23*10465441SEvalZero.globl rt_hw_interrupt_disable 24*10465441SEvalZero.type rt_hw_interrupt_disable, %function 25*10465441SEvalZerort_hw_interrupt_disable: 26*10465441SEvalZero ssrf AVR32_SR_GM_OFFSET 27*10465441SEvalZero mov pc, lr 28*10465441SEvalZero 29*10465441SEvalZero/* 30*10465441SEvalZero * void rt_hw_interrupt_enable(rt_base_t level) 31*10465441SEvalZero */ 32*10465441SEvalZero.globl rt_hw_interrupt_enable 33*10465441SEvalZero.type rt_hw_interrupt_enable, %function 34*10465441SEvalZerort_hw_interrupt_enable: 35*10465441SEvalZero csrf AVR32_SR_GM_OFFSET 36*10465441SEvalZero mov pc, lr 37*10465441SEvalZero 38*10465441SEvalZero/* 39*10465441SEvalZero * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/* 40*10465441SEvalZero * r8 --> from 41*10465441SEvalZero * r9 --> to 42*10465441SEvalZero */ 43*10465441SEvalZero.globl rt_hw_context_switch 44*10465441SEvalZero.type rt_hw_context_switch, %function 45*10465441SEvalZerort_hw_context_switch: 46*10465441SEvalZero ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */ 47*10465441SEvalZero stm --sp, r8-r12, lr /* Push R8-R12, LR */ 48*10465441SEvalZero st.w --sp, lr /* Push LR (instead of PC) */ 49*10465441SEvalZero mfsr r8, AVR32_SR /* Read Status Register */ 50*10465441SEvalZero cbr r8, AVR32_SR_GM_OFFSET /* Clear GM bit */ 51*10465441SEvalZero st.w --sp, r8 /* Push SR */ 52*10465441SEvalZero stm --sp, r0-r7 /* Push R0-R7 */ 53*10465441SEvalZero /* Stack layout: R8-R12, LR, PC, SR, R0-R7 */ 54*10465441SEvalZero 55*10465441SEvalZero st.w r12[0], sp /* Store SP in preempted tasks TCB */ 56*10465441SEvalZero ld.w sp, r11[0] /* Get new task stack pointer */ 57*10465441SEvalZero 58*10465441SEvalZero ldm sp++, r0-r7 /* pop R0-R7 */ 59*10465441SEvalZero ld.w r8, sp++ /* pop SR */ 60*10465441SEvalZero mtsr AVR32_SR, r8 /* Restore SR */ 61*10465441SEvalZero ldm sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume to thread */ 62*10465441SEvalZero 63*10465441SEvalZero/* 64*10465441SEvalZero * void rt_hw_context_switch_to(rt_uint32 to)/* 65*10465441SEvalZero * r0 --> to 66*10465441SEvalZero */ 67*10465441SEvalZero.globl rt_hw_context_switch_to 68*10465441SEvalZero.type rt_hw_context_switch_to, %function 69*10465441SEvalZerort_hw_context_switch_to: 70*10465441SEvalZero ld.w sp, r12[0] /* Get new task stack pointer */ 71*10465441SEvalZero 72*10465441SEvalZero ldm sp++, r0-r7 /* pop R0-R7 */ 73*10465441SEvalZero ld.w r8, sp++ /* pop SR */ 74*10465441SEvalZero mtsr AVR32_SR, r8 /* Restore SR */ 75*10465441SEvalZero ldm sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume execution */ 76*10465441SEvalZero 77*10465441SEvalZero/* 78*10465441SEvalZero * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/* 79*10465441SEvalZero */ 80*10465441SEvalZero.globl rt_thread_switch_interrupt_flag 81*10465441SEvalZero.globl rt_interrupt_from_thread 82*10465441SEvalZero.globl rt_interrupt_to_thread 83*10465441SEvalZero.globl rt_hw_context_switch_interrupt 84*10465441SEvalZero.type rt_hw_context_switch_interrupt, %function 85*10465441SEvalZerort_hw_context_switch_interrupt: 86*10465441SEvalZero lda.w r8, rt_thread_switch_interrupt_flag 87*10465441SEvalZero ld.w r9, r8[0] 88*10465441SEvalZero cp.w r9, 1 89*10465441SEvalZero breq _reswitch 90*10465441SEvalZero mov r9, 1 91*10465441SEvalZero st.w r8[0], r9 92*10465441SEvalZero lda.w r8, rt_interrupt_from_thread 93*10465441SEvalZero st.w r8[0], r12 94*10465441SEvalZero_reswitch: 95*10465441SEvalZero lda.w r8, rt_interrupt_to_thread 96*10465441SEvalZero st.w r8[0], r11 97*10465441SEvalZero mov pc, lr 98