ami uefi bios 借鸡下蛋 之 在线更新bios 之内容

#include  <Uefi.h>
#include  <Library/UefiLib.h>
//#include  <Library/ShellCEntryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include  <Protocol/UsbIo.h>

#include  <Protocol/AmiUsbController.h>


#include <AmiLib.h>
#include <AmiDxeLib.h>
#include <AmiDxeLib.h>

#include <Protocol/Smbios.h>
#include "EfiKey.h"


#include <Uefi.h>  
#include <Library/UefiLib.h>
#include <IndustryStandard/SmBios.h>
//#include <Library/UefiShellDebug1CommandsLib.h>
//#include <Library/LibSmbiosView.h> 


#include "HomeWorkDxe.h"

extern EFI_BOOT_SERVICES         *gBS;

extern EFI_BOOT_SERVICES     *pBS;

extern EFI_HANDLE                     gImageHandle;


#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include  <Protocol/UsbIo.h>

#include  <Protocol/AmiUsbController.h>


#include <AmiDxeLib.h>

#include <Protocol/Smbios.h>
#include "EfiKey.h"


#include  <Uefi.h>
#include  <Library/UefiLib.h>
//#include  <Library/ShellCEntryLib.h>
#include  <Protocol/Spi.h>
#include  <Library/UefiBootServicesTableLib.h>


EFI_GUID  gEfiUsbIoProtocolGuid   = 
    { 0x2B2F68D6, 0x0CD2, 0x44CF, 
        { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 }};

EFI_GUID  gEfiSimpleTextInputExProtocolGuid = 
    {0xdd9e7534, 0x7762, 0x4698, 
        { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa }};


EFI_GUID  ggEfiHomeWorkProtocolGuid = 
    {0x47590bea, 0x6178, 0x498d, 
        { 0xa9, 0x5, 0x3c, 0xe6, 0x63, 0xc3, 0x84, 0xd9 }};

#if 1

//*************************************************************************
//<AMI_PHDR_START>
//
// Name: Sprintf
//
// Description:
//  UINTN Sprintf(OUT CHAR8 *Buffer, IN CHAR8 *Format, IN ...) produces a
// null-terminated ASCII string in the output Buffer.  The ASCII string is
// produced by parsing the format string specified by Format.  Arguments are 
// pulled from the variable argument list based on the contents of the format
// string.  The number of ASCII characters in the produced output buffer is
// returned, not including the null-terminator. See notes for format string 
// information.
//
// Input:
//  OUT CHAR8 *Buffer
// Pointer to a null-terminated output ASCII string buffer.  User is
// responsible for allocating the necessary memory resources!
//
//  IN CHAR8 *Format
// Pointer to a null-terminated format ASCII string.
//
//  IN ...
// Variable argument list which provides the data/variables used within the
// format string.
//
// Output:
//  UINTN number of ASCII characters in the produced output buffer, not
// including the null-terminator.
//
// Modified:
//
// Referrals:
//  va_start
//  Sprintf_va_list
//  va_end
// 
// Notes:
//  Objects inside the format string have the following syntax.
//   %[flags][width]type
//
//  *** [flags] ***
//  
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
// . Flag  .  Description
// .       . 
// . -     .  The field is left justified.  If flag is not specified, then 
// .       . the field is right justified.
// .       . 
// . space .  Prefix a space character to a number.  Only valid for types X, 
// .       . x, and d.
// .       .  
// . +     .  Prefix a plus character to a number.  Only valid for types X,
// .       . x, and d.  If both space and `+' are specified, then space is
// .       . ignored.
// .       .
// . 0     .  Pad with `0' characters to the left of a number.  Only valid
// .       . for types X, x, and d.
// .       .
// . L, l  .  The number being printed is a UINT64.  Only valid for types X,
// .       . x, and d.  If this flag is not specified, then the number being
// .       . printed is an int.
// .       .
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
//  
//  NOTE
//   All invalid [flags] are ignored.
//
// *** [width] ***
//
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
// . Width  .  Description
// .        .
// . *      .  The width of the field is specified by a UINTN argument in the
// .        . argument list.
// .        .
// . Number .  The number specified as a decimal value represents the width of
// .        . the field.
// .        .
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
//
// NOTE
//  If [width] is not specified, then a field width of 0 is assumed.
//
// *** type ***
// 
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
// . Type  .  Description
// .       .
// . %     .  Print a `%'.
// .       .
// . c     .  The argument is an ASCII character. 
// .       .
// . x     .  The argument is a hexadecimal number.  The characters used are 
// .       . 0..9 and a..f.  If the flag `l' is not specified, then the
// .       . argument is assumed to be an int.
// .       .
// . X     .  The argument is a hexadecimal number.  The characters used are 
// .       . 0..9 and A..F.  If the flag `l' is not specified, then the
// .       . argument is assumed to be an int.
// .       .
// . d     .  The argument is a decimal number.  If the flag `l' is not
// .       . specified, then the argument is assumed to be an int.
// .       .
// . i     .  The same as `d'.
// .       .
// . s     .  The argument is a pointer to null-terminated ASCII string.
// .       .
// . a     .  The same as `s'.
// .       .
// . S     .  The argument is a pointer to a null-terminated Unicode string.
// .       .
// . g     .  The argument is a pointer to a GUID structure.  The GUID is
// .       . printed in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
// .       .
// . G     .  The argument is a pointer to a GUID structure.  The GUID is
// .       . printed in the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
// .       .
// . r     .  The argument is an EFI_STATUS value.  This value is converted
// .       . to a string.
// .       .
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
//
// NOTE
//  All invalid type characters are copied into the result string.
//
//<AMI_PHDR_END>
//*************************************************************************


int macdbg_dmphex_kernel(const char* buff_in, int len)
{
    int retval = 0; 
    int x, y, tot, lineoff;
    const char* curr;
    CHAR16  buff[1024];
    UINTN index;
                                           

    DEBUG( (EFI_D_INFO, "dump addr -> 0x%x: \n", buff_in) );
    //DEBUG((EFI_D_INFO, "len = 0x%x.\n", len ));

    
    
    lineoff = 0;
    curr = buff_in;
    tot = 0;

    for( x = 0; x+16 < len; ){         
         index = 0x00;
         memset( buff, 0x00, sizeof(buff) );       
         Swprintf( &buff[index], L"0x%04x:  ", lineoff );
         index = Wcslen(buff);

         //DEBUG((EFI_D_INFO, "index = %d\n", index ));
         //DEBUG((EFI_D_INFO, "debug.0 = %s\n", buff  ));
         //DEBUG((EFI_D_INFO, "debug.1 = %S\n", buff  ));

         

         
         for( y = 0; y < 16; y++ ){
             Swprintf( &buff[index], L"%02x ", (unsigned char)*(curr + y) );             
              index = Wcslen(buff);
         }

         //DEBUG((EFI_D_INFO, "debug.2 = %s\n", buff  ));

         
         Swprintf( &buff[index], L"%s", L"    " );
         index = Wcslen(buff);
         for( y = 0; y < 16; y++ ){
              char c;
              c = *(curr + y);
              if( c > 31 && c < 127 ){
                  Swprintf( &buff[index], L"%c", c );
              }else{
                  Swprintf( &buff[index], L"%c", L'.' );
              }
              index = Wcslen(buff);
              tot++;
         }
         curr += 16;
         x += 16;
         lineoff+=16;
         Swprintf( &buff[index], L"%s", L"\n" );
         //printk("%s", buff);

         
         //DEBUG((EFI_D_INFO, "debug.2 = %s\n", buff    ));
         DEBUG((EFI_D_INFO, "%s", buff));
         
         //DEBUG((EFI_D_INFO, "debug.3 = %S\n", buff    ));
    }
     
    //do last line
    //Ser_Printf("tot %d.\r\n", tot );
    //Ser_Printf("len %d.\r\n", len );
    index = 0x00;
    memset( buff, 0x00, sizeof(buff) );
    if( tot < len ){
        curr = (buff_in + tot);
        Swprintf( &buff[index], L"0x%04x:  ", lineoff );
        index = Wcslen(buff);
        for( y = 0; y < (len - tot); y++ ){
             Swprintf( &buff[index], L"%02x ", (unsigned char)*(curr + y) );
             index = Wcslen(buff);
        }
        //padding with spaces
        //printk("(len - tot) %d.\r\n", (len - tot) );
        if( (len - tot) < 16 ){
            for( y = 0; y<(16-(len-tot)); y++ ){
                 Swprintf( &buff[index], L"%s", L"   " );  
                 index = index + 3;   
            }
        }
        
        Swprintf( &buff[index], L"%s", L"    " );  
        index = Wcslen(buff);           
        //Ser_Printf("(len - tot) %d.\r\n", (len - tot) );
        for( y = 0; y < (len - tot); y++ ){
             char c;
             c = *(curr + y);
             if( c > 31 && c < 127 ){
                 Swprintf( &buff[index], L"%c", c );
             }else{
                 Swprintf( &buff[index], L"%c", L'.' );
             }
             index = Wcslen(buff);
        }
    }
    Swprintf( &buff[index], L"%s", L"\n" );
    //printk("%s", buff);       
    DEBUG((EFI_D_INFO, "%s\n", buff));
    return retval;
}

#endif


        

/**
  Return SMBIOS string for the given string number.

  @param[in] Smbios         Pointer to SMBIOS structure.
  @param[in] StringNumber   String number to return. -1 is used to skip all strings and
                            point to the next SMBIOS structure.

  @return Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == -1
**/
CHAR8*
LibGetSmbiosString (
  IN  SMBIOS_STRUCTURE_POINTER    *Smbios,
  IN  UINT16                      StringNumber
  )
{
  UINT16  Index;
  CHAR8   *String;

  ASSERT (Smbios != NULL);

  //
  // Skip over formatted section
  //
  String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length);

  //
  // Look through unformated section
  //
  for (Index = 1; Index <= StringNumber; Index++) {
    if (StringNumber == Index) {
      return String;
    }
    //
    // Skip string
    //
    for (; *String != 0; String++);
    String++;

    if (*String == 0) {
      //
      // If double NULL then we are done.
      //  Return pointer to next structure in Smbios.
      //  if you pass in a -1 you will always get here
      //
      Smbios->Raw = (UINT8 *)++String;
      return NULL;
    }
  }

  return NULL;
}

