Use 16bit assembly code to replace hard code db. In V2: Add 0x67 prefix to far jump When we enter protected mode, with the far jump still in big real mode, the JMP instruction not only needs the 0x66 prefix (for 32-bit operand size), but also the 0x67 prefix (for 32-bit address size). Use the a32 nasm modifier to enforce this. This bug breaks S3 resume in the Ia32 + SMM_REQUIRE build of OVMF. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Liming Gao <liming.gao@intel.com> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
160 lines
4.8 KiB
NASM
160 lines
4.8 KiB
NASM
;------------------------------------------------------------------------------ ;
|
|
; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
|
; This program and the accompanying materials
|
|
; are licensed and made available under the terms and conditions of the BSD License
|
|
; which accompanies this distribution. The full text of the license may be found at
|
|
; http://opensource.org/licenses/bsd-license.php.
|
|
;
|
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
;
|
|
; Module Name:
|
|
;
|
|
; MpFuncs.nasm
|
|
;
|
|
; Abstract:
|
|
;
|
|
; This is the assembly code for Multi-processor S3 support
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
|
|
SECTION .text
|
|
|
|
extern ASM_PFX(InitializeFloatingPointUnits)
|
|
|
|
%define VacantFlag 0x0
|
|
%define NotVacantFlag 0xff
|
|
|
|
%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
|
%define StackStart LockLocation + 0x4
|
|
%define StackSize LockLocation + 0x8
|
|
%define RendezvousProc LockLocation + 0xC
|
|
%define GdtrProfile LockLocation + 0x10
|
|
%define IdtrProfile LockLocation + 0x16
|
|
%define BufferStart LockLocation + 0x1C
|
|
|
|
;-------------------------------------------------------------------------------------
|
|
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
|
;procedure serializes all the AP processors through an Init sequence. It must be
|
|
;noted that APs arrive here very raw...ie: real mode, no stack.
|
|
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
|
;IS IN MACHINE CODE.
|
|
;-------------------------------------------------------------------------------------
|
|
;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
|
|
|
|
BITS 16
|
|
global ASM_PFX(RendezvousFunnelProc)
|
|
ASM_PFX(RendezvousFunnelProc):
|
|
RendezvousFunnelProcStart:
|
|
|
|
; At this point CS = 0x(vv00) and ip= 0x0.
|
|
|
|
mov ax, cs
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov ss, ax
|
|
xor ax, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
|
|
flat32Start:
|
|
|
|
mov si, BufferStart
|
|
mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer
|
|
|
|
mov si, GdtrProfile
|
|
o32 lgdt [cs:si]
|
|
|
|
mov si, IdtrProfile
|
|
o32 lidt [cs:si]
|
|
|
|
xor ax, ax
|
|
mov ds, ax
|
|
|
|
mov eax, cr0 ; Get control register 0
|
|
or eax, 0x000000001 ; Set PE bit (bit #0)
|
|
mov cr0, eax
|
|
|
|
FLAT32_JUMP:
|
|
|
|
a32 jmp dword 0x20:0x0
|
|
|
|
BITS 32
|
|
PMODE_ENTRY: ; protected mode entry point
|
|
|
|
mov ax, 0x8
|
|
o16 mov ds, ax
|
|
o16 mov es, ax
|
|
o16 mov fs, ax
|
|
o16 mov gs, ax
|
|
o16 mov ss, ax ; Flat mode setup.
|
|
|
|
mov esi, edx
|
|
|
|
mov edi, esi
|
|
add edi, LockLocation
|
|
mov al, NotVacantFlag
|
|
TestLock:
|
|
xchg byte [edi], al
|
|
cmp al, NotVacantFlag
|
|
jz TestLock
|
|
|
|
ProgramStack:
|
|
|
|
mov edi, esi
|
|
add edi, StackSize
|
|
mov eax, dword [edi]
|
|
mov edi, esi
|
|
add edi, StackStart
|
|
add eax, dword [edi]
|
|
mov esp, eax
|
|
mov dword [edi], eax
|
|
|
|
Releaselock:
|
|
|
|
mov al, VacantFlag
|
|
mov edi, esi
|
|
add edi, LockLocation
|
|
xchg byte [edi], al
|
|
|
|
;
|
|
; Call assembly function to initialize FPU.
|
|
;
|
|
mov ebx, ASM_PFX(InitializeFloatingPointUnits)
|
|
call ebx
|
|
;
|
|
; Call C Function
|
|
;
|
|
mov edi, esi
|
|
add edi, RendezvousProc
|
|
mov eax, dword [edi]
|
|
|
|
test eax, eax
|
|
jz GoToSleep
|
|
call eax ; Call C function
|
|
|
|
GoToSleep:
|
|
cli
|
|
hlt
|
|
jmp $-2
|
|
|
|
RendezvousFunnelProcEnd:
|
|
;-------------------------------------------------------------------------------------
|
|
; AsmGetAddressMap (&AddressMap);
|
|
;-------------------------------------------------------------------------------------
|
|
global ASM_PFX(AsmGetAddressMap)
|
|
ASM_PFX(AsmGetAddressMap):
|
|
|
|
pushad
|
|
mov ebp,esp
|
|
|
|
mov ebx, dword [ebp+0x24]
|
|
mov dword [ebx], RendezvousFunnelProcStart
|
|
mov dword [ebx+0x4], PMODE_ENTRY - RendezvousFunnelProcStart
|
|
mov dword [ebx+0x8], FLAT32_JUMP - RendezvousFunnelProcStart
|
|
mov dword [ebx+0xc], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
|
|
|
popad
|
|
ret
|
|
|