• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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