98 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * File      : context.S
 | |
|  * This file is part of RT-Thread RTOS
 | |
|  * COPYRIGHT (C) 2010, RT-Thread Development Team
 | |
|  *
 | |
|  * The license and distribution terms for this file may be
 | |
|  * found in the file LICENSE in this distribution or at
 | |
|  * http://www.rt-thread.org/license/LICENSE
 | |
|  *
 | |
|  * Change Logs:
 | |
|  * Date           Author       Notes
 | |
|  * 2010-03-27     Kyle         First version
 | |
|  */
 | |
| 
 | |
| #define AVR32_SR			0
 | |
| #define AVR32_SR_GM_OFFSET	16
 | |
| 
 | |
| .text
 | |
| 
 | |
| /*
 | |
|  * rt_base_t rt_hw_interrupt_disable()
 | |
|  */
 | |
| .globl rt_hw_interrupt_disable
 | |
| .type rt_hw_interrupt_disable, %function
 | |
| rt_hw_interrupt_disable:
 | |
| 	ssrf	AVR32_SR_GM_OFFSET
 | |
| 	mov		pc, lr
 | |
| 
 | |
| /*
 | |
|  * void rt_hw_interrupt_enable(rt_base_t level)
 | |
|  */
 | |
| .globl rt_hw_interrupt_enable
 | |
| .type rt_hw_interrupt_enable, %function
 | |
| rt_hw_interrupt_enable:
 | |
| 	csrf	AVR32_SR_GM_OFFSET
 | |
| 	mov		pc, lr
 | |
| 
 | |
| /*
 | |
|  * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
 | |
|  * r8 --> from
 | |
|  * r9 --> to
 | |
|  */
 | |
| .globl rt_hw_context_switch
 | |
| .type rt_hw_context_switch, %function
 | |
| rt_hw_context_switch:
 | |
| 	ssrf	AVR32_SR_GM_OFFSET	/* Disable global interrupt */
 | |
| 	stm		--sp, r8-r12, lr	/* Push R8-R12, LR */
 | |
| 	st.w	--sp, lr			/* Push LR (instead of PC) */
 | |
| 	mfsr	r8, AVR32_SR		/* Read Status Register */
 | |
| 	cbr		r8, AVR32_SR_GM_OFFSET	/* Clear GM bit */
 | |
| 	st.w	--sp, r8			/* Push SR */
 | |
| 	stm		--sp, r0-r7			/* Push R0-R7 */
 | |
| 								/* Stack layout: R8-R12, LR, PC, SR, R0-R7 */
 | |
| 
 | |
| 	st.w	r12[0], sp			/* Store SP in preempted tasks TCB */
 | |
| 	ld.w	sp, r11[0]			/* Get new task stack pointer */
 | |
| 
 | |
| 	ldm		sp++, r0-r7			/* pop R0-R7 */
 | |
| 	ld.w	r8, sp++			/* pop SR */
 | |
| 	mtsr	AVR32_SR, r8		/* Restore SR */
 | |
| 	ldm		sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume to thread */
 | |
| 
 | |
| /*
 | |
|  * void rt_hw_context_switch_to(rt_uint32 to)/*
 | |
|  * r0 --> to
 | |
|  */
 | |
| .globl rt_hw_context_switch_to
 | |
| .type rt_hw_context_switch_to, %function
 | |
| rt_hw_context_switch_to:
 | |
| 	ld.w	sp, r12[0]			/* Get new task stack pointer */
 | |
| 
 | |
| 	ldm		sp++, r0-r7			/* pop R0-R7 */
 | |
| 	ld.w	r8, sp++			/* pop SR */
 | |
| 	mtsr	AVR32_SR, r8		/* Restore SR */
 | |
| 	ldm		sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume execution */
 | |
| 
 | |
| /*
 | |
|  * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
 | |
|  */
 | |
| .globl rt_thread_switch_interrupt_flag
 | |
| .globl rt_interrupt_from_thread
 | |
| .globl rt_interrupt_to_thread
 | |
| .globl rt_hw_context_switch_interrupt
 | |
| .type rt_hw_context_switch_interrupt, %function
 | |
| rt_hw_context_switch_interrupt:
 | |
| 	lda.w	r8, rt_thread_switch_interrupt_flag
 | |
| 	ld.w	r9, r8[0]
 | |
| 	cp.w	r9, 1
 | |
| 	breq	_reswitch
 | |
| 	mov		r9, 1
 | |
| 	st.w	r8[0], r9
 | |
| 	lda.w	r8, rt_interrupt_from_thread
 | |
| 	st.w	r8[0], r12
 | |
| _reswitch:
 | |
| 	lda.w	r8, rt_interrupt_to_thread
 | |
| 	st.w	r8[0], r11
 | |
| 	mov		pc, lr
 |