]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Thunk.c
Remove IntelFrameworkModulePkg
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / Thunk.c
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Thunk.c b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Thunk.c
deleted file mode 100644 (file)
index a4985ed..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-/** @file\r
-  Call into 16-bit BIOS code, Use AsmThunk16 function of BaseLib.\r
-\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "LegacyBiosInterface.h"\r
-\r
-THUNK_CONTEXT      mThunkContext;\r
-\r
-/**\r
-  Sets the counter value for Timer #0 in a legacy 8254 timer.\r
-\r
-  @param  Count - The 16-bit counter value to program into Timer #0 of the legacy 8254 timer.\r
-\r
-**/\r
-VOID\r
-SetPitCount (\r
-  IN UINT16  Count\r
-  )\r
-{\r
-  IoWrite8 (TIMER_CONTROL_PORT, TIMER0_CONTROL_WORD);\r
-  IoWrite8 (TIMER0_COUNT_PORT, (UINT8) (Count & 0xFF));\r
-  IoWrite8 (TIMER0_COUNT_PORT, (UINT8) ((Count>>8) & 0xFF));\r
-}\r
-\r
-/**\r
-  Thunk to 16-bit real mode and execute a software interrupt with a vector\r
-  of BiosInt. Regs will contain the 16-bit register context on entry and\r
-  exit.\r
-\r
-  @param  This    Protocol instance pointer.\r
-  @param  BiosInt Processor interrupt vector to invoke\r
-  @param  Regs    Register contexted passed into (and returned) from thunk to\r
-                  16-bit mode\r
-\r
-  @retval FALSE   Thunk completed, and there were no BIOS errors in the target code.\r
-                  See Regs for status.\r
-  @retval TRUE    There was a BIOS erro in the target code.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosInt86 (\r
-  IN  EFI_LEGACY_BIOS_PROTOCOL      *This,\r
-  IN  UINT8                         BiosInt,\r
-  IN  EFI_IA32_REGISTER_SET         *Regs\r
-  )\r
-{\r
-  UINT16                Segment;\r
-  UINT16                Offset;\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        = 0;\r
-  Regs->X.Flags.TF        = 0;\r
-  Regs->X.Flags.CF        = 0;\r
-  //\r
-  // The base address of legacy interrupt vector table is 0.\r
-  // We use this base address to get the legacy interrupt handler.\r
-  //\r
-  ACCESS_PAGE0_CODE (\r
-    Segment               = (UINT16)(((UINT32 *)0)[BiosInt] >> 16);\r
-    Offset                = (UINT16)((UINT32 *)0)[BiosInt];\r
-  );\r
-\r
-  return InternalLegacyBiosFarCall (\r
-           This,\r
-           Segment,\r
-           Offset,\r
-           Regs,\r
-           &Regs->X.Flags,\r
-           sizeof (Regs->X.Flags)\r
-           );\r
-}\r
-\r
-/**\r
-  Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the\r
-  16-bit register context on entry and exit. Arguments can be passed on\r
-  the Stack argument\r
-\r
-  @param  This                   Protocol instance pointer.\r
-  @param  Segment                Segemnt of 16-bit mode call\r
-  @param  Offset                 Offset of 16-bit mdoe call\r
-  @param  Regs                   Register contexted passed into (and returned) from\r
-                                 thunk to  16-bit mode\r
-  @param  Stack                  Caller allocated stack used to pass arguments\r
-  @param  StackSize              Size of Stack in bytes\r
-\r
-  @retval FALSE                  Thunk completed, and there were no BIOS errors in\r
-                                 the target code. See Regs for status.\r
-  @retval TRUE                   There was a BIOS erro in the target code.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosFarCall86 (\r
-  IN  EFI_LEGACY_BIOS_PROTOCOL        *This,\r
-  IN  UINT16                          Segment,\r
-  IN  UINT16                          Offset,\r
-  IN  EFI_IA32_REGISTER_SET           *Regs,\r
-  IN  VOID                            *Stack,\r
-  IN  UINTN                           StackSize\r
-  )\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
-  return InternalLegacyBiosFarCall (This, Segment, Offset, Regs, Stack, StackSize);\r
-}\r
-\r
-/**\r
-  Provide NULL interrupt handler which is used to check\r
-  if there is more than one HW interrupt registers with the CPU AP.\r
-\r
-  @param  InterruptType - The type of interrupt that occured\r
-  @param  SystemContext - A pointer to the system context when the interrupt occured\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-LegacyBiosNullInterruptHandler (\r
-  IN EFI_EXCEPTION_TYPE   InterruptType,\r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
-  )\r
-{\r
-}\r
-\r
-/**\r
-  Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the\r
-  16-bit register context on entry and exit. Arguments can be passed on\r
-  the Stack argument\r
-\r
-  @param  This       Protocol instance pointer.\r
-  @param  Segment    Segemnt of 16-bit mode call\r
-  @param  Offset     Offset of 16-bit mdoe call\r
-  @param  Regs       Register contexted passed into (and returned) from thunk to\r
-                     16-bit mode\r
-  @param  Stack      Caller allocated stack used to pass arguments\r
-  @param  StackSize  Size of Stack in bytes\r
-\r
-  @retval FALSE      Thunk completed, and there were no BIOS errors in the target code.\r
-                     See Regs for status.\r
-  @retval TRUE       There was a BIOS erro in the target code.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-InternalLegacyBiosFarCall (\r
-  IN  EFI_LEGACY_BIOS_PROTOCOL        *This,\r
-  IN  UINT16                          Segment,\r
-  IN  UINT16                          Offset,\r
-  IN  EFI_IA32_REGISTER_SET           *Regs,\r
-  IN  VOID                            *Stack,\r
-  IN  UINTN                           StackSize\r
-  )\r
-{\r
-  UINTN                 Status;\r
-  LEGACY_BIOS_INSTANCE  *Private;\r
-  UINT16                *Stack16;\r
-  EFI_TPL               OriginalTpl;\r
-  IA32_REGISTER_SET     ThunkRegSet;\r
-  BOOLEAN               InterruptState;\r
-  UINT64                TimerPeriod;\r
-\r
-  Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This);\r
-\r
-  ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));\r
-  ThunkRegSet.X.DI   = Regs->X.DI;\r
-  ThunkRegSet.X.SI   = Regs->X.SI;\r
-  ThunkRegSet.X.BP   = Regs->X.BP;\r
-  ThunkRegSet.X.BX   = Regs->X.BX;\r
-  ThunkRegSet.X.DX   = Regs->X.DX;\r
-  //\r
-  // Sometimes, ECX is used to pass in 32 bit data. For example, INT 1Ah, AX = B10Dh is\r
-  // "PCI BIOS v2.0c + Write Configuration DWORD" and ECX has the dword to write.\r
-  //\r
-  ThunkRegSet.E.ECX   = Regs->E.ECX;\r
-  ThunkRegSet.X.AX   = Regs->X.AX;\r
-  ThunkRegSet.E.DS   = Regs->X.DS;\r
-  ThunkRegSet.E.ES   = Regs->X.ES;\r
-\r
-  CopyMem (&(ThunkRegSet.E.EFLAGS.UintN), &(Regs->X.Flags), sizeof (Regs->X.Flags));\r
-\r
-  //\r
-  // Clear the error flag; thunk code may set it. Stack16 should be the high address\r
-  // Make Statk16 address the low 16 bit must be not zero.\r
-  //\r
-  Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));\r
-\r
-  //\r
-  // Save current rate of DXE Timer\r
-  //\r
-  Private->Timer->GetTimerPeriod (Private->Timer, &TimerPeriod);\r
-\r
-  //\r
-  // Disable DXE Timer while executing in real mode\r
-  //\r
-  Private->Timer->SetTimerPeriod (Private->Timer, 0);\r
-\r
-  //\r
-  // Save and disable interrupt of debug timer\r
-  //\r
-  InterruptState = SaveAndSetDebugTimerInterrupt (FALSE);\r
-\r
-  //\r
-  // The call to Legacy16 is a critical section to EFI\r
-  //\r
-  OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
-\r
-  //\r
-  // Check to see if there is more than one HW interrupt registers with the CPU AP.\r
-  // If there is, then ASSERT() since that is not compatible with the CSM because\r
-  // interupts other than the Timer interrupt that was disabled above can not be\r
-  // handled properly from real mode.\r
-  //\r
-  DEBUG_CODE (\r
-    UINTN  Vector;\r
-    UINTN  Count;\r
-\r
-    for (Vector = 0x20, Count = 0; Vector < 0x100; Vector++) {\r
-      Status = Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, LegacyBiosNullInterruptHandler);\r
-      if (Status == EFI_ALREADY_STARTED) {\r
-        Count++;\r
-      }\r
-      if (Status == EFI_SUCCESS) {\r
-        Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, NULL);\r
-      }\r
-    }\r
-    if (Count >= 2) {\r
-      DEBUG ((EFI_D_ERROR, "ERROR: More than one HW interrupt active with CSM enabled\n"));\r
-    }\r
-    ASSERT (Count < 2);\r
-  );\r
-\r
-  //\r
-  // If the Timer AP has enabled the 8254 timer IRQ and the current 8254 timer\r
-  // period is less than the CSM required rate of 54.9254, then force the 8254\r
-  // PIT counter to 0, which is the CSM required rate of 54.9254 ms\r
-  //\r
-  if (Private->TimerUses8254 && TimerPeriod < 549254) {\r
-    SetPitCount (0);\r
-  }\r
-\r
-  if (Stack != NULL && StackSize != 0) {\r
-    //\r
-    // Copy Stack to low memory stack\r
-    //\r
-    Stack16 -= StackSize / sizeof (UINT16);\r
-    CopyMem (Stack16, Stack, StackSize);\r
-  }\r
-\r
-  ThunkRegSet.E.SS   = (UINT16) (((UINTN) Stack16 >> 16) << 12);\r
-  ThunkRegSet.E.ESP  = (UINT16) (UINTN) Stack16;\r
-  ThunkRegSet.E.CS   = Segment;\r
-  ThunkRegSet.E.Eip  = Offset;\r
-\r
-  mThunkContext.RealModeState      = &ThunkRegSet;\r
-\r
-  //\r
-  // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.\r
-  //\r
-  Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259LegacyMode, NULL, NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  AsmThunk16 (&mThunkContext);\r
-\r
-  if (Stack != NULL && StackSize != 0) {\r
-    //\r
-    // Copy low memory stack to Stack\r
-    //\r
-    CopyMem (Stack, Stack16, StackSize);\r
-  }\r
-\r
-  //\r
-  // Restore protected mode interrupt state\r
-  //\r
-  Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259ProtectedMode, NULL, NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  mThunkContext.RealModeState = NULL;\r
-\r
-  //\r
-  // Enable and restore rate of DXE Timer\r
-  //\r
-  Private->Timer->SetTimerPeriod (Private->Timer, TimerPeriod);\r
-\r
-  //\r
-  // End critical section\r
-  //\r
-  gBS->RestoreTPL (OriginalTpl);\r
-\r
-  //\r
-  // OPROM may allocate EBDA range by itself and change EBDA base and EBDA size.\r
-  // Get the current EBDA base address, and compared with pre-allocate minimum\r
-  // EBDA base address, if the current EBDA base address is smaller, it indicates\r
-  // PcdEbdaReservedMemorySize should be adjusted to larger for more OPROMs.\r
-  //\r
-  DEBUG_CODE (\r
-    {\r
-      UINTN                 EbdaBaseAddress;\r
-      UINTN                 ReservedEbdaBaseAddress;\r
-\r
-      ACCESS_PAGE0_CODE (\r
-        EbdaBaseAddress = (*(UINT16 *) (UINTN) 0x40E) << 4;\r
-        ReservedEbdaBaseAddress = CONVENTIONAL_MEMORY_TOP\r
-                                  - PcdGet32 (PcdEbdaReservedMemorySize);\r
-        ASSERT (ReservedEbdaBaseAddress <= EbdaBaseAddress);\r
-      );\r
-    }\r
-  );\r
-\r
-  //\r
-  // Restore interrupt of debug timer\r
-  //\r
-  SaveAndSetDebugTimerInterrupt (InterruptState);\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->X.SS       = ThunkRegSet.E.SS;\r
-  Regs->X.CS       = ThunkRegSet.E.CS;\r
-  Regs->X.DS       = ThunkRegSet.E.DS;\r
-  Regs->X.ES       = ThunkRegSet.E.ES;\r
-\r
-  CopyMem (&(Regs->X.Flags), &(ThunkRegSet.E.EFLAGS.UintN), sizeof (Regs->X.Flags));\r
-\r
-  return (BOOLEAN) (Regs->X.Flags.CF == 1);\r
-}\r
-\r
-/**\r
-  Allocate memory < 1 MB and copy the thunker code into low memory. Se up\r
-  all the descriptors.\r
-\r
-  @param  Private                Private context for Legacy BIOS\r
-\r
-  @retval EFI_SUCCESS            Should only pass.\r
-\r
-**/\r
-EFI_STATUS\r
-LegacyBiosInitializeThunk (\r
-  IN  LEGACY_BIOS_INSTANCE    *Private\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_PHYSICAL_ADDRESS    MemoryAddress;\r
-  UINT8                   TimerVector;\r
-\r
-  MemoryAddress   = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->IntThunk;\r
-\r
-  mThunkContext.RealModeBuffer     = (VOID *) (UINTN) (MemoryAddress + ((sizeof (LOW_MEMORY_THUNK) / EFI_PAGE_SIZE) + 1) * EFI_PAGE_SIZE);\r
-  mThunkContext.RealModeBufferSize = EFI_PAGE_SIZE;\r
-  mThunkContext.ThunkAttributes    = THUNK_ATTRIBUTE_BIG_REAL_MODE | THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15;\r
-\r
-  AsmPrepareThunk16 (&mThunkContext);\r
-\r
-  //\r
-  // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver\r
-  //\r
-  TimerVector = 0;\r
-  Status = Private->Legacy8259->GetVector (Private->Legacy8259, Efi8259Irq0, &TimerVector);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Check to see if the Timer AP has hooked the IRQ0 from the 8254 PIT\r
-  //\r
-  Status = Private->Cpu->RegisterInterruptHandler (\r
-                           Private->Cpu,\r
-                           TimerVector,\r
-                           LegacyBiosNullInterruptHandler\r
-                           );\r
-  if (Status == EFI_SUCCESS) {\r
-    //\r
-    // If the Timer AP has not enabled the 8254 timer IRQ, then force the 8254 PIT\r
-    // counter to 0, which is the CSM required rate of 54.9254 ms\r
-    //\r
-    Private->Cpu->RegisterInterruptHandler (\r
-                    Private->Cpu,\r
-                    TimerVector,\r
-                    NULL\r
-                    );\r
-    SetPitCount (0);\r
-\r
-    //\r
-    // Save status that the Timer AP is not using the 8254 PIT\r
-    //\r
-    Private->TimerUses8254 = FALSE;\r
-  } else if (Status == EFI_ALREADY_STARTED) {\r
-    //\r
-    // Save status that the Timer AP is using the 8254 PIT\r
-    //\r
-    Private->TimerUses8254 = TRUE;\r
-  } else {\r
-    //\r
-    // Unexpected status from CPU AP RegisterInterruptHandler()\r
-    //\r
-    ASSERT (FALSE);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r