//**********************************************************************
//<AMI_PHDR_START>
//
// Procedure:   EfiLibGetSystemConfigurationTable
//
// Description: Get table from configuration table by name
//
// Input:       IN EFI_GUID *TableGuid,
//              IN OUT VOID **Table
//
// Output:      EFI_STATUS
//
// Modified:
//
// Referrals:
//
// Notes:
//<AMI_PHDR_END>
//**********************************************************************
EFI_STATUS EfiLibGetSystemConfigurationTable(
    IN EFI_GUID *TableGuid,
    IN OUT VOID **Table )
{
    UINTN Index;

    *Table = NULL;

    for ( Index = 0; Index < gST->NumberOfTableEntries; Index++ )
    {
        if ( !CompareMem( TableGuid, &(gST->ConfigurationTable[Index].VendorGuid),
                          sizeof(EFI_GUID)))
        {
            *Table = gST->ConfigurationTable[Index].VendorTable;
            return EFI_SUCCESS;
        }
    }

    return EFI_NOT_FOUND;
}


void test_fuck(void)
{
    CHAR16  debug_buff[128];
    UINTN index;
    int len;
    
    memset( debug_buff, 0x00, sizeof(debug_buff) );

    index = 0x00;
    Swprintf( &debug_buff[index], L"0x%04x:  ", 0x1234 );
    index = Wcslen(debug_buff);
      
    len = sizeof(debug_buff);
    macdbg_dmphex_kernel((const char *)debug_buff, len );

    DEBUG( (EFI_D_INFO, "index = %d\n", index) );  
    DEBUG( (EFI_D_INFO, "in test_fuck 4 = %s\n", debug_buff) );
    
    

}


EFI_STATUS test_smbios_table()
{
    EFI_STATUS                      Status;
    SMBIOS_TABLE_ENTRY_POINT      *mSmbiosTable   = NULL;
    SMBIOS_STRUCTURE_POINTER      m_SmbiosStruct;
    SMBIOS_STRUCTURE_POINTER      *mSmbiosStruct = &m_SmbiosStruct;
               
    SMBIOS_STRUCTURE_POINTER  Smbios;
    SMBIOS_STRUCTURE_POINTER  SmbiosEnd;
    UINT8                      *Raw;
              
    UINT16                      Handle1 = 0;
    UINT8                      *Buffer1;
    UINT16                      Length1;
         
    UINT16                      *Handle;
    UINT8                      **Buffer;
    UINT16                      *Length;
    UINT8                      Type;
                                                                    
    mSmbiosTable = NULL;
      
    //Get SMBIOS table from System Configure table
    Status = EfiLibGetSystemConfigurationTable(&gEfiSmbiosTableGuid,(VOID**)&mSmbiosTable);
    if( mSmbiosTable == NULL ){       
        Print(L"%r.\n",Status);
    }
                
    //Init SMBIOS structure table address
    mSmbiosStruct->Raw    = (UINT8 *)(UINTN)(mSmbiosTable->TableAddress);  
    //Find the structure
    Handle = &Handle1;
    Length = &Length1;
    Buffer = &Buffer1;
   
    *Length       = 0;
    Smbios.Hdr      = mSmbiosStruct->Hdr;
    SmbiosEnd.Raw = Smbios.Raw + mSmbiosTable->TableLength;
    Print(L"TableLenth:%02d\n",mSmbiosTable->TableLength);
          
    while( Smbios.Raw < SmbiosEnd.Raw ){
      if( Smbios.Hdr->Handle == *Handle ){
          Raw = Smbios.Raw;
          Type = Smbios.Hdr->Type;
          //Walk to next structure
          LibGetSmbiosString(&Smbios,(UINT16)(-1));
          //Length = Next structure head - this structure head
          *Length = (UINT16)(Smbios.Raw - Raw);
          *Buffer = Raw;          
          //update with the next structure handle.
          if( Smbios.Raw < SmbiosEnd.Raw ){
              *Handle = Smbios.Hdr->Handle;
          } else{
              *Handle = (UINT16)(-1);
          }
          DEBUG( (EFI_D_INFO, "Handle:0x%04x Type:0x%02x Address:%08x Length:%04x.\n", *Handle - 1, Type, *Buffer, *Length) );
          macdbg_dmphex_kernel(*Buffer, *Length );
      }
    }
    *Handle = (UINT16)(-1);
    return EFI_SUCCESS;
}

           


#include <Token.h>
#include <AmiDxeLib.h>
#include<Protocol/SmmBase2.h>
#include <Protocol/SmmSxDispatch2.h>
#include <Setup.h>
#if RTCWAKEUP_POWERBUTTON_SUPPORT
#include <Protocol/SmmPowerButtonDispatch.h>
#endif

#define CMOS_INDEX  0x70
#define CMOS_DATA   0x71
#define RTC_SECONDS_ALARM   1
#define RTC_MIN_ALARM       3
#define RTC_HOUR_ALARM      5
#define RTC_STATUS_REG_A    0xA
#define RTC_STATUS_REG_B    0xB
#define RTC_STATUS_REG_C    0xC


EFI_GUID    gSetupGuid = SETUP_GUID;
SETUP_DATA  gSetupData ;

UINT8   RtcWakeType=0;
UINT8   RTCWakeupTimeHour;
UINT8   RTCWakeupTimeMinute;
UINT8   RTCWakeupTimeSecond;
UINT8   DynamicMinIncrease;


//<AMI_PHDR_START>
//----------------------------------------------------------------------------
// Procedure:   DecToBCD
//
// Description: Converts a Decimal value to a BCD value.
//
// Input:       
//      IN UINT8 Dec - Decimal value
//
// Output:      
//      UINT8 - BCD value
//
// Notes:       
//      Only for 2 digit decimal.
//
//----------------------------------------------------------------------------
//<AMI_PHDR_END>
UINT8 DecToBCD (
  IN UINT8 Dec )
{
    UINT8 FirstDigit = Dec % 10;
    UINT8 SecondDigit = Dec / 10;

    return (SecondDigit << 4) + FirstDigit;
}

//<AMI_PHDR_START>
//----------------------------------------------------------------------------
// Procedure:   BCDToDec
//
// Description: Converts a BCD value to a Decimal value.
//
// Input:       
//      IN UINT8 BCD -- BCD value
//
// Output:      
//      UINT8 - decimal value
//
// Notes:       
//      Only for 2 digit BCD.
//
//----------------------------------------------------------------------------
//<AMI_PHDR_END>
UINT8 BCDToDec (
  IN UINT8 BCD )
{
    UINT8 FirstDigit = BCD & 0xf;
    UINT8 SecondDigit = BCD >> 4;;

    return SecondDigit * 10  + FirstDigit;
}

//<AMI_PHDR_START>
//----------------------------------------------------------------------------
// Procedure:   ReadRtcIndex
//
// Description: Read the RTC value at the given Index.
//
// Input:       Index       RTC Index
//
// Output:      RTC Value read from the provided Index
//
// Notes:       Here is the control flow of this function:
//              1. Read port 0x70 (RTC Index Register) to get bit 7.
//                  Bit 7 is the NMI bit-it should not be changed.
//              2. Output 0x70 with the Index and NMI bit setting.
//              3. Read 0x71 for Data. Getting Dec when appropriate.
//              4. Return the Data.
//----------------------------------------------------------------------------
//<AMI_PHDR_END>

UINT8 ReadRtcIndex (
  IN UINT8 Index )
{
    UINT8 volatile Value=0;

    #if 0
    do {
        IoWrite8(CMOS_INDEX, RTC_STATUS_REG_A | 0x80);
        Value = IoRead8(CMOS_DATA);     
    } while (Value & 0x80); 
    #endif
    
    IoWrite8(CMOS_INDEX, Index);

    // Read register
    Value = IoRead8(CMOS_DATA);
    if (Index <= 9) { 
        //Value = BCDToDec(Value);    
    }

    return (UINT8)Value;
}

//<AMI_PHDR_START>
//----------------------------------------------------------------------------
// Procedure:   WriteRtcIndex
//
// Description: Write the RTC value at the given Index.
//
// Input:       Index   RTC Index
//              Data    RTC Index
//
// Output:      None
//
// Notes:       Here is the control flow of this function:
//              1. Read port 0x70 (RTC Index Register) to get bit 7.
//                 Bit 7 is the NMI bit-it should not be changed.
//              2. Output 0x70 with the Index. Switch to BCD when needed.
//              3. Write the data to 0x71.
//----------------------------------------------------------------------------
//<AMI_PHDR_END>

void WriteRtcIndex (
  IN UINT8 Index, 
  IN UINT8 Value )
{
    IoWrite8(CMOS_INDEX,Index | 0x80);
    if (Index <= 9 ) { 
        Value = DecToBCD(Value);
    }

    // Write Register
    IoWrite8(CMOS_DATA,Value);

    return;
}

//UpdateVariable

#if 1
char* g_buff = 0x00;


VOID HomeWorkDxeProtocolCallback( void )
{
    EFI_STATUS                             Status;
  
    EFI_HOMEWORKINTERFACE_PROTOCOL         *HomeworkProtocolinterface;
        
    //step.2
    //DEBUG( (EFI_D_INFO, "in HomeWorkDxeProtocolCallback\n")); 


    //DEBUG( (EFI_D_INFO, "gEfiHomeWorkProtocolGuid     : %g\n", ggEfiHomeWorkProtocolGuid ) );
    //CoreLocateProtocol
    Status = gBS->LocateProtocol(&ggEfiHomeWorkProtocolGuid,
                                 NULL,
                                 &HomeworkProtocolinterface );

    //DEBUG((EFI_D_INFO,"HomeWorkPciread Status: %d\n",Status));
    
    if (!EFI_ERROR(Status)) {
        //step.3
        Status = HomeworkProtocolinterface->macdbg_dmphex_kernel(g_buff, 0x100);
        g_buff = g_buff + 0x100;
       
    }
}
#endif

/*
 * BootOrder.c
 *
 *  Created on: 2018年3月14日
 *      Author:
 */
 
 
 
 
#include <Uefi.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiLib.h>
//#include "UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h"


#include <Protocol/DevicePathToText.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Uefi.h>
 
extern EFI_BOOT_SERVICES  *gBS;

EFI_GUID ggEfiDevicePathToTextProtocolGuid = 
    { 0x8b843e20, 0x8132, 0x4852, 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c };

//EFI_GUID  ggEfiHomeWorkProtocolGuid = 
    //{0x47590bea, 0x6178, 0x498d, 
        //{ 0xa9, 0x5, 0x3c, 0xe6, 0x63, 0xc3, 0x84, 0xd9 }};


 
