vfrservices.cpp
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C++ 代码 · 共 755 行 · 第 1/2 页
CPP
755 行
if (Curr->Next != NULL) {
BytesLeftThisOpcode = (UINT32)Curr->Next->OpcodeByte;
}
}
fprintf (OutFptr, "%02X ", (UINT32)Curr->OpcodeByte);
ByteCount++;
BytesLeftThisOpcode--;
if (BytesLeftThisOpcode == 0) {
fprintf (OutFptr, "\n");
}
Curr = Curr->Next;
}
}
//
// Dump any remaining lines from the input file
//
while (fgets (Line, sizeof (Line), InFptr) != NULL) {
fprintf (OutFptr, "%s", Line);
}
fclose (InFptr);
fclose (OutFptr);
}
//
// Debug code to make sure that each opcode we write out has as many
// bytes as the IFR structure requires. If there were errors, then
// don't do this step.
//
if (GetUtilityStatus () != STATUS_ERROR) {
Curr = mIfrBytes;
ByteCount = 0;
while (Curr != NULL) {
//
// First byte is the opcode, second byte is the length
//
if (Curr->Next == NULL) {
Error (__FILE__, __LINE__, 0, "application error", "last opcode written does not contain a length byte");
break;
}
Count = (UINT32)Curr->Next->OpcodeByte;
if (Count == 0) {
Error (
__FILE__,
__LINE__,
0,
"application error",
"opcode with 0 length specified in output at offset 0x%X",
ByteCount
);
break;
}
//
// Check the length
//
if ((Curr->OpcodeByte > EFI_IFR_LAST_OPCODE) || (Curr->OpcodeByte == 0)) {
Error (
__FILE__,
__LINE__,
0,
"application error",
"invalid opcode 0x%X in output at offset 0x%X",
(UINT32) Curr->OpcodeByte, ByteCount
);
} else if (mOpcodeSizes[Curr->OpcodeByte].Size < 0) {
//
// For those cases where the length is variable, the size is negative, and indicates
// the miniumum size.
//
if ((mOpcodeSizes[Curr->OpcodeByte].Size * -1) > Count) {
Error (
__FILE__,
__LINE__,
0,
"application error",
"insufficient number of bytes written for %s at offset 0x%X",
mOpcodeSizes[Curr->OpcodeByte].Name,
ByteCount
);
}
} else {
//
// Check for gaps
//
if (mOpcodeSizes[Curr->OpcodeByte].Size == 0) {
Error (
__FILE__,
__LINE__,
0,
"application error",
"invalid opcode 0x%X in output at offset 0x%X",
(UINT32)Curr->OpcodeByte,
ByteCount
);
} else {
//
// Check size
//
if (mOpcodeSizes[Curr->OpcodeByte].Size != Count) {
Error (
__FILE__,
__LINE__,
0,
"application error",
"invalid number of bytes (%d written s/b %d) written for %s at offset 0x%X",
Count,
mOpcodeSizes[Curr->OpcodeByte].Size,
mOpcodeSizes[Curr->OpcodeByte].Name,
ByteCount
);
}
}
}
//
// Skip to next opcode
//
while (Count > 0) {
ByteCount++;
if (Curr == NULL) {
Error (__FILE__, __LINE__, 0, "application error", "last opcode written has invalid length");
break;
}
Curr = Curr->Next;
Count--;
}
}
}
}
VfrOpcodeHandler::~VfrOpcodeHandler(
)
/*++
Routine Description:
Destructor for the VFR opcode handler. Free up memory allocated
while parsing the VFR script.
Arguments:
None
Returns:
None
--*/
{
IFR_BYTE *Curr;
IFR_BYTE *Next;
//
// Free up the IFR bytes
//
Curr = mIfrBytes;
while (Curr != NULL) {
Next = Curr->Next;
free (Curr);
Curr = Next;
}
}
int
VfrOpcodeHandler::AddOpcodeByte (
UINT8 OpcodeByte,
UINT32 LineNum
)
/*++
Routine Description:
This function is invoked by the parser when a new IFR
opcode should be emitted.
Arguments:
OpcodeByte - the IFR opcode
LineNum - the line number from the source file that resulted
in the opcode being emitted.
Returns:
0 always
--*/
{
UINT32 Count;
FlushQueue();
//
// Now add this new byte
//
mQueuedOpcodeByte = OpcodeByte;
mQueuedLineNum = LineNum;
mQueuedOpcodeByteValid = 1;
return 0;
}
VOID
VfrOpcodeHandler::AddByte (
UINT8 ByteVal,
UINT8 KeyByte
)
/*++
Routine Description:
This function is invoked by the parser when it determines
that more raw IFR bytes should be emitted to the output stream.
Here we just queue them up into an output buffer.
Arguments:
ByteVal - the raw byte to emit to the output IFR stream
KeyByte - a value that can be used for debug.
Returns:
None
--*/
{
//
// Check for buffer overflow
//
if (mQueuedByteCount > MAX_QUEUE_COUNT) {
Error (PROGRAM_NAME, 0, 0, NULL, "opcode queue overflow");
} else {
mQueuedBytes[mQueuedByteCount] = ByteVal;
mQueuedKeyBytes[mQueuedByteCount] = KeyByte;
mQueuedByteCount++;
}
}
int
VfrOpcodeHandler::FlushQueue (
)
/*++
Routine Description:
This function is invoked to flush the internal IFR buffer.
Arguments:
None
Returns:
0 always
--*/
{
UINT32 Count;
UINT32 EmitNoneOnePair;
EmitNoneOnePair = 0;
//
// If the secondary varstore was specified, then we have to emit
// a varstore-select-pair opcode, which only applies to the following
// statement.
//
if (mSecondaryVarStoreIdSet) {
mSecondaryVarStoreIdSet = 0;
//
// If primary and secondary are the same as the current default
// varstore, then we don't have to do anything.
// Note that the varstore-select-pair only applies to the following
// opcode.
//
if ((mPrimaryVarStoreId != mSecondaryVarStoreId) || (mPrimaryVarStoreId != mDefaultVarStoreId)) {
IAddByte (EFI_IFR_VARSTORE_SELECT_PAIR_OP, 'O', mQueuedLineNum);
IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT_PAIR), 'L', 0);
IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0);
IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0);
IAddByte ((UINT8)mSecondaryVarStoreId, 0, 0);
IAddByte ((UINT8)(mSecondaryVarStoreId >> 8), 0, 0);
}
} else if (mPrimaryVarStoreIdSet != 0) {
mPrimaryVarStoreIdSet = 0;
if (mDefaultVarStoreId != mPrimaryVarStoreId) {
//
// The VFR statement referenced a different variable store
// than the last one we reported. Insert a new varstore select
// statement.
//
IAddByte (EFI_IFR_VARSTORE_SELECT_OP, 'O', mQueuedLineNum);
IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT), 'L', 0);
IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0);
IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0);
mDefaultVarStoreId = mPrimaryVarStoreId;
}
}
//
// Likely a new opcode is being added. Since each opcode item in the IFR has
// a header that specifies the size of the opcode item (which we don't
// know until we find the next opcode in the VFR), we queue up bytes
// until we know the size. Then we write them out. So flush the queue
// now.
//
if (mQueuedOpcodeByteValid != 0) {
//
// Add the previous opcode byte, the length byte, and the binary
// data.
//
IAddByte (mQueuedOpcodeByte, 'O', mQueuedLineNum);
IAddByte ((UINT8)(mQueuedByteCount + 2), 'L', 0);
for (Count = 0; Count < mQueuedByteCount; Count++) {
IAddByte (mQueuedBytes[Count], mQueuedKeyBytes[Count], 0);
}
mQueuedByteCount = 0;
mQueuedOpcodeByteValid = 0;
}
return 0;
}
int
VfrOpcodeHandler::IAddByte (
UINT8 ByteVal,
UINT8 KeyByte,
UINT32 LineNum
)
/*++
Routine Description:
This internal function is used to add actual IFR bytes to
the output stream. Most other functions queue up the bytes
in an internal buffer. Once they come here, there's no
going back.
Arguments:
ByteVal - value to write to output
KeyByte - key value tied to the byte -- useful for debug
LineNum - line number from source file the byte resulted from
Returns:
0 - if successful
1 - failed due to memory allocation failure
--*/
{
IFR_BYTE *NewByte;
NewByte = (IFR_BYTE *)malloc (sizeof (IFR_BYTE));
if (NewByte == NULL) {
return 1;
}
memset ((char *)NewByte, 0, sizeof (IFR_BYTE));
NewByte->OpcodeByte = ByteVal;
NewByte->KeyByte = KeyByte;
NewByte->LineNum = LineNum;
//
// Add to the list
//
if (mIfrBytes == NULL) {
mIfrBytes = NewByte;
} else {
mLastIfrByte->Next = NewByte;
}
mLastIfrByte = NewByte;
mBytesWritten++;
return 0;
}
VOID
WriteStandardFileHeader (
FILE *OutFptr
)
/*++
Routine Description:
This function is invoked to emit a standard header to an
output text file.
Arguments:
OutFptr - file to write the header to
Returns:
None
--*/
{
UINT32 TempIndex;
for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) {
fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]);
}
//
// Write out the VFR compiler version
//
fprintf (OutFptr, "// VFR compiler version " VFR_COMPILER_VERSION "\n//\n");
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?