summaryrefslogtreecommitdiff
path: root/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
blob: 425bc202fdea4401d3bd26e6ceb684b7461f3a3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution.  The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php.
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
; Module Name:
;
;   MpFuncs32.asm
;
; Abstract:
;
;   This is the assembly code for MP support
;
;-------------------------------------------------------------------------------

include  MpEqu.inc
extern   InitializeFloatingPointUnits:PROC

.code
;-------------------------------------------------------------------------------------
;RendezvousFunnelProc  procedure follows. All APs execute their procedure. This
;procedure serializes all the AP processors through an Init sequence. It must be
;noted that APs arrive here very raw...ie: real mode, no stack.
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
;IS IN MACHINE CODE.
;-------------------------------------------------------------------------------------
RendezvousFunnelProc   PROC  PUBLIC
RendezvousFunnelProcStart::
; At this point CS = 0x(vv00) and ip= 0x0.
; Save BIST information to ebp firstly
    db 66h,  08bh, 0e8h               ; mov        ebp, eax    ; save BIST information

    db 8ch,0c8h                       ; mov        ax,cs
    db 8eh,0d8h                       ; mov        ds,ax
    db 8eh,0c0h                       ; mov        es,ax
    db 8eh,0d0h                       ; mov        ss,ax
    db 33h,0c0h                       ; xor        ax,ax
    db 8eh,0e0h                       ; mov        fs,ax
    db 8eh,0e8h                       ; mov        gs,ax

    db 0BEh                           ; opcode of mov si, mem16
    dw BufferStartLocation            ; mov        si, BufferStartLocation
    db 66h,  8Bh, 1Ch                 ; mov        ebx,dword ptr [si]

    db 0BFh                           ; opcode of mov di, mem16
    dw PmodeOffsetLocation            ; mov        di, PmodeOffsetLocation
    db 66h,  8Bh, 05h                 ; mov        eax,dword ptr [di]
    db 8Bh,  0F8h                     ; mov        di, ax
    db 83h,  0EFh,06h                 ; sub        di, 06h
    db 66h,  03h, 0C3h                ; add        eax, ebx
    db 66h,  89h, 05h                 ; mov        dword ptr [di],eax

    db 0BFh                           ; opcode of mov di, mem16
    dw LmodeOffsetLocation            ; mov        di, LmodeOffsetLocation
    db 66h,  8Bh, 05h                 ; mov        eax,dword ptr [di]
    db 8Bh,  0F8h                     ; mov        di, ax
    db 83h,  0EFh,06h                 ; sub        di, 06h
    db 66h,  03h, 0C3h                ; add        eax, ebx
    db 66h,  89h, 05h                 ; mov        dword ptr [di],eax

    db 0BEh
    dw Cr3Location                    ; mov        si, Cr3Location
    db 66h,  8Bh, 0Ch                 ; mov        ecx,dword ptr [si]     ; ECX is keeping the value of CR3

    db 0BEh                           ; opcode of mov si, mem16
    dw GdtrLocation                   ; mov        si, GdtrLocation
    db 66h                            ; db         66h
    db 2Eh,  0Fh, 01h, 14h            ; lgdt       fword ptr cs:[si]

    db 0BEh
    dw IdtrLocation                   ; mov        si, IdtrLocation
    db 66h                            ; db         66h
    db 2Eh,0Fh, 01h, 1Ch              ; lidt       fword ptr cs:[si]

    db 33h,  0C0h                     ; xor        ax,  ax
    db 8Eh,  0D8h                     ; mov        ds,  ax

    db 0Fh,  20h, 0C0h                ; mov        eax, cr0               ;Get control register 0
    db 66h,  83h, 0C8h, 03h           ; or         eax, 000000003h        ;Set PE bit (bit #0) & MP
    db 0Fh,  22h, 0C0h                ; mov        cr0, eax

    db 66h,  67h, 0EAh                ; far jump
    dd 0h                             ; 32-bit offset
    dw PROTECT_MODE_CS                ; 16-bit selector

Flat32Start::                         ; protected mode entry point
    mov        ax, PROTECT_MODE_DS
    mov        ds, ax
    mov        es, ax
    mov        fs, ax
    mov        gs, ax
    mov        ss, ax

    db 0Fh,  20h,  0E0h           ; mov        eax, cr4
    db 0Fh,  0BAh, 0E8h, 05h      ; bts        eax, 5
    db 0Fh,  22h,  0E0h           ; mov        cr4, eax

    db 0Fh,  22h,  0D9h           ; mov        cr3, ecx

    db 0B9h
    dd 0C0000080h                 ; mov        ecx, 0c0000080h     ; EFER MSR number.
    db 0Fh,  32h                  ; rdmsr                          ; Read EFER.
    db 0Fh,  0BAh, 0E8h, 08h      ; bts        eax, 8              ; Set LME=1.
    db 0Fh,  30h                  ; wrmsr                          ; Write EFER.

    db 0Fh,  20h,  0C0h           ; mov        eax, cr0            ; Read CR0.
    db 0Fh,  0BAh, 0E8h, 1Fh      ; bts        eax, 31             ; Set PG=1.
    db 0Fh,  22h,  0C0h           ; mov        cr0, eax            ; Write CR0.

LONG_JUMP:
    db 67h,  0EAh                 ; far jump
    dd 0h                         ; 32-bit offset
    dw LONG_MODE_CS               ; 16-bit selector

LongModeStart::
    mov        ax,  LONG_MODE_DS
    mov        ds,  ax
    mov        es,  ax
    mov        ss,  ax

    mov        esi, ebx
    mov        edi, esi
    add        edi, LockLocation
    mov        rax, NotVacantFlag

TestLock:
    xchg       qword ptr [edi], rax
    cmp        rax, NotVacantFlag
    jz         TestLock

    mov        edi, esi
    add        edi, NumApsExecutingLoction
    inc        dword ptr [edi]
    mov        ebx, dword ptr [edi]

ProgramStack:
    mov        edi, esi
    add        edi, StackSizeLocation
    mov        rax, qword ptr [edi]
    mov        edi, esi
    add        edi, StackStartAddressLocation
    add        rax, qword ptr [edi]
    mov        rsp, rax
    mov        qword ptr [edi], rax

Releaselock:
    mov        rax, VacantFlag
    mov        edi, esi
    add        edi, LockLocation
    xchg       qword ptr [edi], rax

CProcedureInvoke:
    push       rbp               ; push BIST data
    xor        rbp, rbp          ; clear ebp for call stack trace
    push       rbp
    mov        rbp, rsp

    mov        rax, InitializeFloatingPointUnits
    sub        rsp, 20h
    call       rax               ; Call assembly function to initialize FPU per UEFI spec
    add        rsp, 20h

    mov        edx, ebx          ; edx is NumApsExecuting
    mov        ecx, esi
    add        ecx, LockLocation ; rcx is address of exchange info data buffer

    mov        edi, esi
    add        edi, ApProcedureLocation
    mov        rax, qword ptr [edi]

    sub        rsp, 20h
    call       rax               ; invoke C function
    add        rsp, 20h
    jmp        $

RendezvousFunnelProc   ENDP
RendezvousFunnelProcEnd::


AsmInitializeGdt   PROC
    push       rbp
    mov        rbp, rsp

    lgdt       fword PTR [rcx]  ; update the GDTR

    sub        rsp, 0x10
    lea        rax, SetCodeSelectorFarJump
    mov        [rsp], rax
    mov        rdx, LONG_MODE_CS
    mov        [rsp + 4], dx    ; get new CS
    jmp        fword ptr [rsp]
SetCodeSelectorFarJump:
    add        rsp, 0x10

    mov        rax, LONG_MODE_DS          ; get new DS
    mov        ds, ax
    mov        es, ax
    mov        fs, ax
    mov        gs, ax
    mov        ss, ax

    pop        rbp
    ret
AsmInitializeGdt  ENDP

END