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