[19] | 1 | ; $Id: EMAllA.asm 37955 2011-07-14 12:23:02Z vboxsync $
|
---|
[1] | 2 | ;; @file
|
---|
[15] | 3 | ; EM Assembly Routines.
|
---|
[1] | 4 | ;
|
---|
| 5 |
|
---|
[19] | 6 | ;
|
---|
[28800] | 7 | ; Copyright (C) 2006-2007 Oracle Corporation
|
---|
[4284] | 8 | ;
|
---|
[5999] | 9 | ; This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
| 10 | ; available from http://www.virtualbox.org. This file is free software;
|
---|
| 11 | ; you can redistribute it and/or modify it under the terms of the GNU
|
---|
| 12 | ; General Public License (GPL) as published by the Free Software
|
---|
| 13 | ; Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
| 14 | ; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
| 15 | ; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
| 16 | ;
|
---|
[1] | 17 |
|
---|
| 18 | ;*******************************************************************************
|
---|
| 19 | ;* Header Files *
|
---|
| 20 | ;*******************************************************************************
|
---|
[19] | 21 | %include "VBox/asmdefs.mac"
|
---|
[1] | 22 | %include "VBox/err.mac"
|
---|
[37955] | 23 | %include "iprt/x86.mac"
|
---|
[1] | 24 |
|
---|
| 25 | ;; @def MY_PTR_REG
|
---|
[30338] | 26 | ; The register we use for value pointers (And,Or,Dec,Inc,XAdd).
|
---|
[3696] | 27 | %ifdef RT_ARCH_AMD64
|
---|
[12688] | 28 | %define MY_PTR_REG rcx
|
---|
[1] | 29 | %else
|
---|
[12688] | 30 | %define MY_PTR_REG ecx
|
---|
[1] | 31 | %endif
|
---|
| 32 |
|
---|
| 33 | ;; @def MY_RET_REG
|
---|
| 34 | ; The register we return the result in.
|
---|
[3696] | 35 | %ifdef RT_ARCH_AMD64
|
---|
[12688] | 36 | %define MY_RET_REG rax
|
---|
[1] | 37 | %else
|
---|
[12688] | 38 | %define MY_RET_REG eax
|
---|
[1] | 39 | %endif
|
---|
| 40 |
|
---|
[15413] | 41 | ;; @def RT_ARCH_AMD64
|
---|
[33540] | 42 | ; Indicator for whether we can deal with 8 byte operands. (Darwin fun again.)
|
---|
[15413] | 43 | %ifdef RT_ARCH_AMD64
|
---|
| 44 | %define CAN_DO_8_BYTE_OP 1
|
---|
| 45 | %endif
|
---|
| 46 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 47 | %define CAN_DO_8_BYTE_OP 1
|
---|
[15418] | 48 | %define MY_PTR_REG64 rcx
|
---|
[15413] | 49 | %endif
|
---|
| 50 |
|
---|
| 51 |
|
---|
| 52 | ;*******************************************************************************
|
---|
| 53 | ;* External Symbols *
|
---|
| 54 | ;*******************************************************************************
|
---|
| 55 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 56 | extern NAME(SUPR0Abs64bitKernelCS)
|
---|
| 57 | extern NAME(SUPR0AbsKernelCS)
|
---|
| 58 | %endif
|
---|
| 59 |
|
---|
| 60 |
|
---|
[1] | 61 | BEGINCODE
|
---|
| 62 |
|
---|
| 63 |
|
---|
| 64 | ;;
|
---|
| 65 | ; Emulate CMP instruction, CDECL calling conv.
|
---|
[12989] | 66 | ; VMMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint64_t u64Param2, size_t cb);
|
---|
[1] | 67 | ;
|
---|
[11508] | 68 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1] | 69 | ; @param [esp + 04h] rdi rcx Param 1 - First parameter (Dst).
|
---|
| 70 | ; @param [esp + 08h] rsi edx Param 2 - Second parameter (Src).
|
---|
[9984] | 71 | ; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
|
---|
[1] | 72 | ;
|
---|
| 73 | align 16
|
---|
| 74 | BEGINPROC EMEmulateCmp
|
---|
[3696] | 75 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 76 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 77 | mov rax, r8 ; eax = size of parameters
|
---|
[3697] | 78 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 79 | mov rax, rdx ; rax = size of parameters
|
---|
| 80 | mov rcx, rdi ; rcx = first parameter
|
---|
| 81 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 82 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 83 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 84 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[1] | 85 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 86 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 87 | %endif
|
---|
| 88 |
|
---|
| 89 | ; switch on size
|
---|
[3696] | 90 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 91 | cmp al, 8
|
---|
| 92 | je short .do_qword ; 8 bytes variant
|
---|
| 93 | %endif
|
---|
| 94 | cmp al, 4
|
---|
| 95 | je short .do_dword ; 4 bytes variant
|
---|
| 96 | cmp al, 2
|
---|
| 97 | je short .do_word ; 2 byte variant
|
---|
| 98 | cmp al, 1
|
---|
| 99 | je short .do_byte ; 1 bytes variant
|
---|
| 100 | int3
|
---|
| 101 |
|
---|
| 102 | ; workers
|
---|
[3696] | 103 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 104 | .do_qword:
|
---|
| 105 | cmp rcx, rdx ; do 8 bytes CMP
|
---|
| 106 | jmp short .done
|
---|
| 107 | %endif
|
---|
| 108 |
|
---|
| 109 | .do_dword:
|
---|
| 110 | cmp ecx, edx ; do 4 bytes CMP
|
---|
| 111 | jmp short .done
|
---|
| 112 |
|
---|
| 113 | .do_word:
|
---|
| 114 | cmp cx, dx ; do 2 bytes CMP
|
---|
| 115 | jmp short .done
|
---|
| 116 |
|
---|
| 117 | .do_byte:
|
---|
| 118 | cmp cl, dl ; do 1 byte CMP
|
---|
| 119 |
|
---|
| 120 | ; collect flags and return.
|
---|
| 121 | .done:
|
---|
| 122 | pushf
|
---|
| 123 | pop MY_RET_REG
|
---|
| 124 | retn
|
---|
| 125 | ENDPROC EMEmulateCmp
|
---|
| 126 |
|
---|
| 127 |
|
---|
| 128 | ;;
|
---|
| 129 | ; Emulate AND instruction, CDECL calling conv.
|
---|
[12989] | 130 | ; VMMDECL(uint32_t) EMEmulateAnd(void *pvParam1, uint64_t u64Param2, size_t cb);
|
---|
[1] | 131 | ;
|
---|
[11508] | 132 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1] | 133 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 134 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
[9984] | 135 | ; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
|
---|
[1] | 136 | ; @uses eax, ecx, edx
|
---|
| 137 | ;
|
---|
| 138 | align 16
|
---|
| 139 | BEGINPROC EMEmulateAnd
|
---|
[3696] | 140 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 141 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 142 | mov rax, r8 ; eax = size of parameters
|
---|
[3697] | 143 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 144 | mov rax, rdx ; rax = size of parameters
|
---|
| 145 | mov rcx, rdi ; rcx = first parameter
|
---|
| 146 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 147 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 148 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 149 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[1] | 150 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 151 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 152 | %endif
|
---|
| 153 |
|
---|
| 154 | ; switch on size
|
---|
[15418] | 155 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[1] | 156 | cmp al, 8
|
---|
| 157 | je short .do_qword ; 8 bytes variant
|
---|
| 158 | %endif
|
---|
| 159 | cmp al, 4
|
---|
| 160 | je short .do_dword ; 4 bytes variant
|
---|
| 161 | cmp al, 2
|
---|
| 162 | je short .do_word ; 2 byte variant
|
---|
| 163 | cmp al, 1
|
---|
| 164 | je short .do_byte ; 1 bytes variant
|
---|
| 165 | int3
|
---|
| 166 |
|
---|
| 167 | ; workers
|
---|
[3696] | 168 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 169 | .do_qword:
|
---|
| 170 | and [MY_PTR_REG], rdx ; do 8 bytes AND
|
---|
| 171 | jmp short .done
|
---|
| 172 | %endif
|
---|
| 173 |
|
---|
| 174 | .do_dword:
|
---|
| 175 | and [MY_PTR_REG], edx ; do 4 bytes AND
|
---|
| 176 | jmp short .done
|
---|
| 177 |
|
---|
| 178 | .do_word:
|
---|
| 179 | and [MY_PTR_REG], dx ; do 2 bytes AND
|
---|
| 180 | jmp short .done
|
---|
| 181 |
|
---|
| 182 | .do_byte:
|
---|
| 183 | and [MY_PTR_REG], dl ; do 1 byte AND
|
---|
| 184 |
|
---|
| 185 | ; collect flags and return.
|
---|
| 186 | .done:
|
---|
| 187 | pushf
|
---|
| 188 | pop MY_RET_REG
|
---|
| 189 | retn
|
---|
[15418] | 190 |
|
---|
| 191 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 192 | .do_qword:
|
---|
| 193 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 194 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 195 | BITS 64
|
---|
| 196 | .sixtyfourbit_mode:
|
---|
| 197 | and esp, 0ffffffffh
|
---|
| 198 | and MY_PTR_REG, 0ffffffffh
|
---|
| 199 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 200 | and [MY_PTR_REG64], rdx ; do 8 bytes AND
|
---|
| 201 | jmp far [.fpret wrt rip]
|
---|
| 202 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 203 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 204 | BITS 32
|
---|
| 205 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[1] | 206 | ENDPROC EMEmulateAnd
|
---|
| 207 |
|
---|
| 208 |
|
---|
| 209 | ;;
|
---|
[20588] | 210 | ; Emulate LOCK AND instruction.
|
---|
| 211 | ; VMMDECL(int) EMEmulateLockAnd(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
|
---|
| 212 | ;
|
---|
| 213 | ; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
|
---|
| 214 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
|
---|
| 215 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value.
|
---|
| 216 | ; @param [esp + 10h] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
|
---|
| 217 | ; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success.
|
---|
| 218 | ; only arithmetic flags are valid.
|
---|
| 219 | align 16
|
---|
| 220 | BEGINPROC EMEmulateLockAnd
|
---|
| 221 | %ifdef RT_ARCH_AMD64
|
---|
| 222 | %ifdef RT_OS_WINDOWS
|
---|
| 223 | mov rax, r8 ; eax = size of parameters
|
---|
| 224 | %else ; !RT_OS_WINDOWS
|
---|
[20641] | 225 | mov r9, rcx ; r9 = eflags result ptr
|
---|
[20588] | 226 | mov rax, rdx ; rax = size of parameters
|
---|
| 227 | mov rcx, rdi ; rcx = first parameter
|
---|
| 228 | mov rdx, rsi ; rdx = second parameter
|
---|
| 229 | %endif ; !RT_OS_WINDOWS
|
---|
| 230 | %else ; !RT_ARCH_AMD64
|
---|
| 231 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
| 232 | mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG)
|
---|
| 233 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 234 | %endif
|
---|
| 235 |
|
---|
| 236 | ; switch on size
|
---|
| 237 | %ifdef CAN_DO_8_BYTE_OP
|
---|
| 238 | cmp al, 8
|
---|
| 239 | je short .do_qword ; 8 bytes variant
|
---|
| 240 | %endif
|
---|
| 241 | cmp al, 4
|
---|
| 242 | je short .do_dword ; 4 bytes variant
|
---|
| 243 | cmp al, 2
|
---|
| 244 | je short .do_word ; 2 byte variant
|
---|
| 245 | cmp al, 1
|
---|
| 246 | je short .do_byte ; 1 bytes variant
|
---|
| 247 | int3
|
---|
| 248 |
|
---|
| 249 | ; workers
|
---|
| 250 | %ifdef RT_ARCH_AMD64
|
---|
| 251 | .do_qword:
|
---|
| 252 | lock and [MY_PTR_REG], rdx ; do 8 bytes OR
|
---|
| 253 | jmp short .done
|
---|
| 254 | %endif
|
---|
| 255 |
|
---|
| 256 | .do_dword:
|
---|
| 257 | lock and [MY_PTR_REG], edx ; do 4 bytes OR
|
---|
| 258 | jmp short .done
|
---|
| 259 |
|
---|
| 260 | .do_word:
|
---|
| 261 | lock and [MY_PTR_REG], dx ; do 2 bytes OR
|
---|
| 262 | jmp short .done
|
---|
| 263 |
|
---|
| 264 | .do_byte:
|
---|
| 265 | lock and [MY_PTR_REG], dl ; do 1 byte OR
|
---|
| 266 |
|
---|
| 267 | ; collect flags and return.
|
---|
| 268 | .done:
|
---|
| 269 | pushf
|
---|
| 270 | %ifdef RT_ARCH_AMD64
|
---|
| 271 | pop rax
|
---|
| 272 | mov [r9], eax
|
---|
| 273 | %else ; !RT_ARCH_AMD64
|
---|
| 274 | mov eax, [esp + 14h + 4]
|
---|
| 275 | pop dword [eax]
|
---|
| 276 | %endif
|
---|
| 277 | mov eax, VINF_SUCCESS
|
---|
| 278 | retn
|
---|
| 279 |
|
---|
| 280 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 281 | .do_qword:
|
---|
| 282 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 283 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 284 | BITS 64
|
---|
| 285 | .sixtyfourbit_mode:
|
---|
| 286 | and esp, 0ffffffffh
|
---|
| 287 | and MY_PTR_REG, 0ffffffffh
|
---|
| 288 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 289 | lock and [MY_PTR_REG64], rdx ; do 8 bytes OR
|
---|
| 290 | jmp far [.fpret wrt rip]
|
---|
| 291 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 292 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 293 | BITS 32
|
---|
| 294 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 295 | ENDPROC EMEmulateLockAnd
|
---|
| 296 |
|
---|
| 297 | ;;
|
---|
[1] | 298 | ; Emulate OR instruction, CDECL calling conv.
|
---|
[12989] | 299 | ; VMMDECL(uint32_t) EMEmulateOr(void *pvParam1, uint64_t u64Param2, size_t cb);
|
---|
[1] | 300 | ;
|
---|
[11508] | 301 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1] | 302 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 303 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
[9984] | 304 | ; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
|
---|
[1] | 305 | ; @uses eax, ecx, edx
|
---|
| 306 | ;
|
---|
| 307 | align 16
|
---|
| 308 | BEGINPROC EMEmulateOr
|
---|
[3696] | 309 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 310 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 311 | mov rax, r8 ; eax = size of parameters
|
---|
[3697] | 312 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 313 | mov rax, rdx ; rax = size of parameters
|
---|
| 314 | mov rcx, rdi ; rcx = first parameter
|
---|
| 315 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 316 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 317 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 318 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[1] | 319 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 320 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 321 | %endif
|
---|
| 322 |
|
---|
| 323 | ; switch on size
|
---|
[15418] | 324 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[1] | 325 | cmp al, 8
|
---|
| 326 | je short .do_qword ; 8 bytes variant
|
---|
| 327 | %endif
|
---|
| 328 | cmp al, 4
|
---|
| 329 | je short .do_dword ; 4 bytes variant
|
---|
| 330 | cmp al, 2
|
---|
| 331 | je short .do_word ; 2 byte variant
|
---|
| 332 | cmp al, 1
|
---|
| 333 | je short .do_byte ; 1 bytes variant
|
---|
| 334 | int3
|
---|
| 335 |
|
---|
| 336 | ; workers
|
---|
[3696] | 337 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 338 | .do_qword:
|
---|
| 339 | or [MY_PTR_REG], rdx ; do 8 bytes OR
|
---|
| 340 | jmp short .done
|
---|
| 341 | %endif
|
---|
| 342 |
|
---|
| 343 | .do_dword:
|
---|
| 344 | or [MY_PTR_REG], edx ; do 4 bytes OR
|
---|
| 345 | jmp short .done
|
---|
| 346 |
|
---|
| 347 | .do_word:
|
---|
| 348 | or [MY_PTR_REG], dx ; do 2 bytes OR
|
---|
| 349 | jmp short .done
|
---|
| 350 |
|
---|
| 351 | .do_byte:
|
---|
| 352 | or [MY_PTR_REG], dl ; do 1 byte OR
|
---|
| 353 |
|
---|
| 354 | ; collect flags and return.
|
---|
| 355 | .done:
|
---|
| 356 | pushf
|
---|
| 357 | pop MY_RET_REG
|
---|
| 358 | retn
|
---|
[15418] | 359 |
|
---|
| 360 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 361 | .do_qword:
|
---|
| 362 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 363 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 364 | BITS 64
|
---|
| 365 | .sixtyfourbit_mode:
|
---|
| 366 | and esp, 0ffffffffh
|
---|
| 367 | and MY_PTR_REG, 0ffffffffh
|
---|
| 368 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 369 | or [MY_PTR_REG64], rdx ; do 8 bytes OR
|
---|
| 370 | jmp far [.fpret wrt rip]
|
---|
| 371 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 372 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 373 | BITS 32
|
---|
| 374 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[1] | 375 | ENDPROC EMEmulateOr
|
---|
| 376 |
|
---|
[12688] | 377 |
|
---|
[1] | 378 | ;;
|
---|
[5384] | 379 | ; Emulate LOCK OR instruction.
|
---|
[12989] | 380 | ; VMMDECL(int) EMEmulateLockOr(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
|
---|
[5384] | 381 | ;
|
---|
| 382 | ; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
|
---|
| 383 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
|
---|
| 384 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value.
|
---|
[9984] | 385 | ; @param [esp + 10h] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
|
---|
| 386 | ; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success.
|
---|
[5384] | 387 | ; only arithmetic flags are valid.
|
---|
| 388 | align 16
|
---|
| 389 | BEGINPROC EMEmulateLockOr
|
---|
| 390 | %ifdef RT_ARCH_AMD64
|
---|
| 391 | %ifdef RT_OS_WINDOWS
|
---|
| 392 | mov rax, r8 ; eax = size of parameters
|
---|
| 393 | %else ; !RT_OS_WINDOWS
|
---|
[20641] | 394 | mov r9, rcx ; r9 = eflags result ptr
|
---|
[5384] | 395 | mov rax, rdx ; rax = size of parameters
|
---|
| 396 | mov rcx, rdi ; rcx = first parameter
|
---|
| 397 | mov rdx, rsi ; rdx = second parameter
|
---|
| 398 | %endif ; !RT_OS_WINDOWS
|
---|
| 399 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 400 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[5384] | 401 | mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG)
|
---|
| 402 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 403 | %endif
|
---|
| 404 |
|
---|
| 405 | ; switch on size
|
---|
[15418] | 406 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[5384] | 407 | cmp al, 8
|
---|
| 408 | je short .do_qword ; 8 bytes variant
|
---|
| 409 | %endif
|
---|
| 410 | cmp al, 4
|
---|
| 411 | je short .do_dword ; 4 bytes variant
|
---|
| 412 | cmp al, 2
|
---|
| 413 | je short .do_word ; 2 byte variant
|
---|
| 414 | cmp al, 1
|
---|
| 415 | je short .do_byte ; 1 bytes variant
|
---|
| 416 | int3
|
---|
| 417 |
|
---|
| 418 | ; workers
|
---|
| 419 | %ifdef RT_ARCH_AMD64
|
---|
| 420 | .do_qword:
|
---|
| 421 | lock or [MY_PTR_REG], rdx ; do 8 bytes OR
|
---|
| 422 | jmp short .done
|
---|
| 423 | %endif
|
---|
| 424 |
|
---|
| 425 | .do_dword:
|
---|
| 426 | lock or [MY_PTR_REG], edx ; do 4 bytes OR
|
---|
| 427 | jmp short .done
|
---|
| 428 |
|
---|
| 429 | .do_word:
|
---|
| 430 | lock or [MY_PTR_REG], dx ; do 2 bytes OR
|
---|
| 431 | jmp short .done
|
---|
| 432 |
|
---|
| 433 | .do_byte:
|
---|
| 434 | lock or [MY_PTR_REG], dl ; do 1 byte OR
|
---|
| 435 |
|
---|
| 436 | ; collect flags and return.
|
---|
| 437 | .done:
|
---|
| 438 | pushf
|
---|
| 439 | %ifdef RT_ARCH_AMD64
|
---|
| 440 | pop rax
|
---|
| 441 | mov [r9], eax
|
---|
| 442 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 443 | mov eax, [esp + 14h + 4]
|
---|
[5384] | 444 | pop dword [eax]
|
---|
| 445 | %endif
|
---|
[12688] | 446 | mov eax, VINF_SUCCESS
|
---|
[5384] | 447 | retn
|
---|
| 448 |
|
---|
[15418] | 449 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 450 | .do_qword:
|
---|
| 451 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 452 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 453 | BITS 64
|
---|
| 454 | .sixtyfourbit_mode:
|
---|
| 455 | and esp, 0ffffffffh
|
---|
| 456 | and MY_PTR_REG, 0ffffffffh
|
---|
| 457 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 458 | lock or [MY_PTR_REG64], rdx ; do 8 bytes OR
|
---|
| 459 | jmp far [.fpret wrt rip]
|
---|
| 460 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 461 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 462 | BITS 32
|
---|
| 463 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[5384] | 464 | ENDPROC EMEmulateLockOr
|
---|
| 465 |
|
---|
[12688] | 466 |
|
---|
[5384] | 467 | ;;
|
---|
[1] | 468 | ; Emulate XOR instruction, CDECL calling conv.
|
---|
[12989] | 469 | ; VMMDECL(uint32_t) EMEmulateXor(void *pvParam1, uint64_t u64Param2, size_t cb);
|
---|
[1] | 470 | ;
|
---|
[11508] | 471 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1] | 472 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 473 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
[9984] | 474 | ; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
|
---|
[1] | 475 | ; @uses eax, ecx, edx
|
---|
| 476 | ;
|
---|
| 477 | align 16
|
---|
| 478 | BEGINPROC EMEmulateXor
|
---|
[3696] | 479 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 480 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 481 | mov rax, r8 ; eax = size of parameters
|
---|
[3697] | 482 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 483 | mov rax, rdx ; rax = size of parameters
|
---|
| 484 | mov rcx, rdi ; rcx = first parameter
|
---|
| 485 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 486 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 487 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 488 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[1] | 489 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 490 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 491 | %endif
|
---|
| 492 |
|
---|
| 493 | ; switch on size
|
---|
[15418] | 494 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[1] | 495 | cmp al, 8
|
---|
| 496 | je short .do_qword ; 8 bytes variant
|
---|
| 497 | %endif
|
---|
| 498 | cmp al, 4
|
---|
| 499 | je short .do_dword ; 4 bytes variant
|
---|
| 500 | cmp al, 2
|
---|
| 501 | je short .do_word ; 2 byte variant
|
---|
| 502 | cmp al, 1
|
---|
| 503 | je short .do_byte ; 1 bytes variant
|
---|
| 504 | int3
|
---|
| 505 |
|
---|
| 506 | ; workers
|
---|
[3696] | 507 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 508 | .do_qword:
|
---|
| 509 | xor [MY_PTR_REG], rdx ; do 8 bytes XOR
|
---|
| 510 | jmp short .done
|
---|
| 511 | %endif
|
---|
| 512 |
|
---|
| 513 | .do_dword:
|
---|
| 514 | xor [MY_PTR_REG], edx ; do 4 bytes XOR
|
---|
| 515 | jmp short .done
|
---|
| 516 |
|
---|
| 517 | .do_word:
|
---|
| 518 | xor [MY_PTR_REG], dx ; do 2 bytes XOR
|
---|
| 519 | jmp short .done
|
---|
| 520 |
|
---|
| 521 | .do_byte:
|
---|
| 522 | xor [MY_PTR_REG], dl ; do 1 byte XOR
|
---|
| 523 |
|
---|
| 524 | ; collect flags and return.
|
---|
| 525 | .done:
|
---|
| 526 | pushf
|
---|
| 527 | pop MY_RET_REG
|
---|
| 528 | retn
|
---|
[15418] | 529 |
|
---|
| 530 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 531 | .do_qword:
|
---|
| 532 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 533 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 534 | BITS 64
|
---|
| 535 | .sixtyfourbit_mode:
|
---|
| 536 | and esp, 0ffffffffh
|
---|
| 537 | and MY_PTR_REG, 0ffffffffh
|
---|
| 538 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 539 | xor [MY_PTR_REG64], rdx ; do 8 bytes XOR
|
---|
| 540 | jmp far [.fpret wrt rip]
|
---|
| 541 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 542 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 543 | BITS 32
|
---|
| 544 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[1] | 545 | ENDPROC EMEmulateXor
|
---|
| 546 |
|
---|
[20588] | 547 | ;;
|
---|
| 548 | ; Emulate LOCK XOR instruction.
|
---|
| 549 | ; VMMDECL(int) EMEmulateLockXor(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
|
---|
| 550 | ;
|
---|
| 551 | ; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
|
---|
| 552 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
|
---|
| 553 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value.
|
---|
| 554 | ; @param [esp + 10h] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
|
---|
| 555 | ; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success.
|
---|
| 556 | ; only arithmetic flags are valid.
|
---|
| 557 | align 16
|
---|
| 558 | BEGINPROC EMEmulateLockXor
|
---|
| 559 | %ifdef RT_ARCH_AMD64
|
---|
| 560 | %ifdef RT_OS_WINDOWS
|
---|
| 561 | mov rax, r8 ; eax = size of parameters
|
---|
| 562 | %else ; !RT_OS_WINDOWS
|
---|
[20641] | 563 | mov r9, rcx ; r9 = eflags result ptr
|
---|
[20588] | 564 | mov rax, rdx ; rax = size of parameters
|
---|
| 565 | mov rcx, rdi ; rcx = first parameter
|
---|
| 566 | mov rdx, rsi ; rdx = second parameter
|
---|
| 567 | %endif ; !RT_OS_WINDOWS
|
---|
| 568 | %else ; !RT_ARCH_AMD64
|
---|
| 569 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
| 570 | mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG)
|
---|
| 571 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 572 | %endif
|
---|
[12688] | 573 |
|
---|
[20588] | 574 | ; switch on size
|
---|
| 575 | %ifdef CAN_DO_8_BYTE_OP
|
---|
| 576 | cmp al, 8
|
---|
| 577 | je short .do_qword ; 8 bytes variant
|
---|
| 578 | %endif
|
---|
| 579 | cmp al, 4
|
---|
| 580 | je short .do_dword ; 4 bytes variant
|
---|
| 581 | cmp al, 2
|
---|
| 582 | je short .do_word ; 2 byte variant
|
---|
| 583 | cmp al, 1
|
---|
| 584 | je short .do_byte ; 1 bytes variant
|
---|
| 585 | int3
|
---|
| 586 |
|
---|
| 587 | ; workers
|
---|
| 588 | %ifdef RT_ARCH_AMD64
|
---|
| 589 | .do_qword:
|
---|
| 590 | lock xor [MY_PTR_REG], rdx ; do 8 bytes OR
|
---|
| 591 | jmp short .done
|
---|
| 592 | %endif
|
---|
| 593 |
|
---|
| 594 | .do_dword:
|
---|
| 595 | lock xor [MY_PTR_REG], edx ; do 4 bytes OR
|
---|
| 596 | jmp short .done
|
---|
| 597 |
|
---|
| 598 | .do_word:
|
---|
| 599 | lock xor [MY_PTR_REG], dx ; do 2 bytes OR
|
---|
| 600 | jmp short .done
|
---|
| 601 |
|
---|
| 602 | .do_byte:
|
---|
| 603 | lock xor [MY_PTR_REG], dl ; do 1 byte OR
|
---|
| 604 |
|
---|
| 605 | ; collect flags and return.
|
---|
| 606 | .done:
|
---|
| 607 | pushf
|
---|
| 608 | %ifdef RT_ARCH_AMD64
|
---|
| 609 | pop rax
|
---|
| 610 | mov [r9], eax
|
---|
| 611 | %else ; !RT_ARCH_AMD64
|
---|
| 612 | mov eax, [esp + 14h + 4]
|
---|
| 613 | pop dword [eax]
|
---|
| 614 | %endif
|
---|
| 615 | mov eax, VINF_SUCCESS
|
---|
| 616 | retn
|
---|
| 617 |
|
---|
| 618 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 619 | .do_qword:
|
---|
| 620 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 621 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 622 | BITS 64
|
---|
| 623 | .sixtyfourbit_mode:
|
---|
| 624 | and esp, 0ffffffffh
|
---|
| 625 | and MY_PTR_REG, 0ffffffffh
|
---|
| 626 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 627 | lock xor [MY_PTR_REG64], rdx ; do 8 bytes OR
|
---|
| 628 | jmp far [.fpret wrt rip]
|
---|
| 629 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 630 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 631 | BITS 32
|
---|
| 632 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 633 | ENDPROC EMEmulateLockXor
|
---|
| 634 |
|
---|
[1] | 635 | ;;
|
---|
| 636 | ; Emulate INC instruction, CDECL calling conv.
|
---|
[12989] | 637 | ; VMMDECL(uint32_t) EMEmulateInc(void *pvParam1, size_t cb);
|
---|
[1] | 638 | ;
|
---|
| 639 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
| 640 | ; @param [esp + 04h] rdi rcx Param 1 - First parameter - pointer to data item.
|
---|
| 641 | ; @param [esp + 08h] rsi rdx Param 2 - Size of parameters, only 1/2/4 is valid.
|
---|
| 642 | ; @uses eax, ecx, edx
|
---|
| 643 | ;
|
---|
| 644 | align 16
|
---|
| 645 | BEGINPROC EMEmulateInc
|
---|
[3696] | 646 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 647 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 648 | mov rax, rdx ; eax = size of parameters
|
---|
[3697] | 649 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 650 | mov rax, rsi ; eax = size of parameters
|
---|
| 651 | mov rcx, rdi ; rcx = first parameter
|
---|
[3697] | 652 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 653 | %else ; !RT_ARCH_AMD64
|
---|
[1] | 654 | mov eax, [esp + 08h] ; eax = size of parameters
|
---|
| 655 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 656 | %endif
|
---|
| 657 |
|
---|
| 658 | ; switch on size
|
---|
[3696] | 659 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 660 | cmp al, 8
|
---|
| 661 | je short .do_qword ; 8 bytes variant
|
---|
| 662 | %endif
|
---|
| 663 | cmp al, 4
|
---|
| 664 | je short .do_dword ; 4 bytes variant
|
---|
| 665 | cmp al, 2
|
---|
| 666 | je short .do_word ; 2 byte variant
|
---|
| 667 | cmp al, 1
|
---|
| 668 | je short .do_byte ; 1 bytes variant
|
---|
| 669 | int3
|
---|
| 670 |
|
---|
| 671 | ; workers
|
---|
[3696] | 672 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 673 | .do_qword:
|
---|
| 674 | inc qword [MY_PTR_REG] ; do 8 bytes INC
|
---|
| 675 | jmp short .done
|
---|
| 676 | %endif
|
---|
| 677 |
|
---|
| 678 | .do_dword:
|
---|
| 679 | inc dword [MY_PTR_REG] ; do 4 bytes INC
|
---|
| 680 | jmp short .done
|
---|
| 681 |
|
---|
| 682 | .do_word:
|
---|
| 683 | inc word [MY_PTR_REG] ; do 2 bytes INC
|
---|
| 684 | jmp short .done
|
---|
| 685 |
|
---|
| 686 | .do_byte:
|
---|
| 687 | inc byte [MY_PTR_REG] ; do 1 byte INC
|
---|
| 688 | jmp short .done
|
---|
| 689 |
|
---|
| 690 | ; collect flags and return.
|
---|
| 691 | .done:
|
---|
| 692 | pushf
|
---|
| 693 | pop MY_RET_REG
|
---|
| 694 | retn
|
---|
| 695 | ENDPROC EMEmulateInc
|
---|
| 696 |
|
---|
| 697 |
|
---|
| 698 | ;;
|
---|
| 699 | ; Emulate DEC instruction, CDECL calling conv.
|
---|
[12989] | 700 | ; VMMDECL(uint32_t) EMEmulateDec(void *pvParam1, size_t cb);
|
---|
[1] | 701 | ;
|
---|
| 702 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
| 703 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 704 | ; @param [esp + 08h] Param 2 - Size of parameters, only 1/2/4 is valid.
|
---|
| 705 | ; @uses eax, ecx, edx
|
---|
| 706 | ;
|
---|
| 707 | align 16
|
---|
| 708 | BEGINPROC EMEmulateDec
|
---|
[3696] | 709 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 710 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 711 | mov rax, rdx ; eax = size of parameters
|
---|
[3697] | 712 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 713 | mov rax, rsi ; eax = size of parameters
|
---|
| 714 | mov rcx, rdi ; rcx = first parameter
|
---|
[3697] | 715 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 716 | %else ; !RT_ARCH_AMD64
|
---|
[1] | 717 | mov eax, [esp + 08h] ; eax = size of parameters
|
---|
| 718 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 719 | %endif
|
---|
| 720 |
|
---|
| 721 | ; switch on size
|
---|
[3696] | 722 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 723 | cmp al, 8
|
---|
| 724 | je short .do_qword ; 8 bytes variant
|
---|
| 725 | %endif
|
---|
| 726 | cmp al, 4
|
---|
| 727 | je short .do_dword ; 4 bytes variant
|
---|
| 728 | cmp al, 2
|
---|
| 729 | je short .do_word ; 2 byte variant
|
---|
| 730 | cmp al, 1
|
---|
| 731 | je short .do_byte ; 1 bytes variant
|
---|
| 732 | int3
|
---|
| 733 |
|
---|
| 734 | ; workers
|
---|
[3696] | 735 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 736 | .do_qword:
|
---|
| 737 | dec qword [MY_PTR_REG] ; do 8 bytes DEC
|
---|
| 738 | jmp short .done
|
---|
| 739 | %endif
|
---|
| 740 |
|
---|
| 741 | .do_dword:
|
---|
| 742 | dec dword [MY_PTR_REG] ; do 4 bytes DEC
|
---|
| 743 | jmp short .done
|
---|
| 744 |
|
---|
| 745 | .do_word:
|
---|
| 746 | dec word [MY_PTR_REG] ; do 2 bytes DEC
|
---|
| 747 | jmp short .done
|
---|
| 748 |
|
---|
| 749 | .do_byte:
|
---|
| 750 | dec byte [MY_PTR_REG] ; do 1 byte DEC
|
---|
| 751 | jmp short .done
|
---|
| 752 |
|
---|
| 753 | ; collect flags and return.
|
---|
| 754 | .done:
|
---|
| 755 | pushf
|
---|
| 756 | pop MY_RET_REG
|
---|
| 757 | retn
|
---|
| 758 | ENDPROC EMEmulateDec
|
---|
| 759 |
|
---|
[12688] | 760 |
|
---|
[1] | 761 | ;;
|
---|
| 762 | ; Emulate ADD instruction, CDECL calling conv.
|
---|
[12989] | 763 | ; VMMDECL(uint32_t) EMEmulateAdd(void *pvParam1, uint64_t u64Param2, size_t cb);
|
---|
[1] | 764 | ;
|
---|
[11508] | 765 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1] | 766 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 767 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
[9984] | 768 | ; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
|
---|
[1] | 769 | ; @uses eax, ecx, edx
|
---|
| 770 | ;
|
---|
| 771 | align 16
|
---|
| 772 | BEGINPROC EMEmulateAdd
|
---|
[3696] | 773 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 774 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 775 | mov rax, r8 ; eax = size of parameters
|
---|
[3697] | 776 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 777 | mov rax, rdx ; rax = size of parameters
|
---|
| 778 | mov rcx, rdi ; rcx = first parameter
|
---|
| 779 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 780 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 781 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 782 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[1] | 783 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 784 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 785 | %endif
|
---|
| 786 |
|
---|
| 787 | ; switch on size
|
---|
[15420] | 788 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[1] | 789 | cmp al, 8
|
---|
| 790 | je short .do_qword ; 8 bytes variant
|
---|
| 791 | %endif
|
---|
| 792 | cmp al, 4
|
---|
| 793 | je short .do_dword ; 4 bytes variant
|
---|
| 794 | cmp al, 2
|
---|
| 795 | je short .do_word ; 2 byte variant
|
---|
| 796 | cmp al, 1
|
---|
| 797 | je short .do_byte ; 1 bytes variant
|
---|
| 798 | int3
|
---|
| 799 |
|
---|
| 800 | ; workers
|
---|
[3696] | 801 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 802 | .do_qword:
|
---|
| 803 | add [MY_PTR_REG], rdx ; do 8 bytes ADD
|
---|
| 804 | jmp short .done
|
---|
| 805 | %endif
|
---|
| 806 |
|
---|
| 807 | .do_dword:
|
---|
| 808 | add [MY_PTR_REG], edx ; do 4 bytes ADD
|
---|
| 809 | jmp short .done
|
---|
| 810 |
|
---|
| 811 | .do_word:
|
---|
| 812 | add [MY_PTR_REG], dx ; do 2 bytes ADD
|
---|
| 813 | jmp short .done
|
---|
| 814 |
|
---|
| 815 | .do_byte:
|
---|
| 816 | add [MY_PTR_REG], dl ; do 1 byte ADD
|
---|
| 817 |
|
---|
| 818 | ; collect flags and return.
|
---|
| 819 | .done:
|
---|
| 820 | pushf
|
---|
| 821 | pop MY_RET_REG
|
---|
| 822 | retn
|
---|
[15420] | 823 |
|
---|
| 824 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 825 | .do_qword:
|
---|
| 826 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 827 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 828 | BITS 64
|
---|
| 829 | .sixtyfourbit_mode:
|
---|
| 830 | and esp, 0ffffffffh
|
---|
| 831 | and MY_PTR_REG, 0ffffffffh
|
---|
| 832 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 833 | add [MY_PTR_REG64], rdx ; do 8 bytes ADD
|
---|
| 834 | jmp far [.fpret wrt rip]
|
---|
| 835 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 836 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 837 | BITS 32
|
---|
| 838 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[1] | 839 | ENDPROC EMEmulateAdd
|
---|
| 840 |
|
---|
[12688] | 841 |
|
---|
[1] | 842 | ;;
|
---|
| 843 | ; Emulate ADC instruction, CDECL calling conv.
|
---|
[12989] | 844 | ; VMMDECL(uint32_t) EMEmulateAdcWithCarrySet(void *pvParam1, uint64_t u64Param2, size_t cb);
|
---|
[1] | 845 | ;
|
---|
[11508] | 846 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1] | 847 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 848 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
[9984] | 849 | ; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
|
---|
[1] | 850 | ; @uses eax, ecx, edx
|
---|
| 851 | ;
|
---|
| 852 | align 16
|
---|
| 853 | BEGINPROC EMEmulateAdcWithCarrySet
|
---|
[3696] | 854 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 855 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 856 | mov rax, r8 ; eax = size of parameters
|
---|
[3697] | 857 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 858 | mov rax, rdx ; rax = size of parameters
|
---|
| 859 | mov rcx, rdi ; rcx = first parameter
|
---|
| 860 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 861 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 862 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 863 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[1] | 864 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 865 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 866 | %endif
|
---|
| 867 |
|
---|
| 868 | ; switch on size
|
---|
[15420] | 869 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[1] | 870 | cmp al, 8
|
---|
| 871 | je short .do_qword ; 8 bytes variant
|
---|
| 872 | %endif
|
---|
| 873 | cmp al, 4
|
---|
| 874 | je short .do_dword ; 4 bytes variant
|
---|
| 875 | cmp al, 2
|
---|
| 876 | je short .do_word ; 2 byte variant
|
---|
| 877 | cmp al, 1
|
---|
| 878 | je short .do_byte ; 1 bytes variant
|
---|
| 879 | int3
|
---|
| 880 |
|
---|
| 881 | ; workers
|
---|
[3696] | 882 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 883 | .do_qword:
|
---|
| 884 | stc ; set carry flag
|
---|
| 885 | adc [MY_PTR_REG], rdx ; do 8 bytes ADC
|
---|
| 886 | jmp short .done
|
---|
| 887 | %endif
|
---|
| 888 |
|
---|
| 889 | .do_dword:
|
---|
| 890 | stc ; set carry flag
|
---|
| 891 | adc [MY_PTR_REG], edx ; do 4 bytes ADC
|
---|
| 892 | jmp short .done
|
---|
| 893 |
|
---|
| 894 | .do_word:
|
---|
| 895 | stc ; set carry flag
|
---|
| 896 | adc [MY_PTR_REG], dx ; do 2 bytes ADC
|
---|
| 897 | jmp short .done
|
---|
| 898 |
|
---|
| 899 | .do_byte:
|
---|
| 900 | stc ; set carry flag
|
---|
| 901 | adc [MY_PTR_REG], dl ; do 1 byte ADC
|
---|
| 902 |
|
---|
| 903 | ; collect flags and return.
|
---|
| 904 | .done:
|
---|
| 905 | pushf
|
---|
| 906 | pop MY_RET_REG
|
---|
| 907 | retn
|
---|
[15420] | 908 |
|
---|
| 909 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 910 | .do_qword:
|
---|
| 911 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 912 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 913 | BITS 64
|
---|
| 914 | .sixtyfourbit_mode:
|
---|
| 915 | and esp, 0ffffffffh
|
---|
| 916 | and MY_PTR_REG, 0ffffffffh
|
---|
| 917 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 918 | stc ; set carry flag
|
---|
| 919 | adc [MY_PTR_REG64], rdx ; do 8 bytes ADC
|
---|
| 920 | jmp far [.fpret wrt rip]
|
---|
| 921 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 922 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 923 | BITS 32
|
---|
| 924 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[1] | 925 | ENDPROC EMEmulateAdcWithCarrySet
|
---|
| 926 |
|
---|
[12688] | 927 |
|
---|
[1] | 928 | ;;
|
---|
| 929 | ; Emulate SUB instruction, CDECL calling conv.
|
---|
[12989] | 930 | ; VMMDECL(uint32_t) EMEmulateSub(void *pvParam1, uint64_t u64Param2, size_t cb);
|
---|
[1] | 931 | ;
|
---|
[11508] | 932 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1] | 933 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 934 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
[9984] | 935 | ; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
|
---|
[1] | 936 | ; @uses eax, ecx, edx
|
---|
| 937 | ;
|
---|
| 938 | align 16
|
---|
| 939 | BEGINPROC EMEmulateSub
|
---|
[3696] | 940 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 941 | %ifdef RT_OS_WINDOWS
|
---|
[1] | 942 | mov rax, r8 ; eax = size of parameters
|
---|
[3697] | 943 | %else ; !RT_OS_WINDOWS
|
---|
[1] | 944 | mov rax, rdx ; rax = size of parameters
|
---|
| 945 | mov rcx, rdi ; rcx = first parameter
|
---|
| 946 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 947 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 948 | %else ; !RT_ARCH_AMD64
|
---|
[9984] | 949 | mov eax, [esp + 10h] ; eax = size of parameters
|
---|
[1] | 950 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 951 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 952 | %endif
|
---|
| 953 |
|
---|
| 954 | ; switch on size
|
---|
[15420] | 955 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[1] | 956 | cmp al, 8
|
---|
| 957 | je short .do_qword ; 8 bytes variant
|
---|
| 958 | %endif
|
---|
| 959 | cmp al, 4
|
---|
| 960 | je short .do_dword ; 4 bytes variant
|
---|
| 961 | cmp al, 2
|
---|
| 962 | je short .do_word ; 2 byte variant
|
---|
| 963 | cmp al, 1
|
---|
| 964 | je short .do_byte ; 1 bytes variant
|
---|
| 965 | int3
|
---|
| 966 |
|
---|
| 967 | ; workers
|
---|
[3696] | 968 | %ifdef RT_ARCH_AMD64
|
---|
[1] | 969 | .do_qword:
|
---|
| 970 | sub [MY_PTR_REG], rdx ; do 8 bytes SUB
|
---|
| 971 | jmp short .done
|
---|
| 972 | %endif
|
---|
| 973 |
|
---|
| 974 | .do_dword:
|
---|
| 975 | sub [MY_PTR_REG], edx ; do 4 bytes SUB
|
---|
| 976 | jmp short .done
|
---|
| 977 |
|
---|
| 978 | .do_word:
|
---|
| 979 | sub [MY_PTR_REG], dx ; do 2 bytes SUB
|
---|
| 980 | jmp short .done
|
---|
| 981 |
|
---|
| 982 | .do_byte:
|
---|
| 983 | sub [MY_PTR_REG], dl ; do 1 byte SUB
|
---|
| 984 |
|
---|
| 985 | ; collect flags and return.
|
---|
| 986 | .done:
|
---|
| 987 | pushf
|
---|
| 988 | pop MY_RET_REG
|
---|
| 989 | retn
|
---|
[15420] | 990 |
|
---|
| 991 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 992 | .do_qword:
|
---|
| 993 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 994 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 995 | BITS 64
|
---|
| 996 | .sixtyfourbit_mode:
|
---|
| 997 | and esp, 0ffffffffh
|
---|
| 998 | and MY_PTR_REG, 0ffffffffh
|
---|
| 999 | mov rdx, qword [rsp + 08h] ; rdx = second parameter
|
---|
| 1000 | sub [MY_PTR_REG64], rdx ; do 8 bytes SUB
|
---|
| 1001 | jmp far [.fpret wrt rip]
|
---|
| 1002 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 1003 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 1004 | BITS 32
|
---|
| 1005 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[1] | 1006 | ENDPROC EMEmulateSub
|
---|
[1986] | 1007 |
|
---|
| 1008 |
|
---|
| 1009 | ;;
|
---|
| 1010 | ; Emulate BTR instruction, CDECL calling conv.
|
---|
[12989] | 1011 | ; VMMDECL(uint32_t) EMEmulateBtr(void *pvParam1, uint64_t u64Param2);
|
---|
[1986] | 1012 | ;
|
---|
[11508] | 1013 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1986] | 1014 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 1015 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
| 1016 | ; @uses eax, ecx, edx
|
---|
| 1017 | ;
|
---|
| 1018 | align 16
|
---|
| 1019 | BEGINPROC EMEmulateBtr
|
---|
[3696] | 1020 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 1021 | %ifndef RT_OS_WINDOWS
|
---|
[1986] | 1022 | mov rcx, rdi ; rcx = first parameter
|
---|
| 1023 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 1024 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 1025 | %else ; !RT_ARCH_AMD64
|
---|
[1986] | 1026 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 1027 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 1028 | %endif
|
---|
| 1029 |
|
---|
| 1030 | and edx, 7
|
---|
| 1031 | btr [MY_PTR_REG], edx
|
---|
| 1032 |
|
---|
| 1033 | ; collect flags and return.
|
---|
| 1034 | pushf
|
---|
| 1035 | pop MY_RET_REG
|
---|
| 1036 | retn
|
---|
| 1037 | ENDPROC EMEmulateBtr
|
---|
[1991] | 1038 |
|
---|
| 1039 | ;;
|
---|
[5384] | 1040 | ; Emulate LOCK BTR instruction.
|
---|
[12989] | 1041 | ; VMMDECL(int) EMEmulateLockBtr(void *pvParam1, uint64_t u64Param2, RTGCUINTREG32 *pf);
|
---|
[5384] | 1042 | ;
|
---|
| 1043 | ; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
|
---|
| 1044 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
|
---|
| 1045 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value. (really an 8 byte value)
|
---|
[9984] | 1046 | ; @param [esp + 10h] gcc:rdx msc:r8 Param 3 - Where to store the eflags on success.
|
---|
[5384] | 1047 | ;
|
---|
| 1048 | align 16
|
---|
| 1049 | BEGINPROC EMEmulateLockBtr
|
---|
| 1050 | %ifdef RT_ARCH_AMD64
|
---|
| 1051 | %ifdef RT_OS_WINDOWS
|
---|
| 1052 | mov rax, r8 ; rax = third parameter
|
---|
| 1053 | %else ; !RT_OS_WINDOWS
|
---|
| 1054 | mov rcx, rdi ; rcx = first parameter
|
---|
| 1055 | mov rax, rdx ; rax = third parameter
|
---|
| 1056 | mov rdx, rsi ; rdx = second parameter
|
---|
| 1057 | %endif ; !RT_OS_WINDOWS
|
---|
| 1058 | %else ; !RT_ARCH_AMD64
|
---|
| 1059 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 1060 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
[9984] | 1061 | mov eax, [esp + 10h] ; eax = third parameter
|
---|
[5384] | 1062 | %endif
|
---|
| 1063 |
|
---|
| 1064 | lock btr [MY_PTR_REG], edx
|
---|
| 1065 |
|
---|
| 1066 | ; collect flags and return.
|
---|
| 1067 | pushf
|
---|
| 1068 | pop xDX
|
---|
| 1069 | mov [xAX], edx
|
---|
| 1070 | mov eax, VINF_SUCCESS
|
---|
| 1071 | retn
|
---|
| 1072 | ENDPROC EMEmulateLockBtr
|
---|
| 1073 |
|
---|
[12688] | 1074 |
|
---|
[5384] | 1075 | ;;
|
---|
[1991] | 1076 | ; Emulate BTC instruction, CDECL calling conv.
|
---|
[12989] | 1077 | ; VMMDECL(uint32_t) EMEmulateBtc(void *pvParam1, uint64_t u64Param2);
|
---|
[1991] | 1078 | ;
|
---|
[11508] | 1079 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1991] | 1080 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 1081 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
| 1082 | ; @uses eax, ecx, edx
|
---|
| 1083 | ;
|
---|
| 1084 | align 16
|
---|
| 1085 | BEGINPROC EMEmulateBtc
|
---|
[3696] | 1086 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 1087 | %ifndef RT_OS_WINDOWS
|
---|
[1991] | 1088 | mov rcx, rdi ; rcx = first parameter
|
---|
| 1089 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 1090 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 1091 | %else ; !RT_ARCH_AMD64
|
---|
[1991] | 1092 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 1093 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 1094 | %endif
|
---|
| 1095 |
|
---|
| 1096 | and edx, 7
|
---|
| 1097 | btc [MY_PTR_REG], edx
|
---|
| 1098 |
|
---|
| 1099 | ; collect flags and return.
|
---|
| 1100 | pushf
|
---|
| 1101 | pop MY_RET_REG
|
---|
| 1102 | retn
|
---|
| 1103 | ENDPROC EMEmulateBtc
|
---|
| 1104 |
|
---|
[12688] | 1105 |
|
---|
[1991] | 1106 | ;;
|
---|
| 1107 | ; Emulate BTS instruction, CDECL calling conv.
|
---|
[12989] | 1108 | ; VMMDECL(uint32_t) EMEmulateBts(void *pvParam1, uint64_t u64Param2);
|
---|
[1991] | 1109 | ;
|
---|
[8225] | 1110 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[1991] | 1111 | ; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
|
---|
| 1112 | ; @param [esp + 08h] Param 2 - Second parameter.
|
---|
| 1113 | ; @uses eax, ecx, edx
|
---|
| 1114 | ;
|
---|
| 1115 | align 16
|
---|
| 1116 | BEGINPROC EMEmulateBts
|
---|
[3696] | 1117 | %ifdef RT_ARCH_AMD64
|
---|
[3697] | 1118 | %ifndef RT_OS_WINDOWS
|
---|
[1991] | 1119 | mov rcx, rdi ; rcx = first parameter
|
---|
| 1120 | mov rdx, rsi ; rdx = second parameter
|
---|
[3697] | 1121 | %endif ; !RT_OS_WINDOWS
|
---|
[3696] | 1122 | %else ; !RT_ARCH_AMD64
|
---|
[1991] | 1123 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 1124 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 1125 | %endif
|
---|
| 1126 |
|
---|
| 1127 | and edx, 7
|
---|
| 1128 | bts [MY_PTR_REG], edx
|
---|
| 1129 |
|
---|
| 1130 | ; collect flags and return.
|
---|
| 1131 | pushf
|
---|
| 1132 | pop MY_RET_REG
|
---|
| 1133 | retn
|
---|
| 1134 | ENDPROC EMEmulateBts
|
---|
[8225] | 1135 |
|
---|
| 1136 |
|
---|
| 1137 | ;;
|
---|
| 1138 | ; Emulate LOCK CMPXCHG instruction, CDECL calling conv.
|
---|
[12989] | 1139 | ; VMMDECL(uint32_t) EMEmulateLockCmpXchg(void *pvParam1, uint64_t *pu64Param2, uint64_t u64Param3, size_t cbSize);
|
---|
[8225] | 1140 | ;
|
---|
[11508] | 1141 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[8225] | 1142 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
|
---|
| 1143 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
|
---|
| 1144 | ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
|
---|
[11508] | 1145 | ; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4/8 is valid
|
---|
[8225] | 1146 | ; @uses eax, ecx, edx
|
---|
| 1147 | ;
|
---|
| 1148 | align 16
|
---|
[11508] | 1149 | BEGINPROC EMEmulateLockCmpXchg
|
---|
| 1150 | push xBX
|
---|
| 1151 | %ifdef RT_ARCH_AMD64
|
---|
| 1152 | %ifdef RT_OS_WINDOWS
|
---|
| 1153 | ; rcx contains the first parameter already
|
---|
| 1154 | mov rbx, rdx ; rdx = 2nd parameter
|
---|
| 1155 | mov rdx, r8 ; r8 = 3rd parameter
|
---|
| 1156 | mov rax, r9 ; r9 = size of parameters
|
---|
| 1157 | %else
|
---|
| 1158 | mov rax, rcx ; rcx = size of parameters (4th)
|
---|
| 1159 | mov rcx, rdi ; rdi = 1st parameter
|
---|
| 1160 | mov rbx, rsi ; rsi = second parameter
|
---|
| 1161 | ;rdx contains the 3rd parameter already
|
---|
| 1162 | %endif ; !RT_OS_WINDOWS
|
---|
| 1163 | %else ; !RT_ARCH_AMD64
|
---|
[8225] | 1164 | mov ecx, [esp + 04h + 4] ; ecx = first parameter
|
---|
| 1165 | mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
|
---|
| 1166 | mov edx, [esp + 0ch + 4] ; edx = third parameter
|
---|
[11508] | 1167 | mov eax, [esp + 14h + 4] ; eax = size of parameters
|
---|
| 1168 | %endif
|
---|
[8225] | 1169 |
|
---|
[15413] | 1170 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[11508] | 1171 | cmp al, 8
|
---|
[12005] | 1172 | je short .do_qword ; 8 bytes variant
|
---|
[11508] | 1173 | %endif
|
---|
[8225] | 1174 | cmp al, 4
|
---|
| 1175 | je short .do_dword ; 4 bytes variant
|
---|
| 1176 | cmp al, 2
|
---|
| 1177 | je short .do_word ; 2 byte variant
|
---|
| 1178 | cmp al, 1
|
---|
| 1179 | je short .do_byte ; 1 bytes variant
|
---|
| 1180 | int3
|
---|
| 1181 |
|
---|
[11508] | 1182 | %ifdef RT_ARCH_AMD64
|
---|
| 1183 | .do_qword:
|
---|
| 1184 | ; load 2nd parameter's value
|
---|
| 1185 | mov rax, qword [rbx]
|
---|
| 1186 |
|
---|
[15413] | 1187 | lock cmpxchg qword [rcx], rdx ; do 8 bytes CMPXCHG
|
---|
[11508] | 1188 | mov qword [rbx], rax
|
---|
| 1189 | jmp short .done
|
---|
| 1190 | %endif
|
---|
| 1191 |
|
---|
[8225] | 1192 | .do_dword:
|
---|
| 1193 | ; load 2nd parameter's value
|
---|
[11508] | 1194 | mov eax, dword [xBX]
|
---|
[8225] | 1195 |
|
---|
[15413] | 1196 | lock cmpxchg dword [xCX], edx ; do 4 bytes CMPXCHG
|
---|
[11508] | 1197 | mov dword [xBX], eax
|
---|
[8225] | 1198 | jmp short .done
|
---|
| 1199 |
|
---|
| 1200 | .do_word:
|
---|
| 1201 | ; load 2nd parameter's value
|
---|
[11508] | 1202 | mov eax, dword [xBX]
|
---|
[8225] | 1203 |
|
---|
[15413] | 1204 | lock cmpxchg word [xCX], dx ; do 2 bytes CMPXCHG
|
---|
[11508] | 1205 | mov word [xBX], ax
|
---|
[8225] | 1206 | jmp short .done
|
---|
| 1207 |
|
---|
| 1208 | .do_byte:
|
---|
| 1209 | ; load 2nd parameter's value
|
---|
[11508] | 1210 | mov eax, dword [xBX]
|
---|
[8225] | 1211 |
|
---|
[15413] | 1212 | lock cmpxchg byte [xCX], dl ; do 1 byte CMPXCHG
|
---|
[11508] | 1213 | mov byte [xBX], al
|
---|
[8225] | 1214 |
|
---|
| 1215 | .done:
|
---|
| 1216 | ; collect flags and return.
|
---|
| 1217 | pushf
|
---|
[11508] | 1218 | pop MY_RET_REG
|
---|
[8225] | 1219 |
|
---|
[11508] | 1220 | pop xBX
|
---|
[8225] | 1221 | retn
|
---|
[15413] | 1222 |
|
---|
| 1223 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 1224 | .do_qword:
|
---|
| 1225 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 1226 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 1227 | BITS 64
|
---|
| 1228 | .sixtyfourbit_mode:
|
---|
| 1229 | and ebx, 0ffffffffh
|
---|
| 1230 | and esp, 0ffffffffh
|
---|
| 1231 | and ecx, 0ffffffffh
|
---|
| 1232 | mov rax, qword [rbx] ; load 2nd parameter's value
|
---|
| 1233 | mov rdx, qword [rsp + 0ch + 4] ; rdx = third parameter
|
---|
| 1234 |
|
---|
| 1235 | lock cmpxchg qword [rcx], rdx ; do 8 byte CMPXCHG
|
---|
| 1236 | mov qword [rbx], rax
|
---|
| 1237 | jmp far [.fpret wrt rip]
|
---|
| 1238 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 1239 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 1240 | BITS 32
|
---|
| 1241 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[11508] | 1242 | ENDPROC EMEmulateLockCmpXchg
|
---|
[8225] | 1243 |
|
---|
[12688] | 1244 |
|
---|
[8225] | 1245 | ;;
|
---|
| 1246 | ; Emulate CMPXCHG instruction, CDECL calling conv.
|
---|
[12989] | 1247 | ; VMMDECL(uint32_t) EMEmulateCmpXchg(void *pvParam1, uint64_t *pu32Param2, uint64_t u32Param3, size_t cbSize);
|
---|
[8225] | 1248 | ;
|
---|
[11508] | 1249 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[8225] | 1250 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
|
---|
| 1251 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
|
---|
| 1252 | ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
|
---|
[11508] | 1253 | ; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4 is valid.
|
---|
[8225] | 1254 | ; @uses eax, ecx, edx
|
---|
| 1255 | ;
|
---|
| 1256 | align 16
|
---|
[11508] | 1257 | BEGINPROC EMEmulateCmpXchg
|
---|
| 1258 | push xBX
|
---|
| 1259 | %ifdef RT_ARCH_AMD64
|
---|
| 1260 | %ifdef RT_OS_WINDOWS
|
---|
| 1261 | ; rcx contains the first parameter already
|
---|
| 1262 | mov rbx, rdx ; rdx = 2nd parameter
|
---|
| 1263 | mov rdx, r8 ; r8 = 3rd parameter
|
---|
| 1264 | mov rax, r9 ; r9 = size of parameters
|
---|
| 1265 | %else
|
---|
| 1266 | mov rax, rcx ; rcx = size of parameters (4th)
|
---|
| 1267 | mov rcx, rdi ; rdi = 1st parameter
|
---|
| 1268 | mov rbx, rsi ; rsi = second parameter
|
---|
| 1269 | ;rdx contains the 3rd parameter already
|
---|
| 1270 | %endif ; !RT_OS_WINDOWS
|
---|
| 1271 | %else ; !RT_ARCH_AMD64
|
---|
[8225] | 1272 | mov ecx, [esp + 04h + 4] ; ecx = first parameter
|
---|
| 1273 | mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
|
---|
| 1274 | mov edx, [esp + 0ch + 4] ; edx = third parameter
|
---|
[11508] | 1275 | mov eax, [esp + 14h + 4] ; eax = size of parameters
|
---|
| 1276 | %endif
|
---|
[8225] | 1277 |
|
---|
[15413] | 1278 | %ifdef CAN_DO_8_BYTE_OP
|
---|
[11508] | 1279 | cmp al, 8
|
---|
[12005] | 1280 | je short .do_qword ; 8 bytes variant
|
---|
[11508] | 1281 | %endif
|
---|
[8225] | 1282 | cmp al, 4
|
---|
| 1283 | je short .do_dword ; 4 bytes variant
|
---|
| 1284 | cmp al, 2
|
---|
| 1285 | je short .do_word ; 2 byte variant
|
---|
| 1286 | cmp al, 1
|
---|
| 1287 | je short .do_byte ; 1 bytes variant
|
---|
| 1288 | int3
|
---|
| 1289 |
|
---|
[11508] | 1290 | %ifdef RT_ARCH_AMD64
|
---|
| 1291 | .do_qword:
|
---|
| 1292 | ; load 2nd parameter's value
|
---|
| 1293 | mov rax, qword [rbx]
|
---|
| 1294 |
|
---|
| 1295 | cmpxchg qword [rcx], rdx ; do 8 bytes CMPXCHG
|
---|
| 1296 | mov qword [rbx], rax
|
---|
| 1297 | jmp short .done
|
---|
| 1298 | %endif
|
---|
| 1299 |
|
---|
[8225] | 1300 | .do_dword:
|
---|
| 1301 | ; load 2nd parameter's value
|
---|
[11508] | 1302 | mov eax, dword [xBX]
|
---|
[8225] | 1303 |
|
---|
[11508] | 1304 | cmpxchg dword [xCX], edx ; do 4 bytes CMPXCHG
|
---|
| 1305 | mov dword [xBX], eax
|
---|
[8225] | 1306 | jmp short .done
|
---|
| 1307 |
|
---|
| 1308 | .do_word:
|
---|
| 1309 | ; load 2nd parameter's value
|
---|
[11508] | 1310 | mov eax, dword [xBX]
|
---|
[8225] | 1311 |
|
---|
[11508] | 1312 | cmpxchg word [xCX], dx ; do 2 bytes CMPXCHG
|
---|
| 1313 | mov word [xBX], ax
|
---|
[8225] | 1314 | jmp short .done
|
---|
| 1315 |
|
---|
| 1316 | .do_byte:
|
---|
| 1317 | ; load 2nd parameter's value
|
---|
[11508] | 1318 | mov eax, dword [xBX]
|
---|
[8225] | 1319 |
|
---|
[11508] | 1320 | cmpxchg byte [xCX], dl ; do 1 byte CMPXCHG
|
---|
| 1321 | mov byte [xBX], al
|
---|
[8225] | 1322 |
|
---|
| 1323 | .done:
|
---|
| 1324 | ; collect flags and return.
|
---|
| 1325 | pushf
|
---|
[11508] | 1326 | pop MY_RET_REG
|
---|
[8225] | 1327 |
|
---|
[11508] | 1328 | pop xBX
|
---|
[8225] | 1329 | retn
|
---|
[15413] | 1330 |
|
---|
| 1331 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 1332 | .do_qword:
|
---|
| 1333 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 1334 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 1335 | BITS 64
|
---|
| 1336 | .sixtyfourbit_mode:
|
---|
| 1337 | and ebx, 0ffffffffh
|
---|
| 1338 | and esp, 0ffffffffh
|
---|
| 1339 | and ecx, 0ffffffffh
|
---|
| 1340 | mov rax, qword [rbx] ; load 2nd parameter's value
|
---|
| 1341 | mov rdx, qword [rsp + 0ch + 4] ; rdx = third parameter
|
---|
| 1342 |
|
---|
| 1343 | cmpxchg qword [rcx], rdx ; do 8 byte CMPXCHG
|
---|
| 1344 | mov qword [rbx], rax
|
---|
| 1345 | jmp far [.fpret wrt rip]
|
---|
| 1346 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 1347 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 1348 | BITS 32
|
---|
| 1349 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
[11508] | 1350 | ENDPROC EMEmulateCmpXchg
|
---|
[8225] | 1351 |
|
---|
[12688] | 1352 |
|
---|
[8225] | 1353 | ;;
|
---|
| 1354 | ; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv.
|
---|
[13561] | 1355 | ; VMMDECL(uint32_t) EMEmulateLockCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
|
---|
[8225] | 1356 | ;
|
---|
[13561] | 1357 | ; @returns EFLAGS after the operation, only the ZF flag is valid.
|
---|
| 1358 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
|
---|
| 1359 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Address of the eax register
|
---|
| 1360 | ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Address of the edx register
|
---|
| 1361 | ; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - EBX
|
---|
| 1362 | ; @param [esp + 14h] gcc:r8 msc:[rsp + 8] Param 5 - ECX
|
---|
[8225] | 1363 | ; @uses eax, ecx, edx
|
---|
| 1364 | ;
|
---|
| 1365 | align 16
|
---|
[11508] | 1366 | BEGINPROC EMEmulateLockCmpXchg8b
|
---|
[13561] | 1367 | push xBP
|
---|
| 1368 | push xBX
|
---|
| 1369 | %ifdef RT_ARCH_AMD64
|
---|
| 1370 | %ifdef RT_OS_WINDOWS
|
---|
| 1371 | mov rbp, rcx
|
---|
| 1372 | mov r10, rdx
|
---|
| 1373 | mov eax, dword [rdx]
|
---|
| 1374 | mov edx, dword [r8]
|
---|
| 1375 | mov rbx, r9
|
---|
| 1376 | mov ecx, [rsp + 28h + 16]
|
---|
| 1377 | %else
|
---|
| 1378 | mov rbp, rdi
|
---|
| 1379 | mov r10, rdx
|
---|
| 1380 | mov eax, dword [rsi]
|
---|
| 1381 | mov edx, dword [rdx]
|
---|
| 1382 | mov rbx, rcx
|
---|
| 1383 | mov rcx, r8
|
---|
| 1384 | %endif
|
---|
| 1385 | %else
|
---|
[8225] | 1386 | mov ebp, [esp + 04h + 8] ; ebp = first parameter
|
---|
| 1387 | mov eax, [esp + 08h + 8] ; &EAX
|
---|
| 1388 | mov eax, dword [eax]
|
---|
| 1389 | mov edx, [esp + 0ch + 8] ; &EDX
|
---|
| 1390 | mov edx, dword [edx]
|
---|
| 1391 | mov ebx, [esp + 10h + 8] ; EBX
|
---|
| 1392 | mov ecx, [esp + 14h + 8] ; ECX
|
---|
[13561] | 1393 | %endif
|
---|
[8225] | 1394 |
|
---|
[13908] | 1395 | %ifdef RT_OS_OS2
|
---|
| 1396 | lock cmpxchg8b [xBP] ; do CMPXCHG8B
|
---|
| 1397 | %else
|
---|
[13561] | 1398 | lock cmpxchg8b qword [xBP] ; do CMPXCHG8B
|
---|
[13908] | 1399 | %endif
|
---|
| 1400 |
|
---|
[13561] | 1401 | %ifdef RT_ARCH_AMD64
|
---|
| 1402 | %ifdef RT_OS_WINDOWS
|
---|
| 1403 | mov dword [r10], eax
|
---|
| 1404 | mov dword [r8], edx
|
---|
| 1405 | %else
|
---|
| 1406 | mov dword [rsi], eax
|
---|
| 1407 | mov dword [r10], edx
|
---|
| 1408 | %endif
|
---|
| 1409 | %else
|
---|
[9250] | 1410 | mov ebx, dword [esp + 08h + 8]
|
---|
| 1411 | mov dword [ebx], eax
|
---|
| 1412 | mov ebx, dword [esp + 0ch + 8]
|
---|
| 1413 | mov dword [ebx], edx
|
---|
[13561] | 1414 | %endif
|
---|
[8225] | 1415 | ; collect flags and return.
|
---|
| 1416 | pushf
|
---|
[13561] | 1417 | pop MY_RET_REG
|
---|
[8225] | 1418 |
|
---|
[13561] | 1419 | pop xBX
|
---|
| 1420 | pop xBP
|
---|
[8225] | 1421 | retn
|
---|
[11508] | 1422 | ENDPROC EMEmulateLockCmpXchg8b
|
---|
[8225] | 1423 |
|
---|
| 1424 | ;;
|
---|
| 1425 | ; Emulate CMPXCHG8B instruction, CDECL calling conv.
|
---|
[13561] | 1426 | ; VMMDECL(uint32_t) EMEmulateCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
|
---|
[8225] | 1427 | ;
|
---|
[11508] | 1428 | ; @returns EFLAGS after the operation, only arithmetic flags are valid.
|
---|
[13561] | 1429 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
|
---|
| 1430 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Address of the eax register
|
---|
| 1431 | ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Address of the edx register
|
---|
| 1432 | ; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - EBX
|
---|
| 1433 | ; @param [esp + 14h] gcc:r8 msc:[rsp + 8] Param 5 - ECX
|
---|
[8225] | 1434 | ; @uses eax, ecx, edx
|
---|
| 1435 | ;
|
---|
| 1436 | align 16
|
---|
[11508] | 1437 | BEGINPROC EMEmulateCmpXchg8b
|
---|
[13561] | 1438 | push xBP
|
---|
| 1439 | push xBX
|
---|
| 1440 | %ifdef RT_ARCH_AMD64
|
---|
| 1441 | %ifdef RT_OS_WINDOWS
|
---|
| 1442 | mov rbp, rcx
|
---|
| 1443 | mov r10, rdx
|
---|
| 1444 | mov eax, dword [rdx]
|
---|
| 1445 | mov edx, dword [r8]
|
---|
| 1446 | mov rbx, r9
|
---|
| 1447 | mov ecx, [rsp + 28h + 16]
|
---|
| 1448 | %else
|
---|
| 1449 | mov rbp, rdi
|
---|
| 1450 | mov r10, rdx
|
---|
| 1451 | mov eax, dword [rsi]
|
---|
| 1452 | mov edx, dword [rdx]
|
---|
| 1453 | mov rbx, rcx
|
---|
| 1454 | mov rcx, r8
|
---|
| 1455 | %endif
|
---|
| 1456 | %else
|
---|
[8225] | 1457 | mov ebp, [esp + 04h + 8] ; ebp = first parameter
|
---|
| 1458 | mov eax, [esp + 08h + 8] ; &EAX
|
---|
| 1459 | mov eax, dword [eax]
|
---|
| 1460 | mov edx, [esp + 0ch + 8] ; &EDX
|
---|
| 1461 | mov edx, dword [edx]
|
---|
| 1462 | mov ebx, [esp + 10h + 8] ; EBX
|
---|
| 1463 | mov ecx, [esp + 14h + 8] ; ECX
|
---|
[13561] | 1464 | %endif
|
---|
[8225] | 1465 |
|
---|
[13908] | 1466 | %ifdef RT_OS_OS2
|
---|
| 1467 | cmpxchg8b [xBP] ; do CMPXCHG8B
|
---|
| 1468 | %else
|
---|
[13561] | 1469 | cmpxchg8b qword [xBP] ; do CMPXCHG8B
|
---|
[13908] | 1470 | %endif
|
---|
[13832] | 1471 |
|
---|
[13561] | 1472 | %ifdef RT_ARCH_AMD64
|
---|
| 1473 | %ifdef RT_OS_WINDOWS
|
---|
| 1474 | mov dword [r10], eax
|
---|
| 1475 | mov dword [r8], edx
|
---|
| 1476 | %else
|
---|
| 1477 | mov dword [rsi], eax
|
---|
| 1478 | mov dword [r10], edx
|
---|
| 1479 | %endif
|
---|
| 1480 | %else
|
---|
[9250] | 1481 | mov ebx, dword [esp + 08h + 8]
|
---|
| 1482 | mov dword [ebx], eax
|
---|
| 1483 | mov ebx, dword [esp + 0ch + 8]
|
---|
| 1484 | mov dword [ebx], edx
|
---|
[13561] | 1485 | %endif
|
---|
[8225] | 1486 |
|
---|
| 1487 | ; collect flags and return.
|
---|
| 1488 | pushf
|
---|
[13561] | 1489 | pop MY_RET_REG
|
---|
[8225] | 1490 |
|
---|
[13561] | 1491 | pop xBX
|
---|
| 1492 | pop xBP
|
---|
[8225] | 1493 | retn
|
---|
[11508] | 1494 | ENDPROC EMEmulateCmpXchg8b
|
---|
[8225] | 1495 |
|
---|
[30338] | 1496 |
|
---|
| 1497 | ;;
|
---|
| 1498 | ; Emulate LOCK XADD instruction.
|
---|
| 1499 | ; VMMDECL(uint32_t) EMEmulateLockXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
|
---|
| 1500 | ;
|
---|
| 1501 | ; @returns (eax=)eflags
|
---|
| 1502 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item.
|
---|
| 1503 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter - pointer to second parameter (general register)
|
---|
| 1504 | ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Size of parameters - {1,2,4,8}.
|
---|
| 1505 | ;
|
---|
| 1506 | align 16
|
---|
| 1507 | BEGINPROC EMEmulateLockXAdd
|
---|
| 1508 | %ifdef RT_ARCH_AMD64
|
---|
| 1509 | %ifdef RT_OS_WINDOWS
|
---|
| 1510 | mov rax, r8 ; eax = size of parameters
|
---|
| 1511 | %else ; !RT_OS_WINDOWS
|
---|
| 1512 | mov rax, rdx ; rax = size of parameters
|
---|
| 1513 | mov rcx, rdi ; rcx = first parameter
|
---|
| 1514 | mov rdx, rsi ; rdx = second parameter
|
---|
| 1515 | %endif ; !RT_OS_WINDOWS
|
---|
| 1516 | %else ; !RT_ARCH_AMD64
|
---|
| 1517 | mov eax, [esp + 0ch] ; eax = size of parameters
|
---|
| 1518 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 1519 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 1520 | %endif
|
---|
| 1521 |
|
---|
| 1522 | ; switch on size
|
---|
| 1523 | %ifdef CAN_DO_8_BYTE_OP
|
---|
| 1524 | cmp al, 8
|
---|
| 1525 | je short .do_qword ; 8 bytes variant
|
---|
| 1526 | %endif
|
---|
| 1527 | cmp al, 4
|
---|
| 1528 | je short .do_dword ; 4 bytes variant
|
---|
| 1529 | cmp al, 2
|
---|
| 1530 | je short .do_word ; 2 byte variant
|
---|
| 1531 | cmp al, 1
|
---|
| 1532 | je short .do_byte ; 1 bytes variant
|
---|
| 1533 | int3
|
---|
| 1534 |
|
---|
| 1535 | ; workers
|
---|
| 1536 | %ifdef RT_ARCH_AMD64
|
---|
| 1537 | .do_qword:
|
---|
| 1538 | mov rax, qword [xDX] ; load 2nd parameter's value
|
---|
| 1539 | lock xadd qword [MY_PTR_REG], rax ; do 8 bytes XADD
|
---|
| 1540 | mov qword [xDX], rax
|
---|
| 1541 | jmp short .done
|
---|
| 1542 | %endif
|
---|
| 1543 |
|
---|
| 1544 | .do_dword:
|
---|
| 1545 | mov eax, dword [xDX] ; load 2nd parameter's value
|
---|
| 1546 | lock xadd dword [MY_PTR_REG], eax ; do 4 bytes XADD
|
---|
| 1547 | mov dword [xDX], eax
|
---|
| 1548 | jmp short .done
|
---|
| 1549 |
|
---|
| 1550 | .do_word:
|
---|
| 1551 | mov eax, dword [xDX] ; load 2nd parameter's value
|
---|
| 1552 | lock xadd word [MY_PTR_REG], ax ; do 2 bytes XADD
|
---|
| 1553 | mov word [xDX], ax
|
---|
| 1554 | jmp short .done
|
---|
| 1555 |
|
---|
| 1556 | .do_byte:
|
---|
| 1557 | mov eax, dword [xDX] ; load 2nd parameter's value
|
---|
| 1558 | lock xadd byte [MY_PTR_REG], al ; do 1 bytes XADD
|
---|
| 1559 | mov byte [xDX], al
|
---|
| 1560 |
|
---|
| 1561 | .done:
|
---|
| 1562 | ; collect flags and return.
|
---|
| 1563 | pushf
|
---|
| 1564 | pop MY_RET_REG
|
---|
| 1565 |
|
---|
| 1566 | retn
|
---|
| 1567 |
|
---|
| 1568 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 1569 | .do_qword:
|
---|
| 1570 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 1571 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 1572 | BITS 64
|
---|
| 1573 | .sixtyfourbit_mode:
|
---|
| 1574 | and esp, 0ffffffffh
|
---|
| 1575 | and edx, 0ffffffffh
|
---|
| 1576 | and MY_PTR_REG, 0ffffffffh
|
---|
| 1577 | mov rax, qword [rdx] ; load 2nd parameter's value
|
---|
| 1578 | and [MY_PTR_REG64], rax ; do 8 bytes XADD
|
---|
| 1579 | jmp far [.fpret wrt rip]
|
---|
| 1580 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 1581 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 1582 | BITS 32
|
---|
| 1583 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 1584 | ENDPROC EMEmulateLockXAdd
|
---|
| 1585 |
|
---|
| 1586 |
|
---|
| 1587 | ;;
|
---|
| 1588 | ; Emulate XADD instruction.
|
---|
| 1589 | ; VMMDECL(uint32_t) EMEmulateXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
|
---|
| 1590 | ;
|
---|
| 1591 | ; @returns eax=eflags
|
---|
| 1592 | ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item.
|
---|
| 1593 | ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter - pointer to second parameter (general register)
|
---|
| 1594 | ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Size of parameters - {1,2,4,8}.
|
---|
| 1595 | align 16
|
---|
| 1596 | BEGINPROC EMEmulateXAdd
|
---|
| 1597 | %ifdef RT_ARCH_AMD64
|
---|
| 1598 | %ifdef RT_OS_WINDOWS
|
---|
| 1599 | mov rax, r8 ; eax = size of parameters
|
---|
| 1600 | %else ; !RT_OS_WINDOWS
|
---|
| 1601 | mov rax, rdx ; rax = size of parameters
|
---|
| 1602 | mov rcx, rdi ; rcx = first parameter
|
---|
| 1603 | mov rdx, rsi ; rdx = second parameter
|
---|
| 1604 | %endif ; !RT_OS_WINDOWS
|
---|
| 1605 | %else ; !RT_ARCH_AMD64
|
---|
| 1606 | mov eax, [esp + 0ch] ; eax = size of parameters
|
---|
| 1607 | mov ecx, [esp + 04h] ; ecx = first parameter
|
---|
| 1608 | mov edx, [esp + 08h] ; edx = second parameter
|
---|
| 1609 | %endif
|
---|
| 1610 |
|
---|
| 1611 | ; switch on size
|
---|
| 1612 | %ifdef CAN_DO_8_BYTE_OP
|
---|
| 1613 | cmp al, 8
|
---|
| 1614 | je short .do_qword ; 8 bytes variant
|
---|
| 1615 | %endif
|
---|
| 1616 | cmp al, 4
|
---|
| 1617 | je short .do_dword ; 4 bytes variant
|
---|
| 1618 | cmp al, 2
|
---|
| 1619 | je short .do_word ; 2 byte variant
|
---|
| 1620 | cmp al, 1
|
---|
| 1621 | je short .do_byte ; 1 bytes variant
|
---|
| 1622 | int3
|
---|
| 1623 |
|
---|
| 1624 | ; workers
|
---|
| 1625 | %ifdef RT_ARCH_AMD64
|
---|
| 1626 | .do_qword:
|
---|
| 1627 | mov rax, qword [xDX] ; load 2nd parameter's value
|
---|
| 1628 | xadd qword [MY_PTR_REG], rax ; do 8 bytes XADD
|
---|
| 1629 | mov qword [xDX], rax
|
---|
| 1630 | jmp short .done
|
---|
| 1631 | %endif
|
---|
| 1632 |
|
---|
| 1633 | .do_dword:
|
---|
| 1634 | mov eax, dword [xDX] ; load 2nd parameter's value
|
---|
| 1635 | xadd dword [MY_PTR_REG], eax ; do 4 bytes XADD
|
---|
| 1636 | mov dword [xDX], eax
|
---|
| 1637 | jmp short .done
|
---|
| 1638 |
|
---|
| 1639 | .do_word:
|
---|
| 1640 | mov eax, dword [xDX] ; load 2nd parameter's value
|
---|
| 1641 | xadd word [MY_PTR_REG], ax ; do 2 bytes XADD
|
---|
| 1642 | mov word [xDX], ax
|
---|
| 1643 | jmp short .done
|
---|
| 1644 |
|
---|
| 1645 | .do_byte:
|
---|
| 1646 | mov eax, dword [xDX] ; load 2nd parameter's value
|
---|
| 1647 | xadd byte [MY_PTR_REG], al ; do 1 bytes XADD
|
---|
| 1648 | mov byte [xDX], al
|
---|
| 1649 |
|
---|
| 1650 | .done:
|
---|
| 1651 | ; collect flags and return.
|
---|
| 1652 | pushf
|
---|
| 1653 | pop MY_RET_REG
|
---|
| 1654 |
|
---|
| 1655 | retn
|
---|
| 1656 |
|
---|
| 1657 | %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 1658 | .do_qword:
|
---|
| 1659 | db 0xea ; jmp far .sixtyfourbit_mode
|
---|
| 1660 | dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
|
---|
| 1661 | BITS 64
|
---|
| 1662 | .sixtyfourbit_mode:
|
---|
| 1663 | and esp, 0ffffffffh
|
---|
| 1664 | and edx, 0ffffffffh
|
---|
| 1665 | and MY_PTR_REG, 0ffffffffh
|
---|
| 1666 | mov rax, qword [rdx] ; load 2nd parameter's value
|
---|
| 1667 | and [MY_PTR_REG64], rax ; do 8 bytes XADD
|
---|
| 1668 | jmp far [.fpret wrt rip]
|
---|
| 1669 | .fpret: ; 16:32 Pointer to .done.
|
---|
| 1670 | dd .done, NAME(SUPR0AbsKernelCS)
|
---|
| 1671 | BITS 32
|
---|
| 1672 | %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
|
---|
| 1673 | ENDPROC EMEmulateXAdd
|
---|
| 1674 |
|
---|