]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add thunk code for CpuDxe driver.
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 1 Mar 2009 10:13:03 +0000 (10:13 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 1 Mar 2009 10:13:03 +0000 (10:13 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7744 6f19259b-4bc3-4df7-8a09-765794883524

DuetPkg/CpuDxe/Cpu.c
DuetPkg/CpuDxe/Cpu.inf
DuetPkg/CpuDxe/CpuDxe.h

index d61e5c1f50fdcdf009c44e5a21e6c05420be1b9c..6d5e9dc3496d33e92960ef2537624fb1dcd8f5f8 100644 (file)
@@ -27,7 +27,21 @@ extern UINT32                        mExceptionCodeSize;
 UINTN                                mTimerVector = 0;\r
 volatile EFI_CPU_INTERRUPT_HANDLER   mTimerHandler = NULL;\r
 EFI_LEGACY_8259_PROTOCOL             *gLegacy8259 = NULL;\r
 UINTN                                mTimerVector = 0;\r
 volatile EFI_CPU_INTERRUPT_HANDLER   mTimerHandler = NULL;\r
 EFI_LEGACY_8259_PROTOCOL             *gLegacy8259 = NULL;\r
+THUNK_CONTEXT                        mThunkContext;\r
+#define EFI_CPU_EFLAGS_IF 0x200\r
 \r
 \r
+VOID\r
+InitializeBiosIntCaller (\r
+  VOID\r
+  );\r
+  \r
+BOOLEAN\r
+EFIAPI\r
+LegacyBiosInt86 (\r
+  IN  UINT8                           BiosInt,\r
+  IN  EFI_IA32_REGISTER_SET           *Regs\r
+  );\r
+  \r
 //\r
 // The Cpu Architectural Protocol that this Driver produces\r
 //\r
 //\r
 // The Cpu Architectural Protocol that this Driver produces\r
 //\r
@@ -914,13 +928,6 @@ Return
   EFI_IA32_REGISTER_SET           Regs;\r
   UINT16                          OriginalVideoMode = (UINT16) -1;\r
   \r
   EFI_IA32_REGISTER_SET           Regs;\r
   UINT16                          OriginalVideoMode = (UINT16) -1;\r
   \r
-  //\r
-  // See if the Legacy BIOS Protocol is available\r
-  //\r
-  Status = gBS->LocateProtocol (&gEfiLegacyBiosThunkProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (EFI_ERROR (Status)) {\r
-    return OriginalVideoMode;\r
-  }\r
 \r
   //\r
   // VESA SuperVGA BIOS - GET CURRENT VIDEO MODE\r
 \r
   //\r
   // VESA SuperVGA BIOS - GET CURRENT VIDEO MODE\r
@@ -931,7 +938,7 @@ Return
   //\r
   gBS->SetMem (&Regs, sizeof (Regs), 0);\r
   Regs.X.AX = 0x4F03;\r
   //\r
   gBS->SetMem (&Regs, sizeof (Regs), 0);\r
   Regs.X.AX = 0x4F03;\r
-  LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
+  LegacyBiosInt86 (0x10, &Regs);\r
   if (Regs.X.AX == 0x004F) {\r
     OriginalVideoMode = Regs.X.BX;\r
   } else {\r
   if (Regs.X.AX == 0x004F) {\r
     OriginalVideoMode = Regs.X.BX;\r
   } else {\r
@@ -944,7 +951,7 @@ Return
     //\r
     gBS->SetMem (&Regs, sizeof (Regs), 0);\r
     Regs.H.AH = 0x0F;\r
     //\r
     gBS->SetMem (&Regs, sizeof (Regs), 0);\r
     Regs.H.AH = 0x0F;\r
-    LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
+    LegacyBiosInt86 (0x10, &Regs);\r
     OriginalVideoMode = Regs.H.AL;\r
   }\r
 \r
     OriginalVideoMode = Regs.H.AL;\r
   }\r
 \r
@@ -967,7 +974,7 @@ Return
     gBS->SetMem (&Regs, sizeof (Regs), 0);\r
     Regs.H.AH = 0x00;\r
     Regs.H.AL = (UINT8) NewVideoMode;\r
     gBS->SetMem (&Regs, sizeof (Regs), 0);\r
     Regs.H.AH = 0x00;\r
     Regs.H.AL = (UINT8) NewVideoMode;\r
-    LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
+    LegacyBiosInt86 (0x10, &Regs);\r
 \r
     //\r
     // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)\r
 \r
     //\r
     // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)\r
@@ -979,7 +986,7 @@ Return
     Regs.H.AH = 0x11;\r
     Regs.H.AL = 0x14;\r
     Regs.H.BL = 0;\r
     Regs.H.AH = 0x11;\r
     Regs.H.AL = 0x14;\r
     Regs.H.BL = 0;\r
-    LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
+    LegacyBiosInt86 (0x10, &Regs);\r
   } else {\r
     //\r
     //    VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE\r
   } else {\r
     //\r
     //    VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE\r
@@ -995,7 +1002,7 @@ Return
     gBS->SetMem (&Regs, sizeof (Regs), 0);\r
     Regs.X.AX = 0x4F02;\r
     Regs.X.BX = NewVideoMode;\r
     gBS->SetMem (&Regs, sizeof (Regs), 0);\r
     Regs.X.AX = 0x4F02;\r
     Regs.X.BX = NewVideoMode;\r
-    LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r
+    LegacyBiosInt86 (0x10, &Regs);\r
     if (Regs.X.AX != 0x004F) {\r
       DEBUG ((EFI_D_ERROR, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode));\r
       return (UINT16) -1;\r
     if (Regs.X.AX != 0x004F) {\r
       DEBUG ((EFI_D_ERROR, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode));\r
       return (UINT16) -1;\r
@@ -1130,6 +1137,8 @@ Returns:
     InstallInterruptHandler (InterruptVector, SystemTimerHandler);\r
   }\r
 \r
     InstallInterruptHandler (InterruptVector, SystemTimerHandler);\r
   }\r
 \r
+  InitializeBiosIntCaller();\r
+  \r
   //\r
   // Install CPU Architectural Protocol and the thunk protocol\r
   //\r
   //\r
   // Install CPU Architectural Protocol and the thunk protocol\r
   //\r
@@ -1145,3 +1154,126 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+VOID\r
+InitializeBiosIntCaller (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT32                RealModeBufferSize;\r
+  UINT32                ExtraStackSize;\r
+  EFI_PHYSICAL_ADDRESS  LegacyRegionBase;\r
+  \r
+  //\r
+  // Get LegacyRegion\r
+  //\r
+  AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);\r
+\r
+  LegacyRegionBase = 0x100000;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiACPIMemoryNVS,\r
+                  EFI_SIZE_TO_PAGES(RealModeBufferSize + ExtraStackSize + 200),\r
+                  &LegacyRegionBase\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  mThunkContext.RealModeBuffer     = (VOID*)(UINTN)LegacyRegionBase;\r
+  mThunkContext.RealModeBufferSize = EFI_PAGES_TO_SIZE (RealModeBufferSize);\r
+  mThunkContext.ThunkAttributes    = 3;\r
+  AsmPrepareThunk16(&mThunkContext);\r
+  \r
+}\r
+\r
+BOOLEAN\r
+EFIAPI\r
+LegacyBiosInt86 (\r
+  IN  UINT8                           BiosInt,\r
+  IN  EFI_IA32_REGISTER_SET           *Regs\r
+  )\r
+{\r
+  UINTN                 Status;\r
+  UINTN                 Eflags;\r
+  IA32_REGISTER_SET     ThunkRegSet;\r
+  BOOLEAN               Ret;\r
+  UINT16                *Stack16;\r
+  \r
+  Regs->X.Flags.Reserved1 = 1;\r
+  Regs->X.Flags.Reserved2 = 0;\r
+  Regs->X.Flags.Reserved3 = 0;\r
+  Regs->X.Flags.Reserved4 = 0;\r
+  Regs->X.Flags.IOPL      = 3;\r
+  Regs->X.Flags.NT        = 0;\r
+  Regs->X.Flags.IF        = 1;\r
+  Regs->X.Flags.TF        = 0;\r
+  Regs->X.Flags.CF        = 0;\r
+\r
+  ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));\r
+  ThunkRegSet.E.EDI  = Regs->E.EDI;\r
+  ThunkRegSet.E.ESI  = Regs->E.ESI;\r
+  ThunkRegSet.E.EBP  = Regs->E.EBP;\r
+  ThunkRegSet.E.EBX  = Regs->E.EBX;\r
+  ThunkRegSet.E.EDX  = Regs->E.EDX;\r
+  ThunkRegSet.E.ECX  = Regs->E.ECX;\r
+  ThunkRegSet.E.EAX  = Regs->E.EAX;\r
+  ThunkRegSet.E.DS   = Regs->E.DS;\r
+  ThunkRegSet.E.ES   = Regs->E.ES;\r
+\r
+  CopyMem (&(ThunkRegSet.E.EFLAGS), &(Regs->E.EFlags), sizeof (UINT32));\r
\r
+  //\r
+  // The call to Legacy16 is a critical section to EFI\r
+  //\r
+  Eflags = AsmReadEflags ();\r
+  if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
+    DisableInterrupts ();\r
+  }\r
+\r
+  //\r
+  // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.\r
+  //\r
+  Status = gLegacy8259->SetMode (gLegacy8259, Efi8259LegacyMode, NULL, NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));\r
+  Stack16 -= sizeof (ThunkRegSet.E.EFLAGS) / sizeof (UINT16);\r
+  CopyMem (Stack16, &ThunkRegSet.E.EFLAGS, sizeof (ThunkRegSet.E.EFLAGS));\r
+\r
+  ThunkRegSet.E.SS   = (UINT16) (((UINTN) Stack16 >> 16) << 12);\r
+  ThunkRegSet.E.ESP  = (UINT16) (UINTN) Stack16;\r
+  ThunkRegSet.E.Eip  = (UINT16)((UINT32 *)NULL)[BiosInt];\r
+  ThunkRegSet.E.CS   = (UINT16)(((UINT32 *)NULL)[BiosInt] >> 16);\r
+  mThunkContext.RealModeState = &ThunkRegSet;\r
+  AsmThunk16 (&mThunkContext);\r
+\r
+  //\r
+  // Restore protected mode interrupt state\r
+  //\r
+  Status = gLegacy8259->SetMode (gLegacy8259, Efi8259ProtectedMode, NULL, NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // End critical section\r
+  //\r
+  if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
+    EnableInterrupts ();\r
+  }\r
+\r
+  Regs->E.EDI      = ThunkRegSet.E.EDI;      \r
+  Regs->E.ESI      = ThunkRegSet.E.ESI;  \r
+  Regs->E.EBP      = ThunkRegSet.E.EBP;  \r
+  Regs->E.EBX      = ThunkRegSet.E.EBX;  \r
+  Regs->E.EDX      = ThunkRegSet.E.EDX;  \r
+  Regs->E.ECX      = ThunkRegSet.E.ECX;  \r
+  Regs->E.EAX      = ThunkRegSet.E.EAX;\r
+  Regs->E.SS       = ThunkRegSet.E.SS;\r
+  Regs->E.CS       = ThunkRegSet.E.CS;  \r
+  Regs->E.DS       = ThunkRegSet.E.DS;  \r
+  Regs->E.ES       = ThunkRegSet.E.ES;\r
+\r
+  CopyMem (&(Regs->E.EFlags), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));\r
+\r
+  Ret = (BOOLEAN) (Regs->E.EFlags.CF == 1);\r
+\r
+  return Ret;\r
+}\r
index d77907287e85475137d57c9dfeb040020819b0eb..ca01c5d4e840adb2624cd81a9fb112d05aa8b985 100644 (file)
@@ -36,6 +36,7 @@
   UefiDriverEntryPoint\r
   PrintLib\r
   UefiBootServicesTableLib\r
   UefiDriverEntryPoint\r
   PrintLib\r
   UefiBootServicesTableLib\r