VOID MmBootDev (void)
{         
    UINT16                             *VariablePtr;
    UINTN                              VariableSize = 0;
    EFI_STATUS                         Status;
    UINTN                              Count;
    EFI_LOAD_OPTION                    *EfiLoadOption;
    UINTN                              OptionSize = 0;
    CHAR16                             a[100];
    UINTN                              Index;
    UINT8                              NameLen;                          
    EFI_DEVICE_PATH_PROTOCOL           *pDevicePathProcotol;                 
    EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *pDevicePath2TextProtocol;            
    CHAR16                             *pStrDevicePath;                    
                                                                         
    EfiLoadOption  = NULL;  
    VariablePtr    = NULL;
    pStrDevicePath = NULL;
    //get bootcurrent
    Status  = gRT->GetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, NULL, &VariableSize, VariablePtr);
    if( Status == EFI_BUFFER_TOO_SMALL ){
        Status = gBS->AllocatePool (EfiBootServicesData, VariableSize, &VariablePtr);
    }
    gBS->SetMem(VariablePtr ,VariableSize, 0);
    Status  = gRT->GetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, NULL, &VariableSize, VariablePtr);
    macdbg_dmphex_kernel( (const char *)VariablePtr, (int)VariableSize ); 
    UnicodeSPrint (a, sizeof (L"Boot1234"), L"Boot%04x", *VariablePtr);
    Print (L"1 = %s.\r\n",a);
       
    //get bootcurrent option.
    Status  = gRT->GetVariable (a, &gEfiGlobalVariableGuid, NULL, &OptionSize, EfiLoadOption);
    if( Status == EFI_BUFFER_TOO_SMALL ){
        Status = gBS->AllocatePool (EfiBootServicesData, OptionSize, &EfiLoadOption);
    }
    gBS->SetMem(EfiLoadOption ,OptionSize, 0);
    Status  = gRT->GetVariable (a, &gEfiGlobalVariableGuid, NULL, &OptionSize, EfiLoadOption);
    macdbg_dmphex_kernel( (const char *)EfiLoadOption, (int)OptionSize ); 
    Print (L"  DeviceName:%s\r\n",((UINT8*)EfiLoadOption+6));
      
    //get device path
    NameLen = (UINT8)StrLen((UINT16*)EfiLoadOption + 3);
    DEBUG((EFI_D_INFO,"ShellAppMain NameLen: %x\n",NameLen));
        
  Status = gBS->LocateProtocol(&ggEfiDevicePathToTextProtocolGuid, NULL, (VOID**)&pDevicePath2TextProtocol);
  
  pDevicePathProcotol = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)EfiLoadOption+ 6 + 2*(NameLen+1));
 
  pStrDevicePath = pDevicePath2TextProtocol->ConvertDevicePathToText (pDevicePathProcotol, TRUE, TRUE);
  Print (L"  DevicePath:%s\r\n",pStrDevicePath);


  Print (L"  DevicePath:%x\r\n",pStrDevicePath);
  

  
  //get boot order.
  Status  = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &VariableSize, VariablePtr);
  Count = VariableSize / sizeof(UINT16);
  Index = Count - 1;
  if (Status == EFI_BUFFER_TOO_SMALL)
     Status = gBS->AllocatePool (EfiBootServicesData, VariableSize, &VariablePtr);
  gBS->SetMem(VariablePtr ,VariableSize, 0);
  Status  = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &VariableSize, VariablePtr);
  while (Count--)
  {
    UnicodeSPrint (a, sizeof (L"Boot1234"), L"Boot%04x", VariablePtr[ Index - Count]);
    Print (L"%s\r\n",a);
    
    // get boot option.
    Status  = gRT->GetVariable (a, &gEfiGlobalVariableGuid, NULL, &OptionSize, EfiLoadOption);
    if (Status == EFI_BUFFER_TOO_SMALL)
       Status = gBS->AllocatePool (EfiBootServicesData, OptionSize, &EfiLoadOption);
    gBS->SetMem(EfiLoadOption ,OptionSize, 0);
    Status  = gRT->GetVariable (a, &gEfiGlobalVariableGuid, NULL, &OptionSize, EfiLoadOption);
    Print (L"  DeviceName:%s\r\n",((UINT8*)EfiLoadOption+6));
    //get device path
    NameLen = (UINT8)StrLen((UINT16*)EfiLoadOption + 3);
    Status = gBS->LocateProtocol(&ggEfiDevicePathToTextProtocolGuid, NULL, (VOID**)&pDevicePath2TextProtocol);
    
    pDevicePathProcotol = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)EfiLoadOption+ 6 + 2*(NameLen+1));
 
    pStrDevicePath = pDevicePath2TextProtocol->ConvertDevicePathToText (pDevicePathProcotol, TRUE, TRUE);
    Print (L"  DevicePath:%s\r\n",pStrDevicePath);
    Print (L"  DevicePath:%x\r\n",pStrDevicePath);
 
 
  }
  gBS->FreePool(pStrDevicePath);
  gBS->FreePool(EfiLoadOption); 
  gBS->FreePool(VariablePtr);
  
 
}


#if 1
INTN EFIAPI ShellAppMain( void )
{                      
    EFI_STATUS                      Status;
    IN OUT UINTN                    DataSize;
    OUT VOID                        *pData;
    UINT32                          Attributes;
    CHAR16                          *InputStr;
    UINT64                          Data;
     
    DataSize    = 0;
    pData       = NULL;
    InputStr    = NULL;
    Data        = 0;
          
    Status = gRT->GetVariable(L"BootOrder", &gEfiGlobalVariableGuid, &Attributes, &DataSize,pData);  
    if( Status == EFI_BUFFER_TOO_SMALL ){
        Status = gBS->AllocatePool(EfiBootServicesData, DataSize, &pData);
        Status = gRT->GetVariable(L"BootOrder", &gEfiGlobalVariableGuid, &Attributes, &DataSize,pData);
    }
    DEBUG((EFI_D_INFO,"ShellAppMain Status1: %r\n",Status));

    DEBUG((EFI_D_INFO," DataSize: %d\n",DataSize));

    
    macdbg_dmphex_kernel( (const char *)pData, 12 ); 
    MmBootDev();
                                               
    Status = gRT->SetVariable(L"BootOrder", &gEfiGlobalVariableGuid, Attributes, DataSize, pData);
    DEBUG((EFI_D_INFO,"ShellAppMain Status2: %r\n",Status));
    return EFI_SUCCESS;
}
#endif

#if 0
INTN EFIAPI ShellAppMain( void )
{                      
    //unsigned char Buffer[0x1000];      
    //EFI_STATUS          Status;
    //PCH_SPI_PROTOCOL    *mSpiProtocol;
           
   // Print(L"Welcome to the world of EDK II.\n");
    //DEBUG( (EFI_D_INFO, "gEfiHomeWorkProtocolGuid     : %g\n", ggEfiHomeWorkProtocolGuid ) );
    //DEBUG( (EFI_D_INFO, "gPchSpiProtocolGuid     : %g\n", gPchSpiProtocolGuid ) );


    HomeWorkDxeProtocolCallback();


    
    #if 0
    Status = gBS->LocateProtocol(
                    &gPchSpiProtocolGuid,
                    NULL,
                    (VOID **)&mSpiProtocol
                    );


    DEBUG((EFI_D_INFO,"gPchSpiProtocolGuid Status1: %r\n",Status));
    
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }
    
    
      Status = mSpiProtocol->FlashRead (
                             mSpiProtocol,
                             FlashRegionBios,
                             (UINT32) 0,
                             (UINT32) 0x1000,
                             Buffer
                             );
   
   

          
   
    DEBUG((EFI_D_INFO,"ShellAppMain Status1: %r\n",123));
    macdbg_dmphex_kernel( (const char *)0, 12 ); 

    #endif
    
  // xxxxvvvv
    return EFI_SUCCESS;
}
#endif


#include  <Uefi.h>
#include  <Library/UefiLib.h>
//#include  <Library/ShellCEntryLib.h>

//#include  <stdio.h>
//#include  <stdlib.h>
//#include  <wchar.h>

//#include <Protocol/EfiShell.h>
//#include <Library/ShellLib.h>

#include <Protocol/SimpleFileSystem.h>
#include <Protocol/BlockIo.h>
#include <Library/DevicePathLib.h>
//#include <Library/HandleParsingLib.h>
#include <Library/SortLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>

extern EFI_BOOT_SERVICES         *gBS;
extern EFI_SYSTEM_TABLE             *gST;
extern EFI_RUNTIME_SERVICES      *gRT;

//extern EFI_SHELL_ENVIRONMENT2    *mEfiShellEnvironment2;
extern EFI_HANDLE                 gImageHandle;

STATIC CONST UINTN SecondsToNanoSeconds = 10000000;

UINTN    Counter = 0;
/**
  The callback function for the timer event used to get map.

  @param[in] Event    The event this function is registered to.
  @param[in] Context  The context registered to the event.
**/
VOID
EFIAPI
Timeout (
  IN EFI_EVENT      Event,
  IN VOID           *Context
  )
{
  Print(L"www.lab-z.com [%d]\r\n",++ Counter);
  return ;
}

int main_timer(void )
{
  EFI_STATUS                Status;
  EFI_HANDLE                TimerOne = NULL;
  BOOLEAN                    ExitMark=FALSE;
  
  Status  = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
                    TPL_CALLBACK,
                    Timeout,
                    NULL,
                    &TimerOne
                    );
    
    if (EFI_ERROR (Status)) {
        Print(L"Create Event Error! \r\n");
        return 1;
    }

    Status = gBS->SetTimer (
                   TimerOne,
                   TimerPeriodic,
                   MultU64x32 (SecondsToNanoSeconds, 1)
                   );
    
    if (EFI_ERROR (Status)) {
        Print(L"Set Timer Error! \r\n");
        return 2;
    }

    while (!ExitMark)
    {
        //if (mEfiShellEnvironment2 -> GetExecutionBreak()) {ExitMark=TRUE;}


        if(Counter>5){
           ExitMark=TRUE; 
        }
    }
    gBS->SetTimer (TimerOne, TimerCancel, 0);
    gBS->CloseEvent (TimerOne);    
    return EFI_SUCCESS;
}


#if 0                 
EFI_STATUS UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable )                      
{                 
    EFI_STATUS Status;
    Status = EFI_SUCCESS;
    DEBUG( (EFI_D_WARN, "\n\n\nstart UefiMain...\n") ); 
    
      
    //main_timer();
    //HomeWorkDxeProtocolCallback();
    return EFI_SUCCESS;
}      
#endif


#if 0


//xxvv

