alder_lake_bios/Insyde/InsydeModulePkg/Library/CmosLib/CmosLib.c

448 lines
10 KiB
C

/** @file
Function definition for the CMOS library.
;******************************************************************************
;* Copyright (c) 2012 - 2019, 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/IoLib.h>
#include <Library/CmosLib.h>
#include <Library/SmmServicesTableLib.h>
#define R_CMOS_INDEX 0x70
#define R_CMOS_DATA 0x71
#define INTERRUPT_FLAG BIT9
VOID
CmosDisableInterrupt (
VOID
);
VOID
CmosEableInterrupt (
VOID
);
UINT16
CmosGetCpuFlags (
VOID
);
/**
Read an 8-bit value from the address offset of CMOS.
@param[in] Address Address offset of CMOS.
@return An 8-bit value in the address offset of CMOS.
**/
UINT8
ReadCmos8 (
IN UINT8 Address
)
{
UINT16 Eflags;
UINT8 Value;
Eflags = 0;
if (gSmst == NULL) {
Eflags = CmosGetCpuFlags ();
CmosDisableInterrupt ();
}
IoWrite8 (R_CMOS_INDEX, (UINT8) (Address | (UINT8) (IoRead8 (R_CMOS_INDEX) & 0x80)));
Value = IoRead8 (R_CMOS_DATA);
if (gSmst == NULL && (Eflags & INTERRUPT_FLAG)) {
CmosEableInterrupt ();
}
return Value;
}
/**
Write an 8-bit value to the address offset of CMOS.
@param[in] Address Address offset of CMOS.
@param[in] Data Data written into CMOS.
**/
VOID
WriteCmos8 (
IN UINT8 Address,
IN UINT8 Data
)
{
UINT16 Eflags;
Eflags = 0;
if (gSmst == NULL) {
Eflags = CmosGetCpuFlags ();
CmosDisableInterrupt ();
}
IoWrite8 (R_CMOS_INDEX, (UINT8) (Address | (UINT8) (IoRead8 (R_CMOS_INDEX) & 0x80)));
IoWrite8 (R_CMOS_DATA, Data);
if (gSmst == NULL && (Eflags & INTERRUPT_FLAG)) {
CmosEableInterrupt ();
}
return;
}
/**
Read a 16-bit value from the address offset of CMOS.
@param[in] Address Address offset of CMOS.
@return A 16-bit value in the address offset of CMOS.
**/
UINT16
ReadCmos16 (
IN UINT8 Address
)
{
UINT16 Temp16 = 0;
UINT8 Temp8 = 0;
Temp8 = ReadCmos8(Address + 1);
Temp16 = (UINT16)(Temp8<<8);
Temp8 = ReadCmos8(Address);
Temp16 =(UINT16) (Temp16 + Temp8);
return Temp16;
}
/**
Write a 16-bit value to the address offset of CMOS.
@param[in] Address Address offset of CMOS.
@param[in] Data Data written into CMOS.
**/
VOID
WriteCmos16 (
IN UINT8 Address,
IN UINT16 Data
)
{
UINT8 Temp8 = 0;
Temp8 = (UINT8)(Data&0x00FF);
WriteCmos8(Address, Temp8);
Temp8 = (UINT8)((Data&0xFF00)>>8);
WriteCmos8(Address + 1, Temp8);
return;
}
/**
Read a 32-bit value from the address offset of CMOS.
@param[in] Address Address offset of CMOS.
@return A 32-bit value in the address offset of CMOS.
**/
UINT32
ReadCmos32 (
IN UINT8 Address
)
{
UINT32 Temp32 = 0;
UINT8 Temp8 = 0;
Temp8 = ReadCmos8(Address + 3);
Temp32 = (UINT32) (Temp8<<24);
Temp8 = ReadCmos8(Address + 2);
Temp32 = Temp32 + (UINT32)(Temp8<<16);
Temp8 = ReadCmos8(Address + 1);
Temp32 = Temp32 + (UINT32)(Temp8<<8);
Temp8 = ReadCmos8(Address);
Temp32 =(UINT32) (Temp32 + Temp8);
return Temp32;
}
/**
Write a 32-bit value to the address offset of CMOS.
@param[in] Address Address offset of CMOS.
@param[in] Data Data written into CMOS.
**/
VOID
WriteCmos32 (
IN UINT8 Address,
IN UINT32 Data
)
{
UINT8 Temp8 = 0;
Temp8 = (UINT8)(Data&0x000000FF);
WriteCmos8(Address, Temp8);
Temp8 = (UINT8)((Data&0x0000FF00)>>8);
WriteCmos8(Address + 1, Temp8);
Temp8 = (UINT8)((Data&0x00FF0000)>>16);
WriteCmos8(Address + 2, Temp8);
Temp8 = (UINT8)((Data&0xFF000000)>>24);
WriteCmos8(Address + 3, Temp8);
return;
}
/**
Sum standard CMOS.
@return Summed bytes 0x10 through 0x2D
**/
UINT16
SumaryCmos (
VOID
)
{
UINT8 Address;
UINT16 RunningChecksum;
UINT8 Temp;
RunningChecksum = 0;
for (Address = 0x10; Address < 0x2e; Address++) {
Temp = ReadCmos8(Address);
RunningChecksum = (UINT16) ( RunningChecksum + Temp);
}
return RunningChecksum;
}
/**
Validate standard CMOS.
@retval EFI_SUCCESS valid checksum
@retval EFI_VOLUME_CORRUPTED a corrupted checksum
**/
EFI_STATUS
ValidateCmosChecksum (
VOID
)
{
UINT16 RunningChecksum;
UINT16 Checksum;
UINT16 TempChecksum;
RunningChecksum = SumaryCmos();
TempChecksum = ReadCmos16(CmosCheckSum2E);
Checksum = (TempChecksum >> 8) + ((TempChecksum & 0xff) << 8);
if (Checksum == RunningChecksum) {
return EFI_SUCCESS;
} else {
return EFI_VOLUME_CORRUPTED;
}
}
/**
Base on writing the 8-bit I/O port specified by index port with the address value.
Read an 8-bit value from the 8-bit I/O port specified by data port.
@param[in] XCmosIndex Index port.
@param[in] XCmosData Data port.
@param[in] Address Address value.
@return An 8-bit value read.
**/
UINT8
ReadExtCmos8 (
IN UINT8 XCmosIndex,
IN UINT8 XCmosData,
IN UINT8 Address
)
{
UINT16 Eflags;
UINT8 Value;
Eflags = 0;
if (gSmst == NULL) {
Eflags = CmosGetCpuFlags ();
CmosDisableInterrupt ();
}
IoWrite8 (XCmosIndex, Address);
Value = IoRead8 (XCmosData);
if (gSmst == NULL && (Eflags & INTERRUPT_FLAG)) {
CmosEableInterrupt ();
}
return Value;
}
/**
Base on writing the 8-bit I/O port specified by index port with the address value.
Read a 16-bit value from the 8-bit I/O port specified by data port.
@param[in] XCmosIndex Index port.
@param[in] XCmosData Data port.
@param[in] Address Address value.
@return A 16-bit value read.
**/
UINT16
ReadExtCmos16 (
IN UINT8 XCmosIndex,
IN UINT8 XCmosData,
IN UINT8 Address
)
{
UINT16 Temp16 = 0;
UINT8 Temp8 = 0;
Temp8 = ReadExtCmos8(XCmosIndex, XCmosData, Address + 1);
Temp16 = (UINT16)(Temp8<<8);
Temp8 = ReadExtCmos8(XCmosIndex, XCmosData,Address);
Temp16 =(UINT16) (Temp16 + Temp8);
return Temp16;
}
/**
Base on writing the 8-bit I/O port specified by index port with the address value.
Read an 32-bit value from the 8-bit I/O port specified by data port.
@param[in] XCmosIndex Index port.
@param[in] XCmosData Data port.
@param[in] Address Address value.
@return A 32-bit value read.
**/
UINT32
ReadExtCmos32 (
IN UINT8 XCmosIndex,
IN UINT8 XCmosData,
IN UINT8 Address
)
{
UINT32 Temp32 = 0;
UINT8 Temp8 = 0;
Temp8 = ReadExtCmos8(XCmosIndex, XCmosData, Address + 3);
Temp32 = (UINT32) (Temp8<<24);
Temp8 = ReadExtCmos8(XCmosIndex, XCmosData, Address + 2);
Temp32 = Temp32 + (UINT32)(Temp8<<16);
Temp8 = ReadExtCmos8(XCmosIndex, XCmosData, Address + 1);
Temp32 = Temp32 + (UINT32)(Temp8<<8);
Temp8 = ReadExtCmos8(XCmosIndex, XCmosData, Address);
Temp32 =(UINT32) (Temp32 + Temp8);
return Temp32;
}
/**
Base on writing the 8-bit I/O port specified by index port with the address value.
Write an 8-bit value to the 8-bit I/O port specified by data port.
@param[in] XCmosIndex Index port.
@param[in] XCmosData Data port.
@param[in] Address Address value.
@param[in] Data Data written into data port.
**/
VOID
WriteExtCmos8 (
IN UINT8 XCmosIndex,
IN UINT8 XCmosData,
IN UINT8 Address,
IN UINT8 Data
)
{
UINT16 Eflags;
Eflags = 0;
if (gSmst == NULL) {
Eflags = CmosGetCpuFlags ();
CmosDisableInterrupt ();
}
IoWrite8 (XCmosIndex, Address);
IoWrite8 (XCmosData, Data);
if (gSmst == NULL && (Eflags & INTERRUPT_FLAG)) {
CmosEableInterrupt ();
}
return;
}
/**
Base on writing the 8-bit I/O port specified by index port with the address value.
Write a 16-bit value to the 8-bit I/O port specified by data port.
@param[in] XCmosIndex Index port.
@param[in] XCmosData Data port.
@param[in] Address Address value.
@param[in] Data Data written into data port.
**/
VOID
WriteExtCmos16 (
IN UINT8 XCmosIndex,
IN UINT8 XCmosData,
IN UINT8 Address,
IN UINT16 Data
)
{
UINT8 Temp8 = 0;
Temp8 = (UINT8)(Data&0x00FF);
WriteExtCmos8(XCmosIndex, XCmosData, Address, Temp8);
Temp8 = (UINT8)((Data&0xFF00)>>8);
WriteExtCmos8(XCmosIndex, XCmosData, Address + 1, Temp8);
return;
}
/**
Base on writing the 8-bit I/O port specified by index port with the address value.
Write a 32-bit value to the 8-bit I/O port specified by data port.
@param[in] XCmosIndex Index port.
@param[in] XCmosData Data port.
@param[in] Address Address value.
@param[in] Data Data written into data port.
**/
VOID
WriteExtCmos32 (
IN UINT8 XCmosIndex,
IN UINT8 XCmosData,
IN UINT8 Address,
IN UINT32 Data
)
{
UINT8 Temp8 = 0;
Temp8 = (UINT8)(Data&0x000000FF);
WriteExtCmos8(XCmosIndex, XCmosData, Address, Temp8);
Temp8 = (UINT8)((Data&0x0000FF00)>>8);
WriteExtCmos8(XCmosIndex, XCmosData, Address + 1, Temp8);
Temp8 = (UINT8)((Data&0x00FF0000)>>16);
WriteExtCmos8(XCmosIndex, XCmosData, Address + 2, Temp8);
Temp8 = (UINT8)((Data&0xFF000000)>>24);
WriteExtCmos8(XCmosIndex, XCmosData, Address + 3, Temp8);
return;
}