]>
Commit | Line | Data |
---|---|---|
768e2a90 | 1 | ;------------------------------------------------------------------------------\r |
2 | ; X64 assembly file for AP startup vector.\r | |
3 | ;\r | |
de243ee4 | 4 | ; Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r |
584d5652 | 5 | ; This program and the accompanying materials\r |
768e2a90 | 6 | ; are licensed and made available under the terms and conditions of the BSD License\r |
7 | ; which accompanies this distribution. The full text of the license may be found at\r | |
8 | ; http://opensource.org/licenses/bsd-license.php\r | |
9 | ;\r | |
10 | ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
11 | ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
12 | ;\r | |
13 | ;------------------------------------------------------------------------------\r | |
14 | \r | |
15 | .code\r | |
16 | \r | |
de243ee4 | 17 | include AsmInclude.inc\r |
768e2a90 | 18 | ;-------------------------------------------------------------------------------------\r |
19 | \r | |
20 | ;-------------------------------------------------------------------------------------\r | |
21 | ;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r | |
22 | ;procedure serializes all the AP processors through an Init sequence. It must be\r | |
23 | ;noted that APs arrive here very raw...ie: real mode, no stack.\r | |
24 | ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r | |
25 | ;IS IN MACHINE CODE.\r | |
26 | ;-------------------------------------------------------------------------------------\r | |
27 | ;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);\r | |
28 | \r | |
29 | RendezvousFunnelProc PROC PUBLIC\r | |
30 | RendezvousFunnelProcStart::\r | |
31 | \r | |
32 | ; At this point CS = 0x(vv00) and ip= 0x0.\r | |
33 | \r | |
34 | db 8ch, 0c8h ; mov ax, cs\r | |
35 | db 8eh, 0d8h ; mov ds, ax\r | |
36 | db 8eh, 0c0h ; mov es, ax\r | |
de243ee4 | 37 | db 8eh, 0d0h ; mov ss, ax\r |
768e2a90 | 38 | db 33h, 0c0h ; xor ax, ax\r |
39 | db 8eh, 0e0h ; mov fs, ax\r | |
40 | db 8eh, 0e8h ; mov gs, ax\r | |
41 | \r | |
42 | ; Switch to flat mode.\r | |
43 | \r | |
44 | db 0BEh\r | |
45 | dw BufferStartLocation ; mov si, BufferStartLocation\r | |
46 | db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer\r | |
47 | \r | |
48 | db 0BEh\r | |
49 | dw Cr3OffsetLocation ; mov si, Cr3Location\r | |
50 | db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3\r | |
de243ee4 | 51 | \r |
768e2a90 | 52 | db 0BEh\r |
53 | dw GdtrLocation ; mov si, GdtrProfile\r | |
54 | db 66h ; db 66h\r | |
55 | db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]\r | |
56 | \r | |
de243ee4 | 57 | db 0BEh\r |
58 | dw IdtrLocation ; mov si, IdtrProfile\r | |
59 | db 66h ; db 66h\r | |
60 | db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]\r | |
61 | \r | |
768e2a90 | 62 | db 33h, 0C0h ; xor ax, ax\r |
63 | db 8Eh, 0D8h ; mov ds, ax\r | |
de243ee4 | 64 | \r |
768e2a90 | 65 | db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0\r |
66 | db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)\r | |
67 | db 0Fh, 22h, 0C0h ; mov cr0, eax\r | |
68 | \r | |
69 | FLAT32_JUMP::\r | |
70 | \r | |
71 | db 66h, 67h, 0EAh ; far jump\r | |
72 | dd 0h ; 32-bit offset\r | |
73 | dw 20h ; 16-bit selector\r | |
74 | \r | |
75 | ProtectedModeStart::\r | |
76 | \r | |
77 | db 66h, 0B8h, 18h, 00h ; mov ax, 18h\r | |
78 | db 66h, 8Eh, 0D8h ; mov ds, ax\r | |
79 | db 66h, 8Eh, 0C0h ; mov es, ax\r | |
80 | db 66h, 8Eh, 0E0h ; mov fs, ax\r | |
81 | db 66h, 8Eh, 0E8h ; mov gs, ax\r | |
82 | db 66h, 8Eh, 0D0h ; mov ss, ax ; Flat mode setup.\r | |
83 | \r | |
84 | db 0Fh, 20h, 0E0h ; mov eax, cr4\r | |
85 | db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5\r | |
86 | db 0Fh, 22h, 0E0h ; mov cr4, eax\r | |
87 | \r | |
88 | db 0Fh, 22h, 0D9h ; mov cr3, ecx\r | |
de243ee4 | 89 | \r |
768e2a90 | 90 | db 8Bh, 0F2h ; mov esi, edx ; Save wakeup buffer address\r |
de243ee4 | 91 | \r |
768e2a90 | 92 | db 0B9h\r |
93 | dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.\r | |
94 | db 0Fh, 32h ; rdmsr ; Read EFER.\r | |
95 | db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.\r | |
96 | db 0Fh, 30h ; wrmsr ; Write EFER.\r | |
de243ee4 | 97 | \r |
768e2a90 | 98 | db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.\r |
99 | db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.\r | |
100 | db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.\r | |
101 | \r | |
102 | LONG_JUMP::\r | |
de243ee4 | 103 | \r |
768e2a90 | 104 | db 67h, 0EAh ; far jump\r |
105 | dd 0h ; 32-bit offset\r | |
106 | dw 38h ; 16-bit selector\r | |
de243ee4 | 107 | \r |
768e2a90 | 108 | LongModeStart::\r |
109 | \r | |
110 | mov ax, 30h\r | |
111 | mov ds, ax\r | |
112 | mov es, ax\r | |
113 | mov ss, ax\r | |
114 | \r | |
d6d858c4 | 115 | ;\r |
116 | ; ProgramStack\r | |
117 | ;\r | |
118 | mov ecx, 1bh ; Read IA32_APIC_BASE MSR\r | |
119 | rdmsr\r | |
0dfef49a | 120 | \r |
121 | bt eax, 10 ; Check for x2apic mode\r | |
122 | jnc LegacyApicMode\r | |
123 | mov ecx, 802h ; Read APIC_ID\r | |
124 | rdmsr\r | |
125 | mov ebx, eax ; ebx == apicid\r | |
126 | jmp GetCpuNumber\r | |
127 | \r | |
128 | LegacyApicMode::\r | |
129 | \r | |
d6d858c4 | 130 | and eax, 0fffff000h\r |
131 | add eax, 20h\r | |
132 | mov ebx, dword ptr [eax]\r | |
0dfef49a | 133 | shr ebx, 24 ; ebx == apicid\r |
134 | \r | |
135 | GetCpuNumber::\r | |
136 | \r | |
d6d858c4 | 137 | xor rcx, rcx\r |
768e2a90 | 138 | mov edi, esi\r |
d6d858c4 | 139 | add edi, ProcessorNumberLocation\r |
140 | mov ecx, dword ptr [edi + 4 * ebx] ; RCX = CpuNumber\r | |
768e2a90 | 141 | \r |
142 | mov edi, esi\r | |
143 | add edi, StackSizeLocation\r | |
144 | mov rax, qword ptr [edi]\r | |
d6d858c4 | 145 | inc rcx\r |
146 | mul rcx ; RAX = StackSize * (CpuNumber + 1)\r | |
147 | \r | |
768e2a90 | 148 | mov edi, esi\r |
149 | add edi, StackStartAddressLocation\r | |
d6d858c4 | 150 | mov rbx, qword ptr [edi]\r |
151 | add rax, rbx ; RAX = StackStart + StackSize * (CpuNumber + 1)\r | |
768e2a90 | 152 | \r |
d6d858c4 | 153 | mov rsp, rax\r |
768e2a90 | 154 | \r |
155 | ;\r | |
156 | ; Call C Function\r | |
157 | ;\r | |
158 | mov edi, esi\r | |
159 | add edi, CProcedureLocation\r | |
160 | mov rax, qword ptr [edi]\r | |
161 | \r | |
162 | test rax, rax\r | |
163 | jz GoToSleep\r | |
164 | \r | |
165 | sub rsp, 20h\r | |
166 | call rax\r | |
167 | add rsp, 20h\r | |
de243ee4 | 168 | \r |
768e2a90 | 169 | GoToSleep::\r |
170 | \r | |
171 | cli\r | |
172 | hlt\r | |
173 | jmp $-2\r | |
de243ee4 | 174 | \r |
768e2a90 | 175 | RendezvousFunnelProc ENDP\r |
176 | RendezvousFunnelProcEnd::\r | |
177 | \r | |
178 | \r | |
179 | ;-------------------------------------------------------------------------------------\r | |
180 | ; AsmGetAddressMap (&AddressMap);\r | |
181 | ;-------------------------------------------------------------------------------------\r | |
de243ee4 | 182 | AsmGetAddressMap PROC\r |
768e2a90 | 183 | \r |
184 | mov rax, offset RendezvousFunnelProcStart\r | |
185 | mov qword ptr [rcx], rax\r | |
186 | mov qword ptr [rcx+8h], ProtectedModeStart - RendezvousFunnelProcStart\r | |
187 | mov qword ptr [rcx+10h], FLAT32_JUMP - RendezvousFunnelProcStart\r | |
188 | mov qword ptr [rcx+18h], LongModeStart - RendezvousFunnelProcStart\r | |
189 | mov qword ptr [rcx+20h], LONG_JUMP - RendezvousFunnelProcStart\r | |
190 | mov qword ptr [rcx+28h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r | |
de243ee4 | 191 | \r |
768e2a90 | 192 | ret\r |
de243ee4 | 193 | \r |
768e2a90 | 194 | AsmGetAddressMap ENDP\r |
195 | \r | |
196 | END\r |