3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. 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 IN OUT CHAR16
*Buffer
,
549 IN CONST CHAR16
*Format
,
559 VA_START (Marker
, Format
);
562 // Process the format string. Stop if Buffer is over run.
565 for (Index
= 0; *Format
!= 0; Format
++) {
566 if (*Format
!= L
'%') {
567 Buffer
[Index
++] = *Format
;
571 // Now it's time to parse what follows after %
572 // Support: % [ 0 width ] [ l ] x
573 // width - fill 0, to ensure the width of x will be "width"
574 // l - UINT64 instead of UINT32
580 if (*Format
== L
'0') {
581 Flags
|= PREFIX_ZERO
;
583 Width
+= Width
* 10 + (*Format
- L
'0');
585 } while (*Format
>= L
'1' && *Format
<= L
'9');
588 if (*Format
== L
'l') {
596 Flags
|= PREFIX_ZERO
;
597 Width
= sizeof (UINT64
) * 2;
599 // break skiped on purpose
602 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
603 Value
= VA_ARG (Marker
, UINT64
);
605 Value
= VA_ARG (Marker
, UINTN
);
608 UnicodeValueToString (Buffer
+Index
, Flags
, Value
, Width
);
610 for ( ; Buffer
[Index
] != L
'\0'; Index
++) {
617 // if the type is unknown print it to the screen
619 Buffer
[Index
++] = *Format
;
623 Buffer
[Index
++] = '\0';
630 DumpExceptionDataVgaOut (
631 IN EFI_EXCEPTION_TYPE InterruptType
,
632 IN EFI_SYSTEM_CONTEXT SystemContext
637 UINT32 ErrorCodeFlag
;
638 CHAR16
*VideoBufferBase
;
644 ErrorCodeFlag
= 0x00027d00;
645 VideoBufferBase
= (CHAR16
*) (UINTN
) 0xb8000;
646 VideoBuffer
= (CHAR16
*) (UINTN
) 0xb8000;
651 L
"!!!! IA32 Exception Type - %08x !!!!",
654 VideoBuffer
+= COLUMN_MAX
;
657 L
"EIP - %08x, CS - %08x, EFLAGS - %08x",
658 SystemContext
.SystemContextIa32
->Eip
,
659 SystemContext
.SystemContextIa32
->Cs
,
660 SystemContext
.SystemContextIa32
->Eflags
662 VideoBuffer
+= COLUMN_MAX
;
663 if (ErrorCodeFlag
& (1 << InterruptType
)) {
666 L
"ExceptionData - %08x",
667 SystemContext
.SystemContextIa32
->ExceptionData
669 VideoBuffer
+= COLUMN_MAX
;
673 L
"EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x",
674 SystemContext
.SystemContextIa32
->Eax
,
675 SystemContext
.SystemContextIa32
->Ecx
,
676 SystemContext
.SystemContextIa32
->Edx
,
677 SystemContext
.SystemContextIa32
->Ebx
679 VideoBuffer
+= COLUMN_MAX
;
683 L
"ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x",
684 SystemContext
.SystemContextIa32
->Esp
,
685 SystemContext
.SystemContextIa32
->Ebp
,
686 SystemContext
.SystemContextIa32
->Esi
,
687 SystemContext
.SystemContextIa32
->Edi
689 VideoBuffer
+= COLUMN_MAX
;
693 L
"DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x",
694 SystemContext
.SystemContextIa32
->Ds
,
695 SystemContext
.SystemContextIa32
->Es
,
696 SystemContext
.SystemContextIa32
->Fs
,
697 SystemContext
.SystemContextIa32
->Gs
,
698 SystemContext
.SystemContextIa32
->Ss
700 VideoBuffer
+= COLUMN_MAX
;
704 L
"GDTR - %08x %08x, IDTR - %08x %08x",
705 SystemContext
.SystemContextIa32
->Gdtr
[0],
706 SystemContext
.SystemContextIa32
->Gdtr
[1],
707 SystemContext
.SystemContextIa32
->Idtr
[0],
708 SystemContext
.SystemContextIa32
->Idtr
[1]
710 VideoBuffer
+= COLUMN_MAX
;
714 L
"LDTR - %08x, TR - %08x",
715 SystemContext
.SystemContextIa32
->Ldtr
,
716 SystemContext
.SystemContextIa32
->Tr
718 VideoBuffer
+= COLUMN_MAX
;
722 L
"CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x",
723 SystemContext
.SystemContextIa32
->Cr0
,
724 SystemContext
.SystemContextIa32
->Cr2
,
725 SystemContext
.SystemContextIa32
->Cr3
,
726 SystemContext
.SystemContextIa32
->Cr4
728 VideoBuffer
+= COLUMN_MAX
;
732 L
"DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x",
733 SystemContext
.SystemContextIa32
->Dr0
,
734 SystemContext
.SystemContextIa32
->Dr1
,
735 SystemContext
.SystemContextIa32
->Dr2
,
736 SystemContext
.SystemContextIa32
->Dr3
738 VideoBuffer
+= COLUMN_MAX
;
742 L
"DR6 - %08x, DR7 - %08x",
743 SystemContext
.SystemContextIa32
->Dr6
,
744 SystemContext
.SystemContextIa32
->Dr7
746 VideoBuffer
+= COLUMN_MAX
;
750 L
"!!!! X64 Exception Type - %016lx !!!!",
751 (UINT64
)InterruptType
753 VideoBuffer
+= COLUMN_MAX
;
757 L
"RIP - %016lx, CS - %016lx, RFLAGS - %016lx",
758 SystemContext
.SystemContextX64
->Rip
,
759 SystemContext
.SystemContextX64
->Cs
,
760 SystemContext
.SystemContextX64
->Rflags
762 VideoBuffer
+= COLUMN_MAX
;
764 if (ErrorCodeFlag
& (1 << InterruptType
)) {
767 L
"ExceptionData - %016lx",
768 SystemContext
.SystemContextX64
->ExceptionData
770 VideoBuffer
+= COLUMN_MAX
;
775 L
"RAX - %016lx, RCX - %016lx, RDX - %016lx",
776 SystemContext
.SystemContextX64
->Rax
,
777 SystemContext
.SystemContextX64
->Rcx
,
778 SystemContext
.SystemContextX64
->Rdx
780 VideoBuffer
+= COLUMN_MAX
;
784 L
"RBX - %016lx, RSP - %016lx, RBP - %016lx",
785 SystemContext
.SystemContextX64
->Rbx
,
786 SystemContext
.SystemContextX64
->Rsp
,
787 SystemContext
.SystemContextX64
->Rbp
789 VideoBuffer
+= COLUMN_MAX
;
793 L
"RSI - %016lx, RDI - %016lx",
794 SystemContext
.SystemContextX64
->Rsi
,
795 SystemContext
.SystemContextX64
->Rdi
797 VideoBuffer
+= COLUMN_MAX
;
801 L
"R8 - %016lx, R9 - %016lx, R10 - %016lx",
802 SystemContext
.SystemContextX64
->R8
,
803 SystemContext
.SystemContextX64
->R9
,
804 SystemContext
.SystemContextX64
->R10
806 VideoBuffer
+= COLUMN_MAX
;
810 L
"R11 - %016lx, R12 - %016lx, R13 - %016lx",
811 SystemContext
.SystemContextX64
->R11
,
812 SystemContext
.SystemContextX64
->R12
,
813 SystemContext
.SystemContextX64
->R13
815 VideoBuffer
+= COLUMN_MAX
;
819 L
"R14 - %016lx, R15 - %016lx",
820 SystemContext
.SystemContextX64
->R14
,
821 SystemContext
.SystemContextX64
->R15
823 VideoBuffer
+= COLUMN_MAX
;
827 L
"DS - %016lx, ES - %016lx, FS - %016lx",
828 SystemContext
.SystemContextX64
->Ds
,
829 SystemContext
.SystemContextX64
->Es
,
830 SystemContext
.SystemContextX64
->Fs
832 VideoBuffer
+= COLUMN_MAX
;
836 L
"GS - %016lx, SS - %016lx",
837 SystemContext
.SystemContextX64
->Gs
,
838 SystemContext
.SystemContextX64
->Ss
840 VideoBuffer
+= COLUMN_MAX
;
844 L
"GDTR - %016lx %016lx, LDTR - %016lx",
845 SystemContext
.SystemContextX64
->Gdtr
[0],
846 SystemContext
.SystemContextX64
->Gdtr
[1],
847 SystemContext
.SystemContextX64
->Ldtr
849 VideoBuffer
+= COLUMN_MAX
;
853 L
"IDTR - %016lx %016lx, TR - %016lx",
854 SystemContext
.SystemContextX64
->Idtr
[0],
855 SystemContext
.SystemContextX64
->Idtr
[1],
856 SystemContext
.SystemContextX64
->Tr
858 VideoBuffer
+= COLUMN_MAX
;
862 L
"CR0 - %016lx, CR2 - %016lx, CR3 - %016lx",
863 SystemContext
.SystemContextX64
->Cr0
,
864 SystemContext
.SystemContextX64
->Cr2
,
865 SystemContext
.SystemContextX64
->Cr3
867 VideoBuffer
+= COLUMN_MAX
;
871 L
"CR4 - %016lx, CR8 - %016lx",
872 SystemContext
.SystemContextX64
->Cr4
,
873 SystemContext
.SystemContextX64
->Cr8
875 VideoBuffer
+= COLUMN_MAX
;
879 L
"DR0 - %016lx, DR1 - %016lx, DR2 - %016lx",
880 SystemContext
.SystemContextX64
->Dr0
,
881 SystemContext
.SystemContextX64
->Dr1
,
882 SystemContext
.SystemContextX64
->Dr2
884 VideoBuffer
+= COLUMN_MAX
;
888 L
"DR3 - %016lx, DR6 - %016lx, DR7 - %016lx",
889 SystemContext
.SystemContextX64
->Dr3
,
890 SystemContext
.SystemContextX64
->Dr6
,
891 SystemContext
.SystemContextX64
->Dr7
893 VideoBuffer
+= COLUMN_MAX
;
896 for (Index
= 0; Index
< COLUMN_MAX
* ROW_MAX
; Index
++) {
897 if (Index
> (UINTN
)(VideoBuffer
- VideoBufferBase
)) {
898 VideoBufferBase
[Index
] = 0x0c20;
900 VideoBufferBase
[Index
] |= 0x0c00;
907 #if CPU_EXCEPTION_VGA_SWITCH
914 Switch Video Mode from current mode to new mode, and return the old mode.
918 NewVideoMode - new video mode want to set
921 UINT16 - (UINT16) -1 indicates failure
922 Other value indicates the old mode, which can be used for restore later
927 EFI_LEGACY_BIOS_THUNK_PROTOCOL
*LegacyBios
;
928 EFI_IA32_REGISTER_SET Regs
;
929 UINT16 OriginalVideoMode
= (UINT16
) -1;
933 // VESA SuperVGA BIOS - GET CURRENT VIDEO MODE
935 // Return:AL = 4Fh if function supported
936 // AH = status 00h successful
937 // BX = video mode (see #0082,#0083)
939 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
941 LegacyBiosInt86 (0x10, &Regs
);
942 if (Regs
.X
.AX
== 0x004F) {
943 OriginalVideoMode
= Regs
.X
.BX
;
946 // VIDEO - GET CURRENT VIDEO MODE
948 // Return:AH = number of character columns
949 // AL = display mode (see #0009 at AH=00h)
950 // BH = active page (see AH=05h)
952 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
954 LegacyBiosInt86 (0x10, &Regs
);
955 OriginalVideoMode
= Regs
.H
.AL
;
959 // Set new video mode
961 if (NewVideoMode
< 0x100) {
963 // Set the 80x25 Text VGA Mode: Assume successful always
965 // VIDEO - SET VIDEO MODE
967 // AL = desired video mode (see #0009)
968 // Return:AL = video mode flag (Phoenix, AMI BIOS)
970 // 30h modes 0-5 and 7
972 // AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)
974 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
976 Regs
.H
.AL
= (UINT8
) NewVideoMode
;
977 LegacyBiosInt86 (0x10, &Regs
);
980 // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
982 // BL = block to load
985 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
989 LegacyBiosInt86 (0x10, &Regs
);
992 // VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE
994 // BX = mode (see #0082,#0083)
995 // bit 15 set means don't clear video memory
996 // bit 14 set means enable linear framebuffer mode (VBE v2.0+)
997 // Return:AL = 4Fh if function supported
1002 gBS
->SetMem (&Regs
, sizeof (Regs
), 0);
1004 Regs
.X
.BX
= NewVideoMode
;
1005 LegacyBiosInt86 (0x10, &Regs
);
1006 if (Regs
.X
.AX
!= 0x004F) {
1007 DEBUG ((EFI_D_ERROR
, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode
));
1012 return OriginalVideoMode
;
1018 IN EFI_EXCEPTION_TYPE InterruptType
,
1019 IN EFI_SYSTEM_CONTEXT SystemContext
1022 #if CPU_EXCEPTION_VGA_SWITCH
1026 #if CPU_EXCEPTION_DEBUG_OUTPUT
1027 DumpExceptionDataDebugOut (InterruptType
, SystemContext
);
1030 #if CPU_EXCEPTION_VGA_SWITCH
1032 // Switch to text mode for RED-SCREEN output
1034 VideoMode
= SwitchVideoMode (0x83);
1035 if (VideoMode
== (UINT16
) -1) {
1036 DEBUG ((EFI_D_ERROR
, "Video Mode Unknown!\n"));
1040 DumpExceptionDataVgaOut (InterruptType
, SystemContext
);
1043 // Use this macro to hang so that the compiler does not optimize out
1044 // the following RET instructions. This allows us to return if we
1045 // have a debugger attached.
1049 #if CPU_EXCEPTION_VGA_SWITCH
1051 // Switch back to the old video mode
1053 if (VideoMode
!= (UINT16
)-1) {
1054 SwitchVideoMode (VideoMode
);
1063 IN EFI_EXCEPTION_TYPE InterruptType
,
1064 IN EFI_SYSTEM_CONTEXT SystemContext
1067 if (mTimerHandler
!= NULL
) {
1068 mTimerHandler (InterruptType
, SystemContext
);
1075 IN EFI_HANDLE ImageHandle
,
1076 IN EFI_SYSTEM_TABLE
*SystemTable
1080 Routine Description:
1081 Initialize the state information for the CPU Architectural Protocol
1084 ImageHandle of the loaded driver
1085 Pointer to the System Table
1088 EFI_SUCCESS - thread can be successfully created
1089 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
1090 EFI_DEVICE_ERROR - cannot create the thread
1096 UINT32 InterruptVector
;
1099 // Find the Legacy8259 protocol.
1101 Status
= gBS
->LocateProtocol (&gEfiLegacy8259ProtocolGuid
, NULL
, (VOID
**) &gLegacy8259
);
1102 ASSERT_EFI_ERROR (Status
);
1105 // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver
1107 Status
= gLegacy8259
->GetVector (gLegacy8259
, Efi8259Irq0
, (UINT8
*) &mTimerVector
);
1108 ASSERT_EFI_ERROR (Status
);
1116 // Install Exception Handler (0x00 ~ 0x1F)
1118 for (InterruptVector
= 0; InterruptVector
< 0x20; InterruptVector
++) {
1119 InstallInterruptHandler (
1121 (VOID (*)(VOID
))(UINTN
)((UINTN
)SystemExceptionHandler
+ mExceptionCodeSize
* InterruptVector
)
1126 // Install Timer Handler
1128 InstallInterruptHandler (mTimerVector
, SystemTimerHandler
);
1131 // BUGBUG: We add all other interrupt vector
1133 for (Irq
= Efi8259Irq1
; Irq
<= Efi8259Irq15
; Irq
++) {
1134 InterruptVector
= 0;
1135 Status
= gLegacy8259
->GetVector (gLegacy8259
, Irq
, (UINT8
*) &InterruptVector
);
1136 ASSERT_EFI_ERROR (Status
);
1137 InstallInterruptHandler (InterruptVector
, SystemTimerHandler
);
1140 InitializeBiosIntCaller();
1143 // Install CPU Architectural Protocol and the thunk protocol
1146 Status
= gBS
->InstallMultipleProtocolInterfaces (
1148 &gEfiCpuArchProtocolGuid
,
1152 ASSERT_EFI_ERROR (Status
);
1158 InitializeBiosIntCaller (
1163 UINT32 RealModeBufferSize
;
1164 UINT32 ExtraStackSize
;
1165 EFI_PHYSICAL_ADDRESS LegacyRegionBase
;
1170 AsmGetThunk16Properties (&RealModeBufferSize
, &ExtraStackSize
);
1172 LegacyRegionBase
= 0x100000;
1173 Status
= gBS
->AllocatePages (
1176 EFI_SIZE_TO_PAGES(RealModeBufferSize
+ ExtraStackSize
+ 200),
1179 ASSERT_EFI_ERROR (Status
);
1181 mThunkContext
.RealModeBuffer
= (VOID
*)(UINTN
)LegacyRegionBase
;
1182 mThunkContext
.RealModeBufferSize
= EFI_PAGES_TO_SIZE (RealModeBufferSize
);
1183 mThunkContext
.ThunkAttributes
= 3;
1184 AsmPrepareThunk16(&mThunkContext
);
1192 IN EFI_IA32_REGISTER_SET
*Regs
1197 IA32_REGISTER_SET ThunkRegSet
;
1201 Regs
->X
.Flags
.Reserved1
= 1;
1202 Regs
->X
.Flags
.Reserved2
= 0;
1203 Regs
->X
.Flags
.Reserved3
= 0;
1204 Regs
->X
.Flags
.Reserved4
= 0;
1205 Regs
->X
.Flags
.IOPL
= 3;
1206 Regs
->X
.Flags
.NT
= 0;
1207 Regs
->X
.Flags
.IF
= 1;
1208 Regs
->X
.Flags
.TF
= 0;
1209 Regs
->X
.Flags
.CF
= 0;
1211 ZeroMem (&ThunkRegSet
, sizeof (ThunkRegSet
));
1212 ThunkRegSet
.E
.EDI
= Regs
->E
.EDI
;
1213 ThunkRegSet
.E
.ESI
= Regs
->E
.ESI
;
1214 ThunkRegSet
.E
.EBP
= Regs
->E
.EBP
;
1215 ThunkRegSet
.E
.EBX
= Regs
->E
.EBX
;
1216 ThunkRegSet
.E
.EDX
= Regs
->E
.EDX
;
1217 ThunkRegSet
.E
.ECX
= Regs
->E
.ECX
;
1218 ThunkRegSet
.E
.EAX
= Regs
->E
.EAX
;
1219 ThunkRegSet
.E
.DS
= Regs
->E
.DS
;
1220 ThunkRegSet
.E
.ES
= Regs
->E
.ES
;
1222 CopyMem (&(ThunkRegSet
.E
.EFLAGS
), &(Regs
->E
.EFlags
), sizeof (UINT32
));
1225 // The call to Legacy16 is a critical section to EFI
1227 Eflags
= AsmReadEflags ();
1228 if ((Eflags
| EFI_CPU_EFLAGS_IF
) != 0) {
1229 DisableInterrupts ();
1233 // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.
1235 Status
= gLegacy8259
->SetMode (gLegacy8259
, Efi8259LegacyMode
, NULL
, NULL
);
1236 ASSERT_EFI_ERROR (Status
);
1238 Stack16
= (UINT16
*)((UINT8
*) mThunkContext
.RealModeBuffer
+ mThunkContext
.RealModeBufferSize
- sizeof (UINT16
));
1239 Stack16
-= sizeof (ThunkRegSet
.E
.EFLAGS
) / sizeof (UINT16
);
1240 CopyMem (Stack16
, &ThunkRegSet
.E
.EFLAGS
, sizeof (ThunkRegSet
.E
.EFLAGS
));
1242 ThunkRegSet
.E
.SS
= (UINT16
) (((UINTN
) Stack16
>> 16) << 12);
1243 ThunkRegSet
.E
.ESP
= (UINT16
) (UINTN
) Stack16
;
1244 ThunkRegSet
.E
.Eip
= (UINT16
)((UINT32
*)NULL
)[BiosInt
];
1245 ThunkRegSet
.E
.CS
= (UINT16
)(((UINT32
*)NULL
)[BiosInt
] >> 16);
1246 mThunkContext
.RealModeState
= &ThunkRegSet
;
1247 AsmThunk16 (&mThunkContext
);
1250 // Restore protected mode interrupt state
1252 Status
= gLegacy8259
->SetMode (gLegacy8259
, Efi8259ProtectedMode
, NULL
, NULL
);
1253 ASSERT_EFI_ERROR (Status
);
1256 // End critical section
1258 if ((Eflags
| EFI_CPU_EFLAGS_IF
) != 0) {
1259 EnableInterrupts ();
1262 Regs
->E
.EDI
= ThunkRegSet
.E
.EDI
;
1263 Regs
->E
.ESI
= ThunkRegSet
.E
.ESI
;
1264 Regs
->E
.EBP
= ThunkRegSet
.E
.EBP
;
1265 Regs
->E
.EBX
= ThunkRegSet
.E
.EBX
;
1266 Regs
->E
.EDX
= ThunkRegSet
.E
.EDX
;
1267 Regs
->E
.ECX
= ThunkRegSet
.E
.ECX
;
1268 Regs
->E
.EAX
= ThunkRegSet
.E
.EAX
;
1269 Regs
->E
.SS
= ThunkRegSet
.E
.SS
;
1270 Regs
->E
.CS
= ThunkRegSet
.E
.CS
;
1271 Regs
->E
.DS
= ThunkRegSet
.E
.DS
;
1272 Regs
->E
.ES
= ThunkRegSet
.E
.ES
;
1274 CopyMem (&(Regs
->E
.EFlags
), &(ThunkRegSet
.E
.EFLAGS
), sizeof (UINT32
));
1276 Ret
= (BOOLEAN
) (Regs
->E
.EFlags
.CF
== 1);