public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chang, Abner" <abner.chang@amd.com>
To: Nickle Wang <nicklew@nvidia.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Igor Kulchytskyy <igork@ami.com>, Nick Ramirez <nramirez@nvidia.com>
Subject: Re: [edk2-staging][PATCH 1/3] edk2-staging/RedfishPkg: Add interface to get question default value
Date: Mon, 12 Dec 2022 01:58:22 +0000	[thread overview]
Message-ID: <MN2PR12MB39669DCF2015BFAF814343B0EAE29@MN2PR12MB3966.namprd12.prod.outlook.com> (raw)
In-Reply-To: <20221207140910.124-1-nicklew@nvidia.com>

[AMD Official Use Only - General]

Hi Nickle, comments in line.

> -----Original Message-----
> From: Nickle Wang <nicklew@nvidia.com>
> Sent: Wednesday, December 7, 2022 10:09 PM
> To: devel@edk2.groups.io
> Cc: Chang, Abner <Abner.Chang@amd.com>; Igor Kulchytskyy
> <igork@ami.com>; Nick Ramirez <nramirez@nvidia.com>
> Subject: [edk2-staging][PATCH 1/3] edk2-staging/RedfishPkg: Add interface to
> get question default value
> 
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
> 
> 
> Implement GetQuestionDefault() in HiiUtilityLib. Caller can get question default
> value from this interface. GetQuestionDefault() is created and modifed from
> SetupBrowserDxe\Setup.c under MdeModulePkg.
> 
> Signed-off-by: Nickle Wang <nicklew@nvidia.com>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> Cc: Nick Ramirez <nramirez@nvidia.com>
> ---
>  RedfishPkg/Include/Library/HiiUtilityLib.h    |  31 +-
>  .../Library/HiiUtilityLib/HiiExpression.c     |  77 +++
>  .../Library/HiiUtilityLib/HiiExpression.h     |  23 +
>  .../HiiUtilityLib/HiiUtilityInternal.c        | 614 ++++++++++++++++++
>  4 files changed, 728 insertions(+), 17 deletions(-)
> 
> diff --git a/RedfishPkg/Include/Library/HiiUtilityLib.h
> b/RedfishPkg/Include/Library/HiiUtilityLib.h
> index 1f164ba49c..f4be485423 100644
> --- a/RedfishPkg/Include/Library/HiiUtilityLib.h
> +++ b/RedfishPkg/Include/Library/HiiUtilityLib.h
> @@ -3,6 +3,7 @@
> 
>    Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
>    (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +  Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -1168,28 +1169,24 @@ GetHiiExpressionDependency (
>    );
> 
>  /**
> -  Evaluate the result of a HII expression.
> -
> -  If Expression is NULL, then ASSERT.
> +  Get default value of question.
> 
> -  @param  FormSet                FormSet associated with this expression.
> -  @param  Form                   Form associated with this expression.
> -  @param  Expression             Expression to be evaluated.
> +  @param  FormSet                The form set.
> +  @param  Form                   The form.
> +  @param  Question               The question.
> +  @param  DefaultId              The Class of the default.
> +  @param  DefaultValue           The default value of given question.
No [in, out] for the Doxygen parameter/
> 
> -  @retval EFI_SUCCESS            The expression evaluated successfuly
> -  @retval EFI_NOT_FOUND          The Question which referenced by a
> QuestionId
> -                                 could not be found.
> -  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to
> grow the
> -                                 stack.
> -  @retval EFI_ACCESS_DENIED      The pop operation underflowed the stack
> -  @retval EFI_INVALID_PARAMETER  Syntax error with the Expression
> +  @retval EFI_SUCCESS            Question is reset to default value.
> 
>  **/
>  EFI_STATUS
> -HpEvaluateHiiExpression (
> -  IN     HII_FORMSET       *FormSet,
> -  IN     HII_FORM          *Form,
> -  IN OUT HII_EXPRESSION    *Expression
> +GetQuestionDefault (
> +  IN HII_FORMSET           *FormSet,
> +  IN HII_FORM              *Form,
> +  IN HII_STATEMENT         *Question,
> +  IN UINT16                DefaultId,
> +  OUT HII_STATEMENT_VALUE  *DefaultValue
>    );
> 
>  #endif // _HII_UTILITY_LIB_
> diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c
> b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c
> index 7111b40acf..c6954587f5 100644
> --- a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c
> +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c
> @@ -3,6 +3,7 @@
> 
>    Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
>    (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +  Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -1365,3 +1366,79 @@ GetHiiExpressionDependency (
>  Done:
>    return Status;
>  }
> +
> +/**
> +  Return the result of the expression list. Check the expression list
> +and
> +  return the highest priority express result.
> +  Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
> +
> +  @param  ExpList             The input expression list.
> +  @param  Evaluate            Whether need to evaluate the expression first.
> +  @param  FormSet             FormSet associated with this expression.
> +  @param  Form                Form associated with this expression.
Just realize we don't have [in,out] for Doxygen @param throughout this file. Please just fix @params in the new added function. We can fix all others later.
> +
> +  @retval EXPRESS_RESULT      Return the higher priority express result.
> +                              DisableIf > SuppressIf > GrayOutIf >
> + FALSE
> +
> +**/
> +EXPRESS_RESULT
> +EvaluateExpressionList (
> +  IN HII_EXPRESSION_LIST *ExpList,
> +  IN BOOLEAN Evaluate,
> +  IN HII_FORMSET *FormSet, OPTIONAL
> +  IN HII_FORM    *Form OPTIONAL
> +  )
> +{
> +  UINTN           Index;
> +  EXPRESS_RESULT  ReturnVal;
> +  EXPRESS_RESULT  CompareOne;
> +  EFI_STATUS      Status;
> +
> +  if (ExpList == NULL) {
> +    return ExpressFalse;
> +  }
> +
> +  ASSERT (ExpList->Signature == HII_EXPRESSION_LIST_SIGNATURE);  Index
> + = 0;
> +
> +  //
> +  // Check whether need to evaluate the expression first.
> +  //
> +  if (Evaluate) {
> +    while (ExpList->Count > Index) {
> +      Status = EvaluateHiiExpression (FormSet, Form, ExpList-
> >Expression[Index++]);
> +      if (EFI_ERROR (Status)) {
> +        return ExpressFalse;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Run the list of expressions.
> +  //
> +  ReturnVal = ExpressFalse;
> +  for (Index = 0; Index < ExpList->Count; Index++) {
> +    if (IsTrue (&ExpList->Expression[Index]->Result)) {
> +      switch (ExpList->Expression[Index]->Type) {
> +        case EFI_HII_EXPRESSION_SUPPRESS_IF:
> +          CompareOne = ExpressSuppress;
> +          break;
> +
> +        case EFI_HII_EXPRESSION_GRAY_OUT_IF:
> +          CompareOne = ExpressGrayOut;
> +          break;
> +
> +        case EFI_HII_EXPRESSION_DISABLE_IF:
> +          CompareOne = ExpressDisable;
> +          break;
> +
> +        default:
> +          return ExpressFalse;
> +      }
> +
> +      ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;
> +    }
> +  }
> +
> +  return ReturnVal;
> +}
> diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h
> b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h
> index e96c07b4de..25a3a44b48 100644
> --- a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h
> +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h
> @@ -3,6 +3,7 @@
> 
>    Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
>    (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +  Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -187,4 +188,26 @@ PopScope (
>    OUT UINT8    *Operand
>    );
> 
> +/**
> +  Return the result of the expression list. Check the expression list
> +and
> +  return the highest priority express result.
> +  Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
> +
> +  @param  ExpList             The input expression list.
> +  @param  Evaluate            Whether need to evaluate the expression first.
> +  @param  FormSet             FormSet associated with this expression.
> +  @param  Form                Form associated with this expression.
Same, [in,out] is miseed.
> +
> +  @retval EXPRESS_RESULT      Return the higher priority express result.
> +                              DisableIf > SuppressIf > GrayOutIf >
> + FALSE
> +
> +**/
> +EXPRESS_RESULT
> +EvaluateExpressionList (
> +  IN HII_EXPRESSION_LIST *ExpList,
> +  IN BOOLEAN Evaluate,
> +  IN HII_FORMSET *FormSet, OPTIONAL
> +  IN HII_FORM    *Form OPTIONAL
> +  );
> +
>  #endif
> diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c
> b/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c
> index 55b78315d1..b4dd61f360 100644
> --- a/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c
> +++ b/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c
> @@ -3,6 +3,7 @@
> 
>    Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
>    (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +  Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -5043,3 +5044,616 @@ Done:
> 
>    return Status;
>  }
> +
> +/**
> +  Set value of a data element in an Array by its Index.
> +
> +  @param  Array                  The data array.
> +  @param  Type                   Type of the data in this array.
> +  @param  Index                  Zero based index for data in this array.
> +  @param  Value                  The value to be set.
Same here.
> +
> +**/
> +VOID
> +SetArrayData (
> +  IN VOID    *Array,
> +  IN UINT8   Type,
> +  IN UINTN   Index,
> +  IN UINT64  Value
> +  )
> +{
> +  ASSERT (Array != NULL);
> +
> +  switch (Type) {
> +    case EFI_IFR_TYPE_NUM_SIZE_8:
> +      *(((UINT8 *)Array) + Index) = (UINT8)Value;
> +      break;
> +
> +    case EFI_IFR_TYPE_NUM_SIZE_16:
> +      *(((UINT16 *)Array) + Index) = (UINT16)Value;
> +      break;
> +
> +    case EFI_IFR_TYPE_NUM_SIZE_32:
> +      *(((UINT32 *)Array) + Index) = (UINT32)Value;
> +      break;
> +
> +    case EFI_IFR_TYPE_NUM_SIZE_64:
> +      *(((UINT64 *)Array) + Index) = (UINT64)Value;
> +      break;
> +
> +    default:
> +      break;
> +  }
> +}
> +
> +/**
> +  Search an Option of a Question by its value.
> +
> +  @param  Question               The Question
> +  @param  OptionValue            Value for Option to be searched.
> +
> +  @retval Pointer                Pointer to the found Option.
> +  @retval NULL                   Option not found.
> +
> +**/
> +HII_QUESTION_OPTION *
> +ValueToOption (
> +  IN HII_STATEMENT        *Question,
> +  IN HII_STATEMENT_VALUE  *OptionValue
> +  )
> +{
> +  LIST_ENTRY           *Link;
> +  HII_QUESTION_OPTION  *Option;
> +  EFI_HII_VALUE        Data1;
> +  EFI_HII_VALUE        Data2;
> +  INTN                 Result;
> +  EFI_STATUS           Status;
> +
> +  Status = HiiStatementValueToHiiValue (OptionValue, &Data1);
> + ASSERT_EFI_ERROR (Status);
> +
> +  Link = GetFirstNode (&Question->OptionListHead);  while (!IsNull
> + (&Question->OptionListHead, Link)) {
> +    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> +    Status = HiiStatementValueToHiiValue (&Option->Value, &Data2);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    if ((CompareHiiValue (&Data1, &Data2, &Result, NULL) == EFI_SUCCESS) &&
> (Result == 0)) {
> +      //
> +      // Check the suppressif condition, only a valid option can be return.
> +      //
> +      if ((Option->SuppressExpression == NULL) ||
> +          ((EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL,
> NULL) == ExpressFalse)))
> +      {
The open curly bracket should be at the end of condition check one line above.
Abner

> +        return Option;
> +      }
> +    }
> +
> +    Link = GetNextNode (&Question->OptionListHead, Link);  }
> +
> +  return NULL;
> +}
> +
> +/**
> +  Find the point in the ConfigResp string for this question.
> +
> +  @param  Question               The question.
> +  @param  ConfigResp             Get ConfigResp string.
Same here. Please check all @param in the new added function in this file.
> +
> +  @retval  point to the offset where is for this question.
> +
> +**/
> +CHAR16 *
> +GetOffsetFromConfigResp (
> +  IN HII_STATEMENT  *Question,
> +  IN CHAR16         *ConfigResp
> +  )
> +{
> +  CHAR16  *RequestElement;
> +  CHAR16  *BlockData;
> +
> +  //
> +  // Type is EFI_HII_VARSTORE_NAME_VALUE.
> +  //
> +  if (Question->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
> +    RequestElement = StrStr (ConfigResp, Question->VariableName);
> +    if (RequestElement != NULL) {
> +      //
> +      // Skip the "VariableName=" field.
> +      //
> +      RequestElement += StrLen (Question->VariableName) + 1;
> +    }
> +
> +    return RequestElement;
> +  }
> +
> +  //
> +  // Type is EFI_HII_VARSTORE_EFI_VARIABLE or
> + EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
> +  //
> +
> +  //
> +  // Convert all hex digits in ConfigResp to lower case before searching.
> +  //
> +  HiiToLower (ConfigResp);
> +
> +  //
> +  // 1. Directly use Question->BlockName to find.
> +  //
> +  RequestElement = StrStr (ConfigResp, Question->BlockName);  if
> + (RequestElement != NULL) {
> +    //
> +    // Skip the "Question->BlockName&VALUE=" field.
> +    //
> +    RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");
> +    return RequestElement;
> +  }
> +
> +  //
> +  // 2. Change all hex digits in Question->BlockName to lower and compare
> again.
> +  //
> +  BlockData = AllocateCopyPool (StrSize (Question->BlockName),
> + Question->BlockName);  ASSERT (BlockData != NULL);  HiiToLower
> + (BlockData);  RequestElement = StrStr (ConfigResp, BlockData);
> + FreePool (BlockData);
> +
> +  if (RequestElement != NULL) {
> +    //
> +    // Skip the "Question->BlockName&VALUE=" field.
> +    //
> +    RequestElement += StrLen (Question->BlockName) + StrLen
> + (L"&VALUE=");  }
> +
> +  return RequestElement;
> +}
> +
> +/**
> +  Get Question default value from AltCfg string.
> +
> +  @param  FormSet                The form set.
> +  @param  Form                   The form
> +  @param  Question               The question.
> +  @param  DefaultValue           Default value.
> +
> +  @retval EFI_SUCCESS            Question is reset to default value.
> +
> +**/
> +EFI_STATUS
> +GetDefaultValueFromAltCfg (
> +  IN     HII_FORMSET          *FormSet,
> +  IN     HII_FORM             *Form,
> +  IN     HII_STATEMENT        *Question,
> +  OUT    HII_STATEMENT_VALUE  *DefaultValue
> +  )
> +{
> +  HII_FORMSET_STORAGE      *Storage;
> +  CHAR16                   *ConfigResp;
> +  CHAR16                   *Value;
> +  LIST_ENTRY               *Link;
> +  HII_FORM_CONFIG_REQUEST  *ConfigInfo;
> +
> +  Storage = Question->Storage;
> +  if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE))
> {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Try to get AltCfg string from form. If not found it, then  // try
> + to get it from formset.
> +  //
> +  ConfigResp = NULL;
> +  Link       = GetFirstNode (&Form->ConfigRequestHead);
> +  while (!IsNull (&Form->ConfigRequestHead, Link)) {
> +    ConfigInfo = HII_FORM_CONFIG_REQUEST_FROM_LINK (Link);
> +    Link       = GetNextNode (&Form->ConfigRequestHead, Link);
> +
> +    if (Storage == ConfigInfo->Storage) {
> +      ConfigResp = ConfigInfo->ConfigAltResp;
> +      break;
> +    }
> +  }
> +
> +  if (ConfigResp == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Value = GetOffsetFromConfigResp (Question, ConfigResp);  if (Value ==
> + NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return BufferToValue (Question, Value, DefaultValue); }
> +
> +/**
> +  Get default Id value used for browser.
> +
> +  @param  DefaultId              The default id value used by hii.
> +
> +  @retval Browser used default value.
> +
> +**/
> +INTN
> +GetDefaultIdForCallBack (
> +  UINTN  DefaultId
> +  )
> +{
> +  if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {
> +    return EFI_BROWSER_ACTION_DEFAULT_STANDARD;
> +  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
> +    return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;
> +  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {
> +    return EFI_BROWSER_ACTION_DEFAULT_SAFE;
> +  } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN) &&
> (DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000)) {
> +    return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId -
> +EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;
> +  } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN) &&
> (DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000)) {
> +    return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId -
> +EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;
> +  } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN) &&
> (DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000)) {
> +    return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId -
> +EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;
> +  } else {
> +    return -1;
> +  }
> +}
> +
> +/**
> +  Get default value of question.
> +
> +  @param  FormSet                The form set.
> +  @param  Form                   The form.
> +  @param  Question               The question.
> +  @param  DefaultId              The Class of the default.
> +  @param  DefaultValue           The default value of given question.
> +
> +  @retval EFI_SUCCESS            Question is reset to default value.
> +
> +**/
> +EFI_STATUS
> +GetQuestionDefault (
> +  IN HII_FORMSET           *FormSet,
> +  IN HII_FORM              *Form,
> +  IN HII_STATEMENT         *Question,
> +  IN UINT16                DefaultId,
> +  OUT HII_STATEMENT_VALUE  *DefaultValue
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  LIST_ENTRY                      *Link;
> +  HII_QUESTION_DEFAULT            *Default;
> +  HII_QUESTION_OPTION             *Option;
> +  HII_STATEMENT_VALUE             *HiiValue;
> +  UINT8                           Index;
> +  EFI_STRING                      StrValue;
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
> +  EFI_BROWSER_ACTION_REQUEST      ActionRequest;
> +  INTN                            Action;
> +  EFI_IFR_TYPE_VALUE              *TypeValue;
> +  UINT16                          OriginalDefaultId;
> +  HII_FORMSET_DEFAULTSTORE        *DefaultStore;
> +  LIST_ENTRY                      *DefaultLink;
> +
> +  if ((FormSet == NULL) || (Form == NULL) || (Question == NULL) ||
> (DefaultValue == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status            = EFI_NOT_FOUND;
> +  StrValue          = NULL;
> +  OriginalDefaultId = DefaultId;
> +  DefaultLink       = GetFirstNode (&FormSet->DefaultStoreListHead);
> +
> +  //
> +  // Statement don't have storage, skip them  //  if
> + (Question->QuestionId == 0) {
> +    return Status;
> +  }
> +
> +  //
> +  // There are Five ways to specify default value for a Question:
> +  //  1, use call back function (highest priority)
> +  //  2, use ExtractConfig function
> +  //  3, use nested EFI_IFR_DEFAULT
> +  //  4, set flags of EFI_ONE_OF_OPTION (provide Standard and
> +Manufacturing default)
> +  //  5, set flags of EFI_IFR_CHECKBOX (provide Standard and
> +Manufacturing default) (lowest priority)
> +  //
> +  CopyMem (DefaultValue, &Question->Value, sizeof
> +(HII_STATEMENT_VALUE));
> +ReGetDefault:
> +  HiiValue  = DefaultValue;
> +  TypeValue = &HiiValue->Value;
> +  if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {
> +    //
> +    // For orderedlist, need to pass the BufferValue to Callback function.
> +    //
> +    DefaultValue->BufferLen = Question->Value.BufferLen;
> +    DefaultValue->Buffer    = AllocateZeroPool (DefaultValue->BufferLen);
> +    ASSERT (DefaultValue->Buffer != NULL);
> +    if (DefaultValue->Buffer == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    TypeValue = (EFI_IFR_TYPE_VALUE *)DefaultValue->Buffer;  }
> +
> +  //
> +  // Get Question defaut value from call back function.
> +  // The string type of question cause HII driver to set string to its default value.
> +  // So, we don't do this otherwise it will actually set question to default value.
> +  // We only want to get default value of question.
> +  //
> +  if (HiiValue->Type != EFI_IFR_TYPE_STRING) {
> +    ConfigAccess = FormSet->ConfigAccess;
> +    Action       = GetDefaultIdForCallBack (DefaultId);
> +    if ((Action > 0) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) !=
> 0) && (ConfigAccess != NULL)) {
> +      ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
> +      Status        = ConfigAccess->Callback (
> +                                      ConfigAccess,
> +                                      Action,
> +                                      Question->QuestionId,
> +                                      HiiValue->Type,
> +                                      TypeValue,
> +                                      &ActionRequest
> +                                      );
> +      if (!EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Get default value from altcfg string.
> +  //
> +  if (ConfigAccess != NULL) {
> +    Status = GetDefaultValueFromAltCfg (FormSet, Form, Question,
> DefaultValue);
> +    if (!EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  //
> +  // EFI_IFR_DEFAULT has highest priority  //  if (!IsListEmpty
> + (&Question->DefaultListHead)) {
> +    Link = GetFirstNode (&Question->DefaultListHead);
> +    while (!IsNull (&Question->DefaultListHead, Link)) {
> +      Default = HII_QUESTION_DEFAULT_FROM_LINK (Link);
> +
> +      if (Default->DefaultId == DefaultId) {
> +        if (Default->ValueExpression != NULL) {
> +          //
> +          // Default is provided by an Expression, evaluate it
> +          //
> +          Status = EvaluateHiiExpression (FormSet, Form, Default-
> >ValueExpression);
> +          if (EFI_ERROR (Status)) {
> +            return Status;
> +          }
> +
> +          if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {
> +            ASSERT (HiiValue->Type == EFI_IFR_TYPE_BUFFER && DefaultValue-
> >Buffer != NULL);
> +            if (DefaultValue->BufferLen > Default->ValueExpression-
> >Result.BufferLen) {
> +              CopyMem (DefaultValue->Buffer, Default->ValueExpression-
> >Result.Buffer, Default->ValueExpression->Result.BufferLen);
> +              DefaultValue->BufferLen = Default->ValueExpression-
> >Result.BufferLen;
> +            } else {
> +              CopyMem (DefaultValue->Buffer, Default->ValueExpression-
> >Result.Buffer, DefaultValue->BufferLen);
> +            }
> +
> +            FreePool (Default->ValueExpression->Result.Buffer);
> +          }
> +
> +          HiiValue->Type = Default->ValueExpression->Result.Type;
> +          CopyMem (&HiiValue->Value, &Default->ValueExpression->Result.Value,
> sizeof (EFI_IFR_TYPE_VALUE));
> +        } else {
> +          //
> +          // Default value is embedded in EFI_IFR_DEFAULT
> +          //
> +          if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {
> +            ASSERT (HiiValue->Buffer != NULL);
> +            CopyMem (HiiValue->Buffer, Default->Value.Buffer, Default-
> >Value.BufferLen);
> +          } else {
> +            CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));
> +          }
> +        }
> +
> +        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
> +          StrValue = HiiGetString (FormSet->HiiHandle, HiiValue->Value.string,
> NULL);
> +          if (StrValue == NULL) {
> +            return EFI_NOT_FOUND;
> +          }
> +
> +          if (DefaultValue->BufferLen > StrSize (StrValue)) {
> +            ZeroMem (DefaultValue->Buffer, DefaultValue->BufferLen);
> +            CopyMem (DefaultValue->Buffer, StrValue, StrSize (StrValue));
> +          } else {
> +            CopyMem (DefaultValue->Buffer, StrValue, DefaultValue->BufferLen);
> +          }
> +        }
> +
> +        return EFI_SUCCESS;
> +      }
> +
> +      Link = GetNextNode (&Question->DefaultListHead, Link);
> +    }
> +  }
> +
> +  //
> +  // EFI_ONE_OF_OPTION
> +  //
> +  if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question-
> >OptionListHead)) {
> +    if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
> +      //
> +      // OneOfOption could only provide Standard and Manufacturing default
> +      //
> +      Link = GetFirstNode (&Question->OptionListHead);
> +      while (!IsNull (&Question->OptionListHead, Link)) {
> +        Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +        Link   = GetNextNode (&Question->OptionListHead, Link);
> +
> +        if ((Option->SuppressExpression != NULL) &&
> +            (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL,
> NULL) != ExpressFalse))
> +        {
> +          continue;
> +        }
> +
> +        if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags
> & EFI_IFR_OPTION_DEFAULT) != 0)) ||
> +            ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) &&
> ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))
> +            )
> +        {
> +          CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));
> +
> +          return EFI_SUCCESS;
> +        }
> +      }
> +    }
> +  }
> +
> +  //
> +  // EFI_IFR_CHECKBOX - lowest priority  //  if (Question->Operand ==
> + EFI_IFR_CHECKBOX_OP) {
> +    if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
> +      //
> +      // Checkbox could only provide Standard and Manufacturing default
> +      //
> +      if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question-
> >ExtraData.Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) ||
> +          ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) &&
> ((Question->ExtraData.Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))
> +          )
> +      {
> +        HiiValue->Value.b = TRUE;
> +      }
> +
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  //
> +  // For question without default value for current default Id, we try to re-get
> the default value form other default id in the DefaultStoreList.
> +  // If get, will exit the function, if not, will choose next default id in the
> DefaultStoreList.
> +  // The default id in DefaultStoreList are in ascending order to make sure
> choose the smallest default id every time.
> +  //
> +  while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {
> +    DefaultStore = HII_FORMSET_DEFAULTSTORE_FROM_LINK (DefaultLink);
> +    DefaultLink  = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);
> +    DefaultId    = DefaultStore->DefaultId;
> +    if (DefaultId == OriginalDefaultId) {
> +      continue;
> +    }
> +
> +    goto ReGetDefault;
> +  }
> +
> +  //
> +  // For Questions without default value for all the default id in the
> DefaultStoreList.
> +  //
> +  Status = EFI_NOT_FOUND;
> +  switch (Question->Operand) {
> +    case EFI_IFR_CHECKBOX_OP:
> +      HiiValue->Value.b = FALSE;
> +      Status            = EFI_SUCCESS;
> +      break;
> +
> +    case EFI_IFR_NUMERIC_OP:
> +      //
> +      // Take minimum value as numeric default value
> +      //
> +      if ((Question->ExtraData.NumData.Flags & EFI_IFR_DISPLAY) == 0) {
> +        //
> +        // In EFI_IFR_DISPLAY_INT_DEC type, should check value with int* type.
> +        //
> +        switch (Question->ExtraData.NumData.Flags & EFI_IFR_NUMERIC_SIZE) {
> +          case EFI_IFR_NUMERIC_SIZE_1:
> +            if (((INT8)HiiValue->Value.u8 < (INT8)Question-
> >ExtraData.NumData.Minimum) || ((INT8)HiiValue->Value.u8 > (INT8)Question-
> >ExtraData.NumData.Maximum)) {
> +              HiiValue->Value.u8 = (UINT8)Question->ExtraData.NumData.Minimum;
> +              Status             = EFI_SUCCESS;
> +            }
> +
> +            break;
> +          case EFI_IFR_NUMERIC_SIZE_2:
> +            if (((INT16)HiiValue->Value.u16 < (INT16)Question-
> >ExtraData.NumData.Minimum) || ((INT16)HiiValue->Value.u16 >
> (INT16)Question->ExtraData.NumData.Maximum)) {
> +              HiiValue->Value.u16 = (UINT16)Question-
> >ExtraData.NumData.Minimum;
> +              Status              = EFI_SUCCESS;
> +            }
> +
> +            break;
> +          case EFI_IFR_NUMERIC_SIZE_4:
> +            if (((INT32)HiiValue->Value.u32 < (INT32)Question-
> >ExtraData.NumData.Minimum) || ((INT32)HiiValue->Value.u32 >
> (INT32)Question->ExtraData.NumData.Maximum)) {
> +              HiiValue->Value.u32 = (UINT32)Question-
> >ExtraData.NumData.Minimum;
> +              Status              = EFI_SUCCESS;
> +            }
> +
> +            break;
> +          case EFI_IFR_NUMERIC_SIZE_8:
> +            if (((INT64)HiiValue->Value.u64 < (INT64)Question-
> >ExtraData.NumData.Minimum) || ((INT64)HiiValue->Value.u64 >
> (INT64)Question->ExtraData.NumData.Maximum)) {
> +              HiiValue->Value.u64 = Question->ExtraData.NumData.Minimum;
> +              Status              = EFI_SUCCESS;
> +            }
> +
> +            break;
> +          default:
> +            break;
> +        }
> +      } else {
> +        if ((HiiValue->Value.u64 < Question->ExtraData.NumData.Minimum) ||
> (HiiValue->Value.u64 > Question->ExtraData.NumData.Maximum)) {
> +          HiiValue->Value.u64 = Question->ExtraData.NumData.Minimum;
> +          Status              = EFI_SUCCESS;
> +        }
> +      }
> +
> +      break;
> +
> +    case EFI_IFR_ONE_OF_OP:
> +      //
> +      // Take first oneof option as oneof's default value
> +      //
> +      if (ValueToOption (Question, HiiValue) == NULL) {
> +        Link = GetFirstNode (&Question->OptionListHead);
> +        while (!IsNull (&Question->OptionListHead, Link)) {
> +          Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +          Link   = GetNextNode (&Question->OptionListHead, Link);
> +
> +          if ((Option->SuppressExpression != NULL) &&
> +              (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL,
> NULL) != ExpressFalse))
> +          {
> +            continue;
> +          }
> +
> +          CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));
> +          Status = EFI_SUCCESS;
> +          break;
> +        }
> +      }
> +
> +      break;
> +
> +    case EFI_IFR_ORDERED_LIST_OP:
> +      //
> +      // Take option sequence in IFR as ordered list's default value
> +      //
> +      Index = 0;
> +      Link  = GetFirstNode (&Question->OptionListHead);
> +      while (!IsNull (&Question->OptionListHead, Link)) {
> +        Status = EFI_SUCCESS;
> +        Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +        Link   = GetNextNode (&Question->OptionListHead, Link);
> +
> +        if ((Option->SuppressExpression != NULL) &&
> +            (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL,
> NULL) != ExpressFalse))
> +        {
> +          continue;
> +        }
> +
> +        SetArrayData (DefaultValue->Buffer, Question->Value.Type,
> + Index, Option->Value.Value.u64);
> +
> +        Index++;
> +        if (Index >= Question->ExtraData.OrderListData.MaxContainers) {
> +          break;
> +        }
> +      }
> +
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return Status;
> +}
> --
> 2.38.1.windows.1

      reply	other threads:[~2022-12-12  1:58 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-07 14:09 [edk2-staging][PATCH 1/3] edk2-staging/RedfishPkg: Add interface to get question default value Nickle Wang
2022-12-12  1:58 ` Chang, Abner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=MN2PR12MB39669DCF2015BFAF814343B0EAE29@MN2PR12MB3966.namprd12.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox