;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
; This program and the accompanying materials\r
; are licensed and made available under the terms and conditions of the BSD License\r
; which accompanies this distribution. The full text of the license may be found at\r
mov ss, ax\r
\r
mov esi, ebx\r
+ lea edi, [esi + InitFlagLocation]\r
+ cmp qword [edi], 1 ; ApInitConfig\r
+ jnz GetApicId\r
+\r
+ ; Increment the number of APs executing here as early as possible\r
+ ; This is decremented in C code when AP is finished executing\r
+ mov edi, esi\r
+ add edi, NumApsExecutingLocation\r
+ lock inc dword [edi]\r
+\r
+ ; AP init\r
mov edi, esi\r
add edi, LockLocation\r
mov rax, NotVacantFlag\r
cmp rax, NotVacantFlag\r
jz TestLock\r
\r
- mov edi, esi\r
- add edi, NumApsExecutingLocation\r
- inc dword [edi]\r
- mov ebx, [edi]\r
+ lea ecx, [esi + ApIndexLocation]\r
+ inc dword [ecx]\r
+ mov ebx, [ecx]\r
\r
-ProgramStack:\r
+Releaselock:\r
+ mov rax, VacantFlag\r
+ xchg qword [edi], rax\r
+ ; program stack\r
mov edi, esi\r
add edi, StackSizeLocation\r
- mov rax, qword [edi]\r
+ mov eax, dword [edi]\r
+ mov ecx, ebx\r
+ inc ecx\r
+ mul ecx ; EAX = StackSize * (CpuNumber + 1)\r
mov edi, esi\r
add edi, StackStartAddressLocation\r
add rax, qword [edi]\r
mov rsp, rax\r
- mov qword [edi], rax\r
+ jmp CProcedureInvoke\r
+\r
+GetApicId:\r
+ mov eax, 0\r
+ cpuid\r
+ cmp eax, 0bh\r
+ jb NoX2Apic ; CPUID level below CPUID_EXTENDED_TOPOLOGY\r
+\r
+ mov eax, 0bh\r
+ xor ecx, ecx\r
+ cpuid\r
+ test ebx, 0ffffh\r
+ jz NoX2Apic ; CPUID.0BH:EBX[15:0] is zero\r
+\r
+ ; Processor is x2APIC capable; 32-bit x2APIC ID is already in EDX\r
+ jmp GetProcessorNumber\r
+\r
+NoX2Apic:\r
+ ; Processor is not x2APIC capable, so get 8-bit APIC ID\r
+ mov eax, 1\r
+ cpuid\r
+ shr ebx, 24\r
+ mov edx, ebx\r
+\r
+GetProcessorNumber:\r
+ ;\r
+ ; Get processor number for this AP\r
+ ; Note that BSP may become an AP due to SwitchBsp()\r
+ ;\r
+ xor ebx, ebx\r
+ lea eax, [esi + CpuInfoLocation]\r
+ mov edi, [eax]\r
\r
-Releaselock:\r
- mov rax, VacantFlag\r
- mov edi, esi\r
- add edi, LockLocation\r
- xchg qword [edi], rax\r
+GetNextProcNumber:\r
+ cmp dword [edi], edx ; APIC ID match?\r
+ jz ProgramStack\r
+ add edi, 20\r
+ inc ebx\r
+ jmp GetNextProcNumber \r
+\r
+ProgramStack:\r
+ mov rsp, qword [edi + 12]\r
\r
CProcedureInvoke:\r
push rbp ; Push BIST data at top of AP stack\r
push rbp\r
mov rbp, rsp\r
\r
- mov rax, ASM_PFX(InitializeFloatingPointUnits)\r
+ mov rax, qword [esi + InitializeFloatingPointUnitsAddress]\r
sub rsp, 20h\r
call rax ; Call assembly function to initialize FPU per UEFI spec\r
add rsp, 20h\r
\r
- mov edx, ebx ; edx is NumApsExecuting\r
+ mov edx, ebx ; edx is ApIndex\r
mov ecx, esi\r
add ecx, LockLocation ; rcx is address of exchange info data buffer\r
\r
\r
RendezvousFunnelProcEnd:\r
\r
+;-------------------------------------------------------------------------------------\r
+; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish);\r
+;-------------------------------------------------------------------------------------\r
+global ASM_PFX(AsmRelocateApLoop)\r
+ASM_PFX(AsmRelocateApLoop):\r
+AsmRelocateApLoopStart:\r
+ mov rax, [rsp + 40] ; CountTofinish\r
+ lock dec dword [rax] ; (*CountTofinish)--\r
+ mov rsp, r9\r
+ push rcx\r
+ push rdx\r
+\r
+ lea rsi, [PmEntry] ; rsi <- The start address of transition code\r
+\r
+ push r8\r
+ push rsi\r
+ DB 0x48\r
+ retf\r
+BITS 32\r
+PmEntry:\r
+ mov eax, cr0\r
+ btr eax, 31 ; Clear CR0.PG\r
+ mov cr0, eax ; Disable paging and caches\r
+\r
+ mov ebx, edx ; Save EntryPoint to rbx, for rdmsr will overwrite rdx\r
+ mov ecx, 0xc0000080\r
+ rdmsr\r
+ and ah, ~ 1 ; Clear LME\r
+ wrmsr\r
+ mov eax, cr4\r
+ and al, ~ (1 << 5) ; Clear PAE\r
+ mov cr4, eax\r
+\r
+ pop edx\r
+ add esp, 4\r
+ pop ecx,\r
+ add esp, 4\r
+ cmp cl, 1 ; Check mwait-monitor support\r
+ jnz HltLoop\r
+ mov ebx, edx ; Save C-State to ebx\r
+MwaitLoop:\r
+ mov eax, esp ; Set Monitor Address\r
+ xor ecx, ecx ; ecx = 0\r
+ xor edx, edx ; edx = 0\r
+ monitor\r
+ mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4]\r
+ shl eax, 4\r
+ mwait\r
+ jmp MwaitLoop\r
+HltLoop:\r
+ cli\r
+ hlt\r
+ jmp HltLoop\r
+BITS 64\r
+AsmRelocateApLoopEnd:\r
+\r
;-------------------------------------------------------------------------------------\r
; AsmGetAddressMap (&AddressMap);\r
;-------------------------------------------------------------------------------------\r
global ASM_PFX(AsmGetAddressMap)\r
ASM_PFX(AsmGetAddressMap):\r
- mov rax, ASM_PFX(RendezvousFunnelProc)\r
+ lea rax, [ASM_PFX(RendezvousFunnelProc)]\r
mov qword [rcx], rax\r
mov qword [rcx + 8h], LongModeStart - RendezvousFunnelProcStart\r
mov qword [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
+ lea rax, [ASM_PFX(AsmRelocateApLoop)]\r
+ mov qword [rcx + 18h], rax\r
+ mov qword [rcx + 20h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart\r
ret\r
\r
;-------------------------------------------------------------------------------------\r