context_gcc.S 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2006-09-15 QiuYi The first version
  9. * 2006-10-09 Bernard add rt_hw_context_switch_to implementation
  10. */
  11. /**
  12. * @addtogroup ia32
  13. */
  14. /*@{*/
  15. /*
  16. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  17. */
  18. .globl rt_hw_context_switch
  19. rt_hw_context_switch:
  20. pushfl /*pushed eflags*/
  21. /*
  22. * add by ssslady@gmail.com 2009-10-14
  23. * When we return again the esp should no be change.
  24. * The old code change the esp to esp-4 :-(.
  25. * A protection fault maybe occure for img created by some compiler,eg.gcc in the fedor-11
  26. * -------------------------------------------------------------------------
  27. * entry old code new code
  28. * EIP ->return esp EIP FLAGS ->return esp
  29. * ... FLAGS ->retern esp CS
  30. * CS EIP
  31. * EIP
  32. */
  33. popl %eax /*get flags*/
  34. popl %ebx /*get eip*/
  35. pushl %eax /*push flags*/
  36. push %cs /*push cs*/
  37. pushl %ebx /*push eip*/
  38. /*-------------------------------------------------------------------
  39. */
  40. /*push %cs*/ /*push cs register*/
  41. /*pushl 0x8(%esp)*/ /*pushed eip register*/
  42. pushl $0 /*fill irqno*/
  43. push %ds /*push ds register*/
  44. push %es /*push es register*/
  45. pushal /*push eax,ecx,edx,ebx,esp,ebp,esp,edi registers*/
  46. /*movl 0x40(%esp), %eax*/ /*to thread TCB*/
  47. /*movl 0x3c(%esp), %ebx*/ /*from thread TCB*/
  48. movl 0x3c(%esp), %eax /*to thread TCB*/
  49. movl 0x38(%esp), %ebx /*from thread TCB*/
  50. movl %esp, (%ebx) /*store esp in preempted tasks TCB*/
  51. movl (%eax), %esp /*get new task stack pointer*/
  52. popal /*restore new task TCB*/
  53. pop %es
  54. pop %ds
  55. add $4,%esp /*skip irqno*/
  56. iret
  57. /*
  58. * void rt_hw_context_switch_to(rt_uint32 to);
  59. */
  60. .globl rt_hw_context_switch_to
  61. rt_hw_context_switch_to:
  62. push %ebp
  63. movl %esp, %ebp
  64. movl 0x8(%ebp), %eax /* to thread TCB */
  65. movl (%eax), %esp /* get new task stack pointer */
  66. popal /* restore new task TCB*/
  67. pop %es
  68. pop %ds
  69. add $4, %esp /* skip irqno */
  70. iret