]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/CpuDxe/Cpu.c
Add thunk code for CpuDxe driver.
[mirror_edk2.git] / DuetPkg / CpuDxe / Cpu.c
CommitLineData
c69dd9df 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 Cpu.c\r
14\r
15Abstract:\r
16\r
17--*/\r
18\r
19#include "CpuDxe.h"\r
20\r
21//\r
22// Global Variables\r
23//\r
24\r
25BOOLEAN mInterruptState = FALSE;\r
26extern UINT32 mExceptionCodeSize;\r
27UINTN mTimerVector = 0;\r
28volatile EFI_CPU_INTERRUPT_HANDLER mTimerHandler = NULL;\r
29EFI_LEGACY_8259_PROTOCOL *gLegacy8259 = NULL;\r
23833b2c 30THUNK_CONTEXT mThunkContext;\r
31#define EFI_CPU_EFLAGS_IF 0x200\r
c69dd9df 32\r
23833b2c 33VOID\r
34InitializeBiosIntCaller (\r
35 VOID\r
36 );\r
37 \r
38BOOLEAN\r
39EFIAPI\r
40LegacyBiosInt86 (\r
41 IN UINT8 BiosInt,\r
42 IN EFI_IA32_REGISTER_SET *Regs\r
43 );\r
44 \r
c69dd9df 45//\r
46// The Cpu Architectural Protocol that this Driver produces\r
47//\r
48EFI_HANDLE mHandle = NULL;\r
49EFI_CPU_ARCH_PROTOCOL mCpu = {\r
50 CpuFlushCpuDataCache,\r
51 CpuEnableInterrupt,\r
52 CpuDisableInterrupt,\r
53 CpuGetInterruptState,\r
54 CpuInit,\r
55 CpuRegisterInterruptHandler,\r
56 CpuGetTimerValue,\r
57 CpuSetMemoryAttributes,\r
58 1, // NumberOfTimers\r
59 4, // DmaBufferAlignment\r
60};\r
61\r
62EFI_STATUS\r
63EFIAPI\r
64CpuFlushCpuDataCache (\r
65 IN EFI_CPU_ARCH_PROTOCOL *This,\r
66 IN EFI_PHYSICAL_ADDRESS Start,\r
67 IN UINT64 Length,\r
68 IN EFI_CPU_FLUSH_TYPE FlushType\r
69 )\r
70/*++\r
71\r
72Routine Description:\r
73 Flush CPU data cache. If the instruction cache is fully coherent\r
74 with all DMA operations then function can just return EFI_SUCCESS.\r
75\r
76Arguments:\r
77 This - Protocol instance structure\r
78 Start - Physical address to start flushing from.\r
79 Length - Number of bytes to flush. Round up to chipset \r
80 granularity.\r
81 FlushType - Specifies the type of flush operation to perform.\r
82\r
83Returns: \r
84\r
85 EFI_SUCCESS - If cache was flushed\r
86 EFI_UNSUPPORTED - If flush type is not supported.\r
87 EFI_DEVICE_ERROR - If requested range could not be flushed.\r
88\r
89--*/\r
90{\r
91 if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {\r
92 AsmWbinvd ();\r
93 return EFI_SUCCESS;\r
94 } else if (FlushType == EfiCpuFlushTypeInvalidate) {\r
95 AsmInvd ();\r
96 return EFI_SUCCESS;\r
97 } else {\r
98 return EFI_UNSUPPORTED;\r
99 }\r
100}\r
101\r
102\r
103EFI_STATUS\r
104EFIAPI\r
105CpuEnableInterrupt (\r
106 IN EFI_CPU_ARCH_PROTOCOL *This\r
107 )\r
108/*++\r
109\r
110Routine Description:\r
111 Enables CPU interrupts.\r
112\r
113Arguments:\r
114 This - Protocol instance structure\r
115\r
116Returns: \r
117 EFI_SUCCESS - If interrupts were enabled in the CPU\r
118 EFI_DEVICE_ERROR - If interrupts could not be enabled on the CPU.\r
119\r
120--*/\r
121{\r
122 EnableInterrupts (); \r
123\r
124 mInterruptState = TRUE;\r
125 return EFI_SUCCESS;\r
126}\r
127\r
128\r
129EFI_STATUS\r
130EFIAPI\r
131CpuDisableInterrupt (\r
132 IN EFI_CPU_ARCH_PROTOCOL *This\r
133 )\r
134/*++\r
135\r
136Routine Description:\r
137 Disables CPU interrupts.\r
138\r
139Arguments:\r
140 This - Protocol instance structure\r
141\r
142Returns: \r
143 EFI_SUCCESS - If interrupts were disabled in the CPU.\r
144 EFI_DEVICE_ERROR - If interrupts could not be disabled on the CPU.\r
145\r
146--*/\r
147{\r
148 DisableInterrupts ();\r
149 \r
150 mInterruptState = FALSE;\r
151 return EFI_SUCCESS;\r
152}\r
153\r
154\r
155EFI_STATUS\r
156EFIAPI\r
157CpuGetInterruptState (\r
158 IN EFI_CPU_ARCH_PROTOCOL *This,\r
159 OUT BOOLEAN *State\r
160 )\r
161/*++\r
162\r
163Routine Description:\r
164 Return the state of interrupts.\r
165\r
166Arguments:\r
167 This - Protocol instance structure\r
168 State - Pointer to the CPU's current interrupt state\r
169\r
170Returns: \r
171 EFI_SUCCESS - If interrupts were disabled in the CPU.\r
172 EFI_INVALID_PARAMETER - State is NULL.\r
173 \r
174--*/\r
175{\r
176 if (State == NULL) {\r
177 return EFI_INVALID_PARAMETER;\r
178 }\r
179\r
180 *State = mInterruptState;\r
181 return EFI_SUCCESS;\r
182}\r
183\r
184\r
185EFI_STATUS\r
186EFIAPI\r
187CpuInit (\r
188 IN EFI_CPU_ARCH_PROTOCOL *This,\r
189 IN EFI_CPU_INIT_TYPE InitType\r
190 )\r
191\r
192/*++\r
193\r
194Routine Description:\r
195 Generates an INIT to the CPU\r
196\r
197Arguments:\r
198 This - Protocol instance structure\r
199 InitType - Type of CPU INIT to perform\r
200\r
201Returns: \r
202 EFI_SUCCESS - If CPU INIT occurred. This value should never be\r
203 seen.\r
204 EFI_DEVICE_ERROR - If CPU INIT failed.\r
205 EFI_NOT_SUPPORTED - Requested type of CPU INIT not supported.\r
206\r
207--*/\r
208{\r
209 return EFI_UNSUPPORTED;\r
210}\r
211\r
212\r
213EFI_STATUS\r
214EFIAPI\r
215CpuRegisterInterruptHandler (\r
216 IN EFI_CPU_ARCH_PROTOCOL *This,\r
217 IN EFI_EXCEPTION_TYPE InterruptType,\r
218 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler\r
219 )\r
220/*++\r
221\r
222Routine Description:\r
223 Registers a function to be called from the CPU interrupt handler.\r
224\r
225Arguments:\r
226 This - Protocol instance structure\r
227 InterruptType - Defines which interrupt to hook. IA-32 valid range\r
228 is 0x00 through 0xFF\r
229 InterruptHandler - A pointer to a function of type \r
230 EFI_CPU_INTERRUPT_HANDLER that is called when a\r
231 processor interrupt occurs. A null pointer\r
232 is an error condition.\r
233\r
234Returns: \r
235 EFI_SUCCESS - If handler installed or uninstalled.\r
236 EFI_ALREADY_STARTED - InterruptHandler is not NULL, and a handler for \r
237 InterruptType was previously installed\r
238 EFI_INVALID_PARAMETER - InterruptHandler is NULL, and a handler for \r
239 InterruptType was not previously installed.\r
240 EFI_UNSUPPORTED - The interrupt specified by InterruptType is not\r
241 supported.\r
242\r
243--*/\r
244{\r
245 if ((InterruptType < 0) || (InterruptType >= INTERRUPT_VECTOR_NUMBER)) {\r
246 return EFI_UNSUPPORTED;\r
247 }\r
248 if ((UINTN)(UINT32)InterruptType != mTimerVector) {\r
249 return EFI_UNSUPPORTED;\r
250 }\r
251 if ((mTimerHandler == NULL) && (InterruptHandler == NULL)) {\r
252 return EFI_INVALID_PARAMETER;\r
253 } else if ((mTimerHandler != NULL) && (InterruptHandler != NULL)) {\r
254 return EFI_ALREADY_STARTED;\r
255 }\r
256 mTimerHandler = InterruptHandler;\r
257 return EFI_SUCCESS;\r
258}\r
259\r
260EFI_STATUS\r
261EFIAPI\r
262CpuGetTimerValue (\r
263 IN EFI_CPU_ARCH_PROTOCOL *This,\r
264 IN UINT32 TimerIndex,\r
265 OUT UINT64 *TimerValue,\r
266 OUT UINT64 *TimerPeriod OPTIONAL\r
267 )\r
268/*++\r
269\r
270Routine Description:\r
271 Returns a timer value from one of the CPU's internal timers. There is no\r
272 inherent time interval between ticks but is a function of the CPU \r
273 frequency.\r
274\r
275Arguments:\r
276 This - Protocol instance structure\r
277 TimerIndex - Specifies which CPU timer ie requested\r
278 TimerValue - Pointer to the returned timer value\r
279 TimerPeriod - \r
280\r
281Returns: \r
282 EFI_SUCCESS - If the CPU timer count was returned.\r
283 EFI_UNSUPPORTED - If the CPU does not have any readable timers\r
284 EFI_DEVICE_ERROR - If an error occurred reading the timer.\r
285 EFI_INVALID_PARAMETER - TimerIndex is not valid\r
286\r
287--*/\r
288{ \r
289 if (TimerValue == NULL) {\r
290 return EFI_INVALID_PARAMETER;\r
291 }\r
292 \r
293 if (TimerIndex == 0) {\r
294 *TimerValue = AsmReadTsc ();\r
295 if (TimerPeriod != NULL) {\r
296 //\r
297 // BugBug: Hard coded. Don't know how to do this generically\r
298 //\r
299 *TimerPeriod = 1000000000;\r
300 }\r
301 return EFI_SUCCESS;\r
302 }\r
303 return EFI_INVALID_PARAMETER;\r
304}\r
305\r
306EFI_STATUS\r
307EFIAPI\r
308CpuSetMemoryAttributes (\r
309 IN EFI_CPU_ARCH_PROTOCOL *This,\r
310 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
311 IN UINT64 Length,\r
312 IN UINT64 Attributes\r
313 )\r
314/*++\r
315\r
316Routine Description:\r
317 Set memory cacheability attributes for given range of memeory\r
318\r
319Arguments:\r
320 This - Protocol instance structure\r
321 BaseAddress - Specifies the start address of the memory range\r
322 Length - Specifies the length of the memory range\r
323 Attributes - The memory cacheability for the memory range\r
324\r
325Returns: \r
326 EFI_SUCCESS - If the cacheability of that memory range is set successfully\r
327 EFI_UNSUPPORTED - If the desired operation cannot be done\r
328 EFI_INVALID_PARAMETER - The input parameter is not correct, such as Length = 0\r
329\r
330--*/\r
331{\r
332 return EFI_UNSUPPORTED;\r
333}\r
334\r
335#if CPU_EXCEPTION_DEBUG_OUTPUT\r
c69dd9df 336VOID\r
337DumpExceptionDataDebugOut (\r
338 IN EFI_EXCEPTION_TYPE InterruptType,\r
339 IN EFI_SYSTEM_CONTEXT SystemContext\r
340 )\r
341{\r
342 UINT32 ErrorCodeFlag;\r
343\r
344 ErrorCodeFlag = 0x00027d00;\r
345\r
346#ifdef EFI32\r
347 DEBUG ((\r
348 EFI_D_ERROR,\r
349 "!!!! IA32 Exception Type - %08x !!!!\n",\r
350 InterruptType\r
351 ));\r
352 DEBUG ((\r
353 EFI_D_ERROR,\r
354 "EIP - %08x, CS - %08x, EFLAGS - %08x\n",\r
355 SystemContext.SystemContextIa32->Eip,\r
356 SystemContext.SystemContextIa32->Cs,\r
357 SystemContext.SystemContextIa32->Eflags\r
358 ));\r
359 if (ErrorCodeFlag & (1 << InterruptType)) {\r
360 DEBUG ((\r
361 EFI_D_ERROR,\r
362 "ExceptionData - %08x\n",\r
363 SystemContext.SystemContextIa32->ExceptionData\r
364 ));\r
365 }\r
366 DEBUG ((\r
367 EFI_D_ERROR,\r
368 "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",\r
369 SystemContext.SystemContextIa32->Eax,\r
370 SystemContext.SystemContextIa32->Ecx,\r
371 SystemContext.SystemContextIa32->Edx,\r
372 SystemContext.SystemContextIa32->Ebx\r
373 ));\r
374 DEBUG ((\r
375 EFI_D_ERROR,\r
376 "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",\r
377 SystemContext.SystemContextIa32->Esp,\r
378 SystemContext.SystemContextIa32->Ebp,\r
379 SystemContext.SystemContextIa32->Esi,\r
380 SystemContext.SystemContextIa32->Edi\r
381 ));\r
382 DEBUG ((\r
383 EFI_D_ERROR,\r
384 "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x\n",\r
385 SystemContext.SystemContextIa32->Ds,\r
386 SystemContext.SystemContextIa32->Es,\r
387 SystemContext.SystemContextIa32->Fs,\r
388 SystemContext.SystemContextIa32->Gs,\r
389 SystemContext.SystemContextIa32->Ss\r
390 ));\r
391 DEBUG ((\r
392 EFI_D_ERROR,\r
393 "GDTR - %08x %08x, IDTR - %08x %08x\n",\r
394 SystemContext.SystemContextIa32->Gdtr[0],\r
395 SystemContext.SystemContextIa32->Gdtr[1],\r
396 SystemContext.SystemContextIa32->Idtr[0],\r
397 SystemContext.SystemContextIa32->Idtr[1]\r
398 ));\r
399 DEBUG ((\r
400 EFI_D_ERROR,\r
401 "LDTR - %08x, TR - %08x\n",\r
402 SystemContext.SystemContextIa32->Ldtr,\r
403 SystemContext.SystemContextIa32->Tr\r
404 ));\r
405 DEBUG ((\r
406 EFI_D_ERROR,\r
407 "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",\r
408 SystemContext.SystemContextIa32->Cr0,\r
409 SystemContext.SystemContextIa32->Cr2,\r
410 SystemContext.SystemContextIa32->Cr3,\r
411 SystemContext.SystemContextIa32->Cr4\r
412 ));\r
413 DEBUG ((\r
414 EFI_D_ERROR,\r
415 "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",\r
416 SystemContext.SystemContextIa32->Dr0,\r
417 SystemContext.SystemContextIa32->Dr1,\r
418 SystemContext.SystemContextIa32->Dr2,\r
419 SystemContext.SystemContextIa32->Dr3\r
420 ));\r
421 DEBUG ((\r
422 EFI_D_ERROR,\r
423 "DR6 - %08x, DR7 - %08x\n",\r
424 SystemContext.SystemContextIa32->Dr6,\r
425 SystemContext.SystemContextIa32->Dr7\r
426 ));\r
427#else\r
428 DEBUG ((\r
429 EFI_D_ERROR,\r
430 "!!!! X64 Exception Type - %016lx !!!!\n",\r
431 (UINT64)InterruptType\r
432 ));\r
433 DEBUG ((\r
434 EFI_D_ERROR,\r
435 "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",\r
436 SystemContext.SystemContextX64->Rip,\r
437 SystemContext.SystemContextX64->Cs,\r
438 SystemContext.SystemContextX64->Rflags\r
439 ));\r
440 if (ErrorCodeFlag & (1 << InterruptType)) {\r
441 DEBUG ((\r
442 EFI_D_ERROR,\r
443 "ExceptionData - %016lx\n",\r
444 SystemContext.SystemContextX64->ExceptionData\r
445 ));\r
446 }\r
447 DEBUG ((\r
448 EFI_D_ERROR,\r
449 "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",\r
450 SystemContext.SystemContextX64->Rax,\r
451 SystemContext.SystemContextX64->Rcx,\r
452 SystemContext.SystemContextX64->Rdx\r
453 ));\r
454 DEBUG ((\r
455 EFI_D_ERROR,\r
456 "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",\r
457 SystemContext.SystemContextX64->Rbx,\r
458 SystemContext.SystemContextX64->Rsp,\r
459 SystemContext.SystemContextX64->Rbp\r
460 ));\r
461 DEBUG ((\r
462 EFI_D_ERROR,\r
463 "RSI - %016lx, RDI - %016lx\n",\r
464 SystemContext.SystemContextX64->Rsi,\r
465 SystemContext.SystemContextX64->Rdi\r
466 ));\r
467 DEBUG ((\r
468 EFI_D_ERROR,\r
469 "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",\r
470 SystemContext.SystemContextX64->R8,\r
471 SystemContext.SystemContextX64->R9,\r
472 SystemContext.SystemContextX64->R10\r
473 ));\r
474 DEBUG ((\r
475 EFI_D_ERROR,\r
476 "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",\r
477 SystemContext.SystemContextX64->R11,\r
478 SystemContext.SystemContextX64->R12,\r
479 SystemContext.SystemContextX64->R13\r
480 ));\r
481 DEBUG ((\r
482 EFI_D_ERROR,\r
483 "R14 - %016lx, R15 - %016lx\n",\r
484 SystemContext.SystemContextX64->R14,\r
485 SystemContext.SystemContextX64->R15\r
486 ));\r
487 DEBUG ((\r
488 EFI_D_ERROR,\r
489 "DS - %016lx, ES - %016lx, FS - %016lx\n",\r
490 SystemContext.SystemContextX64->Ds,\r
491 SystemContext.SystemContextX64->Es,\r
492 SystemContext.SystemContextX64->Fs\r
493 ));\r
494 DEBUG ((\r
495 EFI_D_ERROR,\r
496 "GS - %016lx, SS - %016lx\n",\r
497 SystemContext.SystemContextX64->Gs,\r
498 SystemContext.SystemContextX64->Ss\r
499 ));\r
500 DEBUG ((\r
501 EFI_D_ERROR,\r
502 "GDTR - %016lx %016lx, LDTR - %016lx\n",\r
503 SystemContext.SystemContextX64->Gdtr[0],\r
504 SystemContext.SystemContextX64->Gdtr[1],\r
505 SystemContext.SystemContextX64->Ldtr\r
506 ));\r
507 DEBUG ((\r
508 EFI_D_ERROR,\r
509 "IDTR - %016lx %016lx, TR - %016lx\n",\r
510 SystemContext.SystemContextX64->Idtr[0],\r
511 SystemContext.SystemContextX64->Idtr[1],\r
512 SystemContext.SystemContextX64->Tr\r
513 ));\r
514 DEBUG ((\r
515 EFI_D_ERROR,\r
516 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",\r
517 SystemContext.SystemContextX64->Cr0,\r
518 SystemContext.SystemContextX64->Cr2,\r
519 SystemContext.SystemContextX64->Cr3\r
520 ));\r
521 DEBUG ((\r
522 EFI_D_ERROR,\r
523 "CR4 - %016lx, CR8 - %016lx\n",\r
524 SystemContext.SystemContextX64->Cr4,\r
525 SystemContext.SystemContextX64->Cr8\r
526 ));\r
527 DEBUG ((\r
528 EFI_D_ERROR,\r
529 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",\r
530 SystemContext.SystemContextX64->Dr0,\r
531 SystemContext.SystemContextX64->Dr1,\r
532 SystemContext.SystemContextX64->Dr2\r
533 ));\r
534 DEBUG ((\r
535 EFI_D_ERROR,\r
536 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",\r
537 SystemContext.SystemContextX64->Dr3,\r
538 SystemContext.SystemContextX64->Dr6,\r
539 SystemContext.SystemContextX64->Dr7\r
540 ));\r
541#endif\r
542 return ;\r
543}\r
544#endif\r
545\r
c69dd9df 546UINTN\r
547SPrint (\r
548 IN OUT CHAR16 *Buffer,\r
549 IN CONST CHAR16 *Format,\r
550 ...\r
551 )\r
552{\r
553 VA_LIST Marker;\r
554 UINTN Index;\r
555 UINTN Flags;\r
556 UINTN Width;\r
557 UINT64 Value;\r
558\r
559 VA_START (Marker, Format);\r
560\r
561 //\r
562 // Process the format string. Stop if Buffer is over run.\r
563 //\r
564\r
565 for (Index = 0; *Format != 0; Format++) {\r
566 if (*Format != L'%') {\r
567 Buffer[Index++] = *Format;\r
568 } else {\r
569 \r
570 //\r
571 // Now it's time to parse what follows after %\r
572 // Support: % [ 0 width ] [ l ] x\r
573 // width - fill 0, to ensure the width of x will be "width"\r
574 // l - UINT64 instead of UINT32\r
575 //\r
576 Width = 0;\r
577 Flags = 0;\r
578 Format ++;\r
579\r
580 if (*Format == L'0') {\r
581 Flags |= PREFIX_ZERO;\r
582 do {\r
583 Width += Width * 10 + (*Format - L'0');\r
584 Format ++;\r
585 } while (*Format >= L'1' && *Format <= L'9');\r
586 }\r
587\r
588 if (*Format == L'l') {\r
589 Flags |= LONG_TYPE;\r
590 Format ++;\r
591 }\r
592\r
593 \r
594 switch (*Format) {\r
595 case 'X':\r
596 Flags |= PREFIX_ZERO;\r
597 Width = sizeof (UINT64) * 2;\r
598 //\r
599 // break skiped on purpose\r
600 //\r
601 case 'x':\r
602 if ((Flags & LONG_TYPE) == LONG_TYPE) {\r
603 Value = VA_ARG (Marker, UINT64);\r
604 } else {\r
605 Value = VA_ARG (Marker, UINTN);\r
606 }\r
607\r
608 UnicodeValueToString (Buffer+Index, Flags, Value, Width);\r
609 \r
610 for ( ; Buffer[Index] != L'\0'; Index ++) {\r
611 }\r
612\r
613 break;\r
614\r
615 default:\r
616 //\r
617 // if the type is unknown print it to the screen\r
618 //\r
619 Buffer[Index++] = *Format;\r
620 }\r
621 } \r
622 }\r
623 Buffer[Index++] = '\0'; \r
624 \r
625 VA_END (Marker);\r
626 return Index;\r
627}\r
628\r
c69dd9df 629VOID\r
630DumpExceptionDataVgaOut (\r
631 IN EFI_EXCEPTION_TYPE InterruptType,\r
632 IN EFI_SYSTEM_CONTEXT SystemContext\r
633 )\r
634{\r
635 UINTN COLUMN_MAX;\r
636 UINTN ROW_MAX;\r
637 UINT32 ErrorCodeFlag;\r
638 CHAR16 *VideoBufferBase;\r
639 CHAR16 *VideoBuffer;\r
640 UINTN Index;\r
641\r
642 COLUMN_MAX = 80;\r
643 ROW_MAX = 25;\r
644 ErrorCodeFlag = 0x00027d00;\r
645 VideoBufferBase = (CHAR16 *) (UINTN) 0xb8000;\r
646 VideoBuffer = (CHAR16 *) (UINTN) 0xb8000;\r
647\r
648#ifdef EFI32\r
649 SPrint (\r
650 VideoBuffer, \r
651 L"!!!! IA32 Exception Type - %08x !!!!",\r
652 InterruptType\r
653 );\r
654 VideoBuffer += COLUMN_MAX;\r
655 SPrint (\r
656 VideoBuffer, \r
657 L"EIP - %08x, CS - %08x, EFLAGS - %08x",\r
658 SystemContext.SystemContextIa32->Eip,\r
659 SystemContext.SystemContextIa32->Cs,\r
660 SystemContext.SystemContextIa32->Eflags\r
661 );\r
662 VideoBuffer += COLUMN_MAX;\r
663 if (ErrorCodeFlag & (1 << InterruptType)) {\r
664 SPrint (\r
665 VideoBuffer,\r
666 L"ExceptionData - %08x",\r
667 SystemContext.SystemContextIa32->ExceptionData\r
668 );\r
669 VideoBuffer += COLUMN_MAX;\r
670 }\r
671 SPrint (\r
672 VideoBuffer,\r
673 L"EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x",\r
674 SystemContext.SystemContextIa32->Eax,\r
675 SystemContext.SystemContextIa32->Ecx,\r
676 SystemContext.SystemContextIa32->Edx,\r
677 SystemContext.SystemContextIa32->Ebx\r
678 );\r
679 VideoBuffer += COLUMN_MAX;\r
680\r
681 SPrint (\r
682 VideoBuffer,\r
683 L"ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x",\r
684 SystemContext.SystemContextIa32->Esp,\r
685 SystemContext.SystemContextIa32->Ebp,\r
686 SystemContext.SystemContextIa32->Esi,\r
687 SystemContext.SystemContextIa32->Edi\r
688 );\r
689 VideoBuffer += COLUMN_MAX;\r
690\r
691 SPrint (\r
692 VideoBuffer,\r
693 L"DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x",\r
694 SystemContext.SystemContextIa32->Ds,\r
695 SystemContext.SystemContextIa32->Es,\r
696 SystemContext.SystemContextIa32->Fs,\r
697 SystemContext.SystemContextIa32->Gs,\r
698 SystemContext.SystemContextIa32->Ss\r
699 );\r
700 VideoBuffer += COLUMN_MAX;\r
701\r
702 SPrint (\r
703 VideoBuffer,\r
704 L"GDTR - %08x %08x, IDTR - %08x %08x",\r
705 SystemContext.SystemContextIa32->Gdtr[0],\r
706 SystemContext.SystemContextIa32->Gdtr[1],\r
707 SystemContext.SystemContextIa32->Idtr[0],\r
708 SystemContext.SystemContextIa32->Idtr[1]\r
709 );\r
710 VideoBuffer += COLUMN_MAX;\r
711\r
712 SPrint (\r
713 VideoBuffer,\r
714 L"LDTR - %08x, TR - %08x",\r
715 SystemContext.SystemContextIa32->Ldtr,\r
716 SystemContext.SystemContextIa32->Tr\r
717 );\r
718 VideoBuffer += COLUMN_MAX;\r
719\r
720 SPrint (\r
721 VideoBuffer,\r
722 L"CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x",\r
723 SystemContext.SystemContextIa32->Cr0,\r
724 SystemContext.SystemContextIa32->Cr2,\r
725 SystemContext.SystemContextIa32->Cr3,\r
726 SystemContext.SystemContextIa32->Cr4\r
727 );\r
728 VideoBuffer += COLUMN_MAX;\r
729\r
730 SPrint (\r
731 VideoBuffer,\r
732 L"DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x",\r
733 SystemContext.SystemContextIa32->Dr0,\r
734 SystemContext.SystemContextIa32->Dr1,\r
735 SystemContext.SystemContextIa32->Dr2,\r
736 SystemContext.SystemContextIa32->Dr3\r
737 );\r
738 VideoBuffer += COLUMN_MAX;\r
739\r
740 SPrint (\r
741 VideoBuffer,\r
742 L"DR6 - %08x, DR7 - %08x",\r
743 SystemContext.SystemContextIa32->Dr6,\r
744 SystemContext.SystemContextIa32->Dr7\r
745 );\r
746 VideoBuffer += COLUMN_MAX;\r
747#else\r
748 SPrint (\r
749 VideoBuffer,\r
750 L"!!!! X64 Exception Type - %016lx !!!!",\r
751 (UINT64)InterruptType\r
752 );\r
753 VideoBuffer += COLUMN_MAX;\r
754\r
755 SPrint (\r
756 VideoBuffer,\r
757 L"RIP - %016lx, CS - %016lx, RFLAGS - %016lx",\r
758 SystemContext.SystemContextX64->Rip,\r
759 SystemContext.SystemContextX64->Cs,\r
760 SystemContext.SystemContextX64->Rflags\r
761 );\r
762 VideoBuffer += COLUMN_MAX;\r
763\r
764 if (ErrorCodeFlag & (1 << InterruptType)) {\r
765 SPrint (\r
766 VideoBuffer,\r
767 L"ExceptionData - %016lx",\r
768 SystemContext.SystemContextX64->ExceptionData\r
769 );\r
770 VideoBuffer += COLUMN_MAX;\r
771 }\r
772\r
773 SPrint (\r
774 VideoBuffer,\r
775 L"RAX - %016lx, RCX - %016lx, RDX - %016lx",\r
776 SystemContext.SystemContextX64->Rax,\r
777 SystemContext.SystemContextX64->Rcx,\r
778 SystemContext.SystemContextX64->Rdx\r
779 );\r
780 VideoBuffer += COLUMN_MAX;\r
781\r
782 SPrint (\r
783 VideoBuffer,\r
784 L"RBX - %016lx, RSP - %016lx, RBP - %016lx",\r
785 SystemContext.SystemContextX64->Rbx,\r
786 SystemContext.SystemContextX64->Rsp,\r
787 SystemContext.SystemContextX64->Rbp\r
788 );\r
789 VideoBuffer += COLUMN_MAX;\r
790\r
791 SPrint (\r
792 VideoBuffer,\r
793 L"RSI - %016lx, RDI - %016lx",\r
794 SystemContext.SystemContextX64->Rsi,\r
795 SystemContext.SystemContextX64->Rdi\r
796 );\r
797 VideoBuffer += COLUMN_MAX;\r
798\r
799 SPrint (\r
800 VideoBuffer,\r
801 L"R8 - %016lx, R9 - %016lx, R10 - %016lx",\r
802 SystemContext.SystemContextX64->R8,\r
803 SystemContext.SystemContextX64->R9,\r
804 SystemContext.SystemContextX64->R10\r
805 );\r
806 VideoBuffer += COLUMN_MAX;\r
807\r
808 SPrint (\r
809 VideoBuffer,\r
810 L"R11 - %016lx, R12 - %016lx, R13 - %016lx",\r
811 SystemContext.SystemContextX64->R11,\r
812 SystemContext.SystemContextX64->R12,\r
813 SystemContext.SystemContextX64->R13\r
814 );\r
815 VideoBuffer += COLUMN_MAX;\r
816\r
817 SPrint (\r
818 VideoBuffer,\r
819 L"R14 - %016lx, R15 - %016lx",\r
820 SystemContext.SystemContextX64->R14,\r
821 SystemContext.SystemContextX64->R15\r
822 );\r
823 VideoBuffer += COLUMN_MAX;\r
824\r
825 SPrint (\r
826 VideoBuffer,\r
827 L"DS - %016lx, ES - %016lx, FS - %016lx",\r
828 SystemContext.SystemContextX64->Ds,\r
829 SystemContext.SystemContextX64->Es,\r
830 SystemContext.SystemContextX64->Fs\r
831 );\r
832 VideoBuffer += COLUMN_MAX;\r
833\r
834 SPrint (\r
835 VideoBuffer,\r
836 L"GS - %016lx, SS - %016lx",\r
837 SystemContext.SystemContextX64->Gs,\r
838 SystemContext.SystemContextX64->Ss\r
839 );\r
840 VideoBuffer += COLUMN_MAX;\r
841\r
842 SPrint (\r
843 VideoBuffer,\r
844 L"GDTR - %016lx %016lx, LDTR - %016lx",\r
845 SystemContext.SystemContextX64->Gdtr[0],\r
846 SystemContext.SystemContextX64->Gdtr[1],\r
847 SystemContext.SystemContextX64->Ldtr\r
848 );\r
849 VideoBuffer += COLUMN_MAX;\r
850\r
851 SPrint (\r
852 VideoBuffer,\r
853 L"IDTR - %016lx %016lx, TR - %016lx",\r
854 SystemContext.SystemContextX64->Idtr[0],\r
855 SystemContext.SystemContextX64->Idtr[1],\r
856 SystemContext.SystemContextX64->Tr\r
857 );\r
858 VideoBuffer += COLUMN_MAX;\r
859\r
860 SPrint (\r
861 VideoBuffer,\r
862 L"CR0 - %016lx, CR2 - %016lx, CR3 - %016lx",\r
863 SystemContext.SystemContextX64->Cr0,\r
864 SystemContext.SystemContextX64->Cr2,\r
865 SystemContext.SystemContextX64->Cr3\r
866 );\r
867 VideoBuffer += COLUMN_MAX;\r
868\r
869 SPrint (\r
870 VideoBuffer,\r
871 L"CR4 - %016lx, CR8 - %016lx",\r
872 SystemContext.SystemContextX64->Cr4,\r
873 SystemContext.SystemContextX64->Cr8\r
874 );\r
875 VideoBuffer += COLUMN_MAX;\r
876\r
877 SPrint (\r
878 VideoBuffer,\r
879 L"DR0 - %016lx, DR1 - %016lx, DR2 - %016lx",\r
880 SystemContext.SystemContextX64->Dr0,\r
881 SystemContext.SystemContextX64->Dr1,\r
882 SystemContext.SystemContextX64->Dr2\r
883 );\r
884 VideoBuffer += COLUMN_MAX;\r
885\r
886 SPrint (\r
887 VideoBuffer,\r
888 L"DR3 - %016lx, DR6 - %016lx, DR7 - %016lx",\r
889 SystemContext.SystemContextX64->Dr3,\r
890 SystemContext.SystemContextX64->Dr6,\r
891 SystemContext.SystemContextX64->Dr7\r
892 );\r
893 VideoBuffer += COLUMN_MAX;\r
894#endif\r
895\r
896 for (Index = 0; Index < COLUMN_MAX * ROW_MAX; Index ++) {\r
897 if (Index > (UINTN)(VideoBuffer - VideoBufferBase)) {\r
898 VideoBufferBase[Index] = 0x0c20;\r
899 } else {\r
900 VideoBufferBase[Index] |= 0x0c00;\r
901 }\r
902 }\r
903\r
904 return ;\r
905}\r
906\r
907#if CPU_EXCEPTION_VGA_SWITCH\r
c69dd9df 908UINT16\r
909SwitchVideoMode (\r
910 UINT16 NewVideoMode\r
911 )\r
912/*++\r
913Description\r
914 Switch Video Mode from current mode to new mode, and return the old mode.\r
915 Use Thuink\r
916\r
917Arguments\r
918 NewVideoMode - new video mode want to set\r
919\r
920Return\r
921 UINT16 - (UINT16) -1 indicates failure\r
922 Other value indicates the old mode, which can be used for restore later\r
923 \r
924--*/\r
925{\r
926 EFI_STATUS Status;\r
927 EFI_LEGACY_BIOS_THUNK_PROTOCOL *LegacyBios;\r
928 EFI_IA32_REGISTER_SET Regs;\r
929 UINT16 OriginalVideoMode = (UINT16) -1;\r
930 \r
c69dd9df 931\r
932 //\r
933 // VESA SuperVGA BIOS - GET CURRENT VIDEO MODE\r
934 // AX = 4F03h\r
935 // Return:AL = 4Fh if function supported\r
936 // AH = status 00h successful\r
937 // BX = video mode (see #0082,#0083)\r
938 //\r
939 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
940 Regs.X.AX = 0x4F03;\r
23833b2c 941 LegacyBiosInt86 (0x10, &Regs);\r
c69dd9df 942 if (Regs.X.AX == 0x004F) {\r
943 OriginalVideoMode = Regs.X.BX;\r
944 } else {\r
945 //\r
946 // VIDEO - GET CURRENT VIDEO MODE\r
947 // AH = 0Fh\r
948 // Return:AH = number of character columns\r
949 // AL = display mode (see #0009 at AH=00h)\r
950 // BH = active page (see AH=05h)\r
951 //\r
952 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
953 Regs.H.AH = 0x0F;\r
23833b2c 954 LegacyBiosInt86 (0x10, &Regs);\r
c69dd9df 955 OriginalVideoMode = Regs.H.AL;\r
956 }\r
957\r
958 //\r
959 // Set new video mode\r
960 //\r
961 if (NewVideoMode < 0x100) {\r
962 //\r
963 // Set the 80x25 Text VGA Mode: Assume successful always\r
964 //\r
965 // VIDEO - SET VIDEO MODE\r
966 // AH = 00h\r
967 // AL = desired video mode (see #0009)\r
968 // Return:AL = video mode flag (Phoenix, AMI BIOS)\r
969 // 20h mode > 7\r
970 // 30h modes 0-5 and 7\r
971 // 3Fh mode 6\r
972 // AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)\r
973 //\r
974 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
975 Regs.H.AH = 0x00;\r
976 Regs.H.AL = (UINT8) NewVideoMode;\r
23833b2c 977 LegacyBiosInt86 (0x10, &Regs);\r
c69dd9df 978\r
979 //\r
980 // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)\r
981 // AX = 1114h\r
982 // BL = block to load\r
983 // Return:Nothing\r
984 //\r
985 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
986 Regs.H.AH = 0x11;\r
987 Regs.H.AL = 0x14;\r
988 Regs.H.BL = 0;\r
23833b2c 989 LegacyBiosInt86 (0x10, &Regs);\r
c69dd9df 990 } else {\r
991 //\r
992 // VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE\r
993 // AX = 4F02h\r
994 // BX = mode (see #0082,#0083)\r
995 // bit 15 set means don't clear video memory\r
996 // bit 14 set means enable linear framebuffer mode (VBE v2.0+)\r
997 // Return:AL = 4Fh if function supported\r
998 // AH = status\r
999 // 00h successful\r
1000 // 01h failed\r
1001 //\r
1002 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
1003 Regs.X.AX = 0x4F02;\r
1004 Regs.X.BX = NewVideoMode;\r
23833b2c 1005 LegacyBiosInt86 (0x10, &Regs);\r
c69dd9df 1006 if (Regs.X.AX != 0x004F) {\r
1007 DEBUG ((EFI_D_ERROR, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode));\r
1008 return (UINT16) -1;\r
1009 }\r
1010 }\r
1011\r
1012 return OriginalVideoMode;\r
1013}\r
1014#endif\r
1015\r
1016VOID\r
1017ExceptionHandler (\r
1018 IN EFI_EXCEPTION_TYPE InterruptType,\r
1019 IN EFI_SYSTEM_CONTEXT SystemContext\r
1020 )\r
1021{\r
1022#if CPU_EXCEPTION_VGA_SWITCH\r
1023 UINT16 VideoMode;\r
1024#endif\r
1025\r
1026#if CPU_EXCEPTION_DEBUG_OUTPUT\r
1027 DumpExceptionDataDebugOut (InterruptType, SystemContext);\r
1028#endif\r
1029\r
1030#if CPU_EXCEPTION_VGA_SWITCH\r
1031 //\r
1032 // Switch to text mode for RED-SCREEN output\r
1033 //\r
1034 VideoMode = SwitchVideoMode (0x83);\r
1035 if (VideoMode == (UINT16) -1) {\r
1036 DEBUG ((EFI_D_ERROR, "Video Mode Unknown!\n"));\r
1037 }\r
1038#endif\r
1039\r
1040 DumpExceptionDataVgaOut (InterruptType, SystemContext);\r
1041\r
1042 //\r
1043 // Use this macro to hang so that the compiler does not optimize out\r
1044 // the following RET instructions. This allows us to return if we\r
1045 // have a debugger attached.\r
1046 //\r
1047 CpuDeadLoop ();\r
1048\r
1049#if CPU_EXCEPTION_VGA_SWITCH\r
1050 //\r
1051 // Switch back to the old video mode\r
1052 //\r
1053 if (VideoMode != (UINT16)-1) {\r
1054 SwitchVideoMode (VideoMode);\r
1055 }\r
1056#endif\r
1057\r
1058 return ;\r
1059}\r
1060\r
1061VOID\r
1062TimerHandler (\r
1063 IN EFI_EXCEPTION_TYPE InterruptType,\r
1064 IN EFI_SYSTEM_CONTEXT SystemContext\r
1065 )\r
1066{\r
1067 if (mTimerHandler != NULL) {\r
1068 mTimerHandler (InterruptType, SystemContext);\r
1069 }\r
1070}\r
1071\r
1072EFI_STATUS\r
1073EFIAPI\r
1074InitializeCpu (\r
1075 IN EFI_HANDLE ImageHandle,\r
1076 IN EFI_SYSTEM_TABLE *SystemTable\r
1077 )\r
1078/*++\r
1079\r
1080Routine Description:\r
1081 Initialize the state information for the CPU Architectural Protocol\r
1082\r
1083Arguments:\r
1084 ImageHandle of the loaded driver\r
1085 Pointer to the System Table\r
1086\r
1087Returns:\r
1088 EFI_SUCCESS - thread can be successfully created\r
1089 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure\r
1090 EFI_DEVICE_ERROR - cannot create the thread\r
1091\r
1092--*/\r
1093{\r
1094 EFI_STATUS Status;\r
1095 EFI_8259_IRQ Irq;\r
1096 UINT32 InterruptVector;\r
1097\r
1098 //\r
1099 // Find the Legacy8259 protocol.\r
1100 //\r
1101 Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &gLegacy8259);\r
1102 ASSERT_EFI_ERROR (Status);\r
1103\r
1104 //\r
1105 // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver\r
1106 //\r
1107 Status = gLegacy8259->GetVector (gLegacy8259, Efi8259Irq0, (UINT8 *) &mTimerVector);\r
1108 ASSERT_EFI_ERROR (Status);\r
1109\r
1110 //\r
1111 // Reload GDT, IDT\r
1112 //\r
1113 InitDescriptor ();\r
1114\r
1115 //\r
1116 // Install Exception Handler (0x00 ~ 0x1F)\r
1117 //\r
1118 for (InterruptVector = 0; InterruptVector < 0x20; InterruptVector++) {\r
1119 InstallInterruptHandler (\r
1120 InterruptVector,\r
1121 (VOID (*)(VOID))(UINTN)((UINTN)SystemExceptionHandler + mExceptionCodeSize * InterruptVector)\r
1122 );\r
1123 }\r
1124\r
1125 //\r
1126 // Install Timer Handler\r
1127 //\r
1128 InstallInterruptHandler (mTimerVector, SystemTimerHandler);\r
1129\r
1130 //\r
1131 // BUGBUG: We add all other interrupt vector\r
1132 //\r
1133 for (Irq = Efi8259Irq1; Irq <= Efi8259Irq15; Irq++) {\r
1134 InterruptVector = 0;\r
1135 Status = gLegacy8259->GetVector (gLegacy8259, Irq, (UINT8 *) &InterruptVector);\r
1136 ASSERT_EFI_ERROR (Status);\r
1137 InstallInterruptHandler (InterruptVector, SystemTimerHandler);\r
1138 }\r
1139\r
23833b2c 1140 InitializeBiosIntCaller();\r
1141 \r
c69dd9df 1142 //\r
1143 // Install CPU Architectural Protocol and the thunk protocol\r
1144 //\r
1145 mHandle = NULL;\r
1146 Status = gBS->InstallMultipleProtocolInterfaces (\r
1147 &mHandle,\r
1148 &gEfiCpuArchProtocolGuid,\r
1149 &mCpu,\r
1150 NULL\r
1151 );\r
1152 ASSERT_EFI_ERROR (Status);\r
1153\r
1154 return EFI_SUCCESS;\r
1155}\r
1156\r
23833b2c 1157VOID\r
1158InitializeBiosIntCaller (\r
1159 VOID\r
1160 )\r
1161{\r
1162 EFI_STATUS Status;\r
1163 UINT32 RealModeBufferSize;\r
1164 UINT32 ExtraStackSize;\r
1165 EFI_PHYSICAL_ADDRESS LegacyRegionBase;\r
1166 \r
1167 //\r
1168 // Get LegacyRegion\r
1169 //\r
1170 AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);\r
1171\r
1172 LegacyRegionBase = 0x100000;\r
1173 Status = gBS->AllocatePages (\r
1174 AllocateMaxAddress,\r
1175 EfiACPIMemoryNVS,\r
1176 EFI_SIZE_TO_PAGES(RealModeBufferSize + ExtraStackSize + 200),\r
1177 &LegacyRegionBase\r
1178 );\r
1179 ASSERT_EFI_ERROR (Status);\r
1180 \r
1181 mThunkContext.RealModeBuffer = (VOID*)(UINTN)LegacyRegionBase;\r
1182 mThunkContext.RealModeBufferSize = EFI_PAGES_TO_SIZE (RealModeBufferSize);\r
1183 mThunkContext.ThunkAttributes = 3;\r
1184 AsmPrepareThunk16(&mThunkContext);\r
1185 \r
1186}\r
1187\r
1188BOOLEAN\r
1189EFIAPI\r
1190LegacyBiosInt86 (\r
1191 IN UINT8 BiosInt,\r
1192 IN EFI_IA32_REGISTER_SET *Regs\r
1193 )\r
1194{\r
1195 UINTN Status;\r
1196 UINTN Eflags;\r
1197 IA32_REGISTER_SET ThunkRegSet;\r
1198 BOOLEAN Ret;\r
1199 UINT16 *Stack16;\r
1200 \r
1201 Regs->X.Flags.Reserved1 = 1;\r
1202 Regs->X.Flags.Reserved2 = 0;\r
1203 Regs->X.Flags.Reserved3 = 0;\r
1204 Regs->X.Flags.Reserved4 = 0;\r
1205 Regs->X.Flags.IOPL = 3;\r
1206 Regs->X.Flags.NT = 0;\r
1207 Regs->X.Flags.IF = 1;\r
1208 Regs->X.Flags.TF = 0;\r
1209 Regs->X.Flags.CF = 0;\r
1210\r
1211 ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));\r
1212 ThunkRegSet.E.EDI = Regs->E.EDI;\r
1213 ThunkRegSet.E.ESI = Regs->E.ESI;\r
1214 ThunkRegSet.E.EBP = Regs->E.EBP;\r
1215 ThunkRegSet.E.EBX = Regs->E.EBX;\r
1216 ThunkRegSet.E.EDX = Regs->E.EDX;\r
1217 ThunkRegSet.E.ECX = Regs->E.ECX;\r
1218 ThunkRegSet.E.EAX = Regs->E.EAX;\r
1219 ThunkRegSet.E.DS = Regs->E.DS;\r
1220 ThunkRegSet.E.ES = Regs->E.ES;\r
1221\r
1222 CopyMem (&(ThunkRegSet.E.EFLAGS), &(Regs->E.EFlags), sizeof (UINT32));\r
1223 \r
1224 //\r
1225 // The call to Legacy16 is a critical section to EFI\r
1226 //\r
1227 Eflags = AsmReadEflags ();\r
1228 if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
1229 DisableInterrupts ();\r
1230 }\r
1231\r
1232 //\r
1233 // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.\r
1234 //\r
1235 Status = gLegacy8259->SetMode (gLegacy8259, Efi8259LegacyMode, NULL, NULL);\r
1236 ASSERT_EFI_ERROR (Status);\r
1237 \r
1238 Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));\r
1239 Stack16 -= sizeof (ThunkRegSet.E.EFLAGS) / sizeof (UINT16);\r
1240 CopyMem (Stack16, &ThunkRegSet.E.EFLAGS, sizeof (ThunkRegSet.E.EFLAGS));\r
1241\r
1242 ThunkRegSet.E.SS = (UINT16) (((UINTN) Stack16 >> 16) << 12);\r
1243 ThunkRegSet.E.ESP = (UINT16) (UINTN) Stack16;\r
1244 ThunkRegSet.E.Eip = (UINT16)((UINT32 *)NULL)[BiosInt];\r
1245 ThunkRegSet.E.CS = (UINT16)(((UINT32 *)NULL)[BiosInt] >> 16);\r
1246 mThunkContext.RealModeState = &ThunkRegSet;\r
1247 AsmThunk16 (&mThunkContext);\r
1248\r
1249 //\r
1250 // Restore protected mode interrupt state\r
1251 //\r
1252 Status = gLegacy8259->SetMode (gLegacy8259, Efi8259ProtectedMode, NULL, NULL);\r
1253 ASSERT_EFI_ERROR (Status);\r
1254\r
1255 //\r
1256 // End critical section\r
1257 //\r
1258 if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
1259 EnableInterrupts ();\r
1260 }\r
1261\r
1262 Regs->E.EDI = ThunkRegSet.E.EDI; \r
1263 Regs->E.ESI = ThunkRegSet.E.ESI; \r
1264 Regs->E.EBP = ThunkRegSet.E.EBP; \r
1265 Regs->E.EBX = ThunkRegSet.E.EBX; \r
1266 Regs->E.EDX = ThunkRegSet.E.EDX; \r
1267 Regs->E.ECX = ThunkRegSet.E.ECX; \r
1268 Regs->E.EAX = ThunkRegSet.E.EAX;\r
1269 Regs->E.SS = ThunkRegSet.E.SS;\r
1270 Regs->E.CS = ThunkRegSet.E.CS; \r
1271 Regs->E.DS = ThunkRegSet.E.DS; \r
1272 Regs->E.ES = ThunkRegSet.E.ES;\r
1273\r
1274 CopyMem (&(Regs->E.EFlags), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));\r
1275\r
1276 Ret = (BOOLEAN) (Regs->E.EFlags.CF == 1);\r
1277\r
1278 return Ret;\r
1279}\r