]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
0034920b2f6b1785e359b95c2e6a5865668b7fc0
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / X64 / AmdSev.nasm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2021, AMD Inc. All rights reserved.<BR>
3 ; SPDX-License-Identifier: BSD-2-Clause-Patent
4 ;
5 ; Module Name:
6 ;
7 ; AmdSev.nasm
8 ;
9 ; Abstract:
10 ;
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).
13 ;
14 ;-------------------------------------------------------------------------------
15
16 %define SIZE_4KB 0x1000
17
18 RegisterGhcbGpa:
19 ;
20 ; Register GHCB GPA when SEV-SNP is enabled
21 ;
22 lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevSnpIsEnabled)]
23 cmp byte [edi], 1 ; SevSnpIsEnabled
24 jne RegisterGhcbGpaDone
25
26 ; Save the rdi and rsi to used for later comparison
27 push rdi
28 push rsi
29 mov edi, eax
30 mov esi, edx
31 or eax, 18 ; Ghcb registration request
32 wrmsr
33 rep vmmcall
34 rdmsr
35 mov r12, rax
36 and r12, 0fffh
37 cmp r12, 19 ; Ghcb registration response
38 jne GhcbGpaRegisterFailure
39
40 ; Verify that GPA is not changed
41 and eax, 0fffff000h
42 cmp edi, eax
43 jne GhcbGpaRegisterFailure
44 cmp esi, edx
45 jne GhcbGpaRegisterFailure
46 pop rsi
47 pop rdi
48 jmp RegisterGhcbGpaDone
49
50 ;
51 ; Request the guest termination
52 ;
53 GhcbGpaRegisterFailure:
54 xor edx, edx
55 mov eax, 256 ; GHCB terminate
56 wrmsr
57 rep vmmcall
58
59 ; We should not return from the above terminate request, but if we do
60 ; then enter into the hlt loop.
61 DoHltLoop:
62 cli
63 hlt
64 jmp DoHltLoop
65
66 RegisterGhcbGpaDone:
67 OneTimeCallRet RegisterGhcbGpa
68
69 ;
70 ; The function checks whether SEV-ES is enabled, if enabled
71 ; then setup the GHCB page.
72 ;
73 SevEsSetupGhcb:
74 lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
75 cmp byte [edi], 1 ; SevEsIsEnabled
76 jne SevEsSetupGhcbExit
77
78 ;
79 ; program GHCB
80 ; Each page after the GHCB is a per-CPU page, so the calculation programs
81 ; a GHCB to be every 8KB.
82 ;
83 mov eax, SIZE_4KB
84 shl eax, 1 ; EAX = SIZE_4K * 2
85 mov ecx, ebx
86 mul ecx ; EAX = SIZE_4K * 2 * CpuNumber
87 mov edi, esi
88 add edi, MP_CPU_EXCHANGE_INFO_FIELD (GhcbBase)
89 add rax, qword [edi]
90 mov rdx, rax
91 shr rdx, 32
92 mov rcx, 0xc0010130
93
94 OneTimeCall RegisterGhcbGpa
95
96 wrmsr
97
98 SevEsSetupGhcbExit:
99 OneTimeCallRet SevEsSetupGhcb
100
101 ;
102 ; The function checks whether SEV-ES is enabled, if enabled, use
103 ; the GHCB
104 ;
105 SevEsGetApicId:
106 lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevEsIsEnabled)]
107 cmp byte [edi], 1 ; SevEsIsEnabled
108 jne SevEsGetApicIdExit
109
110 ;
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
113 ; calls.
114 ;
115 mov rcx, 0xc0010130
116 rdmsr
117 shl rdx, 32
118 or rax, rdx
119 mov rdi, rax ; RDI now holds the original GHCB GPA
120
121 mov rdx, 0 ; CPUID function 0
122 mov rax, 0 ; RAX register requested
123 or rax, 4
124 wrmsr
125 rep vmmcall
126 rdmsr
127 cmp edx, 0bh
128 jb NoX2ApicSevEs ; CPUID level below CPUID_EXTENDED_TOPOLOGY
129
130 mov rdx, 0bh ; CPUID function 0x0b
131 mov rax, 040000000h ; RBX register requested
132 or rax, 4
133 wrmsr
134 rep vmmcall
135 rdmsr
136 test edx, 0ffffh
137 jz NoX2ApicSevEs ; CPUID.0BH:EBX[15:0] is zero
138
139 mov rdx, 0bh ; CPUID function 0x0b
140 mov rax, 0c0000000h ; RDX register requested
141 or rax, 4
142 wrmsr
143 rep vmmcall
144 rdmsr
145
146 ; Processor is x2APIC capable; 32-bit x2APIC ID is now in EDX
147 jmp RestoreGhcb
148
149 NoX2ApicSevEs:
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
153 or rax, 4
154 wrmsr
155 rep vmmcall
156 rdmsr
157 shr edx, 24
158
159 RestoreGhcb:
160 mov rbx, rdx ; Save x2APIC/APIC ID
161
162 mov rdx, rdi ; RDI holds the saved GHCB GPA
163 shr rdx, 32
164 mov eax, edi
165 wrmsr
166
167 mov rdx, rbx
168
169 ; x2APIC ID or APIC ID is in EDX
170 jmp GetProcessorNumber
171
172 SevEsGetApicIdExit:
173 OneTimeCallRet SevEsGetApicId