397 lines
10 KiB
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;
|
|
}
|