;------------------------------------------------------------------------------ ; | |
; Copyright (c) 2016 - 2018, 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 | |
; | |
;------------------------------------------------------------------------------- | |
%define VacantFlag 0x0 | |
%define NotVacantFlag 0xff | |
%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart | |
%define StackStartAddressLocation LockLocation + 0x8 | |
%define StackSizeLocation LockLocation + 0x10 | |
%define CProcedureLocation LockLocation + 0x18 | |
%define GdtrLocation LockLocation + 0x20 | |
%define IdtrLocation LockLocation + 0x2A | |
%define BufferStartLocation LockLocation + 0x34 | |
%define Cr3OffsetLocation LockLocation + 0x38 | |
%define InitializeFloatingPointUnitsAddress LockLocation + 0x3C | |
;------------------------------------------------------------------------------------- | |
;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); | |
;text SEGMENT | |
DEFAULT REL | |
SECTION .text | |
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, BufferStartLocation | |
mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer | |
mov si, Cr3OffsetLocation | |
mov ecx,dword [si] ; ECX is keeping the value of CR3 | |
mov si, GdtrLocation | |
o32 lgdt [cs:si] | |
mov si, IdtrLocation | |
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, 0x18 | |
o16 mov ds, ax | |
o16 mov es, ax | |
o16 mov fs, ax | |
o16 mov gs, ax | |
o16 mov ss, ax ; Flat mode setup. | |
mov eax, cr4 | |
bts eax, 5 | |
mov cr4, eax | |
mov cr3, ecx | |
mov esi, edx ; Save wakeup buffer address | |
mov ecx, 0xc0000080 ; EFER MSR number. | |
rdmsr ; Read EFER. | |
bts eax, 8 ; Set LME=1. | |
wrmsr ; Write EFER. | |
mov eax, cr0 ; Read CR0. | |
bts eax, 31 ; Set PG=1. | |
mov cr0, eax ; Write CR0. | |
LONG_JUMP: | |
a16 jmp dword 0x38:0x0 | |
BITS 64 | |
LongModeStart: | |
mov ax, 0x30 | |
o16 mov ds, ax | |
o16 mov es, ax | |
o16 mov ss, ax | |
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, StackSizeLocation | |
mov rax, qword [edi] | |
mov edi, esi | |
add edi, StackStartAddressLocation | |
add rax, qword [edi] | |
mov rsp, rax | |
mov qword [edi], rax | |
Releaselock: | |
mov al, VacantFlag | |
mov edi, esi | |
add edi, LockLocation | |
xchg byte [edi], al | |
; | |
; Call assembly function to initialize FPU. | |
; | |
mov rax, qword [esi + InitializeFloatingPointUnitsAddress] | |
sub rsp, 0x20 | |
call rax | |
add rsp, 0x20 | |
; | |
; Call C Function | |
; | |
mov edi, esi | |
add edi, CProcedureLocation | |
mov rax, qword [edi] | |
test rax, rax | |
jz GoToSleep | |
sub rsp, 0x20 | |
call rax | |
add rsp, 0x20 | |
GoToSleep: | |
cli | |
hlt | |
jmp $-2 | |
RendezvousFunnelProcEnd: | |
;------------------------------------------------------------------------------------- | |
; AsmGetAddressMap (&AddressMap); | |
;------------------------------------------------------------------------------------- | |
; comments here for definition of address map | |
global ASM_PFX(AsmGetAddressMap) | |
ASM_PFX(AsmGetAddressMap): | |
lea rax, [RendezvousFunnelProcStart] | |
mov qword [rcx], rax | |
mov qword [rcx+0x8], PMODE_ENTRY - RendezvousFunnelProcStart | |
mov qword [rcx+0x10], FLAT32_JUMP - RendezvousFunnelProcStart | |
mov qword [rcx+0x18], RendezvousFunnelProcEnd - RendezvousFunnelProcStart | |
mov qword [rcx+0x20], LongModeStart - RendezvousFunnelProcStart | |
mov qword [rcx+0x28], LONG_JUMP - RendezvousFunnelProcStart | |
ret | |