263 lines
6.5 KiB
C
263 lines
6.5 KiB
C
/** @file
|
|
DXE PSS Operation Library File
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2017 - 2021 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains a 'Sample Driver' and is licensed as such under the terms
|
|
of your license agreement with Intel or your vendor. This file may be modified
|
|
by the user, subject to the additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
#include <PiDxe.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/PssLib.h>
|
|
#include <Library/SerialIoI2cLib.h>
|
|
|
|
/**
|
|
Read data from PSS chip.
|
|
|
|
@param[out] Buffer
|
|
@param[in] Address
|
|
@param[in] Size
|
|
|
|
@retval EFI_STATUS
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ReadPssData (
|
|
UINT8 *Buffer,
|
|
UINT32 Address,
|
|
UINT32 Size
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 WriBuf [2] ={0, 0};
|
|
UINT8 I2cNumber;
|
|
|
|
if (Size == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (Buffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((DEBUG_INFO, "ReadPssData ()\n"));
|
|
|
|
I2cNumber = PcdGet8 (PcdPssI2cBusNumber);
|
|
|
|
WriBuf [0] = (UINT8) (Address >> 8);
|
|
WriBuf [1] = (UINT8) (Address & 0xFF);
|
|
|
|
Status = SerialIoI2cWrite (
|
|
0,
|
|
&I2cNumber,
|
|
PcdGet8 (PcdPssI2cSlaveAddress),
|
|
2,
|
|
WriBuf,
|
|
1000000, //1sec
|
|
400, //400kHz
|
|
NULL,
|
|
TRUE,
|
|
TRUE
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
return SerialIoI2cRead (
|
|
0,
|
|
&I2cNumber,
|
|
PcdGet8 (PcdPssI2cSlaveAddress),
|
|
Size,
|
|
Buffer,
|
|
1000000, //1sec
|
|
400, //400kHz
|
|
NULL,
|
|
FALSE
|
|
);
|
|
}
|
|
|
|
/**
|
|
Write data to PSS chip.
|
|
|
|
@param[in] Buffer
|
|
@param[in] Address
|
|
@param[in] Size
|
|
|
|
@retval EFI_STATUS
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WritePssData (
|
|
UINT8 *Buffer,
|
|
UINT32 Address,
|
|
UINTN Size
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 WriBuf [2] ={0, 0};
|
|
UINT8 I2cNumber;
|
|
|
|
if (Size == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (Buffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((DEBUG_INFO, "WritePssData()\n"));
|
|
|
|
I2cNumber = PcdGet8 (PcdPssI2cBusNumber);
|
|
|
|
WriBuf [0] = (UINT8) (Address >> 8);
|
|
WriBuf [1] = (UINT8) (Address & 0xFF);
|
|
|
|
Status = SerialIoI2cWrite (
|
|
0,
|
|
&I2cNumber,
|
|
PcdGet8 (PcdPssI2cSlaveAddress),
|
|
2,
|
|
WriBuf,
|
|
1000000, //1sec
|
|
400, //400kHz
|
|
NULL,
|
|
TRUE,
|
|
TRUE
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
return SerialIoI2cRead (
|
|
0,
|
|
&I2cNumber,
|
|
PcdGet8 (PcdPssI2cSlaveAddress),
|
|
(UINT32) Size,
|
|
Buffer,
|
|
1000000, //1sec
|
|
400, //400kHz
|
|
NULL,
|
|
FALSE
|
|
);
|
|
}
|
|
|
|
/**
|
|
Check PSS chip status.
|
|
|
|
@param[in] none
|
|
|
|
@retval EFI_STATUS
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PssDetect (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 PssData[4];
|
|
|
|
//
|
|
// Read the chip's Class ID from the TID bank, it should be 0xE2 (Gen2)
|
|
// Check whether the PSS IC is Monza X-8K
|
|
//
|
|
ZeroMem (PssData, sizeof(PssData));
|
|
Status = ReadPssData(&PssData[0], PSS_BASE_ADDR_CLASSID, 4);
|
|
DEBUG((EFI_D_INFO, "Get PSS Class ID: %2X-%2X-%2X-%2X\n",\
|
|
PssData[0], PssData[1], PssData[2], PssData[3]));
|
|
if (!EFI_ERROR(Status)) {
|
|
if ((PssData[0] == PSS_CHIP_CLASS_ID) &&
|
|
((PssData [2] & 0x0F) == PSS_CHIP_TID_MODEL_HIGH) &&
|
|
(PssData [3] == PSS_CHIP_TID_MODEL_LOW)
|
|
) {
|
|
DEBUG((EFI_D_INFO, "PSS (Monza X-8K) deteced\n"));
|
|
return EFI_SUCCESS; //Monza X-8K
|
|
} else {
|
|
return EFI_NOT_FOUND; // Other device, handled as not found.
|
|
}
|
|
} else {
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Get 16 bytes Serial Number from PSS chip.
|
|
|
|
@param[in] Buffer
|
|
@param[in] Size
|
|
|
|
@retval EFI_STATUS
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PssGetSerialNumber (
|
|
UINT8 *Buffer,
|
|
UINT32 Size
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 PssSerialNumber[PSS_SN_LENGTH + 1]; // With null termintor for string usage
|
|
|
|
if ((Size > PSS_SN_LENGTH) || (Buffer == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (PssSerialNumber, PSS_SN_LENGTH + 1);
|
|
|
|
Status = PssDetect ();
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = ReadPssData ((UINT8 *) &PssSerialNumber [0], PSS_BASE_ADDR_USER + PSS_CHIP_BOARD_SERIAL_NUMBER_OFFSET, PSS_SN_LENGTH);
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "PSS Serial Number: %a, Data Length: 0x%X\n", PssSerialNumber, AsciiStrLen((CHAR8 *)PssSerialNumber)));
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, "PSS Read Failed : %r\n", Status));
|
|
return Status;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, "PSS detect Failed : %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// If no valid Serial number is found, skip filling Smbios Type1/2 Serial number information.
|
|
//
|
|
if (AsciiStrLen((CHAR8 *)PssSerialNumber) == 0) {
|
|
DEBUG ((DEBUG_ERROR, "No valid serial number."));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
ZeroMem (Buffer, Size);
|
|
CopyMem (Buffer, PssSerialNumber, Size);
|
|
return EFI_SUCCESS;
|
|
}
|