213 lines
5.2 KiB
C
213 lines
5.2 KiB
C
/** @file
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2012 - 2019 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 <Library/MmPciLib.h>
|
|
#include <Library/EcMiscLib.h>
|
|
#include <Library/EcLib.h>
|
|
#include <Library/TimerLib.h>
|
|
#include <Library/IoLib.h>
|
|
|
|
#include "E3DongleLibInternal.h"
|
|
|
|
|
|
EFI_STATUS
|
|
ECSpaceRead (
|
|
IN UINT8 Offset,
|
|
OUT UINT8 *Value
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = SendEcCommand(EC_C_READ_MEM);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = SendEcData(Offset);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = ReceiveEcData(Value);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
ECSpaceWrite (
|
|
IN UINT8 Offset,
|
|
IN UINT8 Value
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = SendEcCommand(EC_C_WRITE_MEM);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = SendEcData(Offset);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = SendEcData(Value);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
ECSpaceAndOr (
|
|
IN UINT8 Offset,
|
|
IN UINT8 AndValue,
|
|
IN UINT8 OrValue
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Value;
|
|
|
|
Status = ECSpaceRead(Offset, &Value);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Value = Value & AndValue | OrValue;
|
|
Status = ECSpaceWrite(Offset,Value);
|
|
if(EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Sends command and to command & data ports which are decoded by EC.
|
|
|
|
@param[in] CmdPort CommandIO Port to be sent to
|
|
@param[in] Command Command byte to send
|
|
@param[in] DataPort Data IO Port to be sent to
|
|
@param[in] Data Data byte to send
|
|
@param[in] StatusPort Status IO Port to be sent to
|
|
@param[in] Timeout Timeout in microseonds
|
|
|
|
@retval EFI_SUCCESS Command success
|
|
@retval EFI_DEVICE_ERROR Command error
|
|
@retval EFI_TIMEOUT Command timeout
|
|
**/
|
|
EFI_STATUS
|
|
SendEcPortCommandAndDataTimeout (
|
|
IN UINT8 CmdPort,
|
|
IN UINT8 Command,
|
|
IN UINT8 DataPort,
|
|
IN UINT8 Data,
|
|
IN UINT8 StatusPort,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINT8 EcStatus;
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
|
|
Index = 0;
|
|
EcStatus = 0;
|
|
//
|
|
// Wait for EC to be ready (with a timeout)
|
|
//
|
|
EcStatus = IoRead8 ((UINTN)StatusPort & 0xFF);
|
|
//
|
|
// Check if output buffer bit(OBF) is set.
|
|
// Read and discard the output buffer data so that next BIOS-EC cmd is in sync
|
|
// OBF is cleared by h/w after all data in output buffer is read by BIOS.
|
|
//
|
|
while (((EcStatus & EC_S_OBF) != 0) && (Index < Timeout)) {
|
|
//
|
|
// Read EC data
|
|
//
|
|
MicroSecondDelay (10);
|
|
IoRead8 (DataPort);
|
|
EcStatus = IoRead8 ((UINTN)StatusPort & 0xFF);;
|
|
Index+=10;
|
|
}
|
|
|
|
if (Index >= Timeout) {
|
|
Status = EFI_TIMEOUT;
|
|
}
|
|
|
|
Index = 0;
|
|
|
|
while (((EcStatus & EC_S_IBF) != 0) && (Index < Timeout)) {
|
|
MicroSecondDelay (10);
|
|
EcStatus = IoRead8 ((UINTN)StatusPort & 0xFF);;
|
|
Index+=10;
|
|
}
|
|
|
|
if (Index >= Timeout) {
|
|
Status = EFI_TIMEOUT;
|
|
}
|
|
|
|
//
|
|
// Send the EC command
|
|
//
|
|
IoWrite8 (CmdPort, Command);
|
|
|
|
EcStatus = IoRead8 ((UINTN)StatusPort & 0xFF);;
|
|
Index = 0;
|
|
while (((EcStatus & EC_S_IBF) != 0) && (Index < Timeout)) {
|
|
MicroSecondDelay (10);
|
|
EcStatus = IoRead8 ((UINTN)StatusPort & 0xFF);;
|
|
Index+=10;
|
|
}
|
|
|
|
if (Index >= Timeout) {
|
|
Status = EFI_TIMEOUT;
|
|
}
|
|
|
|
//
|
|
// Send the EC data
|
|
//
|
|
IoWrite8 (DataPort, Data);
|
|
|
|
EcStatus = IoRead8 ((UINTN)StatusPort & 0xFF);;
|
|
Index = 0;
|
|
while (((EcStatus & EC_S_IBF) != 0) && (Index < Timeout)) {
|
|
MicroSecondDelay (10);
|
|
EcStatus = IoRead8 ((UINTN)StatusPort & 0xFF);;
|
|
Index+=10;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|