1/* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: dll/win32/kernel32/client/i386/fiber.S 5 * PURPOSE: Fiber context switch code for the x86 architecture 6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) 7 * KJK::Hyperion <noog@libero.it> 8 */ 9 10#include <asm.inc> 11#include <ks386.inc> 12 13EXTERN _BaseThreadStartup@8:PROC 14 15.code 16 17PUBLIC _BaseFiberStartup@0 18FUNC _BaseFiberStartup@0 19 FPO 0, 0, 0, 0, 0, FRAME_FPO 20 21 /* Note that EBP is already zeroed for us during fiber creation */ 22 23 /* Get the fiber data */ 24 mov eax, fs:[TEB_FIBER_DATA] 25 26 /* Start the thread with our parameters */ 27 push dword ptr [eax+FIBER_CONTEXT_EBX] 28 push dword ptr [eax+FIBER_CONTEXT_EAX] 29 push 0 30 jmp _BaseThreadStartup@8 31 32ENDFUNC 33 34 35PUBLIC _SwitchToFiber@4 36FUNC _SwitchToFiber@4 37 FPO 0, 0, 0, 0, 0, FRAME_FPO 38 39 /* Get the TEB */ 40 mov edx, fs:[TEB_SELF] 41 42 /* Get the Fiber */ 43 mov eax, [edx+TEB_FIBER_DATA] 44 45 /* Save the non-volatile registers */ 46 mov [eax+FIBER_CONTEXT_EBX], ebx 47 mov [eax+FIBER_CONTEXT_ESI], esi 48 mov [eax+FIBER_CONTEXT_EDI], edi 49 mov [eax+FIBER_CONTEXT_EBP], ebp 50 51 /* Check if we're to save FPU State */ 52 cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT 53 jnz NoFpuStateSave 54 55 /* Save the FPU State (Status and Control)*/ 56 fstsw [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD] 57 fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] 58 59 /* Check if the CPU supports SIMD MXCSR State Save */ 60 cmp byte ptr ds:[USER_SHARED_DATA + USER_SHARED_DATA_PROCESSOR_FEATURES + PF_XMMI_INSTRUCTIONS_AVAILABLE], 1 61 jnz NoFpuStateSave 62 stmxcsr [eax+FIBER_CONTEXT_DR6] 63 64NoFpuStateSave: 65 66 /* Save stack since we're not touching it anymore */ 67 mov [eax+FIBER_CONTEXT_ESP], esp 68 69 /* Transfer some data from the TEB */ 70 mov ecx, [edx+TEB_FLS_DATA] 71 mov [eax+FIBER_FLS_DATA], ecx 72 mov ecx, [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER] 73 mov [eax+FIBER_ACTIVATION_CONTEXT_STACK], ecx 74 75 /* Transfer some data related to the Stack */ 76 mov ecx, [edx+TEB_EXCEPTION_LIST] 77 mov [eax+FIBER_EXCEPTION_LIST], ecx 78 mov ecx, [edx+TEB_STACK_LIMIT] 79 mov [eax+FIBER_STACK_LIMIT], ecx 80 mov ecx, [edx+TEB_GUARANTEED_STACK_BYTES] 81 mov [eax+FIBER_GUARANTEED_STACK_BYTES], ecx 82 83 /* Switch to the new fiber */ 84 mov ecx, [esp+4] 85 mov [edx+TEB_FIBER_DATA], ecx 86 87 /* Switch Fiber Data */ 88 mov esi, [ecx+FIBER_EXCEPTION_LIST] 89 mov [edx+TEB_EXCEPTION_LIST], esi 90 mov esi, [ecx+FIBER_STACK_BASE] 91 mov [edx+TEB_STACK_BASE], esi 92 mov esi, [ecx+FIBER_STACK_LIMIT] 93 mov [edx+TEB_STACK_LIMIT], esi 94 mov esi, [ecx+FIBER_DEALLOCATION_STACK] 95 mov [edx+TEB_DEALLOCATION_STACK], esi 96 mov esi, [ecx+FIBER_GUARANTEED_STACK_BYTES] 97 mov [edx+TEB_GUARANTEED_STACK_BYTES], esi 98 mov esi, [ecx+FIBER_ACTIVATION_CONTEXT_STACK] 99 mov [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER], esi 100 101 /* Restore FPU State */ 102 cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT 103 jnz NoFpuStateRestore 104 105 /* Check if the Status Word Changed */ 106 mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD] 107 cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD] 108 jnz StatusWordChanged 109 110 /* Check if the Control Word Changed */ 111 mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] 112 cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] 113 jz ControlWordEqual 114 115StatusWordChanged: 116 117 /* Load the new one */ 118 mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], HEX(FFFF) 119 fldenv [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] 120 121ControlWordEqual: 122 123 /* Load the new one */ 124 cmp byte ptr ds:[USER_SHARED_DATA + USER_SHARED_DATA_PROCESSOR_FEATURES + PF_XMMI_INSTRUCTIONS_AVAILABLE], 1 125 jnz NoFpuStateRestore 126 ldmxcsr [ecx+FIBER_CONTEXT_DR6] 127 128NoFpuStateRestore: 129 130 /* Restore non-volatile registers */ 131 mov esi, [ecx+FIBER_CONTEXT_ESI] 132 mov edi, [ecx+FIBER_CONTEXT_EDI] 133 mov ebx, [ecx+FIBER_CONTEXT_EBX] 134 mov ebp, [ecx+FIBER_CONTEXT_EBP] 135 mov esp, [ecx+FIBER_CONTEXT_ESP] 136 137 /* Restore FLS Data */ 138 mov eax, [ecx+FIBER_FLS_DATA] 139 mov [edx+TEB_FLS_DATA], eax 140 141 /* Jump to new fiber */ 142 mov esp, [ecx+FIBER_CONTEXT_ESP] 143 ret 4 144 145ENDFUNC 146 147END 148/* EOF */ 149