111 lines
4.2 KiB
C
111 lines
4.2 KiB
C
/** @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 <Library/BaseMemoryLib.h>
|
|
#include <Library/IoLib.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <PortNumberMap.h>
|
|
#include <Library/MmPciLib.h>
|
|
#include <IndustryStandard/Pci22.h>
|
|
#include <Library/PchInfoLib.h>
|
|
#include <Register/PchRegs.h>
|
|
#include <Register/SataRegs.h>
|
|
#include <Library/SataSocLib.h>
|
|
//[-start-191225-IB16740000-add]// for SataDevNumber & SataFuncNumber function
|
|
#include <Library/PchPciBdfLib.h>
|
|
//[-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;
|
|
}
|