alder_lake_bios/Insyde/InsydeModulePkg/Library/CommonEcLib/CommonEcLib.c

181 lines
4.0 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2013, 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 <Uefi.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/CommonEcLib.h>
#define ACPI_TIMER_ADDR (PcdGet16(PcdPerfPkgAcpiIoPortBaseAddress) + 0x08)
#define ACPI_TIMER_MAX_VALUE 0x1000000
#define KBC_TIME_OUT 0x10000
EFI_STATUS
Stall (
IN UINTN Microseconds
)
{
UINTN Ticks;
UINTN Counts;
UINT32 CurrentTick;
UINT32 OriginalTick;
UINT32 RemainingTick;
if (Microseconds == 0) {
return EFI_SUCCESS;
}
//
// Don't use CpuIO PPI for IO port access here, it will result 915
// platform recovery fail when using the floppy,because the CpuIO PPI is
// located at the flash.Use the ASM file to replace it.
//
OriginalTick = IoRead32 (ACPI_TIMER_ADDR) & 0x00FFFFFF;
CurrentTick = OriginalTick;
//
// The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
//
Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
//
// The loops needed by timer overflow
//
Counts = Ticks / ACPI_TIMER_MAX_VALUE;
//
// remaining clocks within one loop
//
RemainingTick = (UINT32) Ticks % ACPI_TIMER_MAX_VALUE;
//
// not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
// one I/O operation, and maybe generate SMI
//
while (Counts != 0) {
CurrentTick = IoRead32 (ACPI_TIMER_ADDR) & 0x00FFFFFF;
if (CurrentTick <= OriginalTick) {
Counts--;
}
OriginalTick = CurrentTick;
}
while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
OriginalTick = CurrentTick;
CurrentTick = (UINT32) IoRead32 (ACPI_TIMER_ADDR) & 0x00FFFFFF;
}
return EFI_SUCCESS;
}
/**
Wait for output buffer full
@param[in] CommandState - the Io to read.
@retval EFI_SUCCESS - input buffer full.
**/
EFI_STATUS
WaitKbcObf (
IN UINT16 CommandState
)
{
UINT8 KbdCmdState;
UINTN Index;
KbdCmdState = 0;
for (Index = 0; Index < KBC_TIME_OUT; Index++) {
KbdCmdState = IoRead8 (CommandState);
if (KbdCmdState & KEY_OBF) {
return EFI_SUCCESS;
} else{
Stall(15);
}
}
return EFI_DEVICE_ERROR;
}
/**
Wait for input buffer empty
@param[in] CommandState - the Io to read.
@retval EFI_SUCCESS - input buffer full.
**/
EFI_STATUS
WaitKbcIbe (
IN UINT16 CommandState
)
{
UINT8 KbdCmdState;
UINTN Index;
KbdCmdState = 0;
for (Index = 0; Index < KBC_TIME_OUT; Index++) {
KbdCmdState = IoRead8 (CommandState);
if (!(KbdCmdState & KEY_IBF)) {
return EFI_SUCCESS;
} else{
Stall(15);
}
}
return EFI_DEVICE_ERROR;
}
/**
Write data to Kbc data port
@param[in] CommandState - the Io to write.
@param[in] Data - The data which want write to Kbc data port
@retval EFI_SUCCESS - Write data to Kbc port successfully
**/
EFI_STATUS
WriteKbc (
IN UINT16 CommandState,
IN UINT8 Data
)
{
IoWrite8(CommandState, Data);
return EFI_SUCCESS;
}
/**
Read data from kbc data port
@param[in] CommandState - the Io to read.
@param[in] Data - IN OUT :The data which read from Kbc data port
@retval EFI_SUCCESS - Read data from Kbc port successfully.
@retval EFI_INVALID_PARAMETER - The input parameter is invalid.
**/
EFI_STATUS
ReadKbc (
IN UINT16 CommandState,
IN OUT UINT8 *Data
)
{
if (Data == NULL) {
return EFI_INVALID_PARAMETER;
}
*Data = IoRead8 (CommandState);
return EFI_SUCCESS;
}