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