/** @file DXE Chipset Services Library. This file contains only one function that is DxeCsSvcSataComReset(). The function DxeCsSvcSataComReset() use chipset services to reset specified SATA port. ;*************************************************************************** ;* Copyright (c) 2017, 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 #include #include #include #include #include #include #include #include #include #include //[-start-191225-IB16740000-add]// for SataDevNumber & SataFuncNumber function #include //[-end-191225-IB16740000-add]// #define V_SATA_CFG_SUB_CLASS_CODE_AHCI 0x06 #define V_SATA_CFG_SUB_CLASS_CODE_RAID 0x04 //#define ICH_ACPI_TIMER_MAX_VALUE 0x1000000 // The timer is 24 bit overflow //#define ICH_ACPI_TIMER_ADDR (FixedPcdGet16(PcdPerfPkgAcpiIoPortBaseAddress) + 0x08) // PCS-Port Control and Status Register. // PCH LP Address Offset: 92h-93h. Bit0-Bit5 // PCH H Address offset: 94h-95h. Bit0-bit7 // Bit0:Port0 Enable-(R/W), Bit1:Port1 Enable-(R/W) // Bit2:Port2 Enable-(R/W), Bit3:Port3 Enable-(R/W) // Bit4:Port4 Enable-(R/W), Bit5:Port5 Enable-(R/W) // Bit6:Port6 Enable-(R/W), Bit7:Port7 Enable-(R/W) UINT16 mAhciPortEnableBit[8] = {BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7}; /** This routine issues SATA COM reset on the specified SATA port @param[in] PortNumber The SATA port number to be reset @retval EFI_SUCCESS The SATA port has been reset successfully @retval EFI_DEVICE_ERROR 1.SATA controller isn't in IDE, AHCI or RAID mode. 2.Get error when getting PortNumberMapTable. */ EFI_STATUS SataComReset ( IN UINTN PortNumber ) { UINT8 SataMode; UINT32 BusNumber; UINT32 DeviceNumber; UINT32 FunctionNumber; PORT_NUMBER_MAP *PortNumberMapTable; //retrieved from Pcd PORT_NUMBER_MAP EndEntry; UINT16 PortEnableBit; UINTN SataRegBase; BusNumber = 0; DeviceNumber = 0; FunctionNumber = 0; PortEnableBit = 0; PortNumberMapTable = NULL; SataRegBase = MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH, SataDevNumber (SATA_1_CONTROLLER_INDEX), SataFuncNumber (SATA_1_CONTROLLER_INDEX)); ZeroMem (&EndEntry, sizeof (PORT_NUMBER_MAP)); // //Get Sata Mode // SataMode = MmioRead8 (SataRegBase + PCI_CLASSCODE_OFFSET + 1); if ((SataMode == V_SATA_CFG_SUB_CLASS_CODE_AHCI) || (SataMode == V_SATA_CFG_SUB_CLASS_CODE_RAID)) { // //AHCI Mode or RAID Mode => D23:F0 // BusNumber = DEFAULT_PCI_BUS_NUMBER_PCH; DeviceNumber = SataDevNumber (SATA_1_CONTROLLER_INDEX); FunctionNumber = SataFuncNumber (SATA_1_CONTROLLER_INDEX); PortEnableBit = mAhciPortEnableBit[PortNumber]; } else { return EFI_DEVICE_ERROR; } if (IsPchH()) { MmioAnd16 (MmPciBase (BusNumber, DeviceNumber, FunctionNumber) + R_SATA_CFG_PCS, ~PortEnableBit); gBS->Stall (400); MmioOr16 (MmPciBase (BusNumber, DeviceNumber, FunctionNumber) + R_SATA_CFG_PCS, PortEnableBit); gBS->Stall (400); } else { MmioAnd16 (MmPciBase (BusNumber, DeviceNumber, FunctionNumber) + R_SATA_CFG_PCS, ~PortEnableBit); gBS->Stall (400); MmioOr16 (MmPciBase (BusNumber, DeviceNumber, FunctionNumber) + R_SATA_CFG_PCS, PortEnableBit); gBS->Stall (400); } return EFI_SUCCESS; }