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