/** @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 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; }