#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "EfiKey.h"
#include
#include
#include
//#include
//#include
#include "HomeWorkDxe.h"
extern EFI_BOOT_SERVICES *gBS;
extern EFI_BOOT_SERVICES *pBS;
extern EFI_HANDLE gImageHandle;
#include
#include
#include
#include
#include
#include
#include "EfiKey.h"
#include
#include
//#include
#include
#include
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
//*************************************************************************
//
//
// 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.
//
//
//*************************************************************************
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;
}
//**********************************************************************
//
//
// 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:
//
//**********************************************************************
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
#include
#include
#include
#include
#if RTCWAKEUP_POWERBUTTON_SUPPORT
#include
#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;
//
//----------------------------------------------------------------------------
// 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.
//
//----------------------------------------------------------------------------
//
UINT8 DecToBCD (
IN UINT8 Dec )
{
UINT8 FirstDigit = Dec % 10;
UINT8 SecondDigit = Dec / 10;
return (SecondDigit << 4) + FirstDigit;
}
//
//----------------------------------------------------------------------------
// 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.
//
//----------------------------------------------------------------------------
//
UINT8 BCDToDec (
IN UINT8 BCD )
{
UINT8 FirstDigit = BCD & 0xf;
UINT8 SecondDigit = BCD >> 4;;
return SecondDigit * 10 + FirstDigit;
}
//
//----------------------------------------------------------------------------
// 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.
//----------------------------------------------------------------------------
//
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;
}
//
//----------------------------------------------------------------------------
// 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.
//----------------------------------------------------------------------------
//
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
#include
#include
//#include "UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h"
#include
#include
#include
#include
#include
#include
#include
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
#include
//#include
//#include
//#include
//#include
//#include
//#include
#include
#include
#include
//#include
#include
#include
#include
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"
//"
DEBUG( (EFI_D_WARN, "%s: max line input length (%d) reached without"
"
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
#include
#include
#include
#include
#include
#include
#include
//#include
// {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
#include
#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;
}