alder_lake_bios/Insyde/SioDummyPkg/Library/SioLib/SioLib.c

441 lines
9.9 KiB
C

/** @file
SIO Library.
;******************************************************************************
;* Copyright (c) 2014, Insyde Software Corporation. 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/SioLib.h>
/**
Pass in informatioin to find LDN of SIO device.
@param[in] *DeviceProtocolTable DeviceProtocolFunction table pointer.
@param[in] Devicee What kind of the device.
@param[in] DeviceInstance SIO instance.
@param[out] LDN LDN of SIO device.
**/
VOID
FindDeviceLdn (
IN EFI_INSTALL_DEVICE_FUNCTION *DeviceProtocolTable,
IN UINT8 Device,
IN UINT8 DeviceInstance,
OUT UINT8 *Ldn
)
{
if (DeviceProtocolTable != NULL) {
while (DeviceProtocolTable->Device != NULL_ID) {
if ((DeviceProtocolTable->Device == Device) && (DeviceProtocolTable->Instance == DeviceInstance)) {
*Ldn = DeviceProtocolTable->Ldn;
return;
}
DeviceProtocolTable++;
}
}
return;
}
/**
Write data to the specific register.
@param[in] Index SIO index port.
@param[in] Data The 8 bits value write to index port.
**/
VOID
IDW8 (
IN UINT8 Index,
IN UINT8 Data,
IN EFI_SIO_RESOURCE_FUNCTION *SioResourceFunction
)
{
SioWrite8 (
SioResourceFunction->SioCfgPort,
Index,
SioResourceFunction->ScriptFlag
);
SioWrite8 (
SioResourceFunction->SioCfgPort + 1,
Data,
SioResourceFunction->ScriptFlag
);
}
/**
Read data to the specific register.
@param[in] Index SIO index port.
@retval UINT8 Read value from SIO.
**/
UINT8
IDR8 (
IN UINT8 Index,
IN EFI_SIO_RESOURCE_FUNCTION *SioResourceFunction
)
{
SioWrite8 (
SioResourceFunction->SioCfgPort,
Index,
FALSE
);
return SioRead8(SioResourceFunction->SioCfgPort + 1);
}
/**
Writes an I/O port.
@param[in] Port I/O Port to write.
@param[in] Value The 8 bits value write to port.
**/
VOID
SioWrite8 (
IN UINT16 Port,
IN UINT8 Value,
IN BOOLEAN ScriptFlag
)
{
IoWrite8 ((UINTN)Port, Value);
if (ScriptFlag == TRUE) {
S3BootScriptSaveIoWrite (
EfiBootScriptWidthUint8,
Port,
1,
&Value
);
}
}
/**
Writes an I/O port.
@param[in] Port I/O Port to write.
@retval Value Get data from SIO.
**/
UINT8
SioRead8 (
IN UINT16 Port
)
{
return IoRead8 ((UINTN)Port);
}
/**
Check physical existence of keyboard.
@retval True or false Keyboard existence return true, otherwise funs return false
**/
BOOLEAN
KbcExistence (
)
{
if (IoRead8 (DATA_PORT) == DECODE_NOT_OPEN) return FALSE;
WriteValueToKbcPort (DATA_PORT, ECHO_COMMAND, 0);
while(!(IoRead8(STATUS_PORT) & BIT0));
if (IoRead8(DATA_PORT) == ECHO) return TRUE;
return FALSE;
}
/**
Check physical existence of MOUSE.
@retval True or false Mouse existence return true, otherwise funs return false
**/
BOOLEAN
MouseExistence (
)
{
BOOLEAN Result;
Result = FALSE;
if (IoRead8 (DATA_PORT) == DECODE_NOT_OPEN) return FALSE;
WriteValueToKbcPort (COMMAND_PORT, NEXT_TO_MOUSE, 0);
WriteValueToKbcPort (DATA_PORT, WRAP_MODE, 8000);
WriteValueToKbcPort (COMMAND_PORT, NEXT_TO_MOUSE, 0);
WriteValueToKbcPort (DATA_PORT, TEST_VALUE, 0);
while(!(IoRead8(STATUS_PORT) & BIT0));
if (IoRead8(DATA_PORT) == TEST_VALUE) Result = TRUE;
WriteValueToKbcPort (COMMAND_PORT, NEXT_TO_MOUSE, 0);
WriteValueToKbcPort (DATA_PORT, NORMAL_MODE, 8000);
while(!(IoRead8(STATUS_PORT) & BIT0));
IoRead8(DATA_PORT);
return Result;
}
/**
Write Data or Command to specified IoPort 60h or 64h.
@param[in] Port IoPort Index.
@param[in] Value Data value or KBC command.
@param[in] StallMicroseconds Stall Microseconds.
**/
VOID
WriteValueToKbcPort (
IN UINT8 Port,
IN UINT8 Value,
IN UINT32 StallMicroseconds
)
{
while (IoRead8 (STATUS_PORT) & BIT0) {
IoRead8 (DATA_PORT);
}
while (IoRead8 (STATUS_PORT) & BIT1);
IoWrite8 (Port, Value);
//
// Stall Microseconds
//
while (StallMicroseconds) {
while (!(IoRead8 (0x61) & 0x10));
while (IoRead8 (0x61) & 0x10);
StallMicroseconds--;
}
while (IoRead8 (STATUS_PORT) & BIT1);
}
/**
Pass in informatioin to find extensive resource from PCD data.
@param[in, out] *TableList PCD data pointer.
@param[in] TypeInstance SIO instance.
@param[in] Device What kind of the device.
@param[in] DeviceInstance Device instance.
**/
VOID
FindExtensiveDevice (
UINT8 **PcdExtensiveCfgPointer,
UINT8 TypeInstance,
UINT8 Device,
UINT8 DeviceInstance
)
{
BOOLEAN Found;
SIO_IDENTIFY_DEVICE *Table;
Found = FALSE;
if (*PcdExtensiveCfgPointer != NULL) {
while (*(UINT32*)(*PcdExtensiveCfgPointer) != EXTENSIVE_TABLE_ENDING) {
if (*(UINT8*)(*PcdExtensiveCfgPointer) == DEVICE_EXTENSIVE_RESOURCE) {
Table = (SIO_IDENTIFY_DEVICE*)*PcdExtensiveCfgPointer;
if ((Device == Table->Device) && (DeviceInstance == Table->DeviceInstance)) {
Found = TRUE;
break;
}
}
*PcdExtensiveCfgPointer += *(UINT8*)(*PcdExtensiveCfgPointer + 1);
}
}
if (!Found) {
*PcdExtensiveCfgPointer = NULL;
}
}
/**
Pass in informatioin to find device resource from PCD data.
@param[in, out] *TableList PCD data pointer.
@param[in] TypeInstance SIO instance.
@param[in] Device What kind of the device.
@param[in] DeviceInstance Device instance.
@retval PcdPointer If found device, it'll return pointer or else it return NULL.
**/
SIO_DEVICE_LIST_TABLE*
FindSioDevice (
SIO_DEVICE_LIST_TABLE *PcdPointer,
UINT8 TypeInstance,
UINT8 Device,
UINT8 DeviceInstance
)
{
if (PcdPointer != NULL) {
//
// Calculate the number of non-zero entries in the table
//
while (!((PcdPointer->TypeH == NONE_ID) && (PcdPointer->TypeL == NONE_ID))) {
if ((PcdPointer->TypeInstance == TypeInstance) && (PcdPointer->Device == Device) &&
(PcdPointer->DeviceInstance == DeviceInstance)) {
return PcdPointer;
}
PcdPointer++;
}
}
PcdPointer = NULL;
return PcdPointer;
}
/**
Word to chage place for high byte, low byte
@param[in] Value The number need to chage.
@retval Value Function complete successfully.
**/
UINT16
UpsideDown (
IN UINT16 Value
)
{
UINT16 High;
UINT8 Low;
High = Value & 0xFF;
Low = Value >> 8;
Value = (High << 8) + Low;
return Value;
}
/**
Convert a single number to character.
It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'.
@param[in] Num The input char which need to change to a hex number.
**/
UINT16
UintToChar (
IN UINT8 Num
)
{
UINT8 Index;
UINT16 Value;
UINT8 TempValue;
Value = 0;
for (Index = 0; Index < (sizeof(UINT16)/sizeof(UINT8)); Index++) {
TempValue = Num & 0xF;
if (TempValue <= 9) {
Value = (Value << 8) + ((UINT16) (TempValue + L'0'));
}
if ((TempValue >= 0xA) && (TempValue <= 0xF)) {
Value = (Value << 8) + ((UINT16) (TempValue + L'A' - 0xA ));
}
Num = Num >> 4;
}
return Value;
}
/**
Decode character in ASCII to hexadecimal
@param[in] Asc Character in ASCII
@retval Value in hexadecimal.
**/
UINT8
AsciiToHexadecimal (
IN UINT8 Asc
)
{
if (Asc >= '0' && Asc <= '9') {
return Asc - '0';
} else if (Asc >= 'A' && Asc <= 'F') {
return Asc - 'A' + 0xA;
} else if (Asc >= 'a' && Asc <= 'f') {
return Asc - 'a' + 0xA;
}
return 0;
}
/**
Pass in informatioin to find hardware monitor resource from PCD data.
@param[in, out] *TableList PCD data pointer.
@param[in] Type Hwm type.
**/
VOID
FindExtensiveDeviceType (
IN OUT UINT8 **PcdExtensiveCfgPointer,
IN UINT8 Type
)
{
BOOLEAN Found;
Found = FALSE;
if (*PcdExtensiveCfgPointer != NULL) {
do {
*PcdExtensiveCfgPointer += *(UINT8*)(*PcdExtensiveCfgPointer + 1);
if (*(UINT8*)(*PcdExtensiveCfgPointer) == Type) {
Found = TRUE;
break;
}
} while (*(UINT8*)(*PcdExtensiveCfgPointer) != DEVICE_EXTENSIVE_RESOURCE &&
*(UINT32*)(*PcdExtensiveCfgPointer) != EXTENSIVE_TABLE_ENDING);
}
if (!Found) {
*PcdExtensiveCfgPointer = NULL;
}
}
/**
Pass in informatioin to find fan configuration from PCD data.
@param[in, out] *TableList PCD data pointer.
@param[in] Type Fan type.
**/
UINT8*
FindSmartFanType (
IN OUT UINT8 *PcdExtensiveCfgPointer,
IN UINT8 Type
)
{
BOOLEAN Found;
Found = FALSE;
if (PcdExtensiveCfgPointer != NULL) {
do {
PcdExtensiveCfgPointer += *(PcdExtensiveCfgPointer + 1);
if (*PcdExtensiveCfgPointer == Type) {
Found = TRUE;
break;
}
} while (*PcdExtensiveCfgPointer != DEVICE_EXTENSIVE_RESOURCE &&
*(UINT32*)PcdExtensiveCfgPointer != EXTENSIVE_TABLE_ENDING &&
*PcdExtensiveCfgPointer != FAN_CONFIG_TYPE);
}
if (!Found) {
PcdExtensiveCfgPointer = NULL;
}
return PcdExtensiveCfgPointer;
}