Home | History | Annotate | Download | only in HttpBootDxe
      1 /** @file
      2   UEFI HTTP boot driver's private data structure and interfaces declaration.
      3 
      4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials are licensed and made available under
      6 the terms and conditions of the BSD License that accompanies this distribution.
      7 The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php.
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #ifndef __EFI_HTTP_BOOT_DXE_H__
     16 #define __EFI_HTTP_BOOT_DXE_H__
     17 
     18 #include <Uefi.h>
     19 
     20 //
     21 // Libraries
     22 //
     23 #include <Library/UefiBootServicesTableLib.h>
     24 #include <Library/MemoryAllocationLib.h>
     25 #include <Library/BaseLib.h>
     26 #include <Library/UefiLib.h>
     27 #include <Library/DevicePathLib.h>
     28 #include <Library/DebugLib.h>
     29 #include <Library/NetLib.h>
     30 #include <Library/HttpLib.h>
     31 
     32 //
     33 // UEFI Driver Model Protocols
     34 //
     35 #include <Protocol/DriverBinding.h>
     36 #include <Protocol/ComponentName2.h>
     37 #include <Protocol/ComponentName.h>
     38 
     39 //
     40 // Consumed Protocols
     41 //
     42 #include <Protocol/NetworkInterfaceIdentifier.h>
     43 #include <Protocol/Dhcp4.h>
     44 #include <Protocol/Dhcp6.h>
     45 #include <Protocol/Dns6.h>
     46 #include <Protocol/Http.h>
     47 #include <Protocol/Ip4Config2.h>
     48 #include <Protocol/Ip6Config.h>
     49 //
     50 // Produced Protocols
     51 //
     52 #include <Protocol/LoadFile.h>
     53 
     54 //
     55 // Driver Version
     56 //
     57 #define HTTP_BOOT_DXE_VERSION  0xa
     58 
     59 //
     60 // Protocol instances
     61 //
     62 extern EFI_DRIVER_BINDING_PROTOCOL  gHttpBootDxeDriverBinding;
     63 extern EFI_COMPONENT_NAME2_PROTOCOL gHttpBootDxeComponentName2;
     64 extern EFI_COMPONENT_NAME_PROTOCOL  gHttpBootDxeComponentName;
     65 
     66 //
     67 // Private data structure
     68 //
     69 typedef struct _HTTP_BOOT_PRIVATE_DATA      HTTP_BOOT_PRIVATE_DATA;
     70 typedef struct _HTTP_BOOT_VIRTUAL_NIC       HTTP_BOOT_VIRTUAL_NIC;
     71 
     72 //
     73 // Include files with internal function prototypes
     74 //
     75 #include "HttpBootComponentName.h"
     76 #include "HttpBootDhcp4.h"
     77 #include "HttpBootDhcp6.h"
     78 #include "HttpBootImpl.h"
     79 #include "HttpBootSupport.h"
     80 #include "HttpBootClient.h"
     81 
     82 typedef union {
     83   HTTP_BOOT_DHCP4_PACKET_CACHE              Dhcp4;
     84   HTTP_BOOT_DHCP6_PACKET_CACHE              Dhcp6;
     85 } HTTP_BOOT_DHCP_PACKET_CACHE;
     86 
     87 struct _HTTP_BOOT_VIRTUAL_NIC {
     88   UINT32                                    Signature;
     89   EFI_HANDLE                                Controller;
     90   EFI_LOAD_FILE_PROTOCOL                    LoadFile;
     91   EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
     92   HTTP_BOOT_PRIVATE_DATA                    *Private;
     93 };
     94 
     95 struct _HTTP_BOOT_PRIVATE_DATA {
     96   UINT32                                    Signature;
     97   EFI_HANDLE                                Controller;
     98   EFI_HANDLE                                Image;
     99 
    100   HTTP_BOOT_VIRTUAL_NIC                     *Ip4Nic;
    101   HTTP_BOOT_VIRTUAL_NIC                     *Ip6Nic;
    102 
    103   //
    104   // Cousumed children
    105   //
    106   EFI_HANDLE                                Ip6Child;
    107   EFI_HANDLE                                Dhcp4Child;
    108   EFI_HANDLE                                Dhcp6Child;
    109   HTTP_IO                                   HttpIo;
    110   BOOLEAN                                   HttpCreated;
    111 
    112   //
    113   // Consumed protocol
    114   //
    115   EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
    116   EFI_IP6_PROTOCOL                          *Ip6;
    117   EFI_IP4_CONFIG2_PROTOCOL                  *Ip4Config2;
    118   EFI_IP6_CONFIG_PROTOCOL                   *Ip6Config;
    119   EFI_DHCP4_PROTOCOL                        *Dhcp4;
    120   EFI_DHCP6_PROTOCOL                        *Dhcp6;
    121   EFI_DEVICE_PATH_PROTOCOL                  *ParentDevicePath;
    122 
    123 
    124   //
    125   // Produced protocol
    126   //
    127   EFI_LOAD_FILE_PROTOCOL                    LoadFile;
    128   EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
    129   UINT32                                    Id;
    130 
    131   //
    132   // Mode data
    133   //
    134   BOOLEAN                                   UsingIpv6;
    135   BOOLEAN                                   Started;
    136   EFI_IP_ADDRESS                            StationIp;
    137   EFI_IP_ADDRESS                            SubnetMask;
    138   EFI_IP_ADDRESS                            GatewayIp;
    139   EFI_IP_ADDRESS                            ServerIp;
    140   UINT16                                    Port;
    141   CHAR8                                     *BootFileUri;
    142   VOID                                      *BootFileUriParser;
    143   UINTN                                     BootFileSize;
    144   BOOLEAN                                   NoGateway;
    145 
    146   //
    147   // Cached HTTP data
    148   //
    149   LIST_ENTRY                                CacheList;
    150 
    151   //
    152   // Cached DHCP offer
    153   //
    154   // OfferIndex records the index of DhcpOffer[] buffer, and OfferCount records the num of each type of offer.
    155   //
    156   // It supposed that
    157   //
    158   //   OfferNum:    8
    159   //   OfferBuffer: [ProxyNameUri, DhcpNameUri, DhcpIpUri, ProxyNameUri, ProxyIpUri, DhcpOnly, DhcpIpUri, DhcpNameUriDns]
    160   //   (OfferBuffer is 0-based.)
    161   //
    162   // And assume that (DhcpIpUri is the first priority actually.)
    163   //
    164   //   SelectIndex:     5
    165   //   SelectProxyType: HttpOfferTypeProxyIpUri
    166   //   (SelectIndex is 1-based, and 0 means no one is selected.)
    167   //
    168   // So it should be
    169   //
    170   //                 DhcpIpUri  DhcpNameUriDns  DhcpDns  DhcpOnly  ProxyNameUri  ProxyIpUri  DhcpNameUri
    171   //   OfferCount:  [       2,              1,       0,        1,            2,          1,            1]
    172   //
    173   //   OfferIndex: {[       2,              7,       0,        5,            0,         *4,            1]
    174   //                [       6,              0,       0,        0,            3,          0,            0]
    175   //                [       0,              0,       0,        0,            0,          0,            0]
    176   //                ...                                                                                 ]}
    177   //   (OfferIndex is 0-based.)
    178   //
    179   //
    180   UINT32                                    SelectIndex;
    181   UINT32                                    SelectProxyType;
    182   HTTP_BOOT_DHCP_PACKET_CACHE               OfferBuffer[HTTP_BOOT_OFFER_MAX_NUM];
    183   UINT32                                    OfferNum;
    184   UINT32                                    OfferCount[HttpOfferTypeMax];
    185   UINT32                                    OfferIndex[HttpOfferTypeMax][HTTP_BOOT_OFFER_MAX_NUM];
    186 };
    187 
    188 #define HTTP_BOOT_PRIVATE_DATA_SIGNATURE          SIGNATURE_32 ('H', 'B', 'P', 'D')
    189 #define HTTP_BOOT_VIRTUAL_NIC_SIGNATURE           SIGNATURE_32 ('H', 'B', 'V', 'N')
    190 #define HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE(a)   CR (a, HTTP_BOOT_PRIVATE_DATA, LoadFile, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
    191 #define HTTP_BOOT_PRIVATE_DATA_FROM_ID(a)         CR (a, HTTP_BOOT_PRIVATE_DATA, Id, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
    192 #define HTTP_BOOT_VIRTUAL_NIC_FROM_LOADFILE(a)    CR (a, HTTP_BOOT_VIRTUAL_NIC, LoadFile, HTTP_BOOT_VIRTUAL_NIC_SIGNATURE)
    193 extern EFI_LOAD_FILE_PROTOCOL               gHttpBootDxeLoadFile;
    194 
    195 /**
    196   Tests to see if this driver supports a given controller. If a child device is provided,
    197   it further tests to see if this driver supports creating a handle for the specified child device.
    198 
    199   This function checks to see if the driver specified by This supports the device specified by
    200   ControllerHandle. Drivers will typically use the device path attached to
    201   ControllerHandle and/or the services from the bus I/O abstraction attached to
    202   ControllerHandle to determine if the driver supports ControllerHandle. This function
    203   may be called many times during platform initialization. In order to reduce boot times, the tests
    204   performed by this function must be very small, and take as little time as possible to execute. This
    205   function must not change the state of any hardware devices, and this function must be aware that the
    206   device specified by ControllerHandle may already be managed by the same driver or a
    207   different driver. This function must match its calls to AllocatePages() with FreePages(),
    208   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
    209   Because ControllerHandle may have been previously started by the same driver, if a protocol is
    210   already in the opened state, then it must not be closed with CloseProtocol(). This is required
    211   to guarantee the state of ControllerHandle is not modified by this function.
    212 
    213   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    214   @param[in]  ControllerHandle     The handle of the controller to test. This handle
    215                                    must support a protocol interface that supplies
    216                                    an I/O abstraction to the driver.
    217   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    218                                    parameter is ignored by device drivers, and is optional for bus
    219                                    drivers. For bus drivers, if this parameter is not NULL, then
    220                                    the bus driver must determine if the bus controller specified
    221                                    by ControllerHandle and the child controller specified
    222                                    by RemainingDevicePath are both supported by this
    223                                    bus driver.
    224 
    225   @retval EFI_SUCCESS              The device specified by ControllerHandle and
    226                                    RemainingDevicePath is supported by the driver specified by This.
    227   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
    228                                    RemainingDevicePath is already being managed by the driver
    229                                    specified by This.
    230   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
    231                                    RemainingDevicePath is already being managed by a different
    232                                    driver or an application that requires exclusive access.
    233                                    Currently not implemented.
    234   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
    235                                    RemainingDevicePath is not supported by the driver specified by This.
    236 **/
    237 EFI_STATUS
    238 EFIAPI
    239 HttpBootIp4DxeDriverBindingSupported (
    240   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    241   IN EFI_HANDLE                   ControllerHandle,
    242   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    243   );
    244 
    245 /**
    246   Starts a device controller or a bus controller.
    247 
    248   The Start() function is designed to be invoked from the EFI boot service ConnectController().
    249   As a result, much of the error checking on the parameters to Start() has been moved into this
    250   common boot service. It is legal to call Start() from other locations,
    251   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
    252   1. ControllerHandle must be a valid EFI_HANDLE.
    253   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
    254      EFI_DEVICE_PATH_PROTOCOL.
    255   3. Prior to calling Start(), the Supported() function for the driver specified by This must
    256      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
    257 
    258   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    259   @param[in]  ControllerHandle     The handle of the controller to start. This handle
    260                                    must support a protocol interface that supplies
    261                                    an I/O abstraction to the driver.
    262   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    263                                    parameter is ignored by device drivers, and is optional for bus
    264                                    drivers. For a bus driver, if this parameter is NULL, then handles
    265                                    for all the children of Controller are created by this driver.
    266                                    If this parameter is not NULL and the first Device Path Node is
    267                                    not the End of Device Path Node, then only the handle for the
    268                                    child device specified by the first Device Path Node of
    269                                    RemainingDevicePath is created by this driver.
    270                                    If the first Device Path Node of RemainingDevicePath is
    271                                    the End of Device Path Node, no child handle is created by this
    272                                    driver.
    273 
    274   @retval EFI_SUCCESS              The device was started.
    275   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
    276   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
    277   @retval Others                   The driver failded to start the device.
    278 
    279 **/
    280 EFI_STATUS
    281 EFIAPI
    282 HttpBootIp4DxeDriverBindingStart (
    283   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    284   IN EFI_HANDLE                   ControllerHandle,
    285   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    286   );
    287 
    288 /**
    289   Stops a device controller or a bus controller.
    290 
    291   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
    292   As a result, much of the error checking on the parameters to Stop() has been moved
    293   into this common boot service. It is legal to call Stop() from other locations,
    294   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
    295   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
    296      same driver's Start() function.
    297   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
    298      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
    299      Start() function, and the Start() function must have called OpenProtocol() on
    300      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
    301 
    302   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    303   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
    304                                 support a bus specific I/O protocol for the driver
    305                                 to use to stop the device.
    306   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
    307   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
    308                                 if NumberOfChildren is 0.
    309 
    310   @retval EFI_SUCCESS           The device was stopped.
    311   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
    312 
    313 **/
    314 EFI_STATUS
    315 EFIAPI
    316 HttpBootIp4DxeDriverBindingStop (
    317   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    318   IN EFI_HANDLE                   ControllerHandle,
    319   IN UINTN                        NumberOfChildren,
    320   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
    321   );
    322 
    323 /**
    324   Tests to see if this driver supports a given controller. If a child device is provided,
    325   it further tests to see if this driver supports creating a handle for the specified child device.
    326 
    327   This function checks to see if the driver specified by This supports the device specified by
    328   ControllerHandle. Drivers will typically use the device path attached to
    329   ControllerHandle and/or the services from the bus I/O abstraction attached to
    330   ControllerHandle to determine if the driver supports ControllerHandle. This function
    331   may be called many times during platform initialization. In order to reduce boot times, the tests
    332   performed by this function must be very small, and take as little time as possible to execute. This
    333   function must not change the state of any hardware devices, and this function must be aware that the
    334   device specified by ControllerHandle may already be managed by the same driver or a
    335   different driver. This function must match its calls to AllocatePages() with FreePages(),
    336   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
    337   Because ControllerHandle may have been previously started by the same driver, if a protocol is
    338   already in the opened state, then it must not be closed with CloseProtocol(). This is required
    339   to guarantee the state of ControllerHandle is not modified by this function.
    340 
    341   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    342   @param[in]  ControllerHandle     The handle of the controller to test. This handle
    343                                    must support a protocol interface that supplies
    344                                    an I/O abstraction to the driver.
    345   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    346                                    parameter is ignored by device drivers, and is optional for bus
    347                                    drivers. For bus drivers, if this parameter is not NULL, then
    348                                    the bus driver must determine if the bus controller specified
    349                                    by ControllerHandle and the child controller specified
    350                                    by RemainingDevicePath are both supported by this
    351                                    bus driver.
    352 
    353   @retval EFI_SUCCESS              The device specified by ControllerHandle and
    354                                    RemainingDevicePath is supported by the driver specified by This.
    355   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
    356                                    RemainingDevicePath is already being managed by the driver
    357                                    specified by This.
    358   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
    359                                    RemainingDevicePath is already being managed by a different
    360                                    driver or an application that requires exclusive access.
    361                                    Currently not implemented.
    362   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
    363                                    RemainingDevicePath is not supported by the driver specified by This.
    364 **/
    365 EFI_STATUS
    366 EFIAPI
    367 HttpBootIp6DxeDriverBindingSupported (
    368   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    369   IN EFI_HANDLE                   ControllerHandle,
    370   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    371   );
    372 
    373 /**
    374   Starts a device controller or a bus controller.
    375 
    376   The Start() function is designed to be invoked from the EFI boot service ConnectController().
    377   As a result, much of the error checking on the parameters to Start() has been moved into this
    378   common boot service. It is legal to call Start() from other locations,
    379   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
    380   1. ControllerHandle must be a valid EFI_HANDLE.
    381   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
    382      EFI_DEVICE_PATH_PROTOCOL.
    383   3. Prior to calling Start(), the Supported() function for the driver specified by This must
    384      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
    385 
    386   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    387   @param[in]  ControllerHandle     The handle of the controller to start. This handle
    388                                    must support a protocol interface that supplies
    389                                    an I/O abstraction to the driver.
    390   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    391                                    parameter is ignored by device drivers, and is optional for bus
    392                                    drivers. For a bus driver, if this parameter is NULL, then handles
    393                                    for all the children of Controller are created by this driver.
    394                                    If this parameter is not NULL and the first Device Path Node is
    395                                    not the End of Device Path Node, then only the handle for the
    396                                    child device specified by the first Device Path Node of
    397                                    RemainingDevicePath is created by this driver.
    398                                    If the first Device Path Node of RemainingDevicePath is
    399                                    the End of Device Path Node, no child handle is created by this
    400                                    driver.
    401 
    402   @retval EFI_SUCCESS              The device was started.
    403   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
    404   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
    405   @retval Others                   The driver failded to start the device.
    406 
    407 **/
    408 EFI_STATUS
    409 EFIAPI
    410 HttpBootIp6DxeDriverBindingStart (
    411   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    412   IN EFI_HANDLE                   ControllerHandle,
    413   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    414   );
    415 
    416 /**
    417   Stops a device controller or a bus controller.
    418 
    419   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
    420   As a result, much of the error checking on the parameters to Stop() has been moved
    421   into this common boot service. It is legal to call Stop() from other locations,
    422   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
    423   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
    424      same driver's Start() function.
    425   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
    426      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
    427      Start() function, and the Start() function must have called OpenProtocol() on
    428      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
    429 
    430   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    431   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
    432                                 support a bus specific I/O protocol for the driver
    433                                 to use to stop the device.
    434   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
    435   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
    436                                 if NumberOfChildren is 0.
    437 
    438   @retval EFI_SUCCESS           The device was stopped.
    439   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
    440 
    441 **/
    442 EFI_STATUS
    443 EFIAPI
    444 HttpBootIp6DxeDriverBindingStop (
    445   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    446   IN EFI_HANDLE                   ControllerHandle,
    447   IN UINTN                        NumberOfChildren,
    448   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
    449   );
    450 #endif
    451