1ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;------------------------------------------------------------------------------ ;
2ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
3ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; This program and the accompanying materials
4ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; are licensed and made available under the terms and conditions of the BSD License
5ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; which accompanies this distribution.  The full text of the license may be found at
6ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; http://opensource.org/licenses/bsd-license.php.
7ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;
8ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;
11ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; Module Name:
12ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;
13ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;   MpFuncs32.asm
14ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;
15ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; Abstract:
16ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;
17ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;   This is the assembly code for MP support
18ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;
19ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;-------------------------------------------------------------------------------
20ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
21ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Faninclude  MpEqu.inc
22ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fanextern   InitializeFloatingPointUnits:PROC
23ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
24ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan.code
25ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;-------------------------------------------------------------------------------------
26ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;RendezvousFunnelProc  procedure follows. All APs execute their procedure. This
27ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;procedure serializes all the AP processors through an Init sequence. It must be
28ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;noted that APs arrive here very raw...ie: real mode, no stack.
29ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
30ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;IS IN MACHINE CODE.
31ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;-------------------------------------------------------------------------------------
32ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanRendezvousFunnelProc   PROC  PUBLIC
33ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanRendezvousFunnelProcStart::
34ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; At this point CS = 0x(vv00) and ip= 0x0.
35ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan; Save BIST information to ebp firstly
36ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  08bh, 0e8h               ; mov        ebp, eax    ; save BIST information
37ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
38ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8ch,0c8h                       ; mov        ax,cs
39ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8eh,0d8h                       ; mov        ds,ax
40ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8eh,0c0h                       ; mov        es,ax
41ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8eh,0d0h                       ; mov        ss,ax
42ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 33h,0c0h                       ; xor        ax,ax
43ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8eh,0e0h                       ; mov        fs,ax
44ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8eh,0e8h                       ; mov        gs,ax
45ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
46ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0BEh                           ; opcode of mov si, mem16
47ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw BufferStartLocation            ; mov        si, BufferStartLocation
48ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  8Bh, 1Ch                 ; mov        ebx,dword ptr [si]
49ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
50ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0BFh                           ; opcode of mov di, mem16
51ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw PmodeOffsetLocation            ; mov        di, PmodeOffsetLocation
52ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  8Bh, 05h                 ; mov        eax,dword ptr [di]
53ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8Bh,  0F8h                     ; mov        di, ax
54ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 83h,  0EFh,06h                 ; sub        di, 06h
55ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  03h, 0C3h                ; add        eax, ebx
56ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  89h, 05h                 ; mov        dword ptr [di],eax
57ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
58ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0BFh                           ; opcode of mov di, mem16
59ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw LmodeOffsetLocation            ; mov        di, LmodeOffsetLocation
60ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  8Bh, 05h                 ; mov        eax,dword ptr [di]
61ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8Bh,  0F8h                     ; mov        di, ax
62ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 83h,  0EFh,06h                 ; sub        di, 06h
63ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  03h, 0C3h                ; add        eax, ebx
64ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  89h, 05h                 ; mov        dword ptr [di],eax
65ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
66ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0BEh
67ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw Cr3Location                    ; mov        si, Cr3Location
68ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  8Bh, 0Ch                 ; mov        ecx,dword ptr [si]     ; ECX is keeping the value of CR3
69ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
70ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0BEh                           ; opcode of mov si, mem16
71ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw GdtrLocation                   ; mov        si, GdtrLocation
72ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h                            ; db         66h
73ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 2Eh,  0Fh, 01h, 14h            ; lgdt       fword ptr cs:[si]
74ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
75ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0BEh
76ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw IdtrLocation                   ; mov        si, IdtrLocation
77ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h                            ; db         66h
78ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 2Eh,0Fh, 01h, 1Ch              ; lidt       fword ptr cs:[si]
79ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
80ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 33h,  0C0h                     ; xor        ax,  ax
81ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 8Eh,  0D8h                     ; mov        ds,  ax
82ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
83ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  20h, 0C0h                ; mov        eax, cr0               ;Get control register 0
84ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  83h, 0C8h, 03h           ; or         eax, 000000003h        ;Set PE bit (bit #0) & MP
85ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  22h, 0C0h                ; mov        cr0, eax
86ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
87ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 66h,  67h, 0EAh                ; far jump
88ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dd 0h                             ; 32-bit offset
89ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw PROTECT_MODE_CS                ; 16-bit selector
90ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
91ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanFlat32Start::                         ; protected mode entry point
92ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ax, PROTECT_MODE_DS
93ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ds, ax
94ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        es, ax
95ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        fs, ax
96ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        gs, ax
97ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ss, ax
98ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
99ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  20h,  0E0h           ; mov        eax, cr4
100ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  0BAh, 0E8h, 05h      ; bts        eax, 5
101ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  22h,  0E0h           ; mov        cr4, eax
102ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
103ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  22h,  0D9h           ; mov        cr3, ecx
104ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
105ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0B9h
106ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dd 0C0000080h                 ; mov        ecx, 0c0000080h     ; EFER MSR number.
107ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  32h                  ; rdmsr                          ; Read EFER.
108ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  0BAh, 0E8h, 08h      ; bts        eax, 8              ; Set LME=1.
109ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  30h                  ; wrmsr                          ; Write EFER.
110ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
111ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  20h,  0C0h           ; mov        eax, cr0            ; Read CR0.
112ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  0BAh, 0E8h, 1Fh      ; bts        eax, 31             ; Set PG=1.
113ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 0Fh,  22h,  0C0h           ; mov        cr0, eax            ; Write CR0.
114ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
115ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanLONG_JUMP:
116ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    db 67h,  0EAh                 ; far jump
117ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dd 0h                         ; 32-bit offset
118ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    dw LONG_MODE_CS               ; 16-bit selector
119ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
120ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanLongModeStart::
121ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ax,  LONG_MODE_DS
122ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ds,  ax
123ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        es,  ax
124ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ss,  ax
125ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
126ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        esi, ebx
127ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        edi, esi
128ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        edi, LockLocation
129ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, NotVacantFlag
130ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
131ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanTestLock:
132ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    xchg       qword ptr [edi], rax
133ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    cmp        rax, NotVacantFlag
134ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    jz         TestLock
135ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
136ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        edi, esi
137ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        edi, NumApsExecutingLoction
138ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    inc        dword ptr [edi]
139ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ebx, dword ptr [edi]
140ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
141ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanProgramStack:
142ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        edi, esi
143ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        edi, StackSizeLocation
144ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, qword ptr [edi]
145ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        edi, esi
146ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        edi, StackStartAddressLocation
147ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        rax, qword ptr [edi]
148ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rsp, rax
149ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        qword ptr [edi], rax
150ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
151ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanReleaselock:
152ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, VacantFlag
153ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        edi, esi
154ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        edi, LockLocation
155ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    xchg       qword ptr [edi], rax
156ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
157ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanCProcedureInvoke:
158ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rbp               ; push BIST data
159ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    xor        rbp, rbp          ; clear ebp for call stack trace
160ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rbp
161ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rbp, rsp
162ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
163ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, InitializeFloatingPointUnits
164ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    sub        rsp, 20h
165ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    call       rax               ; Call assembly function to initialize FPU per UEFI spec
166ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        rsp, 20h
167ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
168ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        edx, ebx          ; edx is NumApsExecuting
169ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ecx, esi
170ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        ecx, LockLocation ; rcx is address of exchange info data buffer
171ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
172ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        edi, esi
173ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        edi, ApProcedureLocation
174ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, qword ptr [edi]
175ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
176ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    sub        rsp, 20h
177ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    call       rax               ; invoke C function
178ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        rsp, 20h
179ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    jmp        $
180ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
181ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanRendezvousFunnelProc   ENDP
182ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanRendezvousFunnelProcEnd::
183ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
184ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;-------------------------------------------------------------------------------------
185ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;  AsmGetAddressMap (&AddressMap);
186ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;-------------------------------------------------------------------------------------
187ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanAsmGetAddressMap   PROC
188ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, offset RendezvousFunnelProcStart
189ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        qword ptr [rcx], rax
190ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        qword ptr [rcx +  8h], Flat32Start - RendezvousFunnelProcStart
191ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
192ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
193ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ret
194ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanAsmGetAddressMap   ENDP
195ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
196ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;-------------------------------------------------------------------------------------
197ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
198ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;about to become an AP. It switches it'stack with the current AP.
199ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;AsmExchangeRole (IN   CPU_EXCHANGE_INFO    *MyInfo, IN   CPU_EXCHANGE_INFO    *OthersInfo);
200ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan;-------------------------------------------------------------------------------------
201ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanAsmExchangeRole   PROC
202ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
203ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
204ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
205ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rax
206ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rbx
207ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rcx
208ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rdx
209ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rsi
210ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rdi
211ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rbp
212ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r8
213ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r9
214ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r10
215ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r11
216ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r12
217ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r13
218ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r14
219ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       r15
220ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
221ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, cr0
222ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rax
223ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
224ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, cr4
225ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rax
226ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
227ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; rsi contains MyInfo pointer
228ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rsi, rcx
229ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
230ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; rdi contains OthersInfo pointer
231ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rdi, rdx
232ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
233ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ;Store EFLAGS, GDTR and IDTR regiter to stack
234ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pushfq
235ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    sgdt       fword ptr [rsi + 16]
236ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    sidt       fword ptr [rsi + 26]
237ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
238ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; Store the its StackPointer
239ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        qword ptr [rsi + 8], rsp
240ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
241ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; update its switch state to STORED
242ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        byte ptr [rsi], CPU_SWITCH_STATE_STORED
243ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
244ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanWaitForOtherStored:
245ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; wait until the other CPU finish storing its state
246ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    cmp        byte ptr [rdi], CPU_SWITCH_STATE_STORED
247ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    jz         OtherStored
248ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pause
249ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    jmp        WaitForOtherStored
250ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
251ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanOtherStored:
252ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; Since another CPU already stored its state, load them
253ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; load GDTR value
254ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    lgdt       fword ptr [rdi + 16]
255ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
256ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; load IDTR value
257ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    lidt       fword ptr [rdi + 26]
258ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
259ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; load its future StackPointer
260ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rsp, qword ptr [rdi + 8]
261ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
262ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; update the other CPU's switch state to LOADED
263ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        byte ptr [rdi], CPU_SWITCH_STATE_LOADED
264ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
265ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanWaitForOtherLoaded:
266ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; wait until the other CPU finish loading new state,
267ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; otherwise the data in stack may corrupt
268ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    cmp        byte ptr [rsi], CPU_SWITCH_STATE_LOADED
269ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    jz         OtherLoaded
270ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pause
271ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    jmp        WaitForOtherLoaded
272ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
273ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanOtherLoaded:
274ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ; since the other CPU already get the data it want, leave this procedure
275ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    popfq
276ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
277ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rax
278ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        cr4, rax
279ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
280ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rax
281ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        cr0, rax
282ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
283ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r15
284ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r14
285ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r13
286ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r12
287ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r11
288ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r10
289ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r9
290ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        r8
291ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rbp
292ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rdi
293ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rsi
294ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rdx
295ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rcx
296ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rbx
297ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rax
298ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
299ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ret
300ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanAsmExchangeRole   ENDP
301ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
302ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanAsmInitializeGdt   PROC
303ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    push       rbp
304ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rbp, rsp
305ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
306ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    lgdt       fword PTR [rcx]  ; update the GDTR
307ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
308ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    sub        rsp, 0x10
309ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    lea        rax, SetCodeSelectorFarJump
310ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        [rsp], rax
311ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rdx, LONG_MODE_CS
312ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        [rsp + 4], dx    ; get new CS
313ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    jmp        fword ptr [rsp]
314ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanSetCodeSelectorFarJump:
315ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    add        rsp, 0x10
316ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
317ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        rax, LONG_MODE_DS          ; get new DS
318ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ds, ax
319ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        es, ax
320ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        fs, ax
321ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        gs, ax
322ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    mov        ss, ax
323ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
324ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    pop        rbp
325ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan    ret
326ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanAsmInitializeGdt  ENDP
327ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff Fan
328ea0f431cec51247658901a4f65ae76d6bbdd96e9Jeff FanEND
329