EFI_STATUS UefiMain ( 
    IN EFI_HANDLE ImageHandle, 
    IN EFI_SYSTEM_TABLE  *SystemTable )
{       
    EFI_STATUS                        Status;
    EFI_SMBIOS_HANDLE                 SmbiosHandle = 0;
    EFI_SMBIOS_TABLE_HEADER           *Record;
    EFI_SMBIOS_PROTOCOL               *Smbios;
    UINTN                             OrigStringNumber = 5;
    CHAR8                             *AsciiData = "smbios_test_str = 12345";
  
    DEBUG( (EFI_D_WARN, "start UefiMain...\n") ); 

     
    Status = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
    Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);

    DEBUG( (EFI_D_INFO, "gEfiSmbiosProtocolGuid     : %g\n", gEfiSmbiosProtocolGuid ) );

    
      

   
    DEBUG( (EFI_D_INFO, "Type    : %x\n", Record->Type) );
    DEBUG( (EFI_D_INFO, "Length  : %x\n", Record->Length) );
    DEBUG( (EFI_D_INFO, "Handle  : %x\n", Record->Handle) );
    //macdbg_dmphex_kernel( (const char *)Record, 256 ); 
    //Status = Smbios->UpdateString (Smbios, &SmbiosHandle, &OrigStringNumber, AsciiData);
    //macdbg_dmphex_kernel((const char *)Record, 256 );
    //return EFI_SUCCESS;
    test_smbios_table();
    
    
    return EFI_SUCCESS;
}     

#endif


char get_a_char( IN EFI_SYSTEM_TABLE *SystemTable )
{
    EFI_STATUS Status;
    UINTN Index;
    EFI_INPUT_KEY Key;
    CHAR16 StrBuffer[3] = { 0x00 };
    SystemTable->BootServices->WaitForEvent(1,&SystemTable->ConIn->WaitForKey,&Index);   // 等待按键事件
    Status = SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &Key);                 // 读取键盘
    StrBuffer[0] = Key.UnicodeChar;                                                      // 取得按键的 Unicode 码
    return (char)(StrBuffer[0]&0xff);
}


int str2hex_num(char *input_buff)
{
    int i=0x00;
    int out_num;
    UINT8 curr_in;  
    out_num = 0x00;
    
    while(1){
      if( input_buff[i] == 0x00 ){
          break;
      }
      if( input_buff[i]>='0' && input_buff[i]<='9' ){
          curr_in = input_buff[i] - '0';
      }else if( input_buff[i]>='a' && input_buff[i]<='f' ){
          curr_in = input_buff[i] - 'a'+10;
      }else if( input_buff[i]>='A' && input_buff[i]<='F' ){
          curr_in = input_buff[i] - 'A'+10;
      }else{
          return 0;
      }
      out_num = out_num << 4;
      out_num = out_num | curr_in;
      i++;
    }
    return out_num;
}


/*
   macdbg_rdline_ser

  Description:
  reads a single line of input from the user on the debug serial port
  until a CR (0x0D) character is detected. the CR is NOT included in the line
  returned to the caller.
  Line returned to caller IS null terminated.

  NOTE: this blocks forever until a CR (0x0D) is read

  Returns on Success:
  0

  Returns on Failure:
  -1
*/
static int macdbg_rdline_ser(IN EFI_SYSTEM_TABLE *SystemTable, char* linebuff, unsigned int* outlen)
{
  int retval = 0;
  char userIn[2];
  unsigned int chcnt, max;

  userIn[0] = '\0';
  userIn[1] = '\0';
  chcnt = 0;
  max = *outlen;
  max -= 1; /* for NULL */

  while(1)
  {
    /* parse input, character by character
    waiting for a carriage return, no timeout */
    userIn[0] = get_a_char(SystemTable);

    if(userIn[0] == 0x0D)
    {
      /* print what the user typed */
      //macdbg_tx_char_ser(userIn[0]);

      
      DEBUG( (EFI_D_WARN, "%c", userIn[0]) );  

      /* we got a carriage return, set the outlen value and return*/
      *outlen = chcnt;
      /* set NULL */
      *(linebuff+chcnt) = 0x0;
      break; /* get out of while(1) and return */
    }
    /* handle backspace as backspace + delete */
    else if(userIn[0] == 0x08 || userIn[0] == 0x10)
    {
      /* we only need to do this logic if there
      has already been something typed ..we don't
      want to delete the command prompt! */
      if(chcnt > 0)
      {
        /* print backspace*/
        userIn[0] = 0x08;
        //macdbg_tx_char_ser(userIn[0]);
        DEBUG( (EFI_D_WARN, "%c", userIn[0]) ); 
        /* print space*/
        userIn[0] = 0x20;
        //macdbg_tx_char_ser(userIn[0]);
        DEBUG( (EFI_D_WARN, "%c", userIn[0]) ); 
        /* print backspace*/
        userIn[0] = 0x08;
        //macdbg_tx_char_ser(userIn[0]);
        DEBUG( (EFI_D_WARN, "%c", userIn[0]) ); 
        userIn[0] = 0x0;

        /* for backspace and delete keystrokes decrement the
        character counter and delete the prev char */
        chcnt--;
        *(linebuff + chcnt) = 0x0;
      }
    }
    else
    {
      /* first, check to see if we're over the caller's limit*/
      if(chcnt >= max )
      {
        //macdbg_prser("%s: max line input length (%d) reached without"
        //" <CR>, try again!\r\n", __FUNCTION__,max);

        DEBUG( (EFI_D_WARN, "%s: max line input length (%d) reached without"
            " <CR>, try again!\r\n", __FUNCTION__,max) ); 

        
        chcnt = 0;

        /* clear the buffer */
        memset(linebuff, '\0', max);
      }
      else
      {
        /* print what the user typed */
        //macdbg_tx_char_ser(userIn[0]);
        DEBUG( (EFI_D_WARN, "%c", userIn[0]) ); 

        /* filter out any undesired chars here */
        if(userIn[0] == 0x0A)
        {
          /* nothing really to do with these filtered out chars*/
        }
        else
        {
          /* we got a valid char - copy line buffer */
          *(linebuff + chcnt) = userIn[0];
          /* increment counter for next char and continue */
          chcnt++;
        }
      }
    }
  } /* while(1)*/

  return retval;
}


void get_hexstr(IN EFI_SYSTEM_TABLE *SystemTable, char *input_buff)
{
    int input_index;
    char input_char;
    input_index = 0x00;     
    while(1){
      input_char = get_a_char(SystemTable);
      DEBUG( (EFI_D_WARN, "%c", input_char) );  
      if( input_char=='\n' || input_char=='\r' ){
          break;
      }  
      if( input_char == 0x08 ){
            input_char = 0x20; 
          DEBUG( (EFI_D_WARN, "%c", input_char) );
          input_char = 0x08; 
          DEBUG( (EFI_D_WARN, "%c", input_char) );
          input_char = 0x00;
          input_index--;
      }
      input_buff[input_index] = input_char;
      if( input_char ){
          input_index++; 
      }
    }
}

#if 0
EFI_STATUS UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable )
{     
    EFI_STATUS Status;
    char input_buff[128];
    Status = EFI_SUCCESS;

         
    DEBUG( (EFI_D_WARN, "Please Input a hexstr...\n") ); 
    memset( input_buff, 0x00, sizeof(input_buff) );
    //get_hexstr(SystemTable,input_buff);

    //macdbg_dmphex_kernel((const char *)&Key, sizeof(Key) );
    //DEBUG( (EFI_D_WARN, "sizeof(input_buff) = %d", sizeof(input_buff)) ); 

    //DEBUG( (EFI_D_WARN, "get num xc= %x", str2hex_num(input_buff)) ); 


    ShellAppMain();
    return Status;
}

#endif


#include <uefi.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/PcdLib.h>

//#include <Efi.h>

// {755B6596-6896-4ba3-B3DD-1C629FD1EA88}
#define FLASH_PROTOCOL_GUID \
    { 0x755b6596, 0x6896, 0x4ba3, 0xb3, 0xdd, 0x1c, 0x62, 0x9f, 0xd1, 0xea, 0x88 }

// {ECB867AB-8DF4-492d-8150-A7FD1B9B5A75}
#define FLASH_SMM_PROTOCOL_GUID \
    { 0xecb867ab, 0x8df4, 0x492d, 0x81, 0x50, 0xa7, 0xfd, 0x1b, 0x9b, 0x5a, 0x75 }


EFI_GUID gFlashProtocolGuid = { 0x755b6596, 0x6896, 0x4ba3, { 0xb3, 0xdd, 0x1c, 0x62, 0x9f, 0xd1, 0xea, 0x88 }};

EFI_GUID gAmiSmmFlashProtocolGuid = { 0xECB867AB, 0x8DF4, 0x492D, { 0x81, 0x50, 0xa7, 0xfd, 0x1b, 0x9b, 0x5a, 0x75 }};
                                        //ECB867AB-   8DF4-   492D-8150-A7FD1B9B5A75 gAmiSmmFlashProtocolGuid

                                        //ECB867AB-8DF4-492D-8150-A7FD1B9B5A75 gAmiSmmFlashProtocolGuid
                                        //755B6596-6896-4BA3-B3DD-1C629FD1EA88 gFlashProtocolGuid


//GUID_VARIABLE_DECLARATION(gFlashProtocolGuid,FLASH_PROTOCOL_GUID);
//GUID_VARIABLE_DECLARATION(gFlashSmmProtocolGuid,FLASH_SMM_PROTOCOL_GUID);

typedef struct _FLASH_PROTOCOL FLASH_PROTOCOL;

typedef EFI_STATUS (EFIAPI *FLASH_READ_WRITE)(
    VOID* FlashAddress, UINTN Size, VOID* DataBuffer
);
typedef EFI_STATUS (EFIAPI *FLASH_ERASE)(
    VOID* FlashAddress, UINTN Size
);
typedef EFI_STATUS (EFIAPI *FLASH_WRITE_ENABLE_DISABLE)();

struct _FLASH_PROTOCOL {
    FLASH_READ_WRITE Read;
    FLASH_ERASE Erase;
    FLASH_READ_WRITE Write; //Write only
    FLASH_READ_WRITE Update; //Erase if necessary
    FLASH_WRITE_ENABLE_DISABLE DeviceWriteEnable;
    FLASH_WRITE_ENABLE_DISABLE DeviceWriteDisable; 
};

//----------------------------------------------------------------------------
// Includes
#include <Efi.h>
#include <AmiDxeLib.h>
#include "FlashPart.h"
//#include "SpiFlash.h"
#include "Token.h"
//----------------------------------------------------------------------------
// Local defines for transaction types
#ifndef SPI_OPCODE_TYPE_READ_NO_ADDRESS
#define SPI_OPCODE_TYPE_READ_NO_ADDRESS     0x0
#define SPI_OPCODE_TYPE_WRITE_NO_ADDRESS    0x1
#define SPI_OPCODE_TYPE_READ_WITH_ADDRESS   0x2
#define SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS  0x3
#endif
//----------------------------------------------------------------------------
// Module level global data
UINT32  MfgDevId = 0;
//extern  UINT16          gFlashId;
extern  FLASH_PART      mCommonSpiFlash;

