xref: /reactos/dll/win32/kernel32/client/i386/fiber.S (revision c2c66aff)
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