; $Id: EMAllA.asm 20278 2007-04-09 11:56:29Z sandervl $ ;; @file ; EM Assembly Routines. ; ; ; Copyright (C) 2006-2007 innotek GmbH ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; ; you can redistribute it and/or modify it under the terms of the GNU ; General Public License as published by the Free Software Foundation, ; in version 2 as it comes in the "COPYING" file of the VirtualBox OSE ; distribution. VirtualBox OSE is distributed in the hope that it will ; be useful, but WITHOUT ANY WARRANTY of any kind. ;******************************************************************************* ;* Header Files * ;******************************************************************************* %include "VBox/asmdefs.mac" %include "VBox/err.mac" %include "VBox/x86.mac" BEGINCODE ;; ; Emulate lock CMPXCHG instruction, CDECL calling conv. ; EMGCDECL(uint32_t) EMGCEmulateLockCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); ; ; @returns eax=0 if data written, other code - invalid access, #PF was generated. ; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter ; @param [esp + 08h] Param 2 - Second parameter - pointer to second parameter (eax) ; @param [esp + 0ch] Param 3 - Third parameter - third parameter ; @param [esp + 10h] Param 4 - Size of parameters, only 1/2/4 is valid. ; @param [esp + 14h] Param 4 - Pointer to eflags (out) ; @uses eax, ecx, edx ; align 16 BEGINPROC EMGCEmulateLockCmpXchg push ebx mov ecx, [esp + 04h + 4] ; ecx = first parameter mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax) mov edx, [esp + 0ch + 4] ; edx = third parameter mov eax, [esp + 10h + 4] ; eax = size of parameters cmp al, 4 je short .do_dword ; 4 bytes variant cmp al, 2 je short .do_word ; 2 byte variant cmp al, 1 je short .do_byte ; 1 bytes variant int3 .do_dword: ; load 2nd parameter's value mov eax, dword [ebx] lock cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG mov dword [ebx], eax jmp short .done .do_word: ; load 2nd parameter's value mov eax, dword [ebx] lock cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG mov word [ebx], ax jmp short .done .do_byte: ; load 2nd parameter's value mov eax, dword [ebx] lock cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG mov byte [ebx], al .done: ; collect flags and return. pushf pop eax mov edx, [esp + 14h + 4] ; eflags pointer mov dword [edx], eax pop ebx mov eax, VINF_SUCCESS retn ; Read error - we will be here after our page fault handler. GLOBALNAME EMGCEmulateLockCmpXchg_Error pop ebx mov eax, VERR_ACCESS_DENIED ret ENDPROC EMGCEmulateLockCmpXchg ;; ; Emulate CMPXCHG instruction, CDECL calling conv. ; EMGCDECL(uint32_t) EMGCEmulateCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); ; ; @returns eax=0 if data written, other code - invalid access, #PF was generated. ; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter ; @param [esp + 08h] Param 2 - Second parameter - pointer to second parameter (eax) ; @param [esp + 0ch] Param 3 - Third parameter - third parameter ; @param [esp + 10h] Param 4 - Size of parameters, only 1/2/4 is valid. ; @param [esp + 14h] Param 4 - Pointer to eflags (out) ; @uses eax, ecx, edx ; align 16 BEGINPROC EMGCEmulateCmpXchg push ebx mov ecx, [esp + 04h + 4] ; ecx = first parameter mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax) mov edx, [esp + 0ch + 4] ; edx = third parameter mov eax, [esp + 10h + 4] ; eax = size of parameters cmp al, 4 je short .do_dword ; 4 bytes variant cmp al, 2 je short .do_word ; 2 byte variant cmp al, 1 je short .do_byte ; 1 bytes variant int3 .do_dword: ; load 2nd parameter's value mov eax, dword [ebx] cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG mov dword [ebx], eax jmp short .done .do_word: ; load 2nd parameter's value mov eax, dword [ebx] cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG mov word [ebx], ax jmp short .done .do_byte: ; load 2nd parameter's value mov eax, dword [ebx] cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG mov byte [ebx], al .done: ; collect flags and return. pushf pop eax mov edx, [esp + 14h + 4] ; eflags pointer mov dword [edx], eax pop ebx mov eax, VINF_SUCCESS retn ; Read error - we will be here after our page fault handler. GLOBALNAME EMGCEmulateCmpXchg_Error pop ebx mov eax, VERR_ACCESS_DENIED ret ENDPROC EMGCEmulateCmpXchg