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