]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Import two CPU Exception Handler Library instances: SecPeiCpuExceptionHandler.inf...
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 15 Mar 2012 05:24:07 +0000 (05:24 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 15 Mar 2012 05:24:07 +0000 (05:24 +0000)
Signed-off-by: vanjeff
Reviewed-by: jyao1
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13098 6f19259b-4bc3-4df7-8a09-765794883524

13 files changed:
UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm [new file with mode: 0644]
UefiCpuPkg/UefiCpuPkg.dsc

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
new file mode 100644 (file)
index 0000000..4a4925a
--- /dev/null
@@ -0,0 +1,132 @@
+/** @file\r
+  CPU Exception Hanlder Library common functions.\r
+\r
+  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "CpuExceptionCommon.h"\r
+\r
+//\r
+// Error code flag indicating whether or not an error code will be \r
+// pushed on the stack if an exception occurs.\r
+//\r
+// 1 means an error code will be pushed, otherwise 0\r
+//\r
+UINT32 mErrorCodeFlag = 0x00027d00;\r
+\r
+//\r
+// Define the maximum message length \r
+//\r
+#define MAX_DEBUG_MESSAGE_LENGTH  0x100\r
+\r
+/**\r
+  Prints a message to the serial port.\r
+\r
+  @param  Format      Format string for the message to print.\r
+  @param  ...         Variable argument list whose contents are accessed \r
+                      based on the format string specified by Format.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalPrintMessage (\r
+  IN  CONST CHAR8  *Format,\r
+  ...\r
+  )\r
+{\r
+  CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
+  VA_LIST  Marker;\r
+\r
+  //\r
+  // Convert the message to an ASCII String\r
+  //\r
+  VA_START (Marker, Format);\r
+  AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
+  VA_END (Marker);\r
+\r
+  //\r
+  // Send the print string to a Serial Port \r
+  //\r
+  SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));\r
+}\r
+\r
+/**\r
+  Find and display image base address and return image base and its entry point.\r
+  \r
+  @return EFI_SUCCESS     Image base address.\r
+  @return 0               Image header cannot be found.\r
+**/\r
+UINTN \r
+FindModuleImageBase (\r
+  IN  UINTN              CurrentEip,\r
+  OUT UINTN              *EntryPoint\r
+  )\r
+{\r
+  UINTN                                Pe32Data;\r
+  EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;\r
+  VOID                                 *PdbPointer;\r
+\r
+  //\r
+  // Find Image Base\r
+  //\r
+  Pe32Data = CurrentEip & ~(mImageAlignSize - 1);\r
+  while (Pe32Data != 0) {\r
+    DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
+    if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+      //\r
+      // DOS image header is present, so read the PE header after the DOS image header.\r
+      //\r
+      Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+      if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
+        //\r
+        // It's PE image.\r
+        //\r
+        InternalPrintMessage ("!!!! Find PE image ");\r
+        *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff);\r
+        break;\r
+      }\r
+    } else {\r
+      //\r
+      // DOS image header is not present, TE header is at the image base.\r
+      //\r
+      Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
+      if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) &&\r
+          ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) {\r
+        //\r
+        // It's TE image, it TE header and Machine type match\r
+        //\r
+        InternalPrintMessage ("!!!! Find TE image ");\r
+        *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
+        break;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Not found the image base, check the previous aligned address\r
+    // \r
+    Pe32Data -= mImageAlignSize;\r
+  }\r
+\r
+  if (Pe32Data != 0) {\r
+    PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);\r
+    if (PdbPointer != NULL) {\r
+      InternalPrintMessage ("%a", PdbPointer);\r
+    } else {\r
+      InternalPrintMessage ("(No PDB) " );\r
+    }\r
+  } else {\r
+    InternalPrintMessage ("!!!! Can't find image information. !!!!\n");\r
+  }\r
+\r
+  return Pe32Data;\r
+}\r
+\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
new file mode 100644 (file)
index 0000000..fa245e2
--- /dev/null
@@ -0,0 +1,96 @@
+/** @file\r
+  Common header file for CPU Exception Handler Library.\r
+\r
+  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _CPU_EXCEPTION_COMMON_H_\r
+#define _CPU_EXCEPTION_COMMON_H_\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/LocalApicLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+\r
+#define  CPU_EXCEPTION_NUM     32\r
+//\r
+// Record exception handler information\r
+//\r
+typedef struct {\r
+  UINTN ExceptionStart;\r
+  UINTN ExceptionStubHeaderSize;\r
+} EXCEPTION_HANDLER_TEMPLATE_MAP;\r
+\r
+extern UINT32           mErrorCodeFlag;\r
+extern CONST UINTN      mImageAlignSize;\r
+\r
+/**\r
+  Return address map of exception handler template so that C code can generate\r
+  exception tables.\r
+\r
+  @param AddressMap  Pointer to a buffer where the address map is returned.\r
+**/\r
+VOID\r
+EFIAPI\r
+GetTemplateAddressMap (\r
+  OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
+  );\r
+\r
+/**\r
+  Internal function to setup CPU exception handlers.\r
+\r
+**/\r
+VOID\r
+InternalSetupCpuExceptionHandlers (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Prints a message to the serial port.\r
+\r
+  @param  Format      Format string for the message to print.\r
+  @param  ...         Variable argument list whose contents are accessed \r
+                      based on the format string specified by Format.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalPrintMessage (\r
+  IN  CONST CHAR8  *Format,\r
+  ...\r
+  );\r
+\r
+/**\r
+  Find and display image base address and return image base and its entry point.\r
+  \r
+  @return EFI_SUCCESS     Image base address.\r
+  @return 0               Image header cannot be found.\r
+**/\r
+UINTN \r
+FindModuleImageBase (\r
+  IN  UINTN              CurrentEip,\r
+  OUT UINTN              *EntryPoint\r
+  );\r
+\r
+/**\r
+  Display CPU information.\r
+\r
+  @param InterruptType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+DumpCpuContent (\r
+  IN UINTN                InterruptType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  );\r
+\r
+#endif\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
new file mode 100644 (file)
index 0000000..3110687
--- /dev/null
@@ -0,0 +1,84 @@
+/** @file\r
+  CPU Exception Library provides DXE/SMM CPU exception handler.\r
+\r
+Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+\r
+#include "CpuExceptionCommon.h"\r
+#include <Library/SynchronizationLib.h>\r
+\r
+//\r
+// Spinlock for CPU information display\r
+//\r
+SPIN_LOCK        mDisplayMessageSpinLock;\r
+\r
+//\r
+// Image align size for DXE/SMM\r
+//\r
+CONST UINTN      mImageAlignSize = SIZE_4KB;\r
+\r
+/**\r
+  Common exception handler.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+EFIAPI\r
+CommonExceptionHandler (\r
+  IN EFI_EXCEPTION_TYPE   ExceptionType, \r
+  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  )\r
+{\r
+  //\r
+  // Get Spinlock to display CPU information\r
+  //\r
+  while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) {\r
+    CpuPause ();\r
+  }\r
+\r
+  //\r
+  // Display ExceptionType, CPU information and Image information\r
+  //\r
+  DumpCpuContent (ExceptionType, SystemContext);\r
+\r
+  //\r
+  // Release Spinlock\r
+  //\r
+  ReleaseSpinLock (&mDisplayMessageSpinLock);\r
+\r
+  //\r
+  // Enter a dead loop.\r
+  //\r
+  CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+  Setup CPU exception handlers.\r
+\r
+  This API will setups the CPU exception handler to display CPU contents and run into\r
+  CpuDeadLoop(). \r
+  @Note: Before invoking this API, caller must allocate memory for IDT table and load \r
+         IDTR by AsmWriteIdtr().\r
+  \r
+**/\r
+VOID\r
+EFIAPI\r
+SetupCpuExceptionHandlers (\r
+  IN VOID\r
+  )\r
+{\r
+  InitializeSpinLock (&mDisplayMessageSpinLock);\r
+  InternalSetupCpuExceptionHandlers ();\r
+}\r
+\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf
new file mode 100644 (file)
index 0000000..9f0f2d9
--- /dev/null
@@ -0,0 +1,57 @@
+## @file\r
+#  Component description file for DXE/SMM CPU Exception Handler Library instance.\r
+#\r
+#  This library instance supports DXE SMM module only.\r
+#\r
+#  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeSmmCpuExceptionHandlerLib\r
+  FILE_GUID                      = EC629480-BD36-4e8e-8AB2-D28BF0D45864\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = CpuExceptionHandlerLib|DXE_CORE DXE_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.Ia32]\r
+  Ia32/ExceptionHandlerAsm.asm |MSFT\r
+  Ia32/ExceptionHandlerAsm.S   |GCC\r
+  Ia32/ArchExceptionHandler.c\r
+\r
+[Sources.X64]\r
+  X64/ExceptionHandlerAsm.asm   |MSFT\r
+  X64/ExceptionHandlerAsm.S     |GCC\r
+  X64/ArchExceptionHandler.c\r
+\r
+[Sources.common]\r
+  CpuExceptionCommon.h\r
+  CpuExceptionCommon.c\r
+  DxeSmmCpuException.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  SerialPortLib\r
+  PrintLib\r
+  SynchronizationLib\r
+  LocalApicLib\r
+  PeCoffGetEntryPointLib \r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
new file mode 100644 (file)
index 0000000..a69f0d3
--- /dev/null
@@ -0,0 +1,164 @@
+/** @file\r
+  IA32 CPU Exception Hanlder functons.\r
+\r
+  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "CpuExceptionCommon.h"\r
+\r
+/**\r
+  Internal function to setup CPU exception handlers.\r
+\r
+**/\r
+VOID\r
+InternalSetupCpuExceptionHandlers (\r
+  VOID\r
+  )\r
+{\r
+  IA32_DESCRIPTOR                     IdtDescriptor;\r
+  UINTN                               IdtSize;\r
+  EXCEPTION_HANDLER_TEMPLATE_MAP      TemplateMap;\r
+  UINT16                              CodeSegment;\r
+  IA32_IDT_GATE_DESCRIPTOR            *IdtEntry;\r
+  UINTN                               Index;\r
+  UINTN                               InterruptHandler;;\r
+\r
+  //\r
+  // Read IDT descriptor and calculate IDT size\r
+  //\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtSize = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
+  if (IdtSize > CPU_EXCEPTION_NUM) {\r
+    //\r
+    // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most\r
+    //\r
+    IdtSize = CPU_EXCEPTION_NUM;\r
+  }\r
+\r
+  //\r
+  // Use current CS as the segment selector of interrupt gate in IDT\r
+  //\r
+  CodeSegment = AsmReadCs ();\r
+  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+\r
+  GetTemplateAddressMap (&TemplateMap);\r
+\r
+  for (Index = 0; Index < IdtSize; Index ++) {\r
+    InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;\r
+    IdtEntry[Index].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;\r
+    IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);\r
+    IdtEntry[Index].Bits.Selector   = CodeSegment;\r
+    IdtEntry[Index].Bits.GateType   = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+  }\r
+}\r
+\r
+/**\r
+  Dump CPU content information.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+DumpCpuContent (\r
+  IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  )\r
+{\r
+  UINTN                   ImageBase;\r
+  UINTN                   EntryPoint;\r
+\r
+  InternalPrintMessage (\r
+    "!!!! IA32 Exception Type - %08x    CPU Apic ID - %08x !!!!\n",\r
+    ExceptionType,\r
+    GetApicId ()\r
+    );\r
+  InternalPrintMessage (\r
+    "EIP  - %08x, CS  - %08x, EFLAGS - %08x\n",\r
+    SystemContext.SystemContextIa32->Eip,\r
+    SystemContext.SystemContextIa32->Cs,\r
+    SystemContext.SystemContextIa32->Eflags\r
+    );\r
+  if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) {\r
+    InternalPrintMessage (\r
+      "ExceptionData - %08x\n",\r
+      SystemContext.SystemContextIa32->ExceptionData\r
+      );\r
+  }\r
+  InternalPrintMessage (\r
+    "EAX  - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",\r
+    SystemContext.SystemContextIa32->Eax,\r
+    SystemContext.SystemContextIa32->Ecx,\r
+    SystemContext.SystemContextIa32->Edx,\r
+    SystemContext.SystemContextIa32->Ebx\r
+    );\r
+  InternalPrintMessage (\r
+    "ESP  - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",\r
+    SystemContext.SystemContextIa32->Esp,\r
+    SystemContext.SystemContextIa32->Ebp,\r
+    SystemContext.SystemContextIa32->Esi,\r
+    SystemContext.SystemContextIa32->Edi\r
+    );\r
+  InternalPrintMessage (\r
+    "DS   - %08x, ES  - %08x, FS  - %08x, GS  - %08x, SS - %08x\n",\r
+    SystemContext.SystemContextIa32->Ds,\r
+    SystemContext.SystemContextIa32->Es,\r
+    SystemContext.SystemContextIa32->Fs,\r
+    SystemContext.SystemContextIa32->Gs,\r
+    SystemContext.SystemContextIa32->Ss\r
+    );\r
+  InternalPrintMessage (\r
+    "CR0  - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",\r
+    SystemContext.SystemContextIa32->Cr0,\r
+    SystemContext.SystemContextIa32->Cr2,\r
+    SystemContext.SystemContextIa32->Cr3,\r
+    SystemContext.SystemContextIa32->Cr4\r
+    );\r
+  InternalPrintMessage (\r
+    "DR0  - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",\r
+    SystemContext.SystemContextIa32->Dr0,\r
+    SystemContext.SystemContextIa32->Dr1,\r
+    SystemContext.SystemContextIa32->Dr2,\r
+    SystemContext.SystemContextIa32->Dr3\r
+    );\r
+  InternalPrintMessage (\r
+    "DR6  - %08x, DR7 - %08x\n",\r
+    SystemContext.SystemContextIa32->Dr6,\r
+    SystemContext.SystemContextIa32->Dr7\r
+    );\r
+  InternalPrintMessage (\r
+    "GDTR - %08x %08x, IDTR - %08x %08x\n",\r
+    SystemContext.SystemContextIa32->Gdtr[0],\r
+    SystemContext.SystemContextIa32->Gdtr[1],\r
+    SystemContext.SystemContextIa32->Idtr[0],\r
+    SystemContext.SystemContextIa32->Idtr[1]\r
+    );\r
+  InternalPrintMessage (\r
+    "LDTR - %08x, TR - %08x\n",\r
+    SystemContext.SystemContextIa32->Ldtr,\r
+    SystemContext.SystemContextIa32->Tr\r
+    );\r
+  InternalPrintMessage (\r
+    "FXSAVE_STATE - %08x\n",\r
+    &SystemContext.SystemContextIa32->FxSaveState\r
+    );\r
+\r
+  //\r
+  // Find module image base and module entry point by RIP\r
+  //\r
+  ImageBase = FindModuleImageBase (SystemContext.SystemContextIa32->Eip, &EntryPoint);\r
+  if (ImageBase != 0) {\r
+    InternalPrintMessage (\r
+      " (ImageBase=%08x, EntryPoint=%08x) !!!!\n",\r
+      ImageBase,\r
+      EntryPoint\r
+      );\r
+  }\r
+}\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
new file mode 100644 (file)
index 0000000..8b3f631
--- /dev/null
@@ -0,0 +1,467 @@
+#------------------------------------------------------------------------------\r
+#*\r
+#*   Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+#*   This program and the accompanying materials\r
+#*   are licensed and made available under the terms and conditions of the BSD License\r
+#*   which accompanies this distribution.  The full text of the license may be found at\r
+#*   http://opensource.org/licenses/bsd-license.php\r
+#*\r
+#*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#*\r
+#*    ExceptionHandlerAsm.S\r
+#*\r
+#*   Abstract:\r
+#*\r
+#*     IA32 CPU Exception Handler\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+\r
+\r
+\r
+\r
+#.MMX\r
+#.XMM\r
+\r
+ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+\r
+.text\r
+\r
+#\r
+# exception handler stub table\r
+#\r
+Exception0Handle:\r
+    pushl   $0\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception1Handle:\r
+    pushl   $1\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception2Handle:\r
+    pushl   $2\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception3Handle:\r
+    pushl    $3\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception4Handle:\r
+    pushl    $4\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception5Handle:\r
+    pushl    $5\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception6Handle:\r
+    pushl    $6\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception7Handle:\r
+    pushl    $7\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception8Handle:\r
+    pushl    $8\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception9Handle:\r
+    pushl    $9\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception10Handle:\r
+    pushl    $10\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception11Handle:\r
+    pushl    $11\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception12Handle:\r
+    pushl    $12\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception13Handle:\r
+    pushl    $13\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception14Handle:\r
+    pushl    $14\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception15Handle:\r
+    pushl    $15\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception16Handle:\r
+    pushl    $16\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception17Handle:\r
+    pushl    $17\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception18Handle:\r
+    pushl    $18\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception19Handle:\r
+    pushl    $19\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception20Handle:\r
+    pushl    $20\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception21Handle:\r
+    pushl    $21\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception22Handle:\r
+    pushl    $22\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception23Handle:\r
+    pushl    $23\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception24Handle:\r
+    pushl    $24\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception25Handle:\r
+    pushl    $25\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception26Handle:\r
+    pushl    $26\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception27Handle:\r
+    pushl    $27\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception28Handle:\r
+    pushl    $28\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception29Handle:\r
+    pushl    $29\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception30Handle:\r
+    pushl    $30\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception31Handle:\r
+    pushl    $31\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+\r
+#---------------------------------------;\r
+# CommonInterruptEntry                  ;\r
+#---------------------------------------;\r
+# The follow algorithm is used for the common interrupt routine.\r
+\r
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_PFX(CommonInterruptEntry):\r
+    cli\r
+    #\r
+    # All interrupt handlers are invoked through interrupt gates, so\r
+    # IF flag automatically cleared at the entry point\r
+    #\r
+\r
+    #\r
+    # Calculate vector number\r
+    #\r
+    # Get the return address of call, actually, it is the\r
+    # address of vector number.\r
+    #\r
+    xchgl   (%esp), %ecx\r
+    andl    $0x0FFFF, %ecx\r
+    cmpl    $32, %ecx         # Intel reserved vector for exceptions?\r
+    jae     NoErrorCode\r
+    bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
+    jc      HasErrorCode\r
+\r
+NoErrorCode:\r
+\r
+    #\r
+    # Stack:\r
+    # +---------------------+\r
+    # +    EFlags           +\r
+    # +---------------------+\r
+    # +    CS               +\r
+    # +---------------------+\r
+    # +    EIP              +\r
+    # +---------------------+\r
+    # +    ECX              +\r
+    # +---------------------+ <-- ESP\r
+    #\r
+    # Registers:\r
+    #   ECX - Vector Number\r
+    #\r
+\r
+    #\r
+    # Put Vector Number on stack\r
+    #\r
+    pushl   %ecx\r
+\r
+    #\r
+    # Put 0 (dummy) error code on stack, and restore ECX\r
+    #\r
+    xorl    %ecx, %ecx  # ECX = 0\r
+    xchgl   4(%esp), %ecx\r
+\r
+    jmp     ErrorCodeAndVectorOnStack\r
+\r
+HasErrorCode:\r
+\r
+    #\r
+    # Stack:\r
+    # +---------------------+\r
+    # +    EFlags           +\r
+    # +---------------------+\r
+    # +    CS               +\r
+    # +---------------------+\r
+    # +    EIP              +\r
+    # +---------------------+\r
+    # +    Error Code       +\r
+    # +---------------------+\r
+    # +    ECX              +\r
+    # +---------------------+ <-- ESP\r
+    #\r
+    # Registers:\r
+    #   ECX - Vector Number\r
+    #\r
+\r
+    #\r
+    # Put Vector Number on stack and restore ECX\r
+    #\r
+    xchgl   (%esp), %ecx \r
+\r
+    #\r
+    # Fall through to join main routine code\r
+    # at ErrorCodeAndVectorOnStack\r
+    #\r
+CommonInterruptEntry_al_0000:\r
+    jmp CommonInterruptEntry_al_0000\r
+\r
+ErrorCodeAndVectorOnStack:\r
+    pushl   %ebp\r
+    movl    %esp, %ebp\r
+\r
+    #\r
+    # Stack:\r
+    # +---------------------+\r
+    # +    EFlags           +\r
+    # +---------------------+\r
+    # +    CS               +\r
+    # +---------------------+\r
+    # +    EIP              +\r
+    # +---------------------+\r
+    # +    Error Code       +\r
+    # +---------------------+\r
+    # +    Vector Number    +\r
+    # +---------------------+\r
+    # +    EBP              +\r
+    # +---------------------+ <-- EBP\r
+    #\r
+\r
+    #\r
+    # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
+    # is 16-byte aligned\r
+    #\r
+    andl    $0x0fffffff0, %esp \r
+    subl    $12, %esp\r
+\r
+#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+    pushl   %eax\r
+    pushl   %ecx\r
+    pushl   %edx\r
+    pushl   %ebx\r
+    leal    24(%ebp), %ecx\r
+    pushl   %ecx                          # ESP\r
+    pushl   (%ebp)              # EBP\r
+    pushl   %esi\r
+    pushl   %edi\r
+\r
+#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
+    movl    %ss, %eax\r
+    pushl   %eax\r
+    movzwl  16(%ebp), %eax \r
+    pushl   %eax\r
+    movl    %ds, %eax\r
+    pushl   %eax\r
+    movl    %es, %eax\r
+    pushl   %eax\r
+    movl    %fs, %eax\r
+    pushl   %eax\r
+    movl    %gs, %eax\r
+    pushl   %eax\r
+\r
+#; UINT32  Eip;\r
+    movl    12(%ebp), %eax\r
+    pushl   %eax\r
+\r
+#; UINT32  Gdtr[2], Idtr[2];\r
+    subl    $8, %esp\r
+    sidt    (%esp)\r
+    movl    2(%esp), %eax\r
+    xchgl   (%esp), %eax\r
+    andl    $0x0FFFF, %eax \r
+    movl    %eax, 4(%esp)\r
+\r
+    subl    $8, %esp\r
+    sgdt    (%esp)\r
+    movl    2(%esp), %eax\r
+    xchgl   (%esp), %eax\r
+    andl    $0x0FFFF, %eax \r
+    movl    %eax, 4(%esp)\r
+\r
+#; UINT32  Ldtr, Tr;\r
+    xorl    %eax, %eax\r
+    str     %ax\r
+    pushl   %eax\r
+    sldt    %ax\r
+    pushl   %eax\r
+\r
+#; UINT32  EFlags;\r
+    movl    20(%ebp), %eax\r
+    pushl   %eax\r
+\r
+#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    movl    %cr4, %eax\r
+    orl     $0x208, %eax\r
+    movl    %eax, %cr4\r
+    pushl   %eax\r
+    movl    %cr3, %eax\r
+    pushl   %eax\r
+    movl    %cr2, %eax\r
+    pushl   %eax\r
+    xorl    %eax, %eax\r
+    pushl   %eax\r
+    movl    %cr0, %eax\r
+    pushl   %eax\r
+\r
+#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    movl    %dr7, %eax\r
+    pushl   %eax\r
+    movl    %dr6, %eax\r
+    pushl   %eax\r
+    movl    %dr3, %eax\r
+    pushl   %eax\r
+    movl    %dr2, %eax\r
+    pushl   %eax\r
+    movl    %dr1, %eax\r
+    pushl   %eax\r
+    movl    %dr0, %eax\r
+    pushl   %eax\r
+\r
+#; FX_SAVE_STATE_IA32 FxSaveState;\r
+    subl    $512, %esp\r
+    movl    %esp, %edi\r
+    .byte      0x0f, 0x0ae, 0x07 #fxsave [edi]\r
+\r
+#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
+    cld\r
+\r
+#; UINT32  ExceptionData;\r
+    pushl   8(%ebp)\r
+\r
+#; Prepare parameter and call\r
+    movl    %esp, %edx\r
+    pushl   %edx\r
+    movl    4(%ebp), %edx\r
+    pushl   %edx\r
+\r
+    #\r
+    # Call External Exception Handler\r
+    #\r
+    call    ASM_PFX(CommonExceptionHandler)\r
+    addl    $8, %esp\r
+\r
+    cli\r
+#; UINT32  ExceptionData;\r
+    addl    $4, %esp\r
+\r
+#; FX_SAVE_STATE_IA32 FxSaveState;\r
+    movl    %esp, %esi\r
+    .byte      0x0f, 0x0ae, 0x0e # fxrstor [esi]\r
+    addl    $512, %esp\r
+\r
+#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+#; Skip restoration of DRx registers to support in-circuit emualators\r
+#; or debuggers set breakpoint in interrupt/exception context\r
+    addl    $24, %esp\r
+\r
+#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    popl    %eax\r
+    movl    %eax, %cr0\r
+    addl    $4, %esp    # not for Cr1\r
+    popl    %eax\r
+    movl    %eax, %cr2\r
+    popl    %eax\r
+    movl    %eax, %cr3\r
+    popl    %eax\r
+    movl    %eax, %cr4\r
+\r
+#; UINT32  EFlags;\r
+    popl    20(%ebp)\r
+\r
+#; UINT32  Ldtr, Tr;\r
+#; UINT32  Gdtr[2], Idtr[2];\r
+#; Best not let anyone mess with these particular registers...\r
+    addl    $24, %esp\r
+\r
+#; UINT32  Eip;\r
+    popl    12(%ebp)\r
+\r
+#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
+#; NOTE - modified segment registers could hang the debugger...  We\r
+#;        could attempt to insulate ourselves against this possibility,\r
+#;        but that poses risks as well.\r
+#;\r
+    popl    %gs\r
+    popl    %fs\r
+    popl    %es\r
+    popl    %ds\r
+    popl    16(%ebp)\r
+    popl    %ss\r
+\r
+#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+    popl    %edi\r
+    popl    %esi\r
+    addl    $4, %esp   # not for ebp\r
+    addl    $4, %esp   # not for esp\r
+    popl    %ebx\r
+    popl    %edx\r
+    popl    %ecx\r
+    popl    %eax\r
+\r
+    movl    %ebp, %esp\r
+    popl    %ebp\r
+    addl    $8, %esp\r
+    iretl\r
+\r
+\r
+#---------------------------------------;\r
+# _GetTemplateAddressMap                  ;\r
+#----------------------------------------------------------------------------;\r
+# \r
+# Protocol prototype\r
+#   GetTemplateAddressMap (\r
+#     EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
+#   );\r
+#           \r
+# Routine Description:\r
+# \r
+#  Return address map of interrupt handler template so that C code can generate\r
+#  interrupt table.\r
+# \r
+# Arguments:\r
+# \r
+# \r
+# Returns: \r
+# \r
+#   Nothing\r
+#\r
+# \r
+# Input:  [ebp][0]  = Original ebp\r
+#         [ebp][4]  = Return address\r
+#          \r
+# Output: Nothing\r
+#          \r
+# Destroys: Nothing\r
+#-----------------------------------------------------------------------------;\r
+#-------------------------------------------------------------------------------------\r
+#  AsmGetAddressMap (&AddressMap);\r
+#-------------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)\r
+ASM_PFX(GetTemplateAddressMap):\r
+\r
+        pushl       %ebp\r
+        movl        %esp,%ebp\r
+        pushal\r
+\r
+        movl        0x8(%ebp), %ebx\r
+        movl        $Exception0Handle, (%ebx)\r
+        movl        $(Exception1Handle - Exception0Handle), 0x4(%ebx)\r
+\r
+        popal\r
+        popl        %ebp\r
+        ret\r
+\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
new file mode 100644 (file)
index 0000000..dc71959
--- /dev/null
@@ -0,0 +1,471 @@
+;------------------------------------------------------------------------------ ;\r
+; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Module Name:\r
+;\r
+;   ExceptionHandlerAsm.Asm\r
+;\r
+; Abstract:\r
+;\r
+;   IA32 CPU Exception Handler\r
+;\r
+; Notes:\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    .686\r
+    .model  flat,C\r
+\r
+;\r
+; CommonExceptionHandler()\r
+;\r
+CommonExceptionHandler             PROTO   C\r
+\r
+.data\r
+\r
+CommonEntryAddr           DD    CommonInterruptEntry\r
+\r
+EXTRN mErrorCodeFlag:DWORD             ; Error code flags for exceptions\r
+\r
+.code\r
+\r
+;\r
+; exception handler stub table\r
+;\r
+Exception0Handle:\r
+    push    0\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception1Handle:\r
+    push    1\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception2Handle:\r
+    push    2\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception3Handle:\r
+    push    3\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception4Handle:\r
+    push    4\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception5Handle:\r
+    push    5\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception6Handle:\r
+    push    6\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception7Handle:\r
+    push    7\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception8Handle:\r
+    push    8\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception9Handle:\r
+    push    9\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception10Handle:\r
+    push    10\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception11Handle:\r
+    push    11\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception12Handle:\r
+    push    12\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception13Handle:\r
+    push    13\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception14Handle:\r
+    push    14\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception15Handle:\r
+    push    15\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception16Handle:\r
+    push    16\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception17Handle:\r
+    push    17\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception18Handle:\r
+    push    18\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception19Handle:\r
+    push    19\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception20Handle:\r
+    push    20\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception21Handle:\r
+    push    21\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception22Handle:\r
+    push    22\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception23Handle:\r
+    push    23\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception24Handle:\r
+    push    24\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception25Handle:\r
+    push    25\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception26Handle:\r
+    push    26\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception27Handle:\r
+    push    27\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception28Handle:\r
+    push    28\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception29Handle:\r
+    push    29\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception30Handle:\r
+    push    30\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception31Handle:\r
+    push    31\r
+    jmp     dword ptr [CommonEntryAddr]\r
+\r
+;----------------------------------------------------------------------------;\r
+; CommonInterruptEntry                                                               ;\r
+;----------------------------------------------------------------------------;\r
+; The follow algorithm is used for the common interrupt routine.\r
+; Entry from each interrupt with a push eax and eax=interrupt number\r
+\r
+CommonInterruptEntry PROC PUBLIC\r
+    cli\r
+    ;\r
+    ; All interrupt handlers are invoked through interrupt gates, so\r
+    ; IF flag automatically cleared at the entry point\r
+    ;\r
+\r
+    ;\r
+    ; Calculate vector number\r
+    ;\r
+    ; Get the return address of call, actually, it is the\r
+    ; address of vector number.\r
+    ;\r
+    xchg    ecx, [esp]\r
+    and     ecx, 0FFFFh\r
+    cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
+    jae     NoErrorCode\r
+    bt      mErrorCodeFlag, ecx\r
+    jc      HasErrorCode\r
+\r
+NoErrorCode:\r
+\r
+    ;\r
+    ; Stack:\r
+    ; +---------------------+\r
+    ; +    EFlags           +\r
+    ; +---------------------+\r
+    ; +    CS               +\r
+    ; +---------------------+\r
+    ; +    EIP              +\r
+    ; +---------------------+\r
+    ; +    ECX              +\r
+    ; +---------------------+ <-- ESP\r
+    ;\r
+    ; Registers:\r
+    ;   ECX - Vector Number\r
+    ;\r
+\r
+    ;\r
+    ; Put Vector Number on stack\r
+    ;\r
+    push    ecx\r
+\r
+    ;\r
+    ; Put 0 (dummy) error code on stack, and restore ECX\r
+    ;\r
+    xor     ecx, ecx  ; ECX = 0\r
+    xchg    ecx, [esp+4]\r
+\r
+    jmp     ErrorCodeAndVectorOnStack\r
+\r
+HasErrorCode:\r
+\r
+    ;\r
+    ; Stack:\r
+    ; +---------------------+\r
+    ; +    EFlags           +\r
+    ; +---------------------+\r
+    ; +    CS               +\r
+    ; +---------------------+\r
+    ; +    EIP              +\r
+    ; +---------------------+\r
+    ; +    Error Code       +\r
+    ; +---------------------+\r
+    ; +    ECX              +\r
+    ; +---------------------+ <-- ESP\r
+    ;\r
+    ; Registers:\r
+    ;   ECX - Vector Number\r
+    ;\r
+\r
+    ;\r
+    ; Put Vector Number on stack and restore ECX\r
+    ;\r
+    xchg    ecx, [esp]\r
+\r
+    ;\r
+    ; Fall through to join main routine code\r
+    ; at ErrorCodeAndVectorOnStack\r
+    ;\r
+@@:\r
+    jmp @B\r
+\r
+ErrorCodeAndVectorOnStack:\r
+    push    ebp\r
+    mov     ebp, esp\r
+\r
+    ;\r
+    ; Stack:\r
+    ; +---------------------+\r
+    ; +    EFlags           +\r
+    ; +---------------------+\r
+    ; +    CS               +\r
+    ; +---------------------+\r
+    ; +    EIP              +\r
+    ; +---------------------+\r
+    ; +    Error Code       +\r
+    ; +---------------------+\r
+    ; +    Vector Number    +\r
+    ; +---------------------+\r
+    ; +    EBP              +\r
+    ; +---------------------+ <-- EBP\r
+    ;\r
+\r
+    ;\r
+    ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
+    ; is 16-byte aligned\r
+    ;\r
+    and     esp, 0fffffff0h\r
+    sub     esp, 12\r
+\r
+;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+    push    eax\r
+    push    ecx\r
+    push    edx\r
+    push    ebx\r
+    lea     ecx, [ebp + 6 * 4]\r
+    push    ecx                          ; ESP\r
+    push    dword ptr [ebp]              ; EBP\r
+    push    esi\r
+    push    edi\r
+\r
+;; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
+    mov     eax, ss\r
+    push    eax\r
+    movzx   eax, word ptr [ebp + 4 * 4]\r
+    push    eax\r
+    mov     eax, ds\r
+    push    eax\r
+    mov     eax, es\r
+    push    eax\r
+    mov     eax, fs\r
+    push    eax\r
+    mov     eax, gs\r
+    push    eax\r
+\r
+;; UINT32  Eip;\r
+    mov     eax, [ebp + 3 * 4]\r
+    push    eax\r
+\r
+;; UINT32  Gdtr[2], Idtr[2];\r
+    sub     esp, 8\r
+    sidt    [esp]\r
+    mov     eax, [esp + 2]\r
+    xchg    eax, [esp]\r
+    and     eax, 0FFFFh\r
+    mov     [esp+4], eax\r
+\r
+    sub     esp, 8\r
+    sgdt    [esp]\r
+    mov     eax, [esp + 2]\r
+    xchg    eax, [esp]\r
+    and     eax, 0FFFFh\r
+    mov     [esp+4], eax\r
+\r
+;; UINT32  Ldtr, Tr;\r
+    xor     eax, eax\r
+    str     ax\r
+    push    eax\r
+    sldt    ax\r
+    push    eax\r
+\r
+;; UINT32  EFlags;\r
+    mov     eax, [ebp + 5 * 4]\r
+    push    eax\r
+\r
+;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    mov     eax, cr4\r
+    or      eax, 208h\r
+    mov     cr4, eax\r
+    push    eax\r
+    mov     eax, cr3\r
+    push    eax\r
+    mov     eax, cr2\r
+    push    eax\r
+    xor     eax, eax\r
+    push    eax\r
+    mov     eax, cr0\r
+    push    eax\r
+\r
+;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    mov     eax, dr7\r
+    push    eax\r
+    mov     eax, dr6\r
+    push    eax\r
+    mov     eax, dr3\r
+    push    eax\r
+    mov     eax, dr2\r
+    push    eax\r
+    mov     eax, dr1\r
+    push    eax\r
+    mov     eax, dr0\r
+    push    eax\r
+\r
+;; FX_SAVE_STATE_IA32 FxSaveState;\r
+    sub     esp, 512\r
+    mov     edi, esp\r
+    db      0fh, 0aeh, 07h ;fxsave [edi]\r
+\r
+;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
+    cld\r
+\r
+;; UINT32  ExceptionData;\r
+    push    dword ptr [ebp + 2 * 4]\r
+\r
+;; Prepare parameter and call\r
+    mov     edx, esp\r
+    push    edx\r
+    mov     edx, dword ptr [ebp + 1 * 4]\r
+    push    edx\r
+\r
+    ;\r
+    ; Call External Exception Handler\r
+    ;\r
+    mov     eax, CommonExceptionHandler\r
+    call    eax\r
+    add     esp, 8\r
+\r
+    cli\r
+;; UINT32  ExceptionData;\r
+    add     esp, 4\r
+\r
+;; FX_SAVE_STATE_IA32 FxSaveState;\r
+    mov     esi, esp\r
+    db      0fh, 0aeh, 0eh ; fxrstor [esi]\r
+    add     esp, 512\r
+\r
+;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+;; Skip restoration of DRx registers to support in-circuit emualators\r
+;; or debuggers set breakpoint in interrupt/exception context\r
+    add     esp, 4 * 6\r
+\r
+;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    pop     eax\r
+    mov     cr0, eax\r
+    add     esp, 4    ; not for Cr1\r
+    pop     eax\r
+    mov     cr2, eax\r
+    pop     eax\r
+    mov     cr3, eax\r
+    pop     eax\r
+    mov     cr4, eax\r
+\r
+;; UINT32  EFlags;\r
+    pop     dword ptr [ebp + 5 * 4]\r
+\r
+;; UINT32  Ldtr, Tr;\r
+;; UINT32  Gdtr[2], Idtr[2];\r
+;; Best not let anyone mess with these particular registers...\r
+    add     esp, 24\r
+\r
+;; UINT32  Eip;\r
+    pop     dword ptr [ebp + 3 * 4]\r
+\r
+;; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
+;; NOTE - modified segment registers could hang the debugger...  We\r
+;;        could attempt to insulate ourselves against this possibility,\r
+;;        but that poses risks as well.\r
+;;\r
+    pop     gs\r
+    pop     fs\r
+    pop     es\r
+    pop     ds\r
+    pop     dword ptr [ebp + 4 * 4]\r
+    pop     ss\r
+\r
+;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+    pop     edi\r
+    pop     esi\r
+    add     esp, 4   ; not for ebp\r
+    add     esp, 4   ; not for esp\r
+    pop     ebx\r
+    pop     edx\r
+    pop     ecx\r
+    pop     eax\r
+\r
+    mov     esp, ebp\r
+    pop     ebp\r
+    add     esp, 8\r
+    iretd\r
+\r
+CommonInterruptEntry ENDP\r
+\r
+;---------------------------------------;\r
+; _GetTemplateAddressMap                  ;\r
+;----------------------------------------------------------------------------;\r
+; \r
+; Protocol prototype\r
+;   GetTemplateAddressMap (\r
+;     EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
+;   );\r
+;           \r
+; Routine Description:\r
+; \r
+;  Return address map of interrupt handler template so that C code can generate\r
+;  interrupt table.\r
+; \r
+; Arguments:\r
+; \r
+; \r
+; Returns: \r
+; \r
+;   Nothing\r
+;\r
+; \r
+; Input:  [ebp][0]  = Original ebp\r
+;         [ebp][4]  = Return address\r
+;          \r
+; Output: Nothing\r
+;           \r
+; Destroys: Nothing\r
+;-----------------------------------------------------------------------------;\r
+GetTemplateAddressMap  proc near public\r
+    push    ebp                 ; C prolog\r
+    mov     ebp, esp\r
+    pushad\r
+\r
+    mov ebx, dword ptr [ebp+08h]\r
+    mov dword ptr [ebx],    Exception0Handle\r
+    mov dword ptr [ebx+4h], Exception1Handle - Exception0Handle\r
+  \r
+    popad\r
+    pop     ebp\r
+    ret\r
+GetTemplateAddressMap  ENDP\r
+\r
+END\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
new file mode 100644 (file)
index 0000000..de76e47
--- /dev/null
@@ -0,0 +1,63 @@
+/** @file\r
+  CPU Exception Library provides SEC/PEIM CPU exception handler.\r
+\r
+Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include "CpuExceptionCommon.h"\r
+\r
+//\r
+// Image Aglinment size for SEC/PEI phase\r
+//\r
+CONST UINTN      mImageAlignSize = 4;\r
+\r
+/**\r
+  Common exception handler.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+EFIAPI\r
+CommonExceptionHandler (\r
+  IN EFI_EXCEPTION_TYPE   ExceptionType, \r
+  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  )\r
+{\r
+  //\r
+  // Display ExceptionType, CPU information and Image information\r
+  //  \r
+  DumpCpuContent (ExceptionType, SystemContext);\r
+  \r
+  //\r
+  // Enter a dead loop.\r
+  //\r
+  CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+  Setup CPU exception handlers.\r
+\r
+  This API will setups the CPU exception handler to display CPU contents and run into\r
+  CpuDeadLoop(). \r
+  @Note: Before invoking this API, caller must allocate memory for IDT table and load \r
+         IDTR by AsmWriteIdtr().\r
+  \r
+**/\r
+VOID\r
+EFIAPI\r
+SetupCpuExceptionHandlers (\r
+  IN VOID\r
+  )\r
+{\r
+  InternalSetupCpuExceptionHandlers ();\r
+}\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
new file mode 100644 (file)
index 0000000..96ddaaf
--- /dev/null
@@ -0,0 +1,56 @@
+## @file\r
+#  Component description file for SEC/PEI CPU Exception Handler Library instance\r
+#\r
+#  This library instance supports SEC/PEI module only.\r
+#\r
+#  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SecPeiCpuExceptionHandlerLib\r
+  FILE_GUID                      = CA4BBC99-DFC6-4234-B553-8B6586B7B113\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = CpuExceptionHandlerLib|SEC PEIM_CORE PEIM\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.Ia32]\r
+  Ia32/ExceptionHandlerAsm.asm |MSFT\r
+  Ia32/ExceptionHandlerAsm.S   |GCC\r
+  Ia32/ArchExceptionHandler.c\r
+\r
+[Sources.X64]\r
+  X64/ExceptionHandlerAsm.asm |MSFT\r
+  X64/ExceptionHandlerAsm.S   |GCC\r
+  X64/ArchExceptionHandler.c\r
+\r
+[Sources.common]\r
+  CpuExceptionCommon.h\r
+  CpuExceptionCommon.c\r
+  SecPeiCpuException.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  SerialPortLib\r
+  PrintLib\r
+  LocalApicLib\r
+  PeCoffGetEntryPointLib\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
new file mode 100644 (file)
index 0000000..664472a
--- /dev/null
@@ -0,0 +1,192 @@
+/** @file\r
+  x64 CPU Exception Hanlder.\r
+\r
+  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "CpuExceptionCommon.h"\r
+\r
+/**\r
+  Internal function to setup CPU exception handlers.\r
+\r
+**/\r
+VOID\r
+InternalSetupCpuExceptionHandlers (\r
+  VOID\r
+  )\r
+{\r
+  IA32_DESCRIPTOR                     IdtDescriptor;\r
+  UINTN                               IdtSize;\r
+  EXCEPTION_HANDLER_TEMPLATE_MAP      TemplateMap;\r
+  UINT16                              CodeSegment;\r
+  IA32_IDT_GATE_DESCRIPTOR            *IdtEntry;\r
+  UINTN                               Index;\r
+  UINTN                               InterruptHandler;\r
+\r
+  //\r
+  // Read IDT descriptor and calculate IDT size\r
+  //\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtSize = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
+  if (IdtSize > CPU_EXCEPTION_NUM) {\r
+    //\r
+    // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most\r
+    //\r
+    IdtSize = CPU_EXCEPTION_NUM;\r
+  }\r
+\r
+  //\r
+  // Use current CS as the segment selector of interrupt gate in IDT\r
+  //\r
+  CodeSegment = AsmReadCs ();\r
+  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+\r
+  GetTemplateAddressMap (&TemplateMap);\r
+\r
+  for (Index = 0; Index < IdtSize; Index ++) {\r
+    InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;\r
+    IdtEntry[Index].Bits.OffsetLow       = (UINT16)(UINTN)InterruptHandler;\r
+    IdtEntry[Index].Bits.OffsetHigh      = (UINT16)((UINTN)InterruptHandler >> 16);\r
+    IdtEntry[Index].Bits.OffsetUpper     = (UINT32)((UINTN)InterruptHandler >> 32);\r
+    IdtEntry[Index].Bits.Selector        = CodeSegment;\r
+    IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+  }\r
+}\r
+\r
+/**\r
+  Common exception handler.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+DumpCpuContent (\r
+  IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  )\r
+{\r
+  UINTN                   ImageBase;\r
+  UINTN                   EntryPoint;\r
+\r
+  InternalPrintMessage (\r
+    "!!!! X64 Exception Type - %016lx     CPU Apic ID - %08x !!!!\n",\r
+    ExceptionType,\r
+    GetApicId ()\r
+    );\r
+  InternalPrintMessage (\r
+    "RIP  - %016lx, CS  - %016lx, RFLAGS - %016lx\n",\r
+    SystemContext.SystemContextX64->Rip,\r
+    SystemContext.SystemContextX64->Cs,\r
+    SystemContext.SystemContextX64->Rflags\r
+    );\r
+  if (mErrorCodeFlag & (1 << ExceptionType)) {\r
+    InternalPrintMessage (\r
+      "ExceptionData - %016lx\n",\r
+      SystemContext.SystemContextX64->ExceptionData\r
+      );\r
+  }\r
+  InternalPrintMessage (\r
+    "RAX  - %016lx, RCX - %016lx, RDX - %016lx\n",\r
+    SystemContext.SystemContextX64->Rax,\r
+    SystemContext.SystemContextX64->Rcx,\r
+    SystemContext.SystemContextX64->Rdx\r
+    );\r
+  InternalPrintMessage (\r
+    "RBX  - %016lx, RSP - %016lx, RBP - %016lx\n",\r
+    SystemContext.SystemContextX64->Rbx,\r
+    SystemContext.SystemContextX64->Rsp,\r
+    SystemContext.SystemContextX64->Rbp\r
+    );\r
+  InternalPrintMessage (\r
+    "RSI  - %016lx, RDI - %016lx\n",\r
+    SystemContext.SystemContextX64->Rsi,\r
+    SystemContext.SystemContextX64->Rdi\r
+    );\r
+  InternalPrintMessage (\r
+    "R8   - %016lx, R9  - %016lx, R10 - %016lx\n",\r
+    SystemContext.SystemContextX64->R8,\r
+    SystemContext.SystemContextX64->R9,\r
+    SystemContext.SystemContextX64->R10\r
+    );\r
+  InternalPrintMessage (\r
+    "R11  - %016lx, R12 - %016lx, R13 - %016lx\n",\r
+    SystemContext.SystemContextX64->R11,\r
+    SystemContext.SystemContextX64->R12,\r
+    SystemContext.SystemContextX64->R13\r
+    );\r
+  InternalPrintMessage (\r
+    "R14  - %016lx, R15 - %016lx\n",\r
+    SystemContext.SystemContextX64->R14,\r
+    SystemContext.SystemContextX64->R15\r
+    );\r
+  InternalPrintMessage (\r
+    "DS   - %016lx, ES  - %016lx, FS  - %016lx\n",\r
+    SystemContext.SystemContextX64->Ds,\r
+    SystemContext.SystemContextX64->Es,\r
+    SystemContext.SystemContextX64->Fs\r
+    );\r
+  InternalPrintMessage (\r
+    "GS   - %016lx, SS  - %016lx\n",\r
+    SystemContext.SystemContextX64->Gs,\r
+    SystemContext.SystemContextX64->Ss\r
+    );\r
+  InternalPrintMessage (\r
+    "CR0  - %016lx, CR2 - %016lx, CR3 - %016lx\n",\r
+    SystemContext.SystemContextX64->Cr0,\r
+    SystemContext.SystemContextX64->Cr2,\r
+    SystemContext.SystemContextX64->Cr3\r
+    );\r
+  InternalPrintMessage (\r
+    "CR4  - %016lx, CR8 - %016lx\n",\r
+    SystemContext.SystemContextX64->Cr4,\r
+    SystemContext.SystemContextX64->Cr8\r
+    );\r
+  InternalPrintMessage (\r
+    "DR0  - %016lx, DR1 - %016lx, DR2 - %016lx\n",\r
+    SystemContext.SystemContextX64->Dr0,\r
+    SystemContext.SystemContextX64->Dr1,\r
+    SystemContext.SystemContextX64->Dr2\r
+    );\r
+  InternalPrintMessage (\r
+    "DR3  - %016lx, DR6 - %016lx, DR7 - %016lx\n",\r
+    SystemContext.SystemContextX64->Dr3,\r
+    SystemContext.SystemContextX64->Dr6,\r
+    SystemContext.SystemContextX64->Dr7\r
+    );\r
+  InternalPrintMessage (\r
+    "GDTR - %016lx %016lx, LDTR - %016lx\n",\r
+    SystemContext.SystemContextX64->Gdtr[0],\r
+    SystemContext.SystemContextX64->Gdtr[1],\r
+    SystemContext.SystemContextX64->Ldtr\r
+    );\r
+  InternalPrintMessage (\r
+    "IDTR - %016lx %016lx,   TR - %016lx\n",\r
+    SystemContext.SystemContextX64->Idtr[0],\r
+    SystemContext.SystemContextX64->Idtr[1],\r
+    SystemContext.SystemContextX64->Tr\r
+    );\r
+       InternalPrintMessage (\r
+    "FXSAVE_STATE - %016lx\n",\r
+    &SystemContext.SystemContextX64->FxSaveState\r
+    );\r
+\r
+  //\r
+  // Find module image base and module entry point by RIP\r
+  //\r
+  ImageBase = FindModuleImageBase (SystemContext.SystemContextX64->Rip, &EntryPoint);\r
+  if (ImageBase != 0) {\r
+    InternalPrintMessage (\r
+      " (ImageBase=%016lx, EntryPoint=%016lx) !!!!\n",\r
+      ImageBase,\r
+      EntryPoint\r
+      );\r
+  }\r
+}\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
new file mode 100644 (file)
index 0000000..cd10147
--- /dev/null
@@ -0,0 +1,406 @@
+#------------------------------------------------------------------------------ ;\r
+# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Module Name:\r
+#\r
+#   ExceptionHandlerAsm.S\r
+#\r
+# Abstract:\r
+#\r
+#   x64 CPU Exception Handler\r
+#\r
+# Notes:\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+\r
+ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+\r
+\r
+.text\r
+\r
+#\r
+# point to the external interrupt vector table\r
+#\r
+Exception0Handle:\r
+    pushq   $0\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception1Handle:\r
+    pushq   $1\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception2Handle:\r
+    pushq   $2\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception3Handle:\r
+    pushq   $3\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception4Handle:\r
+    pushq   $4\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception5Handle:\r
+    pushq   $5\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception6Handle:\r
+    pushq   $6\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception7Handle:\r
+    pushq   $7\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception8Handle:\r
+    pushq   $8\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception9Handle:\r
+    pushq   $9\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception10Handle:\r
+    pushq   $10\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception11Handle:\r
+    pushq   $11\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception12Handle:\r
+    pushq   $12\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception13Handle:\r
+    pushq   $13\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception14Handle:\r
+    pushq   $14\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception15Handle:\r
+    pushq   $15\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception16Handle:\r
+    pushq   $16\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception17Handle:\r
+    pushq   $17\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception18Handle:\r
+    pushq   $18\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception19Handle:\r
+    pushq   $19\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception20Handle:\r
+    pushq   $20\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception21Handle:\r
+    pushq   $21\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception22Handle:\r
+    pushq   $22\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception23Handle:\r
+    pushq   $23\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception24Handle:\r
+    pushq   $24\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception25Handle:\r
+    pushq   $25\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception26Handle:\r
+    pushq   $26\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception27Handle:\r
+    pushq   $27\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception28Handle:\r
+    pushq   $28\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception29Handle:\r
+    pushq   $29\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception30Handle:\r
+    pushq   $30\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+Exception31Handle:\r
+    pushq   $31\r
+    jmp     ASM_PFX(CommonInterruptEntry)\r
+\r
+\r
+#---------------------------------------;\r
+# CommonInterruptEntry                  ;\r
+#---------------------------------------;\r
+# The follow algorithm is used for the common interrupt routine.\r
+\r
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_PFX(CommonInterruptEntry):\r
+    cli\r
+    #\r
+    # All interrupt handlers are invoked through interrupt gates, so\r
+    # IF flag automatically cleared at the entry point\r
+    #\r
+    #\r
+    # Calculate vector number\r
+    #\r
+    xchgq   (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.\r
+    cmp     $32, %ecx          # Intel reserved vector for exceptions?\r
+    jae     NoErrorCode\r
+    pushq   %rax\r
+    leaq    ASM_PFX(mErrorCodeFlag)(%rip), %rax\r
+    bt      %ecx, (%rax) \r
+    popq    %rax\r
+    jc      CommonInterruptEntry_al_0000\r
+\r
+NoErrorCode:\r
+\r
+    #\r
+    # Push a dummy error code on the stack\r
+    # to maintain coherent stack map\r
+    #\r
+    pushq   (%rsp)\r
+    movq    $0, 8(%rsp)\r
+CommonInterruptEntry_al_0000:\r
+    pushq   %rbp\r
+    movq    %rsp, %rbp\r
+\r
+    #\r
+    # Stack:\r
+    # +---------------------+ <-- 16-byte aligned ensured by processor\r
+    # +    Old SS           +\r
+    # +---------------------+\r
+    # +    Old RSP          +\r
+    # +---------------------+\r
+    # +    RFlags           +\r
+    # +---------------------+\r
+    # +    CS               +\r
+    # +---------------------+\r
+    # +    RIP              +\r
+    # +---------------------+\r
+    # +    Error Code       +\r
+    # +---------------------+\r
+    # + RCX / Vector Number +\r
+    # +---------------------+\r
+    # +    RBP              +\r
+    # +---------------------+ <-- RBP, 16-byte aligned\r
+    #\r
+\r
+\r
+    #\r
+    # Since here the stack pointer is 16-byte aligned, so\r
+    # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
+    # is 16-byte aligned\r
+    #\r
+\r
+#; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+#; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+    pushq    %r15\r
+    pushq    %r14\r
+    pushq    %r13\r
+    pushq    %r12\r
+    pushq    %r11\r
+    pushq    %r10\r
+    pushq    %r9\r
+    pushq    %r8\r
+    pushq    %rax\r
+    pushq    8(%rbp)   # RCX\r
+    pushq    %rdx\r
+    pushq    %rbx\r
+    pushq    48(%rbp)  # RSP\r
+    pushq    (%rbp)    # RBP\r
+    pushq    %rsi\r
+    pushq    %rdi\r
+\r
+#; UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero\r
+    movzwq  56(%rbp), %rax\r
+    pushq   %rax                      # for ss\r
+    movzwq  32(%rbp), %rax\r
+    pushq   %rax                      # for cs\r
+    movl    %ds, %eax\r
+    pushq   %rax\r
+    movl    %es, %eax\r
+    pushq   %rax\r
+    movl    %fs, %eax\r
+    pushq   %rax\r
+    movl    %gs, %eax\r
+    pushq   %rax\r
+\r
+    movq    %rcx, 8(%rbp)                # save vector number\r
+\r
+#; UINT64  Rip;\r
+    pushq   24(%rbp)\r
+\r
+#; UINT64  Gdtr[2], Idtr[2];\r
+    xorq    %rax, %rax\r
+    pushq   %rax\r
+    pushq   %rax\r
+    sidt    (%rsp)\r
+    xchgq   2(%rsp), %rax\r
+    xchgq   (%rsp), %rax\r
+    xchgq   8(%rsp), %rax\r
+\r
+    xorq    %rax, %rax\r
+    pushq   %rax\r
+    pushq   %rax\r
+    sgdt    (%rsp)\r
+    xchgq   2(%rsp), %rax\r
+    xchgq   (%rsp), %rax\r
+    xchgq   8(%rsp), %rax\r
+\r
+#; UINT64  Ldtr, Tr;\r
+    xorq    %rax, %rax\r
+    str     %ax\r
+    pushq   %rax\r
+    sldt    %ax\r
+    pushq   %rax\r
+\r
+#; UINT64  RFlags;\r
+    pushq   40(%rbp)\r
+\r
+#; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+    movq    %cr8, %rax\r
+    pushq   %rax\r
+    movq    %cr4, %rax\r
+    orq     $0x208, %rax \r
+    movq    %rax, %cr4 \r
+    pushq   %rax\r
+    mov     %cr3, %rax \r
+    pushq   %rax\r
+    mov     %cr2, %rax \r
+    pushq   %rax\r
+    xorq    %rax, %rax\r
+    pushq   %rax\r
+    mov     %cr0, %rax \r
+    pushq   %rax\r
+\r
+#; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    movq    %dr7, %rax\r
+    pushq   %rax\r
+    movq    %dr6, %rax\r
+    pushq   %rax\r
+    movq    %dr3, %rax\r
+    pushq   %rax\r
+    movq    %dr2, %rax\r
+    pushq   %rax\r
+    movq    %dr1, %rax\r
+    pushq   %rax\r
+    movq    %dr0, %rax\r
+    pushq   %rax\r
+\r
+#; FX_SAVE_STATE_X64 FxSaveState;\r
+    subq    $512, %rsp\r
+    movq    %rsp, %rdi\r
+    .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]\r
+\r
+#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
+    cld\r
+\r
+#; UINT32  ExceptionData;\r
+    pushq   16(%rbp)\r
+\r
+#; Prepare parameter and call\r
+    mov     8(%rbp), %rcx\r
+    mov     %rsp, %rdx\r
+    #\r
+    # Per X64 calling convention, allocate maximum parameter stack space\r
+    # and make sure RSP is 16-byte aligned\r
+    #\r
+    subq    $40, %rsp \r
+    call    ASM_PFX(CommonExceptionHandler)\r
+    addq    $40, %rsp\r
+\r
+    cli\r
+#; UINT64  ExceptionData;\r
+    addq    $8, %rsp\r
+\r
+#; FX_SAVE_STATE_X64 FxSaveState;\r
+\r
+    movq    %rsp, %rsi\r
+    .byte   0x0f, 0x0ae, 0x0E # fxrstor [rsi]\r
+    addq    $512, %rsp\r
+\r
+#; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+#; Skip restoration of DRx registers to support in-circuit emualators\r
+#; or debuggers set breakpoint in interrupt/exception context\r
+    addq    $48, %rsp\r
+\r
+#; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+    popq    %rax\r
+    movq    %rax, %cr0\r
+    addq    $8, %rsp   # not for Cr1\r
+    popq    %rax\r
+    movq    %rax, %cr2\r
+    popq    %rax\r
+    movq    %rax, %cr3\r
+    popq    %rax\r
+    movq    %rax, %cr4\r
+    popq    %rax\r
+    movq    %rax, %cr8\r
+\r
+#; UINT64  RFlags;\r
+    popq    40(%rbp)\r
+\r
+#; UINT64  Ldtr, Tr;\r
+#; UINT64  Gdtr[2], Idtr[2];\r
+#; Best not let anyone mess with these particular registers...\r
+    addq    $48, %rsp\r
+\r
+#; UINT64  Rip;\r
+    popq    24(%rbp)\r
+\r
+#; UINT64  Gs, Fs, Es, Ds, Cs, Ss;\r
+    popq    %rax\r
+    # mov   %rax, %gs ; not for gs\r
+    popq    %rax\r
+    # mov   %rax, %fs ; not for fs\r
+    # (X64 will not use fs and gs, so we do not restore it)\r
+    popq    %rax\r
+    movl    %eax, %es\r
+    popq    %rax\r
+    movl    %eax, %ds\r
+    popq    32(%rbp)  # for cs\r
+    popq    56(%rbp)  # for ss\r
+\r
+#; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+#; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+    popq    %rdi\r
+    popq    %rsi\r
+    addq    $8, %rsp              # not for rbp\r
+    popq    48(%rbp)              # for rsp\r
+    popq    %rbx\r
+    popq    %rdx\r
+    popq    %rcx\r
+    popq    %rax\r
+    popq    %r8\r
+    popq    %r9\r
+    popq    %r10\r
+    popq    %r11\r
+    popq    %r12\r
+    popq    %r13\r
+    popq    %r14\r
+    popq    %r15\r
+\r
+    movq    %rbp, %rsp\r
+    popq    %rbp\r
+    addq    $16, %rsp\r
+    iretq\r
+\r
+\r
+#-------------------------------------------------------------------------------------\r
+#  AsmGetAddressMap (&AddressMap);\r
+#-------------------------------------------------------------------------------------\r
+# comments here for definition of address map\r
+ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)\r
+ASM_PFX(GetTemplateAddressMap):\r
+\r
+        movabsq      $Exception0Handle, %rax\r
+        movq         %rax, (%rcx)\r
+        movq         $(Exception1Handle - Exception0Handle), 0x08(%rcx)\r
+\r
+        ret\r
+\r
+#END\r
+\r
+\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
new file mode 100644 (file)
index 0000000..1fa7cb8
--- /dev/null
@@ -0,0 +1,407 @@
+;------------------------------------------------------------------------------ ;\r
+; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Module Name:\r
+;\r
+;   ExceptionHandlerAsm.Asm\r
+;\r
+; Abstract:\r
+;\r
+;   x64 CPU Exception Handler\r
+;\r
+; Notes:\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+;\r
+; CommonExceptionHandler()\r
+;\r
+CommonExceptionHandler             PROTO   C\r
+\r
+EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
+\r
+data SEGMENT\r
+\r
+CommonEntryAddr                dq      CommonInterruptEntry;\r
+\r
+.code\r
+\r
+Exception0Handle:\r
+    push    0\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception1Handle:\r
+    push    1\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception2Handle:\r
+    push    2\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception3Handle:\r
+    push    3\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception4Handle:\r
+    push    4\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception5Handle:\r
+    push    5\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception6Handle:\r
+    push    6\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception7Handle:\r
+    push    7\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception8Handle:\r
+    push    8\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception9Handle:\r
+    push    9\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception10Handle:\r
+    push    10\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception11Handle:\r
+    push    11\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception12Handle:\r
+    push    12\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception13Handle:\r
+    push    13\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception14Handle:\r
+    push    14\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception15Handle:\r
+    push    15\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception16Handle:\r
+    push    16\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception17Handle:\r
+    push    17\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception18Handle:\r
+    push    18\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception19Handle:\r
+    push    19\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception20Handle:\r
+    push    20\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception21Handle:\r
+    push    21\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception22Handle:\r
+    push    22\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception23Handle:\r
+    push    23\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception24Handle:\r
+    push    24\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception25Handle:\r
+    push    25\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception26Handle:\r
+    push    26\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception27Handle:\r
+    push    27\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception28Handle:\r
+    push    28\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception29Handle:\r
+    push    29\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception30Handle:\r
+    push    30\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception31Handle:\r
+    push    31\r
+    jmp     qword ptr [CommonEntryAddr]\r
+\r
+;CommonInterruptEntrypoint:\r
+;---------------------------------------;\r
+; _CommonEntry                  ;\r
+;----------------------------------------------------------------------------;\r
+; The follow algorithm is used for the common interrupt routine.\r
+; Entry from each interrupt with a push eax and eax=interrupt number\r
+\r
+;---------------------------------------;\r
+; CommonInterruptEntry                  ;\r
+;---------------------------------------;\r
+; The follow algorithm is used for the common interrupt routine.\r
+\r
+CommonInterruptEntry PROC PUBLIC  \r
+    cli\r
+    ;\r
+    ; All interrupt handlers are invoked through interrupt gates, so\r
+    ; IF flag automatically cleared at the entry point\r
+    ;\r
+    ;\r
+    ; Calculate vector number\r
+    ;\r
+    xchg    rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.\r
+    cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
+    jae     NoErrorCode\r
+    bt      mErrorCodeFlag, ecx\r
+    jc      @F\r
+\r
+NoErrorCode:\r
+\r
+    ;\r
+    ; Push a dummy error code on the stack\r
+    ; to maintain coherent stack map\r
+    ;\r
+    push    [rsp]\r
+    mov     qword ptr [rsp + 8], 0\r
+@@:       \r
+    push    rbp\r
+    mov     rbp, rsp\r
+\r
+    ;\r
+    ; Stack:\r
+    ; +---------------------+ <-- 16-byte aligned ensured by processor\r
+    ; +    Old SS           +\r
+    ; +---------------------+\r
+    ; +    Old RSP          +\r
+    ; +---------------------+\r
+    ; +    RFlags           +\r
+    ; +---------------------+\r
+    ; +    CS               +\r
+    ; +---------------------+\r
+    ; +    RIP              +\r
+    ; +---------------------+\r
+    ; +    Error Code       +\r
+    ; +---------------------+\r
+    ; + RCX / Vector Number +\r
+    ; +---------------------+\r
+    ; +    RBP              +\r
+    ; +---------------------+ <-- RBP, 16-byte aligned\r
+    ;\r
+\r
+\r
+    ;\r
+    ; Since here the stack pointer is 16-byte aligned, so\r
+    ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
+    ; is 16-byte aligned\r
+    ;\r
+\r
+;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+    push r15\r
+    push r14\r
+    push r13\r
+    push r12\r
+    push r11\r
+    push r10\r
+    push r9\r
+    push r8\r
+    push rax\r
+    push qword ptr [rbp + 8]   ; RCX\r
+    push rdx\r
+    push rbx\r
+    push qword ptr [rbp + 48]  ; RSP\r
+    push qword ptr [rbp]       ; RBP\r
+    push rsi\r
+    push rdi\r
+\r
+;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero\r
+    movzx   rax, word ptr [rbp + 56]\r
+    push    rax                      ; for ss\r
+    movzx   rax, word ptr [rbp + 32]\r
+    push    rax                      ; for cs\r
+    mov     rax, ds\r
+    push    rax\r
+    mov     rax, es\r
+    push    rax\r
+    mov     rax, fs\r
+    push    rax\r
+    mov     rax, gs\r
+    push    rax\r
+\r
+    mov     [rbp + 8], rcx               ; save vector number\r
+\r
+;; UINT64  Rip;\r
+    push    qword ptr [rbp + 24]\r
+\r
+;; UINT64  Gdtr[2], Idtr[2];\r
+    xor     rax, rax\r
+    push    rax\r
+    push    rax\r
+    sidt    [rsp]\r
+    xchg    rax, [rsp + 2]\r
+    xchg    rax, [rsp]\r
+    xchg    rax, [rsp + 8]\r
+\r
+    xor     rax, rax\r
+    push    rax\r
+    push    rax\r
+    sgdt    [rsp]\r
+    xchg    rax, [rsp + 2]\r
+    xchg    rax, [rsp]\r
+    xchg    rax, [rsp + 8]\r
+\r
+;; UINT64  Ldtr, Tr;\r
+    xor     rax, rax\r
+    str     ax\r
+    push    rax\r
+    sldt    ax\r
+    push    rax\r
+\r
+;; UINT64  RFlags;\r
+    push    qword ptr [rbp + 40]\r
+\r
+;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+    mov     rax, cr8\r
+    push    rax\r
+    mov     rax, cr4\r
+    or      rax, 208h\r
+    mov     cr4, rax\r
+    push    rax\r
+    mov     rax, cr3\r
+    push    rax\r
+    mov     rax, cr2\r
+    push    rax\r
+    xor     rax, rax\r
+    push    rax\r
+    mov     rax, cr0\r
+    push    rax\r
+\r
+;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    mov     rax, dr7\r
+    push    rax\r
+    mov     rax, dr6\r
+    push    rax\r
+    mov     rax, dr3\r
+    push    rax\r
+    mov     rax, dr2\r
+    push    rax\r
+    mov     rax, dr1\r
+    push    rax\r
+    mov     rax, dr0\r
+    push    rax\r
+\r
+;; FX_SAVE_STATE_X64 FxSaveState;\r
+    sub rsp, 512\r
+    mov rdi, rsp\r
+    db 0fh, 0aeh, 07h ;fxsave [rdi]\r
+\r
+;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
+    cld\r
+\r
+;; UINT32  ExceptionData;\r
+    push    qword ptr [rbp + 16]\r
+\r
+;; Prepare parameter and call\r
+    mov     rcx, [rbp + 8]\r
+    mov     rdx, rsp\r
+    ;\r
+    ; Per X64 calling convention, allocate maximum parameter stack space\r
+    ; and make sure RSP is 16-byte aligned\r
+    ;\r
+    sub     rsp, 4 * 8 + 8\r
+    mov     rax, CommonExceptionHandler\r
+    call    rax\r
+    add     rsp, 4 * 8 + 8\r
+\r
+    cli\r
+;; UINT64  ExceptionData;\r
+    add     rsp, 8\r
+\r
+;; FX_SAVE_STATE_X64 FxSaveState;\r
+\r
+    mov rsi, rsp\r
+    db 0fh, 0aeh, 0Eh ; fxrstor [rsi]\r
+    add rsp, 512\r
+\r
+;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+;; Skip restoration of DRx registers to support in-circuit emualators\r
+;; or debuggers set breakpoint in interrupt/exception context\r
+    add     rsp, 8 * 6\r
+\r
+;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+    pop     rax\r
+    mov     cr0, rax\r
+    add     rsp, 8   ; not for Cr1\r
+    pop     rax\r
+    mov     cr2, rax\r
+    pop     rax\r
+    mov     cr3, rax\r
+    pop     rax\r
+    mov     cr4, rax\r
+    pop     rax\r
+    mov     cr8, rax\r
+\r
+;; UINT64  RFlags;\r
+    pop     qword ptr [rbp + 40]\r
+\r
+;; UINT64  Ldtr, Tr;\r
+;; UINT64  Gdtr[2], Idtr[2];\r
+;; Best not let anyone mess with these particular registers...\r
+    add     rsp, 48\r
+\r
+;; UINT64  Rip;\r
+    pop     qword ptr [rbp + 24]\r
+\r
+;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;\r
+    pop     rax\r
+    ; mov     gs, rax ; not for gs\r
+    pop     rax\r
+    ; mov     fs, rax ; not for fs\r
+    ; (X64 will not use fs and gs, so we do not restore it)\r
+    pop     rax\r
+    mov     es, rax\r
+    pop     rax\r
+    mov     ds, rax\r
+    pop     qword ptr [rbp + 32]  ; for cs\r
+    pop     qword ptr [rbp + 56]  ; for ss\r
+\r
+;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+    pop     rdi\r
+    pop     rsi\r
+    add     rsp, 8               ; not for rbp\r
+    pop     qword ptr [rbp + 48] ; for rsp\r
+    pop     rbx\r
+    pop     rdx\r
+    pop     rcx\r
+    pop     rax\r
+    pop     r8\r
+    pop     r9\r
+    pop     r10\r
+    pop     r11\r
+    pop     r12\r
+    pop     r13\r
+    pop     r14\r
+    pop     r15\r
+\r
+    mov     rsp, rbp\r
+    pop     rbp\r
+    add     rsp, 16\r
+    iretq\r
+\r
+CommonInterruptEntry ENDP\r
+\r
+;-------------------------------------------------------------------------------------\r
+;  GetTemplateAddressMap (&AddressMap);\r
+;-------------------------------------------------------------------------------------\r
+; comments here for definition of address map\r
+GetTemplateAddressMap   PROC\r
+        mov         rax, offset Exception0Handle\r
+        mov         qword ptr [rcx], rax\r
+        mov         qword ptr [rcx+8h], Exception1Handle - Exception0Handle\r
+        ret\r
+GetTemplateAddressMap   ENDP\r
+\r
+END\r
index 8d049bbc82a66091d02539eea2404a1e82265b7e..73dbbaf3a2fe6de5cfcee2bac324ef204c3b0078 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  UefiCpuPkg Package\r
 #\r
-#  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -85,5 +85,7 @@
   UefiCpuPkg/Library/MtrrLib/MtrrLib.inf\r
   UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf\r
   UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf\r
+  UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf\r
+  UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf\r
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf\r
 \r