• 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;  Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
8;  This program and the accompanying materials
9;  are licensed and made available under the terms and conditions of the BSD License
10;  which accompanies this distribution.  The full text of the license may be found at
11;  http://opensource.org/licenses/bsd-license.php
12;
13;  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14;  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15;
16;**/
17
18  page    ,132
19  title   VM ASSEMBLY LANGUAGE ROUTINES
20
21;---------------------------------------------------------------------------
22; Equate files needed.
23;---------------------------------------------------------------------------
24
25.CODE
26
27CopyMem  PROTO  Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
28EbcInterpret               PROTO
29ExecuteEbcImageEntryPoint  PROTO
30
31;****************************************************************************
32; EbcLLCALLEX
33;
34; This function is called to execute an EBC CALLEX instruction.
35; This instruction requires that we thunk out to external native
36; code. For x64, we switch stacks, copy the arguments to the stack
37; and jump to the specified function.
38; On return, we restore the stack pointer to its original location.
39;
40; Destroys no working registers.
41;****************************************************************************
42; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
43EbcLLCALLEXNative        PROC    PUBLIC
44      push   rbp
45      push   rbx
46      mov    rbp, rsp
47      ; Function prolog
48
49      ; Copy FuncAddr to a preserved register.
50      mov    rbx, rcx
51
52      ; Set stack pointer to new value
53      sub    r8,  rdx
54
55      ;
56      ; Fix X64 native function call prolog. Prepare space for at least 4 arguments,
57      ; even if the native function's arguments are less than 4.
58      ;
59      ; From MSDN x64 Software Conventions, Overview of x64 Calling Conventions:
60      ;   "The caller is responsible for allocating space for parameters to the
61      ;   callee, and must always allocate sufficient space for the 4 register
62      ;   parameters, even if the callee doesn't have that many parameters.
63      ;   This aids in the simplicity of supporting C unprototyped functions,
64      ;   and vararg C/C++ functions."
65      ;
66      cmp    r8, 20h
67      jae    skip_expansion
68      mov    r8, 20h
69skip_expansion:
70
71      sub    rsp, r8
72
73      ;
74      ; Fix X64 native function call 16-byte alignment.
75      ;
76      ; From MSDN x64 Software Conventions, Stack Usage:
77      ;   "The stack will always be maintained 16-byte aligned, except within
78      ;   the prolog (for example, after the return address is pushed)."
79      ;
80      and    rsp, NOT 0fh
81
82      mov    rcx, rsp
83      sub    rsp, 20h
84      call   CopyMem
85      add    rsp, 20h
86
87      ; Considering the worst case, load 4 potiential arguments
88      ; into registers.
89      mov    rcx, qword ptr [rsp]
90      mov    rdx, qword ptr [rsp+8h]
91      mov    r8,  qword ptr [rsp+10h]
92      mov    r9,  qword ptr [rsp+18h]
93
94      ; Now call the external routine
95      call  rbx
96
97      ; Function epilog
98      mov      rsp, rbp
99      pop      rbx
100      pop      rbp
101      ret
102EbcLLCALLEXNative    ENDP
103
104;****************************************************************************
105; EbcLLEbcInterpret
106;
107; Begin executing an EBC image.
108;****************************************************************************
109; UINT64 EbcLLEbcInterpret(VOID)
110EbcLLEbcInterpret PROC PUBLIC
111    ;
112    ;; mov rax, ca112ebccall2ebch
113    ;; mov r10, EbcEntryPoint
114    ;; mov r11, EbcLLEbcInterpret
115    ;; jmp r11
116    ;
117    ; Caller uses above instruction to jump here
118    ; The stack is below:
119    ; +-----------+
120    ; |  RetAddr  |
121    ; +-----------+
122    ; |EntryPoint | (R10)
123    ; +-----------+
124    ; |   Arg1    | <- RDI
125    ; +-----------+
126    ; |   Arg2    |
127    ; +-----------+
128    ; |   ...     |
129    ; +-----------+
130    ; |   Arg16   |
131    ; +-----------+
132    ; |   Dummy   |
133    ; +-----------+
134    ; |   RDI     |
135    ; +-----------+
136    ; |   RSI     |
137    ; +-----------+
138    ; |   RBP     | <- RBP
139    ; +-----------+
140    ; |  RetAddr  | <- RSP is here
141    ; +-----------+
142    ; |  Scratch1 | (RCX) <- RSI
143    ; +-----------+
144    ; |  Scratch2 | (RDX)
145    ; +-----------+
146    ; |  Scratch3 | (R8)
147    ; +-----------+
148    ; |  Scratch4 | (R9)
149    ; +-----------+
150    ; |   Arg5    |
151    ; +-----------+
152    ; |   Arg6    |
153    ; +-----------+
154    ; |   ...     |
155    ; +-----------+
156    ; |   Arg16   |
157    ; +-----------+
158    ;
159
160    ; save old parameter to stack
161    mov  [rsp + 08h], rcx
162    mov  [rsp + 10h], rdx
163    mov  [rsp + 18h], r8
164    mov  [rsp + 20h], r9
165
166    ; Construct new stack
167    push rbp
168    mov  rbp, rsp
169    push rsi
170    push rdi
171    push rbx
172    sub  rsp, 80h
173    push r10
174    mov  rsi, rbp
175    add  rsi, 10h
176    mov  rdi, rsp
177    add  rdi, 8
178    mov  rcx, 16
179    rep  movsq
180
181    ; build new paramater calling convention
182    mov  r9,  [rsp + 18h]
183    mov  r8,  [rsp + 10h]
184    mov  rdx, [rsp + 08h]
185    mov  rcx, r10
186
187    ; call C-code
188    call EbcInterpret
189    add  rsp, 88h
190    pop  rbx
191    pop  rdi
192    pop  rsi
193    pop  rbp
194    ret
195EbcLLEbcInterpret ENDP
196
197;****************************************************************************
198; EbcLLExecuteEbcImageEntryPoint
199;
200; Begin executing an EBC image.
201;****************************************************************************
202; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
203EbcLLExecuteEbcImageEntryPoint PROC PUBLIC
204    ;
205    ;; mov rax, ca112ebccall2ebch
206    ;; mov r10, EbcEntryPoint
207    ;; mov r11, EbcLLExecuteEbcImageEntryPoint
208    ;; jmp r11
209    ;
210    ; Caller uses above instruction to jump here
211    ; The stack is below:
212    ; +-----------+
213    ; |  RetAddr  |
214    ; +-----------+
215    ; |EntryPoint | (R10)
216    ; +-----------+
217    ; |ImageHandle|
218    ; +-----------+
219    ; |SystemTable|
220    ; +-----------+
221    ; |   Dummy   |
222    ; +-----------+
223    ; |   Dummy   |
224    ; +-----------+
225    ; |  RetAddr  | <- RSP is here
226    ; +-----------+
227    ; |ImageHandle| (RCX)
228    ; +-----------+
229    ; |SystemTable| (RDX)
230    ; +-----------+
231    ;
232
233    ; build new paramater calling convention
234    mov  r8, rdx
235    mov  rdx, rcx
236    mov  rcx, r10
237
238    ; call C-code
239    sub  rsp, 28h
240    call ExecuteEbcImageEntryPoint
241    add  rsp, 28h
242    ret
243EbcLLExecuteEbcImageEntryPoint ENDP
244
245END
246
247