alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/BootOptionService/BootDeviceInfo.c

397 lines
10 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2012 - 2015, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "BootDeviceInfo.h"
#include "L05Config.h"
#include <Library/FeatureLib/OemSvcSetSataDeviceLocationList.h>
EFI_L05_SATA_DEVICE_LOCATION *mSataDeviceLocationList = NULL;
EFI_STATUS
L05GetLocationByDeviceType (
IN UINT16 DeviceType,
IN OUT EFI_L05_SATA_HDD_ODD_LOCATION *Location
)
{
UINTN Index;
Index = 0;
if (mSataDeviceLocationList == NULL) {
return EFI_NOT_FOUND;
}
for (Index = 0; Index < EFI_L05_SATA_LOCATION_TABLE_MAX; Index++) {
if (mSataDeviceLocationList[Index].DeviceType == L05_BOOT_TYPE_END_OF_LIST) {
break;
} else if (mSataDeviceLocationList[Index].DeviceType == DeviceType) {
Location->Bus = mSataDeviceLocationList[Index].Bus;
Location->Device = mSataDeviceLocationList[Index].Device;
Location->Function = mSataDeviceLocationList[Index].Function;
Location->PortNumber = mSataDeviceLocationList[Index].PortNumber;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/*++
Check the CSM version for USB class code recognition
@param None.
@retval EFI_SUCCESS The CSM version is new. Which means the class code of USB device is normal.
@retval EFI_UNSUPPORTED The CSM version is old. Which means the class code of USB device is reversed.
@retval EFI_NOT_FOUND Cannot find CSM version.
--*/
EFI_STATUS
CheckCsmVersion (
)
{
UINTN Ptr;
STATIC EFI_STATUS CsmVersionStatus = EFI_NOT_READY;
if (CsmVersionStatus != EFI_NOT_READY) {
return CsmVersionStatus;
}
for (Ptr = EFI_L05_CSM_REGION_START; Ptr < EFI_L05_CSM_REGION_END; Ptr += 0x10) {
if (((EFI_COMPATIBILITY16_TABLE *) (VOID *) Ptr)->Signature == EFI_L05_CSM_SIGNATURE) {
if (((EFI_COMPATIBILITY16_TABLE *) (VOID *) Ptr)->OemRevision >= EFI_L05_CSM_VERSION_FOR_USB_CLASS) {
CsmVersionStatus = EFI_SUCCESS;
} else {
CsmVersionStatus = EFI_UNSUPPORTED;
}
return CsmVersionStatus;
}
}
CsmVersionStatus = EFI_NOT_FOUND;
return CsmVersionStatus;
}
/*++
Check the specific BBS Table entry is USB device
@param[in] CurrentBbsTable Pointer to current BBS table start address.
@retval TRUE It is USB device.
@retval FALSE It isn't USB device.
--*/
BOOLEAN
L05IsUsbDevice (
IN BBS_TABLE *CurrentBbsTable
)
{
EFI_STATUS Status;
Status = CheckCsmVersion ();
switch (Status) {
case EFI_SUCCESS:
if ((CurrentBbsTable->Class == PCI_CLASS_SERIAL) && (CurrentBbsTable->SubClass == PCI_CLASS_SERIAL_USB)) {
return TRUE;
}
break;
case EFI_UNSUPPORTED:
if ((CurrentBbsTable->Class == PCI_CLASS_SERIAL_USB) && (CurrentBbsTable->SubClass == PCI_CLASS_SERIAL)) {
return TRUE;
}
break;
case EFI_NOT_FOUND:
default:
if (((CurrentBbsTable->Class == PCI_CLASS_SERIAL_USB) && (CurrentBbsTable->SubClass == PCI_CLASS_SERIAL)) ||
((CurrentBbsTable->Class == PCI_CLASS_SERIAL) && (CurrentBbsTable->SubClass == PCI_CLASS_SERIAL_USB))
) {
return TRUE;
}
}
return FALSE;
}
BOOLEAN
L05IsThisInternalHddInfo (
IN BBS_TABLE *CurrentBbsTable,
IN UINTN TableIndex
)
{
EFI_STATUS Status;
EFI_L05_SATA_HDD_ODD_LOCATION FirstSataHddInfo;
Status = L05GetLocationByDeviceType (L05_BOOT_TYPE_BBS_FIRST_SATA_HDD, &FirstSataHddInfo);
if (EFI_ERROR (Status)) {
return FALSE;
}
if (L05IsUsbDevice (CurrentBbsTable)) {
return FALSE;
}
if (TableIndex <= 8) {
//
// IDE mode enable.
//
// System connect device(0,1F,2) first
// BbsTableIndex Dev Fun Primary/Secondary Port
// 1 1F 2 Primary 0
// 3 1F 2 Secondary 1
// 5 1F 5 Primary 4
// 7 1F 5 Secondary 5
// System connect device(0,1F,5) first
// BbsTableIndex Dev Fun Primary/Secondary Port
// 1 1F 5 Primary 4
// 3 1F 5 Secondary 5
// 5 1F 2 Primary 0
// 7 1F 2 Secondary 1
//
if ((FirstSataHddInfo.Bus == CurrentBbsTable->Bus) &&
(FirstSataHddInfo.Device == CurrentBbsTable->Device) &&
(FirstSataHddInfo.Function == CurrentBbsTable->Function)) {
switch (FirstSataHddInfo.PortNumber) {
case 0:
case 4:
if ((TableIndex == 1) || (TableIndex == 5)) {
return TRUE;
}
break;
case 1:
case 5:
if ((TableIndex == 3) || (TableIndex == 7)) {
return TRUE;
}
break;
case 2:
if ((TableIndex == 2) || (TableIndex == 6)) {
return TRUE;
}
break;
case 3:
if ((TableIndex == 4) || (TableIndex == 8)) {
return TRUE;
}
break;
default:
return FALSE;
break;
}
}
} else {
//
// AHCI or RAID mode enable.
//
// InitPerReserved:
// BIT 24-27 : Device Type
// BIT 28-31 : PortNumber
//
if (FirstSataHddInfo.PortNumber == (UINT8) (CurrentBbsTable->InitPerReserved >> 28)) {
return TRUE;
}
}
return FALSE;
}
BOOLEAN
L05IsThisSecondHddInfo (
IN BBS_TABLE *CurrentBbsTable,
IN UINTN TableIndex
)
{
EFI_STATUS Status;
EFI_L05_SATA_HDD_ODD_LOCATION SecondSataHddInfo;
Status = L05GetLocationByDeviceType (L05_BOOT_TYPE_BBS_SECOND_SATA_HDD, &SecondSataHddInfo);
if (EFI_ERROR (Status)) {
return FALSE;
}
if (L05IsUsbDevice (CurrentBbsTable)) {
return FALSE;
}
if (TableIndex <= 8) {
//
// IDE mode enable.
//
// System connect device(0,1F,2) first
// BbsTableIndex Dev Fun Primary/Secondary Port
// 1 1F 2 Primary 0
// 3 1F 2 Secondary 1
// 5 1F 5 Primary 4
// 7 1F 5 Secondary 5
// System connect device(0,1F,5) first
// BbsTableIndex Dev Fun Primary/Secondary Port
// 1 1F 5 Primary 4
// 3 1F 5 Secondary 5
// 5 1F 2 Primary 0
// 7 1F 2 Secondary 1
//
if ((SecondSataHddInfo.Bus == CurrentBbsTable->Bus) &&
(SecondSataHddInfo.Device == CurrentBbsTable->Device) &&
(SecondSataHddInfo.Function == CurrentBbsTable->Function)) {
switch (SecondSataHddInfo.PortNumber) {
case 0:
case 4:
if ((TableIndex == 1) || (TableIndex == 5)) {
return TRUE;
}
break;
case 1:
case 5:
if ((TableIndex == 3) || (TableIndex == 7)) {
return TRUE;
}
break;
case 2:
if ((TableIndex == 2) || (TableIndex == 6)) {
return TRUE;
}
break;
case 3:
if ((TableIndex == 4) || (TableIndex == 8)) {
return TRUE;
}
break;
default:
return FALSE;
break;
}
}
} else {
//
// AHCI or RAID mode enable.
//
// InitPerReserved:
// BIT 24-27 : Device Type
// BIT 28-31 : PortNumber
//
if (SecondSataHddInfo.PortNumber == (UINT8) (CurrentBbsTable->InitPerReserved >> 28)) {
return TRUE;
}
}
return FALSE;
}
UINT16
L05DistinguishSataHddType (
IN BBS_TABLE *CurrentBbsTable,
IN UINTN TableIndex
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
if (Status == EFI_UNSUPPORTED || mSataDeviceLocationList == NULL) {
Status = OemSvcSetSataDeviceLocationList (&mSataDeviceLocationList);
}
if (Status == EFI_UNSUPPORTED || mSataDeviceLocationList == NULL) {
return BBS_HARDDISK;
}
if (L05IsThisInternalHddInfo (CurrentBbsTable, TableIndex)) {
return L05_BOOT_TYPE_BBS_FIRST_SATA_HDD;
} else if (L05IsThisSecondHddInfo (CurrentBbsTable, TableIndex)) {
return L05_BOOT_TYPE_BBS_SECOND_SATA_HDD;
} else {
return CurrentBbsTable->DeviceType;
}
}
UINT16
L05DistinguishEfiSataHddType (
IN UINTN PortNumber
)
{
EFI_STATUS Status;
UINTN Index;
UINT16 DeviceType;
Status = EFI_SUCCESS;
DeviceType = 0;
if (mSataDeviceLocationList == NULL) {
Status = OemSvcSetSataDeviceLocationList (&mSataDeviceLocationList);
}
if (Status == EFI_MEDIA_CHANGED && mSataDeviceLocationList == NULL) {
return L05_BOOT_TYPE_EFI_HARDDISK;
}
for (Index = 0; Index < EFI_L05_SATA_LOCATION_TABLE_MAX; Index++) {
if (mSataDeviceLocationList[Index].DeviceType == L05_BOOT_TYPE_END_OF_LIST) {
break;
} else if (mSataDeviceLocationList[Index].PortNumber == PortNumber) {
DeviceType = mSataDeviceLocationList[Index].DeviceType;
break;
}
}
switch (DeviceType) {
case L05_BOOT_TYPE_BBS_FIRST_SATA_HDD:
DeviceType = L05_BOOT_TYPE_EFI_FIRST_SATA_HDD;
break;
case L05_BOOT_TYPE_BBS_SECOND_SATA_HDD:
DeviceType = L05_BOOT_TYPE_EFI_SECOND_SATA_HDD;
break;
default:
DeviceType = L05_BOOT_TYPE_EFI_HARDDISK;
break;
}
return DeviceType;
}