alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/ChipsetSvcDxe/SataComReset.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;
}