]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/CpuDxe/Cpu.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[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
c69dd9df 322VOID\r
323DumpExceptionDataDebugOut (\r
324 IN EFI_EXCEPTION_TYPE InterruptType,\r
325 IN EFI_SYSTEM_CONTEXT SystemContext\r
326 )\r
327{\r
328 UINT32 ErrorCodeFlag;\r
329\r
330 ErrorCodeFlag = 0x00027d00;\r
331\r
332#ifdef EFI32\r
333 DEBUG ((\r
334 EFI_D_ERROR,\r
335 "!!!! IA32 Exception Type - %08x !!!!\n",\r
336 InterruptType\r
337 ));\r
338 DEBUG ((\r
339 EFI_D_ERROR,\r
340 "EIP - %08x, CS - %08x, EFLAGS - %08x\n",\r
341 SystemContext.SystemContextIa32->Eip,\r
342 SystemContext.SystemContextIa32->Cs,\r
343 SystemContext.SystemContextIa32->Eflags\r
344 ));\r
345 if (ErrorCodeFlag & (1 << InterruptType)) {\r
346 DEBUG ((\r
347 EFI_D_ERROR,\r
348 "ExceptionData - %08x\n",\r
349 SystemContext.SystemContextIa32->ExceptionData\r
350 ));\r
351 }\r
352 DEBUG ((\r
353 EFI_D_ERROR,\r
354 "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",\r
355 SystemContext.SystemContextIa32->Eax,\r
356 SystemContext.SystemContextIa32->Ecx,\r
357 SystemContext.SystemContextIa32->Edx,\r
358 SystemContext.SystemContextIa32->Ebx\r
359 ));\r
360 DEBUG ((\r
361 EFI_D_ERROR,\r
362 "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",\r
363 SystemContext.SystemContextIa32->Esp,\r
364 SystemContext.SystemContextIa32->Ebp,\r
365 SystemContext.SystemContextIa32->Esi,\r
366 SystemContext.SystemContextIa32->Edi\r
367 ));\r
368 DEBUG ((\r
369 EFI_D_ERROR,\r
370 "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x\n",\r
371 SystemContext.SystemContextIa32->Ds,\r
372 SystemContext.SystemContextIa32->Es,\r
373 SystemContext.SystemContextIa32->Fs,\r
374 SystemContext.SystemContextIa32->Gs,\r
375 SystemContext.SystemContextIa32->Ss\r
376 ));\r
377 DEBUG ((\r
378 EFI_D_ERROR,\r
379 "GDTR - %08x %08x, IDTR - %08x %08x\n",\r
380 SystemContext.SystemContextIa32->Gdtr[0],\r
381 SystemContext.SystemContextIa32->Gdtr[1],\r
382 SystemContext.SystemContextIa32->Idtr[0],\r
383 SystemContext.SystemContextIa32->Idtr[1]\r
384 ));\r
385 DEBUG ((\r
386 EFI_D_ERROR,\r
387 "LDTR - %08x, TR - %08x\n",\r
388 SystemContext.SystemContextIa32->Ldtr,\r
389 SystemContext.SystemContextIa32->Tr\r
390 ));\r
391 DEBUG ((\r
392 EFI_D_ERROR,\r
393 "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",\r
394 SystemContext.SystemContextIa32->Cr0,\r
395 SystemContext.SystemContextIa32->Cr2,\r
396 SystemContext.SystemContextIa32->Cr3,\r
397 SystemContext.SystemContextIa32->Cr4\r
398 ));\r
399 DEBUG ((\r
400 EFI_D_ERROR,\r
401 "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",\r
402 SystemContext.SystemContextIa32->Dr0,\r
403 SystemContext.SystemContextIa32->Dr1,\r
404 SystemContext.SystemContextIa32->Dr2,\r
405 SystemContext.SystemContextIa32->Dr3\r
406 ));\r
407 DEBUG ((\r
408 EFI_D_ERROR,\r
409 "DR6 - %08x, DR7 - %08x\n",\r
410 SystemContext.SystemContextIa32->Dr6,\r
411 SystemContext.SystemContextIa32->Dr7\r
412 ));\r
413#else\r
414 DEBUG ((\r
415 EFI_D_ERROR,\r
416 "!!!! X64 Exception Type - %016lx !!!!\n",\r
417 (UINT64)InterruptType\r
418 ));\r
419 DEBUG ((\r
420 EFI_D_ERROR,\r
421 "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",\r
422 SystemContext.SystemContextX64->Rip,\r
423 SystemContext.SystemContextX64->Cs,\r
424 SystemContext.SystemContextX64->Rflags\r
425 ));\r
426 if (ErrorCodeFlag & (1 << InterruptType)) {\r
427 DEBUG ((\r
428 EFI_D_ERROR,\r
429 "ExceptionData - %016lx\n",\r
430 SystemContext.SystemContextX64->ExceptionData\r
431 ));\r
432 }\r
433 DEBUG ((\r
434 EFI_D_ERROR,\r
435 "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",\r
436 SystemContext.SystemContextX64->Rax,\r
437 SystemContext.SystemContextX64->Rcx,\r
438 SystemContext.SystemContextX64->Rdx\r
439 ));\r
440 DEBUG ((\r
441 EFI_D_ERROR,\r
442 "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",\r
443 SystemContext.SystemContextX64->Rbx,\r
444 SystemContext.SystemContextX64->Rsp,\r
445 SystemContext.SystemContextX64->Rbp\r
446 ));\r
447 DEBUG ((\r
448 EFI_D_ERROR,\r
449 "RSI - %016lx, RDI - %016lx\n",\r
450 SystemContext.SystemContextX64->Rsi,\r
451 SystemContext.SystemContextX64->Rdi\r
452 ));\r
453 DEBUG ((\r
454 EFI_D_ERROR,\r
455 "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",\r
456 SystemContext.SystemContextX64->R8,\r
457 SystemContext.SystemContextX64->R9,\r
458 SystemContext.SystemContextX64->R10\r
459 ));\r
460 DEBUG ((\r
461 EFI_D_ERROR,\r
462 "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",\r
463 SystemContext.SystemContextX64->R11,\r
464 SystemContext.SystemContextX64->R12,\r
465 SystemContext.SystemContextX64->R13\r
466 ));\r
467 DEBUG ((\r
468 EFI_D_ERROR,\r
469 "R14 - %016lx, R15 - %016lx\n",\r
470 SystemContext.SystemContextX64->R14,\r
471 SystemContext.SystemContextX64->R15\r
472 ));\r
473 DEBUG ((\r
474 EFI_D_ERROR,\r
475 "DS - %016lx, ES - %016lx, FS - %016lx\n",\r
476 SystemContext.SystemContextX64->Ds,\r
477 SystemContext.SystemContextX64->Es,\r
478 SystemContext.SystemContextX64->Fs\r
479 ));\r
480 DEBUG ((\r
481 EFI_D_ERROR,\r
482 "GS - %016lx, SS - %016lx\n",\r
483 SystemContext.SystemContextX64->Gs,\r
484 SystemContext.SystemContextX64->Ss\r
485 ));\r
486 DEBUG ((\r
487 EFI_D_ERROR,\r
488 "GDTR - %016lx %016lx, LDTR - %016lx\n",\r
489 SystemContext.SystemContextX64->Gdtr[0],\r
490 SystemContext.SystemContextX64->Gdtr[1],\r
491 SystemContext.SystemContextX64->Ldtr\r
492 ));\r
493 DEBUG ((\r
494 EFI_D_ERROR,\r
495 "IDTR - %016lx %016lx, TR - %016lx\n",\r
496 SystemContext.SystemContextX64->Idtr[0],\r
497 SystemContext.SystemContextX64->Idtr[1],\r
498 SystemContext.SystemContextX64->Tr\r
499 ));\r
500 DEBUG ((\r
501 EFI_D_ERROR,\r
502 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",\r
503 SystemContext.SystemContextX64->Cr0,\r
504 SystemContext.SystemContextX64->Cr2,\r
505 SystemContext.SystemContextX64->Cr3\r
506 ));\r
507 DEBUG ((\r
508 EFI_D_ERROR,\r
509 "CR4 - %016lx, CR8 - %016lx\n",\r
510 SystemContext.SystemContextX64->Cr4,\r
511 SystemContext.SystemContextX64->Cr8\r
512 ));\r
513 DEBUG ((\r
514 EFI_D_ERROR,\r
515 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",\r
516 SystemContext.SystemContextX64->Dr0,\r
517 SystemContext.SystemContextX64->Dr1,\r
518 SystemContext.SystemContextX64->Dr2\r
519 ));\r
520 DEBUG ((\r
521 EFI_D_ERROR,\r
522 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",\r
523 SystemContext.SystemContextX64->Dr3,\r
524 SystemContext.SystemContextX64->Dr6,\r
525 SystemContext.SystemContextX64->Dr7\r
526 ));\r
527#endif\r
528 return ;\r
529}\r
530#endif\r
531\r
c69dd9df 532UINTN\r
533SPrint (\r
534 IN OUT CHAR16 *Buffer,\r
535 IN CONST CHAR16 *Format,\r
536 ...\r
537 )\r
538{\r
539 VA_LIST Marker;\r
540 UINTN Index;\r
541 UINTN Flags;\r
542 UINTN Width;\r
543 UINT64 Value;\r
544\r
545 VA_START (Marker, Format);\r
546\r
547 //\r
548 // Process the format string. Stop if Buffer is over run.\r
549 //\r
550\r
551 for (Index = 0; *Format != 0; Format++) {\r
552 if (*Format != L'%') {\r
553 Buffer[Index++] = *Format;\r
554 } else {\r
555 \r
556 //\r
557 // Now it's time to parse what follows after %\r
558 // Support: % [ 0 width ] [ l ] x\r
559 // width - fill 0, to ensure the width of x will be "width"\r
560 // l - UINT64 instead of UINT32\r
561 //\r
562 Width = 0;\r
563 Flags = 0;\r
564 Format ++;\r
565\r
566 if (*Format == L'0') {\r
567 Flags |= PREFIX_ZERO;\r
568 do {\r
569 Width += Width * 10 + (*Format - L'0');\r
570 Format ++;\r
571 } while (*Format >= L'1' && *Format <= L'9');\r
572 }\r
573\r
574 if (*Format == L'l') {\r
575 Flags |= LONG_TYPE;\r
576 Format ++;\r
577 }\r
578\r
579 \r
580 switch (*Format) {\r
581 case 'X':\r
582 Flags |= PREFIX_ZERO;\r
583 Width = sizeof (UINT64) * 2;\r
584 //\r
585 // break skiped on purpose\r
586 //\r
587 case 'x':\r
588 if ((Flags & LONG_TYPE) == LONG_TYPE) {\r
589 Value = VA_ARG (Marker, UINT64);\r
590 } else {\r
591 Value = VA_ARG (Marker, UINTN);\r
592 }\r
593\r
594 UnicodeValueToString (Buffer+Index, Flags, Value, Width);\r
595 \r
596 for ( ; Buffer[Index] != L'\0'; Index ++) {\r
597 }\r
598\r
599 break;\r
600\r
601 default:\r
602 //\r
603 // if the type is unknown print it to the screen\r
604 //\r
605 Buffer[Index++] = *Format;\r
606 }\r
607 } \r
608 }\r
609 Buffer[Index++] = '\0'; \r
610 \r
611 VA_END (Marker);\r
612 return Index;\r
613}\r
614\r
c69dd9df 615VOID\r
616DumpExceptionDataVgaOut (\r
617 IN EFI_EXCEPTION_TYPE InterruptType,\r
618 IN EFI_SYSTEM_CONTEXT SystemContext\r
619 )\r
620{\r
621 UINTN COLUMN_MAX;\r
622 UINTN ROW_MAX;\r
623 UINT32 ErrorCodeFlag;\r
624 CHAR16 *VideoBufferBase;\r
625 CHAR16 *VideoBuffer;\r
626 UINTN Index;\r
627\r
628 COLUMN_MAX = 80;\r
629 ROW_MAX = 25;\r
630 ErrorCodeFlag = 0x00027d00;\r
631 VideoBufferBase = (CHAR16 *) (UINTN) 0xb8000;\r
632 VideoBuffer = (CHAR16 *) (UINTN) 0xb8000;\r
633\r
634#ifdef EFI32\r
635 SPrint (\r
636 VideoBuffer, \r
637 L"!!!! IA32 Exception Type - %08x !!!!",\r
638 InterruptType\r
639 );\r
640 VideoBuffer += COLUMN_MAX;\r
641 SPrint (\r
642 VideoBuffer, \r
643 L"EIP - %08x, CS - %08x, EFLAGS - %08x",\r
644 SystemContext.SystemContextIa32->Eip,\r
645 SystemContext.SystemContextIa32->Cs,\r
646 SystemContext.SystemContextIa32->Eflags\r
647 );\r
648 VideoBuffer += COLUMN_MAX;\r
649 if (ErrorCodeFlag & (1 << InterruptType)) {\r
650 SPrint (\r
651 VideoBuffer,\r
652 L"ExceptionData - %08x",\r
653 SystemContext.SystemContextIa32->ExceptionData\r
654 );\r
655 VideoBuffer += COLUMN_MAX;\r
656 }\r
657 SPrint (\r
658 VideoBuffer,\r
659 L"EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x",\r
660 SystemContext.SystemContextIa32->Eax,\r
661 SystemContext.SystemContextIa32->Ecx,\r
662 SystemContext.SystemContextIa32->Edx,\r
663 SystemContext.SystemContextIa32->Ebx\r
664 );\r
665 VideoBuffer += COLUMN_MAX;\r
666\r
667 SPrint (\r
668 VideoBuffer,\r
669 L"ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x",\r
670 SystemContext.SystemContextIa32->Esp,\r
671 SystemContext.SystemContextIa32->Ebp,\r
672 SystemContext.SystemContextIa32->Esi,\r
673 SystemContext.SystemContextIa32->Edi\r
674 );\r
675 VideoBuffer += COLUMN_MAX;\r
676\r
677 SPrint (\r
678 VideoBuffer,\r
679 L"DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x",\r
680 SystemContext.SystemContextIa32->Ds,\r
681 SystemContext.SystemContextIa32->Es,\r
682 SystemContext.SystemContextIa32->Fs,\r
683 SystemContext.SystemContextIa32->Gs,\r
684 SystemContext.SystemContextIa32->Ss\r
685 );\r
686 VideoBuffer += COLUMN_MAX;\r
687\r
688 SPrint (\r
689 VideoBuffer,\r
690 L"GDTR - %08x %08x, IDTR - %08x %08x",\r
691 SystemContext.SystemContextIa32->Gdtr[0],\r
692 SystemContext.SystemContextIa32->Gdtr[1],\r
693 SystemContext.SystemContextIa32->Idtr[0],\r
694 SystemContext.SystemContextIa32->Idtr[1]\r
695 );\r
696 VideoBuffer += COLUMN_MAX;\r
697\r
698 SPrint (\r
699 VideoBuffer,\r
700 L"LDTR - %08x, TR - %08x",\r
701 SystemContext.SystemContextIa32->Ldtr,\r
702 SystemContext.SystemContextIa32->Tr\r
703 );\r
704 VideoBuffer += COLUMN_MAX;\r
705\r
706 SPrint (\r
707 VideoBuffer,\r
708 L"CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x",\r
709 SystemContext.SystemContextIa32->Cr0,\r
710 SystemContext.SystemContextIa32->Cr2,\r
711 SystemContext.SystemContextIa32->Cr3,\r
712 SystemContext.SystemContextIa32->Cr4\r
713 );\r
714 VideoBuffer += COLUMN_MAX;\r
715\r
716 SPrint (\r
717 VideoBuffer,\r
718 L"DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x",\r
719 SystemContext.SystemContextIa32->Dr0,\r
720 SystemContext.SystemContextIa32->Dr1,\r
721 SystemContext.SystemContextIa32->Dr2,\r
722 SystemContext.SystemContextIa32->Dr3\r
723 );\r
724 VideoBuffer += COLUMN_MAX;\r
725\r
726 SPrint (\r
727 VideoBuffer,\r
728 L"DR6 - %08x, DR7 - %08x",\r
729 SystemContext.SystemContextIa32->Dr6,\r
730 SystemContext.SystemContextIa32->Dr7\r
731 );\r
732 VideoBuffer += COLUMN_MAX;\r
733#else\r
734 SPrint (\r
735 VideoBuffer,\r
736 L"!!!! X64 Exception Type - %016lx !!!!",\r
737 (UINT64)InterruptType\r
738 );\r
739 VideoBuffer += COLUMN_MAX;\r
740\r
741 SPrint (\r
742 VideoBuffer,\r
743 L"RIP - %016lx, CS - %016lx, RFLAGS - %016lx",\r
744 SystemContext.SystemContextX64->Rip,\r
745 SystemContext.SystemContextX64->Cs,\r
746 SystemContext.SystemContextX64->Rflags\r
747 );\r
748 VideoBuffer += COLUMN_MAX;\r
749\r
750 if (ErrorCodeFlag & (1 << InterruptType)) {\r
751 SPrint (\r
752 VideoBuffer,\r
753 L"ExceptionData - %016lx",\r
754 SystemContext.SystemContextX64->ExceptionData\r
755 );\r
756 VideoBuffer += COLUMN_MAX;\r
757 }\r
758\r
759 SPrint (\r
760 VideoBuffer,\r
761 L"RAX - %016lx, RCX - %016lx, RDX - %016lx",\r
762 SystemContext.SystemContextX64->Rax,\r
763 SystemContext.SystemContextX64->Rcx,\r
764 SystemContext.SystemContextX64->Rdx\r
765 );\r
766 VideoBuffer += COLUMN_MAX;\r
767\r
768 SPrint (\r
769 VideoBuffer,\r
770 L"RBX - %016lx, RSP - %016lx, RBP - %016lx",\r
771 SystemContext.SystemContextX64->Rbx,\r
772 SystemContext.SystemContextX64->Rsp,\r
773 SystemContext.SystemContextX64->Rbp\r
774 );\r
775 VideoBuffer += COLUMN_MAX;\r
776\r
777 SPrint (\r
778 VideoBuffer,\r
779 L"RSI - %016lx, RDI - %016lx",\r
780 SystemContext.SystemContextX64->Rsi,\r
781 SystemContext.SystemContextX64->Rdi\r
782 );\r
783 VideoBuffer += COLUMN_MAX;\r
784\r
785 SPrint (\r
786 VideoBuffer,\r
787 L"R8 - %016lx, R9 - %016lx, R10 - %016lx",\r
788 SystemContext.SystemContextX64->R8,\r
789 SystemContext.SystemContextX64->R9,\r
790 SystemContext.SystemContextX64->R10\r
791 );\r
792 VideoBuffer += COLUMN_MAX;\r
793\r
794 SPrint (\r
795 VideoBuffer,\r
796 L"R11 - %016lx, R12 - %016lx, R13 - %016lx",\r
797 SystemContext.SystemContextX64->R11,\r
798 SystemContext.SystemContextX64->R12,\r
799 SystemContext.SystemContextX64->R13\r
800 );\r
801 VideoBuffer += COLUMN_MAX;\r
802\r
803 SPrint (\r
804 VideoBuffer,\r
805 L"R14 - %016lx, R15 - %016lx",\r
806 SystemContext.SystemContextX64->R14,\r
807 SystemContext.SystemContextX64->R15\r
808 );\r
809 VideoBuffer += COLUMN_MAX;\r
810\r
811 SPrint (\r
812 VideoBuffer,\r
813 L"DS - %016lx, ES - %016lx, FS - %016lx",\r
814 SystemContext.SystemContextX64->Ds,\r
815 SystemContext.SystemContextX64->Es,\r
816 SystemContext.SystemContextX64->Fs\r
817 );\r
818 VideoBuffer += COLUMN_MAX;\r
819\r
820 SPrint (\r
821 VideoBuffer,\r
822 L"GS - %016lx, SS - %016lx",\r
823 SystemContext.SystemContextX64->Gs,\r
824 SystemContext.SystemContextX64->Ss\r
825 );\r
826 VideoBuffer += COLUMN_MAX;\r
827\r
828 SPrint (\r
829 VideoBuffer,\r
830 L"GDTR - %016lx %016lx, LDTR - %016lx",\r
831 SystemContext.SystemContextX64->Gdtr[0],\r
832 SystemContext.SystemContextX64->Gdtr[1],\r
833 SystemContext.SystemContextX64->Ldtr\r
834 );\r
835 VideoBuffer += COLUMN_MAX;\r
836\r
837 SPrint (\r
838 VideoBuffer,\r
839 L"IDTR - %016lx %016lx, TR - %016lx",\r
840 SystemContext.SystemContextX64->Idtr[0],\r
841 SystemContext.SystemContextX64->Idtr[1],\r
842 SystemContext.SystemContextX64->Tr\r
843 );\r
844 VideoBuffer += COLUMN_MAX;\r
845\r
846 SPrint (\r
847 VideoBuffer,\r
848 L"CR0 - %016lx, CR2 - %016lx, CR3 - %016lx",\r
849 SystemContext.SystemContextX64->Cr0,\r
850 SystemContext.SystemContextX64->Cr2,\r
851 SystemContext.SystemContextX64->Cr3\r
852 );\r
853 VideoBuffer += COLUMN_MAX;\r
854\r
855 SPrint (\r
856 VideoBuffer,\r
857 L"CR4 - %016lx, CR8 - %016lx",\r
858 SystemContext.SystemContextX64->Cr4,\r
859 SystemContext.SystemContextX64->Cr8\r
860 );\r
861 VideoBuffer += COLUMN_MAX;\r
862\r
863 SPrint (\r
864 VideoBuffer,\r
865 L"DR0 - %016lx, DR1 - %016lx, DR2 - %016lx",\r
866 SystemContext.SystemContextX64->Dr0,\r
867 SystemContext.SystemContextX64->Dr1,\r
868 SystemContext.SystemContextX64->Dr2\r
869 );\r
870 VideoBuffer += COLUMN_MAX;\r
871\r
872 SPrint (\r
873 VideoBuffer,\r
874 L"DR3 - %016lx, DR6 - %016lx, DR7 - %016lx",\r
875 SystemContext.SystemContextX64->Dr3,\r
876 SystemContext.SystemContextX64->Dr6,\r
877 SystemContext.SystemContextX64->Dr7\r
878 );\r
879 VideoBuffer += COLUMN_MAX;\r
880#endif\r
881\r
882 for (Index = 0; Index < COLUMN_MAX * ROW_MAX; Index ++) {\r
883 if (Index > (UINTN)(VideoBuffer - VideoBufferBase)) {\r
884 VideoBufferBase[Index] = 0x0c20;\r
885 } else {\r
886 VideoBufferBase[Index] |= 0x0c00;\r
887 }\r
888 }\r
889\r
890 return ;\r
891}\r
892\r
893#if CPU_EXCEPTION_VGA_SWITCH\r
c69dd9df 894UINT16\r
895SwitchVideoMode (\r
896 UINT16 NewVideoMode\r
897 )\r
898/*++\r
899Description\r
900 Switch Video Mode from current mode to new mode, and return the old mode.\r
901 Use Thuink\r
902\r
903Arguments\r
904 NewVideoMode - new video mode want to set\r
905\r
906Return\r
907 UINT16 - (UINT16) -1 indicates failure\r
908 Other value indicates the old mode, which can be used for restore later\r
909 \r
910--*/\r
911{\r
912 EFI_STATUS Status;\r
913 EFI_LEGACY_BIOS_THUNK_PROTOCOL *LegacyBios;\r
914 EFI_IA32_REGISTER_SET Regs;\r
915 UINT16 OriginalVideoMode = (UINT16) -1;\r
916 \r
917 //\r
918 // See if the Legacy BIOS Protocol is available\r
919 //\r
920 Status = gBS->LocateProtocol (&gEfiLegacyBiosThunkProtocolGuid, NULL, (VOID **) &LegacyBios);\r
921 if (EFI_ERROR (Status)) {\r
922 return OriginalVideoMode;\r
923 }\r
924\r
925 //\r
926 // VESA SuperVGA BIOS - GET CURRENT VIDEO MODE\r
927 // AX = 4F03h\r
928 // Return:AL = 4Fh if function supported\r
929 // AH = status 00h successful\r
930 // BX = video mode (see #0082,#0083)\r
931 //\r
932 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
933 Regs.X.AX = 0x4F03;\r
934 LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
935 if (Regs.X.AX == 0x004F) {\r
936 OriginalVideoMode = Regs.X.BX;\r
937 } else {\r
938 //\r
939 // VIDEO - GET CURRENT VIDEO MODE\r
940 // AH = 0Fh\r
941 // Return:AH = number of character columns\r
942 // AL = display mode (see #0009 at AH=00h)\r
943 // BH = active page (see AH=05h)\r
944 //\r
945 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
946 Regs.H.AH = 0x0F;\r
947 LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
948 OriginalVideoMode = Regs.H.AL;\r
949 }\r
950\r
951 //\r
952 // Set new video mode\r
953 //\r
954 if (NewVideoMode < 0x100) {\r
955 //\r
956 // Set the 80x25 Text VGA Mode: Assume successful always\r
957 //\r
958 // VIDEO - SET VIDEO MODE\r
959 // AH = 00h\r
960 // AL = desired video mode (see #0009)\r
961 // Return:AL = video mode flag (Phoenix, AMI BIOS)\r
962 // 20h mode > 7\r
963 // 30h modes 0-5 and 7\r
964 // 3Fh mode 6\r
965 // AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)\r
966 //\r
967 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
968 Regs.H.AH = 0x00;\r
969 Regs.H.AL = (UINT8) NewVideoMode;\r
970 LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
971\r
972 //\r
973 // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)\r
974 // AX = 1114h\r
975 // BL = block to load\r
976 // Return:Nothing\r
977 //\r
978 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
979 Regs.H.AH = 0x11;\r
980 Regs.H.AL = 0x14;\r
981 Regs.H.BL = 0;\r
982 LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
983 } else {\r
984 //\r
985 // VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE\r
986 // AX = 4F02h\r
987 // BX = mode (see #0082,#0083)\r
988 // bit 15 set means don't clear video memory\r
989 // bit 14 set means enable linear framebuffer mode (VBE v2.0+)\r
990 // Return:AL = 4Fh if function supported\r
991 // AH = status\r
992 // 00h successful\r
993 // 01h failed\r
994 //\r
995 gBS->SetMem (&Regs, sizeof (Regs), 0);\r
996 Regs.X.AX = 0x4F02;\r
997 Regs.X.BX = NewVideoMode;\r
998 LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
999 if (Regs.X.AX != 0x004F) {\r
1000 DEBUG ((EFI_D_ERROR, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode));\r
1001 return (UINT16) -1;\r
1002 }\r
1003 }\r
1004\r
1005 return OriginalVideoMode;\r
1006}\r
1007#endif\r
1008\r
1009VOID\r
1010ExceptionHandler (\r
1011 IN EFI_EXCEPTION_TYPE InterruptType,\r
1012 IN EFI_SYSTEM_CONTEXT SystemContext\r
1013 )\r
1014{\r
1015#if CPU_EXCEPTION_VGA_SWITCH\r
1016 UINT16 VideoMode;\r
1017#endif\r
1018\r
1019#if CPU_EXCEPTION_DEBUG_OUTPUT\r
1020 DumpExceptionDataDebugOut (InterruptType, SystemContext);\r
1021#endif\r
1022\r
1023#if CPU_EXCEPTION_VGA_SWITCH\r
1024 //\r
1025 // Switch to text mode for RED-SCREEN output\r
1026 //\r
1027 VideoMode = SwitchVideoMode (0x83);\r
1028 if (VideoMode == (UINT16) -1) {\r
1029 DEBUG ((EFI_D_ERROR, "Video Mode Unknown!\n"));\r
1030 }\r
1031#endif\r
1032\r
1033 DumpExceptionDataVgaOut (InterruptType, SystemContext);\r
1034\r
1035 //\r
1036 // Use this macro to hang so that the compiler does not optimize out\r
1037 // the following RET instructions. This allows us to return if we\r
1038 // have a debugger attached.\r
1039 //\r
1040 CpuDeadLoop ();\r
1041\r
1042#if CPU_EXCEPTION_VGA_SWITCH\r
1043 //\r
1044 // Switch back to the old video mode\r
1045 //\r
1046 if (VideoMode != (UINT16)-1) {\r
1047 SwitchVideoMode (VideoMode);\r
1048 }\r
1049#endif\r
1050\r
1051 return ;\r
1052}\r
1053\r
1054VOID\r
1055TimerHandler (\r
1056 IN EFI_EXCEPTION_TYPE InterruptType,\r
1057 IN EFI_SYSTEM_CONTEXT SystemContext\r
1058 )\r
1059{\r
1060 if (mTimerHandler != NULL) {\r
1061 mTimerHandler (InterruptType, SystemContext);\r
1062 }\r
1063}\r
1064\r
1065EFI_STATUS\r
1066EFIAPI\r
1067InitializeCpu (\r
1068 IN EFI_HANDLE ImageHandle,\r
1069 IN EFI_SYSTEM_TABLE *SystemTable\r
1070 )\r
1071/*++\r
1072\r
1073Routine Description:\r
1074 Initialize the state information for the CPU Architectural Protocol\r
1075\r
1076Arguments:\r
1077 ImageHandle of the loaded driver\r
1078 Pointer to the System Table\r
1079\r
1080Returns:\r
1081 EFI_SUCCESS - thread can be successfully created\r
1082 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure\r
1083 EFI_DEVICE_ERROR - cannot create the thread\r
1084\r
1085--*/\r
1086{\r
1087 EFI_STATUS Status;\r
1088 EFI_8259_IRQ Irq;\r
1089 UINT32 InterruptVector;\r
1090\r
1091 //\r
1092 // Find the Legacy8259 protocol.\r
1093 //\r
1094 Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &gLegacy8259);\r
1095 ASSERT_EFI_ERROR (Status);\r
1096\r
1097 //\r
1098 // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver\r
1099 //\r
1100 Status = gLegacy8259->GetVector (gLegacy8259, Efi8259Irq0, (UINT8 *) &mTimerVector);\r
1101 ASSERT_EFI_ERROR (Status);\r
1102\r
1103 //\r
1104 // Reload GDT, IDT\r
1105 //\r
1106 InitDescriptor ();\r
1107\r
1108 //\r
1109 // Install Exception Handler (0x00 ~ 0x1F)\r
1110 //\r
1111 for (InterruptVector = 0; InterruptVector < 0x20; InterruptVector++) {\r
1112 InstallInterruptHandler (\r
1113 InterruptVector,\r
1114 (VOID (*)(VOID))(UINTN)((UINTN)SystemExceptionHandler + mExceptionCodeSize * InterruptVector)\r
1115 );\r
1116 }\r
1117\r
1118 //\r
1119 // Install Timer Handler\r
1120 //\r
1121 InstallInterruptHandler (mTimerVector, SystemTimerHandler);\r
1122\r
1123 //\r
1124 // BUGBUG: We add all other interrupt vector\r
1125 //\r
1126 for (Irq = Efi8259Irq1; Irq <= Efi8259Irq15; Irq++) {\r
1127 InterruptVector = 0;\r
1128 Status = gLegacy8259->GetVector (gLegacy8259, Irq, (UINT8 *) &InterruptVector);\r
1129 ASSERT_EFI_ERROR (Status);\r
1130 InstallInterruptHandler (InterruptVector, SystemTimerHandler);\r
1131 }\r
1132\r
1133 //\r
1134 // Install CPU Architectural Protocol and the thunk protocol\r
1135 //\r
1136 mHandle = NULL;\r
1137 Status = gBS->InstallMultipleProtocolInterfaces (\r
1138 &mHandle,\r
1139 &gEfiCpuArchProtocolGuid,\r
1140 &mCpu,\r
1141 NULL\r
1142 );\r
1143 ASSERT_EFI_ERROR (Status);\r
1144\r
1145 return EFI_SUCCESS;\r
1146}\r
1147\r