xref: /nrf52832-nimble/rt-thread/libcpu/ia32/context_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
1/*
2 * File      : context_gcc.S
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2006, RT-Thread Development Team
5 *
6 * The license and distribution terms for this file may be
7 * found in the file LICENSE in this distribution or at
8 * http://www.rt-thread.org/license/LICENSE
9 *
10 * Change Logs:
11 * Date           Author       Notes
12 * 2006-09-15     QiuYi        The first version
13 * 2006-10-09     Bernard      add rt_hw_context_switch_to implementation
14 */
15
16 /**
17 * @addtogroup ia32
18 */
19/*@{*/
20
21/*
22 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
23 */
24.globl rt_hw_context_switch
25rt_hw_context_switch:
26	pushfl					/*pushed eflags*/
27/*
28 *	add by [email protected] 2009-10-14
29 *      When we return again the esp should no be change.
30 * 	The old code change the esp to esp-4 :-(.
31 *	A protection fault maybe occure for img created by some compiler,eg.gcc in the fedor-11
32 *      -------------------------------------------------------------------------
33 *	entry			old code			new code
34 *	EIP	->return esp	EIP				FLAGS ->return esp
35 *	...			FLAGS    ->retern esp		CS
36 *				CS				EIP
37 *				EIP
38 */
39	popl %eax	/*get flags*/
40	popl %ebx	/*get eip*/
41	pushl %eax	/*push flags*/
42	push %cs	/*push cs*/
43	pushl %ebx	/*push eip*/
44
45/*-------------------------------------------------------------------
46 */
47
48	/*push %cs*/				/*push cs register*/
49	/*pushl 0x8(%esp)*/			/*pushed eip register*/
50
51	pushl $0				/*fill irqno*/
52	push %ds				/*push ds register*/
53	push %es				/*push es register*/
54	pushal					/*push eax,ecx,edx,ebx,esp,ebp,esp,edi registers*/
55
56	/*movl 0x40(%esp), %eax*/	/*to thread TCB*/
57	/*movl 0x3c(%esp), %ebx*/	/*from thread TCB*/
58	movl 0x3c(%esp), %eax	/*to thread TCB*/
59	movl 0x38(%esp), %ebx	/*from thread TCB*/
60
61	movl %esp, (%ebx)		/*store esp in preempted tasks TCB*/
62	movl (%eax), %esp		/*get new task stack pointer*/
63
64	popal					/*restore new task TCB*/
65	pop %es
66	pop %ds
67	add $4,%esp				/*skip irqno*/
68	iret
69
70/*
71 * void rt_hw_context_switch_to(rt_uint32 to);
72 */
73.globl rt_hw_context_switch_to
74rt_hw_context_switch_to:
75	push %ebp
76	movl %esp, %ebp
77
78	movl 0x8(%ebp), %eax	/* to thread TCB */
79	movl (%eax), %esp		/* get new task stack pointer */
80
81	popal					/* restore new task TCB*/
82	pop %es
83	pop %ds
84	add $4, %esp			/* skip irqno */
85	iret
86
87/*
88 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
89 */
90.globl rt_thread_switch_interrupt_flag
91.globl rt_interrupt_from_thread
92.globl rt_interrupt_to_thread
93.globl rt_hw_context_switch_interrupt
94rt_hw_context_switch_interrupt:
95	pushl %ebp
96	movl %esp, %ebp
97	movl 0xc(%ebp), %eax
98	movl 0x8(%ebp), %ebx
99
100	movl $rt_thread_switch_interrupt_flag, %ecx
101	movl (%ecx), %edx
102	cmp $0x1, %edx
103	jz _reswitch
104
105	movl $0x1, %edx				/*set rt_thread_switch_interrupt_flag to 1*/
106	movl %edx, (%ecx)
107	movl $rt_interrupt_from_thread, %edx	/*set rt_interrupt_from_thread*/
108	movl %ebx, (%edx)
109_reswitch:
110	movl $rt_interrupt_to_thread, %edx		/*set rt_interrupt_to_thread*/
111	movl %eax, (%edx)
112	leave
113	ret
114