alder_lake_bios/Lcfc/LfcPkg/EcFlashSmm/Shell/EcFlashShell.c

1718 lines
36 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 "EcFlashShell.h"
UINT8 OldSstDevID;
UINT8 OldDevID;
UINT8 SPIDeviceID[4];
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: (Using 0x62/0x66 Port)\n");
//Print (L"Usage: (Using 0x68/0x6C Port)\n");
Print (L" EcFlash -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" EcFlash.efi -r -b:128 EC.ROM\n");
Print (L" Written the EC ROM from the file:\n");
Print (L" EcFlash.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", ECFLASH_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 (
UINT8 BlockNum
)
{
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 (
UINT8 BlockNum
)
{
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 (
UINT8 BlockNum,
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 (
UINT8 BlockNum,
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 (
UINT8 BlockNum,
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
)
{
UINT8 BlockNum = 0;
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 BIOS post life phase.
EFI_STATUS
OpWrite1KRunBios (
UINT8* FileBuf,
UINTN BlockCount
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 BlockNum = 0;
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
/**
UEFI application entry point which has an interface similar to a
standard C main function.
The ShellCEntryLib library instance wrappers the actual UEFI application
entry point and calls this ShellAppMain function.
@param ImageHandle The image handle of the UEFI Application.
@param SystemTable A pointer to the EFI System Table.
@retval 0 The application exited normally.
@retval Other An error occurred.
**/
INTN
EFIAPI
ShellAppMain64K (
IN UINTN Argc,
IN CHAR16 **Argv
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 *FileBuf = NULL;
UINTN BufSize = 0;
OPERATION_EC Operation = OP_HELP;
SHELL_FILE_HANDLE FileHandle = NULL;
BOOLEAN EcAd = FALSE;
UINT64 IteSign;
UINT64 FileSize;
UINTN BlockCount;
CHAR16 *ParamPtr = NULL;
EFI_FILE_INFO *FileInfo = NULL;
// Showing Copyright
ShowVersion ();
// Checking input parameters.
if (Argc < 3) {
Status = OpHelp();
goto Exit;
}
if (((StrCmp(Argv[1], L"-r") == 0) || (StrCmp(Argv[1], L"-R") == 0))
&& (Argc == 4)) {
// Reading EC Binary from EC ROM
// Getting the block count for this EC ROM.
ParamPtr = Argv[2];
// Checking the bank count.
if ((ParamPtr[0] == L'-') &&
((ParamPtr[1] ==L'b' ) ||(ParamPtr[1] ==L'B' )) &&
(ParamPtr[2] == L':')
) {
BlockCount = StrDecimalToUintn(ParamPtr + 3);
if (BlockCount == 0) {
Print (L"It's not one valid bank number! [%s]\n", ParamPtr + 3);
goto Exit;
}
} else {
Print (L"It's not one valid bank count parameter! [%s]\n", Argv[2]);
goto Exit;
}
Status = ShellOpenFileByName (
Argv[3],
&FileHandle,
(EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE),
0
);
if (EFI_ERROR (Status)) {
Print (L"Create file is failed!\n");
goto Exit;
}
// Getting file information
FileInfo = ShellGetFileInfo (FileHandle);
if (FileInfo->FileSize != 0) {
ShellDeleteFile (&FileHandle);
Status = ShellOpenFileByName (
Argv[3],
&FileHandle,
(EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE),
0
);
if (EFI_ERROR (Status)) {
Print (L"Create file is failed!\n");
goto Exit;
}
}
// Allocating the file buffer.
BufSize = BlockCount * BLOCK_SIZE_64K;
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiBootServicesData,
EFI_SIZE_TO_PAGES(BufSize),
(EFI_PHYSICAL_ADDRESS *) (&FileBuf)
);
if(EFI_ERROR(Status)){
Print (L"\n Allocate Memory Error %r\n", Status);
goto Exit;
}
Operation = OP_DUMP;
} else if (((StrCmp(Argv[1], L"-w") == 0) || (StrCmp(Argv[1], L"-W") == 0))
&& (Argc == 3)) {
// Written EC Binary to EC ROM
Operation = OP_PROG;
Status = ShellOpenFileByName(
Argv[2],
&FileHandle,
(EFI_FILE_MODE_READ),
0
);
if (EFI_ERROR (Status)) {
Print (L"Open file is failed!\n");
goto Exit;
}
// Getting the file size.
Status = ShellGetFileSize (FileHandle, &FileSize);
if (EFI_ERROR (Status)) {
Print (L"Can't get the file size!\n");
goto Exit;
}
if (FileSize == 0 ) {
Print (L"Invalid the file size!\n");
goto Exit;
}
//Print (L"File Size = %d Bytes\n", FileSize);
// Get the block number with the file.
BlockCount = FileSize / BLOCK_SIZE_64K;
if ( (FileSize % 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 *) (&FileBuf)
);
if(EFI_ERROR(Status)){
Print(L"\n Allocate Memory Error %r\n", Status);
goto Exit;
}
// Using 0xFF to fill the file buffer.
SetMem (FileBuf, BufSize, 0xFF);
Status = ShellReadFile (FileHandle, &BufSize, FileBuf);
if (EFI_ERROR(Status)) {
Print (L"Reading EC File Error %r\n",Status);
goto Exit;
}
IteSign = *(UINT64 *)(UINTN)(FileBuf + ITE_8386_ID_OFFSET);
Print (L"EC ROM SIGNATURE = %lxH\n", IteSign);
if (IteSign != ITE_8386_ID) {
Print (L"It's not one valid EC ROM file!\n");
goto Exit;
}
} else {
// Incorrectly input parameters.
Status = OpHelp();
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;
}
// Getting EC ID
OpIdentify ();
switch (Operation) {
// Dump EC ROM
case OP_DUMP:
Status = OpRead64K (FileBuf, BlockCount);
if (EFI_ERROR (Status)) {
Print (L"Reading EC ROM Error %r\n", Status);
goto Exit;
}
Status = ShellWriteFile (FileHandle, &BufSize, FileBuf);
if (EFI_ERROR(Status)) {
Print (L"Written File Error %r\n", Status);
goto Exit;
}
ShellCloseFile (&FileHandle);
if(FileBuf != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)FileBuf, EFI_SIZE_TO_PAGES(BufSize));
}
Print (L" \nReading EC ROM onto [%s] successfully!\n", Argv[3]);
break;
// Program EC ROM
case OP_PROG:
Status = OpWrite64K (FileBuf, BlockCount);
if (EFI_ERROR(Status)) {
Print (L"Program EC ROM Error %r\n",Status);
goto Exit;
}
break;
// Helpping Message
case OP_HELP:
default:
Status = OpHelp();
break;
}
Exit:
if(EcAd) {
SendKbCmd (0xAE);
gBS->Stall (10 * 1000 * 1000);
SendEcCmd (0xFE); // return to shell
}
if(FileBuf != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)FileBuf, EFI_SIZE_TO_PAGES(BufSize));
}
if(FileHandle != NULL) {
ShellCloseFile (&FileHandle);
}
gST->ConOut->EnableCursor (gST->ConOut, TRUE);
return Status;
}
// 1K Unit
/**
UEFI application entry point which has an interface similar to a
standard C main function.
The ShellCEntryLib library instance wrappers the actual UEFI application
entry point and calls this ShellAppMain function.
@param ImageHandle The image handle of the UEFI Application.
@param SystemTable A pointer to the EFI System Table.
@retval 0 The application exited normally.
@retval Other An error occurred.
**/
INTN
EFIAPI
ShellAppMain (
IN UINTN Argc,
IN CHAR16 **Argv
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 *FileBuf = NULL;
UINTN BufSize = 0;
OPERATION_EC Operation = OP_HELP;
SHELL_FILE_HANDLE FileHandle = NULL;
BOOLEAN EcAd = FALSE;
UINT64 IteSign;
UINT64 FileSize;
UINTN BlockCount;
CHAR16 *ParamPtr = NULL;
EFI_FILE_INFO *FileInfo = NULL;
UINTN ProgRomRetryCount = 3;
// Showing Copyright
ShowVersion ();
// Checking input parameters.
if (Argc < 3) {
Status = OpHelp();
goto Exit;
}
if (((StrCmp(Argv[1], L"-r") == 0) || (StrCmp(Argv[1], L"-R") == 0))
&& (Argc == 4)) {
// Reading EC Binary from EC ROM
// Getting the block count for this EC ROM.
ParamPtr = Argv[2];
// Checking the bank count.
if ((ParamPtr[0] == L'-') &&
((ParamPtr[1] ==L'b' ) ||(ParamPtr[1] ==L'B' )) &&
(ParamPtr[2] == L':')
) {
BlockCount = StrDecimalToUintn(ParamPtr + 3);
if (BlockCount == 0) {
Print (L"It's not one valid EC ROM size! [%s]\n", ParamPtr + 3);
goto Exit;
}
} else {
Print (L"It's not one valid EC ROM size parameter! [%s]\n", Argv[2]);
goto Exit;
}
Status = ShellOpenFileByName (
Argv[3],
&FileHandle,
(EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE),
0
);
if (EFI_ERROR (Status)) {
Print (L"Create file is failed!\n");
goto Exit;
}
// Getting file information
FileInfo = ShellGetFileInfo (FileHandle);
if (FileInfo->FileSize != 0) {
ShellDeleteFile (&FileHandle);
Status = ShellOpenFileByName (
Argv[3],
&FileHandle,
(EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE),
0
);
if (EFI_ERROR (Status)) {
Print (L"Create file is failed!\n");
goto Exit;
}
}
// Allocating the file buffer.
BufSize = BlockCount * BLOCK_SIZE_1K;
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiBootServicesData,
EFI_SIZE_TO_PAGES(BufSize),
(EFI_PHYSICAL_ADDRESS *) (&FileBuf)
);
if(EFI_ERROR(Status)){
Print (L"\n Allocate Memory Error %r\n", Status);
goto Exit;
}
Operation = OP_DUMP;
} else if (((StrCmp(Argv[1], L"-w") == 0) || (StrCmp(Argv[1], L"-W") == 0))
&& (Argc == 3)) {
// Written EC Binary to EC ROM
Operation = OP_PROG;
Status = ShellOpenFileByName(
Argv[2],
&FileHandle,
(EFI_FILE_MODE_READ),
0
);
if (EFI_ERROR (Status)) {
Print (L"Open file is failed!\n");
goto Exit;
}
// Getting the file size.
Status = ShellGetFileSize (FileHandle, &FileSize);
if (EFI_ERROR (Status)) {
Print (L"Can't get the file size!\n");
goto Exit;
}
if (FileSize == 0 ) {
Print (L"Invalid the file size, it must be integer times of 1K bytes.\n");
goto Exit;
}
//Print (L"File Size = %d Bytes\n", FileSize);
// Get the block number with the file.
BlockCount = FileSize / BLOCK_SIZE_1K;
if ( (FileSize % BLOCK_SIZE_1K) != 0) {
Print (L"Invalid the file size, it must be integer times of 1K bytes.\n");
goto Exit;
}
//Print (L"Total Blocks = %d (UNIT: 1K Byte)\n", BlockCount);
// Allocating file buffer.
BufSize = BlockCount * BLOCK_SIZE_1K;
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiBootServicesData,
EFI_SIZE_TO_PAGES(BufSize),
(EFI_PHYSICAL_ADDRESS *) (&FileBuf)
);
if(EFI_ERROR(Status)){
Print(L"\n Allocate Memory Error %r\n", Status);
goto Exit;
}
// Using 0xFF to fill the file buffer.
SetMem (FileBuf, BufSize, 0xFF);
Status = ShellReadFile (FileHandle, &BufSize, FileBuf);
if (EFI_ERROR(Status)) {
Print (L"Reading EC File Error %r\n",Status);
goto Exit;
}
IteSign = *(UINT64 *)(UINTN)(FileBuf + ITE_8386_ID_OFFSET);
if (IteSign != ITE_8386_ID) {
IteSign = *(UINT64 *)(UINTN)(FileBuf + ITE_8586_ID_OFFSET);
if (IteSign != ITE_8586_ID) {
Print (L"EC ROM SIGNATURE = %lxH\n", IteSign);
Print (L"It's not one valid EC ROM file!\n");
goto Exit;
}
else {
Print (L"EC ROM SIGNATURE = %lxH\n", IteSign);
}
}
else {
Print (L"EC ROM SIGNATURE = %lxH\n", IteSign);
}
} else {
// Incorrectly input parameters.
Status = OpHelp();
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;
}
// Getting EC ID
OpIdentify ();
switch (Operation) {
// Dump EC ROM
case OP_DUMP:
Status = OpRead1K (FileBuf, BlockCount);
if (EFI_ERROR (Status)) {
Print (L"Reading EC ROM Error %r\n", Status);
goto Exit;
}
Status = ShellWriteFile (FileHandle, &BufSize, FileBuf);
if (EFI_ERROR(Status)) {
Print (L"Written File Error %r\n", Status);
goto Exit;
}
ShellCloseFile (&FileHandle);
if(FileBuf != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)FileBuf, EFI_SIZE_TO_PAGES(BufSize));
}
Print (L"Reading EC ROM onto [%s] successfully!\n", Argv[3]);
break;
// Program EC ROM
case OP_PROG:
// 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 (FileBuf, 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" \nProgram EC ROM Failure \n ");
ProgRomRetryCount--;
}while (ProgRomRetryCount != 0);
// Stopping the machine when program EC ROM failed.
if (ProgRomRetryCount == 0) {
while (1);
}
break;
// Helpping Message
case OP_HELP:
default:
Status = OpHelp();
break;
}
Exit:
if(EcAd) {
SendKbCmd (0xAE);
gBS->Stall (10 * 1000 * 1000);
SendEcCmd (0xFE); // return to shell
}
if(FileBuf != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)FileBuf, EFI_SIZE_TO_PAGES(BufSize));
}
if(FileHandle != NULL) {
ShellCloseFile (&FileHandle);
}
gST->ConOut->EnableCursor (gST->ConOut, TRUE);
return Status;
}