Archive for the VFR Category

Note: UEFI 定義的四種VFR 的 VARSTORE的型別

Posted in BIOS, EFI/UEFI, VFR on 2011 年 05 月 26 日 by Kun-Yi

根據 28.2.5.6 Storage in UEFI 2.3 spec. 寫到UEFI目前可用在VFR Question的有 4種型別

1. Buffer Storage, 它是一個Buffer Storage Type, 用 EFI_IFR_VARSTORE OpCode表示, VFR 語法則是 varstore,  在Driver內要建立 EFI_HII_CONFIG_ACCESS_PROTOCOL 中的 ExtraceConfig() 與 RouteConfig(), 讓Framwork去存取 Var 的Buffer

2.  EFI Storage, 它是一種特定的 Buffer Storage, 用 EFI_IFR_EFIVARSTORE OpCode表示, VFR語法是 efivarstore, 在Driver內它是透過 EFI runtimer Service 中的 GetVariable()/SetVariable()存取變數, 因此這個會回存 NVRAM(Flash)

3. Name/Value Storage, 主要是一個 String 型別, 用 EFI_IFR_VARSTORE_NAME_VALUE Opcode表示, VFR語法是 namevaluevarstore,  在Driver內一樣要提供EFI_HII_CONFIG_ACCESS_PROTOCOL 來存取與儲存變數.

4. Date/Time Storage, 這就是Date/Time的專屬型別, 用 EFI_HII_DATE/EFI_HII_TIME OpCode表示,  VFR則直接就是data/time, 在Driver內就透過 GetTime()/SetTime(), GetWakeupTime()/SetWakeupTime() 存取之

當FormBrowse DXE使用 Buffer Storage 時, 會透過 EFI_HII_CONFIG_ACCESS_PROTOCOL,呼叫 ExtraceConfig(), 會透過Request 的EFI_STRING 將需要的 Var information 傳進來, 底下是該 Request String的一些 Example. 如果是一個Varstore的集合, 會有Byte offset, Width 的值是以Byte為單位, width為1時代表是一個byte. 而NameValue則直接傳進 Var Name

  • GUID=f4274aa000df424db55239511302113d&NAME=004d0079004900660072004e00560044006100740061&PATH=010414008db653c1fceb8e48b110662867745b877fff0400&OFFSET=DE&WIDTH=10
  • GUID=f4274aa000df424db55239511302113d&NAME=004d0079004900660072004e00560044006100740061&PATH=010414008db653c1fceb8e48b110662867745b877fff0400&OFFSET=EF&WIDTH=1
  • GUID=f4274aa000df424db55239511302113d&NAME=004d0079004900660072004e00560044006100740061&PATH=010414008db653c1fceb8e48b110662867745b877fff0400&OFFSET=D5&WIDTH=1&O
  • GUID=f4274aa000df424db55239511302113d&NAME=&PATH=010414008db653c1fceb8e48b110662867745b877fff0400&NameValueVar0&NameValueVar1&NameValueVar2

Buffer Storage 可以是Struct.Member 的變數形式, 在Form的 DXE Driver被載入時要自己將Struct 給初始化, 並透過 NewPackageList 去加入HII 的Database

Note: VFR with Dynamic Refresh

Posted in BIOS, EFI/UEFI, VFR on 2011 年 05 月 26 日 by Kun-Yi

在 EDKII 的 DriverSampleDxe 中可以看到 VFR.vfr中有 下面一個Form3的宣告, 重點的地方用Color標示

form formid = 3, title = STRING_TOKEN(STR_FORM3_TITLE);  // note formid is a variable (for readability) (UINT16) – also added Form to the line to signify the Op-Code

  suppressif  ideqval MyEfiVar == 111;
    text
      help = STRING_TOKEN(STR_TEXT_HELP),
      text = STRING_TOKEN(STR_TEXT_TEXT_1);
  endif;

  goto 1,
    prompt = STRING_TOKEN(STR_GOTO_FORM1), //MainSetupPage
    help   = STRING_TOKEN(STR_GOTO_HELP);

  numeric varid   = MyIfrNVData.DynamicRefresh,
          prompt  = STRING_TOKEN(STR_NUMERIC_MANUAL_PROMPT),
          help    = STRING_TOKEN(STR_NUMERIC_HELP0),
         flags   = INTERACTIVE,
          key     = 0x5678,
          minimum = 0,
          maximum = 0xff,
          step    = 0,
          default = 0,
          refresh interval = 3             // Refresh interval in seconds
  endnumeric;

然後在 DriverSample.c 中可以找到對應的Callback function “DriverCallBack()”, 在Dxe Entry Point“DriverSampleInit()”時, 透過 EFI_HII_CONFIG_ACCESS_PROTOCOL 來建立 CallBack link.

