• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1;/** @file
2;
3;    This code provides low level routines that support the Virtual Machine
4;    for option ROMs.
5;
6;  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
7;  This program and the accompanying materials
8;  are licensed and made available under the terms and conditions of the BSD License
9;  which accompanies this distribution.  The full text of the license may be found at
10;  http://opensource.org/licenses/bsd-license.php
11;
12;  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13;  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14;
15;**/
16
17;---------------------------------------------------------------------------
18; Equate files needed.
19;---------------------------------------------------------------------------
20
21;---------------------------------------------------------------------------
22; Assembler options
23;---------------------------------------------------------------------------
24
25SECTION .text
26extern ASM_PFX(CopyMem)
27extern ASM_PFX(EbcInterpret)
28extern ASM_PFX(ExecuteEbcImageEntryPoint)
29
30;****************************************************************************
31; EbcLLCALLEXNative
32;
33; This function is called to execute an EBC CALLEX instruction
34; to native code.
35; This instruction requires that we thunk out to external native
36; code. For IA32, we simply switch stacks and jump to the
37; specified function. On return, we restore the stack pointer
38; to its original location.
39;
40; Destroys no working registers.
41;****************************************************************************
42; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
43global ASM_PFX(EbcLLCALLEXNative)
44ASM_PFX(EbcLLCALLEXNative):
45      push   ebp
46      push   ebx
47      mov    ebp, esp              ; standard function prolog
48
49      ; Get function address in a register
50      ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr]
51      mov    ecx, dword [esp + 0xC]
52
53      ; Set stack pointer to new value
54      ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp]
55      mov    eax, dword [esp + 0x14]
56      mov    edx, dword [esp + 0x10]
57      sub    eax, edx
58      sub    esp, eax
59      mov    ebx, esp
60      push   ecx
61      push   eax
62      push   edx
63      push   ebx
64      call   ASM_PFX(CopyMem)
65      pop    eax
66      pop    eax
67      pop    eax
68      pop    ecx
69
70      ; Now call the external routine
71      call  ecx
72
73      ; ebp is preserved by the callee. In this function it
74      ; equals the original esp, so set them equal
75      mov    esp, ebp
76
77      ; Standard function epilog
78      mov      esp, ebp
79      pop      ebx
80      pop      ebp
81      ret
82
83;****************************************************************************
84; EbcLLEbcInterpret
85;
86; Begin executing an EBC image.
87;****************************************************************************
88; UINT64 EbcLLEbcInterpret(VOID)
89global ASM_PFX(EbcLLEbcInterpret)
90ASM_PFX(EbcLLEbcInterpret):
91    ;
92    ;; mov eax, 0xca112ebc
93    ;; mov eax, EbcEntryPoint
94    ;; mov ecx, EbcLLEbcInterpret
95    ;; jmp ecx
96    ;
97    ; Caller uses above instruction to jump here
98    ; The stack is below:
99    ; +-----------+
100    ; |  RetAddr  |
101    ; +-----------+
102    ; |EntryPoint | (EAX)
103    ; +-----------+
104    ; |   Arg1    | <- EDI
105    ; +-----------+
106    ; |   Arg2    |
107    ; +-----------+
108    ; |   ...     |
109    ; +-----------+
110    ; |   Arg16   |
111    ; +-----------+
112    ; |   EDI     |
113    ; +-----------+
114    ; |   ESI     |
115    ; +-----------+
116    ; |   EBP     | <- EBP
117    ; +-----------+
118    ; |  RetAddr  | <- ESP is here
119    ; +-----------+
120    ; |   Arg1    | <- ESI
121    ; +-----------+
122    ; |   Arg2    |
123    ; +-----------+
124    ; |   ...     |
125    ; +-----------+
126    ; |   Arg16   |
127    ; +-----------+
128    ;
129
130    ; Construct new stack
131    push ebp
132    mov  ebp, esp
133    push esi
134    push edi
135    sub  esp, 0x40
136    push eax
137    mov  esi, ebp
138    add  esi, 8
139    mov  edi, esp
140    add  edi, 4
141    mov  ecx, 16
142    rep  movsd
143
144    ; call C-code
145    call ASM_PFX(EbcInterpret)
146    add  esp, 0x44
147    pop  edi
148    pop  esi
149    pop  ebp
150    ret
151
152;****************************************************************************
153; EbcLLExecuteEbcImageEntryPoint
154;
155; Begin executing an EBC image.
156;****************************************************************************
157; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
158global ASM_PFX(EbcLLExecuteEbcImageEntryPoint)
159ASM_PFX(EbcLLExecuteEbcImageEntryPoint):
160    ;
161    ;; mov eax, 0xca112ebc
162    ;; mov eax, EbcEntryPoint
163    ;; mov ecx, EbcLLExecuteEbcImageEntryPoint
164    ;; jmp ecx
165    ;
166    ; Caller uses above instruction to jump here
167    ; The stack is below:
168    ; +-----------+
169    ; |  RetAddr  |
170    ; +-----------+
171    ; |EntryPoint | (EAX)
172    ; +-----------+
173    ; |ImageHandle|
174    ; +-----------+
175    ; |SystemTable|
176    ; +-----------+
177    ; |  RetAddr  | <- ESP is here
178    ; +-----------+
179    ; |ImageHandle|
180    ; +-----------+
181    ; |SystemTable|
182    ; +-----------+
183    ;
184
185    ; Construct new stack
186    mov  [esp - 0xC], eax
187    mov  eax, [esp + 0x4]
188    mov  [esp - 0x8], eax
189    mov  eax, [esp + 0x8]
190    mov  [esp - 0x4], eax
191
192    ; call C-code
193    sub  esp, 0xC
194    call ASM_PFX(ExecuteEbcImageEntryPoint)
195    add  esp, 0xC
196    ret
197
198