+  BaseMemoryLib\r
 \r
 [Sources.IA32]\r
   Ia32/CpuInterrupt.asm |INTEL\r
 \r
 [Sources.IA32]\r
   Ia32/CpuInterrupt.asm |INTEL\r
@@ -53,7 +54,6 @@
 \r
 [Protocols]\r
   gEfiCpuArchProtocolGuid\r
 \r
 [Protocols]\r
   gEfiCpuArchProtocolGuid\r
-  gEfiLegacyBiosThunkProtocolGuid\r
   gEfiLegacy8259ProtocolGuid\r
 \r
 [Depex]\r
   gEfiLegacy8259ProtocolGuid\r
 \r
 [Depex]\r
index 017f49ec5c8e3577682363f21631589b806a746a..74f1eeba4fcf86fb7733caa21d55a0b9c2f3aab4 100644 (file)
@@ -24,9 +24,10 @@ Abstract:
 #include <Protocol/Legacy8259.h>\r
 \r
 #include <Protocol/LegacyBios.h>\r
 #include <Protocol/Legacy8259.h>\r
 \r
 #include <Protocol/LegacyBios.h>\r
-#include <Protocol/LegacyBiosThunk.h>\r
+\r
 \r
 #include <Library/BaseLib.h>\r
 \r
 #include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/PrintLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/PrintLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r