On 06/21/16 10:37, Gary Lin wrote:
> Hi,
> 
> When I booted latest OVMF with iPXE(*), none of the options under the
> network device menu worked. To be precise, when I chose the following
> options, instead of going to the configuration UI, it just jumped back
> to the main UI, i.e. the UI shows "Device Manger", "Boot Manager", and
> "Boot Maintenance Manager".
> 
> Device Manager -> Network Device List -> MAC:XX:XX:XX:XX:XX:XX -> 
>   iPXE (XX:XX:XX:XX:XX:XX)
>   VLAN Configuration
>   IPv4 Network Configuration
>   IPv6 Network Configuration
>   HTTP Boot Configuration
> 
> If I disable ipxe with "romfile=", all the options work again.
> The bisect result shows the symptom started from this commit:
> 
> commit 79c098b6d25d7aa06136de7c753516af6cddfa63
> Author: Ruiyu Ni <ruiyu...@intel.com>
> Date:   Mon Apr 18 09:47:55 2016 +0800
> 
>     OvmfPkg: Use MdeModulePkg/BDS
> 
> It seems related to the change between the new and old device manager.
> I also tried the iPXE git head (694c18addc) but it made no difference.
> Does anyone encounter this issue?
> 
> Cheers,
> 
> Gary Lin
> 
> (*) with the qemu options:
>   -netdev user,id=hostnet0 \
>   -device 
> virtio-net-pci,romfile=/usr/share/qemu/efi-virtio.rom,netdev=hostnet0
> 
>   I was using qemu 2.6.0 and iPXE within the qemu tarball.

I can reproduce this, and I have some partial results (well, more or less 
speculation).

* In the old device manager 
[IntelFrameworkModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c], the 
network device form -- where you see VLAN, IPv4, HTTP boot etc) -- is populated 
by the CallDeviceManager() function like this:

      } else if (mNextShowFormId == NETWORK_DEVICE_FORM_ID) {
        //
        // In network device form, only the selected mac address device need to 
be show.
        //
        HiiCreateGotoOpCode (
          StartOpCodeHandle,
          INVALID_FORM_ID, // destination form
          Token,
          TokenHelp,
          EFI_IFR_FLAG_CALLBACK, // question flags
          (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET) // question id
          );
      }

(the "//" comments are from me, just here). This function call creates a 
*callback* opcode, where the destination form is not specified. The opcode 
being generated on the current form is identified by the last parameter.

Given that this is a callback opcode / question, when the user hits Enter on 
it, the callback function is called again -- CallDeviceManager(). In this case, 
the following part of it becomes active, I think:

  //
  // We will have returned from processing a callback, selected
  // a target to display
  //
  if ((gCallbackKey >= DEVICE_KEY_OFFSET)) {
    ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
    Status = gFormBrowser2->SendForm (
                             gFormBrowser2,
                             &HiiHandles[gCallbackKey - DEVICE_KEY_OFFSET],
                             1,
                             GuidLists[gCallbackKey - DEVICE_KEY_OFFSET],
                             0,
                             NULL,
                             &ActionRequest
                             );

So practically, using the old device manager, each option on the device form 
(VLAN, IPv4, HTTP boot) is implemented by a separate callback, and when that 
option is picked, an explicit SendForm() request is made.

* The new device manager does not work like this, AIUI. There we have the 
CreateDeviceManagerForm() function 
[MdeModulePkg/Library/DeviceManagerUiLib/DeviceManager.c], which populates the 
device form as follows:

          } else if (NextShowFormId == NETWORK_DEVICE_FORM_ID) {
            //
            // In network device form, only the selected mac address device 
need to be show.
            //
            DevicePathStr = DmExtractDevicePathFromHiiHandle(HiiHandles[Index]);
            DevicePathId  = 0;
            if (DevicePathStr != NULL){
              DevicePathId =  HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
              FreePool(DevicePathStr);
            }
            HiiCreateGotoExOpCode (
              StartOpCodeHandle,
              0, // destination form
              Token,
              TokenHelp,
              0, // question flags
              (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET), //question id
              0, // point to the top of the destination form
              &FormSetGuid,    // ipxe formset
              DevicePathId // devpath associated with destination formset
            );

(Again, the "//" remarks are from me.)

This function call creates a different opcode / question for each entry (VLAN, 
IPv4, HTTP Boot, etc) on the device form. Most importantly: the opcode is *not* 
a callback. It is just a reference ("goto") opcode, where the destination is 
*apparently* identified by:
- the textual devpath identifying the target formset
- the target formset (by GUID)
- the target form within the target formset (by number)
- the target question within the target form (by number)

and the jump is made internally by the form browser, without calling back to 
the device manager driver code.

I believe that iPXE installs a HII formset that for some reason confuses this 
logic. I'll have to investigate more (e.g., write some debug code...) for a 
better understanding.

Thanks
Laszlo
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to