;------------------------------------------------------------------------------ ; | |
; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> | |
; SPDX-License-Identifier: BSD-2-Clause-Patent | |
; | |
; 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 | |