1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2021, AMD Inc. All rights reserved.<BR>
3 ; SPDX-License-Identifier: BSD-2-Clause-Patent
11 ; This provides helper used by the MpFunc.nasm. If AMD SEV-ES is active
12 ; then helpers perform the additional setups (such as GHCB).
14 ;-------------------------------------------------------------------------------
16 %define SIZE_4KB 0x1000
20 ; Register GHCB GPA when SEV-SNP is enabled
22 lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevSnpIsEnabled)]
23 cmp byte [edi], 1 ; SevSnpIsEnabled
24 jne RegisterGhcbGpaDone
26 ; Save the rdi and rsi to used for later comparison
31 or eax, 18 ; Ghcb registration request
37 cmp r12, 19 ; Ghcb registration response
38 jne GhcbGpaRegisterFailure
40 ; Verify that GPA is not changed
43 jne GhcbGpaRegisterFailure
45 jne GhcbGpaRegisterFailure
48 jmp RegisterGhcbGpaDone
51 ; Request the guest termination
53 GhcbGpaRegisterFailure:
55 mov eax, 256 ; GHCB terminate
59 ; We should not return from the above terminate request, but if we do
60 ; then enter into the hlt loop.
67 OneTimeCallRet RegisterGhcbGpa
70 ; The function checks whether SEV-ES is enabled, if enabled
71 ; then setup the GHCB page.
74 lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
75 cmp byte [edi], 1 ; SevEsIsEnabled
76 jne SevEsSetupGhcbExit
80 ; Each page after the GHCB is a per-CPU page, so the calculation programs
81 ; a GHCB to be every 8KB.
84 shl eax, 1 ; EAX = SIZE_4K * 2
86 mul ecx ; EAX = SIZE_4K * 2 * CpuNumber
88 add edi, MP_CPU_EXCHANGE_INFO_FIELD (GhcbBase)
94 OneTimeCall RegisterGhcbGpa
99 OneTimeCallRet SevEsSetupGhcb
102 ; The function checks whether SEV-ES is enabled, if enabled, use
106 lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
107 cmp byte [edi], 1 ; SevEsIsEnabled
108 jne SevEsGetApicIdExit
111 ; Since we don't have a stack yet, we can't take a #VC
112 ; exception. Use the GHCB protocol to perform the CPUID
119 mov rdi, rax ; RDI now holds the original GHCB GPA
121 mov rdx, 0 ; CPUID function 0
122 mov rax, 0 ; RAX register requested
128 jb NoX2ApicSevEs ; CPUID level below CPUID_EXTENDED_TOPOLOGY
130 mov rdx, 0bh ; CPUID function 0x0b
131 mov rax, 040000000h ; RBX register requested
137 jz NoX2ApicSevEs ; CPUID.0BH:EBX[15:0] is zero
139 mov rdx, 0bh ; CPUID function 0x0b
140 mov rax, 0c0000000h ; RDX register requested
146 ; Processor is x2APIC capable; 32-bit x2APIC ID is now in EDX
150 ; Processor is not x2APIC capable, so get 8-bit APIC ID
151 mov rdx, 1 ; CPUID function 1
152 mov rax, 040000000h ; RBX register requested
160 mov rbx, rdx ; Save x2APIC/APIC ID
162 mov rdx, rdi ; RDI holds the saved GHCB GPA
169 ; x2APIC ID or APIC ID is in EDX
170 jmp GetProcessorNumber
173 OneTimeCallRet SevEsGetApicId