在CallBack 中是透過 EFI_BROWSER_ACTION_CHANGING 通知要 Refersh 了,  如果是原本 EDKII 的code, 會發現畫面一直閃, 原因是它會動態插入 Exit Item, 所以整個Form 會重畫! 只要簡單移除該段插入的code就可以, 如下

    case 0x5678:
      //
      // We will reach here once the Question is refreshed
      //
    #if 0 // By KunYi , remove dynamic add Exit Item
      //
      // Initialize the container for dynamic opcodes
      //
      StartOpCodeHandle = HiiAllocateOpCodeHandle ();
      ASSERT (StartOpCodeHandle != NULL);

      //
      // Create Hii Extend Label OpCode as the start opcode
      //
      StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
      StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
      StartLabel->Number       = LABEL_UPDATE2;

      HiiCreateActionOpCode (
        StartOpCodeHandle,                // Container for dynamic created opcodes
        0x1237,                           // Question ID
        STRING_TOKEN(STR_EXIT_TEXT),      // Prompt text
        STRING_TOKEN(STR_EXIT_TEXT),      // Help text
        EFI_IFR_FLAG_CALLBACK,            // Question flag
        0                                 // Action String ID
      );

      HiiUpdateForm (
        PrivateData->HiiHandle[0],  // HII handle
        &mFormSetGuid,              // Formset GUID
        0x3,                        // Form ID
        StartOpCodeHandle,          // Label for where to insert opcodes
        NULL                        // Insert data
        );

      HiiFreeOpCodeHandle (StartOpCodeHandle);
    #endif
      //
      // Refresh the Question value
      //
      PrivateData->Configuration.DynamicRefresh++;
      Status = gRT->SetVariable(
                      VariableName,
                      &mFormSetGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                      sizeof (DRIVER_SAMPLE_CONFIGURATION),
                      &PrivateData->Configuration
                      );

      //
      // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause
      // the first statement in Form 3 be suppressed
      //
      MyVarSize = 1;
      MyVar = 111;
      Status = gRT->SetVariable(
                      L"MyVar",
                      &mFormSetGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                      MyVarSize,
                      &MyVar
                      );
      break;

Note: VFR “formset”subclass in Phoenix SCT2

Posted in BIOS, EFI/UEFI, VFR on 2011 年 03 月 30 日 by Kun-Yi

see Section 1.6.25. formset in SCT 2.1 Volume 2 Document

formset

subclass-keyword := SETUP_APPLICATION | GENERAL_APPLICATION | FRONT_PAGE |

SINGLE_USE | uint16

Subclass support implement in .\System01\HII\FormBrowserLayout\Dxe\SystemHiiFormBrowserLayout.c

STATIC SCT_FORM_BROWSER_LAYOUT_LIST_PROTOCOL ProtocolTemplate [] = {
  {
    EFI_SETUP_APPLICATION_SUBCLASS, SCT_FORM_BROWSER_LAYOUT_STANDARD,
  },
  {
 EFI_FRONT_PAGE_SUBCLASS, SCT_FORM_BROWSER_LAYOUT_NO_HELP,
  },
  {
 EFI_SINGLE_USE_SUBCLASS, SCT_FORM_BROWSER_LAYOUT_POPUP,
  },
  {
 EFI_GENERAL_APPLICATION_SUBCLASS, SCT_FORM_BROWSER_LAYOUT_POPUP,
  },
  {
    SCT_FORM_BROWSER_LAYOUT_LIST_END,
    ZERO_GUID,
  },
};

Layout implement in .\System01\HII\FormBrowserLayout\Dxe

簡單講就是指定fromset的顯示的類型, 有標準型的Setup Application, 這個帶有Help欄, 還是一般的Applicaiton/SingleUse 都是PopUp 形式, 剩下一種是FRONT_PAGE, 就是把Standard的Help 欄位取消, 今天還發現SCT 2.1跟EDKII比起來有個缺點, EDKII 如果一個字串過長會自動摺疊到下一行, SCT2.1 目前沒有把這個做出來, 應該是要改 Presentation.c 吧,

EDK2 的 Presentation 在.\MdeModulePkg\Universal\SetupBrowserDxe 下, 這裡也可以看到 VFR compiling 過後產生的 IFR binary怎樣被Parse建構成每個視覺元件的資料結構.

而 VFR 語法的應用的 Sample在 \MdeModulePkg\Universal\DriverSampleDxe 下, 當跑NT32 emulation 時 進 Setup 選DeviceManager\BrowserTestcase Engine 就是會跑 DriverSample 進行測試