1718 lines
36 KiB
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;
|
|
} |