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