]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / LegacyBootSupport.c
index 40d027a5238746b5b358ff2205f577a7f286b57d..a7b8e6a9a0ae7f4ded9293b5b8f4646935939b93 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, 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\r
@@ -33,6 +33,10 @@ UINT64              mLowWater           = 0xffffffffffffffffULL;
 \r
 extern BBS_TABLE           *mBbsTable;\r
 \r
+extern VOID                  *mRuntimeSmbiosEntryPoint;\r
+extern EFI_PHYSICAL_ADDRESS  mReserveSmbiosEntryPoint;\r
+extern EFI_PHYSICAL_ADDRESS  mStructureTableAddress;\r
+\r
 /**\r
   Print the BBS Table.\r
 \r
@@ -87,7 +91,7 @@ PrintBbsTable (
     //\r
     // Print DescString\r
     //\r
-    String = (CHAR8 *)(UINTN)((BbsTable[Index].DescStringSegment << 4) + BbsTable[Index].DescStringOffset);\r
+    String = (CHAR8 *)(((UINTN)BbsTable[Index].DescStringSegment << 4) + BbsTable[Index].DescStringOffset);\r
     if (String != NULL) {\r
       DEBUG ((EFI_D_INFO," ("));\r
       for (SubIndex = 0; String[SubIndex] != 0; SubIndex++) {\r
@@ -135,6 +139,72 @@ PrintHddInfo (
   return ;\r
 }\r
 \r
+/**\r
+  Print the PCI Interrupt Line and Interrupt Pin registers.\r
+**/\r
+VOID\r
+PrintPciInterruptRegister (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINTN                       Index;\r
+  EFI_HANDLE                  *Handles;\r
+  UINTN                       HandleNum;\r
+  EFI_PCI_IO_PROTOCOL         *PciIo;\r
+  UINT8                       Interrupt[2];\r
+  UINTN                       Segment;\r
+  UINTN                       Bus;\r
+  UINTN                       Device;\r
+  UINTN                       Function;\r
+\r
+  gBS->LocateHandleBuffer (\r
+         ByProtocol,\r
+         &gEfiPciIoProtocolGuid,\r
+         NULL,\r
+         &HandleNum,\r
+         &Handles\r
+         );\r
+\r
+  Bus      = 0;\r
+  Device   = 0;\r
+  Function = 0;\r
+\r
+  DEBUG ((EFI_D_INFO, "\n"));\r
+  DEBUG ((EFI_D_INFO, " bb/dd/ff interrupt line interrupt pin\n"));\r
+  DEBUG ((EFI_D_INFO, "======================================\n"));\r
+  for (Index = 0; Index < HandleNum; Index++) {\r
+    Status = gBS->HandleProtocol (Handles[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = PciIo->Pci.Read (\r
+                            PciIo,\r
+                            EfiPciIoWidthUint8,\r
+                            PCI_INT_LINE_OFFSET,\r
+                            2,\r
+                            Interrupt\r
+                            );\r
+    }\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = PciIo->GetLocation (\r
+                        PciIo,\r
+                        &Segment,\r
+                        &Bus,\r
+                        &Device,\r
+                        &Function\r
+                        );\r
+    }\r
+    if (!EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_INFO, " %02x/%02x/%02x 0x%02x           0x%02x\n",\r
+              Bus, Device, Function, Interrupt[0], Interrupt[1]));\r
+    }\r
+  }\r
+  DEBUG ((EFI_D_INFO, "\n"));\r
+\r
+  if (Handles != NULL) {\r
+    FreePool (Handles);\r
+  }\r
+}\r
+\r
 /**\r
   Identify drive data must be updated to actual parameters before boot.\r
 \r
@@ -711,6 +781,63 @@ LegacyGetDataOrTable (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Copy SMBIOS table to EfiReservedMemoryType of memory for legacy boot.\r
+\r
+**/\r
+VOID\r
+CreateSmbiosTableInReservedMemory (\r
+  VOID\r
+  )\r
+{\r
+  SMBIOS_TABLE_ENTRY_POINT    *EntryPointStructure;\r
+\r
+  if ((mRuntimeSmbiosEntryPoint == NULL) ||\r
+      (mReserveSmbiosEntryPoint == 0) ||\r
+      (mStructureTableAddress == 0)) {\r
+    return;\r
+  }\r
+\r
+  EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint;\r
+\r
+  //\r
+  // Copy SMBIOS Entry Point Structure\r
+  //\r
+  CopyMem (\r
+    (VOID *)(UINTN) mReserveSmbiosEntryPoint,\r
+    EntryPointStructure,\r
+    EntryPointStructure->EntryPointLength\r
+  );\r
+\r
+  //\r
+  // Copy SMBIOS Structure Table into EfiReservedMemoryType memory\r
+  //\r
+  CopyMem (\r
+    (VOID *)(UINTN) mStructureTableAddress,\r
+    (VOID *)(UINTN) EntryPointStructure->TableAddress,\r
+    EntryPointStructure->TableLength\r
+  );\r
+\r
+  //\r
+  // Update TableAddress in Entry Point Structure\r
+  //\r
+  EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN) mReserveSmbiosEntryPoint;\r
+  EntryPointStructure->TableAddress = (UINT32)(UINTN) mStructureTableAddress;\r
+\r
+  //\r
+  // Fixup checksums in the Entry Point Structure\r
+  //\r
+  EntryPointStructure->IntermediateChecksum = 0;\r
+  EntryPointStructure->EntryPointStructureChecksum = 0;\r
+\r
+  EntryPointStructure->IntermediateChecksum =\r
+    CalculateCheckSum8 (\r
+      (UINT8 *) EntryPointStructure + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString),\r
+      EntryPointStructure->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString)\r
+      );\r
+  EntryPointStructure->EntryPointStructureChecksum =\r
+    CalculateCheckSum8 ((UINT8 *) EntryPointStructure, EntryPointStructure->EntryPointLength);\r
+}\r
 \r
 /**\r
   Assign drive number to legacy HDD drives prior to booting an EFI\r
@@ -749,18 +876,14 @@ GenericLegacyBoot (
   EFI_HANDLE                        IdeController;\r
   UINTN                             HandleCount;\r
   EFI_HANDLE                        *HandleBuffer;\r
-  VOID                              *SmbiosTable;\r
   VOID                              *AcpiTable;\r
   UINTN                             ShadowAddress;\r
   UINT32                            Granularity;\r
-  EFI_TIMER_ARCH_PROTOCOL           *Timer;\r
-  UINT64                            TimerPeriod;\r
 \r
   LocalHddInfo  = NULL;\r
   HddCount      = 0;\r
   BbsCount      = 0;\r
   LocalBbsTable = NULL;\r
-  TimerPeriod   = 0;\r
 \r
   Private       = LEGACY_BIOS_INSTANCE_FROM_THIS (This);\r
   DEBUG_CODE (\r
@@ -776,36 +899,6 @@ GenericLegacyBoot (
   EfiToLegacy16BootTable->MajorVersion = EFI_TO_LEGACY_MAJOR_VERSION;\r
   EfiToLegacy16BootTable->MinorVersion = EFI_TO_LEGACY_MINOR_VERSION;\r
 \r
-  //\r
-  // Before starting the Legacy boot check the system ticker.\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiTimerArchProtocolGuid, \r
-                  NULL,\r
-                  (VOID **) &Timer\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = Timer->GetTimerPeriod (\r
-                    Timer,\r
-                    &TimerPeriod\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  if (TimerPeriod != DEFAULT_LAGACY_TIMER_TICK_DURATION) {\r
-    Status = Timer->SetTimerPeriod (\r
-                      Timer, \r
-                      DEFAULT_LAGACY_TIMER_TICK_DURATION\r
-                      );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-  \r
   //\r
   // If booting to a legacy OS then force HDD drives to the appropriate\r
   // boot mode by calling GetIdeHandle.\r
@@ -823,7 +916,7 @@ GenericLegacyBoot (
                                   );\r
     if (!EFI_ERROR (Status)) {\r
       IdeController = HandleBuffer[0];\r
-    }   \r
+    }\r
   }\r
   //\r
   // Unlock the Legacy BIOS region\r
@@ -871,21 +964,15 @@ GenericLegacyBoot (
       );\r
     Private->Legacy16Table->E820Length = (UINT32) CopySize;\r
   }\r
-  //\r
-  // Get SMBIOS and ACPI table pointers\r
-  //\r
-  SmbiosTable = NULL;\r
-  EfiGetSystemConfigurationTable (\r
-    &gEfiSmbiosTableGuid,\r
-    &SmbiosTable\r
-    );\r
+\r
   //\r
   // We do not ASSERT if SmbiosTable not found. It is possbile that a platform does not produce SmbiosTable.\r
   //\r
-  if (SmbiosTable == NULL) {\r
+  if (mReserveSmbiosEntryPoint == 0) {\r
     DEBUG ((EFI_D_INFO, "Smbios table is not found!\n"));\r
   }\r
-  EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)SmbiosTable;\r
+  CreateSmbiosTableInReservedMemory ();\r
+  EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)mReserveSmbiosEntryPoint;\r
 \r
   AcpiTable = NULL;\r
   Status = EfiGetSystemConfigurationTable (\r
@@ -954,7 +1041,9 @@ GenericLegacyBoot (
   //\r
   // Setup BDA and EBDA standard areas before Legacy Boot\r
   //\r
-  LegacyBiosCompleteBdaBeforeBoot (Private);\r
+  ACCESS_PAGE0_CODE (\r
+    LegacyBiosCompleteBdaBeforeBoot (Private);\r
+  );\r
   LegacyBiosCompleteStandardCmosBeforeBoot (Private);\r
 \r
   //\r
@@ -986,8 +1075,10 @@ GenericLegacyBoot (
   // Use 182/10 to avoid floating point math.\r
   //\r
   LocalTime = (LocalTime * 182) / 10;\r
-  BdaPtr    = (UINT32 *) (UINTN)0x46C;\r
-  *BdaPtr   = LocalTime;\r
+  ACCESS_PAGE0_CODE (\r
+    BdaPtr    = (UINT32 *) (UINTN)0x46C;\r
+    *BdaPtr   = LocalTime;\r
+  );\r
 \r
   //\r
   // Shadow PCI ROMs. We must do this near the end since this will kick\r
@@ -1031,9 +1122,11 @@ GenericLegacyBoot (
     &LocalBbsTable\r
     );\r
 \r
-  PrintBbsTable (LocalBbsTable);\r
-  PrintHddInfo (LocalHddInfo);\r
-\r
+  DEBUG_CODE (\r
+    PrintPciInterruptRegister ();\r
+    PrintBbsTable (LocalBbsTable);\r
+    PrintHddInfo (LocalHddInfo);\r
+    );\r
   //\r
   // If drive wasn't spun up then BuildIdeData may have found new drives.\r
   // Need to update BBS boot priority.\r
@@ -1125,8 +1218,8 @@ GenericLegacyBoot (
   //\r
   // Pass in handoff data\r
   //\r
-  Regs.X.ES = EFI_SEGMENT ((UINTN)EfiToLegacy16BootTable);\r
-  Regs.X.BX = EFI_OFFSET ((UINTN)EfiToLegacy16BootTable);\r
+  Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINTN)EfiToLegacy16BootTable);\r
+  Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINTN)EfiToLegacy16BootTable);\r
 \r
   Private->LegacyBios.FarCall86 (\r
     This,\r
@@ -1149,6 +1242,24 @@ GenericLegacyBoot (
                            0x40000,\r
                            &Granularity\r
                            );\r
+\r
+  if ((Private->Legacy16Table->TableLength >= OFFSET_OF (EFI_COMPATIBILITY16_TABLE, HiPermanentMemoryAddress)) &&\r
+      ((Private->Legacy16Table->UmaAddress != 0) && (Private->Legacy16Table->UmaSize != 0))) {\r
+    //\r
+    // Here we could reduce UmaAddress down as far as Private->OptionRom, taking into\r
+    // account the granularity of the access control.\r
+    //\r
+    DEBUG((EFI_D_INFO, "Unlocking UMB RAM region 0x%x-0x%x\n", Private->Legacy16Table->UmaAddress,\r
+                        Private->Legacy16Table->UmaAddress + Private->Legacy16Table->UmaSize));\r
+\r
+    Private->LegacyRegion->UnLock (\r
+                             Private->LegacyRegion,\r
+                             Private->Legacy16Table->UmaAddress,\r
+                             Private->Legacy16Table->UmaSize,\r
+                             &Granularity\r
+                             );\r
+  }\r
+\r
   //\r
   // Lock attributes of the Legacy Region if chipset supports\r
   //\r
@@ -1164,15 +1275,32 @@ GenericLegacyBoot (
   //\r
   EnableAllControllers (Private);\r
   if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) {\r
+\r
     //\r
     // Signal all the events that are waiting on EVT_SIGNAL_LEGACY_BOOT\r
     //\r
     EfiSignalEventLegacyBoot ();\r
+\r
+    //\r
+    // Report Status Code to indicate legacy boot event was signalled\r
+    //\r
+    REPORT_STATUS_CODE (\r
+      EFI_PROGRESS_CODE,\r
+      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)\r
+      );\r
+\r
     DEBUG ((EFI_D_INFO, "Legacy INT19 Boot...\n"));\r
+\r
     //\r
-    // Raise TPL to high level to disable CPU interrupts\r
+    // Disable DXE Timer while executing in real mode\r
     //\r
-    gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+    Private->Timer->SetTimerPeriod (Private->Timer, 0);\r
+\r
+    //\r
+    // Save and disable interrupt of debug timer\r
+    //\r
+    SaveAndSetDebugTimerInterrupt (FALSE);\r
+\r
 \r
     //\r
     // Put the 8259 into its legacy mode by reprogramming the vector bases\r
@@ -1196,13 +1324,15 @@ GenericLegacyBoot (
     //          set of TIANO vectors) or takes it over.\r
     //\r
     //\r
-    BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER);\r
-    for (Index = 0; Index < 8; Index++) {\r
-      Private->ThunkSavedInt[Index] = BaseVectorMaster[Index];\r
-      if (Private->ThunkSeg == (UINT16) (BaseVectorMaster[Index] >> 16)) {\r
-        BaseVectorMaster[Index] = (UINT32) (Private->BiosUnexpectedInt);\r
+    ACCESS_PAGE0_CODE (\r
+      BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER);\r
+      for (Index = 0; Index < 8; Index++) {\r
+        Private->ThunkSavedInt[Index] = BaseVectorMaster[Index];\r
+        if (Private->ThunkSeg == (UINT16) (BaseVectorMaster[Index] >> 16)) {\r
+          BaseVectorMaster[Index] = (UINT32) (Private->BiosUnexpectedInt);\r
+        }\r
       }\r
-    }\r
+    );\r
 \r
     ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));\r
     Regs.X.AX = Legacy16Boot;\r
@@ -1216,10 +1346,12 @@ GenericLegacyBoot (
       0\r
       );\r
 \r
-    BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER);\r
-    for (Index = 0; Index < 8; Index++) {\r
-      BaseVectorMaster[Index] = Private->ThunkSavedInt[Index];\r
-    }\r
+    ACCESS_PAGE0_CODE (\r
+      BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER);\r
+      for (Index = 0; Index < 8; Index++) {\r
+        BaseVectorMaster[Index] = Private->ThunkSavedInt[Index];\r
+      }\r
+    );\r
   }\r
   Private->LegacyBootEntered = TRUE;\r
   if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) {\r
@@ -1332,8 +1464,8 @@ LegacyBiosBootUnconventionalDevice (
   }\r
 \r
   UcdTable = (UD_TABLE *) AllocatePool (\r
-                                                                                                               sizeof (UD_TABLE)\r
-                                                                                                               );\r
+                            sizeof (UD_TABLE)\r
+                            );\r
   if (NULL == UcdTable) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -1489,10 +1621,19 @@ EfiMemoryTypeToE820Type (
   case EfiBootServicesCode:\r
   case EfiBootServicesData:\r
   case EfiConventionalMemory:\r
+  //\r
+  // The memory of EfiRuntimeServicesCode and EfiRuntimeServicesData are\r
+  // usable memory for legacy OS, because legacy OS is not aware of EFI runtime concept.\r
+  // In ACPI specification, EfiRuntimeServiceCode and EfiRuntimeServiceData\r
+  // should be mapped to AddressRangeReserved. This statement is for UEFI OS, not for legacy OS.\r
+  //\r
   case EfiRuntimeServicesCode:\r
   case EfiRuntimeServicesData:\r
     return EfiAcpiAddressRangeMemory;\r
 \r
+  case EfiPersistentMemory:\r
+    return EfiAddressRangePersistentMemory;\r
+\r
   case EfiACPIReclaimMemory:\r
     return EfiAcpiAddressRangeACPI;\r
 \r
@@ -1598,9 +1739,11 @@ LegacyBiosBuildE820 (
   //\r
   // First entry is 0 to (640k - EBDA)\r
   //\r
-  E820Table[0].BaseAddr  = 0;\r
-  E820Table[0].Length    = (UINT64) ((*(UINT16 *) (UINTN)0x40E) << 4);\r
-  E820Table[0].Type      = EfiAcpiAddressRangeMemory;\r
+  ACCESS_PAGE0_CODE (\r
+    E820Table[0].BaseAddr  = 0;\r
+    E820Table[0].Length    = (UINT64) ((*(UINT16 *) (UINTN)0x40E) << 4);\r
+    E820Table[0].Type      = EfiAcpiAddressRangeMemory;\r
+  );\r
 \r
   //\r
   // Second entry is (640k - EBDA) to 640k\r
@@ -1916,15 +2059,18 @@ LegacyBiosUpdateKeyboardLedStatus (
   UINT8                 LocalLeds;\r
   EFI_IA32_REGISTER_SET Regs;\r
 \r
-  Bda                 = (BDA_STRUC *) ((UINTN) 0x400);\r
-\r
   Private             = LEGACY_BIOS_INSTANCE_FROM_THIS (This);\r
-  LocalLeds           = Leds;\r
-  Bda->LedStatus      = (UINT8) ((Bda->LedStatus &~0x07) | LocalLeds);\r
-  LocalLeds           = (UINT8) (LocalLeds << 4);\r
-  Bda->ShiftStatus    = (UINT8) ((Bda->ShiftStatus &~0x70) | LocalLeds);\r
-  LocalLeds           = (UINT8) (Leds & 0x20);\r
-  Bda->KeyboardStatus = (UINT8) ((Bda->KeyboardStatus &~0x20) | LocalLeds);\r
+\r
+  ACCESS_PAGE0_CODE (\r
+    Bda                 = (BDA_STRUC *) ((UINTN) 0x400);\r
+    LocalLeds           = Leds;\r
+    Bda->LedStatus      = (UINT8) ((Bda->LedStatus &~0x07) | LocalLeds);\r
+    LocalLeds           = (UINT8) (LocalLeds << 4);\r
+    Bda->ShiftStatus    = (UINT8) ((Bda->ShiftStatus &~0x70) | LocalLeds);\r
+    LocalLeds           = (UINT8) (Leds & 0x20);\r
+    Bda->KeyboardStatus = (UINT8) ((Bda->KeyboardStatus &~0x20) | LocalLeds);\r
+  );\r
+\r
   //\r
   // Call into Legacy16 code to allow it to do any processing\r
   //\r
@@ -1969,7 +2115,9 @@ LegacyBiosCompleteStandardCmosBeforeBoot (
   //            to large capacity drives\r
   // CMOS 14 = BDA 40:10 plus bit 3(display enabled)\r
   //\r
-  Bda = (UINT8)(*((UINT8 *)((UINTN)0x410)) | BIT3);\r
+  ACCESS_PAGE0_CODE (\r
+    Bda = (UINT8)(*((UINT8 *)((UINTN)0x410)) | BIT3);\r
+  );\r
 \r
   //\r
   // Force display enabled\r
@@ -1997,7 +2145,7 @@ LegacyBiosCompleteStandardCmosBeforeBoot (
   //\r
   // redo memory size since it can change\r
   //\r
-  Size = 15 * SIZE_1MB;\r
+  Size = (15 * SIZE_1MB) >> 10;\r
   if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) {\r
     Size  = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10;\r
   }\r