windows-nt/Source/XPSP1/NT/base/boot/lib/i386/pae.asm
2020-09-26 16:20:57 +08:00

181 lines
2.4 KiB
NASM

;++
;
;Copyright (c) 1998 Microsoft Corporation
;
;Module Name:
;
; pae.asm
;
;Abstract:
;
; Contains routines to aid in enabling PAE mode.
;
;Author:
;
; Forrest Foltz (forrestf) 12-28-98
;
;
;Revision History:
;
;--
.586p
.xlist
include ks386.inc
.list
_TEXT SEGMENT PARA PUBLIC 'CODE'
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
EFLAGS_ID equ 200000h
;++
;
; BOOLEAN
; BlpPaeSupported (
; VOID
; )
;
; Routine Description:
;
; This routine determines whether the CPU supports PAE mode
;
; Arguments:
;
; None.
;
; Return value:
;
; al == 1 if the CPU does support PAE mode.
; al == 0 if not.
;
;--
public _BlpPaeSupported@0
_BlpPaeSupported@0 proc
;
; First determine whether the CPUID instruction is supported. If
; the EFLAGS_ID bit "sticks" when stored in the flags register, then
; the CPUID instruction is supported.
;
mov ecx, EFLAGS_ID
pushfd
pop eax ; eax == flags
xor ecx, eax ; ecx == flags ^ EFLAGS_ID
push ecx
popfd ; load new flags
pushfd
pop ecx ; ecx == result of flag load
xor eax, ecx ; Q: did the EFLAGS_ID bit stick?
jz done ; N: CPUID is not available
;
; We can use the CPUID instruction.
;
push ebx ; CPUID steps on eax, ebx, ecx, edx
mov eax, 1
cpuid
pop ebx
;
; edx contains the feature bits. Bit 6 is the PAE extensions flag.
;
sub eax, eax ; assume not set
test dl, 40h ; Q: bit 6 set?
jz done ; N: return with eax == 0
inc eax ; Y: set eax == 1
done: ret
_BlpPaeSupported@0 endp
;++
;
; VOID
; BlSetPae (
; IN ULONG IdentityAddress,
; IN ULONG PaeCr3
; )
;
; Routine Description:
;
; Arguments:
;
; Return
;
;--
public _BlpEnablePAE@4
_BlpEnablePAE@4 proc
;
; Load PDPT address
;
mov edx, [esp]+4
;
; Do this to set the state machine in motion
;
mov ecx, cr3
mov cr3, ecx
;
; Disable paging
;
mov eax, cr0
and eax, NOT CR0_PG
mov cr0, eax
jmp $+2
;
; Enable physical address extensions
;
mov eax, cr4
or eax, CR4_PAE
;
; The following instruction was necessary in order to boot some
; machines. Probably due to an errata.
;
mov ecx, cr3
mov cr4, eax
;
; Point cr3 to the page directory pointer table
;
mov cr3, edx
;
; Enable paging
;
mov ecx, cr0
or ecx, CR0_PG
mov cr0, ecx
jmp $+2
;
; Clean the stack and return
;
_BlpEnablePAEEnd:
ret 4
_BlpEnablePAE@4 endp
_TEXT ends
end