3 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 BOOLEAN mInterruptState
= FALSE
;
26 extern UINT32 mExceptionCodeSize
;
27 UINTN mTimerVector
= 0;
28 volatile EFI_CPU_INTERRUPT_HANDLER mTimerHandler
= NULL
;
29 EFI_LEGACY_8259_PROTOCOL
*gLegacy8259
= NULL
;
30 THUNK_CONTEXT mThunkContext
;
31 #define EFI_CPU_EFLAGS_IF 0x200
34 InitializeBiosIntCaller (
42 IN EFI_IA32_REGISTER_SET
*Regs
46 // The Cpu Architectural Protocol that this Driver produces
48 EFI_HANDLE mHandle
= NULL
;
49 EFI_CPU_ARCH_PROTOCOL mCpu
= {
55 CpuRegisterInterruptHandler
,
57 CpuSetMemoryAttributes
,
59 4, // DmaBufferAlignment
64 CpuFlushCpuDataCache (
65 IN EFI_CPU_ARCH_PROTOCOL
*This
,
66 IN EFI_PHYSICAL_ADDRESS Start
,
68 IN EFI_CPU_FLUSH_TYPE FlushType
73 Flush CPU data cache. If the instruction cache is fully coherent
74 with all DMA operations then function can just return EFI_SUCCESS.
77 This - Protocol instance structure
78 Start - Physical address to start flushing from.
79 Length - Number of bytes to flush. Round up to chipset
81 FlushType - Specifies the type of flush operation to perform.
85 EFI_SUCCESS - If cache was flushed
86 EFI_UNSUPPORTED - If flush type is not supported.
87 EFI_DEVICE_ERROR - If requested range could not be flushed.
91 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
94 } else if (FlushType
== EfiCpuFlushTypeInvalidate
) {
98 return EFI_UNSUPPORTED
;
106 IN EFI_CPU_ARCH_PROTOCOL
*This
111 Enables CPU interrupts.
114 This - Protocol instance structure
117 EFI_SUCCESS - If interrupts were enabled in the CPU
118 EFI_DEVICE_ERROR - If interrupts could not be enabled on the CPU.
124 mInterruptState
= TRUE
;
131 CpuDisableInterrupt (
132 IN EFI_CPU_ARCH_PROTOCOL
*This
137 Disables CPU interrupts.
140 This - Protocol instance structure
143 EFI_SUCCESS - If interrupts were disabled in the CPU.
144 EFI_DEVICE_ERROR - If interrupts could not be disabled on the CPU.
148 DisableInterrupts ();
150 mInterruptState
= FALSE
;
157 CpuGetInterruptState (
158 IN EFI_CPU_ARCH_PROTOCOL
*This
,
164 Return the state of interrupts.
167 This - Protocol instance structure
168 State - Pointer to the CPU's current interrupt state
171 EFI_SUCCESS - If interrupts were disabled in the CPU.
172 EFI_INVALID_PARAMETER - State is NULL.
177 return EFI_INVALID_PARAMETER
;
180 *State
= mInterruptState
;
188 IN EFI_CPU_ARCH_PROTOCOL
*This
,
189 IN EFI_CPU_INIT_TYPE InitType
195 Generates an INIT to the CPU
198 This - Protocol instance structure
199 InitType - Type of CPU INIT to perform
202 EFI_SUCCESS - If CPU INIT occurred. This value should never be
204 EFI_DEVICE_ERROR - If CPU INIT failed.
205 EFI_NOT_SUPPORTED - Requested type of CPU INIT not supported.
209 return EFI_UNSUPPORTED
;
215 CpuRegisterInterruptHandler (
216 IN EFI_CPU_ARCH_PROTOCOL
*This
,
217 IN EFI_EXCEPTION_TYPE InterruptType
,
218 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
223 Registers a function to be called from the CPU interrupt handler.
226 This - Protocol instance structure
227 InterruptType - Defines which interrupt to hook. IA-32 valid range
229 InterruptHandler - A pointer to a function of type
230 EFI_CPU_INTERRUPT_HANDLER that is called when a
231 processor interrupt occurs. A null pointer
232 is an error condition.
235 EFI_SUCCESS - If handler installed or uninstalled.
236 EFI_ALREADY_STARTED - InterruptHandler is not NULL, and a handler for
237 InterruptType was previously installed
238 EFI_INVALID_PARAMETER - InterruptHandler is NULL, and a handler for
239 InterruptType was not previously installed.
240 EFI_UNSUPPORTED - The interrupt specified by InterruptType is not
245 if ((InterruptType
< 0) || (InterruptType
>= INTERRUPT_VECTOR_NUMBER
)) {
246 return EFI_UNSUPPORTED
;
248 if ((UINTN
)(UINT32
)InterruptType
!= mTimerVector
) {
249 return EFI_UNSUPPORTED
;
251 if ((mTimerHandler
== NULL
) && (InterruptHandler
== NULL
)) {
252 return EFI_INVALID_PARAMETER
;
253 } else if ((mTimerHandler
!= NULL
) && (InterruptHandler
!= NULL
)) {
254 return EFI_ALREADY_STARTED
;
256 mTimerHandler
= InterruptHandler
;
263 IN EFI_CPU_ARCH_PROTOCOL
*This
,
264 IN UINT32 TimerIndex
,
265 OUT UINT64
*TimerValue
,
266 OUT UINT64
*TimerPeriod OPTIONAL
271 Returns a timer value from one of the CPU's internal timers. There is no
272 inherent time interval between ticks but is a function of the CPU
276 This - Protocol instance structure
277 TimerIndex - Specifies which CPU timer ie requested
278 TimerValue - Pointer to the returned timer value
282 EFI_SUCCESS - If the CPU timer count was returned.
283 EFI_UNSUPPORTED - If the CPU does not have any readable timers
284 EFI_DEVICE_ERROR - If an error occurred reading the timer.
285 EFI_INVALID_PARAMETER - TimerIndex is not valid
289 if (TimerValue
== NULL
) {
290 return EFI_INVALID_PARAMETER
;
293 if (TimerIndex
== 0) {
294 *TimerValue
= AsmReadTsc ();
295 if (TimerPeriod
!= NULL
) {
297 // BugBug: Hard coded. Don't know how to do this generically
299 *TimerPeriod
= 1000000000;
303 return EFI_INVALID_PARAMETER
;
308 CpuSetMemoryAttributes (
309 IN EFI_CPU_ARCH_PROTOCOL
*This
,
310 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
317 Set memory cacheability attributes for given range of memeory
320 This - Protocol instance structure
321 BaseAddress - Specifies the start address of the memory range
322 Length - Specifies the length of the memory range
323 Attributes - The memory cacheability for the memory range
326 EFI_SUCCESS - If the cacheability of that memory range is set successfully
327 EFI_UNSUPPORTED - If the desired operation cannot be done
328 EFI_INVALID_PARAMETER - The input parameter is not correct, such as Length = 0
332 return EFI_UNSUPPORTED
;
335 #if CPU_EXCEPTION_DEBUG_OUTPUT
337 DumpExceptionDataDebugOut (
338 IN EFI_EXCEPTION_TYPE InterruptType
,
339 IN EFI_SYSTEM_CONTEXT SystemContext
342 UINT32 ErrorCodeFlag
;
344 ErrorCodeFlag
= 0x00027d00;
349 "!!!! IA32 Exception Type - %08x !!!!\n",
354 "EIP - %08x, CS - %08x, EFLAGS - %08x\n",
355 SystemContext
.SystemContextIa32
->Eip
,
356 SystemContext
.SystemContextIa32
->Cs
,
357 SystemContext
.SystemContextIa32
->Eflags
359 if (ErrorCodeFlag
& (1 << InterruptType
)) {
362 "ExceptionData - %08x\n",
363 SystemContext
.SystemContextIa32
->ExceptionData
368 "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",
369 SystemContext
.SystemContextIa32
->Eax
,
370 SystemContext
.SystemContextIa32
->Ecx
,
371 SystemContext
.SystemContextIa32
->Edx
,
372 SystemContext
.SystemContextIa32
->Ebx
376 "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
377 SystemContext
.SystemContextIa32
->Esp
,
378 SystemContext
.SystemContextIa32
->Ebp
,
379 SystemContext
.SystemContextIa32
->Esi
,
380 SystemContext
.SystemContextIa32
->Edi
384 "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x\n",
385 SystemContext
.SystemContextIa32
->Ds
,
386 SystemContext
.SystemContextIa32
->Es
,
387 SystemContext
.SystemContextIa32
->Fs
,
388 SystemContext
.SystemContextIa32
->Gs
,
389 SystemContext
.SystemContextIa32
->Ss
393 "GDTR - %08x %08x, IDTR - %08x %08x\n",
394 SystemContext
.SystemContextIa32
->Gdtr
[0],
395 SystemContext
.SystemContextIa32
->Gdtr
[1],
396 SystemContext
.SystemContextIa32
->Idtr
[0],
397 SystemContext
.SystemContextIa32
->Idtr
[1]
401 "LDTR - %08x, TR - %08x\n",
402 SystemContext
.SystemContextIa32
->Ldtr
,
403 SystemContext
.SystemContextIa32
->Tr
407 "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
408 SystemContext
.SystemContextIa32
->Cr0
,
409 SystemContext
.SystemContextIa32
->Cr2
,
410 SystemContext
.SystemContextIa32
->Cr3
,
411 SystemContext
.SystemContextIa32
->Cr4
415 "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
416 SystemContext
.SystemContextIa32
->Dr0
,
417 SystemContext
.SystemContextIa32
->Dr1
,
418 SystemContext
.SystemContextIa32
->Dr2
,
419 SystemContext
.SystemContextIa32
->Dr3
423 "DR6 - %08x, DR7 - %08x\n",
424 SystemContext
.SystemContextIa32
->Dr6
,
425 SystemContext
.SystemContextIa32
->Dr7
430 "!!!! X64 Exception Type - %016lx !!!!\n",
431 (UINT64
)InterruptType
435 "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",
436 SystemContext
.SystemContextX64
->Rip
,
437 SystemContext
.SystemContextX64
->Cs
,
438 SystemContext
.SystemContextX64
->Rflags
440 if (ErrorCodeFlag
& (1 << InterruptType
)) {
443 "ExceptionData - %016lx\n",
444 SystemContext
.SystemContextX64
->ExceptionData
449 "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
450 SystemContext
.SystemContextX64
->Rax
,
451 SystemContext
.SystemContextX64
->Rcx
,
452 SystemContext
.SystemContextX64
->Rdx
456 "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
457 SystemContext
.SystemContextX64
->Rbx
,
458 SystemContext
.SystemContextX64
->Rsp
,
459 SystemContext
.SystemContextX64
->Rbp
463 "RSI - %016lx, RDI - %016lx\n",
464 SystemContext
.SystemContextX64
->Rsi
,
465 SystemContext
.SystemContextX64
->Rdi
469 "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
470 SystemContext
.SystemContextX64
->R8
,
471 SystemContext
.SystemContextX64
->R9
,
472 SystemContext
.SystemContextX64
->R10
476 "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
477 SystemContext
.SystemContextX64
->R11
,
478 SystemContext
.SystemContextX64
->R12
,
479 SystemContext
.SystemContextX64
->R13
483 "R14 - %016lx, R15 - %016lx\n",
484 SystemContext
.SystemContextX64
->R14
,
485 SystemContext
.SystemContextX64
->R15
489 "DS - %016lx, ES - %016lx, FS - %016lx\n",
490 SystemContext
.SystemContextX64
->Ds
,
491 SystemContext
.SystemContextX64
->Es
,
492 SystemContext
.SystemContextX64
->Fs
496 "GS - %016lx, SS - %016lx\n",
497 SystemContext
.SystemContextX64
->Gs
,
498 SystemContext
.SystemContextX64
->Ss
502 "GDTR - %016lx %016lx, LDTR - %016lx\n",
503 SystemContext
.SystemContextX64
->Gdtr
[0],
504 SystemContext
.SystemContextX64
->Gdtr
[1],
505 SystemContext
.SystemContextX64
->Ldtr
509 "IDTR - %016lx %016lx, TR - %016lx\n",
510 SystemContext
.SystemContextX64
->Idtr
[0],
511 SystemContext
.SystemContextX64
->Idtr
[1],
512 SystemContext
.SystemContextX64
->Tr
516 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
517 SystemContext
.SystemContextX64
->Cr0
,
518 SystemContext
.SystemContextX64
->Cr2
,
519 SystemContext
.SystemContextX64
->Cr3
523 "CR4 - %016lx, CR8 - %016lx\n",
524 SystemContext
.SystemContextX64
->Cr4
,
525 SystemContext
.SystemContextX64
->Cr8
529 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
530 SystemContext
.SystemContextX64
->Dr0
,
531 SystemContext
.SystemContextX64
->Dr1
,
532 SystemContext
.SystemContextX64
->Dr2
536 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
537 SystemContext
.SystemContextX64
->Dr3
,
538 SystemContext
.SystemContextX64
->Dr6
,
539 SystemContext
.SystemContextX64
->Dr7
548 DumpExceptionDataVgaOut (
549 IN EFI_EXCEPTION_TYPE InterruptType
,
550 IN EFI_SYSTEM_CONTEXT SystemContext
555 UINT32 ErrorCodeFlag
;
556 CHAR16
*VideoBufferBase
;
562 ErrorCodeFlag
= 0x00027d00;
563 VideoBufferBase
= (CHAR16
*) (UINTN
) 0xb8000;
564 VideoBuffer
= (CHAR16
*) (UINTN
) 0xb8000;
567 UnicodeSPrintAsciiFormat (
569 COLUMN_MAX
* sizeof (CHAR16
),
570 "!!!! IA32 Exception Type - %08x !!!!",
573 VideoBuffer
+= COLUMN_MAX
;
574 UnicodeSPrintAsciiFormat (
576 COLUMN_MAX
* sizeof (CHAR16
),
577 "EIP - %08x, CS - %08x, EFLAGS - %08x",
578 SystemContext
.SystemContextIa32
->Eip
,
579 SystemContext
.SystemContextIa32
->Cs
,
580 SystemContext
.SystemContextIa32
->Eflags
582 VideoBuffer
+= COLUMN_MAX
;
583 if (ErrorCodeFlag
& (1 << InterruptType
)) {
584 UnicodeSPrintAsciiFormat (
586 COLUMN_MAX
* sizeof (CHAR16
),
587 "ExceptionData - %08x",
588 SystemContext
.SystemContextIa32
->ExceptionData
590 VideoBuffer
+= COLUMN_MAX
;
592 UnicodeSPrintAsciiFormat (
594 COLUMN_MAX
* sizeof (CHAR16
),
595 "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x",
596 SystemContext
.SystemContextIa32
->Eax
,
597 SystemContext
.SystemContextIa32
->Ecx
,
598 SystemContext
.SystemContextIa32
->Edx
,
599 SystemContext
.SystemContextIa32
->Ebx
601 VideoBuffer
+= COLUMN_MAX
;
603 UnicodeSPrintAsciiFormat (
605 COLUMN_MAX
* sizeof (CHAR16
),
606 "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x",
607 SystemContext
.SystemContextIa32
->Esp
,
608 SystemContext
.SystemContextIa32
->Ebp
,
609 SystemContext
.SystemContextIa32
->Esi
,
610 SystemContext
.SystemContextIa32
->Edi
612 VideoBuffer
+= COLUMN_MAX
;
614 UnicodeSPrintAsciiFormat (
616 COLUMN_MAX
* sizeof (CHAR16
),
617 "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x",
618 SystemContext
.SystemContextIa32
->Ds
,
619 SystemContext
.SystemContextIa32
->Es
,
620 SystemContext
.SystemContextIa32
->Fs
,
621 SystemContext
.SystemContextIa32
->Gs
,
622 SystemContext
.SystemContextIa32
->Ss
624 VideoBuffer
+= COLUMN_MAX
;
626 UnicodeSPrintAsciiFormat (
628 COLUMN_MAX
* sizeof (CHAR16
),
629 "GDTR - %08x %08x, IDTR - %08x %08x",
630 SystemContext
.SystemContextIa32
->Gdtr
[0],
631 SystemContext
.SystemContextIa32
->Gdtr
[1],
632 SystemContext
.SystemContextIa32
->Idtr
[0],
633 SystemContext
.SystemContextIa32
->Idtr
[1]
635 VideoBuffer
+= COLUMN_MAX
;
637 UnicodeSPrintAsciiFormat (
639 COLUMN_MAX
* sizeof (CHAR16
),
640 "LDTR - %08x, TR - %08x",
641 SystemContext
.SystemContextIa32
->Ldtr
,
642 SystemContext
.SystemContextIa32
->Tr
644 VideoBuffer
+= COLUMN_MAX
;
646 UnicodeSPrintAsciiFormat (
648 COLUMN_MAX
* sizeof (CHAR16
),
649 "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x",
650 SystemContext
.SystemContextIa32
->Cr0
,
651 SystemContext
.SystemContextIa32
->Cr2
,
652 SystemContext
.SystemContextIa32
->Cr3
,
653 SystemContext
.SystemContextIa32
->Cr4
655 VideoBuffer
+= COLUMN_MAX
;
657 UnicodeSPrintAsciiFormat (
659 COLUMN_MAX
* sizeof (CHAR16
),
660 "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x",
661 SystemContext
.SystemContextIa32
->Dr0
,
662 SystemContext
.SystemContextIa32
->Dr1
,
663 SystemContext
.SystemContextIa32
->Dr2
,
664 SystemContext
.SystemContextIa32
->Dr3
666 VideoBuffer
+= COLUMN_MAX
;
668 UnicodeSPrintAsciiFormat (
670 COLUMN_MAX
* sizeof (CHAR16
),
671 "DR6 - %08x, DR7 - %08x",
672 SystemContext
.SystemContextIa32
->Dr6
,
673 SystemContext
.SystemContextIa32
->Dr7
675 VideoBuffer
+= COLUMN_MAX
;
677 UnicodeSPrintAsciiFormat (
679 COLUMN_MAX
* sizeof (CHAR16
),
680 "!!!! X64 Exception Type - %016lx !!!!",
681 (UINT64
)InterruptType
683 VideoBuffer
+= COLUMN_MAX
;
685 UnicodeSPrintAsciiFormat (
687 COLUMN_MAX
* sizeof (CHAR16
),
688 "RIP - %016lx, CS - %016lx, RFLAGS - %016lx",
689 SystemContext
.SystemContextX64
->Rip
,
690 SystemContext
.SystemContextX64
->Cs
,
691 SystemContext
.SystemContextX64
->Rflags
693 VideoBuffer
+= COLUMN_MAX
;
695 if (ErrorCodeFlag
& (1 << InterruptType
)) {
696 UnicodeSPrintAsciiFormat (
698 COLUMN_MAX
* sizeof (CHAR16
),
699 "ExceptionData - %016lx",
700 SystemContext
.SystemContextX64
->ExceptionData
702 VideoBuffer
+= COLUMN_MAX
;
705 UnicodeSPrintAsciiFormat (
707 COLUMN_MAX
* sizeof (CHAR16
),
708 "RAX - %016lx, RCX - %016lx, RDX - %016lx",
709 SystemContext
.SystemContextX64
->Rax
,
710 SystemContext
.SystemContextX64
->Rcx
,
711 SystemContext
.SystemContextX64
->Rdx
713 VideoBuffer
+= COLUMN_MAX
;
715 UnicodeSPrintAsciiFormat (
717 COLUMN_MAX
* sizeof (CHAR16
),
718 "RBX - %016lx, RSP - %016lx, RBP - %016lx",
719 SystemContext
.SystemContextX64
->Rbx
,
720 SystemContext
.SystemContextX64
->Rsp
,
721 SystemContext
.SystemContextX64
->Rbp
723 VideoBuffer
+= COLUMN_MAX
;
725 UnicodeSPrintAsciiFormat (
727 COLUMN_MAX
* sizeof (CHAR16
),
728 "RSI - %016lx, RDI - %016lx",
729 SystemContext
.SystemContextX64
->Rsi
,
730 SystemContext
.SystemContextX64
->Rdi
732 VideoBuffer
+= COLUMN_MAX
;
734 UnicodeSPrintAsciiFormat (
736 COLUMN_MAX
* sizeof (CHAR16
),
737 "R8 - %016lx, R9 - %016lx, R10 - %016lx",
738 SystemContext
.SystemContextX64
->R8
,
739 SystemContext
.SystemContextX64
->R9
,
740 SystemContext
.SystemContextX64
->R10
742 VideoBuffer
+= COLUMN_MAX
;
744 UnicodeSPrintAsciiFormat (
746 COLUMN_MAX
* sizeof (CHAR16
),
747 "R11 - %016lx, R12 - %016lx, R13 - %016lx",
748 SystemContext
.SystemContextX64
->R11
,
749 SystemContext
.SystemContextX64
->R12
,
750 SystemContext
.SystemContextX64
->R13
752 VideoBuffer
+= COLUMN_MAX
;
754 UnicodeSPrintAsciiFormat (
756 COLUMN_MAX
* sizeof (CHAR16
),
757 "R14 - %016lx, R15 - %016lx",
758 SystemContext
.SystemContextX64
->R14
,
759 SystemContext
.SystemContextX64
->R15
761 VideoBuffer
+= COLUMN_MAX
;
763 UnicodeSPrintAsciiFormat (
765 COLUMN_MAX
* sizeof (CHAR16
),
766 "DS - %016lx, ES - %016lx, FS - %016lx",
767 SystemContext
.SystemContextX64
->Ds
,
768 SystemContext
.SystemContextX64
->Es
,
769 SystemContext
.SystemContextX64
->Fs
771 VideoBuffer
+= COLUMN_MAX
;
773 UnicodeSPrintAsciiFormat (
775 COLUMN_MAX
* sizeof (CHAR16
),
776 "GS - %016lx, SS - %016lx",
777 SystemContext
.SystemContextX64
->Gs
,
778 SystemContext
.SystemContextX64
->Ss
780 VideoBuffer
+= COLUMN_MAX
;
782 UnicodeSPrintAsciiFormat (
784 COLUMN_MAX
* sizeof (CHAR16
),
785 "GDTR - %016lx %016lx, LDTR - %016lx",
786 SystemContext
.SystemContextX64
->Gdtr
[0],
787 SystemContext
.SystemContextX64
->Gdtr
[1],
788 SystemContext
.SystemContextX64
->Ldtr
790 VideoBuffer
+= COLUMN_MAX
;
792 UnicodeSPrintAsciiFormat (
794 COLUMN_MAX
* sizeof (CHAR16
),
795 "IDTR - %016lx %016lx, TR - %016lx",
796 SystemContext
.SystemContextX64
->Idtr
[0],
797 SystemContext
.SystemContextX64
->Idtr
[1],
798 SystemContext
.SystemContextX64
->Tr
800 VideoBuffer
+= COLUMN_MAX
;
802 UnicodeSPrintAsciiFormat (
804 COLUMN_MAX
* sizeof (CHAR16
),
805 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx",
806 SystemContext
.SystemContextX64
->Cr0
,
807 SystemContext
.SystemContextX64
->Cr2
,
808 SystemContext
.SystemContextX64
->Cr3
810 VideoBuffer
+= COLUMN_MAX
;
812 UnicodeSPrintAsciiFormat (
814 COLUMN_MAX
* sizeof (CHAR16
),
815 "CR4 - %016lx, CR8 - %016lx",
816 SystemContext
.SystemContextX64
->Cr4
,
817 SystemContext
.SystemContextX64
->Cr8
819 VideoBuffer
+= COLUMN_MAX
;
821 UnicodeSPrintAsciiFormat (
823 COLUMN_MAX
* sizeof (CHAR16
),
824 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx",
825 SystemContext
.SystemContextX64
->Dr0
,
826 SystemContext
.SystemContextX64
->Dr1
,
827 SystemContext
.SystemContextX64
->Dr2
829 VideoBuffer
+= COLUMN_MAX
;
831 UnicodeSPrintAsciiFormat (
833 COLUMN_MAX
* sizeof (CHAR16
),
834 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx",
835 SystemContext
.SystemContextX64
->Dr3
,
836 SystemContext
.SystemContextX64
->Dr6
,
837 SystemContext
.SystemContextX64
->Dr7
839 VideoBuffer
+= COLUMN_MAX
;
842 for (Index
= 0; Index
< COLUMN_MAX
* ROW_MAX
; Index
++) {
843 if (Index
> (UINTN
)(VideoBuffer
- VideoBufferBase
)) {
844 VideoBufferBase
[Index
] = 0x0c20;
846 VideoBufferBase
[Index
] |= 0x0c00;
853 #if CPU_EXCEPTION_VGA_SWITCH
860 Switch Video Mode from current mode to new mode, and return the old mode.
864 NewVideoMode - new video mode want to set
867 UINT16 - (UINT16) -1 indicates failure
868 Other value indicates the old mode, which can be used for restore later
873 EFI_LEGACY_BIOS_THUNK_PROTOCOL
*LegacyBios
;
874 EFI_IA32_REGISTER_SET Regs
;
875 UINT16 OriginalVideoMode
= (UINT16
) -1;
879 // VESA SuperVGA BIOS - GET CURRENT VIDEO MODE
881 // Return:AL = 4Fh if function supported
882 // AH = status 00h successful
883 // BX = video mode (see #0082,#0083)
885 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
887 LegacyBiosInt86 (0x10, &Regs
);
888 if (Regs
.X
.AX
== 0x004F) {
889 OriginalVideoMode
= Regs
.X
.BX
;
892 // VIDEO - GET CURRENT VIDEO MODE
894 // Return:AH = number of character columns
895 // AL = display mode (see #0009 at AH=00h)
896 // BH = active page (see AH=05h)
898 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
900 LegacyBiosInt86 (0x10, &Regs
);
901 OriginalVideoMode
= Regs
.H
.AL
;
905 // Set new video mode
907 if (NewVideoMode
< 0x100) {
909 // Set the 80x25 Text VGA Mode: Assume successful always
911 // VIDEO - SET VIDEO MODE
913 // AL = desired video mode (see #0009)
914 // Return:AL = video mode flag (Phoenix, AMI BIOS)
916 // 30h modes 0-5 and 7
918 // AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)
920 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
922 Regs
.H
.AL
= (UINT8
) NewVideoMode
;
923 LegacyBiosInt86 (0x10, &Regs
);
926 // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
928 // BL = block to load
931 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
935 LegacyBiosInt86 (0x10, &Regs
);
938 // VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE
940 // BX = mode (see #0082,#0083)
941 // bit 15 set means don't clear video memory
942 // bit 14 set means enable linear framebuffer mode (VBE v2.0+)
943 // Return:AL = 4Fh if function supported
948 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
950 Regs
.X
.BX
= NewVideoMode
;
951 LegacyBiosInt86 (0x10, &Regs
);
952 if (Regs
.X
.AX
!= 0x004F) {
953 DEBUG ((EFI_D_ERROR
, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode
));
958 return OriginalVideoMode
;
964 IN EFI_EXCEPTION_TYPE InterruptType
,
965 IN EFI_SYSTEM_CONTEXT SystemContext
968 #if CPU_EXCEPTION_VGA_SWITCH
972 #if CPU_EXCEPTION_DEBUG_OUTPUT
973 DumpExceptionDataDebugOut (InterruptType
, SystemContext
);
976 #if CPU_EXCEPTION_VGA_SWITCH
978 // Switch to text mode for RED-SCREEN output
980 VideoMode
= SwitchVideoMode (0x83);
981 if (VideoMode
== (UINT16
) -1) {
982 DEBUG ((EFI_D_ERROR
, "Video Mode Unknown!\n"));
986 DumpExceptionDataVgaOut (InterruptType
, SystemContext
);
989 // Use this macro to hang so that the compiler does not optimize out
990 // the following RET instructions. This allows us to return if we
991 // have a debugger attached.
995 #if CPU_EXCEPTION_VGA_SWITCH
997 // Switch back to the old video mode
999 if (VideoMode
!= (UINT16
)-1) {
1000 SwitchVideoMode (VideoMode
);
1009 IN EFI_EXCEPTION_TYPE InterruptType
,
1010 IN EFI_SYSTEM_CONTEXT SystemContext
1013 if (mTimerHandler
!= NULL
) {
1014 mTimerHandler (InterruptType
, SystemContext
);
1021 IN EFI_HANDLE ImageHandle
,
1022 IN EFI_SYSTEM_TABLE
*SystemTable
1026 Routine Description:
1027 Initialize the state information for the CPU Architectural Protocol
1030 ImageHandle of the loaded driver
1031 Pointer to the System Table
1034 EFI_SUCCESS - thread can be successfully created
1035 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
1036 EFI_DEVICE_ERROR - cannot create the thread
1042 UINT32 InterruptVector
;
1045 // Find the Legacy8259 protocol.
1047 Status
= gBS
->LocateProtocol (&gEfiLegacy8259ProtocolGuid
, NULL
, (VOID
**) &gLegacy8259
);
1048 ASSERT_EFI_ERROR (Status
);
1051 // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver
1053 Status
= gLegacy8259
->GetVector (gLegacy8259
, Efi8259Irq0
, (UINT8
*) &mTimerVector
);
1054 ASSERT_EFI_ERROR (Status
);
1062 // Install Exception Handler (0x00 ~ 0x1F)
1064 for (InterruptVector
= 0; InterruptVector
< 0x20; InterruptVector
++) {
1065 InstallInterruptHandler (
1067 (VOID (*)(VOID
))(UINTN
)((UINTN
)SystemExceptionHandler
+ mExceptionCodeSize
* InterruptVector
)
1072 // Install Timer Handler
1074 InstallInterruptHandler (mTimerVector
, SystemTimerHandler
);
1077 // BUGBUG: We add all other interrupt vector
1079 for (Irq
= Efi8259Irq1
; Irq
<= Efi8259Irq15
; Irq
++) {
1080 InterruptVector
= 0;
1081 Status
= gLegacy8259
->GetVector (gLegacy8259
, Irq
, (UINT8
*) &InterruptVector
);
1082 ASSERT_EFI_ERROR (Status
);
1083 InstallInterruptHandler (InterruptVector
, SystemTimerHandler
);
1086 InitializeBiosIntCaller();
1089 // Install CPU Architectural Protocol and the thunk protocol
1092 Status
= gBS
->InstallMultipleProtocolInterfaces (
1094 &gEfiCpuArchProtocolGuid
,
1098 ASSERT_EFI_ERROR (Status
);
1104 InitializeBiosIntCaller (
1109 UINT32 RealModeBufferSize
;
1110 UINT32 ExtraStackSize
;
1111 EFI_PHYSICAL_ADDRESS LegacyRegionBase
;
1116 AsmGetThunk16Properties (&RealModeBufferSize
, &ExtraStackSize
);
1118 LegacyRegionBase
= 0x100000;
1119 Status
= gBS
->AllocatePages (
1122 EFI_SIZE_TO_PAGES(RealModeBufferSize
+ ExtraStackSize
+ 200),
1125 ASSERT_EFI_ERROR (Status
);
1127 mThunkContext
.RealModeBuffer
= (VOID
*)(UINTN
)LegacyRegionBase
;
1128 mThunkContext
.RealModeBufferSize
= EFI_PAGES_TO_SIZE (RealModeBufferSize
);
1129 mThunkContext
.ThunkAttributes
= 3;
1130 AsmPrepareThunk16(&mThunkContext
);
1138 IN EFI_IA32_REGISTER_SET
*Regs
1143 IA32_REGISTER_SET ThunkRegSet
;
1147 Regs
->X
.Flags
.Reserved1
= 1;
1148 Regs
->X
.Flags
.Reserved2
= 0;
1149 Regs
->X
.Flags
.Reserved3
= 0;
1150 Regs
->X
.Flags
.Reserved4
= 0;
1151 Regs
->X
.Flags
.IOPL
= 3;
1152 Regs
->X
.Flags
.NT
= 0;
1153 Regs
->X
.Flags
.IF
= 1;
1154 Regs
->X
.Flags
.TF
= 0;
1155 Regs
->X
.Flags
.CF
= 0;
1157 ZeroMem (&ThunkRegSet
, sizeof (ThunkRegSet
));
1158 ThunkRegSet
.E
.EDI
= Regs
->E
.EDI
;
1159 ThunkRegSet
.E
.ESI
= Regs
->E
.ESI
;
1160 ThunkRegSet
.E
.EBP
= Regs
->E
.EBP
;
1161 ThunkRegSet
.E
.EBX
= Regs
->E
.EBX
;
1162 ThunkRegSet
.E
.EDX
= Regs
->E
.EDX
;
1163 ThunkRegSet
.E
.ECX
= Regs
->E
.ECX
;
1164 ThunkRegSet
.E
.EAX
= Regs
->E
.EAX
;
1165 ThunkRegSet
.E
.DS
= Regs
->E
.DS
;
1166 ThunkRegSet
.E
.ES
= Regs
->E
.ES
;
1168 CopyMem (&(ThunkRegSet
.E
.EFLAGS
), &(Regs
->E
.EFlags
), sizeof (UINT32
));
1171 // The call to Legacy16 is a critical section to EFI
1173 Eflags
= AsmReadEflags ();
1174 if ((Eflags
| EFI_CPU_EFLAGS_IF
) != 0) {
1175 DisableInterrupts ();
1179 // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.
1181 Status
= gLegacy8259
->SetMode (gLegacy8259
, Efi8259LegacyMode
, NULL
, NULL
);
1182 ASSERT_EFI_ERROR (Status
);
1184 Stack16
= (UINT16
*)((UINT8
*) mThunkContext
.RealModeBuffer
+ mThunkContext
.RealModeBufferSize
- sizeof (UINT16
));
1185 Stack16
-= sizeof (ThunkRegSet
.E
.EFLAGS
) / sizeof (UINT16
);
1186 CopyMem (Stack16
, &ThunkRegSet
.E
.EFLAGS
, sizeof (ThunkRegSet
.E
.EFLAGS
));
1188 ThunkRegSet
.E
.SS
= (UINT16
) (((UINTN
) Stack16
>> 16) << 12);
1189 ThunkRegSet
.E
.ESP
= (UINT16
) (UINTN
) Stack16
;
1190 ThunkRegSet
.E
.Eip
= (UINT16
)((UINT32
*)NULL
)[BiosInt
];
1191 ThunkRegSet
.E
.CS
= (UINT16
)(((UINT32
*)NULL
)[BiosInt
] >> 16);
1192 mThunkContext
.RealModeState
= &ThunkRegSet
;
1193 AsmThunk16 (&mThunkContext
);
1196 // Restore protected mode interrupt state
1198 Status
= gLegacy8259
->SetMode (gLegacy8259
, Efi8259ProtectedMode
, NULL
, NULL
);
1199 ASSERT_EFI_ERROR (Status
);
1202 // End critical section
1204 if ((Eflags
| EFI_CPU_EFLAGS_IF
) != 0) {
1205 EnableInterrupts ();
1208 Regs
->E
.EDI
= ThunkRegSet
.E
.EDI
;
1209 Regs
->E
.ESI
= ThunkRegSet
.E
.ESI
;
1210 Regs
->E
.EBP
= ThunkRegSet
.E
.EBP
;
1211 Regs
->E
.EBX
= ThunkRegSet
.E
.EBX
;
1212 Regs
->E
.EDX
= ThunkRegSet
.E
.EDX
;
1213 Regs
->E
.ECX
= ThunkRegSet
.E
.ECX
;
1214 Regs
->E
.EAX
= ThunkRegSet
.E
.EAX
;
1215 Regs
->E
.SS
= ThunkRegSet
.E
.SS
;
1216 Regs
->E
.CS
= ThunkRegSet
.E
.CS
;
1217 Regs
->E
.DS
= ThunkRegSet
.E
.DS
;
1218 Regs
->E
.ES
= ThunkRegSet
.E
.ES
;
1220 CopyMem (&(Regs
->E
.EFlags
), &(ThunkRegSet
.E
.EFLAGS
), sizeof (UINT32
));
1222 Ret
= (BOOLEAN
) (Regs
->E
.EFlags
.CF
== 1);