+ //\r
+ // Initialize IDT - Since this is before library constructors are called,\r
+ // we use a loop rather than CopyMem.\r
+ //\r
+ IdtTableInStack.PeiService = NULL;\r
+\r
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {\r
+ //\r
+ // Declare the local variables that actually move the data elements as\r
+ // volatile to prevent the optimizer from replacing this function with\r
+ // the intrinsic memcpy()\r
+ //\r
+ CONST UINT8 *Src;\r
+ volatile UINT8 *Dst;\r
+ UINTN Byte;\r
+\r
+ Src = (CONST UINT8 *)&mIdtEntryTemplate;\r
+ Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];\r
+ for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {\r
+ Dst[Byte] = Src[Byte];\r
+ }\r
+ }\r
+\r
+ IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;\r
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
+\r
+ if (SevEsIsEnabled ()) {\r
+ SevEsProtocolCheck ();\r
+\r
+ //\r
+ // For SEV-ES guests, the exception handler is needed before calling\r
+ // ProcessLibraryConstructorList() because some of the library constructors\r
+ // perform some functions that result in #VC exceptions being generated.\r
+ //\r
+ // Due to this code executing before library constructors, *all* library\r
+ // API calls are theoretically interface contract violations. However,\r
+ // because this is SEC (executing in flash), those constructors cannot\r
+ // write variables with static storage duration anyway. Furthermore, only\r
+ // a small, restricted set of APIs, such as AsmWriteIdtr() and\r
+ // InitializeCpuExceptionHandlers(), are called, where we require that the\r
+ // underlying library not require constructors to have been invoked and\r
+ // that the library instance not trigger any #VC exceptions.\r
+ //\r
+ AsmWriteIdtr (&IdtDescriptor);\r
+ InitializeCpuExceptionHandlers (NULL);\r
+ }\r
+\r