]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.nasm
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / MpFuncs.nasm
CommitLineData
78cf66ee 1;------------------------------------------------------------------------------ ;\r
e21e355e 2; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
0acd8697 3; SPDX-License-Identifier: BSD-2-Clause-Patent\r
78cf66ee
LG
4;\r
5; Module Name:\r
6;\r
7; MpFuncs.nasm\r
8;\r
9; Abstract:\r
10;\r
11; This is the assembly code for Multi-processor S3 support\r
12;\r
13;-------------------------------------------------------------------------------\r
14\r
78cf66ee
LG
15%define VacantFlag 0x0\r
16%define NotVacantFlag 0xff\r
17\r
18%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
19%define StackStartAddressLocation LockLocation + 0x8\r
20%define StackSizeLocation LockLocation + 0x10\r
21%define CProcedureLocation LockLocation + 0x18\r
22%define GdtrLocation LockLocation + 0x20\r
23%define IdtrLocation LockLocation + 0x2A\r
24%define BufferStartLocation LockLocation + 0x34\r
25%define Cr3OffsetLocation LockLocation + 0x38\r
e21e355e 26%define InitializeFloatingPointUnitsAddress LockLocation + 0x3C\r
78cf66ee
LG
27\r
28;-------------------------------------------------------------------------------------\r
29;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
30;procedure serializes all the AP processors through an Init sequence. It must be\r
31;noted that APs arrive here very raw...ie: real mode, no stack.\r
32;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
33;IS IN MACHINE CODE.\r
34;-------------------------------------------------------------------------------------\r
35;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);\r
36\r
37;text SEGMENT\r
38DEFAULT REL\r
39SECTION .text\r
40\r
e1f0eed1 41BITS 16\r
78cf66ee
LG
42global ASM_PFX(RendezvousFunnelProc)\r
43ASM_PFX(RendezvousFunnelProc):\r
44RendezvousFunnelProcStart:\r
45\r
46; At this point CS = 0x(vv00) and ip= 0x0.\r
47\r
e1f0eed1
LG
48 mov ax, cs\r
49 mov ds, ax\r
50 mov es, ax\r
51 mov ss, ax\r
52 xor ax, ax\r
53 mov fs, ax\r
54 mov gs, ax\r
78cf66ee
LG
55\r
56flat32Start:\r
57\r
e1f0eed1
LG
58 mov si, BufferStartLocation\r
59 mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer\r
78cf66ee 60\r
e1f0eed1
LG
61 mov si, Cr3OffsetLocation\r
62 mov ecx,dword [si] ; ECX is keeping the value of CR3\r
78cf66ee 63\r
e1f0eed1
LG
64 mov si, GdtrLocation\r
65o32 lgdt [cs:si]\r
78cf66ee 66\r
e1f0eed1
LG
67 mov si, IdtrLocation\r
68o32 lidt [cs:si]\r
78cf66ee 69\r
e1f0eed1
LG
70 xor ax, ax\r
71 mov ds, ax\r
78cf66ee 72\r
e1f0eed1
LG
73 mov eax, cr0 ; Get control register 0\r
74 or eax, 0x000000001 ; Set PE bit (bit #0)\r
75 mov cr0, eax\r
78cf66ee
LG
76\r
77FLAT32_JUMP:\r
78\r
e1f0eed1 79a32 jmp dword 0x20:0x0\r
78cf66ee 80\r
e1f0eed1 81BITS 32\r
78cf66ee
LG
82PMODE_ENTRY: ; protected mode entry point\r
83\r
e1f0eed1
LG
84 mov ax, 0x18\r
85o16 mov ds, ax\r
86o16 mov es, ax\r
87o16 mov fs, ax\r
88o16 mov gs, ax\r
89o16 mov ss, ax ; Flat mode setup.\r
78cf66ee 90\r
e1f0eed1
LG
91 mov eax, cr4\r
92 bts eax, 5\r
93 mov cr4, eax\r
78cf66ee 94\r
e1f0eed1 95 mov cr3, ecx\r
78cf66ee 96\r
e1f0eed1 97 mov esi, edx ; Save wakeup buffer address\r
78cf66ee 98\r
e1f0eed1
LG
99 mov ecx, 0xc0000080 ; EFER MSR number.\r
100 rdmsr ; Read EFER.\r
101 bts eax, 8 ; Set LME=1.\r
102 wrmsr ; Write EFER.\r
78cf66ee 103\r
e1f0eed1
LG
104 mov eax, cr0 ; Read CR0.\r
105 bts eax, 31 ; Set PG=1.\r
106 mov cr0, eax ; Write CR0.\r
78cf66ee
LG
107\r
108LONG_JUMP:\r
109\r
e1f0eed1 110a16 jmp dword 0x38:0x0\r
78cf66ee 111\r
e1f0eed1 112BITS 64\r
78cf66ee
LG
113LongModeStart:\r
114\r
115 mov ax, 0x30\r
116o16 mov ds, ax\r
117o16 mov es, ax\r
118o16 mov ss, ax\r
119\r
120 mov edi, esi\r
121 add edi, LockLocation\r
122 mov al, NotVacantFlag\r
123TestLock:\r
124 xchg byte [edi], al\r
125 cmp al, NotVacantFlag\r
126 jz TestLock\r
127\r
128ProgramStack:\r
129\r
130 mov edi, esi\r
131 add edi, StackSizeLocation\r
132 mov rax, qword [edi]\r
133 mov edi, esi\r
134 add edi, StackStartAddressLocation\r
135 add rax, qword [edi]\r
136 mov rsp, rax\r
137 mov qword [edi], rax\r
138\r
139Releaselock:\r
140\r
141 mov al, VacantFlag\r
142 mov edi, esi\r
143 add edi, LockLocation\r
144 xchg byte [edi], al\r
145\r
146 ;\r
147 ; Call assembly function to initialize FPU.\r
148 ;\r
e21e355e 149 mov rax, qword [esi + InitializeFloatingPointUnitsAddress]\r
78cf66ee
LG
150 sub rsp, 0x20\r
151 call rax\r
152 add rsp, 0x20\r
153\r
154 ;\r
155 ; Call C Function\r
156 ;\r
157 mov edi, esi\r
158 add edi, CProcedureLocation\r
159 mov rax, qword [edi]\r
160\r
161 test rax, rax\r
162 jz GoToSleep\r
163\r
164 sub rsp, 0x20\r
165 call rax\r
166 add rsp, 0x20\r
167\r
168GoToSleep:\r
169 cli\r
170 hlt\r
171 jmp $-2\r
172\r
173RendezvousFunnelProcEnd:\r
174\r
175;-------------------------------------------------------------------------------------\r
176; AsmGetAddressMap (&AddressMap);\r
177;-------------------------------------------------------------------------------------\r
178; comments here for definition of address map\r
179global ASM_PFX(AsmGetAddressMap)\r
180ASM_PFX(AsmGetAddressMap):\r
e21e355e 181 lea rax, [RendezvousFunnelProcStart]\r
78cf66ee
LG
182 mov qword [rcx], rax\r
183 mov qword [rcx+0x8], PMODE_ENTRY - RendezvousFunnelProcStart\r
184 mov qword [rcx+0x10], FLAT32_JUMP - RendezvousFunnelProcStart\r
185 mov qword [rcx+0x18], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
186 mov qword [rcx+0x20], LongModeStart - RendezvousFunnelProcStart\r
187 mov qword [rcx+0x28], LONG_JUMP - RendezvousFunnelProcStart\r
188 ret\r
189\r