• 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  page    ,132
18  title   VM ASSEMBLY LANGUAGE ROUTINES
19
20;---------------------------------------------------------------------------
21; Equate files needed.
22;---------------------------------------------------------------------------
23
24.XLIST
25
26.LIST
27
28;---------------------------------------------------------------------------
29; Assembler options
30;---------------------------------------------------------------------------
31
32.686p
33.model  flat, C
34.code
35CopyMem  PROTO  Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
36EbcInterpret               PROTO
37ExecuteEbcImageEntryPoint  PROTO
38
39;****************************************************************************
40; EbcLLCALLEXNative
41;
42; This function is called to execute an EBC CALLEX instruction
43; to native code.
44; This instruction requires that we thunk out to external native
45; code. For IA32, we simply switch stacks and jump to the
46; specified function. On return, we restore the stack pointer
47; to its original location.
48;
49; Destroys no working registers.
50;****************************************************************************
51; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
52EbcLLCALLEXNative        PROC        PUBLIC
53      push   ebp
54      push   ebx
55      mov    ebp, esp              ; standard function prolog
56
57      ; Get function address in a register
58      ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr]
59      mov    ecx, dword ptr [esp + 0Ch]
60
61      ; Set stack pointer to new value
62      ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp]
63      mov    eax, dword ptr [esp + 14h]
64      mov    edx, dword ptr [esp + 10h]
65      sub    eax, edx
66      sub    esp, eax
67      mov    ebx, esp
68      push   ecx
69      push   eax
70      push   edx
71      push   ebx
72      call   CopyMem
73      pop    eax
74      pop    eax
75      pop    eax
76      pop    ecx
77
78      ; Now call the external routine
79      call  ecx
80
81      ; ebp is preserved by the callee. In this function it
82      ; equals the original esp, so set them equal
83      mov    esp, ebp
84
85      ; Standard function epilog
86      mov      esp, ebp
87      pop      ebx
88      pop      ebp
89      ret
90EbcLLCALLEXNative    ENDP
91
92;****************************************************************************
93; EbcLLEbcInterpret
94;
95; Begin executing an EBC image.
96;****************************************************************************
97; UINT64 EbcLLEbcInterpret(VOID)
98EbcLLEbcInterpret PROC PUBLIC
99    ;
100    ;; mov eax, 0xca112ebc
101    ;; mov eax, EbcEntryPoint
102    ;; mov ecx, EbcLLEbcInterpret
103    ;; jmp ecx
104    ;
105    ; Caller uses above instruction to jump here
106    ; The stack is below:
107    ; +-----------+
108    ; |  RetAddr  |
109    ; +-----------+
110    ; |EntryPoint | (EAX)
111    ; +-----------+
112    ; |   Arg1    | <- EDI
113    ; +-----------+
114    ; |   Arg2    |
115    ; +-----------+
116    ; |   ...     |
117    ; +-----------+
118    ; |   Arg16   |
119    ; +-----------+
120    ; |   EDI     |
121    ; +-----------+
122    ; |   ESI     |
123    ; +-----------+
124    ; |   EBP     | <- EBP
125    ; +-----------+
126    ; |  RetAddr  | <- ESP is here
127    ; +-----------+
128    ; |   Arg1    | <- ESI
129    ; +-----------+
130    ; |   Arg2    |
131    ; +-----------+
132    ; |   ...     |
133    ; +-----------+
134    ; |   Arg16   |
135    ; +-----------+
136    ;
137
138    ; Construct new stack
139    push ebp
140    mov  ebp, esp
141    push esi
142    push edi
143    sub  esp, 40h
144    push eax
145    mov  esi, ebp
146    add  esi, 8
147    mov  edi, esp
148    add  edi, 4
149    mov  ecx, 16
150    rep  movsd
151
152    ; call C-code
153    call EbcInterpret
154    add  esp, 44h
155    pop  edi
156    pop  esi
157    pop  ebp
158    ret
159EbcLLEbcInterpret ENDP
160
161;****************************************************************************
162; EbcLLExecuteEbcImageEntryPoint
163;
164; Begin executing an EBC image.
165;****************************************************************************
166; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
167EbcLLExecuteEbcImageEntryPoint PROC PUBLIC
168    ;
169    ;; mov eax, 0xca112ebc
170    ;; mov eax, EbcEntryPoint
171    ;; mov ecx, EbcLLExecuteEbcImageEntryPoint
172    ;; jmp ecx
173    ;
174    ; Caller uses above instruction to jump here
175    ; The stack is below:
176    ; +-----------+
177    ; |  RetAddr  |
178    ; +-----------+
179    ; |EntryPoint | (EAX)
180    ; +-----------+
181    ; |ImageHandle|
182    ; +-----------+
183    ; |SystemTable|
184    ; +-----------+
185    ; |  RetAddr  | <- ESP is here
186    ; +-----------+
187    ; |ImageHandle|
188    ; +-----------+
189    ; |SystemTable|
190    ; +-----------+
191    ;
192
193    ; Construct new stack
194    mov  [esp - 0Ch], eax
195    mov  eax, [esp + 04h]
196    mov  [esp - 08h], eax
197    mov  eax, [esp + 08h]
198    mov  [esp - 04h], eax
199
200    ; call C-code
201    sub  esp, 0Ch
202    call ExecuteEbcImageEntryPoint
203    add  esp, 0Ch
204    ret
205EbcLLExecuteEbcImageEntryPoint ENDP
206
207END
208