91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2006-2018, RT-Thread Development Team
 | |
|  *
 | |
|  * SPDX-License-Identifier: Apache-2.0
 | |
|  *
 | |
|  * Change Logs:
 | |
|  * Date           Author       Notes
 | |
|  * 2006-03-13     Bernard      first version
 | |
|  */
 | |
| 
 | |
| #define NOINT			0xc0
 | |
| 
 | |
| /*
 | |
|  * rt_base_t rt_hw_interrupt_disable()/*
 | |
|  */
 | |
| .globl rt_hw_interrupt_disable
 | |
| rt_hw_interrupt_disable:
 | |
| 	mrs r0, cpsr
 | |
| 	orr r1, r0, #NOINT
 | |
| 	msr cpsr_c, r1
 | |
| 	mov pc, lr
 | |
| 
 | |
| /*
 | |
|  * void rt_hw_interrupt_enable(rt_base_t level)/*
 | |
|  */
 | |
| .globl rt_hw_interrupt_enable
 | |
| rt_hw_interrupt_enable:
 | |
| 	msr cpsr, r0
 | |
| 	mov pc, lr
 | |
| 
 | |
| /*
 | |
|  * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
 | |
|  * r0 --> from
 | |
|  * r1 --> to
 | |
|  */
 | |
| .globl rt_hw_context_switch
 | |
| rt_hw_context_switch:
 | |
| 	stmfd	sp!, {lr}			/* push pc (lr should be pushed in place of PC) */
 | |
| 	stmfd	sp!, {r0-r12, lr}	/* push lr & register file */
 | |
| 
 | |
| 	mrs		r4, cpsr
 | |
| 	stmfd	sp!, {r4}			/* push cpsr */
 | |
| 	mrs		r4, spsr
 | |
| 	stmfd	sp!, {r4}			/* push spsr */
 | |
| 
 | |
| 	str		sp, [r0]			/* store sp in preempted tasks TCB */
 | |
| 	ldr		sp, [r1]			/* get new task stack pointer */
 | |
| 
 | |
| 	ldmfd	sp!, {r4}			/* pop new task spsr */
 | |
| 	msr		spsr_cxsf, r4
 | |
| 	ldmfd	sp!, {r4}			/* pop new task cpsr */
 | |
| 	msr		cpsr_cxsf, r4
 | |
| 
 | |
| 	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
 | |
| 
 | |
| /*
 | |
|  * void rt_hw_context_switch_to(rt_uint32 to)/*
 | |
|  * r0 --> to
 | |
|  */
 | |
| .globl rt_hw_context_switch_to
 | |
| rt_hw_context_switch_to:
 | |
| 	ldr		sp, [r0]			/* get new task stack pointer */
 | |
| 
 | |
| 	ldmfd	sp!, {r4}			/* pop new task spsr */
 | |
| 	msr		spsr_cxsf, r4
 | |
| 	ldmfd	sp!, {r4}			/* pop new task cpsr */
 | |
| 	msr		cpsr_cxsf, r4
 | |
| 
 | |
| 	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
 | |
| 
 | |
| /*
 | |
|  * 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
 | |
| rt_hw_context_switch_interrupt:
 | |
| 	ldr		r2, =rt_thread_switch_interrupt_flag
 | |
| 	ldr		r3, [r2]
 | |
| 	cmp		r3, #1
 | |
| 	beq		_reswitch
 | |
| 	mov		r3, #1							/* set rt_thread_switch_interrupt_flag to 1 */
 | |
| 	str		r3, [r2]
 | |
| 	ldr		r2, =rt_interrupt_from_thread	/* set rt_interrupt_from_thread */
 | |
| 	str		r0, [r2]
 | |
| _reswitch:
 | |
| 	ldr		r2, =rt_interrupt_to_thread		/* set rt_interrupt_to_thread */
 | |
| 	str		r1, [r2]
 | |
| 	mov		pc, lr
 |