WakeupArgsRelocatedMailBox equ 800h\r
AcceptPageArgsPhysicalStart equ 800h\r
AcceptPageArgsPhysicalEnd equ 808h\r
-AcceptPageArgsChunkSize equ 810h\r
-AcceptPageArgsPageSize equ 818h\r
+AcceptPageArgsTopStackAddress equ 810h\r
+AcceptPageArgsApStackSize equ 818h\r
CpuArrivalOffset equ 900h\r
CpusExitingOffset equ 0a00h\r
TalliesOffset equ 0a08h\r
cmp eax, MpProtectedModeWakeupCommandWakeup\r
je .do_wakeup\r
\r
+ cmp eax, MpProtectedModeWakeupCommandAcceptPages\r
+ je .do_accept_pages\r
+\r
; Don't support this command, so ignore\r
jmp .check_command\r
\r
+.do_accept_pages:\r
+ ;\r
+ ; Read the top stack address from arguments\r
+ mov rsi, [rsp + AcceptPageArgsTopStackAddress]\r
+\r
+ ;\r
+ ; Calculate the top stack address of the AP.\r
+ ; ApStackAddr = BaseStackAddr + (vCpuIndex) * ApStackSize\r
+ xor rdx, rdx\r
+ xor rbx, rbx\r
+ xor rax, rax\r
+ mov eax, [rsp + AcceptPageArgsApStackSize]\r
+ mov ebx, r9d ; vCpuIndex\r
+ mul ebx\r
+ add rsi, rax ; now rsi is ApStackAddr\r
+\r
+.start_accept_pages:\r
+ ;\r
+ ; Read the function address which will be called\r
+ mov rax, [rsp + WakeupVectorOffset]\r
+\r
+ ;\r
+ ; vCPU index as the first argument\r
+ mov ecx, r9d\r
+ mov rdx, [rsp + AcceptPageArgsPhysicalStart]\r
+ mov r8, [rsp + AcceptPageArgsPhysicalEnd]\r
+\r
+ ; save the Mailbox address to rbx\r
+ mov rbx, rsp\r
+\r
+ ;\r
+ ; set AP Stack\r
+ mov rsp, rsi\r
+ nop\r
+\r
+ ; save rax (the Mailbox address)\r
+ push rbx\r
+\r
+ call rax\r
+\r
+ ; recove rsp\r
+ pop rbx\r
+ mov rsp, rbx\r
+ ;\r
+ ; recover r8, r9\r
+ mov rax, 1\r
+ tdcall\r
+\r
+ mov eax, 0FFFFFFFFh\r
+ lock xadd dword [rsp + CpusExitingOffset], eax\r
+ dec eax\r
+\r
+.check_exiting_cnt:\r
+ cmp eax, 0\r
+ je do_wait_loop\r
+ mov eax, dword[rsp + CpusExitingOffset]\r
+ jmp .check_exiting_cnt\r
+\r
.do_wakeup:\r
;\r
; BSP sets these variables before unblocking APs\r