xref: /nrf52832-nimble/rt-thread/libcpu/arm/AT91SAM7S/context_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero/*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date           Author       Notes
8*10465441SEvalZero * 2006-03-13     Bernard      first version
9*10465441SEvalZero */
10*10465441SEvalZero
11*10465441SEvalZero#define NOINT			0xc0
12*10465441SEvalZero
13*10465441SEvalZero/*
14*10465441SEvalZero * rt_base_t rt_hw_interrupt_disable()/*
15*10465441SEvalZero */
16*10465441SEvalZero.globl rt_hw_interrupt_disable
17*10465441SEvalZerort_hw_interrupt_disable:
18*10465441SEvalZero	mrs r0, cpsr
19*10465441SEvalZero	orr r1, r0, #NOINT
20*10465441SEvalZero	msr cpsr_c, r1
21*10465441SEvalZero	mov pc, lr
22*10465441SEvalZero
23*10465441SEvalZero/*
24*10465441SEvalZero * void rt_hw_interrupt_enable(rt_base_t level)/*
25*10465441SEvalZero */
26*10465441SEvalZero.globl rt_hw_interrupt_enable
27*10465441SEvalZerort_hw_interrupt_enable:
28*10465441SEvalZero	msr cpsr, r0
29*10465441SEvalZero	mov pc, lr
30*10465441SEvalZero
31*10465441SEvalZero/*
32*10465441SEvalZero * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
33*10465441SEvalZero * r0 --> from
34*10465441SEvalZero * r1 --> to
35*10465441SEvalZero */
36*10465441SEvalZero.globl rt_hw_context_switch
37*10465441SEvalZerort_hw_context_switch:
38*10465441SEvalZero	stmfd	sp!, {lr}			/* push pc (lr should be pushed in place of PC) */
39*10465441SEvalZero	stmfd	sp!, {r0-r12, lr}	/* push lr & register file */
40*10465441SEvalZero
41*10465441SEvalZero	mrs		r4, cpsr
42*10465441SEvalZero	stmfd	sp!, {r4}			/* push cpsr */
43*10465441SEvalZero	mrs		r4, spsr
44*10465441SEvalZero	stmfd	sp!, {r4}			/* push spsr */
45*10465441SEvalZero
46*10465441SEvalZero	str		sp, [r0]			/* store sp in preempted tasks TCB */
47*10465441SEvalZero	ldr		sp, [r1]			/* get new task stack pointer */
48*10465441SEvalZero
49*10465441SEvalZero	ldmfd	sp!, {r4}			/* pop new task spsr */
50*10465441SEvalZero	msr		spsr_cxsf, r4
51*10465441SEvalZero	ldmfd	sp!, {r4}			/* pop new task cpsr */
52*10465441SEvalZero	msr		cpsr_cxsf, r4
53*10465441SEvalZero
54*10465441SEvalZero	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
55*10465441SEvalZero
56*10465441SEvalZero/*
57*10465441SEvalZero * void rt_hw_context_switch_to(rt_uint32 to)/*
58*10465441SEvalZero * r0 --> to
59*10465441SEvalZero */
60*10465441SEvalZero.globl rt_hw_context_switch_to
61*10465441SEvalZerort_hw_context_switch_to:
62*10465441SEvalZero	ldr		sp, [r0]			/* get new task stack pointer */
63*10465441SEvalZero
64*10465441SEvalZero	ldmfd	sp!, {r4}			/* pop new task spsr */
65*10465441SEvalZero	msr		spsr_cxsf, r4
66*10465441SEvalZero	ldmfd	sp!, {r4}			/* pop new task cpsr */
67*10465441SEvalZero	msr		cpsr_cxsf, r4
68*10465441SEvalZero
69*10465441SEvalZero	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
70*10465441SEvalZero
71*10465441SEvalZero/*
72*10465441SEvalZero * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
73*10465441SEvalZero */
74*10465441SEvalZero.globl rt_thread_switch_interrupt_flag
75*10465441SEvalZero.globl rt_interrupt_from_thread
76*10465441SEvalZero.globl rt_interrupt_to_thread
77*10465441SEvalZero.globl rt_hw_context_switch_interrupt
78*10465441SEvalZerort_hw_context_switch_interrupt:
79*10465441SEvalZero	ldr		r2, =rt_thread_switch_interrupt_flag
80*10465441SEvalZero	ldr		r3, [r2]
81*10465441SEvalZero	cmp		r3, #1
82*10465441SEvalZero	beq		_reswitch
83*10465441SEvalZero	mov		r3, #1							/* set rt_thread_switch_interrupt_flag to 1 */
84*10465441SEvalZero	str		r3, [r2]
85*10465441SEvalZero	ldr		r2, =rt_interrupt_from_thread	/* set rt_interrupt_from_thread */
86*10465441SEvalZero	str		r0, [r2]
87*10465441SEvalZero_reswitch:
88*10465441SEvalZero	ldr		r2, =rt_interrupt_to_thread		/* set rt_interrupt_to_thread */
89*10465441SEvalZero	str		r1, [r2]
90*10465441SEvalZero	mov		pc, lr
91