1/*
2 * PROJECT:     ReactOS API Tests
3 * LICENSE:     LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE:     x64 ASM helper functions for syscall tests
5 * COPYRIGHT:   Copyright 2024 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8#include <asm.inc>
9#include <ksamd64.inc>
10
11.data
12g_Rcx:
13    .quad 0
14g_SegSs:
15    .short 0
16
17.code64
18
19EXTERN RtlCaptureContext:PROC
20EXTERN g_NoopSyscallNumber:DWORD
21
22#define STACK_ARGUMENT_SPACE 16*8
23
24LoadContext:
25    push qword ptr [rcx + CxEFlags]
26    popfq
27    movdqu xmm0, [rcx + CxXmm0]
28    movdqu xmm1, [rcx + CxXmm1]
29    movdqu xmm2, [rcx + CxXmm2]
30    movdqu xmm3, [rcx + CxXmm3]
31    movdqu xmm4, [rcx + CxXmm4]
32    movdqu xmm5, [rcx + CxXmm5]
33    movdqu xmm6, [rcx + CxXmm6]
34    movdqu xmm7, [rcx + CxXmm7]
35    movdqu xmm8, [rcx + CxXmm8]
36    movdqu xmm9, [rcx + CxXmm9]
37    movdqu xmm10, [rcx + CxXmm10]
38    movdqu xmm11, [rcx + CxXmm11]
39    movdqu xmm12, [rcx + CxXmm12]
40    movdqu xmm13, [rcx + CxXmm13]
41    movdqu xmm14, [rcx + CxXmm14]
42    movdqu xmm15, [rcx + CxXmm15]
43    mov rax, [rcx + CxRax]
44    mov rbx, [rcx + CxRbx]
45    mov rdx, [rcx + CxRdx]
46    mov rsi, [rcx + CxRsi]
47    mov rdi, [rcx + CxRdi]
48    mov rbp, [rcx + CxRbp]
49    mov r8, [rcx + CxR8]
50    mov r9, [rcx + CxR9]
51    mov r10, [rcx + CxR10]
52    mov r11, [rcx + CxR11]
53    mov r12, [rcx + CxR12]
54    mov r13, [rcx + CxR13]
55    mov r14, [rcx + CxR14]
56    mov r15, [rcx + CxR15]
57    //mov rcx, [rcx + CxRcx]
58
59    mov ax, [rcx + CxSegDs]
60    mov ds, ax
61    mov ax, [rcx + CxSegEs]
62    mov es, ax
63    mov ax, [rcx + CxSegFs]
64    mov fs, ax
65    mov ax, [rcx + CxSegGs]
66    //mov gs, ax // FIXME: ReactOS does not like this
67
68    ret
69
70PUBLIC SyscallReturn
71
72.PROC DoSyscallAndCaptureContext2
73    /* Allocate enough space for the system call handler */
74    sub rsp, STACK_ARGUMENT_SPACE + 5*8
75    .ALLOCSTACK STACK_ARGUMENT_SPACE + 5*8
76    .ENDPROLOG
77
78    /* Save rcx and r8 in the home space */
79    mov [rsp + STACK_ARGUMENT_SPACE + 6*8], rcx
80    mov [rsp + STACK_ARGUMENT_SPACE + 8*8], r8
81
82    /* Load the pre-context */
83    mov rcx, rdx
84    call LoadContext
85    call RtlCaptureContext
86
87    mov ax, word ptr [rcx + CxSegSs]
88    mov ss, ax
89
90    /* Do the syscall */
91    mov rax, [rsp + STACK_ARGUMENT_SPACE + 6*8]
92    syscall
93
94GLOBAL_LABEL SyscallReturn
95
96    /* Save returned ss */
97    mov qword ptr g_Rcx[rip], rcx
98    mov cx, ss
99    mov word ptr g_SegSs[rip], cx
100
101    mov cx, HEX(2B)
102    mov ss, cx
103
104    /* Save the post-context */
105    mov rcx, [rsp + STACK_ARGUMENT_SPACE + 8*8]
106    call RtlCaptureContext
107
108    mov rcx, qword ptr g_Rcx[rip]
109    mov rax, [rsp + STACK_ARGUMENT_SPACE + 8*8]
110    mov [rax + CxRcx], rcx
111
112    mov ax, HEX(2B)
113    mov ds, ax
114    mov es, ax
115    //mov gs, ax // FIXME: ReactOS does not like this
116    mov ss, ax
117    mov ax, HEX(53)
118    mov fs, ax
119
120    cld
121
122    mov rcx, [rsp + STACK_ARGUMENT_SPACE + 8*8]
123    mov ax, word ptr g_SegSs[rip]
124    mov [rcx + CxSegSs], ax
125
126    add rsp, STACK_ARGUMENT_SPACE + 5*8
127    ret
128.ENDP
129
130/*
131 * VOID
132 * DoSyscallAndCaptureContext(
133 *     _In_ ULONG64 SyscallNumber,
134 *     _Out_ PCONTEXT PreContext,
135 *     _Out_ PCONTEXT PostContext);
136 */
137PUBLIC DoSyscallAndCaptureContext
138.PROC DoSyscallAndCaptureContext
139    GENERATE_EXCEPTION_FRAME
140
141    call DoSyscallAndCaptureContext2
142
143    RESTORE_EXCEPTION_STATE
144    ret
145
146.ENDP
147
148/*
149 * ULONG64
150 * DoSyscallWithUnalignedStack(
151 *     _In_ ULONG64 SyscallNumber);
152 */
153PUBLIC DoSyscallWithUnalignedStack
154.PROC DoSyscallWithUnalignedStack
155    /* Allocate enough space for the system call handler */
156    sub rsp, STACK_ARGUMENT_SPACE + 6*8
157    .ALLOCSTACK STACK_ARGUMENT_SPACE + 6*8
158    .ENDPROLOG
159
160    mov rax, rcx
161    syscall
162
163    add rsp, STACK_ARGUMENT_SPACE + 6*8
164    ret
165.ENDP
166
167END
168