VirtualBox

Changeset 20588 in vbox for trunk


Ignore:
Timestamp:
Jun 15, 2009 11:26:16 AM (15 years ago)
Author:
vboxsync
Message:

Emulate lock and & lock xor.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/em.h

    r20408 r20588  
    153153VMMDECL(int)        EMEmulateLockOr(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
    154154VMMDECL(uint32_t)   EMEmulateXor(void *pvParam1, uint64_t u64Param2, size_t cb);
     155VMMDECL(int)        EMEmulateLockXor(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
    155156VMMDECL(uint32_t)   EMEmulateAdd(void *pvParam1, uint64_t u64Param2, size_t cb);
     157VMMDECL(int)        EMEmulateLockAnd(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
    156158VMMDECL(uint32_t)   EMEmulateSub(void *pvParam1, uint64_t u64Param2, size_t cb);
    157159VMMDECL(uint32_t)   EMEmulateAdcWithCarrySet(void *pvParam1, uint64_t u64Param2, size_t cb);
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r20530 r20588  
    31063106             && pDis->pCurInstr->opcode != OP_XADD
    31073107             && pDis->pCurInstr->opcode != OP_OR
     3108             && pDis->pCurInstr->opcode != OP_AND
     3109             && pDis->pCurInstr->opcode != OP_XOR
    31083110             && pDis->pCurInstr->opcode != OP_BTR
    31093111            )
     
    31163118        ||  (   (pDis->prefix & PREFIX_LOCK)
    31173119             && pDis->pCurInstr->opcode != OP_OR
     3120             && pDis->pCurInstr->opcode != OP_AND
     3121             && pDis->pCurInstr->opcode != OP_XOR
    31183122             && pDis->pCurInstr->opcode != OP_BTR
    31193123             && pDis->pCurInstr->opcode != OP_CMPXCHG
     
    32713275        INTERPRET_CASE_EX_PARAM2(OP_INC,Inc, IncDec, EMEmulateInc);
    32723276        INTERPRET_CASE(OP_POP,Pop);
    3273         INTERPRET_CASE_EX_LOCK_PARAM3(OP_OR, Or, OrXorAnd, EMEmulateOr, EMEmulateLockOr);
    3274         INTERPRET_CASE_EX_PARAM3(OP_XOR,Xor, OrXorAnd, EMEmulateXor);
    3275         INTERPRET_CASE_EX_PARAM3(OP_AND,And, OrXorAnd, EMEmulateAnd);
     3277        INTERPRET_CASE_EX_LOCK_PARAM3(OP_OR, Or,  OrXorAnd, EMEmulateOr, EMEmulateLockOr);
     3278        INTERPRET_CASE_EX_LOCK_PARAM3(OP_XOR,Xor, OrXorAnd, EMEmulateXor, EMEmulateLockXor);
     3279        INTERPRET_CASE_EX_LOCK_PARAM3(OP_AND,And, OrXorAnd, EMEmulateAnd, EMEmulateLockAnd);
    32763280        INTERPRET_CASE(OP_MOV,Mov);
    32773281#ifndef IN_RC
  • trunk/src/VBox/VMM/VMMAll/EMAllA.asm

    r15420 r20588  
    212212
    213213;;
     214; Emulate LOCK AND instruction.
     215; VMMDECL(int)      EMEmulateLockAnd(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
     216;
     217; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
     218; @param    [esp + 04h]  gcc:rdi  msc:rcx   Param 1 - First parameter - pointer to data item (the real stuff).
     219; @param    [esp + 08h]  gcc:rsi  msc:rdx   Param 2 - Second parameter- the immediate / register value.
     220; @param    [esp + 10h]  gcc:rdx  msc:r8    Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
     221; @param    [esp + 14h]  gcc:rcx  msc:r9    Param 4 - Where to store the eflags on success.
     222;                                                     only arithmetic flags are valid.
     223align 16
     224BEGINPROC   EMEmulateLockAnd
     225%ifdef RT_ARCH_AMD64
     226%ifdef RT_OS_WINDOWS
     227    mov     rax, r8                     ; eax = size of parameters
     228%else   ; !RT_OS_WINDOWS
     229    mov     rax, rdx                    ; rax = size of parameters
     230    mov     rcx, rdi                    ; rcx = first parameter
     231    mov     rdx, rsi                    ; rdx = second parameter
     232%endif  ; !RT_OS_WINDOWS
     233%else   ; !RT_ARCH_AMD64
     234    mov     eax, [esp + 10h]            ; eax = size of parameters
     235    mov     ecx, [esp + 04h]            ; ecx = first parameter (MY_PTR_REG)
     236    mov     edx, [esp + 08h]            ; edx = second parameter
     237%endif
     238
     239    ; switch on size
     240%ifdef CAN_DO_8_BYTE_OP
     241    cmp     al, 8
     242    je short .do_qword                  ; 8 bytes variant
     243%endif
     244    cmp     al, 4
     245    je short .do_dword                  ; 4 bytes variant
     246    cmp     al, 2
     247    je short .do_word                   ; 2 byte variant
     248    cmp     al, 1
     249    je short .do_byte                   ; 1 bytes variant
     250    int3
     251
     252    ; workers
     253%ifdef RT_ARCH_AMD64
     254.do_qword:
     255    lock and [MY_PTR_REG], rdx           ; do 8 bytes OR
     256    jmp short .done
     257%endif
     258
     259.do_dword:
     260    lock and [MY_PTR_REG], edx           ; do 4 bytes OR
     261    jmp short .done
     262
     263.do_word:
     264    lock and [MY_PTR_REG], dx            ; do 2 bytes OR
     265    jmp short .done
     266
     267.do_byte:
     268    lock and [MY_PTR_REG], dl            ; do 1 byte OR
     269
     270    ; collect flags and return.
     271.done:
     272    pushf
     273%ifdef RT_ARCH_AMD64
     274    pop    rax
     275 %ifdef RT_OS_WINDOWS
     276    mov    [r9], eax
     277 %else  ; !RT_OS_WINDOWS
     278    mov    [rcx], eax
     279 %endif ; !RT_OS_WINDOWS
     280%else   ; !RT_ARCH_AMD64
     281    mov     eax, [esp + 14h + 4]
     282    pop     dword [eax]
     283%endif
     284    mov     eax, VINF_SUCCESS
     285    retn
     286
     287%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     288.do_qword:
     289    db      0xea                        ; jmp far .sixtyfourbit_mode
     290    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
     291BITS 64
     292.sixtyfourbit_mode:
     293    and     esp, 0ffffffffh
     294    and     MY_PTR_REG, 0ffffffffh
     295    mov     rdx, qword [rsp + 08h]      ; rdx = second parameter
     296    lock and [MY_PTR_REG64], rdx         ; do 8 bytes OR
     297    jmp far [.fpret wrt rip]
     298.fpret:                                 ; 16:32 Pointer to .done.
     299    dd      .done, NAME(SUPR0AbsKernelCS)
     300BITS 32
     301%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     302
     303
     304%ifdef IN_RC
     305; #PF resume point.
     306GLOBALNAME EMEmulateLockAnd_Error
     307    mov     eax, VERR_ACCESS_DENIED
     308    ret
     309%endif
     310
     311ENDPROC     EMEmulateLockAnd
     312
     313;;
    214314; Emulate OR instruction, CDECL calling conv.
    215315; VMMDECL(uint32_t) EMEmulateOr(void *pvParam1, uint64_t u64Param2, size_t cb);
     
    473573ENDPROC     EMEmulateXor
    474574
     575;;
     576; Emulate LOCK XOR instruction.
     577; VMMDECL(int)      EMEmulateLockXor(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
     578;
     579; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
     580; @param    [esp + 04h]  gcc:rdi  msc:rcx   Param 1 - First parameter - pointer to data item (the real stuff).
     581; @param    [esp + 08h]  gcc:rsi  msc:rdx   Param 2 - Second parameter- the immediate / register value.
     582; @param    [esp + 10h]  gcc:rdx  msc:r8    Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
     583; @param    [esp + 14h]  gcc:rcx  msc:r9    Param 4 - Where to store the eflags on success.
     584;                                                     only arithmetic flags are valid.
     585align 16
     586BEGINPROC   EMEmulateLockXor
     587%ifdef RT_ARCH_AMD64
     588%ifdef RT_OS_WINDOWS
     589    mov     rax, r8                     ; eax = size of parameters
     590%else   ; !RT_OS_WINDOWS
     591    mov     rax, rdx                    ; rax = size of parameters
     592    mov     rcx, rdi                    ; rcx = first parameter
     593    mov     rdx, rsi                    ; rdx = second parameter
     594%endif  ; !RT_OS_WINDOWS
     595%else   ; !RT_ARCH_AMD64
     596    mov     eax, [esp + 10h]            ; eax = size of parameters
     597    mov     ecx, [esp + 04h]            ; ecx = first parameter (MY_PTR_REG)
     598    mov     edx, [esp + 08h]            ; edx = second parameter
     599%endif
     600
     601    ; switch on size
     602%ifdef CAN_DO_8_BYTE_OP
     603    cmp     al, 8
     604    je short .do_qword                  ; 8 bytes variant
     605%endif
     606    cmp     al, 4
     607    je short .do_dword                  ; 4 bytes variant
     608    cmp     al, 2
     609    je short .do_word                   ; 2 byte variant
     610    cmp     al, 1
     611    je short .do_byte                   ; 1 bytes variant
     612    int3
     613
     614    ; workers
     615%ifdef RT_ARCH_AMD64
     616.do_qword:
     617    lock xor [MY_PTR_REG], rdx           ; do 8 bytes OR
     618    jmp short .done
     619%endif
     620
     621.do_dword:
     622    lock xor [MY_PTR_REG], edx           ; do 4 bytes OR
     623    jmp short .done
     624
     625.do_word:
     626    lock xor [MY_PTR_REG], dx            ; do 2 bytes OR
     627    jmp short .done
     628
     629.do_byte:
     630    lock xor [MY_PTR_REG], dl            ; do 1 byte OR
     631
     632    ; collect flags and return.
     633.done:
     634    pushf
     635%ifdef RT_ARCH_AMD64
     636    pop    rax
     637 %ifdef RT_OS_WINDOWS
     638    mov    [r9], eax
     639 %else  ; !RT_OS_WINDOWS
     640    mov    [rcx], eax
     641 %endif ; !RT_OS_WINDOWS
     642%else   ; !RT_ARCH_AMD64
     643    mov     eax, [esp + 14h + 4]
     644    pop     dword [eax]
     645%endif
     646    mov     eax, VINF_SUCCESS
     647    retn
     648
     649%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     650.do_qword:
     651    db      0xea                        ; jmp far .sixtyfourbit_mode
     652    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
     653BITS 64
     654.sixtyfourbit_mode:
     655    and     esp, 0ffffffffh
     656    and     MY_PTR_REG, 0ffffffffh
     657    mov     rdx, qword [rsp + 08h]      ; rdx = second parameter
     658    lock xor [MY_PTR_REG64], rdx         ; do 8 bytes OR
     659    jmp far [.fpret wrt rip]
     660.fpret:                                 ; 16:32 Pointer to .done.
     661    dd      .done, NAME(SUPR0AbsKernelCS)
     662BITS 32
     663%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     664
     665
     666%ifdef IN_RC
     667; #PF resume point.
     668GLOBALNAME EMEmulateLockXor_Error
     669    mov     eax, VERR_ACCESS_DENIED
     670    ret
     671%endif
     672
     673ENDPROC     EMEmulateLockXor
    475674
    476675;;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette