~ubuntu-branches/ubuntu/trusty/virtualbox-lts-xenial/trusty-updates

« back to all changes in this revision

Viewing changes to src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#------------------------------------------------------------------------------
 
2
#*
 
3
#*   Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
 
4
#*   This program and the accompanying materials
 
5
#*   are licensed and made available under the terms and conditions of the BSD License
 
6
#*   which accompanies this distribution.  The full text of the license may be found at
 
7
#*   http://opensource.org/licenses/bsd-license.php
 
8
#*
 
9
#*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 
10
#*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
11
#*
 
12
#*    CpuAsm.S
 
13
#*
 
14
#*   Abstract:
 
15
#*
 
16
#------------------------------------------------------------------------------
 
17
 
 
18
 
 
19
#.MMX
 
20
#.XMM
 
21
 
 
22
#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
 
23
 
 
24
 
 
25
#
 
26
# point to the external interrupt vector table
 
27
#
 
28
ExternalVectorTablePtr:
 
29
    .byte      0, 0, 0, 0
 
30
 
 
31
ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
 
32
ASM_PFX(InitializeExternalVectorTablePtr):
 
33
    movl    4(%esp), %eax
 
34
    movl    %eax, ExternalVectorTablePtr
 
35
    ret
 
36
 
 
37
#------------------------------------------------------------------------------
 
38
# VOID
 
39
# SetCodeSelector (
 
40
#   UINT16 Selector
 
41
#   );
 
42
#------------------------------------------------------------------------------
 
43
ASM_GLOBAL ASM_PFX(SetCodeSelector)
 
44
ASM_PFX(SetCodeSelector):
 
45
    movl    4(%esp), %ecx
 
46
    subl    $0x10, %esp 
 
47
    leal    setCodeSelectorLongJump, %eax 
 
48
    movl    %eax, (%esp)
 
49
    movw    %cx, 4(%esp)
 
50
    .byte   0xFF, 0x2C, 0x24   # jmp *(%esp)  note:(FWORD jmp) 
 
51
setCodeSelectorLongJump:
 
52
    addl    $0x10, %esp 
 
53
    ret
 
54
 
 
55
#------------------------------------------------------------------------------
 
56
# VOID
 
57
# SetDataSelectors (
 
58
#   UINT16 Selector
 
59
#   );
 
60
#------------------------------------------------------------------------------
 
61
ASM_GLOBAL ASM_PFX(SetDataSelectors)
 
62
ASM_PFX(SetDataSelectors):
 
63
    movl    4(%esp), %ecx
 
64
    movw    %cx, %ss
 
65
    movw    %cx, %ds
 
66
    movw    %cx, %es
 
67
    movw    %cx, %fs
 
68
    movw    %cx, %gs
 
69
    ret
 
70
 
 
71
#---------------------------------------;
 
72
# CommonInterruptEntry                  ;
 
73
#---------------------------------------;
 
74
# The follow algorithm is used for the common interrupt routine.
 
75
 
 
76
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
 
77
ASM_PFX(CommonInterruptEntry):
 
78
    cli
 
79
    #
 
80
    # All interrupt handlers are invoked through interrupt gates, so
 
81
    # IF flag automatically cleared at the entry point
 
82
    #
 
83
 
 
84
    #
 
85
    # Calculate vector number
 
86
    #
 
87
    # Get the return address of call, actually, it is the
 
88
    # address of vector number.
 
89
    #
 
90
    xchgl   (%esp), %ecx
 
91
    movw    (%ecx), %cx
 
92
    andl    $0x0FFFF, %ecx
 
93
    cmpl    $32, %ecx         # Intel reserved vector for exceptions?
 
94
    jae     NoErrorCode
 
95
    bt      %ecx, ASM_PFX(mErrorCodeFlag)
 
96
    jc      HasErrorCode
 
97
 
 
98
NoErrorCode:
 
99
 
 
100
    #
 
101
    # Stack:
 
102
    # +---------------------+
 
103
    # +    EFlags           +
 
104
    # +---------------------+
 
105
    # +    CS               +
 
106
    # +---------------------+
 
107
    # +    EIP              +
 
108
    # +---------------------+
 
109
    # +    ECX              +
 
110
    # +---------------------+ <-- ESP
 
111
    #
 
112
    # Registers:
 
113
    #   ECX - Vector Number
 
114
    #
 
115
 
 
116
    #
 
117
    # Put Vector Number on stack
 
118
    #
 
119
    pushl   %ecx
 
120
 
 
121
    #
 
122
    # Put 0 (dummy) error code on stack, and restore ECX
 
123
    #
 
124
    xorl    %ecx, %ecx  # ECX = 0
 
125
    xchgl   4(%esp), %ecx
 
126
 
 
127
    jmp     ErrorCodeAndVectorOnStack
 
128
 
 
129
HasErrorCode:
 
130
 
 
131
    #
 
132
    # Stack:
 
133
    # +---------------------+
 
134
    # +    EFlags           +
 
135
    # +---------------------+
 
136
    # +    CS               +
 
137
    # +---------------------+
 
138
    # +    EIP              +
 
139
    # +---------------------+
 
140
    # +    Error Code       +
 
141
    # +---------------------+
 
142
    # +    ECX              +
 
143
    # +---------------------+ <-- ESP
 
144
    #
 
145
    # Registers:
 
146
    #   ECX - Vector Number
 
147
    #
 
148
 
 
149
    #
 
150
    # Put Vector Number on stack and restore ECX
 
151
    #
 
152
    xchgl   (%esp), %ecx 
 
153
 
 
154
    #
 
155
    # Fall through to join main routine code
 
156
    # at ErrorCodeAndVectorOnStack
 
157
    #
 
158
CommonInterruptEntry_al_0000:
 
159
    jmp CommonInterruptEntry_al_0000
 
160
 
 
161
ErrorCodeAndVectorOnStack:
 
162
    pushl   %ebp
 
163
    movl    %esp, %ebp
 
164
 
 
165
    #
 
166
    # Stack:
 
167
    # +---------------------+
 
168
    # +    EFlags           +
 
169
    # +---------------------+
 
170
    # +    CS               +
 
171
    # +---------------------+
 
172
    # +    EIP              +
 
173
    # +---------------------+
 
174
    # +    Error Code       +
 
175
    # +---------------------+
 
176
    # +    Vector Number    +
 
177
    # +---------------------+
 
178
    # +    EBP              +
 
179
    # +---------------------+ <-- EBP
 
180
    #
 
181
 
 
182
    #
 
183
    # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
 
184
    # is 16-byte aligned
 
185
    #
 
186
    andl    $0x0fffffff0, %esp 
 
187
    subl    $12, %esp
 
188
 
 
189
#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
 
190
    pushl   %eax
 
191
    pushl   %ecx
 
192
    pushl   %edx
 
193
    pushl   %ebx
 
194
    leal    24(%ebp), %ecx
 
195
    pushl   %ecx                          # ESP
 
196
    pushl   (%ebp)              # EBP
 
197
    pushl   %esi
 
198
    pushl   %edi
 
199
 
 
200
#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;
 
201
    movl    %ss, %eax
 
202
    pushl   %eax
 
203
    movzwl  16(%ebp), %eax 
 
204
    pushl   %eax
 
205
    movl    %ds, %eax
 
206
    pushl   %eax
 
207
    movl    %es, %eax
 
208
    pushl   %eax
 
209
    movl    %fs, %eax
 
210
    pushl   %eax
 
211
    movl    %gs, %eax
 
212
    pushl   %eax
 
213
 
 
214
#; UINT32  Eip;
 
215
    movl    12(%ebp), %eax
 
216
    pushl   %eax
 
217
 
 
218
#; UINT32  Gdtr[2], Idtr[2];
 
219
    subl    $8, %esp
 
220
    sidt    (%esp)
 
221
    movl    2(%esp), %eax
 
222
    xchgl   (%esp), %eax
 
223
    andl    $0x0FFFF, %eax 
 
224
    movl    %eax, 4(%esp)
 
225
 
 
226
    subl    $8, %esp
 
227
    sgdt    (%esp)
 
228
    movl    2(%esp), %eax
 
229
    xchgl   (%esp), %eax
 
230
    andl    $0x0FFFF, %eax 
 
231
    movl    %eax, 4(%esp)
 
232
 
 
233
#; UINT32  Ldtr, Tr;
 
234
    xorl    %eax, %eax
 
235
    str     %ax
 
236
    pushl   %eax
 
237
    sldt    %ax
 
238
    pushl   %eax
 
239
 
 
240
#; UINT32  EFlags;
 
241
    movl    20(%ebp), %eax
 
242
    pushl   %eax
 
243
 
 
244
#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
 
245
    movl    %cr4, %eax
 
246
    orl     $0x208, %eax
 
247
    movl    %eax, %cr4
 
248
    pushl   %eax
 
249
    movl    %cr3, %eax
 
250
    pushl   %eax
 
251
    movl    %cr2, %eax
 
252
    pushl   %eax
 
253
    xorl    %eax, %eax
 
254
    pushl   %eax
 
255
    movl    %cr0, %eax
 
256
    pushl   %eax
 
257
 
 
258
#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
 
259
    movl    %dr7, %eax
 
260
    pushl   %eax
 
261
    movl    %dr6, %eax
 
262
    pushl   %eax
 
263
    movl    %dr3, %eax
 
264
    pushl   %eax
 
265
    movl    %dr2, %eax
 
266
    pushl   %eax
 
267
    movl    %dr1, %eax
 
268
    pushl   %eax
 
269
    movl    %dr0, %eax
 
270
    pushl   %eax
 
271
 
 
272
#; FX_SAVE_STATE_IA32 FxSaveState;
 
273
    subl    $512, %esp
 
274
    movl    %esp, %edi
 
275
    .byte      0x0f, 0x0ae, 0x07 #fxsave [edi]
 
276
 
 
277
#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
 
278
    cld
 
279
 
 
280
#; UINT32  ExceptionData;
 
281
    pushl   8(%ebp)
 
282
 
 
283
#; call into exception handler
 
284
    movl    ExternalVectorTablePtr, %eax  # get the interrupt vectors base
 
285
    orl     %eax, %eax                        # NULL?
 
286
    jz      nullExternalExceptionHandler
 
287
 
 
288
    mov     4(%ebp), %ecx
 
289
    movl    (%eax,%ecx,4), %eax
 
290
    orl     %eax, %eax                        # NULL?
 
291
    jz      nullExternalExceptionHandler
 
292
 
 
293
#; Prepare parameter and call
 
294
    movl    %esp, %edx
 
295
    pushl   %edx
 
296
    movl    4(%ebp), %edx
 
297
    pushl   %edx
 
298
 
 
299
    #
 
300
    # Call External Exception Handler
 
301
    #
 
302
    call    *%eax
 
303
    addl    $8, %esp
 
304
 
 
305
nullExternalExceptionHandler:
 
306
 
 
307
    cli
 
308
#; UINT32  ExceptionData;
 
309
    addl    $4, %esp
 
310
 
 
311
#; FX_SAVE_STATE_IA32 FxSaveState;
 
312
    movl    %esp, %esi
 
313
    .byte      0x0f, 0x0ae, 0x0e # fxrstor [esi]
 
314
    addl    $512, %esp
 
315
 
 
316
#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
 
317
#; Skip restoration of DRx registers to support in-circuit emualators
 
318
#; or debuggers set breakpoint in interrupt/exception context
 
319
    addl    $24, %esp
 
320
 
 
321
#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
 
322
    popl    %eax
 
323
    movl    %eax, %cr0
 
324
    addl    $4, %esp    # not for Cr1
 
325
    popl    %eax
 
326
    movl    %eax, %cr2
 
327
    popl    %eax
 
328
    movl    %eax, %cr3
 
329
    popl    %eax
 
330
    movl    %eax, %cr4
 
331
 
 
332
#; UINT32  EFlags;
 
333
    popl    20(%ebp)
 
334
 
 
335
#; UINT32  Ldtr, Tr;
 
336
#; UINT32  Gdtr[2], Idtr[2];
 
337
#; Best not let anyone mess with these particular registers...
 
338
    addl    $24, %esp
 
339
 
 
340
#; UINT32  Eip;
 
341
    popl    12(%ebp)
 
342
 
 
343
#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;
 
344
#; NOTE - modified segment registers could hang the debugger...  We
 
345
#;        could attempt to insulate ourselves against this possibility,
 
346
#;        but that poses risks as well.
 
347
#;
 
348
    popl    %gs
 
349
    popl    %fs
 
350
    popl    %es
 
351
    popl    %ds
 
352
    popl    16(%ebp)
 
353
    popl    %ss
 
354
 
 
355
#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
 
356
    popl    %edi
 
357
    popl    %esi
 
358
    addl    $4, %esp   # not for ebp
 
359
    addl    $4, %esp   # not for esp
 
360
    popl    %ebx
 
361
    popl    %edx
 
362
    popl    %ecx
 
363
    popl    %eax
 
364
 
 
365
    movl    %ebp, %esp
 
366
    popl    %ebp
 
367
    addl    $8, %esp
 
368
    iretl
 
369
 
 
370
 
 
371
#END
 
372