]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/EbcDxe/Ia32/EbcLowLevel.nasm
IntelSiliconPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / Ia32 / EbcLowLevel.nasm
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
25 SECTION .text
26 extern ASM_PFX(CopyMem)
27 extern ASM_PFX(EbcInterpret)
28 extern 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)
43 global ASM_PFX(EbcLLCALLEXNative)
44 ASM_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)
89 global ASM_PFX(EbcLLEbcInterpret)
90 ASM_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)
158 global ASM_PFX(EbcLLExecuteEbcImageEntryPoint)
159 ASM_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