| ;------------------------------------------------------------------------------ ; | |
| ; 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 | |