1;------------------------------------------------------------------------------ ; 2; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> 3; This program and the accompanying materials 4; are licensed and made available under the terms and conditions of the BSD License 5; which accompanies this distribution. The full text of the license may be found at 6; http://opensource.org/licenses/bsd-license.php. 7; 8; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 9; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 10; 11; Module Name: 12; 13; MpFuncs32.asm 14; 15; Abstract: 16; 17; This is the assembly code for MP support 18; 19;------------------------------------------------------------------------------- 20 21.686p 22.model flat 23 24include MpEqu.inc 25InitializeFloatingPointUnits PROTO C 26 27.code 28 29;------------------------------------------------------------------------------------- 30;RendezvousFunnelProc procedure follows. All APs execute their procedure. This 31;procedure serializes all the AP processors through an Init sequence. It must be 32;noted that APs arrive here very raw...ie: real mode, no stack. 33;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC 34;IS IN MACHINE CODE. 35;------------------------------------------------------------------------------------- 36RendezvousFunnelProc PROC PUBLIC 37RendezvousFunnelProcStart:: 38; At this point CS = 0x(vv00) and ip= 0x0. 39; Save BIST information to ebp firstly 40 db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information 41 42 db 8ch,0c8h ; mov ax,cs 43 db 8eh,0d8h ; mov ds,ax 44 db 8eh,0c0h ; mov es,ax 45 db 8eh,0d0h ; mov ss,ax 46 db 33h,0c0h ; xor ax,ax 47 db 8eh,0e0h ; mov fs,ax 48 db 8eh,0e8h ; mov gs,ax 49 50 db 0BEh ; opcode of mov si, mem16 51 dw BufferStartLocation ; mov si, BufferStartLocation 52 db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si] 53 54 db 0BFh ; opcode of mov di, mem16 55 dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation 56 db 66h, 8Bh, 05h ; mov eax,dword ptr [di] 57 db 8Bh, 0F8h ; mov di, ax 58 db 83h, 0EFh,06h ; sub di, 06h 59 db 66h, 03h, 0C3h ; add eax, ebx 60 db 66h, 89h, 05h ; mov dword ptr [di],eax 61 62 db 0BEh ; opcode of mov si, mem16 63 dw GdtrLocation ; mov si, GdtrLocation 64 db 66h ; db 66h 65 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si] 66 67 db 0BEh 68 dw IdtrLocation ; mov si, IdtrLocation 69 db 66h ; db 66h 70 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si] 71 72 db 33h, 0C0h ; xor ax, ax 73 db 8Eh, 0D8h ; mov ds, ax 74 75 db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0 76 db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP 77 db 0Fh, 22h, 0C0h ; mov cr0, eax 78 79 db 66h, 67h, 0EAh ; far jump 80 dd 0h ; 32-bit offset 81 dw PROTECT_MODE_CS ; 16-bit selector 82 83Flat32Start:: ; protected mode entry point 84 mov ax, PROTECT_MODE_DS 85 mov ds, ax 86 mov es, ax 87 mov fs, ax 88 mov gs, ax 89 mov ss, ax 90 91 mov esi, ebx 92 mov edi, esi 93 add edi, LockLocation 94 mov eax, NotVacantFlag 95 96TestLock: 97 xchg dword ptr [edi], eax 98 cmp eax, NotVacantFlag 99 jz TestLock 100 101 mov edi, esi 102 add edi, NumApsExecutingLoction 103 inc dword ptr [edi] 104 mov ebx, dword ptr [edi] 105 106ProgramStack: 107 mov edi, esi 108 add edi, StackSizeLocation 109 mov eax, dword ptr [edi] 110 mov edi, esi 111 add edi, StackStartAddressLocation 112 add eax, dword ptr [edi] 113 mov esp, eax 114 mov dword ptr [edi], eax 115 116Releaselock: 117 mov eax, VacantFlag 118 mov edi, esi 119 add edi, LockLocation 120 xchg dword ptr [edi], eax 121 122CProcedureInvoke: 123 push ebp ; push BIST data at top of AP stack 124 xor ebp, ebp ; clear ebp for call stack trace 125 push ebp 126 mov ebp, esp 127 128 mov eax, InitializeFloatingPointUnits 129 call eax ; Call assembly function to initialize FPU per UEFI spec 130 131 push ebx ; Push NumApsExecuting 132 mov eax, esi 133 add eax, LockLocation 134 push eax ; push address of exchange info data buffer 135 136 mov edi, esi 137 add edi, ApProcedureLocation 138 mov eax, dword ptr [edi] 139 140 call eax ; invoke C function 141 142 jmp $ ; never reach here 143 144RendezvousFunnelProc ENDP 145RendezvousFunnelProcEnd:: 146 147;------------------------------------------------------------------------------------- 148; AsmGetAddressMap (&AddressMap); 149;------------------------------------------------------------------------------------- 150AsmGetAddressMap PROC near C PUBLIC 151 pushad 152 mov ebp,esp 153 154 mov ebx, dword ptr [ebp+24h] 155 mov dword ptr [ebx], RendezvousFunnelProcStart 156 mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart 157 mov dword ptr [ebx + 8h], 0 158 mov dword ptr [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart 159 160 popad 161 ret 162AsmGetAddressMap ENDP 163 164PAUSE32 MACRO 165 DB 0F3h 166 DB 090h 167 ENDM 168 169;------------------------------------------------------------------------------------- 170;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is 171;about to become an AP. It switches it'stack with the current AP. 172;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo); 173;------------------------------------------------------------------------------------- 174AsmExchangeRole PROC near C PUBLIC 175 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack 176 ; at the same time. If 1 CPU try to call a function, stack will be corrupted. 177 pushad 178 mov ebp,esp 179 180 ; esi contains MyInfo pointer 181 mov esi, dword ptr [ebp+24h] 182 183 ; edi contains OthersInfo pointer 184 mov edi, dword ptr [ebp+28h] 185 186 ;Store EFLAGS, GDTR and IDTR register to stack 187 pushfd 188 mov eax, cr4 189 push eax ; push cr4 firstly 190 mov eax, cr0 191 push eax 192 193 sgdt fword ptr [esi+8] 194 sidt fword ptr [esi+14] 195 196 ; Store the its StackPointer 197 mov dword ptr [esi+4],esp 198 199 ; update its switch state to STORED 200 mov byte ptr [esi], CPU_SWITCH_STATE_STORED 201 202WaitForOtherStored: 203 ; wait until the other CPU finish storing its state 204 cmp byte ptr [edi], CPU_SWITCH_STATE_STORED 205 jz OtherStored 206 PAUSE32 207 jmp WaitForOtherStored 208 209OtherStored: 210 ; Since another CPU already stored its state, load them 211 ; load GDTR value 212 lgdt fword ptr [edi+8] 213 214 ; load IDTR value 215 lidt fword ptr [edi+14] 216 217 ; load its future StackPointer 218 mov esp, dword ptr [edi+4] 219 220 ; update the other CPU's switch state to LOADED 221 mov byte ptr [edi], CPU_SWITCH_STATE_LOADED 222 223WaitForOtherLoaded: 224 ; wait until the other CPU finish loading new state, 225 ; otherwise the data in stack may corrupt 226 cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED 227 jz OtherLoaded 228 PAUSE32 229 jmp WaitForOtherLoaded 230 231OtherLoaded: 232 ; since the other CPU already get the data it want, leave this procedure 233 pop eax 234 mov cr0, eax 235 pop eax 236 mov cr4, eax 237 popfd 238 239 popad 240 ret 241AsmExchangeRole ENDP 242 243AsmInitializeGdt PROC near C PUBLIC 244 push ebp 245 mov ebp, esp 246 pushad 247 mov edi, [ebp + 8] ; Load GDT register 248 249 mov ax,cs ; Get the selector data from our code image 250 mov es,ax 251 lgdt FWORD PTR es:[edi] ; and update the GDTR 252 253 push PROTECT_MODE_CS 254 lea eax, SetCodeSelectorFarJump 255 push eax 256 retf 257SetCodeSelectorFarJump: 258 mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too 259 mov ds, ax 260 mov es, ax 261 mov fs, ax 262 mov gs, ax 263 mov ss, ax 264 265 popad 266 pop ebp 267 ret 268AsmInitializeGdt ENDP 269 270END 271