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