alder_lake_bios/Lcfc/LfcPkg/EcFlashSmm/EcFlashSmm.c

1877 lines
42 KiB
C

/*****************************************************************************
*
*
* Copyright (c) 2012 - 2015, Hefei LCFC Information Technology Co.Ltd.
* And/or its affiliates. All rights reserved.
* Hefei LCFC Information Technology Co.Ltd. PROPRIETARY/CONFIDENTIAL.
* Use is subject to license terms.
*
*****************************************************************************/
#include "EcFlashSmm.h"
#include <Library/LfcEcLib.h>
#include <LfcCmos.h>
#include <Library/CmosLib.h>
#include <Library/SeamlessRecoveryLib.h>
#include <Library/PcdLib.h>
UINT8 OldSstDevID;
UINT8 OldDevID;
UINT8 SPIDeviceID[4];
EC_ROM_HEADER LcfcECRomHeader [] = {
// ITE 8386
{
{0x45, 0x43, 0x52, 0x4F, 0x4D, 0x00, 0x00, 0x00}, // EcRomName[8]
0x01, // EcVerMajor
0x01, // EcVerMinor
0x00, // Reserved0
0x00, // Reserved1
0x00020000, // EcRomSize
ITE_8386_ID_OFFSET, // EcRomIdOffset
ITE_8386_ID // EcRomSignature
},
// ITE 8586
{
{0x45, 0x43, 0x52, 0x4F, 0x4D, 0x00, 0x00, 0x00}, // EcRomName[8]
0x01, // EcVerMajor
0x01, // EcVerMinor
0x00, // Reserved0
0x00, // Reserved1
0x00020000, // EcRomSize
ITE_8586_ID_OFFSET, // EcRomIdOffset
ITE_8586_ID // EcRomSignature
}
};
EFI_STATUS
MyAsciiToUnicodeStr (
IN CHAR8 *AsciiString,
IN CHAR16 *UnicodeString
)
/*++
Routine Description:
Function to convert ASCII string to Unicode
Arguments:
Returns:
--*/
{
UINT8 Index;
Index = 0;
while (AsciiString[Index] != 0) {
UnicodeString[Index] = (CHAR16)AsciiString[Index];
Index++;
}
UnicodeString[Index] = 0;
return EFI_SUCCESS;
}
VOID
Usage(
VOID
)
{
Print (L"Usage: \n");
Print (L" EcRead -r|w -b:EcRomSize(Unit: KByte) FileName\n");
Print (L" Example:\n");
Print (L" Reading EC ROM to file with 128K Bytes:\n");
Print (L" EcRead.efi -r -b:128 EC.ROM\n");
Print (L" Written the EC ROM from the file:\n");
Print (L" EcRead.efi -w EC.ROM\n");
return;
}
VOID
Stall (
UINTN ms
)
{
gBS->Stall (ms);
}
VOID
ShowSSTID (
VOID
)
{
Print (L"SPI Vendor : SST \n");
}
VOID
ShowWinbondID (
VOID
)
{
Print(L"SPI Vendor : Winbond \n");
}
VOID
ShowAtmelID (
VOID
)
{
Print (L"SPI Vendor : Atmel \n");
}
VOID
ShowSTID (
VOID
)
{
Print(L"SPI Vendor : ST \n");
}
VOID
ShowSpansionID (
VOID
)
{
Print (L"SPI Vendor : Spansion \n");
}
VOID
ShowMXICID (
VOID
)
{
Print (L"SPI Vendor : MXIC \n");
}
VOID
ShowAMICID (
VOID
)
{
Print (L"SPI Vendor : AMIC \n");
}
VOID
ShowEONID (
VOID
)
{
Print (L"SPI Vendor : EON \n");
}
VOID
ShowESMTID (
VOID
)
{
Print (L"SPI Vendor : ESMT \n");
}
VOID
ShowIteID (
VOID
)
{
Print (L"SPI Vendor : ITE \n");
}
FLASH_DEV_VENDOR SpiVendor[]= {
{ SSTID, ShowSSTID },
{ WINBOND_ID, ShowWinbondID },
{ ATMEL_ID, ShowAtmelID },
{ ST_ID, ShowSTID },
{ SPANSION_ID, ShowSpansionID },
{ MXIC_ID, ShowMXICID },
{ AMIC_ID, ShowAMICID },
{ EON_ID, ShowEONID },
{ ESMT_ID, ShowESMTID },
{ ITE_ID, ShowIteID },
};
//------------------------------------
// wait EC output buffer full
//------------------------------------
VOID
WaitEcObf (
VOID
)
{
while (!(IoRead8(EC_STATUS_PORT) & EC_OBF));
}
//------------------------------------
// wait EC input buffer empty
//------------------------------------
VOID
WaitEcIbe (
VOID
)
{
while (IoRead8(EC_STATUS_PORT) & EC_IBF);
}
VOID
SendEcCmd (
UINT8 EcCmd
)
{
WaitEcIbe ();
IoWrite8 (EC_CMD_PORT, EcCmd);
WaitEcIbe ();
}
//------------------------------------
// send EC data
//------------------------------------
VOID
SendEcData (
UINT8 EcData
)
{
WaitEcIbe ();
IoWrite8 (EC_DATA_PORT, EcData);
WaitEcIbe ();
}
UINT8
ReadEcData (
VOID
)
{
WaitEcObf ();
return IoRead8(EC_DATA_PORT);
}
//------------------------------------
// wait KB output buffer full
//------------------------------------
VOID
WaitKbObf (
VOID
)
{
while (!(IoRead8(KB_STATUS_PORT) & KB_OBF));
}
VOID
WaitKbObe (
VOID
)
{
while (IoRead8 (KB_STATUS_PORT) & KB_OBF) {
IoRead8 (KB_DATA_PORT);
}
}
//------------------------------------
// wait KB input buffer empty
//------------------------------------
VOID
WaitKbIbe (
VOID
)
{
while (IoRead8(KB_STATUS_PORT) & KB_IBF);
}
VOID
SendKbCmd (
UINT8 KBCmd
)
{
WaitKbObe ();
WaitKbIbe ();
IoWrite8 (KB_CMD_PORT, KBCmd);
WaitKbIbe ();
}
//------------------------------------
// send KB data
//------------------------------------
VOID
SendKbData (
UINT8 KBData
)
{
WaitKbObe ();
WaitKbIbe ();
IoWrite8 (KB_DATA_PORT, KBData);
WaitKbIbe ();
}
UINT8
ReadKbData (
VOID
)
{
WaitKbObf ();
return IoRead8(0x62);
}
VOID
EnterFollowMode (
VOID
)
{
SendEcCmd (0x01);
}
VOID
ExitFollowMode (
VOID
)
{
SendEcCmd (0x05);
}
VOID
SendSPICommand (
UINT8 Cmd
)
{
SendEcCmd (0x02);
SendEcCmd (Cmd);
}
VOID
SendSPIByte (
UINT8 Index
)
{
SendEcCmd (0x03);
SendEcCmd (Index);
}
UINT8
BReadByteFromSPI (
VOID
)
{
SendEcCmd (0x04);
return ReadEcData();
}
VOID
WaitSPIFree (
VOID
)
{
EnterFollowMode ();
SendSPICommand (SPICMD_READ_STATUS);
while (1) {
if((BReadByteFromSPI ()&0x01) == 0x00) {
break;
}
}
ExitFollowMode();
}
VOID
WaitWriteEnable (
VOID
)
{
EnterFollowMode ();
SendSPICommand (SPICMD_READ_STATUS);
while (1) {
if((BReadByteFromSPI ()&0x03) == 0x02) {
break;
}
}
}
VOID
ShowVersion (
VOID
)
{
// Clear Screen
gST->ConOut->ClearScreen (gST->ConOut);
gST->ConOut->SetMode (gST->ConOut, 0);
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, EFI_BACKGROUND_BLACK));
Print(L"******************************************************************************\n");
Print(L" LCFC EC ROM Flash Utility Version : %s\n", ECREAD_VERSION);
Print(L" Company: Hefei LCFC Information Technology Co.Ltd.\n");
Print(L"******************************************************************************\n");
}
VOID
ShowDeviceID (
VOID
)
{
Print(L"Device ID : %x %x %x %x\n", SPIDeviceID[0], SPIDeviceID[1], SPIDeviceID[2], SPIDeviceID[3]);
}
VOID
ShowVendorID (
VOID
)
{
UINT8 Index;
for(Index = 0x00; Index < (sizeof (SpiVendor) / sizeof (FLASH_DEV_VENDOR)); Index++){
if(SPIDeviceID[0] == SpiVendor[Index].Muid) {
(SpiVendor[Index].ShowId)();
}
}
}
VOID
ReadSPIDeviceIDCmdAB (
VOID
)
{
UINT8 Index;
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_RDID);
SendSPIByte (0x00);
SendSPIByte (0x00);
SendSPIByte (0x00);
for(Index = 0x00; Index < 4; Index++) {
SPIDeviceID[Index] = BReadByteFromSPI();
}
if(SPIDeviceID[0] == SSTID) {
OldSstDevID = 1;
OldDevID = 0;
} else {
OldSstDevID = 0;
OldDevID = 1;
}
ExitFollowMode();
}
VOID
ReadSPIDeviceID (
VOID
)
{
UINT8 Index;
SPIDeviceID[0] = 0x00;
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD__DEVICE_ID);
for(Index=0x00; Index < 4; Index++) {
SPIDeviceID[Index] = BReadByteFromSPI ();
}
if (SPIDeviceID[0] == 0x00) {
ReadSPIDeviceIDCmdAB ();
}
ExitFollowMode ();
}
VOID
SpiWriteDisable (
VOID
)
{
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_WRDI);
EnterFollowMode ();
SendSPICommand (SPICMD_READ_STATUS);
while(1) {
if((BReadByteFromSPI()&0x02 )== 0x00){
break;
}
}
ExitFollowMode ();
}
VOID
SPIUnlockAll (
VOID
)
{
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_WREN);
EnterFollowMode ();
SendSPICommand (SPICMD_READ_STATUS);
while(1) {
if((BReadByteFromSPI ()&0x02) != 0x00){
break;
}
}
if(SPIDeviceID[0] == SSTID) {
EnterFollowMode ();
SendSPICommand (SPICMD_EWSR);
}
EnterFollowMode ();
SendSPICommand (SPICMD_WRSR);
SendSPIByte (0x00);
WaitSPIFree ();
}
VOID
SpiWriteEnable (
VOID
)
{
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_WREN);
if(SPIDeviceID[0] == SSTID) {
EnterFollowMode ();
SendSPICommand (SPICMD_EWSR);
}
EnterFollowMode ();
SendSPICommand (SPICMD_READ_STATUS);
while (1) {
if((BReadByteFromSPI ()&0x03 ) == 0x02) {
break;
}
}
ExitFollowMode ();
}
UINT8
SpiVerifyErase64KByte (
UINT8 BlockNum
)
{
UINT32 AddrInBlock = 0;
UINT32 Index = 0;
AddrInBlock = BlockNum * BLOCK_SIZE_64K;
SpiWriteDisable ();
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_HIGH_SPEED_READ);
SendSPIByte ((UINT8)(((AddrInBlock>>16)&0xFF))); //Addr2
SendSPIByte ((UINT8)(((AddrInBlock>>8)&0xFF))); //Addr1
SendSPIByte ((UINT8)(((AddrInBlock)&0xFF))); // fast read dummy byte
SendSPIByte (0x00);
Print (L"Erase Verify... : ");
for (Index = 0; Index < BLOCK_SIZE_64K; Index++) {
if(BReadByteFromSPI () != 0xFF) {
WaitSPIFree ();
Print (L" -- Verify Fail. \n");
return 0;
}
}
WaitSPIFree ();
Print (L" -- Verify OK. \n");
return 1;
}
UINT8
SpiVerifyErase1KByte (
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum
UINT16 BlockNum
//[-end-210616-YUNLEI0102-modify]//
)
{
UINT32 AddrInBlock = 0;
UINT32 Index = 0;
AddrInBlock = BlockNum * BLOCK_SIZE_1K;
SpiWriteDisable ();
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_HIGH_SPEED_READ);
SendSPIByte ((UINT8)(((AddrInBlock>>16)&0xFF))); //Addr2
SendSPIByte ((UINT8)(((AddrInBlock>>8)&0xFF))); //Addr1
SendSPIByte ((UINT8)(((AddrInBlock)&0xFF))); // fast read dummy byte
SendSPIByte (0x00);
for (Index = 0; Index < BLOCK_SIZE_1K; Index++) {
if(BReadByteFromSPI () != 0xFF) {
WaitSPIFree ();
return 0;
}
}
WaitSPIFree ();
return 1;
}
VOID
SpiBlockErase64KByte (
UINT8 BlockNum
)
{
UINT8 Counter;
//SpiWriteEnable();
SpiWriteEnable ();
EnterFollowMode ();
SendSPICommand (SPICMD_64K_BYTE_BE);
WaitSPIFree ();
if( OldDevID == 0x01 ) {
SpiWriteEnable ();
EnterFollowMode ();
SendSPICommand (SPICMD_64K_BYTE_BE);
ExitFollowMode ();
WaitSPIFree ();
}
//ExitFollowMode();
Print (L"Eraseing... : ");
for(Counter=0x00; Counter < 22; Counter++){
Print (L"%c", 0xDB);
}
Print (L" -- Erase OK. \n");
}
VOID
SpiBlockErase1KByte (
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum
UINT16 BlockNum
//[-end-210616-YUNLEI0102-modify]//
)
{
UINT32 AddrInBlock = 0;
AddrInBlock = BlockNum * BLOCK_SIZE_1K;
SpiWriteEnable ();
EnterFollowMode ();
SendSPICommand (SPICMD_1K_BYTE_BE);
SendSPIByte ((UINT8)((AddrInBlock>>16)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock>>8)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock)&0xFF));
WaitSPIFree ();
}
VOID
ByteProgram64KByte (
UINT8 BlockNum,
UINT8* FileBuf
)
{
UINT8 Addr0,Addr1;
UINT32 AddrInBlock = 0;
Print(L"Programing... : ");
for (Addr1=0x00; Addr1 < 0x100; Addr1++){
SpiWriteEnable ();
EnterFollowMode();
SendSPICommand (SPICMD_BYTE_PROG);
SendSPIByte (BlockNum); //Addr2
SendSPIByte (Addr1); //Addr1
SendSPIByte (0x00); //Addr0
for(Addr0=0x00; Addr0 < 0x100; Addr0++) {
SendSPIByte (FileBuf[AddrInBlock]);
AddrInBlock++;
}
WaitSPIFree ();
//SpiWriteDisable();
}
SpiWriteDisable ();
Print (L" -- Programing OK. \n");
}
VOID
AAIWordProgram64KByte (
UINT8 BlockNum,
UINT8* FileBuf
)
{
UINT8 Index;
UINT32 Counter, AddrInBlock = 0;
AddrInBlock = BlockNum * BLOCK_SIZE_64K;
Index = 0;
SpiWriteEnable();
EnterFollowMode();
SendSPICommand (SPICMD_AAI_WORD_PROG);
SendSPIByte ((UINT8)((AddrInBlock>>16)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock>>8)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock)&0xFF));
Print (L"Programing... : ");
for(Counter = 0; Counter < BLOCK_SIZE_64K; Counter++){
SendSPIByte (FileBuf[AddrInBlock+Counter]);
Index++;
if(Index == 0x02) {
Index = 0x00;
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_AAI_WORD_PROG);
}
}
SpiWriteDisable ();
WaitSPIFree ();
Print(L" -- Programing 64K bytes OK. \n");
}
VOID
AAIWordProgram1KByte (
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum
UINT16 BlockNum,
//[-end-210616-YUNLEI0102-modify]//
UINT8* FileBuf
)
{
UINT8 Index;
UINT32 Counter, AddrInBlock = 0;
AddrInBlock = BlockNum * BLOCK_SIZE_1K;
Index = 0;
SpiWriteEnable();
EnterFollowMode();
SendSPICommand (SPICMD_AAI_WORD_PROG);
SendSPIByte ((UINT8)((AddrInBlock>>16)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock>>8)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock)&0xFF));
for(Counter = 0; Counter < BLOCK_SIZE_1K; Counter++){
SendSPIByte (FileBuf[AddrInBlock + Counter]);
Index++;
if(Index == 0x02) {
Index = 0x00;
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_AAI_WORD_PROG);
}
}
SpiWriteDisable ();
WaitSPIFree ();
}
BOOLEAN
SpiVerify64KByte (
UINT8 BlockNum,
UINT8* FileBuf
)
{
UINT8 Index;
UINT32 Counter, AddrInBlock = 0;
AddrInBlock = BlockNum*BLOCK_SIZE_64K;
Index = 0;
SpiWriteDisable();
WaitSPIFree();
EnterFollowMode();
SendSPICommand (SPICMD_HIGH_SPEED_READ);
SendSPIByte ((UINT8)((AddrInBlock>>16)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock>>8)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock)&0xFF));
SendSPIByte (0x00); // fast read dummy byte
Print (L"Verify... : ");
for(Counter = 0; Counter < BLOCK_SIZE_64K; Counter++){
if (FileBuf[AddrInBlock + Counter]!=BReadByteFromSPI()){
WaitSPIFree ();
Print (L" -- Verify Fail. \n");
return 0;
}
}
WaitSPIFree ();
Print (L" -- Verify OK. \n");
return 1;
}
BOOLEAN
SpiVerify1KByte (
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum
UINT16 BlockNum,
//[-end-210616-YUNLEI0102-modify]//
UINT8* FileBuf
)
{
UINT8 Index;
UINT32 Counter, AddrInBlock = 0;
AddrInBlock = BlockNum*BLOCK_SIZE_1K;
Index = 0;
SpiWriteDisable();
WaitSPIFree();
EnterFollowMode();
SendSPICommand (SPICMD_HIGH_SPEED_READ);
SendSPIByte ((UINT8)((AddrInBlock>>16)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock>>8)&0xFF));
SendSPIByte ((UINT8)((AddrInBlock)&0xFF));
SendSPIByte (0x00); // fast read dummy byte
for(Counter = 0; Counter < BLOCK_SIZE_1K; Counter++){
if (FileBuf[AddrInBlock + Counter]!=BReadByteFromSPI()){
WaitSPIFree ();
return 0;
}
}
WaitSPIFree ();
return 1;
}
VOID
SpiRead64KByte (
UINT8 BlockNum,
UINT8* ReadBuf
)
{
UINT32 AddrInBlock = 0;
SpiWriteDisable ();
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_HIGH_SPEED_READ);
SendSPIByte (BlockNum); //Addr2
SendSPIByte (0x00); //Addr1
SendSPIByte (0x00); //Addr0
SendSPIByte (0x00); // fast read dummy byte
for (AddrInBlock = 0x00; AddrInBlock < BLOCK_SIZE_64K; AddrInBlock++){
ReadBuf[AddrInBlock] = BReadByteFromSPI();
if((AddrInBlock % (1024 * 8)) == 0x00){
Print (L".");
}
}
WaitSPIFree ();
}
VOID
SpiRead1KByte (
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum
UINT16 BlockNum,
//[-end-210616-YUNLEI0102-modify]//
UINT8* ReadBuf
)
{
UINT32 AddrInBlock = 0;
UINT32 BlockAddr = 0;
BlockAddr = BlockNum * BLOCK_SIZE_1K;
SpiWriteDisable ();
WaitSPIFree ();
EnterFollowMode ();
SendSPICommand (SPICMD_HIGH_SPEED_READ);
SendSPIByte ((UINT8)(((BlockAddr>>16)&0xFF))); //Addr2
SendSPIByte ((UINT8)(((BlockAddr>>8)&0xFF))); //Addr1
SendSPIByte ((UINT8)(((BlockAddr)&0xFF))); // fast read dummy byte
SendSPIByte (0x00);
for (AddrInBlock = 0x00; AddrInBlock < BLOCK_SIZE_1K; AddrInBlock++){
ReadBuf[AddrInBlock] = BReadByteFromSPI();
}
ExitFollowMode ();
WaitSPIFree ();
}
EFI_STATUS
OpHelp (
VOID
)
{
Usage ();
return EFI_SUCCESS;
}
EFI_STATUS
OpIdentify (
VOID
)
{
ReadSPIDeviceID ();
//ShowDeviceID ();
//ShowVendorID ();
return EFI_SUCCESS;
}
EFI_STATUS
OpRead64K (
UINT8 *ReadBuf,
UINTN BlockCount
)
{
UINT8 BlockNum = 0;
for (BlockNum = 0; BlockNum < BlockCount; BlockNum++){
Print (L"\nBlock Number : %d \n",BlockNum);
SpiRead64KByte (BlockNum, (ReadBuf + (BlockNum * BLOCK_SIZE_64K)));
}
return EFI_SUCCESS;
}
// Showing progress bar.
EFI_STATUS
ShowProgressBar (
UINTN Col,
UINTN Row,
UINTN MaxCount
)
{
UINTN Index;
// Checking input parameter.
if (MaxCount == 0) {
Print (L"MaxCount can't equal to 0\n");
return EFI_INVALID_PARAMETER;
}
// Output the progress bar in the screen.
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
gST->ConOut->SetAttribute (gST->ConOut, EFI_BLUE);
for (Index = 0; Index < PROGRESS_BAR_LEN; Index++){
Print (L"%c", BLOCKELEMENT_FULL_BLOCK);
}
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, EFI_BACKGROUND_BLACK));
return EFI_SUCCESS;
}
// Setting the progress bar item.
EFI_STATUS
SetProgressBarItem (
UINTN Col,
UINTN Row,
UINTN MaxCount,
UINTN CurValue
)
{
UINTN PrintUnit;
// Checking input parameter.
if (MaxCount == 0 || CurValue >= MaxCount) {
Print (L"MaxCount can't equal to 0\n");
return EFI_INVALID_PARAMETER;
}
// Output current value in the progress bar.
PrintUnit = ((PROGRESS_BAR_LEN - 1) * CurValue) / (MaxCount - 1);
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, EFI_BACKGROUND_BLACK));
gST->ConOut->SetCursorPosition(gST->ConOut, Col + PrintUnit, Row);
Print (L"%c", BLOCKELEMENT_FULL_BLOCK);
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, EFI_BACKGROUND_BLACK));
return EFI_SUCCESS;
}
EFI_STATUS
OpRead1K (
UINT8 *ReadBuf,
UINTN BlockCount
)
{
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum = 0;
UINT16 BlockNum = 0;
//[-end-210616-YUNLEI0102-modify]//
UINTN Col = 0;
UINTN Row = 0;
UINTN ProgBarOffset = PROGRESS_BAR_OFFSET;
Col = 9;
Row = 7;
ShowProgressBar (Col + ProgBarOffset, Row, BlockCount);
gST->ConOut->SetCursorPosition(gST->ConOut, Col + ProgBarOffset + PROGRESS_BAR_LEN, Row);
Print (L"]");
for (BlockNum = 0; BlockNum < BlockCount; BlockNum++){
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
Print (L"Reading EC ROM [Bank: %3d] [", BlockNum + 1);
SpiRead1KByte (BlockNum, (ReadBuf + (BlockNum * BLOCK_SIZE_1K)));
// Output message onto the screen.
SetProgressBarItem (Col + ProgBarOffset, Row, BlockCount, BlockNum);
}
Row += 2;
gST->ConOut->SetCursorPosition(gST->ConOut, 0, Row);
return EFI_SUCCESS;
}
VOID
SpiChipEraseEflash (
VOID
)
{
Print (L"\nEraseing... : ");
SpiWriteEnable ();
EnterFollowMode ();
SendSPICommand (SPICMD_CHIP_ERASE);
ExitFollowMode ();
WaitSPIFree ();
Print (L" -- Erase full EC ROM OK. \n");
}
EFI_STATUS
OpWrite64K (
UINT8* FileBuf,
UINTN BlockCount
)
{
UINT8 BlockNum = 0;
EFI_STATUS Status = EFI_SUCCESS;
SPIUnlockAll ();
SpiChipEraseEflash ();
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
Print (L"\nBlock Number : %d \n",BlockNum);
if(!SpiVerifyErase64KByte (BlockNum)){
Print (L" Erase Verify Fail \n");
Status = EFI_DEVICE_ERROR;
break;
}
AAIWordProgram64KByte (BlockNum,FileBuf);
if(!SpiVerify64KByte (BlockNum,FileBuf)){
Print (L" Program Verify Fail \n");
Status = EFI_DEVICE_ERROR;
break;
}
}
if(EFI_ERROR(Status)){
Print(L" \nProgram Fail \n");
gBS->Stall (10 * 1000 * 1000);
SendEcCmd (0xFC); // return to shell
} else {
Print (L" \nProgram OK \n");
gBS->Stall (10 * 1000 * 1000);
SendEcCmd (0xFE); // Watch dog reset EC
}
return Status;
}
// This API only run in OS environment, for example: DOS and WIN OS.
EFI_STATUS
OpWrite1KRunOs (
UINT8* FileBuf,
UINTN BlockCount
)
{
EFI_STATUS Status = EFI_SUCCESS;
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum = 0;
UINT16 BlockNum = 0;
//[-end-210616-YUNLEI0102-modify]//
SPIUnlockAll ();
// Erase EC ROM based on unit 1K byte.
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
// Erase 1K block.
SpiBlockErase1KByte (BlockNum);
}
// Verify the erased EC ROM based on unit 1K byte.
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
// Verify the erased 1K block.
if(!SpiVerifyErase1KByte (BlockNum)){
Status = EFI_DEVICE_ERROR;
return Status;
}
}
// Program the erased EC ROM based on unit 1K byte.
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
// Programming 1K block.
AAIWordProgram1KByte (BlockNum, FileBuf);
}
// Verify the programmed EC ROM based on unit 1K byte.
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
// Verify the programmed 1K block.
if(!SpiVerify1KByte (BlockNum ,FileBuf)){
Status = EFI_DEVICE_ERROR;
return Status;
}
}
return Status;
}
// This API only run in BIOS post life phase.
EFI_STATUS
OpWrite1KRunBios (
UINT8* FileBuf,
UINTN BlockCount
)
{
EFI_STATUS Status = EFI_SUCCESS;
//[-start-210616-YUNLEI0102-modify]//
// UINT8 BlockNum = 0;
UINT16 BlockNum = 0;
//[-end-210616-YUNLEI0102-modify]//
UINTN Col = 0;
UINTN Row = 0;
UINTN RowIndex = 0;
UINTN ProgBarOffset = PROGRESS_BAR_OFFSET;
SPIUnlockAll ();
// Set the initialization coordinates for the programming window
Col = 9;
Row = 9;
// Clear the programming window
gST->ConOut->SetCursorPosition (gST->ConOut, 0, Row);
for (RowIndex = 0; RowIndex < 11; RowIndex++) {
Print(L" ");
}
gST->ConOut->SetCursorPosition (gST->ConOut, Col, Row);
// Erase EC ROM based on unit 1K byte.
ShowProgressBar (Col + ProgBarOffset, Row, BlockCount);
gST->ConOut->SetCursorPosition(gST->ConOut, Col + ProgBarOffset + PROGRESS_BAR_LEN, Row);
Print (L"]");
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
Print (L"Erase EC ROM [Bank: %3d] [", BlockNum + 1);
// Erase 1K block.
SpiBlockErase1KByte (BlockNum);
// Output message onto the screen.
SetProgressBarItem (Col + ProgBarOffset, Row, BlockCount, BlockNum);
}
// Verify the erased EC ROM based on unit 1K byte.
Row += 2;
ShowProgressBar (Col + ProgBarOffset, Row, BlockCount);
gST->ConOut->SetCursorPosition(gST->ConOut, Col + ProgBarOffset + PROGRESS_BAR_LEN, Row);
Print (L"]");
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
Print (L"Verify EC ROM [Bank: %3d] [", BlockNum + 1);
// Verify the erased 1K block.
if(!SpiVerifyErase1KByte (BlockNum)){
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row + 1);
Print (L" Erase Verify Failure!\n");
Status = EFI_DEVICE_ERROR;
return Status;
}
// Output message onto the screen.
SetProgressBarItem (Col + ProgBarOffset, Row, BlockCount, BlockNum);
}
// Program the erased EC ROM based on unit 1K byte.
Row += 2;
ShowProgressBar (Col + ProgBarOffset, Row, BlockCount);
gST->ConOut->SetCursorPosition(gST->ConOut, Col + ProgBarOffset + PROGRESS_BAR_LEN, Row);
Print (L"]");
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
Print (L"Program EC ROM [Bank: %3d] [", BlockNum + 1);
// Programming 1K block.
AAIWordProgram1KByte (BlockNum, FileBuf);
// Output message onto the screen.
SetProgressBarItem (Col + ProgBarOffset, Row, BlockCount, BlockNum);
}
// Verify the programmed EC ROM based on unit 1K byte.
Row += 2;
ShowProgressBar (Col + ProgBarOffset, Row, BlockCount);
gST->ConOut->SetCursorPosition(gST->ConOut, Col + ProgBarOffset + PROGRESS_BAR_LEN, Row);
Print (L"]");
for(BlockNum = 0; BlockNum < BlockCount; BlockNum++) {
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
Print (L"Verify EC ROM [Bank: %3d] [", BlockNum + 1);
// Verify the programmed 1K block.
if(!SpiVerify1KByte (BlockNum ,FileBuf)){
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row + 1);
Print (L" Program Verify Failure! \n");
Status = EFI_DEVICE_ERROR;
return Status;
}
// Output message onto the screen.
SetProgressBarItem (Col + ProgBarOffset, Row, BlockCount, BlockNum);
}
Row ++;
gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
return Status;
}
// 64K Unit
/**
EcUpgradeEcRom
@param this Pointer to EFI_ECFLASH_PROTOCOL
@retval EFI_SUCCESS
**/
EFI_STATUS
EcUpgradeEcRom64K (
IN EFI_ECFLASH_PROTOCOL *this
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8* EcBuf = NULL;
UINTN EcAddr = 0;
UINTN EcSize = 0;
BOOLEAN EcAd = FALSE;
UINT64 IteSign;
UINTN BlockCount;
UINTN BufSize = 0;
UINT8 Index = 0;
// Showing Copyright
ShowVersion ();
EcAddr = FixedPcdGet32 (PcdFlashEcBase);
if (EcAddr == 0) {
Print (L"Invalid EC ROM Address.\n");
goto Exit;
}
EcSize = FixedPcdGet32 (PcdFlashEcSize);
if (EcSize == 0) {
Print (L"Invalid EC ROM Size.\n");
goto Exit;
}
// Print (L"EC ROM Address = %0xH EC ROM Size = %dK bytes\n", EcAddr, EcSize/1024 );
// Get the block number with the file.
BlockCount = EcSize / BLOCK_SIZE_64K;
if ( (EcSize % BLOCK_SIZE_64K) != 0) {
BlockCount++;
}
//Print (L"Total Blocks = %d (UNIT: 64K Byte)\n", BlockCount);
// Allocating file buffer.
BufSize = BlockCount * BLOCK_SIZE_64K;
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiBootServicesData,
EFI_SIZE_TO_PAGES(BufSize),
(EFI_PHYSICAL_ADDRESS *)(&EcBuf)
);
if(EFI_ERROR(Status)){
Print (L"\n Allocate Memory Error %r\n", Status);
goto Exit;
}
// Using 0xFF to fill the EC buffer.
SetMem (EcBuf, BufSize, 0xFF);
// Transfer the EC ROM data onto the EC buffer.
CopyMem (EcBuf, (UINT8 *)(UINTN)(EcAddr), EcSize);
for(Index = 0; (sizeof(LcfcECRomHeader)/sizeof(EC_ROM_HEADER)); Index++) {
IteSign = *(UINT64 *)(UINTN)(EcBuf + LcfcECRomHeader[Index].EcRomIdOffset);
if (IteSign == LcfcECRomHeader[Index].EcRomSignature) {
// Print (L"EC ROM SIGNATURE = %lxH\n", IteSign);
break;
}
}
if(Index == (sizeof(LcfcECRomHeader)/sizeof(EC_ROM_HEADER))) {
Print (L"Invalid EC ROM Signature.\n");
goto Exit;
}
// Disabled Keyboard
SendKbCmd (0xAD);
EcAd = TRUE;
// Checking EC status
SendEcCmd (0xDC);
if(ReadEcData () == 0x33) {
// Print (L"EC ACK is OK.\n");
} else {
Print (L"EC ACK is Fail.\n");
Status = EFI_DEVICE_ERROR;
goto Exit;
}
OpIdentify ();
//Program
Status = OpWrite64K (EcBuf, BlockCount);
if (EFI_ERROR(Status)) {
Print (L"Program EC ROM Error %r\n", Status);
goto Exit;
}
Exit:
if (EcAd) {
SendKbCmd (0xAE);
}
if(EcBuf != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)EcBuf, EFI_SIZE_TO_PAGES(BufSize));
}
return Status;
}
// This API only run in OS environment, for example: DOS and WIN OS.
// 1K Unit
EFI_STATUS
UpgradeEcRomRunOs (
VOID
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8* EcBuf = NULL;
UINTN EcAddr = 0;
UINTN EcSize = 0;
BOOLEAN EcAd = FALSE;
UINT64 IteSign;
UINTN BlockCount;
UINT8 Index = 0;
UINTN ProgRomRetryCount = 3;
EcAddr = FixedPcdGet32 (PcdFlashEcBase);
if (EcAddr == 0) {
Print (L"Invalid EC ROM Address.\n");
goto Exit;
}
EcSize = FixedPcdGet32 (PcdFlashEcSize);
if (EcSize == 0) {
Print (L"Invalid EC ROM Size.\n");
goto Exit;
}
// Get the block number with the file.
BlockCount = EcSize / BLOCK_SIZE_1K;
if ( (EcSize % BLOCK_SIZE_1K) != 0) {
//Print (L"Invalid the EC ROM size, it must be integer times of 1K bytes.\n");
goto Exit;
}
//Print (L"Total Blocks = %d (UNIT: 64K Byte)\n", BlockCount);
EcBuf = (UINT8 *)EcAddr;
for(Index = 0; Index < (sizeof(LcfcECRomHeader)/sizeof(EC_ROM_HEADER)); Index++) {
IteSign = *(UINT64 *)(UINTN)(EcBuf + LcfcECRomHeader[Index].EcRomIdOffset);
if (IteSign == LcfcECRomHeader[Index].EcRomSignature) {
// Print (L"EC ROM SIGNATURE = %lxH\n", IteSign);
break;
}
}
if(Index == (sizeof(LcfcECRomHeader)/sizeof(EC_ROM_HEADER))) {
Print (L"Invalid EC ROM Signature.\n");
goto Exit;
}
// Disabled Keyboard
SendKbCmd (0xAD);
EcAd = TRUE;
// Checking EC status
SendEcCmd (0xDC);
if(ReadEcData () == 0x33) {
//Print (L"EC ACK is OK.\n");
} else {
//Print (L"EC ACK is Fail.\n");
Status = EFI_DEVICE_ERROR;
goto Exit;
}
//OpIdentify ();
// Try to program EC ROM within retry count times. The default retry count time is 3.
ProgRomRetryCount = PROG_ROM_RETRY_COUNT;
do {
//Program
Status = OpWrite1KRunOs (EcBuf, BlockCount);
if (!EFI_ERROR(Status)) {
//Print (L" \nProgram EC ROM OK \n");
//gBS->Stall(10 * 1000 * 1000);
SendEcCmd (0xFE); // Watch dog reset EC
break;
}
//Print (L"Program EC ROM Error %r\n", Status);
ProgRomRetryCount--;
Print (L"\nProgram EC ROM Error Retry Count %d\n", ProgRomRetryCount);
}while (ProgRomRetryCount != 0);
// Stopping the machine when program EC ROM failed.
if (ProgRomRetryCount == 0) {
Print (L"\nProgram EC ROM Error, and please find the LCFC BIOS/EC team to deal with this issue!!\n");
gBS->Stall(30000000);
}
Exit:
if (EcAd) {
SendKbCmd (0xAE);
}
return Status;
}
// This API only run in BIOS post life phase.
// 1K Unit
EFI_STATUS
UpgradeEcRomRunBios (
VOID
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8* EcBuf = NULL;
UINTN EcAddr = 0;
UINTN EcSize = 0;
BOOLEAN EcAd = FALSE;
UINT64 IteSign;
UINTN BlockCount;
UINTN BufSize = 0;
UINT8 Index = 0;
UINTN ProgRomRetryCount = 3;
BOOLEAN ShowErrorMsg = TRUE;
// UINT8 CurrentProjectIDH = 0;
// UINT8 CurrentProjectIDL = 0;
// UINT8 CurrentScope = 0;
// UINT8 BinScope = 0;
// UINT8 DataH, DataL;
// UINT8 SecondData=0xAA;
// UINT16 BinProjectID = 0;
// UINT32 Temp64 = 0;
//[-start-190926-ElvisYang-add]// If EC support this feature,you need to set it.
// LfcEcLibEcRamWrite (0x2a, 0xA5);//Set EC Flash flag to allow ec flash via BIOS update only, FEPL
// LfcEcLibEcRamWrite (0x2b, 0x5A);//Set EC Flash flag to allow ec flash via BIOS update only, FEPH
//[-end-190926-ElvisYang-add]//
//Set FirmwareUpdatingFlag FALSE during flash EC when secure flash supported to avoid FirmwareUpdatingFlag not cleared and trigger the recovery mode.
if (FeaturePcdGet(PcdSecureFlashSupported)) {
SetFirmwareUpdatingFlag (FALSE);
}
// Showing Copyright
ShowVersion ();
EcAddr = FixedPcdGet32 (PcdFlashEcBase);
if (EcAddr == 0) {
Print (L"Invalid EC ROM Address.\n");
goto Exit;
}
EcSize = FixedPcdGet32 (PcdFlashEcSize);
if (EcSize == 0) {
Print (L"Invalid EC ROM Size.\n");
goto Exit;
}
// Print (L"EC ROM Address = %0xH EC ROM Size = %dK bytes\n", EcAddr, EcSize/1024 );
//[-start-211201-BAIN000063-add]//
#ifdef LCFC_SUPPORT
EcSize = EcSize - (80 * BLOCK_SIZE_1K); // BIOS can only erase 176K of EC Block that can keep EC UUID and BSH Flag in EC EEProm.
#endif
//[-end-211201-BAIN000063-add]//
// Get the block number with the file.
BlockCount = EcSize / BLOCK_SIZE_1K;
if ( (EcSize % BLOCK_SIZE_1K) != 0) {
Print (L"Invalid the EC ROM size, it must be integer times of 1K bytes.\n");
goto Exit;
}
//Print (L"Total Blocks = %d (UNIT: 64K Byte)\n", BlockCount);
/*
//EC flash todo
// Guard EC ->
IoWrite8(LFC_CMOS_INDEX, LFC_FLASH_EC_ONCE_H_INDEX);
DataH = IoRead8(LFC_CMOS_DATA);
IoWrite8(LFC_CMOS_INDEX, LFC_FLASH_EC_ONCE_L_INDEX);
DataL = IoRead8(LFC_CMOS_DATA);
if((SecondData != DataH) || (SecondData != DataL) ){
// get bin file's Project_ID and Scope from bin
Temp64 = *(UINT32 *)(UINTN)(EcAddr + 0x5D); // that's the EC bin file offset for Project ID and Scope
BinProjectID = Temp64 & 0xffff;
BinScope = (Temp64 >> 16) & 0xff;
Print (L"EC Project ID = %04X, Scope = %2X\n", BinProjectID, BinScope);
// get current EC's Project_ID and Scope from bin
SendEcCmd (0x44);
CurrentScope = ReadEcData();
CurrentProjectIDH = ReadEcData();
CurrentProjectIDL = ReadEcData();
// compare BinProjectID and scope between bin and current EC
if ((CurrentProjectIDL != (BinProjectID & 0xff)) || (CurrentProjectIDH != ((BinProjectID >> 8) & 0xff))){
Print (L"Current EC Project ID = %02X%02x\n", CurrentProjectIDH, CurrentProjectIDL);
Print (L"Error! Project ID not matched.\n");
goto Exit;
}
if (CurrentScope != BinScope) {
Print (L"Current EC Scope = %02x\n", CurrentScope);
Print (L"Error! Scope not matched.\n");
goto Exit;
}
} else {
Print (L"\nSkip this time EC flash by engineer command.\n");
goto Exit;
}
// Guard EC -<
*/
// Allocating file buffer.
BufSize = BlockCount * BLOCK_SIZE_1K;
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiBootServicesData,
EFI_SIZE_TO_PAGES(BufSize),
(EFI_PHYSICAL_ADDRESS *)(&EcBuf)
);
if(EFI_ERROR(Status)){
Print (L"\n Allocate Memory Error %r\n", Status);
goto Exit;
}
// Using 0xFF to fill the EC buffer.
SetMem (EcBuf, BufSize, 0xFF);
// Transfer the EC ROM data onto the EC buffer.
CopyMem (EcBuf, (UINT8 *)(UINTN)(EcAddr), EcSize);
for(Index = 0; Index < (sizeof(LcfcECRomHeader)/sizeof(EC_ROM_HEADER)); Index++) {
IteSign = *(UINT64 *)(UINTN)(EcBuf + LcfcECRomHeader[Index].EcRomIdOffset);
if (IteSign == LcfcECRomHeader[Index].EcRomSignature) {
// Print (L"EC ROM SIGNATURE = %lxH\n", IteSign);
break;
}
}
if(Index == (sizeof(LcfcECRomHeader)/sizeof(EC_ROM_HEADER))) {
Print (L"Invalid EC ROM Signature.\n");
goto Exit;
}
// Disabled Keyboard
SendKbCmd (0xAD);
EcAd = TRUE;
// Checking EC status
SendEcCmd (0xDC);
if(ReadEcData () == 0x33) {
// Print (L"EC ACK is OK.\n");
} else {
Print (L"EC ACK is Fail.\n");
Status = EFI_DEVICE_ERROR;
goto Exit;
}
OpIdentify ();
// Try to program EC ROM within retry count times. The default retry count time is 3.
ProgRomRetryCount = PROG_ROM_RETRY_COUNT;
do {
//Program
Status = OpWrite1KRunBios (EcBuf, BlockCount);
if (!EFI_ERROR(Status)) {
Print (L" \nProgram EC ROM OK \n");
Print (L"Please wait EC reset system...\n");
gBS->Stall(10 * 1000 * 1000);
SendEcCmd (0xFE); // Watch dog reset EC
break;
}
ProgRomRetryCount--;
Print (L"\nProgram EC ROM Error Retry Count %d\n", ProgRomRetryCount);
}while (ProgRomRetryCount != 0);
// Stopping the machine when program EC ROM failed.
if (ProgRomRetryCount == 0) {
Print (L"\nProgram EC ROM Error, and please find the LCFC BIOS/EC team to deal with this issue!!\n");
gBS->Stall(30000000);
}
else {
ShowErrorMsg = FALSE;
}
Exit:
if (EcAd) {
SendKbCmd (0xAE);
}
if(EcBuf != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)EcBuf, EFI_SIZE_TO_PAGES(BufSize));
}
// wait here for show error message
if (TRUE == ShowErrorMsg) {
gBS->Stall (10 * 1000 * 1000);
}
//gBS->Stall (10 * 1000 * 1000);
return Status;
}
// 1K Unit
/**
EcUpgradeEcRom
@param this Pointer to EFI_ECFLASH_PROTOCOL
@retval EFI_SUCCESS
**/
EFI_STATUS
EcUpgradeEcRom (
IN EFI_ECFLASH_PROTOCOL *this
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 Data = 0;
if (FeaturePcdGet (PcdSecureFlashSupported)) {
// Upgraed the EC ROM after upgraded BIOS ROM.
Status = UpgradeEcRomRunBios ();
} else {
// Upgraded the EC ROM in the next boot.
// Set Ec Ram Offset 0x8C Bit2 to 1 If want to Flash EC Rom.
LfcEcLibEcRamRead(0x8C, &Data);
Data |= BIT2;
LfcEcLibEcRamWrite(0x8C, Data); // BSFU
}
return Status;
}
/**
Upgraded ECROM funcion.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
UpgradedEcRomFunction (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 Data = 0;
Status = gBS->CloseEvent (Event);
// Read Ec Ram Offset 0x8C bit2 Value
// Checking the Ec Ram Offset 0x8C bit2 value before upgrading EC ROM.
LfcEcLibEcRamRead(0x8C, &Data);
if(Data & BIT2) {
Data &= ~BIT2;
LfcEcLibEcRamWrite(0x8C, Data); // BSFU
// Upgraed the EC ROM after upgraded BIOS ROM.
Status = UpgradeEcRomRunBios ();
}
return;
}
/**
Entry Point.
Create one Upgraded EC ROM event.
@param[in] VOID
@retval EFI_SUCEESS
@return Others Some error occurs.
**/
EFI_STATUS
CreateUpgradedEcRomEvent (
VOID
)
{
EFI_STATUS Status;
EFI_EVENT UpgradedEcRomEvent;
Status = EfiCreateEventReadyToBootEx (
TPL_CALLBACK,
UpgradedEcRomFunction,
NULL,
&UpgradedEcRomEvent
);
return Status;
}
/**
Initialize the EC FLash protocol
@param ImageHandle ImageHandle of the loaded driver
@param SystemTable Pointer to the System Table
@retval EFI_SUCCESS thread can be successfully created
@retval EFI_OUT_OF_RESOURCES cannot allocate protocol data structure
@retval EFI_DEVICE_ERROR cannot create the timer service
**/
EFI_STATUS
EFIAPI
InitializeEcFlashEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE Handle;
EFI_ECFLASH_PROTOCOL *EcFlashDxe;
EFI_ECFLASH_PROTOCOL *EcFlashSmm;
EFI_SMM_BASE2_PROTOCOL *SmmBase2;
BOOLEAN InSmm;
SmmBase2 = NULL;
Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, &SmmBase2);
InSmm = FALSE;
if (!EFI_ERROR (Status)) {
SmmBase2->InSmm (SmmBase2, &InSmm);
}
if (!InSmm) {
// Initialize the DXE driver.
//Allocated EcFlashDxe variable.
gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_ECFLASH_PROTOCOL), &EcFlashDxe);
ASSERT (EcFlashDxe != NULL);
SetMem (EcFlashDxe, sizeof (EFI_ECFLASH_PROTOCOL), 0);
//
// Initialize the interfaces
//
EcFlashDxe->UpgradeEcRom = EcUpgradeEcRom;
Status = gBS->InstallMultipleProtocolInterfaces (
&ImageHandle,
&gEfiEcFlashProtocolGuid,
EcFlashDxe,
NULL
);
DEBUG ((EFI_D_ERROR, "Install EcFlash protocol interface. Status = %r.\n", Status));
ASSERT_EFI_ERROR (Status);
if (FeaturePcdGet (PcdSecureFlashSupported) == FALSE) {
// Create one boot event to upgrade the EC ROM in the BDS life phase.
CreateUpgradedEcRomEvent ();
}
}
else {
// Initialize the SMM driver.
//Allocated EcFlashSmm variable.
gSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof (EFI_ECFLASH_PROTOCOL), &EcFlashSmm);
ASSERT (EcFlashSmm != NULL);
SetMem (EcFlashSmm, sizeof (EFI_ECFLASH_PROTOCOL), 0);
//
// Initialize the interfaces
//
EcFlashSmm->UpgradeEcRom = EcUpgradeEcRom;
Handle = NULL;
Status = gSmst->SmmInstallProtocolInterface (
&Handle,
&gEfiEcFlashProtocolGuid,
EFI_NATIVE_INTERFACE,
EcFlashSmm
);
ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
}