Enable new "ref5" opcode in browser.

Signed-off-by:ydong10
Reviewed-by:lgao4






git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11913 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
ydong10 2011-06-28 06:41:28 +00:00
parent 2ed77d0de5
commit 8ca6180f21
6 changed files with 236 additions and 147 deletions

View File

@ -1143,6 +1143,10 @@ ParseOpCodes (
ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME); ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
break; break;
case EFI_IFR_TYPE_REF:
ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
break;
case EFI_IFR_TYPE_OTHER: case EFI_IFR_TYPE_OTHER:
case EFI_IFR_TYPE_UNDEFINED: case EFI_IFR_TYPE_UNDEFINED:
case EFI_IFR_TYPE_ACTION: case EFI_IFR_TYPE_ACTION:
@ -1548,19 +1552,25 @@ ParseOpCodes (
case EFI_IFR_REF_OP: case EFI_IFR_REF_OP:
CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
ASSERT (CurrentStatement != NULL); ASSERT (CurrentStatement != NULL);
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED; Value = &CurrentStatement->HiiValue;
CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID)); Value->Type = EFI_IFR_TYPE_REF;
if (OpCodeLength >= sizeof (EFI_IFR_REF2)) { if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID)); CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
if (OpCodeLength >= sizeof (EFI_IFR_REF3)) { if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID)); CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
if (OpCodeLength >= sizeof (EFI_IFR_REF4)) { if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID)); CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
}
} }
} }
} }
CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
break; break;
case EFI_IFR_ONE_OF_OP: case EFI_IFR_ONE_OF_OP:

View File

