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
|
;------------------------------------------------------------------------------ ;
; 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:
;
; MpFuncs.nasm
;
; Abstract:
;
; This is the assembly code for MP support
;
;-------------------------------------------------------------------------------
%include "MpEqu.inc"
extern ASM_PFX(InitializeFloatingPointUnits)
SECTION .text
;-------------------------------------------------------------------------------------
;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.
;-------------------------------------------------------------------------------------
global ASM_PFX(RendezvousFunnelProc)
ASM_PFX(RendezvousFunnelProc):
RendezvousFunnelProcStart:
; At this point CS = 0x(vv00) and ip= 0x0.
BITS 16
mov ebp, eax ; save BIST information
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor ax, ax
mov fs, ax
mov gs, ax
mov si, BufferStartLocation
mov ebx, [si]
mov di, PmodeOffsetLocation
mov eax, [di]
mov di, ax
sub di, 06h
add eax, ebx
mov [di],eax
mov si, GdtrLocation
o32 lgdt [cs:si]
mov si, IdtrLocation
o32 lidt [cs:si]
xor ax, ax
mov ds, ax
mov eax, cr0 ;Get control register 0
or eax, 000000003h ;Set PE bit (bit #0) & MP
mov cr0, eax
jmp PROTECT_MODE_CS:strict dword 0 ; far jump to protected mode
BITS 32
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
mov esi, ebx
mov edi, esi
add edi, LockLocation
mov eax, NotVacantFlag
TestLock:
xchg [edi], eax
cmp eax, NotVacantFlag
jz TestLock
mov edi, esi
add edi, NumApsExecutingLoction
inc dword [edi]
mov ebx, [edi]
ProgramStack:
mov edi, esi
add edi, StackSizeLocation
mov eax, [edi]
mov edi, esi
add edi, StackStartAddressLocation
add eax, [edi]
mov esp, eax
mov [edi], eax
Releaselock:
mov eax, VacantFlag
mov edi, esi
add edi, LockLocation
xchg [edi], eax
CProcedureInvoke:
push ebp ; push BIST data at top of AP stack
xor ebp, ebp ; clear ebp for call stack trace
push ebp
mov ebp, esp
mov eax, ASM_PFX(InitializeFloatingPointUnits)
call eax ; Call assembly function to initialize FPU per UEFI spec
push ebx ; Push NumApsExecuting
mov eax, esi
add eax, LockLocation
push eax ; push address of exchange info data buffer
mov edi, esi
add edi, ApProcedureLocation
mov eax, [edi]
call eax ; invoke C function
jmp $ ; never reach here
RendezvousFunnelProcEnd:
global ASM_PFX(AsmInitializeGdt)
ASM_PFX(AsmInitializeGdt):
push ebp
mov ebp, esp
pushad
mov edi, [ebp + 8] ; Load GDT register
lgdt [edi] ; and update the GDTR
push PROTECT_MODE_CS
mov eax, ASM_PFX(SetCodeSelectorFarJump)
push eax
retf
ASM_PFX(SetCodeSelectorFarJump):
mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
popad
pop ebp
ret
|