123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /*
- * 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*/
- /*
- * add by ssslady@gmail.com 2009-10-14
- * When we return again the esp should no be change.
- * The old code change the esp to esp-4 :-(.
- * A protection fault maybe occure for img created by some compiler,eg.gcc in the fedor-11
- * -------------------------------------------------------------------------
- * entry old code new code
- * EIP ->return esp EIP FLAGS ->return esp
- * ... FLAGS ->retern esp CS
- * CS EIP
- * EIP
- */
- popl %eax /*get flags*/
- popl %ebx /*get eip*/
- pushl %eax /*push flags*/
- push %cs /*push cs*/
- pushl %ebx /*push eip*/
-
- /*-------------------------------------------------------------------
- */
- /*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 0x3c(%esp), %eax /*to thread TCB*/
- movl 0x38(%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
|