@ -1162,6 +1162,14 @@ ProcessCallBackFunction (
default: default:
break; break;
} }
//
// According the spec, return value from call back of "changing" and
// "retrieve" should update to the question's temp buffer.
//
if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {
SetQuestionValue(Selection->FormSet,Selection->Form, Question,TRUE);
}
} else if (Status == EFI_UNSUPPORTED) { } else if (Status == EFI_UNSUPPORTED) {
// //
// If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it. // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
@ -1384,11 +1392,18 @@ SetupBrowser (
(Statement->Operand != EFI_IFR_PASSWORD_OP)) { (Statement->Operand != EFI_IFR_PASSWORD_OP)) {
Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE); Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
if ((EFI_ERROR (Status)) && (Status != EFI_UNSUPPORTED)) { if (Statement->Operand == EFI_IFR_REF_OP && Selection->Action != UI_ACTION_EXIT) {
// //
// Callback return error status other than EFI_UNSUPPORTED // Process dynamic update ref opcode.
// //
if (Statement->Operand == EFI_IFR_REF_OP) { if (!EFI_ERROR (Status)) {
Status = ProcessGotoOpCode(Statement, Selection, NULL, NULL);
}
//
// Callback return error status or status return from process goto opcode.
//
if (EFI_ERROR (Status)) {
// //
// Cross reference will not be taken // Cross reference will not be taken
// //

View File

@ -2643,6 +2643,16 @@ LoadFormConfig (
HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL); HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);
} }
//
// According the spec, ref opcode try to get value from call back with "retrieve" type.
//
if ((Question->Operand == EFI_IFR_REF_OP) && (FormSet->ConfigAccess != NULL)) {
Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);
if (EFI_ERROR (Status)) {
return Status;
}
}
// //
// Check whether EfiVarstore with CallBack can be got. // Check whether EfiVarstore with CallBack can be got.
// //

View File

@ -372,10 +372,6 @@ typedef struct {
UINT64 Step; UINT64 Step;
EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON
EFI_FORM_ID RefFormId; // for EFI_IFR_REF
EFI_QUESTION_ID RefQuestionId; // for EFI_IFR_REF2
EFI_GUID RefFormSetId; // for EFI_IFR_REF3
EFI_STRING_ID RefDevicePath; // for EFI_IFR_REF4
EFI_GUID RefreshGuid; // for EFI_IFR_REFRESH_ID EFI_GUID RefreshGuid; // for EFI_IFR_REFRESH_ID
// //

View File

@ -1649,6 +1649,175 @@ DevicePathToHiiHandle (
return HiiHandle; return HiiHandle;
} }
/**
Process the goto op code, update the info in the selection structure.
@param Statement The statement belong to goto op code.
@param Selection The selection info.
@param Repaint Whether need to repaint the menu.
@param NewLine Whether need to create new line.
@retval EFI_SUCCESS The menu process successfully.
@return Other value if the process failed.
**/
EFI_STATUS
ProcessGotoOpCode (
IN OUT FORM_BROWSER_STATEMENT *Statement,
IN OUT UI_MENU_SELECTION *Selection,
OUT BOOLEAN *Repaint,
OUT BOOLEAN *NewLine
)
{
CHAR16 *StringPtr;
UINTN BufferSize;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
CHAR16 TemStr[2];
UINT8 *DevicePathBuffer;
UINTN Index;
UINT8 DigitUint8;
FORM_BROWSER_FORM *RefForm;
EFI_INPUT_KEY Key;
EFI_STATUS Status;
UI_MENU_LIST *MenuList;
Status = EFI_SUCCESS;
if (Statement->HiiValue.Value.ref.DevicePath != 0) {
if (Selection->Form->ModalForm) {
return Status;
}
//
// Goto another Hii Package list
//
Selection->Action = UI_ACTION_REFRESH_FORMSET;
StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);
if (StringPtr == NULL) {
//
// No device path string not found, exit
//
Selection->Action = UI_ACTION_EXIT;
Selection->Statement = NULL;
return Status;
}
BufferSize = StrLen (StringPtr) / 2;
DevicePath = AllocatePool (BufferSize);
ASSERT (DevicePath != NULL);
//
// Convert from Device Path String to DevicePath Buffer in the reverse order.
//
DevicePathBuffer = (UINT8 *) DevicePath;
for (Index = 0; StringPtr[Index] != L'\0'; Index ++) {
TemStr[0] = StringPtr[Index];
DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
if (DigitUint8 == 0 && TemStr[0] != L'0') {
//
// Invalid Hex Char as the tail.
//
break;
}
if ((Index & 1) == 0) {
DevicePathBuffer [Index/2] = DigitUint8;
} else {
DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);
}
}
Selection->Handle = DevicePathToHiiHandle (DevicePath);
if (Selection->Handle == NULL) {
//
// If target Hii Handle not found, exit
//
Selection->Action = UI_ACTION_EXIT;
Selection->Statement = NULL;
return Status;
}
FreePool (StringPtr);
FreePool (DevicePath);
CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
Selection->FormId = Statement->HiiValue.Value.ref.FormId;
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
} else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {
if (Selection->Form->ModalForm) {
return Status;
}
//
// Goto another Formset, check for uncommitted data
//
Selection->Action = UI_ACTION_REFRESH_FORMSET;
CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
Selection->FormId = Statement->HiiValue.Value.ref.FormId;
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
} else if (Statement->HiiValue.Value.ref.FormId != 0) {
//
// Check whether target From is suppressed.
//
RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
Status = EvaluateExpression (Selection->FormSet, RefForm, RefForm->SuppressExpression);
if (EFI_ERROR (Status)) {
return Status;
}
if (RefForm->SuppressExpression->Result.Value.b) {
//
// Form is suppressed.
//
do {
CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
if (Repaint != NULL) {
*Repaint = TRUE;
}
return Status;
}
}
//
// Goto another form inside this formset,
//
Selection->Action = UI_ACTION_REFRESH_FORM;
//
// Link current form so that we can always go back when someone hits the ESC
//
MenuList = UiFindMenuList (&Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId);
if (MenuList == NULL && Selection->CurrentMenu != NULL) {
MenuList = UiAddMenuList (Selection->CurrentMenu, &Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId);
}
Selection->FormId = Statement->HiiValue.Value.ref.FormId;
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
} else if (Statement->HiiValue.Value.ref.QuestionId != 0) {
//
// Goto another Question
//
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
Selection->Action = UI_ACTION_REFRESH_FORM;
} else {
if (Repaint != NULL) {
*Repaint = TRUE;
}
if (NewLine != NULL) {
*NewLine = TRUE;
}
}
} else {
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
Selection->Action = UI_ACTION_REFRESH_FORM;
}
}
return Status;
}
/** /**
Display menu and wait for user to select one menu option, then return it. Display menu and wait for user to select one menu option, then return it.
If AutoBoot is enabled, then if user doesn't select any option, If AutoBoot is enabled, then if user doesn't select any option,
@ -1704,16 +1873,9 @@ UiDisplayMenu (
MENU_REFRESH_ENTRY *MenuUpdateEntry; MENU_REFRESH_ENTRY *MenuUpdateEntry;
UI_SCREEN_OPERATION ScreenOperation; UI_SCREEN_OPERATION ScreenOperation;
UINT8 MinRefreshInterval; UINT8 MinRefreshInterval;
UINTN BufferSize;
UINT16 DefaultId; UINT16 DefaultId;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
FORM_BROWSER_STATEMENT *Statement; FORM_BROWSER_STATEMENT *Statement;
CHAR16 TemStr[2];
UINT8 *DevicePathBuffer;
UINT8 DigitUint8;
UI_MENU_LIST *CurrentMenu; UI_MENU_LIST *CurrentMenu;
UI_MENU_LIST *MenuList;
FORM_BROWSER_FORM *RefForm;
UINTN ModalSkipColumn; UINTN ModalSkipColumn;
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR)); CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
@ -1736,7 +1898,6 @@ UiDisplayMenu (
NextMenuOption = NULL; NextMenuOption = NULL;
PreviousMenuOption = NULL; PreviousMenuOption = NULL;
SavedMenuOption = NULL; SavedMenuOption = NULL;
RefForm = NULL;
ModalSkipColumn = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 6; ModalSkipColumn = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 6;
ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
@ -2613,130 +2774,7 @@ UiDisplayMenu (
switch (Statement->Operand) { switch (Statement->Operand) {
case EFI_IFR_REF_OP: case EFI_IFR_REF_OP:
if (Statement->RefDevicePath != 0) { ProcessGotoOpCode(Statement, Selection, &Repaint, &NewLine);
if (Selection->Form->ModalForm) {
break;
}
//
// Goto another Hii Package list
//
Selection->Action = UI_ACTION_REFRESH_FORMSET;
StringPtr = GetToken (Statement->RefDevicePath, Selection->FormSet->HiiHandle);
if (StringPtr == NULL) {
//
// No device path string not found, exit
//
Selection->Action = UI_ACTION_EXIT;
Selection->Statement = NULL;
break;
}
BufferSize = StrLen (StringPtr) / 2;
DevicePath = AllocatePool (BufferSize);
ASSERT (DevicePath != NULL);
//
// Convert from Device Path String to DevicePath Buffer in the reverse order.
//
DevicePathBuffer = (UINT8 *) DevicePath;
for (Index = 0; StringPtr[Index] != L'\0'; Index ++) {
TemStr[0] = StringPtr[Index];
DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
if (DigitUint8 == 0 && TemStr[0] != L'0') {
//
// Invalid Hex Char as the tail.
//
break;
}
if ((Index & 1) == 0) {
DevicePathBuffer [Index/2] = DigitUint8;
} else {
DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);
}
}
Selection->Handle = DevicePathToHiiHandle (DevicePath);
if (Selection->Handle == NULL) {
//
// If target Hii Handle not found, exit
//
Selection->Action = UI_ACTION_EXIT;
Selection->Statement = NULL;
break;
}
FreePool (StringPtr);
FreePool (DevicePath);
CopyMem (&Selection->FormSetGuid, &Statement->RefFormSetId, sizeof (EFI_GUID));
Selection->FormId = Statement->RefFormId;
Selection->QuestionId = Statement->RefQuestionId;
} else if (!CompareGuid (&Statement->RefFormSetId, &gZeroGuid)) {
if (Selection->Form->ModalForm) {
break;
}
//
// Goto another Formset, check for uncommitted data
//
Selection->Action = UI_ACTION_REFRESH_FORMSET;
CopyMem (&Selection->FormSetGuid, &Statement->RefFormSetId, sizeof (EFI_GUID));
Selection->FormId = Statement->RefFormId;
Selection->QuestionId = Statement->RefQuestionId;
} else if (Statement->RefFormId != 0) {
//
// Check whether target From is suppressed.
//
RefForm = IdToForm (Selection->FormSet, Statement->RefFormId);
if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
Status = EvaluateExpression (Selection->FormSet, RefForm, RefForm->SuppressExpression);
if (EFI_ERROR (Status)) {
return Status;
}
if (RefForm->SuppressExpression->Result.Value.b) {
//
// Form is suppressed.
//
do {
CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
Repaint = TRUE;
break;
}
}
//
// Goto another form inside this formset,
//
Selection->Action = UI_ACTION_REFRESH_FORM;
//
// Link current form so that we can always go back when someone hits the ESC
//
MenuList = UiFindMenuList (&Selection->FormSetGuid, Statement->RefFormId);
if (MenuList == NULL) {
MenuList = UiAddMenuList (CurrentMenu, &Selection->FormSetGuid, Statement->RefFormId);
}
Selection->FormId = Statement->RefFormId;
Selection->QuestionId = Statement->RefQuestionId;
} else if (Statement->RefQuestionId != 0) {
//
// Goto another Question
//
Selection->QuestionId = Statement->RefQuestionId;
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
Selection->Action = UI_ACTION_REFRESH_FORM;
} else {
Repaint = TRUE;
NewLine = TRUE;
break;
}
}
break; break;
case EFI_IFR_ACTION_OP: case EFI_IFR_ACTION_OP:

View File

@ -331,6 +331,26 @@ FreeBrowserStrings (
VOID VOID
); );
/**
Process the goto op code, update the info in the selection structure.
@param Statement The statement belong to goto op code.
@param Selection The selection info.
@param Repaint Whether need to repaint the menu.
@param NewLine Whether need to create new line.
@retval EFI_SUCCESS The menu process successfully.
@return Other value if the process failed.
**/
EFI_STATUS
ProcessGotoOpCode (
IN OUT FORM_BROWSER_STATEMENT *Statement,
IN OUT UI_MENU_SELECTION *Selection,
OUT BOOLEAN *Repaint,
OUT BOOLEAN *NewLine
);
/** /**
The worker function that send the displays to the screen. On output, The worker function that send the displays to the screen. On output,
the selection made by user is returned. the selection made by user is returned.