CpuAsm.asm revision 01a1c0fc9e60dfd6b26bd6d9aa9c3a6242bbb608
1 TITLE CpuAsm.asm: 2;------------------------------------------------------------------------------ 3;* 4;* Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> 5;* This program and the accompanying materials 6;* are licensed and made available under the terms and conditions of the BSD License 7;* which accompanies this distribution. The full text of the license may be found at 8;* http://opensource.org/licenses/bsd-license.php 9;* 10;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12;* 13;* CpuAsm.asm 14;* 15;* Abstract: 16;* 17;------------------------------------------------------------------------------ 18 19 .686 20 .model flat,C 21 .code 22 23EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions 24 25; 26; point to the external interrupt vector table 27; 28ExternalVectorTablePtr DWORD 0 29 30InitializeExternalVectorTablePtr PROC PUBLIC 31 mov eax, [esp+4] 32 mov ExternalVectorTablePtr, eax 33 ret 34InitializeExternalVectorTablePtr ENDP 35 36;------------------------------------------------------------------------------ 37; VOID 38; SetCodeSelector ( 39; UINT16 Selector 40; ); 41;------------------------------------------------------------------------------ 42SetCodeSelector PROC PUBLIC 43 mov ecx, [esp+4] 44 sub esp, 0x10 45 lea eax, setCodeSelectorLongJump 46 mov [esp], eax 47 mov [esp+4], cx 48 jmp fword ptr [esp] 49setCodeSelectorLongJump: 50 add esp, 0x10 51 ret 52SetCodeSelector ENDP 53 54;------------------------------------------------------------------------------ 55; VOID 56; SetDataSelectors ( 57; UINT16 Selector 58; ); 59;------------------------------------------------------------------------------ 60SetDataSelectors PROC PUBLIC 61 mov ecx, [esp+4] 62 mov ss, cx 63 mov ds, cx 64 mov es, cx 65 mov fs, cx 66 mov gs, cx 67 ret 68SetDataSelectors ENDP 69 70;---------------------------------------; 71; CommonInterruptEntry ; 72;---------------------------------------; 73; The follow algorithm is used for the common interrupt routine. 74 75CommonInterruptEntry PROC PUBLIC 76 cli 77 ; 78 ; All interrupt handlers are invoked through interrupt gates, so 79 ; IF flag automatically cleared at the entry point 80 ; 81 82 ; 83 ; Calculate vector number 84 ; 85 ; Get the return address of call, actually, it is the 86 ; address of vector number. 87 ; 88 xchg ecx, [esp] 89 mov cx, [ecx] 90 and ecx, 0FFFFh 91 cmp ecx, 32 ; Intel reserved vector for exceptions? 92 jae NoErrorCode 93 bt mErrorCodeFlag, ecx 94 jc HasErrorCode 95 96NoErrorCode: 97 98 ; 99 ; Stack: 100 ; +---------------------+ 101 ; + EFlags + 102 ; +---------------------+ 103 ; + CS + 104 ; +---------------------+ 105 ; + EIP + 106 ; +---------------------+ 107 ; + ECX + 108 ; +---------------------+ <-- ESP 109 ; 110 ; Registers: 111 ; ECX - Vector Number 112 ; 113 114 ; 115 ; Put Vector Number on stack 116 ; 117 push ecx 118 119 ; 120 ; Put 0 (dummy) error code on stack, and restore ECX 121 ; 122 xor ecx, ecx ; ECX = 0 123 xchg ecx, [esp+4] 124 125 jmp ErrorCodeAndVectorOnStack 126 127HasErrorCode: 128 129 ; 130 ; Stack: 131 ; +---------------------+ 132 ; + EFlags + 133 ; +---------------------+ 134 ; + CS + 135 ; +---------------------+ 136 ; + EIP + 137 ; +---------------------+ 138 ; + Error Code + 139 ; +---------------------+ 140 ; + ECX + 141 ; +---------------------+ <-- ESP 142 ; 143 ; Registers: 144 ; ECX - Vector Number 145 ; 146 147 ; 148 ; Put Vector Number on stack and restore ECX 149 ; 150 xchg ecx, [esp] 151 152 ; 153 ; Fall through to join main routine code 154 ; at ErrorCodeAndVectorOnStack 155 ; 156@@: 157 jmp @B 158 159ErrorCodeAndVectorOnStack: 160 push ebp 161 mov ebp, esp 162 163 ; 164 ; Stack: 165 ; +---------------------+ 166 ; + EFlags + 167 ; +---------------------+ 168 ; + CS + 169 ; +---------------------+ 170 ; + EIP + 171 ; +---------------------+ 172 ; + Error Code + 173 ; +---------------------+ 174 ; + Vector Number + 175 ; +---------------------+ 176 ; + EBP + 177 ; +---------------------+ <-- EBP 178 ; 179 180 ; 181 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 182 ; is 16-byte aligned 183 ; 184 and esp, 0fffffff0h 185 sub esp, 12 186 187;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; 188 push eax 189 push ecx 190 push edx 191 push ebx 192 lea ecx, [ebp + 6 * 4] 193 push ecx ; ESP 194 push dword ptr [ebp] ; EBP 195 push esi 196 push edi 197 198;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; 199 mov eax, ss 200 push eax 201 movzx eax, word ptr [ebp + 4 * 4] 202 push eax 203 mov eax, ds 204 push eax 205 mov eax, es 206 push eax 207 mov eax, fs 208 push eax 209 mov eax, gs 210 push eax 211 212;; UINT32 Eip; 213 mov eax, [ebp + 3 * 4] 214 push eax 215 216;; UINT32 Gdtr[2], Idtr[2]; 217 sub esp, 8 218 sidt [esp] 219 mov eax, [esp + 2] 220 xchg eax, [esp] 221 and eax, 0FFFFh 222 mov [esp+4], eax 223 224 sub esp, 8 225 sgdt [esp] 226 mov eax, [esp + 2] 227 xchg eax, [esp] 228 and eax, 0FFFFh 229 mov [esp+4], eax 230 231;; UINT32 Ldtr, Tr; 232 xor eax, eax 233 str ax 234 push eax 235 sldt ax 236 push eax 237 238;; UINT32 EFlags; 239 mov eax, [ebp + 5 * 4] 240 push eax 241 242;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; 243 mov eax, cr4 244 or eax, 208h 245 mov cr4, eax 246 push eax 247 mov eax, cr3 248 push eax 249 mov eax, cr2 250 push eax 251 xor eax, eax 252 push eax 253 mov eax, cr0 254 push eax 255 256;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 257 mov eax, dr7 258 push eax 259;; clear Dr7 while executing debugger itself 260 xor eax, eax 261 mov dr7, eax 262 263 mov eax, dr6 264 push eax 265;; insure all status bits in dr6 are clear... 266 xor eax, eax 267 mov dr6, eax 268 269 mov eax, dr3 270 push eax 271 mov eax, dr2 272 push eax 273 mov eax, dr1 274 push eax 275 mov eax, dr0 276 push eax 277 278;; FX_SAVE_STATE_IA32 FxSaveState; 279 sub esp, 512 280 mov edi, esp 281 db 0fh, 0aeh, 07h ;fxsave [edi] 282 283;; UINT32 ExceptionData; 284 push dword ptr [ebp + 2 * 4] 285 286;; call into exception handler 287 mov eax, ExternalVectorTablePtr ; get the interrupt vectors base 288 or eax, eax ; NULL? 289 jz nullExternalExceptionHandler 290 291 mov ecx, [ebp + 4] 292 mov eax, [eax + ecx * 4] 293 or eax, eax ; NULL? 294 jz nullExternalExceptionHandler 295 296;; Prepare parameter and call 297 mov edx, esp 298 push edx 299 mov edx, dword ptr [ebp + 1 * 4] 300 push edx 301 302 ; 303 ; Call External Exception Handler 304 ; 305 call eax 306 add esp, 8 307 308nullExternalExceptionHandler: 309 310 cli 311;; UINT32 ExceptionData; 312 add esp, 4 313 314;; FX_SAVE_STATE_IA32 FxSaveState; 315 mov esi, esp 316 db 0fh, 0aeh, 0eh ; fxrstor [esi] 317 add esp, 512 318 319;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 320 pop eax 321 mov dr0, eax 322 pop eax 323 mov dr1, eax 324 pop eax 325 mov dr2, eax 326 pop eax 327 mov dr3, eax 328;; skip restore of dr6. We cleared dr6 during the context save. 329 add esp, 4 330 pop eax 331 mov dr7, eax 332 333;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; 334 pop eax 335 mov cr0, eax 336 add esp, 4 ; not for Cr1 337 pop eax 338 mov cr2, eax 339 pop eax 340 mov cr3, eax 341 pop eax 342 mov cr4, eax 343 344;; UINT32 EFlags; 345 pop dword ptr [ebp + 5 * 4] 346 347;; UINT32 Ldtr, Tr; 348;; UINT32 Gdtr[2], Idtr[2]; 349;; Best not let anyone mess with these particular registers... 350 add esp, 24 351 352;; UINT32 Eip; 353 pop dword ptr [ebp + 3 * 4] 354 355;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; 356;; NOTE - modified segment registers could hang the debugger... We 357;; could attempt to insulate ourselves against this possibility, 358;; but that poses risks as well. 359;; 360 pop gs 361 pop fs 362 pop es 363 pop ds 364 pop dword ptr [ebp + 4 * 4] 365 pop ss 366 367;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; 368 pop edi 369 pop esi 370 add esp, 4 ; not for ebp 371 add esp, 4 ; not for esp 372 pop ebx 373 pop edx 374 pop ecx 375 pop eax 376 377 mov esp, ebp 378 pop ebp 379 add esp, 8 380 iretd 381 382CommonInterruptEntry ENDP 383 384END 385