//extern  UINT8           pFlashDeviceNumber[FLASH_PART_STRING_LENGTH];

UINT16  gFlashId = 0;
UINT8   pFlashDeviceNumber[FLASH_PART_STRING_LENGTH];

FLASH_PART      *FlashAPI = NULL;


//----------------------------------------------------------------------------
// Extern Function Prototypes
extern
BOOLEAN
CommonSpiReadId (
    FLASH_INFO          *FlashInfo,
    UINT32              *dFlashId
);
extern
VOID
ReinitializeSpiEnvironment (
    FLASH_INFO          *FlashInfo
);
//----------------------------------------------------------------------------
// Flash Part Data Structures


// ST Micro M25Pxx commands
#define SPI_M25Pxx_COMMAND_WRITE            0x02        // page program
#define SPI_M25Pxx_COMMAND_READ             0x03        // Read Byte
#define SPI_M25Pxx_COMMAND_ERASE            0xd8        // erase 64K sectors
#define SPI_M25Pxx_COMMAND_WRITE_DISABLE    0x04        // Write Disable
#define SPI_M25Pxx_COMMAND_READ_STATUS      0x05        // read Status Register
#define SPI_M25Pxx_COMMAND_WRITE_ENABLE     0x06        // Write Enable
#define SPI_M25Pxx_COMMAND_READ_ID          0x9f        // Manufacturer/Device ID
#define SPI_M25Pxx_COMMAND_WRITE_S          0x01        // Write Status register

// ST Micro M25Pxx commands
#define SPI_M25PExx_COMMAND_WRITE           0x02        // page program
#if FAST_READ_SUPPORT == 0
#define SPI_M25PExx_COMMAND_READ            0x03        // Read Byte
#elif FAST_READ_SUPPORT == 1
#define SPI_M25PExx_COMMAND_READ            0x0B        // Fast Read
#elif FAST_READ_SUPPORT == 2
#define SPI_M25PExx_COMMAND_READ            0x3B        //  Dual Output Fast Read
#endif
#define SPI_M25PExx_COMMAND_ERASE           0xD8        // erase 64K sectors
#define SPI_M25PExx_COMMAND_PAGE_ERASE      0xDB        // erase 256 byte pages
#define SPI_M25PExx_COMMAND_WRITE_DISABLE   0x04        // Write Disable
#define SPI_M25PExx_COMMAND_READ_STATUS     0x05        // read Status Register
#define SPI_M25PExx_COMMAND_WRITE_ENABLE    0x06        // Write Enable
#define SPI_M25PExx_COMMAND_READ_ID         0x9F        // Manufacturer/Device ID
#define SPI_M25PExx_COMMAND_WRITE_S         0x01        // Write Status register


//#define SECTOR_SIZE_4KB   0x1000  // Common 4kBytes sector size
//#define SECTOR_SIZE_64KB  0x10000  // Common 64kBytes sector size
#define BLOCK_SIZE_64KB     0x00010000  // Common 64kBytes block size
#define MAX_FWH_SIZE        0x00100000  // 8Mbit (Note that this can also be used for the 4Mbit )
 
FLASH_INFO Stm_25PE =
    {
        // Write Byte
        {SPI_M25PExx_COMMAND_WRITE,         SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS},
        // Read Data
        {SPI_M25PExx_COMMAND_READ,          SPI_OPCODE_TYPE_READ_WITH_ADDRESS},
        // Erase 64k Sector
        {SPI_M25PExx_COMMAND_ERASE,         SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS},
        // Read Device Status Reg
        {SPI_M25PExx_COMMAND_READ_STATUS,   SPI_OPCODE_TYPE_READ_NO_ADDRESS},
        // Read device ID
        {SPI_M25PExx_COMMAND_READ_ID,       SPI_OPCODE_TYPE_READ_NO_ADDRESS},
        // Write Status Register
        {SPI_M25PExx_COMMAND_WRITE_S,       SPI_OPCODE_TYPE_WRITE_NO_ADDRESS},
        // Write Status Enable - Not available on this part
        {0,                                 SPI_OPCODE_TYPE_READ_NO_ADDRESS},
        // Write Enable
        {SPI_M25PExx_COMMAND_WRITE_ENABLE,  SPI_OPCODE_TYPE_READ_NO_ADDRESS},
        256,
        SECTOR_SIZE_64KB
    };

#define WINBOND_25Xxx_ID            0x30ef
#define WINBOND_25Qxx_ID            0x40ef
#define WINBOND_25QxxW_ID           0x50ef
#define WINBOND_25QxxF_ID           0x60ef


// MXIC MX25Lx005 commands
#define SPI_MXIC_M25L_COMMAND_WRITE             0x02        // page program
#define SPI_MXIC_M25L_COMMAND_READ              0x03        // Read Byte
#define SPI_MXIC_M25L_COMMAND_ERASE             0x20        // erase 4K sectors
#define SPI_MXIC_M25L_COMMAND_WRITE_DISABLE     0x04        // Write Disable
#define SPI_MXIC_M25L_COMMAND_READ_STATUS       0x05        // read Status Register
#define SPI_MXIC_M25L_COMMAND_WRITE_ENABLE      0x06        // Write Enable
#define SPI_MXIC_M25L_COMMAND_READ_ID           0x9f        // Manufacturer/Device ID
#define SPI_MXIC_M25L_COMMAND_WRITE_S           0x01        // Write Status register

#pragma pack(push, 1)
/**
    This structure contains variables that define the detals and command 
    set of flash part.
**/
typedef struct _EX_FLASH_PART {
    FLASH_INFO                      FlashCommandMenu;
    UINT32                          FlashCapacity;
    UINT32                          FlashVenDevId;
    UINT8                           AAIWordProgram;
    UINT8                           GlobalBlockUnlock;
    UINT8                           bReserved[2];
} EX_FLASH_PART;

#pragma pack(pop)


#if 0
EX_FLASH_PART mExFlashPart = {
      {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},0,0},
      FLASH_SIZE,           // flash size, should be changed in Init function
      0,                    // flash part id, should be changed in Init function
      0                     // flash part string, should be changed in
                            // Init function
};
#endif

extern  EX_FLASH_PART   mExFlashPart;

/**
 * This function identifies the flash capacity of supported flash parts by
 * its capacity ID.
 *
 * @param dVenDevId Manufacturer/Device ID of flash part.
 *
 * @retval flash capacity
 */
UINT32
StmCheckMemoryCapacity  (
    IN UINT32               dVenDevId
)
{
    switch ( ( dVenDevId & 0x00FF0000 ) >> 16 ) {
        case 0x10 : return ( 0x10000 );
        case 0x11 : return ( 0x20000 );
        case 0x12 : return ( 0x40000 );
        case 0x13 : return ( 0x80000 );
        case 0x14 : return ( 0x100000 );
        case 0x15 : return ( 0x200000 );
        case 0x36 : // MX25U32xx 
        case 0x16 : return ( 0x400000 );
        case 0x37 : // MX25U64xx 
        case 0x17 : return ( 0x800000 );
        case 0x18 : return ( 0x1000000 );
        case 0x19 : return ( 0x2000000 );
        case 0x20 : return ( 0x4000000 );
        case 0x21 : return ( 0x8000000 );
    }
    return ( FLASH_SIZE );
}

/**
 * This function identifies the supported flash parts and returns appropriate 
 * flash device API pointer. If flash part is not supported by this module it 
 * will return FALSE.
 *
 * @param pBlockAddress Block address of the flash part. Can be used to 
 *                      send ID command
 * @param FlashStruct Pointer to hold the returned flash API
 *
 * @retval TRUE If flash part is supported, FlashApi contains routines to 
 *              handle the flash requests
 * @retval FALSE Flash part is not supported
 */
BOOLEAN
IdentifyStm_25PExx  (
    IN  volatile UINT8      *pBlockAddress,
    OUT FLASH_PART          **FlashStruct
)
{


    DEBUG((EFI_D_INFO,"in IdentifyStm_25PExx 123\n"));

    if ( !CommonSpiReadId( &Stm_25PE, &MfgDevId ) )    return FALSE;

    DEBUG((EFI_D_INFO,"in IdentifyStm_25PExx.1 MfgDevId = %x\n", MfgDevId));


    //return FALSE;
    
    switch ( (UINT16)MfgDevId ) {
                
        
        case WINBOND_25Xxx_ID :
        case WINBOND_25Qxx_ID :
        case WINBOND_25QxxF_ID :
        case WINBOND_25QxxW_ID :
            Stm_25PE.SectorSize = SECTOR_SIZE_4KB;
            Stm_25PE.Erase.Opcode = SPI_MXIC_M25L_COMMAND_ERASE;
            mExFlashPart.FlashCapacity = StmCheckMemoryCapacity( MfgDevId );
            MemCpy ( pFlashDeviceNumber, "Winbond 25X/Q Series", 20 );
            break;
        
        default :
            return  FALSE;
    }


    #if 1
    *FlashStruct = &mCommonSpiFlash;
    MemCpy( &mExFlashPart.FlashCommandMenu, &Stm_25PE, sizeof(FLASH_INFO) );
    mExFlashPart.FlashVenDevId = MfgDevId;
    gFlashId = MfgDevId;
    (*FlashStruct)->FlashProgramSize = Stm_25PE.PageSize;
    (*FlashStruct)->FlashSectorSize = Stm_25PE.SectorSize;
    (*FlashStruct)->FlashPartNumber = pFlashDeviceNumber;
    // Update the OpCode to OpMenu immediately if need.
    ReinitializeSpiEnvironment ( &mExFlashPart.FlashCommandMenu );
    #endif
    
    return  TRUE;
}

typedef struct {
    UINT32  BusDevFuncRegr; // SPBAR + 04h: Hardware Sequencing Flash Status Register (16bits)
    UINT8   HwSeqStsCtl;   // SPBAR + 04h: Hardware Sequencing Flash Status Register (16bits)
    UINT8   FlashAddr;  // SPBAR + 08h: Flash Address
    UINT8   FlashData;  // SPBAR + 10h: Flasg Data (64 bytes)
    UINT8   SwSeqSts;   // SPBAR + 90h: Software Sequencing Flash Status Register
    UINT8   SwSeqCtrl;  // SPBAR + 91h: Software Sequencing Flash Control Register
    UINT8   PreOpCode;  // SPBAR + 94h: Prefix Opcode Configuration
    UINT8   OpCodeType; // SPBAR + 96h: Opcode Type Configuration
    UINT8   OpCodeMenu; // SPBAR + 98h: Opcode Menu Configuration
    UINT8   BiosFdoc;   // SPBAR + 0B0h: Flash Descriptor Observability Control Register
    UINT8   BiosFdod;   // SPBAR + 0B4h: Flash Descriptor Observability Data Register   
    UINT8   BiosLVscc;  // SPBAR + 0C4h: Host Lower Vendor Specific Component Capabilities Register
    UINT8   BiosUVscc;  // SPBAR + 0C8h: Host Upper Vendor Specific Component Capabilities Register
    UINT8   BiosPTInx;  // SPBAR + 0CCh: Parameter Table Index
    UINT8   BiosPTData;  // SPBAR + 0D0h: Parameter Table Data
} SPI_REGS;

