1;/* 2; * Copyright (c) 2006-2021, RT-Thread Development Team 3; * 4; * SPDX-License-Identifier: Apache-2.0 5; * 6; * Change Logs: 7; * Date Author Notes 8; * 2011-08-14 weety copy from mini2440 9; * 2015-04-15 ArdaFu convert from context_gcc.s 10; */ 11 12#define NOINT 0xc0 13 14 SECTION .text:CODE(6) 15/* 16 * rt_base_t rt_hw_interrupt_disable(); 17 */ 18 PUBLIC rt_hw_interrupt_disable 19rt_hw_interrupt_disable: 20 MRS R0, CPSR 21 ORR R1, R0, #NOINT 22 MSR CPSR_C, R1 23 MOV PC, LR 24 25/* 26 * void rt_hw_interrupt_enable(rt_base_t level); 27 */ 28 PUBLIC rt_hw_interrupt_enable 29rt_hw_interrupt_enable: 30 MSR CPSR_CXSF, R0 31 MOV PC, LR 32 33/* 34 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); 35 * r0 --> from 36 * r1 --> to 37 */ 38 PUBLIC rt_hw_context_switch 39rt_hw_context_switch: 40 STMFD SP!, {LR} ; push pc (lr should be pushed in place of PC) 41 STMFD SP!, {R0-R12, LR} ; push lr & register file 42 MRS R4, CPSR 43 TST LR, #0x01 44 ORRNE R4, R4, #0x20 ; it's thumb code 45 STMFD SP!, {R4} ; push cpsr 46 STR SP, [R0] ; store sp in preempted tasks TCB 47 LDR SP, [R1] ; get new task stack pointer 48 LDMFD SP!, {R4} ; pop new task spsr 49 MSR SPSR_cxsf, R4 50 LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc 51 52/* 53 * void rt_hw_context_switch_to(rt_uint32 to); 54 * r0 --> to 55 */ 56 PUBLIC rt_hw_context_switch_to 57rt_hw_context_switch_to: 58 LDR SP, [R0] ; get new task stack pointer 59 LDMFD SP!, {R4} ; pop new task spsr 60 MSR SPSR_cxsf, R4 61 BIC R4, R4, #0x20 ; must be ARM mode 62 MSR CPSR_CXSF, R4 63 LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc 64 65/* 66 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); 67 */ 68 IMPORT rt_thread_switch_interrupt_flag 69 IMPORT rt_interrupt_from_thread 70 IMPORT rt_interrupt_to_thread 71 PUBLIC rt_hw_context_switch_interrupt 72rt_hw_context_switch_interrupt: 73 LDR R2, =rt_thread_switch_interrupt_flag 74 LDR R3, [R2] 75 CMP R3, #1 76 BEQ _reswitch 77 MOV R3, #1 ; set flag to 1 78 STR R3, [R2] 79 LDR R2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread 80 STR R0, [R2] 81_reswitch: 82 LDR R2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread 83 STR R1, [R2] 84 MOV PC, LR 85 END 86 87