diff options
Diffstat (limited to 'private/mvdm/v86/monitor/i386/fastpm.asm')
-rw-r--r-- | private/mvdm/v86/monitor/i386/fastpm.asm | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/private/mvdm/v86/monitor/i386/fastpm.asm b/private/mvdm/v86/monitor/i386/fastpm.asm new file mode 100644 index 000000000..e42959d04 --- /dev/null +++ b/private/mvdm/v86/monitor/i386/fastpm.asm @@ -0,0 +1,357 @@ + title "Fast Protected Mode services" +;++ +; +; Copyright (c) 1989 Microsoft Corporation +; +; Module Name: +; +; fastpm.asm +; +; Abstract: +; +; This module implements a fast entry to and exit from protected mode +; +; Author: +; +; Dave Hastings (daveh) 26-Jul-91 +; +;-- +.386p + +include ks386.inc +include callconv.inc +include bop.inc +include vint.inc +include vdmtb.inc + +_TEXT SEGMENT PARA PUBLIC 'CODE' + ASSUME DS:NOTHING, ES:NOTHING, SS:FLAT, FS:NOTHING, GS:NOTHING +_TEXT ENDS + +_DATA SEGMENT DWORD PUBLIC 'DATA' + extrn _VdmTib:Dword + + public _NTVDMpLockPrefixTable +_NTVDMpLockPrefixTable label dword + dd offset FLAT:_ntvdmlock1 + dd offset FLAT:_ntvdmlock2 + dd 0 + +_DATA ENDS + +_TEXT SEGMENT + +; Interrupt type definitions +CPU_YODA_INT equ 4 +BIT_CPU_YODA_INT equ 0 +CPU_HW_RESET equ 0 +BIT_CPU_HW_RESET equ 1 +CPU_TIMER_TICK equ 1 +BIT_CPU_TIMER_TICK equ 2 +CPU_HW_INT equ 3 +BIT_CPU_HW_INT equ 3 + + page ,132 + subttl "FastEnterPm" +;++ +; +; Routine Description: +; +; This routine is a faster way to enter 16 bit vdm protected mode. +; Instead of making a system call, we just save the 32 bit state +; into the VdmTib, restore the Vdm state from the VdmTib, and do +; a far return to the application. +; +; Arguments: +; +; ss:sp + 4 = pointer to VdmTib +; +; Returns: +; +; nothing. +; + assume DS:FLAT +cPublicProc _FastEnterPm,0 + + push ebp + mov ebp,esp ; set up stack frame + + push ebx ; free up reg for pointer + lea ebx,_VdmTib + + ; translate the interrupt flag to the virtual interrupt flag + + test [ebx].VtVdmContext.CsEFlags,dword ptr EFLAGS_INTERRUPT_MASK + jz fe10 + +_ntvdmlock1: + lock or dword ptr ds:FIXED_NTVDMSTATE_LINEAR,dword ptr VDM_VIRTUAL_INTERRUPTS + test dword ptr ds:FIXED_NTVDMSTATE_LINEAR,dword ptr VDM_INTERRUPT_PENDING + jz fe20 + + ; set up event info for an interrupt acknowlege + + mov word ptr [ebx].VtEventInfo.EiEvent,VdmIntAck + mov word ptr [ebx].VtEventInfo.EiInstructionSize,0 + mov word ptr [ebx].VtEventInfo.EiIntAckInfo,0 + + pop ebx + mov esp,ebp + pop ebp + stdRET _FastEnterPm + +fe10: +_ntvdmlock2: + lock and dword ptr ds:FIXED_NTVDMSTATE_LINEAR, NOT VDM_VIRTUAL_INTERRUPTS +fe20: + mov [ebx].VtMonitorContext.CsEax,eax + mov eax,[ebp - 4] + mov [ebx].VtMonitorContext.CsEbx,eax + mov [ebx].VtMonitorContext.CsEcx,ecx + mov [ebx].VtMonitorContext.CsEdx,edx + mov [ebx].VtMonitorContext.CsEsi,esi + mov [ebx].VtMonitorContext.CsEdi,edi + mov eax,[ebp] + mov [ebx].VtMonitorContext.CsEbp,eax + mov eax,ebp + + add eax,8 ; pop ebp and ret addr + + mov [ebx].VtMonitorContext.CsEsp,eax + mov eax,[ebp + 4] + mov [ebx].VtMonitorContext.CsEip,eax + mov eax,cs + mov [ebx].VtMonitorContext.CsSegCs,eax + mov eax,ss + mov [ebx].VtMonitorContext.CsSegSs,eax + mov eax,ds + mov [ebx].VtMonitorContext.CsSegDs,eax + mov eax,es + mov [ebx].VtMonitorContext.CsSegEs,eax + mov eax,fs + mov [ebx].VtMonitorContext.CsSegFs,eax + mov eax,gs + mov [ebx].VtMonitorContext.CsSegGs,eax + pushfd + pop eax + mov [ebx].VtMonitorContext.CsEflags,eax + + mov eax,[ebx].VtVdmContext.CsSegSs + mov es,eax + mov edi,[ebx].VtVdmContext.CsEsp ; es:edi -> stack + lar eax,eax + test eax,400000h ; big? + jnz fe30 + + movzx edi,di +fe30: mov eax,[ebx].VtVdmContext.CsEflags + sub edi,4 + mov es:[edi],eax ; push Eflags + mov eax,[ebx].VtVdmContext.CsSegCs + sub edi,4 + mov es:[edi],eax ; push cs + mov eax,[ebx].VtVdmContext.CsEip + sub edi,4 + mov es:[edi],eax ; push ip + sub edi,4 + mov eax,[ebx].VtVdmContext.CsEbp ; push ebp + mov es:[edi],eax + +fe40: push es + push edi ; push ss:esp for lss esp + mov eax,esp ; save sp for pushad + + ; simulate pushad + push dword ptr [ebx].VtVdmContext.CsEax + push dword ptr [ebx].VtVdmContext.CsEcx + push dword ptr [ebx].VtVdmContext.CsEdx + push dword ptr [ebx].VtVdmContext.CsEbx + push eax + push ebp ; save pointer to stack frame + push dword ptr [ebx].VtVdmContext.CsEsi + push dword ptr [ebx].VtVdmContext.CsEdi + + ; push seg regs + push dword ptr [ebx].VtVdmContext.CsSegFs + push dword ptr [ebx].VtVdmContext.CsSegGs + push dword ptr [ebx].VtVdmContext.CsSegDs + push dword ptr [ebx].VtVdmContext.CsSegEs + + ; set up VDM seg regs + pop es + pop ds + pop gs ; pop fs,gs of invalid selectors are trapped in ntoskrnl, + pop fs ; and handled by setting to zero + + ; set up VDM general regs + popad + + ; set up vdm stack + lss esp,[ebp - 12] + + ; restore ebp + pop ebp + + ; return to VDM + iretd +stdENDP _FastEnterPm + + page ,132 + subttl "GetFastBopEntry" +;++ +; +; Routine Description: +; +; This routine supplies the address of the routine that segmented +; protected mode code should call to switch to flat mode. +; +; Arguments: +; +; esp + 4 = pointer to VdmTib->VdmContext +; +; Returns: +; +; nothing. +; + assume DS:FLAT +cPublicProc _GetFastBopEntryAddress,1 + + push ebp + mov ebp,esp + push ebx + push eax + mov ebx,[ebp + 8] + mov [ebx].CsSegEs,cs + mov eax,offset FLAT:_FastLeavePm + mov word ptr [ebx].CsEbx,ax + shr eax,16 + mov word ptr [ebx].CsEdx,ax + pop eax + pop ebx + mov esp,ebp + pop ebp + stdRET _GetFastBopEntryAddress + +stdENDP _GetFastBopEntryAddress + + page ,132 + subttl "FastLeavePm" +;++ +; +; Routine Description: +; +; This routine switches from the VDM context to the monitor context. +; +; Arguments: +; +; none +; +; Returns: +; +; executing with monitor context +; + assume DS:Nothing,ES:Nothing,SS:Nothing +ALIGN 16 +cPublicProc _FastLeavePm,0 + + push ebx + + mov bx,ds + push bx ; so push and pop size same + mov bx,KGDT_R3_DATA OR RPL_MASK + mov ds,bx + assume ds:FLAT + lea ebx,_VdmTib ; get pointer to contexts + pushfd + mov dword ptr [ebx].VtVdmContext.CsEax,eax + pop eax + mov dword ptr [ebx].VtVdmContext.CsEFlags,eax + pop ax + mov word ptr [ebx].VtVdmContext.CsSegDs,ax + pop eax + mov dword ptr [ebx].VtVdmContext.CsEbx,eax + mov dword ptr [ebx].VtVdmContext.CsEcx,ecx + mov dword ptr [ebx].VtVdmContext.CsEdx,edx + mov dword ptr [ebx].VtVdmContext.CsEsi,esi + mov dword ptr [ebx].VtVdmContext.CsEdi,edi + mov dword ptr [ebx].VtVdmContext.CsEbp,ebp + mov word ptr [ebx].VtVdmContext.CsSegEs,es + mov word ptr [ebx].VtVdmContext.CsSegFs,fs + mov word ptr [ebx].VtVdmContext.CsSegGs,gs + pop eax + mov dword ptr [ebx].VtVdmContext.CsEip,eax + pop eax + mov word ptr [ebx].VtVdmContext.CsSegCs,ax + mov dword ptr [ebx].VtVdmContext.CsEsp,esp + mov word ptr [ebx].VtVdmContext.CsSegSs,ss + + ; switch Stacks +.errnz (CsEsp + 4 - CsSegSS) + lss esp, [ebx].VtMonitorContext.CsEsp + + ; Now running on Monitor stack + + ; set up event info + mov word ptr [ebx].VtEventInfo.EiEvent,VdmBop + mov dword ptr [ebx].VtEventInfo.EiInstructionSize,BOP_SIZE + mov ax,[ebx].VtVdmContext.CsSegCs + mov es,ax + ; BUGBUG 16 or 32 bit !!!!! + mov di,[ebx].VtVdmContext.CsEip + mov al,byte ptr es:[di] + movzx eax,al + mov [ebx].VtEventInfo.EiBopNumber,eax + sub di,2 + mov word ptr [ebx].VtVdmContext.CsEip,di ; set up bop bias + + ; set up for IRET + push dword ptr [ebx].VtMonitorContext.CsEFlags + push dword ptr [ebx].VtMonitorContext.CsSegCs + push dword ptr [ebx].VtMonitorContext.CsEip + + ; simulate pushad + mov eax,esp + push dword ptr [ebx].VtMonitorContext.CsEax + push dword ptr [ebx].VtMonitorContext.CsEcx + push dword ptr [ebx].VtMonitorContext.CsEdx + push dword ptr [ebx].VtMonitorContext.CsEbx + push eax + push dword ptr [ebx].VtMonitorContext.CsEbp + push dword ptr [ebx].VtMonitorContext.CsEsi + push dword ptr [ebx].VtMonitorContext.CsEdi + + ; push seg regs + push dword ptr [ebx].VtMonitorContext.CsSegFs + push dword ptr [ebx].VtMonitorContext.CsSegGs + push dword ptr [ebx].VtMonitorContext.CsSegDs + push dword ptr [ebx].VtMonitorContext.CsSegEs + + test ds:FIXED_NTVDMSTATE_LINEAR,dword ptr VDM_VIRTUAL_INTERRUPTS + jz fl10 + + or [ebx].VtVdmContext.CsEFlags,dword ptr EFLAGS_INTERRUPT_MASK + jmp fl20 + +fl10: and dword ptr [ebx].VtVdmContext.CsEFlags, NOT EFLAGS_INTERRUPT_MASK +fl20: + ; set up Monitor seg regs + pop es + pop ds + pop gs + pop fs + + ; set up Monitor general regs + popad + + xor eax,eax ; indicate success + ; return + iretd +stdENDP _FastLeavePm + +_TEXT ends + end + + + + + |