extern volatile UINT8  *gSPIBASE;
extern const SPI_REGS  SPIRegs[];


// SPI default opcode slots
#define     SPI_OPCODE_WRITE_INDEX      0x0
#define     SPI_OPCODE_READ_INDEX       0x1
#define     SPI_OPCODE_ERASE_INDEX      0x2
#define     SPI_OPCODE_READ_S_INDEX     0x3
#define     SPI_OPCODE_READ_ID_INDEX    0x4
#define     SPI_OPCODE_WRITE_S_INDEX    0x5
#define     SPI_OPCODE_WRITE_S_E_INDEX  0x6
#define     SPI_OPCODE_WRITE_E_INDEX    0x7
#define     SPI_OPCODE_READ_SFDP_INDEX  0x7
#define     SPI_OPCODE_AAI_INDEX        0x6
#define     SPI_OPCODE_WRITE_D_INDEX    0x7
#define     SPI_PREFIX_WRITE_S_EN       0x1
#define     SPI_PREFIX_WRITE_EN         0x0

// SPI Hardware Flash Cycle Type  
#define     SPI_HW_SEQ_READ             0x0
#define     SPI_HW_SEQ_WRITE            0x2
#define     SPI_HW_SEQ_ERASE_4K         0x3
// Below Hardware Flash Cycle Types are added from Skylake-PCH  
#define     SPI_HW_SEQ_ERASE_64K        0x4
#define     SPI_HW_SEQ_READ_SFDP        0x5
#define     SPI_HW_SEQ_READ_ID          0x6
#define     SPI_HW_SEQ_WRITE_STATUS     0x7
#define     SPI_HW_SEQ_READ_STATUS      0x8

#define     SPI_MAX_DATA_TRANSFER       0x40
#define     FLASH_VALID_SIGNATURE       0x0ff0a55a
#define     NO_ADDRESS_UPDATE           0
#ifndef SPI_OPCODE_TYPE_READ_NO_ADDRESS
#define     SPI_OPCODE_TYPE_READ_NO_ADDRESS     0x0
#define     SPI_OPCODE_TYPE_WRITE_NO_ADDRESS    0x1
#define     SPI_OPCODE_TYPE_READ_WITH_ADDRESS   0x2
#define     SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS  0x3
#endif  // #ifndef SPI_OPCODE_TYPE_READ_NO_ADDRESS

#undef SPI_USE_HARDWARE_SEQUENCE

#ifndef SPI_USE_HARDWARE_SEQUENCE
#define     SPI_USE_HARDWARE_SEQUENCE  0
#endif  // #ifndef SPI_USE_HARDWARE_SEQUENCE


#ifndef NO_MMIO_FLASH_ACCESS_DURING_UPDATE
#define NO_MMIO_FLASH_ACCESS_DURING_UPDATE 0
#endif


// SPI default opcode slots
#define     SPI_OPCODE_WRITE_INDEX      0x0
#define     SPI_OPCODE_READ_INDEX       0x1
#define     SPI_OPCODE_ERASE_INDEX      0x2
#define     SPI_OPCODE_READ_S_INDEX     0x3
#define     SPI_OPCODE_READ_ID_INDEX    0x4
#define     SPI_OPCODE_WRITE_S_INDEX    0x5
#define     SPI_OPCODE_WRITE_S_E_INDEX  0x6
#define     SPI_OPCODE_WRITE_E_INDEX    0x7
#define     SPI_OPCODE_READ_SFDP_INDEX  0x7
#define     SPI_OPCODE_AAI_INDEX        0x6
#define     SPI_OPCODE_WRITE_D_INDEX    0x7
#define     SPI_PREFIX_WRITE_S_EN       0x1
#define     SPI_PREFIX_WRITE_EN         0x0

// SPI Hardware Flash Cycle Type  
#define     SPI_HW_SEQ_READ             0x0
#define     SPI_HW_SEQ_WRITE            0x2
#define     SPI_HW_SEQ_ERASE_4K         0x3
// Below Hardware Flash Cycle Types are added from Skylake-PCH  
#define     SPI_HW_SEQ_ERASE_64K        0x4
#define     SPI_HW_SEQ_READ_SFDP        0x5
#define     SPI_HW_SEQ_READ_ID          0x6
#define     SPI_HW_SEQ_WRITE_STATUS     0x7
#define     SPI_HW_SEQ_READ_STATUS      0x8

#define     SPI_MAX_DATA_TRANSFER       0x40
#define     FLASH_VALID_SIGNATURE       0x0ff0a55a
#define     NO_ADDRESS_UPDATE           0
#ifndef SPI_OPCODE_TYPE_READ_NO_ADDRESS
#define     SPI_OPCODE_TYPE_READ_NO_ADDRESS     0x0
#define     SPI_OPCODE_TYPE_WRITE_NO_ADDRESS    0x1
#define     SPI_OPCODE_TYPE_READ_WITH_ADDRESS   0x2
#define     SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS  0x3
#endif  // #ifndef SPI_OPCODE_TYPE_READ_NO_ADDRESS
#ifndef SPI_USE_HARDWARE_SEQUENCE
#define     SPI_USE_HARDWARE_SEQUENCE  0
#endif  // #ifndef SPI_USE_HARDWARE_SEQUENCE
#ifndef NO_MMIO_FLASH_ACCESS_DURING_UPDATE
#define NO_MMIO_FLASH_ACCESS_DURING_UPDATE 0
#endif


/**
    This function gets the Base and Limit from the specified Flash Region

    @param Type Type of Flash region.   
    @param Base Base Address of region. 
    @param Limit Limit Address of region.

    @retval EFI_SUCCESS Operation Completed
    @retval EFI_INVALID_PARAMETER Operation not Completed
**/
EFI_STATUS
GetFlashRegionx(
    FLASH_REGION_TYPE   Type,
    UINTN               *Base,
    UINTN               *Limit
)
{
    UINTN               Data;

    // First, check whether works in Flash Descriptor mode.
    *(volatile UINT32*)(gSPIBASE + SPIRegs->BiosFdoc) = 0;
    Data = *(volatile UINT32*)(gSPIBASE + SPIRegs->BiosFdod);
    if ((UINT32)Data != FLASH_VALID_SIGNATURE) return EFI_UNSUPPORTED;
    // Descriptor Mode, Get Region from SPI Memory Mapped Configuration Registers.
    switch (Type) {
        case FlashRegionDescriptor: 
            Data = *(volatile UINT32*)(gSPIBASE + 0x54); 
            break;
        case FlashRegionBios:       
            Data = *(volatile UINT32*)(gSPIBASE + 0x58); 
            break;
        case FlashRegionMe:         
            Data = *(volatile UINT32*)(gSPIBASE + 0x5C); 
            break;
        case FlashRegionGbE:        
            Data = *(volatile UINT32*)(gSPIBASE + 0x60); 
            break;
        case FlashRegionPlatformData: 
            Data = *(volatile UINT32*)(gSPIBASE + 0x64); 
            break;
        default : return EFI_INVALID_PARAMETER;
    }
    if (Data == 0x7FFF) return EFI_UNSUPPORTED;
    if (Base != NULL) *Base = (Data & 0xFFFF) << 12;
    if (Limit != NULL) *Limit = (Data >> 4) | 0xFFF;
    return EFI_SUCCESS;
}


extern EFI_STATUS GetFlashRegion(
    FLASH_REGION_TYPE   Type,
    UINTN               *Base,
    UINTN               *Limit
);

// Intel Flash Region Operation
typedef enum
{
    FlashRegionRead = 0,
    FlashRegionErase,
    FlashRegionWrite
    
}FLASH_OPERATION;

extern EFI_STATUS FlashRegionOperation(
    IN  FLASH_REGION_TYPE   Type,
    IN  FLASH_OPERATION     Operation,
    IN  UINT32              Address,
    IN  UINT32              Length,
    IN  UINT8               *Buffer
);

extern BOOLEAN EFIAPI CommonSpiEraseCommand(
    IN  volatile UINT8  *pBlockAddress
);


extern BOOLEAN CommonSpiEraseCommand_Lib(
    IN  volatile UINT8  *pBlockAddress
);

EFI_STATUS EFIAPI test3(
    IN EFI_HANDLE       ImageHandle,
    IN EFI_SYSTEM_TABLE *SystemTable );


#if 1
EFI_STATUS EFIAPI test2(
    IN EFI_HANDLE       ImageHandle,
    IN EFI_SYSTEM_TABLE *SystemTable )
{
    EFI_STATUS Status = EFI_SUCCESS;

    UINT8      *pBlockAddress=NULL;
    //UINTN     RegionBase, RegionLimit;
    UINT8 Buffer[0x1000] = {0x00};
    //    RegionBase = 0x00;
    //RegionLimit = 0x00;
    //found=FlashList[i](pBlockAddress, &FlashAPI);    
    IdentifyStm_25PExx(pBlockAddress, &FlashAPI);
    
    // Initial SPI Base.
    //InitializeSpiBase();
    //FlashRegionBios = 0,
    //FlashRegionMe,
    //FlashRegionGbE,
    //FlashRegionDescriptor,
    //FlashRegionPlatformData,
    //FlashRegionMax
    //macdbg_dmphex_kernel( (const char *)&Buffer[0], sizeof(Buffer) ); 

    //Status = FlashRegionOperation(0x00,0x00, 0x66ff00,0x200,Buffer);
    //DEBUG ((EFI_D_ERROR,"Status = 0x1%r.\n", Status));
    //macdbg_dmphex_kernel( (const char *)&Buffer[0], 0x200 );     
        
        Buffer[0] = 0x11;
        Buffer[1] = 0x22;
        Buffer[2] = 0x33;
        Buffer[3] = 0x44;

        //Status = FlashRegionOperation(0x00,0x02, 0x80e000,0x4,Buffer);
        //DEBUG( (EFI_D_ERROR,"Statusxcvbn = 0x1%r.\n", Status) );    
        FlashAPI->FlashDeviceWriteEnable();

        //macdbg_dmphex_kernel( (const char *)&Buffer[0], 0x200 ); 
        FlashAPI->FlashBlockWriteEnable((void *)0xFFe60000);

    Status = FlashAPI-> FlashEraseCommand  ((void *)0xFFe60000);
        DEBUG( (EFI_D_ERROR,"Statusxcvbn1 = 0x1%r.\n", Status) );    


        Status = FlashAPI-> FlashEraseCommandEx  ((void *)0xFFe60000, 0x1000);
        DEBUG( (EFI_D_ERROR,"Statusxcvbn2 = 0x1%r.\n", Status) );    

        //CommonSpiEraseCommandEx

        Status = FlashAPI-> FlashEraseCommandEx  ((void *)0xFFe70000, 0x1000);
        DEBUG( (EFI_D_ERROR,"Statusxcvbn2 = 0x1%r.\n", Status) );    


        


        
    //DEBUG ((EFI_D_ERROR,"Getvariable nv_var 0x%x.\n", nv_var));
    return EFI_SUCCESS;
}
//DxeSetVariableSafe
//DxeSetVariableWrapper
//DxeSetVariable
#endif


