TianoCore EDK2 master
Loading...
Searching...
No Matches
CpuExceptionHandlerTestCommon.c
Go to the documentation of this file.
1
10
11//
12// Length of the assembly falut instruction.
13//
14UINTN mFaultInstructionLength = 0;
15EFI_EXCEPTION_TYPE mExceptionType = 256;
16UINTN mNumberOfProcessors = 1;
17UINTN mRspAddress[2] = { 0 };
18
19//
20// Error code flag indicating whether or not an error code will be
21// pushed on the stack if an exception occurs.
22//
23// 1 means an error code will be pushed, otherwise 0
24//
25CONST UINT32 mErrorCodeExceptionFlag = 0x20227d00;
26
34VOID
35EFIAPI
37 IN EFI_EXCEPTION_TYPE ExceptionType,
38 IN EFI_SYSTEM_CONTEXT SystemContext
39 )
40{
41 mExceptionType = ExceptionType;
42}
43
49VOID
50EFIAPI
52 IN VOID *Buffer
53 )
54{
55 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer;
56 UINT16 Tr;
57 IA32_TSS_DESCRIPTOR *Tss;
58
59 CpuOriginalRegisterBuffer = (CPU_REGISTER_BUFFER *)Buffer;
60
61 AsmWriteGdtr (&(CpuOriginalRegisterBuffer->OriginalGdtr));
62 AsmWriteIdtr (&(CpuOriginalRegisterBuffer->OriginalIdtr));
63 Tr = CpuOriginalRegisterBuffer->Tr;
64 if ((Tr != 0) && (Tr < CpuOriginalRegisterBuffer->OriginalGdtr.Limit)) {
65 Tss = (IA32_TSS_DESCRIPTOR *)(CpuOriginalRegisterBuffer->OriginalGdtr.Base + Tr);
66 if (Tss->Bits.P == 1) {
67 //
68 // Clear busy bit of TSS before write Tr
69 //
70 Tss->Bits.Type &= 0xD;
71 AsmWriteTr (Tr);
72 }
73 }
74}
75
83VOID
85 MP_SERVICES *MpServices, OPTIONAL
86 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer,
87 UINTN BspProcessorNum
88 )
89{
90 UINTN Index;
91 EFI_STATUS Status;
92
93 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
94 if (Index == BspProcessorNum) {
95 RestoreRegistersPerCpu ((VOID *)&CpuOriginalRegisterBuffer[Index]);
96 continue;
97 }
98
99 ASSERT (MpServices != NULL);
101 *MpServices,
103 Index,
104 0,
105 (VOID *)&CpuOriginalRegisterBuffer[Index]
106 );
107 ASSERT_EFI_ERROR (Status);
108 }
109}
110
116VOID
117EFIAPI
119 IN VOID *Buffer
120 )
121{
122 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer;
123 IA32_DESCRIPTOR Gdtr;
124 IA32_DESCRIPTOR Idtr;
125
126 CpuOriginalRegisterBuffer = (CPU_REGISTER_BUFFER *)Buffer;
127
128 AsmReadGdtr (&Gdtr);
129 AsmReadIdtr (&Idtr);
130 CpuOriginalRegisterBuffer->OriginalGdtr.Base = Gdtr.Base;
131 CpuOriginalRegisterBuffer->OriginalGdtr.Limit = Gdtr.Limit;
132 CpuOriginalRegisterBuffer->OriginalIdtr.Base = Idtr.Base;
133 CpuOriginalRegisterBuffer->OriginalIdtr.Limit = Idtr.Limit;
134 CpuOriginalRegisterBuffer->Tr = AsmReadTr ();
135}
136
147 MP_SERVICES *MpServices, OPTIONAL
148 UINTN BspProcessorNum
149 )
150{
151 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer;
152 EFI_STATUS Status;
153 UINTN Index;
154
155 CpuOriginalRegisterBuffer = AllocateZeroPool (mNumberOfProcessors * sizeof (CPU_REGISTER_BUFFER));
156 ASSERT (CpuOriginalRegisterBuffer != NULL);
157
158 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
159 if (Index == BspProcessorNum) {
160 SaveRegisterPerCpu ((VOID *)&CpuOriginalRegisterBuffer[Index]);
161 continue;
162 }
163
164 ASSERT (MpServices != NULL);
166 *MpServices,
168 Index,
169 0,
170 (VOID *)&CpuOriginalRegisterBuffer[Index]
171 );
172 ASSERT_EFI_ERROR (Status);
173 }
174
175 return CpuOriginalRegisterBuffer;
176}
177
183VOID
184EFIAPI
186 IN VOID *Buffer
187 )
188{
189 AsmWriteIdtr (Buffer);
190}
191
198VOID
200 MP_SERVICES MpServices,
201 VOID *BspIdtr
202 )
203{
204 EFI_STATUS Status;
205
207 MpServices,
209 FALSE,
210 0,
211 BspIdtr
212 );
213 ASSERT_EFI_ERROR (Status);
214}
215
232EFIAPI
234 IN UNIT_TEST_CONTEXT Context
235 )
236{
237 EFI_STATUS Status;
238 UINTN Index;
239 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer;
240 VOID *NewIdtr;
241
242 CpuOriginalRegisterBuffer = SaveAllCpuRegisters (NULL, 0);
243 NewIdtr = InitializeBspIdt ();
244 Status = InitializeCpuExceptionHandlers (NULL);
246
247 for (Index = 0; Index < SPEC_MAX_EXCEPTION_NUM; Index++) {
248 //
249 // Only test no error code exception by INT n instruction.
250 //
251 if ((mErrorCodeExceptionFlag & (1 << Index)) != 0) {
252 continue;
253 }
254
255 DEBUG ((DEBUG_INFO, "TestCase1: ExceptionType is %d\n", Index));
256 Status = RegisterCpuInterruptHandler (Index, INTnExceptionHandler);
258
259 TriggerINTnException (Index);
260 UT_ASSERT_EQUAL (mExceptionType, Index);
261 Status = RegisterCpuInterruptHandler (Index, NULL);
263 }
264
265 RestoreAllCpuRegisters (NULL, CpuOriginalRegisterBuffer, 0);
266 FreePool (CpuOriginalRegisterBuffer);
267 FreePool (NewIdtr);
268 return UNIT_TEST_PASSED;
269}
270
276VOID
278 OUT UINTN *StackBase
279 )
280{
282 EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
283
284 //
285 // Get the base of stack from Hob.
286 //
287 ASSERT (StackBase != NULL);
288 Hob.Raw = GetHobList ();
289 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
290 MemoryHob = Hob.MemoryAllocation;
291 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) {
292 DEBUG ((
293 DEBUG_INFO,
294 "%a: Bsp StackBase = 0x%016lx StackSize = 0x%016lx\n",
295 __func__,
298 ));
299
300 *StackBase = (UINTN)MemoryHob->AllocDescriptor.MemoryBaseAddress;
301 //
302 // Ensure the base of the stack is page-size aligned.
303 //
304 ASSERT ((*StackBase & EFI_PAGE_MASK) == 0);
305 break;
306 }
307
308 Hob.Raw = GET_NEXT_HOB (Hob);
309 }
310
311 ASSERT (*StackBase != 0);
312}
313
319VOID
320EFIAPI
322 OUT VOID *ApStackBase
323 )
324{
325 UINTN ApTopOfStack;
326
327 ApTopOfStack = ALIGN_VALUE ((UINTN)&ApTopOfStack, (UINTN)PcdGet32 (PcdCpuApStackSize));
328 *(UINTN *)ApStackBase = ApTopOfStack - (UINTN)PcdGet32 (PcdCpuApStackSize);
329}
330
339UINTN *
341 MP_SERVICES *MpServices,
342 UINTN BspProcessorNum
343 )
344{
345 UINTN *CpuStackBaseBuffer;
346 EFI_STATUS Status;
347 UINTN Index;
348
349 CpuStackBaseBuffer = AllocateZeroPool (mNumberOfProcessors * sizeof (UINTN));
350 ASSERT (CpuStackBaseBuffer != NULL);
351
352 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
353 if (Index == BspProcessorNum) {
354 GetBspStackBase (&CpuStackBaseBuffer[Index]);
355 continue;
356 }
357
358 ASSERT (MpServices != NULL);
360 *MpServices,
362 Index,
363 0,
364 (VOID *)&CpuStackBaseBuffer[Index]
365 );
366 ASSERT_EFI_ERROR (Status);
367 DEBUG ((DEBUG_INFO, "AP[%d] StackBase = 0x%x\n", Index, CpuStackBaseBuffer[Index]));
368 }
369
370 return CpuStackBaseBuffer;
371}
372
381BOOLEAN
383 OUT UINTN *PFAddress
384 )
385{
386 IA32_CR0 Cr0;
387 IA32_CR4 Cr4;
388 UINTN PageTable;
389 PAGING_MODE PagingMode;
390 BOOLEAN Enable5LevelPaging;
391 RETURN_STATUS Status;
392 IA32_MAP_ENTRY *Map;
393 UINTN MapCount;
394 UINTN Index;
395 UINTN PreviousAddress;
396
397 ASSERT (PFAddress != NULL);
398
399 Cr0.UintN = AsmReadCr0 ();
400 if (Cr0.Bits.PG == 0) {
401 return FALSE;
402 }
403
404 PageTable = AsmReadCr3 ();
405 Cr4.UintN = AsmReadCr4 ();
406 if (sizeof (UINTN) == sizeof (UINT32)) {
407 ASSERT (Cr4.Bits.PAE == 1);
408 PagingMode = PagingPae;
409 } else {
410 Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);
411 PagingMode = Enable5LevelPaging ? Paging5Level : Paging4Level;
412 }
413
414 MapCount = 0;
415 Status = PageTableParse (PageTable, PagingMode, NULL, &MapCount);
416 ASSERT (Status == RETURN_BUFFER_TOO_SMALL);
417 Map = AllocatePages (EFI_SIZE_TO_PAGES (MapCount * sizeof (IA32_MAP_ENTRY)));
418 Status = PageTableParse (PageTable, PagingMode, Map, &MapCount);
419 ASSERT (Status == RETURN_SUCCESS);
420
421 PreviousAddress = 0;
422 for (Index = 0; Index < MapCount; Index++) {
423 DEBUG ((
424 DEBUG_ERROR,
425 "%02d: %016lx - %016lx, %016lx\n",
426 Index,
427 Map[Index].LinearAddress,
428 Map[Index].LinearAddress + Map[Index].Length,
429 Map[Index].Attribute.Uint64
430 ));
431
432 //
433 // Not present address in page table.
434 //
435 if (Map[Index].LinearAddress > PreviousAddress) {
436 *PFAddress = PreviousAddress;
437 return TRUE;
438 }
439
440 PreviousAddress = (UINTN)(Map[Index].LinearAddress + Map[Index].Length);
441
442 //
443 // ReadOnly address in page table.
444 //
445 if ((Cr0.Bits.WP != 0) && (Map[Index].Attribute.Bits.ReadWrite == 0)) {
446 *PFAddress = (UINTN)Map[Index].LinearAddress;
447 return TRUE;
448 }
449 }
450
451 return FALSE;
452}
453
470EFIAPI
472 IN UNIT_TEST_CONTEXT Context
473 )
474{
475 EFI_STATUS Status;
476 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer;
477 UINTN PFAddress;
478 VOID *NewIdtr;
479
480 PFAddress = 0;
481 CpuOriginalRegisterBuffer = SaveAllCpuRegisters (NULL, 0);
482 NewIdtr = InitializeBspIdt ();
483 Status = InitializeCpuExceptionHandlers (NULL);
484
486
487 //
488 // GP exception.
489 //
490 DEBUG ((DEBUG_INFO, "TestCase2: ExceptionType is %d\n", EXCEPT_IA32_GP_FAULT));
491 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_GP_FAULT, AdjustRipForFaultHandler);
493
494 TriggerGPException (CR4_RESERVED_BIT);
495 UT_ASSERT_EQUAL (mExceptionType, EXCEPT_IA32_GP_FAULT);
496 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_GP_FAULT, NULL);
498
499 //
500 // PF exception.
501 //
502 if (FindPFAddressInPageTable (&PFAddress)) {
503 DEBUG ((DEBUG_INFO, "TestCase2: ExceptionType is %d\n", EXCEPT_IA32_PAGE_FAULT));
504 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, AdjustRipForFaultHandler);
506 TriggerPFException (PFAddress);
507
508 UT_ASSERT_EQUAL (mExceptionType, EXCEPT_IA32_PAGE_FAULT);
509 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, NULL);
511 }
512
513 RestoreAllCpuRegisters (NULL, CpuOriginalRegisterBuffer, 0);
514 FreePool (CpuOriginalRegisterBuffer);
515 FreePool (NewIdtr);
516 return UNIT_TEST_PASSED;
517}
518
535EFIAPI
537 IN UNIT_TEST_CONTEXT Context
538 )
539{
540 EFI_STATUS Status;
541 UINTN Index;
542 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer;
543 UINTN FaultParameter;
544 VOID *NewIdtr;
545
546 FaultParameter = 0;
547 CpuOriginalRegisterBuffer = SaveAllCpuRegisters (NULL, 0);
548 NewIdtr = InitializeBspIdt ();
549 Status = InitializeCpuExceptionHandlers (NULL);
551
552 for (Index = 0; Index < 22; Index++) {
553 if (Index == EXCEPT_IA32_PAGE_FAULT) {
554 if (!FindPFAddressInPageTable (&FaultParameter)) {
555 continue;
556 }
557 } else if (Index == EXCEPT_IA32_GP_FAULT) {
558 FaultParameter = CR4_RESERVED_BIT;
559 } else {
560 if ((mErrorCodeExceptionFlag & (1 << Index)) != 0) {
561 continue;
562 }
563 }
564
565 DEBUG ((DEBUG_INFO, "TestCase3: ExceptionType is %d\n", Index));
566 Status = RegisterCpuInterruptHandler (Index, AdjustCpuContextHandler);
568
569 //
570 // Trigger different type exception and compare different stage cpu context.
571 //
572 AsmTestConsistencyOfCpuContext (Index, FaultParameter);
574 Status = RegisterCpuInterruptHandler (Index, NULL);
576 }
577
578 RestoreAllCpuRegisters (NULL, CpuOriginalRegisterBuffer, 0);
579 FreePool (CpuOriginalRegisterBuffer);
580 FreePool (NewIdtr);
581 return UNIT_TEST_PASSED;
582}
583
593VOID
594EFIAPI
596 IN OUT VOID *Buffer
597 )
598{
599 EXCEPTION_STACK_SWITCH_CONTEXT *CpuSwitchStackData;
600
601 CpuSwitchStackData = (EXCEPTION_STACK_SWITCH_CONTEXT *)Buffer;
602
603 //
604 // This may be called twice for each Cpu. Only run InitializeSeparateExceptionStacks
605 // if this is the first call or the first call failed because of size too small.
606 //
607 if ((CpuSwitchStackData->Status == EFI_NOT_STARTED) || (CpuSwitchStackData->Status == EFI_BUFFER_TOO_SMALL)) {
608 CpuSwitchStackData->Status = InitializeSeparateExceptionStacks (CpuSwitchStackData->Buffer, &CpuSwitchStackData->BufferSize);
609 }
610}
611
625 MP_SERVICES MpServices,
626 UINTN BspProcessorNum
627 )
628{
629 UINTN Index;
630 EXCEPTION_STACK_SWITCH_CONTEXT *SwitchStackData;
631 UINTN BufferSize;
632 EFI_STATUS Status;
633 UINT8 *Buffer;
634
635 SwitchStackData = AllocateZeroPool (mNumberOfProcessors * sizeof (EXCEPTION_STACK_SWITCH_CONTEXT));
636 ASSERT (SwitchStackData != NULL);
637 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
638 //
639 // Because the procedure may runs multiple times, use the status EFI_NOT_STARTED
640 // to indicate the procedure haven't been run yet.
641 //
642 SwitchStackData[Index].Status = EFI_NOT_STARTED;
643 if (Index == BspProcessorNum) {
644 InitializeExceptionStackSwitchHandlersPerAp ((VOID *)&SwitchStackData[Index]);
645 continue;
646 }
647
649 MpServices,
651 Index,
652 0,
653 (VOID *)&SwitchStackData[Index]
654 );
655 ASSERT_EFI_ERROR (Status);
656 }
657
658 BufferSize = 0;
659 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
660 if (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL) {
661 ASSERT (SwitchStackData[Index].BufferSize != 0);
662 BufferSize += SwitchStackData[Index].BufferSize;
663 } else {
664 ASSERT (SwitchStackData[Index].Status == EFI_SUCCESS);
665 ASSERT (SwitchStackData[Index].BufferSize == 0);
666 }
667 }
668
669 if (BufferSize != 0) {
670 Buffer = AllocateZeroPool (BufferSize);
671 ASSERT (Buffer != NULL);
672 BufferSize = 0;
673 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
674 if (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL) {
675 SwitchStackData[Index].Buffer = (VOID *)(&Buffer[BufferSize]);
676 BufferSize += SwitchStackData[Index].BufferSize;
677 DEBUG ((
678 DEBUG_INFO,
679 "Buffer[cpu%lu] for InitializeExceptionStackSwitchHandlersPerAp: 0x%lX with size 0x%lX\n",
680 (UINT64)(UINTN)Index,
681 (UINT64)(UINTN)SwitchStackData[Index].Buffer,
682 (UINT64)(UINTN)SwitchStackData[Index].BufferSize
683 ));
684 }
685 }
686
687 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
688 if (Index == BspProcessorNum) {
689 InitializeExceptionStackSwitchHandlersPerAp ((VOID *)&SwitchStackData[Index]);
690 continue;
691 }
692
694 MpServices,
696 Index,
697 0,
698 (VOID *)&SwitchStackData[Index]
699 );
700 ASSERT_EFI_ERROR (Status);
701 }
702
703 for (Index = 0; Index < mNumberOfProcessors; ++Index) {
704 ASSERT (SwitchStackData[Index].Status == EFI_SUCCESS);
705 }
706 }
707
708 return SwitchStackData;
709}
710
727EFIAPI
729 IN UNIT_TEST_CONTEXT Context
730 )
731{
732 EFI_STATUS Status;
733 UINTN OriginalStackBase;
734 UINTN NewStackTop;
735 UINTN NewStackBase;
736 EXCEPTION_STACK_SWITCH_CONTEXT *SwitchStackData;
737 MP_SERVICES MpServices;
738 UINTN ProcessorNumber;
739 UINTN EnabledProcessorNum;
740 CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer;
741 UINTN Index;
742 UINTN BspProcessorNum;
743 VOID *NewIdtr;
744 UINTN *CpuStackBaseBuffer;
745
746 if (!PcdGetBool (PcdCpuStackGuard)) {
747 return UNIT_TEST_PASSED;
748 }
749
750 //
751 // Get MP Service Protocol
752 //
753 Status = GetMpServices (&MpServices);
754 Status = MpServicesUnitTestGetNumberOfProcessors (MpServices, &ProcessorNumber, &EnabledProcessorNum);
756 Status = MpServicesUnitTestWhoAmI (MpServices, &BspProcessorNum);
758 mNumberOfProcessors = ProcessorNumber;
759
760 CpuOriginalRegisterBuffer = SaveAllCpuRegisters (&MpServices, BspProcessorNum);
761
762 //
763 // Initialize Bsp and AP Idt.
764 // Idt buffer should not be empty or it will hang in MP API.
765 //
766 NewIdtr = InitializeBspIdt ();
767 Status = InitializeCpuExceptionHandlers (NULL);
769 InitializeApIdt (MpServices, NewIdtr);
770
771 //
772 // Get BSP and AP original stack base.
773 //
774 CpuStackBaseBuffer = GetAllCpuStackBase (&MpServices, BspProcessorNum);
775
776 //
777 // InitializeMpExceptionStackSwitchHandlers and register exception handler.
778 //
779 SwitchStackData = InitializeMpExceptionStackSwitchHandlers (MpServices, BspProcessorNum);
780 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, CpuStackGuardExceptionHandler);
782 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_DOUBLE_FAULT, AdjustRipForFaultHandler);
784
785 for (Index = 0; Index < mNumberOfProcessors; Index++) {
786 OriginalStackBase = CpuStackBaseBuffer[Index];
787 NewStackTop = (UINTN)(SwitchStackData[Index].Buffer) + SwitchStackData[Index].BufferSize;
788 NewStackBase = (UINTN)(SwitchStackData[Index].Buffer);
789 if (Index == BspProcessorNum) {
791 } else {
793 MpServices,
795 Index,
796 0,
797 NULL
798 );
799 }
800
801 DEBUG ((DEBUG_INFO, "TestCase4: mRspAddress[0] is 0x%x, mRspAddress[1] is 0x%x\n", mRspAddress[0], mRspAddress[1]));
802 UT_ASSERT_TRUE ((mRspAddress[0] >= OriginalStackBase) && (mRspAddress[0] <= (OriginalStackBase + SIZE_4KB)));
803 UT_ASSERT_TRUE ((mRspAddress[1] >= NewStackBase) && (mRspAddress[1] < NewStackTop));
804 }
805
806 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, NULL);
808 Status = RegisterCpuInterruptHandler (EXCEPT_IA32_DOUBLE_FAULT, NULL);
810 RestoreAllCpuRegisters (&MpServices, CpuOriginalRegisterBuffer, BspProcessorNum);
811 FreePool (SwitchStackData);
812 FreePool (CpuOriginalRegisterBuffer);
813 FreePool (NewIdtr);
814
815 return UNIT_TEST_PASSED;
816}
817
829 IN UNIT_TEST_FRAMEWORK_HANDLE Framework
830 )
831{
832 EFI_STATUS Status;
833 UNIT_TEST_SUITE_HANDLE CpuExceptionLibUnitTestSuite;
834
835 //
836 // Populate the Manual Test Cases.
837 //
838 Status = CreateUnitTestSuite (&CpuExceptionLibUnitTestSuite, Framework, "Test CpuExceptionHandlerLib", "CpuExceptionHandlerLib.Manual", NULL, NULL);
839 if (EFI_ERROR (Status)) {
840 DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for CpuExceptionHandlerLib Test Cases\n"));
841 Status = EFI_OUT_OF_RESOURCES;
842 return Status;
843 }
844
845 AddTestCase (CpuExceptionLibUnitTestSuite, "Check if exception handler can be registered/unregistered for no error code exception", "TestRegisterHandlerForNoErrorCodeException", TestRegisterHandlerForNoErrorCodeException, NULL, NULL, NULL);
846 AddTestCase (CpuExceptionLibUnitTestSuite, "Check if exception handler can be registered/unregistered for GP and PF", "TestRegisterHandlerForGPAndPF", TestRegisterHandlerForGPAndPF, NULL, NULL, NULL);
847
848 AddTestCase (CpuExceptionLibUnitTestSuite, "Check if Cpu Context is consistent before and after exception.", "TestCpuContextConsistency", TestCpuContextConsistency, NULL, NULL, NULL);
849 AddTestCase (CpuExceptionLibUnitTestSuite, "Check if stack overflow is captured by CpuStackGuard in Bsp and AP", "TestCpuStackGuardInBspAndAp", TestCpuStackGuardInBspAndAp, NULL, NULL, NULL);
850
851 return EFI_SUCCESS;
852}
UINT64 UINTN
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID *EFIAPI GetHobList(VOID)
Definition: HobLib.c:76
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
EFI_STATUS MpServicesUnitTestWhoAmI(IN MP_SERVICES MpServices, OUT UINTN *ProcessorNumber)
VOID EFIAPI AdjustCpuContextHandler(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext)
VOID EFIAPI TriggerINTnException(IN EFI_EXCEPTION_TYPE ExceptionType)
VOID EFIAPI TriggerStackOverflow(VOID)
VOID EFIAPI AsmTestConsistencyOfCpuContext(IN EFI_EXCEPTION_TYPE ExceptionType, IN UINTN FaultParameter OPTIONAL)
EFI_STATUS MpServicesUnitTestStartupAllAPs(IN MP_SERVICES MpServices, IN EFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, IN UINTN TimeoutInMicroSeconds, IN VOID *ProcedureArgument)
EFI_STATUS GetMpServices(OUT MP_SERVICES *MpServices)
EFI_STATUS MpServicesUnitTestGetNumberOfProcessors(IN MP_SERVICES MpServices, OUT UINTN *NumberOfProcessors, OUT UINTN *NumberOfEnabledProcessors)
VOID EFIAPI AdjustRipForFaultHandler(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext)
VOID EFIAPI CpuStackGuardExceptionHandler(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext)
VOID EFIAPI TriggerPFException(UINTN PFAddress)
VOID EFIAPI TriggerGPException(UINTN Cr4ReservedBit)
UNIT_TEST_STATUS CompareCpuContext(VOID)
EFI_STATUS MpServicesUnitTestStartupThisAP(IN MP_SERVICES MpServices, IN EFI_AP_PROCEDURE Procedure, IN UINTN ProcessorNumber, IN UINTN TimeoutInMicroSeconds, IN VOID *ProcedureArgument)
VOID * InitializeBspIdt(VOID)
VOID EFIAPI SaveRegisterPerCpu(IN VOID *Buffer)
UINTN * GetAllCpuStackBase(MP_SERVICES *MpServices, UINTN BspProcessorNum)
VOID EFIAPI INTnExceptionHandler(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext)
UNIT_TEST_STATUS EFIAPI TestRegisterHandlerForNoErrorCodeException(IN UNIT_TEST_CONTEXT Context)
VOID GetBspStackBase(OUT UINTN *StackBase)
VOID InitializeApIdt(MP_SERVICES MpServices, VOID *BspIdtr)
UNIT_TEST_STATUS EFIAPI TestCpuContextConsistency(IN UNIT_TEST_CONTEXT Context)
EXCEPTION_STACK_SWITCH_CONTEXT * InitializeMpExceptionStackSwitchHandlers(MP_SERVICES MpServices, UINTN BspProcessorNum)
VOID EFIAPI RestoreRegistersPerCpu(IN VOID *Buffer)
VOID EFIAPI InitializeExceptionStackSwitchHandlersPerAp(IN OUT VOID *Buffer)
EFI_STATUS AddCommonTestCase(IN UNIT_TEST_FRAMEWORK_HANDLE Framework)
BOOLEAN FindPFAddressInPageTable(OUT UINTN *PFAddress)
VOID EFIAPI InitializeIdtPerAp(IN VOID *Buffer)
VOID EFIAPI GetStackBasePerAp(OUT VOID *ApStackBase)
VOID RestoreAllCpuRegisters(MP_SERVICES *MpServices, OPTIONAL CPU_REGISTER_BUFFER *CpuOriginalRegisterBuffer, UINTN BspProcessorNum)
UNIT_TEST_STATUS EFIAPI TestRegisterHandlerForGPAndPF(IN UNIT_TEST_CONTEXT Context)
UNIT_TEST_STATUS EFIAPI TestCpuStackGuardInBspAndAp(IN UNIT_TEST_CONTEXT Context)
CPU_REGISTER_BUFFER * SaveAllCpuRegisters(MP_SERVICES *MpServices, OPTIONAL UINTN BspProcessorNum)
RETURN_STATUS EFIAPI PageTableParse(IN UINTN PageTable, IN PAGING_MODE PagingMode, IN IA32_MAP_ENTRY *Map, IN OUT UINTN *MapCount)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINT16 EFIAPI AsmReadTr(VOID)
UINTN EFIAPI AsmReadCr3(VOID)
UINTN EFIAPI AsmReadCr0(VOID)
UINTN EFIAPI AsmReadCr4(VOID)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
INTN EFI_EXCEPTION_TYPE
Definition: DebugSupport.h:35
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
VOID(EFIAPI * EFI_AP_PROCEDURE)(IN OUT VOID *Buffer)
Definition: PiMultiPhase.h:198
VOID *EFIAPI AllocatePages(IN UINTN Pages)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID * UNIT_TEST_CONTEXT
Definition: UnitTestLib.h:54
#define UT_ASSERT_TRUE(Expression)
Definition: UnitTestLib.h:350
#define UT_ASSERT_EQUAL(ValueA, ValueB)
Definition: UnitTestLib.h:375
EFI_STATUS EFIAPI CreateUnitTestSuite(OUT UNIT_TEST_SUITE_HANDLE *SuiteHandle, IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, IN CHAR8 *Title, IN CHAR8 *Name, IN UNIT_TEST_SUITE_SETUP Setup OPTIONAL, IN UNIT_TEST_SUITE_TEARDOWN Teardown OPTIONAL)
Definition: UnitTestLib.c:326
EFI_STATUS EFIAPI AddTestCase(IN UNIT_TEST_SUITE_HANDLE SuiteHandle, IN CHAR8 *Description, IN CHAR8 *Name, IN UNIT_TEST_FUNCTION Function, IN UNIT_TEST_PREREQUISITE Prerequisite OPTIONAL, IN UNIT_TEST_CLEANUP CleanUp OPTIONAL, IN UNIT_TEST_CONTEXT Context OPTIONAL)
Definition: UnitTestLib.c:426
UINT32 UNIT_TEST_STATUS
Definition: UnitTestLib.h:16
VOID EFIAPI AsmReadGdtr(OUT IA32_DESCRIPTOR *Gdtr)
Definition: X86ReadGdtr.c:24
VOID EFIAPI AsmReadIdtr(OUT IA32_DESCRIPTOR *Idtr)
Definition: X86ReadIdtr.c:24
VOID EFIAPI AsmWriteTr(IN UINT16 Selector)
VOID EFIAPI AsmWriteGdtr(IN CONST IA32_DESCRIPTOR *Gdtr)
VOID EFIAPI AsmWriteIdtr(IN CONST IA32_DESCRIPTOR *Idtr)
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
Definition: PiHob.h:119
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
Definition: PiHob.h:153