diff options
Diffstat (limited to 'libcpu/ia32/context.S')
| -rw-r--r-- | libcpu/ia32/context.S | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/libcpu/ia32/context.S b/libcpu/ia32/context.S new file mode 100644 index 0000000000..96ebda41cf --- /dev/null +++ b/libcpu/ia32/context.S @@ -0,0 +1,89 @@ +/* + * File : context.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-09-15 QiuYi The first version + * 2006-10-09 Bernard add rt_hw_context_switch_to implementation + */ + + /** + * @addtogroup ia32 + */ +/*@{*/ + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + pushfl /*pushed eflags*/ + push %cs /*push cs register*/ + pushl 0x8(%esp) /*pushed eip register*/ + pushl $0 /*fill irqno*/ + push %ds /*push ds register*/ + push %es /*push es register*/ + pushal /*push eax,ecx,edx,ebx,esp,ebp,esp,edi registers*/ + + movl 0x40(%esp), %eax /*to thread TCB*/ + movl 0x3c(%esp), %ebx /*from thread TCB*/ + + movl %esp, (%ebx) /*store esp in preempted tasks TCB*/ + movl (%eax), %esp /*get new task stack pointer*/ + + popal /*restore new task TCB*/ + pop %es + pop %ds + add $4,%esp /*skip irqno*/ + iret + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + push %ebp + movl %esp, %ebp + + movl 0x8(%ebp), %eax /* to thread TCB */ + movl (%eax), %esp /* get new task stack pointer */ + + popal /* restore new task TCB*/ + pop %es + pop %ds + add $4, %esp /* skip irqno */ + iret + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.globl rt_thread_switch_interrput_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + pushl %ebp + movl %esp, %ebp + movl 0xc(%ebp), %eax + movl 0x8(%ebp), %ebx + + movl $rt_thread_switch_interrput_flag, %ecx + movl (%ecx), %edx + cmp $0x1, %edx + jz _reswitch + + movl $0x1, %edx /*set rt_thread_switch_interrput_flag to 1*/ + movl %edx, (%ecx) + movl $rt_interrupt_from_thread, %edx /*set rt_interrupt_from_thread*/ + movl %ebx, (%edx) +_reswitch: + movl $rt_interrupt_to_thread, %edx /*set rt_interrupt_to_thread*/ + movl %eax, (%edx) + leave + ret |
