diff options
Diffstat (limited to 'Board/EM/RapidStartWrapper/Library/RapidStartPlatformLib/Dxe/RapidStartDxeLib.c')
-rw-r--r-- | Board/EM/RapidStartWrapper/Library/RapidStartPlatformLib/Dxe/RapidStartDxeLib.c | 722 |
1 files changed, 722 insertions, 0 deletions
diff --git a/Board/EM/RapidStartWrapper/Library/RapidStartPlatformLib/Dxe/RapidStartDxeLib.c b/Board/EM/RapidStartWrapper/Library/RapidStartPlatformLib/Dxe/RapidStartDxeLib.c new file mode 100644 index 0000000..c062033 --- /dev/null +++ b/Board/EM/RapidStartWrapper/Library/RapidStartPlatformLib/Dxe/RapidStartDxeLib.c @@ -0,0 +1,722 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/Intel Fast Flash Standby/iRST_SharkBay/RapidStartWrapper/RapidStartDxeLib/RapidStartDxeLib.c 5 3/14/14 9:56a Joshchou $ +// +// $Revision: 5 $ +// +// $Date: 3/14/14 9:56a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/Intel Fast Flash Standby/iRST_SharkBay/RapidStartWrapper/RapidStartDxeLib/RapidStartDxeLib.c $ +// +// 5 3/14/14 9:56a Joshchou +// +// 4 8/05/13 3:02a Joshchou +// [TAG] EIP130093 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] System will hang at CP 0xA2 when plug in special mSATA SSD +// and Intel Rapid Start Technology support +// [RootCause] The buffer size isn't enough. +// [Solution] Modify the size when allocate. +// +// 3 2/20/13 1:47a Bensonlai +// [TAG] EIP115468 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] [SharkBay][Rapid Start] Rapid Start can't work using GPT +// partition when enabled RAID mode +// [RootCause] Rapid Start can't work using GPT partition when enabled +// RAID mode +// [Files] RapidStartDxeLib.c +// +// 2 12/07/12 1:25a Bensonlai +// [TAG] EIP108737 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] When system in the RAID mode without the partition of the +// RapidStart, RapidStart menu still show "No Valid Partition" in the +// setup. +// [RootCause] We didn't check the RAID mode. +// [Solution] Add the RAID mode for checking whether in the RAID mode. +// [Files] RapidStartDxeLib.c +// +// 1 10/15/12 4:41a Bensonlai +// [TAG] None +// [Category] Improvement +// [Description] [Category] Improvement +// [Severity] Important +// [Description] Rename all IFFS sting to Rapid Start. +// [Files] Board\EM\RapidStartWrapper\*.*, ReferenceCode\RapidStart\*.* +// +// [Files] RapidStartDxeLib.cif +// RapidStartDxeLib.sdl +// RapidStartDxeLib.mak +// RapidStartDxeLib.c +// RapidStartDxeLib.h +// RapidStartDxeLib.inf +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: RapidStartDxeLib.c +// +// Description: RapidStart Dxe Platform Library. +// +//<AMI_FHDR_END> +//********************************************************************** + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" + +#include EFI_PROTOCOL_CONSUMER (BlockIo) +#include EFI_PROTOCOL_CONSUMER (DiskIo) +#include EFI_PROTOCOL_CONSUMER (RapidStartPlatformPolicy) +#include <SaAccess.h> +#include <PchAccess.h> +#include <UefiGpt.h> +#include <mbr.h> +#include "RapidStartDxeLib.h" +#endif + +//AMIOVERRIDE_BEGIN +#define SIGNATURE_16(A, B) ((A) | (B << 8)) +#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16)) +#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ + (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32)) +//AMIOVERRIDE_END + +#define RAPID_START_PART_TYPE_MBR 0x84 /* Hibernation partition -- APM 1.1f */ +#define PCH_EFI_RAID_DRIVER_EXECUTION_GUID \ + { 0x99D5757C, 0xD906, 0x11E0, 0x8D, 0x78, 0x8D, 0xE4, 0x48, 0x24, 0x01, 0x9B }; + +EFI_GUID gRapidStartGptGuid = RAPID_START_GPT_GUID; +UINT8 gDriveNum = 0x80; +EFI_GUID gPchEfiRaidDriverExecutionGuid = PCH_EFI_RAID_DRIVER_EXECUTION_GUID; +BOOLEAN gPchEfiRaidDriver = FALSE; + +/** + Search device path by specific Type and SubType + + @param[in,out] DevicePath - A pointer to the device path + @param[in] Type - Device path type + @param[in] SubType - Device path SubType + + @retval EFI_DEVICE_PATH_PROTOCOL - Device path found and the pointer of device path returned + @retval NULL - Specific device path not found +**/ +STATIC +EFI_DEVICE_PATH_PROTOCOL * +SearchDevicePath ( + IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN UINT8 Type, + IN UINT8 SubType + ) +{ + if (DevicePath == NULL) { + return NULL; + } + + while (!IsDevicePathEnd (DevicePath)) { + if ((DevicePathType (DevicePath) == Type) && (DevicePathSubType (DevicePath) == SubType)) { + return DevicePath; + } + + DevicePath = NextDevicePathNode (DevicePath); + } + + return NULL; +} + +STATIC +EFI_STATUS +RetrieveSataPortNumberInt13 ( + IN OUT UINT8 *PortNumber, + IN BOOLEAN GPTDetect + ) +{ + UINTN Index; + BOOLEAN CarryFlag; + EFI_IA32_REGISTER_SET Regs; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + EFI_PHYSICAL_ADDRESS TheRealModeBuffer; + VOID* Int13Buffer = NULL; + EFI_STATUS Status; + UINT8 MaxDriveCount; + + Status = gBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios); + ASSERT_EFI_ERROR(Status); + + // allocate conventional memory for int code + TheRealModeBuffer = 0x00000000000FFFFF; + Status = (gBS->AllocatePages)( + AllocateMaxAddress, + EfiBootServicesData, + 1, + &TheRealModeBuffer); + ASSERT_EFI_ERROR(Status); + + Int13Buffer = (VOID*)TheRealModeBuffer; + // clear 4K page + (gBS->SetMem)(Int13Buffer, 1024 * 4, 0); + + MaxDriveCount = *(UINT8*)0x475; +//#### DEBUG ((EFI_D_ERROR, "MaxDriveCount = %x\n", MaxDriveCount)); + + for (Index = 0; Index < MaxDriveCount; Index++) { + *(UINT16*)Int13Buffer = 0x004A; + // Get physical hard disk information by ATA identify command + Regs.X.DS = EFI_SEGMENT(Int13Buffer); + Regs.X.SI = EFI_OFFSET(Int13Buffer); + Regs.H.AH = 0x48; + + if (GPTDetect) + Regs.H.DL = 0x80 + (UINT8)Index; + else + Regs.H.DL = gDriveNum; + + DEBUG ((EFI_D_ERROR, "Drive Number = %x\n", Regs.H.DL)); + + LegacyBios->Int86 (LegacyBios, 0x13, &Regs); + CarryFlag = (BOOLEAN)Regs.X.Flags.CF; + if ((!CarryFlag) && (Regs.H.AH == 0)) { + + DEBUG ((EFI_D_ERROR, "0x28 = %x\n", *((UINT8*)(Int13Buffer)+0x28))); + DEBUG ((EFI_D_ERROR, "0x29 = %x\n", *((UINT8*)(Int13Buffer)+0x29))); + DEBUG ((EFI_D_ERROR, "0x2A = %x\n", *((UINT8*)(Int13Buffer)+0x2A))); + DEBUG ((EFI_D_ERROR, "0x2B = %x\n", *((UINT8*)(Int13Buffer)+0x2B))); + DEBUG ((EFI_D_ERROR, "0x3C = %x\n", *((UINT8*)(Int13Buffer)+0x3C))); + + if ((*((UINT8*)(Int13Buffer)+0x28) == 'R') && \ + (*((UINT8*)(Int13Buffer)+0x29) == 'A') && \ + (*((UINT8*)(Int13Buffer)+0x2A) == 'I') && \ + (*((UINT8*)(Int13Buffer)+0x2B) == 'D')) { + switch (*((UINT8*)(Int13Buffer)+0x3c)) { + case 0x01: + *PortNumber = 0; + break; + case 0x02: + *PortNumber = 1; + break; + case 0x04: + *PortNumber = 2; + break; + case 0x08: + *PortNumber = 3; + break; + case 0x10: + *PortNumber = 4; + break; + case 0x20: + *PortNumber = 5; + break; + default: + *PortNumber = 0; + break; + } + } + } + if (!GPTDetect) break; + } + if (Int13Buffer) (gBS->FreePages) (TheRealModeBuffer, 1); + + return Status; +} + +/** + Scan and check if GPT type RapidStart Store present. + + @param[in] Device - Device handle + @param[in] DevicePath - A pointer to the device path + @param[out] StoreSectors - Size of RapidStart store partition + @param[out] StoreLbaAddr - Address of RapidStart store partition + + @retval EFI_SUCCESS - GPT type RapidStart Store found. + @retval EFI_NOT_FOUND - GPT type RapidStart Store not found. +**/ +STATIC +EFI_STATUS +ScanForRapidStartGptPartition ( + IN EFI_HANDLE Device, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT UINT32 *StoreSectors, + OUT UINT64 *StoreLbaAddr + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_PARTITION_TABLE_HEADER *PrimaryHeader; + EFI_PARTITION_ENTRY *PartitionEntry; + UINT32 Index; + + Status = gBS->HandleProtocol (Device, &gEfiBlockIoProtocolGuid, (VOID*)&BlockIo); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Status = gBS->HandleProtocol (Device, &gEfiDiskIoProtocolGuid, (VOID*)&DiskIo); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + // + // Read the EFI Partition Table Header + // + PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *) AllocatePool (BlockIo->Media->BlockSize); + if (PrimaryHeader == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + 1 * BlockIo->Media->BlockSize, + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; + } +//AMIOVERRIDE_BEGIN + if(PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID ){//Check for "EFI PART" signature + FreePool (PrimaryHeader); + return EFI_NOT_FOUND; + } +//AMIOVERRIDE_END + // + // Read the partition entry. + // +//AMIOVERRIDE_BEGIN + // PartitionEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY)); + PartitionEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); +//AMIOVERRIDE_END + if (PartitionEntry == NULL) { + FreePool (PrimaryHeader); + return EFI_OUT_OF_RESOURCES; + } + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), + PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, + PartitionEntry + ); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + FreePool (PartitionEntry); + return EFI_DEVICE_ERROR; + } + + // + // Count the valid partition + // + for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) { + if (CompareGuid (&PartitionEntry[Index].PartitionTypeGUID, &gRapidStartGptGuid)) { + *StoreLbaAddr = PartitionEntry[Index].StartingLBA; + *StoreSectors = (UINT32) (PartitionEntry[Index].EndingLBA - PartitionEntry[Index].StartingLBA + 1); + DEBUG ( + (EFI_D_INFO, + "Found RapidStart GPT partition: start=%x size=%x\n", + *StoreLbaAddr, + *StoreSectors) + ); + FreePool (PrimaryHeader); + FreePool (PartitionEntry); + return EFI_SUCCESS; + } + } + + FreePool (PrimaryHeader); + FreePool (PartitionEntry); + return EFI_NOT_FOUND; +} + +/** + Scan and check if MBR type RapidStart Store present. + + @param[in] Device - Device handle + @param[out] StoreSectors - Size of RapidStart store partition + @param[out] StoreLbaAddr - Address of RapidStart store partition + + @retval EFI_SUCCESS - MBR type RapidStart Store found. + @retval EFI_NOT_FOUND - MBR type RapidStart Store not found. +**/ +STATIC +EFI_STATUS +ScanForRapidStartMbrPartition ( + IN EFI_HANDLE Device, + OUT UINT32 *StoreSectors, + OUT UINT64 *StoreLbaAddr + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + UINTN Idx; + UINT8 OsType; + + MASTER_BOOT_RECORD BootRecord; + MASTER_BOOT_RECORD *Mbr; + MASTER_BOOT_RECORD ExtBootRecord; + MASTER_BOOT_RECORD *ExtPart; + EFI_LBA Lba; + + Mbr = &BootRecord; + + Status = gBS->HandleProtocol (Device, &gEfiBlockIoProtocolGuid, (VOID *) &BlockIo); + ASSERT_EFI_ERROR (Status); + ASSERT (BlockIo != NULL); + + /// + /// read the MBR + /// + Status = BlockIo->ReadBlocks (BlockIo, BlockIo->Media->MediaId, 0, sizeof (*Mbr), Mbr); + if (Status != EFI_SUCCESS) { + DEBUG ((EFI_D_ERROR, "Cannot read MBR\n")); + return Status; + } + + if (Mbr->Sig != MBR_SIGNATURE) { + DEBUG ((EFI_D_ERROR, "Bad MBR\n")); + if (!BlockIo->Media->RemovableMedia) + gDriveNum++; + return EFI_NOT_FOUND; + } + + for (Idx = 0; Idx < NUM_MBR_PARTITIONS; Idx++) { + OsType = Mbr->PartRec[Idx].OSType; + + /// + /// ignore partitions whose OSType or Size is zero + /// + if ((OsType == 0) || (Mbr->PartRec[Idx].SizeInLba == 0)) { + continue; + } + + if (OsType == RAPID_START_PART_TYPE_MBR) { + DEBUG ( + (EFI_D_INFO, + "Found RapidStart MBR partition: start=%x size=%x\n", + Mbr->PartRec[Idx].StartingLba, + Mbr->PartRec[Idx].SizeInLba) + ); + *StoreLbaAddr = Mbr->PartRec[Idx].StartingLba; + *StoreSectors = Mbr->PartRec[Idx].SizeInLba; + return EFI_SUCCESS; + } + + // Now that a valid partition is found process it + if ((Mbr->PartRec[Idx].OSType == EXTENDED_PARTITION) || + (Mbr->PartRec[Idx].OSType == WIN95_EXTENDED_PARTITION)) { + + ExtPart = &ExtBootRecord; + + // defines where to start reading the next MBR/partition + // table from + Lba = Mbr->PartRec[Idx].StartingLba; + + // loop through logical partitions: any number of + // possible partitions + while (TRUE) { + + // if the table points back to itself, exit + if ( Lba == 0) { + break; + } + + // get Partition table from the first block of the device + Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, + Lba, sizeof (*ExtPart), ExtPart); + + if (EFI_ERROR(Status)) { + return Status; + } + + // make sure this is a valid partition + if (ExtPart->PartRec[0].OSType == NO_PARTITION) { + break; + } + + // check for problems that make the partition invalid + if ((Lba + ExtPart->PartRec[0].SizeInLba) > + (Mbr->PartRec[Idx].StartingLba + + Mbr->PartRec[Idx].SizeInLba)) { + + break; + } + + OsType = ExtPart->PartRec[0].OSType; + + if (OsType == RAPID_START_PART_TYPE_MBR) { + DEBUG ( + (EFI_D_INFO, + "Found RapidStart MBR partition: start=%x size=%x\n", + Mbr->PartRec[Idx].StartingLba, + Mbr->PartRec[Idx].SizeInLba) + ); + + *StoreLbaAddr = ExtPart->PartRec[0].StartingLba + Lba; + *StoreSectors = ExtPart->PartRec[0].SizeInLba; + return EFI_SUCCESS; + } + + // check to see if the next partition is an extended partition + if ((ExtPart->PartRec[1].OSType != EXTENDED_PARTITION) && + (ExtPart->PartRec[1].OSType != WIN95_EXTENDED_PARTITION) ) { + break; + } + + // get set up for the next partition. The Starting Lba + // address is a relative address inside the extended + // partition add the starting address of the extended + // partition to get the actual LBA where it starts + Lba = ExtPart->PartRec[1].StartingLba + + Mbr->PartRec[Idx].StartingLba; + } + } + } + + if (!BlockIo->Media->RemovableMedia) + gDriveNum++; + + return EFI_NOT_FOUND; +} + +/** + Verify if this device path was RapidStart store partition. Get SATA port number if it was. + + @param[in] AhciMode - TRUE means current SATA operation mode is AHCI, otherwise it is RAID + @param[in,out] DevicePath - A pointer to the device path + @param[in,out] PortNumber - Port Number connecting to this drive + + @retval EFI_SUCCESS - This is RapidStart Store partition and Port Number retrieved successfully. + @retval EFI_NOT_FOUND - This is not RapidStart Store +**/ +STATIC +EFI_STATUS +VerifyDevicePath ( + IN BOOLEAN AhciMode, + IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN OUT UINT8 *PortNumber + ) +{ + EFI_STATUS Status; + UINT8 Index; + + Status = EFI_NOT_FOUND; + + DevicePath = SearchDevicePath (DevicePath, MESSAGING_DEVICE_PATH, MSG_SATA_DP); + if ((SATA_DEVICE_PATH *) DevicePath != NULL) { +#if (EFI_SPECIFICATION_VERSION >= 0x0002000A) + * PortNumber = (UINT8) ((SATA_DEVICE_PATH *) DevicePath)->HBAPortNumber; +#else + *PortNumber = (UINT8) ((SATA_DEVICE_PATH *) DevicePath)->HbaPortNumber; +#endif + Status = EFI_SUCCESS; + } + + // Support Intel RST SATA UEFI Driver + if (gPchEfiRaidDriver) { + for (Index = 0; Index < 6; Index++) { + if (*PortNumber & (1 << Index)) { + *PortNumber = Index; + break; + } + } + } + + + if (Status == EFI_SUCCESS) { + DEBUG ((EFI_D_INFO, "Port number=%X\n", *PortNumber)); + } + + return Status; +} + +/** + Look through all device handles to detect if any GPT/MBR type RapidStart Store present + + @param[in] AhciMode - TRUE means current SATA operation mode is AHCI, otherwise it is RAID + @param[in] RapidStartPolicy - RapidStart Platform Policy protocol + @param[out] StoreSectors - Size of RapidStart store partition + @param[out] StoreLbaAddr - Address of RapidStart store partition + @param[out] StoreSataPort - Port number for RapidStart store partition + + @retval EFI_SUCCESS - RapidStart Store found + @retval EFI_NOT_FOUND - RapidStart Store not found +**/ +STATIC +EFI_STATUS +DetectRapidStartPartition ( + IN BOOLEAN AhciMode, + IN RAPID_START_PLATFORM_POLICY_PROTOCOL *RapidStartPolicy, + OUT UINT32 *StoreSectors, + OUT UINT64 *StoreLbaAddr, + OUT UINT8 *StoreSataPort + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN Index; + + Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &HandleBuffer); + if (!EFI_ERROR (Status)) { + // + // Loop through all the device handles that support the BLOCK_IO Protocol + // + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &DevicePath); + if (EFI_ERROR (Status) || DevicePath == NULL) { + continue; + } + + if (VerifyDevicePath (AhciMode, DevicePath, StoreSataPort) == EFI_SUCCESS || (AhciMode == 0)) { //Raid mode + Status = ScanForRapidStartGptPartition (HandleBuffer[Index], DevicePath, StoreSectors, StoreLbaAddr); + if (Status == EFI_SUCCESS) { + if ( (!AhciMode) && (!gPchEfiRaidDriver) ) RetrieveSataPortNumberInt13(StoreSataPort, TRUE); + DEBUG ((EFI_D_INFO, "Found Gpt RapidStart Store on SATA port=%d\n", *StoreSataPort)); + break; + } + Status = ScanForRapidStartMbrPartition (HandleBuffer[Index], StoreSectors, StoreLbaAddr); + if (Status == EFI_SUCCESS) { + + if ( (!AhciMode) && (!gPchEfiRaidDriver) ) RetrieveSataPortNumberInt13(StoreSataPort, FALSE); + + DEBUG ((EFI_D_INFO, "Found Mbr RapidStart Store on SATA port=%d\n", *StoreSataPort)); + break; + } + } + } + + FreePool (HandleBuffer); + } + + return Status; +} + +/** + Search if any type of RapidStart Store partition present + + @param[in] RapidStartPolicy - RapidStart Platform Policy protocol + @param[out] StoreSectors - Size of RapidStart store partition + @param[out] StoreLbaAddr - Address of RapidStart store partition + @param[out] StoreSataPort - Port number for RapidStart store partition + + @retval EFI_SUCCESS - GPT or MBR type RapidStart Store found + @retval EFI_NOT_FOUND - GPT or MBR type RapidStart Store not found +**/ +EFI_STATUS +SearchRapidStartStore ( + IN RAPID_START_PLATFORM_POLICY_PROTOCOL *RapidStartPolicy, + OUT UINT32 *StoreSectors, + OUT UINT64 *StoreLbaAddr, + OUT UINT8 *StoreSataPort + ) +{ + BOOLEAN AhciMode; + EFI_STATUS Status; + VOID *Empty; + + *StoreSectors = 0; + *StoreLbaAddr = 0; + *StoreSataPort = 0; + + // + // Get current SATA operation mode (only AHCI or RAID mode is supported) + // + AhciMode = (MmioRead8 ( + MmPciAddress ( + 0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_SATA, + PCI_FUNCTION_NUMBER_PCH_SATA, + R_PCH_SATA_SUB_CLASS_CODE) + ) == V_PCH_SATA_SUB_CLASS_CODE_AHCI); + + Status = gBS->LocateProtocol(&gPchEfiRaidDriverExecutionGuid, NULL, &Empty); + if (Status == EFI_SUCCESS) gPchEfiRaidDriver = TRUE; + + Status = DetectRapidStartPartition (AhciMode, RapidStartPolicy, StoreSectors, StoreLbaAddr, StoreSataPort); + + return Status; +} + +/** + Generate RapidStart Store UID + + @retval UINT64 as RapidStart Store UID +**/ +UINT64 +GenerateRapidStartStoreUid ( + VOID + ) +{ + UINT64 Uid; + UINT32 HpetBase; + UINT32 HpetSetting; + + Uid = AsmReadTsc (); + + HpetSetting = MmioRead32 (PCH_RCRB_BASE + R_PCH_RCRB_HPTC); + if (HpetSetting & B_PCH_RCRB_HPTC_AE) { + HpetBase = R_PCH_PCH_HPET_CONFIG + (HpetSetting & B_PCH_RCRB_HPTC_AS) * 0x1000; + Uid ^= (LShiftU64 ((*(UINT64 *) (UINTN) (HpetBase + 0xF0)), 32)); + } else { + // + // Use certain random memory content as part of UID. + // + Uid ^= (LShiftU64 ((*(UINT64 *) (UINTN) (0xF5C00)), 32)); + } + + return Uid; +} + +VOID +EnableHibernate ( + VOID + ) +/*++ + +Routine Description: + + Re-enable Hibernation when RapidStart enabled but RapidStart Store not present. + +Arguments: + + None + +Returns: + + None + +--*/ +{ +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* |