EFI_GUID mEfiSimpleFileSystemProtocolGuid = { 0x964E5B22, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
EFI_GUID   gEfiTestGuid = { 0xb71604d3, 0xb8ba, 0x4d9c, { 0x78, 0x88, 0xac, 0xcf, 0x1d, 0xa2, 0x26, 0xc5 }};


UINT8 gFileBuffer[0x1000];

UINT8 gFirmwareFileBuffer[0x1000000];


EFI_FILE_PROTOCOL *EfiDirectory = 0;
EFI_FILE_PROTOCOL *ReadMe = 0;


EFI_STATUS open_firmware(void)
{
    EFI_STATUS  Status = 0;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
    EFI_FILE_PROTOCOL *Root = 0;
    

    
                   
    Status = gBS->LocateProtocol(
            &mEfiSimpleFileSystemProtocolGuid,
            NULL,
            (VOID**)&SimpleFileSystem
    );
    if (EFI_ERROR(Status)) {
     //未找到EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
        return Status;
    }
    Status = SimpleFileSystem->OpenVolume(SimpleFileSystem, &Root);

    // 在根目录下生成efi目录
    Status = Root->Open(
            Root, 
            &EfiDirectory,
            (CHAR16*)L"\\",
            EFI_FILE_MODE_READ, //打开模式
            EFI_FILE_DIRECTORY
            );

    DEBUG((EFI_D_INFO,"open dir Status: %r\n",Status));

    if( Status ){
        return Status;         
    }   
    Status = EfiDirectory ->Open(
             EfiDirectory,    //This 指向目录\efi\ 
             &ReadMe,          //新文件的句柄   
             (CHAR16*)L"spi_image_HV.bin",  //文件全路径为\efi\readme.txt
             EFI_FILE_MODE_READ ,//
             0  //生成普通文件,使用默认属性
    );
    DEBUG((EFI_D_INFO,"open file Status: %r\n",Status));
   
        return Status;         
      
            
                                                                                                                                     
    
}   

EFI_STATUS close_firmware(void)
{
    EFI_STATUS    Status = 0;
    Status = ReadMe -> Close(ReadMe);          
    Status = EfiDirectory->Close(EfiDirectory);           
    return Status;           
}

EFI_STATUS get_a_block( UINT64 Position, UINTN BufferSize, UINT8 *out_buff )
{
    EFI_STATUS  Status = 0;
    
    ReadMe->SetPosition(ReadMe, Position);
    ReadMe ->Read(ReadMe, &BufferSize, out_buff );
    //macdbg_dmphex_kernel( (const char *)&gFileBuffer, (int)0x100 );            
                                                                                                                                     
           
    return Status;           
}            
              

int test_buff_is_empty()
{                 
    int i;
    for( i=0x00; i<0x1000; i++ ){           
         if( gFileBuffer[i] != 0xFF ){
             return 0; 
         }
    }
    return 1;
}

EFI_STATUS prog_app_area(void)
{      
    EFI_STATUS Status = EFI_SUCCESS;
    UINTN      DataSize;
    UINT64 Current_Position;
    UINT32 current_oft;
    UINT8 update_data[0x1100] = {0x00};

    
    DataSize = 9+4096+1;
                                  
    //编程app区域
    Current_Position = 0x860000;
    current_oft      = 0x00;
       
    update_data[0] = 0x55;
    //开始标志
    update_data[1] = 0x01;
    //操作命令 01->编程flash
    update_data[2] = 0x02;
    //编程区块编号
    update_data[3] = 0x00;
    update_data[4] = 0x00;
    update_data[5] = 0x00;
    update_data[6] = 0x00;
    //偏移地址
    update_data[7] = 0x10;
    update_data[8] = 0x00;
    //编程长度
    update_data[9+4096] = 0xed;

    
    while(1){
      
      //macdbg_dmphex_kernel( (const char *)gFileBuffer, (int)0x10 ); 

      memcpy(gFileBuffer, &gFirmwareFileBuffer[Current_Position], 0x1000 );

      if( test_buff_is_empty() ){
          goto skip_next_step_app; 
      }

      update_data[3] = (current_oft>>24) & 0xff;
      update_data[4] = (current_oft>>16) & 0xff;
      update_data[5] = (current_oft>>8)  & 0xff;
      update_data[6] = (current_oft>>0)  & 0xff;

      update_data[7] = 0x10;
      update_data[8] = 0x00;

      
      memcpy( &update_data[9], gFileBuffer, 0x1000);
      //macdbg_dmphex_kernel( (const char *)update_data, (int)DataSize ); 
      
      Status = gRT->SetVariable (
                  L"testvar0",
                  &gEfiTestGuid,
                  EFI_VARIABLE_NON_VOLATILE |
                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
                  EFI_VARIABLE_RUNTIME_ACCESS,
                  DataSize,
                  &update_data[0]
                  );   
       //DEBUG((EFI_D_INFO,"ShellAppMain Status2: %r\n",Status));  
       skip_next_step_app:
       Current_Position = Current_Position + 0x1000;
       current_oft      = current_oft      + 0x1000;    
       if( Current_Position == 0xe70000 ){       
           break;          
       }
       
    }


    
    return EFI_SUCCESS;    

}


EFI_STATUS prog_boot_area(void)
{         
    EFI_STATUS Status = EFI_SUCCESS;
    UINTN      DataSize;
    UINT64 Current_Position;
    UINT32 current_oft;
    UINT8 update_data[0x1100] = {0x00};

    DataSize = 9+4096+1;
    
    update_data[0] = 0x55;
    //开始标志
    update_data[1] = 0x01;
    //操作命令 01->编程flash
    update_data[2] = 0x01;
    //编程区块编号
    update_data[3] = 0x00;
    update_data[4] = 0x00;
    update_data[5] = 0x00;
    update_data[6] = 0x00;
    //偏移地址
    update_data[7] = 0x10;
    update_data[8] = 0x00;
    //编程长度

    update_data[9] = 0xff;
    update_data[9+4096-1] = 0xff;
    
    update_data[9+4096] = 0xed;

    

    //编程boot区域
    Current_Position = 0xe70000;
    current_oft      = 0x00;
    while(1){
      
      //macdbg_dmphex_kernel( (const char *)gFileBuffer, (int)0x10 ); 

      memcpy(gFileBuffer, &gFirmwareFileBuffer[Current_Position], 0x1000 );

      if( test_buff_is_empty() ){
          goto skip_next_step_boot; 
      }

      update_data[3] = (current_oft>>24) & 0xff;
      update_data[4] = (current_oft>>16) & 0xff;
      update_data[5] = (current_oft>>8)  & 0xff;
      update_data[6] = (current_oft>>0)  & 0xff;

      update_data[7] = 0x10;
      update_data[8] = 0x00;

      
      memcpy( &update_data[9], gFileBuffer, 0x1000);
      //macdbg_dmphex_kernel( (const char *)update_data, (int)DataSize ); 
      
      Status = gRT->SetVariable (
                  L"testvar0",
                  &gEfiTestGuid,
                  EFI_VARIABLE_NON_VOLATILE |
                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
                  EFI_VARIABLE_RUNTIME_ACCESS,
                  DataSize,
                  &update_data[0]
                  );   
       //DEBUG((EFI_D_INFO,"ShellAppMain Status2: %r\n",Status));  
       skip_next_step_boot:
       Current_Position = Current_Position + 0x1000;
       current_oft      = current_oft      + 0x1000;    
       if( Current_Position == 0x1000000 ){       
           break;          
       }
       
    }

    return EFI_SUCCESS;    


}


EFI_STATUS test1(void)
{      
    EFI_STATUS Status = EFI_SUCCESS;
    UINTN      DataSize;
    UINT64 Current_Position;
    UINT32 current_oft;
    UINT8 update_data[0x1100] = {0x00};

    
    DataSize = 9+4096+1;
                                  
    //编程app区域
    Current_Position = 0x860000;
    current_oft      = 0x00;
       
    update_data[0] = 0x55;
    //开始标志
    update_data[1] = 0x01;
    //操作命令 01->编程flash
    update_data[2] = 0x02;
    //编程区块编号
    update_data[3] = 0x00;
    update_data[4] = 0x00;
    update_data[5] = 0x00;
    update_data[6] = 0x00;
    //偏移地址
    update_data[7] = 0x10;
    update_data[8] = 0x00;
    //编程长度
    update_data[9+4096] = 0xed;

    gFileBuffer[0] = 0x11;
    gFileBuffer[1] = 0x22;
    gFileBuffer[2] = 0x33;
    gFileBuffer[3] = 0x44;
    current_oft = 0x600000;
    update_data[3] = (current_oft>>24) & 0xff;
    update_data[4] = (current_oft>>16) & 0xff;
    update_data[5] = (current_oft>>8)  & 0xff;
    update_data[6] = (current_oft>>0)  & 0xff;

    update_data[7] = 0x10;
    update_data[8] = 0x00;  
    memcpy( &update_data[9], gFileBuffer, 0x1000);
    //macdbg_dmphex_kernel( (const char *)update_data, (int)DataSize ); 
      
    Status = gRT->SetVariable (
                  L"testvar0",
                  &gEfiTestGuid,
                  EFI_VARIABLE_NON_VOLATILE |
                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
                  EFI_VARIABLE_RUNTIME_ACCESS,
                  DataSize,
                  &update_data[0]
                  );   
    //DEBUG((EFI_D_INFO,"ShellAppMain Status2: %r\n",Status));  
    return EFI_SUCCESS;    

}


        
                                       
#if 1
EFI_STATUS EFIAPI UefiMain(
    IN EFI_HANDLE       ImageHandle,
    IN EFI_SYSTEM_TABLE *SystemTable )
{
    EFI_STATUS Status = EFI_SUCCESS;
    UINTN      DataSize;
    int i;                                      
    UINT32     nv_var = 0x55667788;
    
    OUT VOID                        *pData;
    UINT32                          Attributes;
    UINT64 Current_Position;

    char input_buff[128];

    //UINT8 update_data[0x1100] = {0x00};

    

    //setvar "testvar0" -guid  b71604d2-b8ba-4d9c-7888-accf1da226c5
    //setvar "testvar0" -guid  b71604d2-b8ba-4d9c-7888-accf1da226c5 =aabbccdd
    //setvar "testvar0" -guid  b71604d2-b8ba-4d9c-7888-accf1da226c5 =88776655
    //dmpstore -guid  b71604d2-b8ba-4d9c-7888-accf1da226c5

    nv_var = 0;
    i=0x00;
    DataSize = sizeof (nv_var);
    Status   = gRT->GetVariable (
                L"testvar0",
                &gEfiTestGuid,
                NULL,
                &DataSize,
                &nv_var
                );


    DEBUG((EFI_D_INFO,"ShellAppMain Status1: %r\n",Status));
    pData     = NULL; 
    if( Status == EFI_BUFFER_TOO_SMALL ){
        Status = gBS->AllocatePool(EfiBootServicesData, DataSize, &pData);
        DEBUG((EFI_D_INFO," DataSize: %d\n",DataSize));
        Status = gRT->GetVariable(L"testvar0", &gEfiTestGuid, &Attributes, &DataSize, pData);
    }else if( Status == EFI_NOT_FOUND ){
        DataSize = sizeof(nv_var);
        nv_var = 0x55667788;
        Status = gRT->SetVariable (
                  L"testvar0",
                  &gEfiTestGuid,
                  EFI_VARIABLE_NON_VOLATILE |
                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
                  EFI_VARIABLE_RUNTIME_ACCESS,
                  DataSize,
                  &nv_var
                  );
    }
    //macdbg_dmphex_kernel( (const char *)&nv_var, (int)DataSize ); 
    //DEBUG ((EFI_D_ERROR,"Getvariable nv_var 0x%x.\n", nv_var));
   


         
    DEBUG( (EFI_D_WARN, "Please Input a hexstr...\n") ); 
    memset( input_buff, 0x00, sizeof(input_buff) );
    //get_hexstr(SystemTable,input_buff);

    i=sizeof(input_buff);

    macdbg_rdline_ser(SystemTable,input_buff,&i);

    macdbg_dmphex_kernel((const char *)&input_buff, 16 );

    //DEBUG( (EFI_D_WARN, "get num xc= %s", str2hex_num(input_buff)) ); 
    if( strcmp(input_buff, "prog") == 0x00 ){
        Current_Position = 0x00;
        DEBUG ((EFI_D_ERROR,"start read firmware...\n"));
        open_firmware();
        get_a_block( Current_Position, 0x1000000, &gFirmwareFileBuffer[0] );
        close_firmware();    
        DEBUG ((EFI_D_ERROR,"end read firmware!\n"));
        DEBUG ((EFI_D_ERROR,"prog boot\n"));
        prog_boot_area();
        DEBUG ((EFI_D_ERROR,"prog app\n"));
        prog_app_area();
        DEBUG ((EFI_D_ERROR,"prog end\n"));
    }else if( strcmp(input_buff, "test1") == 0x00 ){
        DEBUG ((EFI_D_ERROR,"in test1 \n"));
        test1();
    }else if( strcmp(input_buff, "test2") == 0x00 ){
        DEBUG ((EFI_D_ERROR,"in test2 \n"));
        test2(ImageHandle, SystemTable);
    }else if( strcmp(input_buff, "test3") == 0x00 ){
        DEBUG ((EFI_D_ERROR,"in test3 \n"));
        test3(ImageHandle, SystemTable);
    }else{
        DEBUG ((EFI_D_ERROR,"input error!!!\n")); 
    }
    
    return EFI_SUCCESS;          
}        

      


//DxeSetVariableSafe
//DxeSetVariableWrapper
//DxeSetVariable
#endif


#if 1
unsigned char Buffer[0x1000];      

FLASH_PROTOCOL                  *mFlash = NULL;

EFI_STATUS EFIAPI test3(
    IN EFI_HANDLE       ImageHandle,
    IN EFI_SYSTEM_TABLE *SystemTable )
{
    EFI_STATUS Status = EFI_SUCCESS;
    

    // Locate FlashProtocol.
    Status = gBS->LocateProtocol( &gFlashProtocolGuid, NULL, &mFlash );
    DEBUG((EFI_D_INFO,"gFlashProtocolGuid Status1: %r\n",Status));
    if( EFI_ERROR(Status) ){
        return Status;
    }
    Status = mFlash->Read((void *)0xff800000, 0x100, Buffer);      
    if( EFI_ERROR(Status) ){
        return Status;
    }
    macdbg_dmphex_kernel( (const char *)Buffer, 0x100 );


    Status = mFlash->DeviceWriteEnable();
    DEBUG((EFI_D_INFO,"DeviceWriteEnable Status: %r\n",Status));


    Status = mFlash->Erase((void *)0xff800000, 0x1000 );  
    DEBUG((EFI_D_INFO,"Erase Status: %r\n",Status));


    Buffer[0x00] = 0x55;
    Buffer[0xff] = 0xAA;
    Status = mFlash->Write((void *)0xff800000, 0x100, Buffer);  
    DEBUG((EFI_D_INFO,"Write Status: %r\n",Status));


    Status = mFlash->Read((void *)0xff800000, 0x100, Buffer);      
    if( EFI_ERROR(Status) ){
        return Status;
    }
    macdbg_dmphex_kernel( (const char *)Buffer, 0x100 ); 


    #if 0
    EFI_GUID gEfiSFlashProtocolGuid = FLASH_PROTOCOL_GUID;
    FLASH_PROTOCOL*  pFlashProtocol;
    EFI_PHYSICAL_ADDRESS        Flash4GBMapStart;
    UINT8         *StrBuffer;
     
    Status = pBS->LocateProtocol( &gEfiSFlashProtocolGuid, NULL, &pFlashProtocol);
     
    Status = gBS->AllocatePool(//start: allocate mem    check point hear
                 EfiBootServicesData,
                 sizeof(UINT8) * FLASH_BLOCK_SIZE,
                 (VOID*)&StrBuffer);
    if (EFI_ERROR(Status) || StrBuffer == NULL) {
        DEBUG((EFI_D_INFO,"gFlashProtocolGuid Status456vvvbb1: %r\n",Status));
     }
     
    MemSet(StrBuffer, (sizeof(UINT8) * FLASH_BLOCK_SIZE), 0);
    Flash4GBMapStart = 0xFFFFFFFF - FLASH_SIZE + 1;


    DEBUG((EFI_D_INFO,"FLASH_SIZE %x\n", FLASH_SIZE));

    DEBUG((EFI_D_INFO,"FLASH_BLOCK_SIZE %x\n", FLASH_BLOCK_SIZE));

    
    DEBUG((EFI_D_INFO,"Flash4GBMapStart %x\n", Flash4GBMapStart));

    
    
          
    //Enable DeviceWrite to read real Flash address, not memory mapping.
    Status = pFlashProtocol->DeviceWriteEnable();//step1. enable
     if (EFI_ERROR(Status)) {
                  
     } 
     Status = pFlashProtocol->Read(//step2. Read
                       (VOID*)Flash4GBMapStart,
                       FLASH_BLOCK_SIZE,
                       (VOID*)StrBuffer);
                    
     *(StrBuffer+0x00) = 0x55;    


     
     DEBUG((EFI_D_INFO,"in pFlashProtocol->Write %p\n", pFlashProtocol->Write));


    Status = pFlashProtocol->Write(//step3. Update or write
     (VOID*)Flash4GBMapStart,
    FLASH_BLOCK_SIZE,
     (VOID*)StrBuffer); 

    DEBUG((EFI_D_INFO,"gFlashProtocolGuid Status456vvvbb12: %r\n",Status));
    
     pFlashProtocol->DeviceWriteDisable();    //step4. Disable
    gBS->FreePool(StrBuffer);//end: free memory

    #endif
    

    
    return EFI_SUCCESS;
}

#endif


//(pBS->LocateProtocol(&gFlashProtocolGuid, NULL, &Flash));


#if 0
Status = mSpiProtocol->FlashRead (
                            mSpiProtocol,
                            FlashRegionBios,
                            (UINT32) 0,
                            (UINT32) 0x1000,
                            Buffer
                            );


#endif

 


EFI_STATUS prog_flash_area(NVRAM_STORE_INTERFACE *Interface, IN VOID *Data, IN UINTN DataSize)
{
    UINT32 offset,op_len;
    UINT8 area,op_cmd;
    UINT8 *pData;
    BOOLEAN ok;

    pData = Data;
    
    if( pData[0]!=0x55 || pData[DataSize-1]!=0xED ){
        return EFI_INVALID_PARAMETER;  
    }
    
    //NVRAM_TRACE((DEBUG_ERROR,"NVRAM: update var: \n"));
    op_cmd = pData[1];
    area   = pData[2];
    offset = (pData[3]<<24) | (pData[4]<<16) | (pData[5]<<8) | (pData[6]<<0);
    op_len = (pData[7]<<8)  | (pData[8]<<0);

    //NVRAM_TRACE( (DEBUG_ERROR, "NVRAM:op_cmd = %x, area = %x, offset = %x, op_len = %x.\n", op_cmd, area, offset, op_len) );
    if( area == 1 ){
        NvEnableWrites( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xffe70000+offset), 0x1000);
        NvErase( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xffe70000+offset), 0x1000);
        ok = NvProgram( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xffe70000+offset), op_len, &pData[9]);
        if( ok == 0x00 ){
            NVRAM_TRACE((DEBUG_ERROR,"NVRAM: ok s1 = %d.\n", ok));
        }
        NvDisableWrites( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xffe70000+offset), 0x1000);
    }else if( area == 2 ){
        NvEnableWrites( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xff860000+offset), 0x1000);
        NvErase( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xff860000+offset), 0x1000);
        ok = NvProgram( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xff860000+offset), op_len, &pData[9]);
        if( ok == 0x00 ){
            NVRAM_TRACE((DEBUG_ERROR,"NVRAM: ok s2 = %d.\n\n", ok));
        }
        NvDisableWrites( ((HYBRID_NVRAM_STORE_INTERFACE*)Interface)->Flash, (void *)(0xff860000+offset), 0x1000);
    }

        

    

    return EFI_SUCCESS;  
}

 

 

 

 

                 
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值