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