1ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin/** @file 2ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* 355a9f75d149ea53d1c8b3da197ec344c2aedb848Olivier Martin* Copyright (c) 2011-2014, ARM Limited. All rights reserved. 4ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* 5ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* This program and the accompanying materials 6ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* are licensed and made available under the terms and conditions of the BSD License 7ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* which accompanies this distribution. The full text of the license may be found at 8ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* http://opensource.org/licenses/bsd-license.php 9ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* 10ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin* 13ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin**/ 14ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 15ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include "BdsInternal.h" 16ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 17ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include <Library/NetLib.h> 18ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 19ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include <Protocol/BlockIo.h> 20ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include <Protocol/DevicePathToText.h> 213a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel#include <Protocol/FirmwareVolumeBlock.h> 22ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include <Protocol/PxeBaseCode.h> 23ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include <Protocol/SimpleFileSystem.h> 24ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include <Protocol/SimpleNetwork.h> 25061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron#include <Protocol/Dhcp4.h> 26061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron#include <Protocol/Mtftp4.h> 27ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 28ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#include <Guid/FileSystemInfo.h> 29ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 30ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype))) 31ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 32ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 33ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemList ( 34ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 35ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 36ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 37ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 38ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemCreateDevicePath ( 3922a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 40889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 41ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 42ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 43ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 44ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemUpdateDevicePath ( 4522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *OldDevicePath, 4622a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 47889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 48ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 49ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 50ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 51ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemIsSupported ( 5222a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *DevicePath 53ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 54ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 55ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 56ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapList ( 57ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 58ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 59ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 60ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 61ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapCreateDevicePath ( 6222a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 63889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 64ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 65ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 66ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 67ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapUpdateDevicePath ( 6822a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *OldDevicePath, 6922a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 70889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 71ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 72ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 73ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 74ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapIsSupported ( 7522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *DevicePath 76ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 77ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 78ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 79ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeList ( 80ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 81ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 82ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 83ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 84ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeCreateDevicePath ( 8522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 86889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 87ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 88ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 89ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 90ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeUpdateDevicePath ( 9122a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *OldDevicePath, 9222a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 93889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 94ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 95ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 96ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 97ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeIsSupported ( 9822a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *DevicePath 99ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 100ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 101ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 102ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpList ( 103ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 104ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 105ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 106ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 107ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpCreateDevicePath ( 10822a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 109889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 110ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 111ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 112ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 113ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpUpdateDevicePath ( 11422a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *OldDevicePath, 11522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 116889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 117ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 118ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 119ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 120ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpIsSupported ( 12122a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *DevicePath 122ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ); 123ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 124ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList[] = { 1252ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin { 1262ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BDS_DEVICE_FILESYSTEM, 1272ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionFileSystemList, 1282ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionFileSystemIsSupported, 1292ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionFileSystemCreateDevicePath, 130889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron BdsLoadOptionFileSystemUpdateDevicePath, 131889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron TRUE 1322ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin }, 1332ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin { 1342ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BDS_DEVICE_MEMMAP, 1352ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionMemMapList, 1362ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionMemMapIsSupported, 1372ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionMemMapCreateDevicePath, 138889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron BdsLoadOptionMemMapUpdateDevicePath, 139889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron TRUE 1402ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin }, 1412ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin { 1422ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BDS_DEVICE_PXE, 1432ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionPxeList, 1442ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionPxeIsSupported, 1452ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionPxeCreateDevicePath, 146889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron BdsLoadOptionPxeUpdateDevicePath, 147889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron FALSE 1482ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin }, 1492ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin { 1502ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BDS_DEVICE_TFTP, 1512ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionTftpList, 1522ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionTftpIsSupported, 1532ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionTftpCreateDevicePath, 154889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron BdsLoadOptionTftpUpdateDevicePath, 155889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron TRUE 1562ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin } 157ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin}; 158ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 159ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 160ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBootDeviceListSupportedInit ( 161ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY *SupportedDeviceList 162ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 163ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 164ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN Index; 165ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 166ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Initialize list of supported devices 167ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin InitializeListHead (SupportedDeviceList); 168ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 169ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin for (Index = 0; Index < BDS_DEVICE_MAX; Index++) { 1702ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin BdsLoadOptionSupportList[Index].ListDevices (SupportedDeviceList); 171ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 172ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 173ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 174ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 175ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 176ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 177ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBootDeviceListSupportedFree ( 178656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin IN LIST_ENTRY *SupportedDeviceList, 179656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin IN BDS_SUPPORTED_DEVICE *Except 180ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 181ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 182ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin LIST_ENTRY *Entry; 183ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin BDS_SUPPORTED_DEVICE* SupportedDevice; 184ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 185ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Entry = GetFirstNode (SupportedDeviceList); 186ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin while (Entry != SupportedDeviceList) { 187ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); 188ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Entry = RemoveEntryList (Entry); 189656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin if (SupportedDevice != Except) { 1902ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin FreePool (SupportedDevice); 191656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin } 192ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 193ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 194ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 195ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 196ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 197ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 198ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBootDeviceGetDeviceSupport ( 19922a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *DevicePath, 20022a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin OUT BDS_LOAD_OPTION_SUPPORT **DeviceSupport 201ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 202ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 203ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN Index; 204ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 205ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Find which supported device is the most appropriate 206ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin for (Index = 0; Index < BDS_DEVICE_MAX; Index++) { 20722a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin if (BdsLoadOptionSupportList[Index].IsSupported (DevicePath)) { 208ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin *DeviceSupport = &BdsLoadOptionSupportList[Index]; 209ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 210ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 211ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 212ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 213ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_UNSUPPORTED; 214ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 215ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 216ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 217ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemList ( 218ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 219ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 220ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 221ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_STATUS Status; 222ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN HandleCount; 223ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_HANDLE *HandleBuffer; 224ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN Index; 225ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin BDS_SUPPORTED_DEVICE *SupportedDevice; 226ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileProtocol; 227ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_FILE_HANDLE Fs; 228ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN Size; 229ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_FILE_SYSTEM_INFO* FsInfo; 230ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; 231ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 232ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // List all the Simple File System Protocols 233ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer); 234ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR (Status)) { 235ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 236ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 237ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 238ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin for (Index = 0; Index < HandleCount; Index++) { 239ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); 240ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!EFI_ERROR(Status)) { 241ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Allocate BDS Supported Device structure 2422ccfb71ebebd54c57aad8f9bb5fb20539e7b892foliviermartin SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE)); 243ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 244ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FileProtocol = NULL; 245ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileProtocol); 246ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ASSERT_EFI_ERROR(Status); 247ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 248ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FileProtocol->OpenVolume (FileProtocol, &Fs); 249ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 250ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Generate a Description from the file system 251ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Size = 0; 252ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FsInfo = NULL; 253ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo); 254ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (Status == EFI_BUFFER_TOO_SMALL) { 255ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FsInfo = AllocatePool (Size); 256ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo); 257ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 258ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"%s (%d MB)",FsInfo->VolumeLabel,(UINT32)(FsInfo->VolumeSize / (1024 * 1024))); 259ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FreePool(FsInfo); 260ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Fs->Close (Fs); 261ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 262ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice->DevicePathProtocol = DevicePathProtocol; 263ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_FILESYSTEM]; 264ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 265ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin InsertTailList (BdsLoadOptionList,&SupportedDevice->Link); 266ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 267ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 268ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 269ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 270ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 271ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 272ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 273ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemCreateDevicePath ( 27422a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 275889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 276ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 277ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 278ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_STATUS Status; 279ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FILEPATH_DEVICE_PATH* FilePathDevicePath; 28074b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; 281ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN BootFilePathSize; 282ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 28322a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Print(L"File path of the %s: ", FileName); 28474b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); 285ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR(Status)) { 286ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_ABORTED; 287ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 288ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 28974b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin BootFilePathSize = StrSize (BootFilePath); 29074b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin if (BootFilePathSize == 2) { 291ecc62d1390402ea99a807679372c955286e295e0oliviermartin *DevicePathNodes = NULL; 292656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin return EFI_NOT_FOUND; 293656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin } 294656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin 295ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Create the FilePath Device Path node 296ecc62d1390402ea99a807679372c955286e295e0oliviermartin FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); 297ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; 298ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; 299ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); 300ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); 301ecc62d1390402ea99a807679372c955286e295e0oliviermartin SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); 30255a9f75d149ea53d1c8b3da197ec344c2aedb848Olivier Martin *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath; 303ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 304ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 305ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 306ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 307ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 308ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemUpdateDevicePath ( 30922a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *OldDevicePath, 31022a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 311889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 312ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 313ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 314ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_STATUS Status; 31574b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; 316ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN BootFilePathSize; 317ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FILEPATH_DEVICE_PATH* EndingDevicePath; 318ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FILEPATH_DEVICE_PATH* FilePathDevicePath; 319ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_DEVICE_PATH* DevicePath; 320ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 3210db25ccc6cf1d05dc6b8fd9b07d033b40c387c88oliviermartin DevicePath = DuplicateDevicePath (OldDevicePath); 322ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 323656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath); 3243402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 32522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Print(L"File path of the %s: ", FileName); 32674b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin StrnCpy (BootFilePath, EndingDevicePath->PathName, BOOT_DEVICE_FILEPATH_MAX); 32774b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); 328ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR(Status)) { 329ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 330ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 331ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 33274b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin BootFilePathSize = StrSize(BootFilePath); 33374b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin if (BootFilePathSize == 2) { 334656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin *NewDevicePath = NULL; 335656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin return EFI_NOT_FOUND; 336656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin } 337656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin 338ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Create the FilePath Device Path node 339ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); 340ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; 341ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; 342ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); 343ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); 344ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 345ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Generate the new Device Path by replacing the last node by the updated node 346ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SetDevicePathEndNode (EndingDevicePath); 347ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin *NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath); 348ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FreePool(DevicePath); 349ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 350656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin return EFI_SUCCESS; 351ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 352ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 35322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron/** 35422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Check if a boot option path is a file system boot option path or not. 35522a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 35622a50a13e555102e1751c2f6665eb67855b43473Ronald Cron The device specified by the beginning of the path has to support the Simple File 35722a50a13e555102e1751c2f6665eb67855b43473Ronald Cron System protocol. Furthermore, the remaining part of the path has to be composed of 35822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron a single node of type MEDIA_DEVICE_PATH and sub-type MEDIA_FILEPATH_DP. 35922a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 36022a50a13e555102e1751c2f6665eb67855b43473Ronald Cron @param[in] DevicePath Complete device path of a boot option. 36122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 36222a50a13e555102e1751c2f6665eb67855b43473Ronald Cron @retval FALSE The boot option path has not been identified as that of a 36322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron file system boot option. 36422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron @retval TRUE The boot option path is a file system boot option. 36522a50a13e555102e1751c2f6665eb67855b43473Ronald Cron**/ 366ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 367ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionFileSystemIsSupported ( 36822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron IN EFI_DEVICE_PATH *DevicePath 369ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 370ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 37122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_STATUS Status; 37222a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_HANDLE Handle; 37322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_DEVICE_PATH *RemainingDevicePath; 37422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileProtocol; 375ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 37622a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); 37722a50a13e555102e1751c2f6665eb67855b43473Ronald Cron if (EFI_ERROR (Status)) { 37822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return FALSE; 37922a50a13e555102e1751c2f6665eb67855b43473Ronald Cron } 38022a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 38122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Status = gBS->HandleProtocol ( 38222a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Handle, 38322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron &gEfiSimpleFileSystemProtocolGuid, 38422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron (VOID **)(&FileProtocol) 38522a50a13e555102e1751c2f6665eb67855b43473Ronald Cron ); 38622a50a13e555102e1751c2f6665eb67855b43473Ronald Cron if (EFI_ERROR (Status)) { 38722a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return FALSE; 38822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron } 389ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 39022a50a13e555102e1751c2f6665eb67855b43473Ronald Cron if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP)) 39122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return FALSE; 39222a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 39322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return TRUE; 394ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 395ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 396ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinSTATIC 397ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 398ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinIsParentDevicePath ( 399ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, 400ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath 401ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 402ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 403ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN ParentSize; 404ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN ChildSize; 405ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 406ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ParentSize = GetDevicePathSize (ParentDevicePath); 407ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ChildSize = GetDevicePathSize (ChildDevicePath); 408ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 409ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (ParentSize > ChildSize) { 410ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 411ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 412ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 413ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (CompareMem (ParentDevicePath, ChildDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0) { 414ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 415ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 416ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 417ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return TRUE; 418ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 419ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 420ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 421ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapList ( 422ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 423ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 424ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 4253a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel EFI_STATUS Status; 4263a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel UINTN HandleCount; 4273a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel EFI_HANDLE *HandleBuffer; 4283a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel UINTN DevicePathHandleCount; 4293a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel EFI_HANDLE *DevicePathHandleBuffer; 4303a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel BOOLEAN IsParent; 4313a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel UINTN Index; 4323a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel UINTN Index2; 4333a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel BDS_SUPPORTED_DEVICE *SupportedDevice; 4343a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; 4353a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel EFI_DEVICE_PATH* DevicePath; 4363a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileProtocol; 4373a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol; 438ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 439ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // List all the BlockIo Protocols 440ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &HandleBuffer); 441ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR (Status)) { 442ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 443ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 444ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 445ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin for (Index = 0; Index < HandleCount; Index++) { 4463a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel // We only select handles WITH a Device Path AND not part of Media (to 4473a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel // avoid duplication with HardDisk, CDROM, etc). Skip handles used by 4483a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel // Simple Filesystem or used for Variable Storage. 4493a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel 4503a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel 4513a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel Status = gBS->HandleProtocol (HandleBuffer[Index], 4523a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel &gEfiSimpleFileSystemProtocolGuid, 4533a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel (VOID *)&FileProtocol); 4543a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel if (!EFI_ERROR(Status)) { 4553a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel // SimpleFilesystem supported on this handle, skip 4563a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel continue; 4573a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel } 4583a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel 4593a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel Status = gBS->HandleProtocol (HandleBuffer[Index], 4603a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel &gEfiFirmwareVolumeBlockProtocolGuid, 4613a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel (VOID *)&FvbProtocol); 4623a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel if (!EFI_ERROR(Status)) { 4633a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel // Firmware Volme Block / Variable storage supported on this handle, skip 4643a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel continue; 4653a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel } 4663a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel 4673a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel Status = gBS->HandleProtocol (HandleBuffer[Index], 4683a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel &gEfiFirmwareVolumeBlock2ProtocolGuid, 4693a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel (VOID *)&FvbProtocol); 4703a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel if (!EFI_ERROR(Status)) { 4713a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel // Firmware Volme Block / Variable storage supported on this handle, skip 4723a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel continue; 4733a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel } 4743a0e4800a328f5d7893e080f65edcc6bd0bc07e5Harry Liebel 475ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); 476ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!EFI_ERROR(Status)) { 477ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // BlockIo is not part of Media Device Path 478ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin DevicePath = DevicePathProtocol; 479ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin while (!IsDevicePathEndType (DevicePath) && (DevicePathType (DevicePath) != MEDIA_DEVICE_PATH)) { 480ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin DevicePath = NextDevicePathNode (DevicePath); 481ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 482ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) { 483ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin continue; 484ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 485ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 486ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child 487ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &DevicePathHandleCount, &DevicePathHandleBuffer); 488ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ASSERT_EFI_ERROR (Status); 489ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IsParent = FALSE; 490ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin for (Index2 = 0; (Index2 < DevicePathHandleCount) && !IsParent; Index2++) { 491ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (HandleBuffer[Index] != DevicePathHandleBuffer[Index2]) { 492ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin gBS->HandleProtocol (DevicePathHandleBuffer[Index2], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); 493ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (IsParentDevicePath (DevicePathProtocol, DevicePath)) { 494ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IsParent = TRUE; 495ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 496ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 497ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 498ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (IsParent) { 499ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin continue; 500ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 501ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 502ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Allocate BDS Supported Device structure 503ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE)); 504ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 505ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = GenerateDeviceDescriptionName (HandleBuffer[Index], SupportedDevice->Description); 506ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ASSERT_EFI_ERROR (Status); 507ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 508ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice->DevicePathProtocol = DevicePathProtocol; 509ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_MEMMAP]; 510ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 511ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin InsertTailList (BdsLoadOptionList,&SupportedDevice->Link); 512ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 513ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 514ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 515ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 516ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 517ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 518ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 519ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapCreateDevicePath ( 52022a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 521889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 522ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 523ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 52422a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin EFI_STATUS Status; 52522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin MEMMAP_DEVICE_PATH *MemMapDevicePath; 52622a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX]; 52722a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX]; 528ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 52922a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Print(L"Starting Address of the %s: ", FileName); 53022a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Status = GetHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX); 531ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR(Status)) { 532ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_ABORTED; 533ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 534ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 53522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Print(L"Ending Address of the %s: ", FileName); 53622a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Status = GetHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX); 537ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR(Status)) { 538ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_ABORTED; 539ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 540ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 541ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Create the MemMap Device Path Node 54222a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin MemMapDevicePath = (MEMMAP_DEVICE_PATH*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH) + END_DEVICE_PATH_LENGTH); 543ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin MemMapDevicePath->Header.Type = HARDWARE_DEVICE_PATH; 544ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin MemMapDevicePath->Header.SubType = HW_MEMMAP_DP; 54522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin SetDevicePathNodeLength (MemMapDevicePath, sizeof(MEMMAP_DEVICE_PATH)); 546ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin MemMapDevicePath->MemoryType = EfiBootServicesData; 54774b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin MemMapDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress); 54874b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin MemMapDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress); 549ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 55022a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin // Set a Device Path End Node after the Memory Map Device Path Node 55122a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin SetDevicePathEndNode (MemMapDevicePath + 1); 55255a9f75d149ea53d1c8b3da197ec344c2aedb848Olivier Martin *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath; 553ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 554ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 555ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 556ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 557ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 558ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapUpdateDevicePath ( 55922a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *OldDevicePath, 56022a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 561889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 562ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 563ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 5646bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin EFI_STATUS Status; 56574b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX]; 56674b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX]; 5676bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin MEMMAP_DEVICE_PATH* EndingDevicePath; 5686bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin EFI_DEVICE_PATH* DevicePath; 5696bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin 570656416bc2ee1409492343cde3f27ce717e90fdf7oliviermartin DevicePath = DuplicateDevicePath (OldDevicePath); 5716bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath); 5726bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin 57322a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Print(L"Starting Address of the %s: ", FileName); 57474b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin UnicodeSPrint (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->StartingAddress); 57574b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin Status = EditHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX); 5766bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin if (EFI_ERROR(Status)) { 5776bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin return EFI_ABORTED; 5786bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin } 5796bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin 58022a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Print(L"Ending Address of the %s: ", FileName); 58174b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin UnicodeSPrint (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->EndingAddress); 58274b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin Status = EditHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX); 5836bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin if (EFI_ERROR(Status)) { 5846bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin return EFI_ABORTED; 5856bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin } 5866bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin 58774b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin EndingDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress); 58874b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin EndingDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress); 5896bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin 5906bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin if (EFI_ERROR(Status)) { 5916bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin FreePool(DevicePath); 5926bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin } else { 5936bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin *NewDevicePath = DevicePath; 5946bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin } 5956bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin 5966bab33c7b677dea7a67df512ef1a058daeebef57oliviermartin return Status; 597ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 598ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 59922a50a13e555102e1751c2f6665eb67855b43473Ronald Cron/** 60022a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Check if a boot option path is a memory map boot option path or not. 60122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 60222a50a13e555102e1751c2f6665eb67855b43473Ronald Cron The device specified by the beginning of the path has to support the BlockIo 60322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron protocol. Furthermore, the remaining part of the path has to be composed of 60422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron a single node of type HARDWARE_DEVICE_PATH and sub-type HW_MEMMAP_DP. 60522a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 60622a50a13e555102e1751c2f6665eb67855b43473Ronald Cron @param[in] DevicePath Complete device path of a boot option. 60722a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 60822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron @retval FALSE The boot option path has not been identified as that of a 60922a50a13e555102e1751c2f6665eb67855b43473Ronald Cron memory map boot option. 61022a50a13e555102e1751c2f6665eb67855b43473Ronald Cron @retval TRUE The boot option path is a a memory map boot option. 61122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron**/ 612ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 613ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionMemMapIsSupported ( 61422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron IN EFI_DEVICE_PATH *DevicePath 615ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 616ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 61722a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_STATUS Status; 61822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_HANDLE Handle; 61922a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_DEVICE_PATH *RemainingDevicePath; 62022a50a13e555102e1751c2f6665eb67855b43473Ronald Cron EFI_BLOCK_IO_PROTOCOL *BlockIoProtocol; 62122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 62222a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); 62322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron if (EFI_ERROR (Status)) { 62422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return FALSE; 62522a50a13e555102e1751c2f6665eb67855b43473Ronald Cron } 626ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 62722a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Status = gBS->HandleProtocol ( 62822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron Handle, 62922a50a13e555102e1751c2f6665eb67855b43473Ronald Cron &gEfiBlockIoProtocolGuid, 63022a50a13e555102e1751c2f6665eb67855b43473Ronald Cron (VOID **)(&BlockIoProtocol) 63122a50a13e555102e1751c2f6665eb67855b43473Ronald Cron ); 63222a50a13e555102e1751c2f6665eb67855b43473Ronald Cron if (EFI_ERROR (Status)) { 63322a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return FALSE; 63422a50a13e555102e1751c2f6665eb67855b43473Ronald Cron } 635ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 63622a50a13e555102e1751c2f6665eb67855b43473Ronald Cron if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP)) 63722a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return FALSE; 63822a50a13e555102e1751c2f6665eb67855b43473Ronald Cron 63922a50a13e555102e1751c2f6665eb67855b43473Ronald Cron return TRUE; 640ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 641ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 642ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 643ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeList ( 644ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 645ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 646ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 647ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_STATUS Status; 648ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN HandleCount; 649ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_HANDLE *HandleBuffer; 650ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UINTN Index; 651ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin BDS_SUPPORTED_DEVICE *SupportedDevice; 652ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; 653ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_SIMPLE_NETWORK_PROTOCOL* SimpleNet; 654ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin CHAR16 DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX]; 655ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_MAC_ADDRESS *Mac; 656ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 657ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // List all the PXE Protocols 658ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer); 659ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR (Status)) { 660ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 661ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 662ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 663ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin for (Index = 0; Index < HandleCount; Index++) { 664ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // We only select the handle WITH a Device Path AND the PXE Protocol 665ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); 666ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!EFI_ERROR(Status)) { 667ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Allocate BDS Supported Device structure 668ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE)); 669ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 670387e7c15f5e3a047de0a7a5edb5700e90a1c6c78Heyi Guo Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleNetworkProtocolGuid, (VOID **)&SimpleNet); 671ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!EFI_ERROR(Status)) { 672ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Mac = &SimpleNet->Mode->CurrentAddress; 673ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5]); 674ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } else { 675ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription); 676ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ASSERT_EFI_ERROR (Status); 677ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 678ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"PXE on %s",DeviceDescription); 679ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 680ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice->DevicePathProtocol = DevicePathProtocol; 681ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_PXE]; 682ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 683ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin InsertTailList (BdsLoadOptionList,&SupportedDevice->Link); 684ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 685ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 686ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 687ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 688ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 689ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 690ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 691ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeCreateDevicePath ( 69222a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 693889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 694ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 695ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 696ecc62d1390402ea99a807679372c955286e295e0oliviermartin *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH); 697ecc62d1390402ea99a807679372c955286e295e0oliviermartin SetDevicePathEndNode (*DevicePathNodes); 69855a9f75d149ea53d1c8b3da197ec344c2aedb848Olivier Martin 699ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 700ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 701ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 7022db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron/** 7032db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron Update the parameters of a Pxe boot option 7042db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron 7052db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron @param[in] OldDevicePath Current complete device path of the Pxe boot option. 7062db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron This has to be a valid complete Pxe boot option path. 7072db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron @param[in] FileName Description of the file the path is asked for 7082db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron @param[out] NewDevicePath Pointer to the new complete device path. 7092db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron 7102db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron @retval EFI_SUCCESS Update completed 7112db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource 7122db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron**/ 713ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 714ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeUpdateDevicePath ( 71522a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *OldDevicePath, 71622a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 717889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 718ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 719ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 7202db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron // 7212db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron // Make a copy of the complete device path that is made of : 7222db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron // the device path of the device supporting the Pxe base code protocol 7232db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron // followed by an end node. 7242db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron // 7252db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron *NewDevicePath = DuplicateDevicePath (OldDevicePath); 7262db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron if (*NewDevicePath == NULL) { 7272db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron return EFI_OUT_OF_RESOURCES; 7282db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron } else { 7292db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron return EFI_SUCCESS; 7302db16368d1554b3243c7b5c0f81aa226e8932722Ronald Cron } 731ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 732ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 733ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 734ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionPxeIsSupported ( 73522a50a13e555102e1751c2f6665eb67855b43473Ronald Cron IN EFI_DEVICE_PATH *DevicePath 736ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 737ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 738ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_STATUS Status; 739ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_HANDLE Handle; 740ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; 741ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol; 742ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 74322a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); 744ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR(Status)) { 745ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 746ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 747ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 748ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!IsDevicePathEnd(RemainingDevicePath)) { 749ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 750ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 751ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 752ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol); 753ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR (Status)) { 754ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 755ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } else { 756ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return TRUE; 757ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 758ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 759ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 760061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron/** 761061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Add to the list of boot devices the devices allowing a TFTP boot 762061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 763061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron @param[in] BdsLoadOptionList List of devices to boot from 764061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 765061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron @retval EFI_SUCCESS Update completed 766061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource 767061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron**/ 768ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 769ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpList ( 770ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IN OUT LIST_ENTRY* BdsLoadOptionList 771ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 772ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 773061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_STATUS Status; 774061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron UINTN HandleCount; 775061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_HANDLE *HandleBuffer; 776061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_HANDLE Handle; 777061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron UINTN Index; 778061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol; 779061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron VOID *Interface; 780061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetworkProtocol; 781061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron BDS_SUPPORTED_DEVICE *SupportedDevice; 782061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_MAC_ADDRESS *Mac; 783ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 784061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // 785061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // List all the handles on which the Simple Network Protocol is installed. 786061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // 787061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = gBS->LocateHandleBuffer ( 788061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ByProtocol, 789061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron &gEfiSimpleNetworkProtocolGuid, 790061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron NULL, 791061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron &HandleCount, 792061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron &HandleBuffer 793061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ); 794ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR (Status)) { 795ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 796ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 797ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 798ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin for (Index = 0; Index < HandleCount; Index++) { 799061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Handle = HandleBuffer[Index]; 800061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // 801061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // We select the handles that support : 802061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // . the Device Path Protocol 803061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // . the MTFTP4 Protocol 804061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // 805061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = gBS->HandleProtocol ( 806061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Handle, 807061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron &gEfiDevicePathProtocolGuid, 808061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron (VOID **)&DevicePathProtocol 809061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ); 810061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 811061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron continue; 812061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 813ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 814061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = gBS->HandleProtocol ( 815061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Handle, 816061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron &gEfiMtftp4ServiceBindingProtocolGuid, 817061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron &Interface 818061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ); 819061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 820061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron continue; 821061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 822ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 823061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = gBS->HandleProtocol ( 824061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Handle, 825061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron &gEfiSimpleNetworkProtocolGuid, 826061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron (VOID **)&SimpleNetworkProtocol 827061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ); 828061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 829061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron continue; 830061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 831ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 832061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron // Allocate BDS Supported Device structure 833061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof (BDS_SUPPORTED_DEVICE)); 834061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (SupportedDevice == NULL) { 835061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron continue; 836ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 837061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 838061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Mac = &SimpleNetworkProtocol->Mode->CurrentAddress; 839061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron UnicodeSPrint ( 840061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron SupportedDevice->Description, 841061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron BOOT_DEVICE_DESCRIPTION_MAX, 842061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron L"TFTP on MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", 843061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5] 844061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ); 845061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 846061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron SupportedDevice->DevicePathProtocol = DevicePathProtocol; 847061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP]; 848061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 849061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron InsertTailList (BdsLoadOptionList, &SupportedDevice->Link); 850ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 851ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 852ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_SUCCESS; 853ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 854ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 855ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 856ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpCreateDevicePath ( 85722a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN CHAR16* FileName, 858889ac6a8b7d632c7c2dc203bd20b722b9ee57719Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes 859ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 860ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 861061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_STATUS Status; 862061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron BOOLEAN IsDHCP; 863061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS LocalIp; 864061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS SubnetMask; 865061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS GatewayIp; 866061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS RemoteIp; 867061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron IPv4_DEVICE_PATH *IPv4DevicePathNode; 868061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron FILEPATH_DEVICE_PATH *FilePathDevicePath; 869061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; 870061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron UINTN BootFilePathSize; 871ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 872061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"Get the IP address from DHCP: "); 873ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = GetHIInputBoolean (&IsDHCP); 874061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 875ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_ABORTED; 876ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 877ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 878ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!IsDHCP) { 879061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"Local static IP address: "); 880ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = GetHIInputIP (&LocalIp); 881061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 882061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron return EFI_ABORTED; 883061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 884061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"Get the network mask: "); 885061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = GetHIInputIP (&SubnetMask); 886061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 887061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron return EFI_ABORTED; 888061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 889061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"Get the gateway IP address: "); 890061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = GetHIInputIP (&GatewayIp); 891061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 892ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_ABORTED; 893ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 894ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 895ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 896061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"Get the TFTP server IP address: "); 897ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = GetHIInputIP (&RemoteIp); 898061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 899ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_ABORTED; 900ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 901ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 902061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"File path of the %s : ", FileName); 90374b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); 904061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 905ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return EFI_ABORTED; 906ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 907ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 908ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin BootFilePathSize = StrSize(BootFilePath); 90974b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin if (BootFilePathSize == 2) { 91074b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin return EFI_NOT_FOUND; 91174b961324c1cc3ae3f97523e085fb169ec63b608oliviermartin } 912ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 913ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Allocate the memory for the IPv4 + File Path Device Path Nodes 914ecc62d1390402ea99a807679372c955286e295e0oliviermartin IPv4DevicePathNode = (IPv4_DEVICE_PATH*)AllocatePool(sizeof(IPv4_DEVICE_PATH) + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); 915ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 916ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Create the IPv4 Device Path 917ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH; 918ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP; 919ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH)); 920061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 921061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (!IsDHCP) { 922061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS)); 923061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&IPv4DevicePathNode->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); 924061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&IPv4DevicePathNode->GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS)); 925061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 926061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 927ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS)); 928ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IPv4DevicePathNode->LocalPort = 0; 929ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IPv4DevicePathNode->RemotePort = 0; 930ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IPv4DevicePathNode->Protocol = EFI_IP_PROTO_TCP; 931ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin IPv4DevicePathNode->StaticIpAddress = (IsDHCP != TRUE); 932ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 933ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Create the FilePath Device Path node 934ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1); 935ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; 936ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; 937ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); 938ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); 939ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 940ecc62d1390402ea99a807679372c955286e295e0oliviermartin // Set the End Device Path Node 941ecc62d1390402ea99a807679372c955286e295e0oliviermartin SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); 94255a9f75d149ea53d1c8b3da197ec344c2aedb848Olivier Martin *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode; 943ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 944ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return Status; 945ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 946ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 947152286cea508549928b776e8a2ca62e089bc6790Ronald Cron/** 948152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Update the parameters of a TFTP boot option 949152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 950152286cea508549928b776e8a2ca62e089bc6790Ronald Cron The function asks sequentially to update the IPv4 parameters as well as the boot file path, 951152286cea508549928b776e8a2ca62e089bc6790Ronald Cron providing the previously set value if any. 952152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 953152286cea508549928b776e8a2ca62e089bc6790Ronald Cron @param[in] OldDevicePath Current complete device path of the Tftp boot option. 954152286cea508549928b776e8a2ca62e089bc6790Ronald Cron This has to be a valid complete Tftp boot option path. 955152286cea508549928b776e8a2ca62e089bc6790Ronald Cron By complete, we mean that it is not only the Tftp 956152286cea508549928b776e8a2ca62e089bc6790Ronald Cron specific end part built by the 957152286cea508549928b776e8a2ca62e089bc6790Ronald Cron "BdsLoadOptionTftpCreateDevicePath()" function. 958152286cea508549928b776e8a2ca62e089bc6790Ronald Cron This path is handled as read only. 959152286cea508549928b776e8a2ca62e089bc6790Ronald Cron @param[in] FileName Description of the file the path is asked for 960152286cea508549928b776e8a2ca62e089bc6790Ronald Cron @param[out] NewDevicePath Pointer to the new complete device path. 961152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 962152286cea508549928b776e8a2ca62e089bc6790Ronald Cron @retval EFI_SUCCESS Update completed 963152286cea508549928b776e8a2ca62e089bc6790Ronald Cron @retval EFI_ABORTED Update aborted by the user 964152286cea508549928b776e8a2ca62e089bc6790Ronald Cron @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource 965152286cea508549928b776e8a2ca62e089bc6790Ronald Cron**/ 966ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinEFI_STATUS 967ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpUpdateDevicePath ( 968152286cea508549928b776e8a2ca62e089bc6790Ronald Cron IN EFI_DEVICE_PATH *OldDevicePath, 969152286cea508549928b776e8a2ca62e089bc6790Ronald Cron IN CHAR16 *FileName, 970152286cea508549928b776e8a2ca62e089bc6790Ronald Cron OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath 971ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 972ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 973152286cea508549928b776e8a2ca62e089bc6790Ronald Cron EFI_STATUS Status; 974152286cea508549928b776e8a2ca62e089bc6790Ronald Cron EFI_DEVICE_PATH *DevicePath; 975152286cea508549928b776e8a2ca62e089bc6790Ronald Cron EFI_DEVICE_PATH *DevicePathNode; 976152286cea508549928b776e8a2ca62e089bc6790Ronald Cron UINT8 *Ipv4NodePtr; 977152286cea508549928b776e8a2ca62e089bc6790Ronald Cron IPv4_DEVICE_PATH Ipv4Node; 978152286cea508549928b776e8a2ca62e089bc6790Ronald Cron BOOLEAN IsDHCP; 979152286cea508549928b776e8a2ca62e089bc6790Ronald Cron EFI_IP_ADDRESS OldIp; 980061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS OldSubnetMask; 981061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS OldGatewayIp; 982152286cea508549928b776e8a2ca62e089bc6790Ronald Cron EFI_IP_ADDRESS LocalIp; 983061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS SubnetMask; 984061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron EFI_IP_ADDRESS GatewayIp; 985152286cea508549928b776e8a2ca62e089bc6790Ronald Cron EFI_IP_ADDRESS RemoteIp; 986152286cea508549928b776e8a2ca62e089bc6790Ronald Cron UINT8 *FileNodePtr; 987152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; 988152286cea508549928b776e8a2ca62e089bc6790Ronald Cron UINTN PathSize; 989152286cea508549928b776e8a2ca62e089bc6790Ronald Cron UINTN BootFilePathSize; 990152286cea508549928b776e8a2ca62e089bc6790Ronald Cron FILEPATH_DEVICE_PATH *NewFilePathNode; 991152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 992152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Ipv4NodePtr = NULL; 993152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 994152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 995152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Make a copy of the complete device path that is made of : 996152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // the device path of the device that support the Simple Network protocol 997152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // followed by an IPv4 node (type IPv4_DEVICE_PATH), 998152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // followed by a file path node (type FILEPATH_DEVICE_PATH) and ended up 999152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // by an end node. The IPv6 case is not handled yet. 1000152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1001152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1002152286cea508549928b776e8a2ca62e089bc6790Ronald Cron DevicePath = DuplicateDevicePath (OldDevicePath); 1003152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (DevicePath == NULL) { 1004152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Status = EFI_OUT_OF_RESOURCES; 1005152286cea508549928b776e8a2ca62e089bc6790Ronald Cron goto ErrorExit; 1006152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1007152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1008152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1009152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Because of the check done by "BdsLoadOptionTftpIsSupported()" prior to the 1010152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // call to this function, we know that the device path ends with an IPv4 node 1011152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // followed by a file path node and finally an end node. To get the address of 1012152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // the last IPv4 node, we loop over the whole device path, noting down the 1013152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // address of each encountered IPv4 node. 1014152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1015152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1016152286cea508549928b776e8a2ca62e089bc6790Ronald Cron for (DevicePathNode = DevicePath; 1017152286cea508549928b776e8a2ca62e089bc6790Ronald Cron !IsDevicePathEnd (DevicePathNode); 1018152286cea508549928b776e8a2ca62e089bc6790Ronald Cron DevicePathNode = NextDevicePathNode (DevicePathNode)) 1019152286cea508549928b776e8a2ca62e089bc6790Ronald Cron { 1020152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (IS_DEVICE_PATH_NODE (DevicePathNode, MESSAGING_DEVICE_PATH, MSG_IPv4_DP)) { 1021152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Ipv4NodePtr = (UINT8*)DevicePathNode; 1022152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1023152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1024152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1025152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Copy for alignment of the IPv4 node data 1026152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CopyMem (&Ipv4Node, Ipv4NodePtr, sizeof (IPv4_DEVICE_PATH)); 1027152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1028152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Print (L"Get the IP address from DHCP: "); 1029152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Status = GetHIInputBoolean (&IsDHCP); 1030152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (EFI_ERROR (Status)) { 1031152286cea508549928b776e8a2ca62e089bc6790Ronald Cron goto ErrorExit; 1032152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1033152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1034152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (!IsDHCP) { 1035152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Print (L"Local static IP address: "); 1036152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (Ipv4Node.StaticIpAddress) { 1037152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS)); 1038152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Status = EditHIInputIP (&OldIp, &LocalIp); 1039152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } else { 1040152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Status = GetHIInputIP (&LocalIp); 1041152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1042152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (EFI_ERROR (Status)) { 1043152286cea508549928b776e8a2ca62e089bc6790Ronald Cron goto ErrorExit; 1044152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1045061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 1046061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"Get the network mask: "); 1047061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (Ipv4Node.StaticIpAddress) { 1048061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&OldSubnetMask.v4, &Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); 1049061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = EditHIInputIP (&OldSubnetMask, &SubnetMask); 1050061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } else { 1051061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = GetHIInputIP (&SubnetMask); 1052061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 1053061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 1054061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron goto ErrorExit; 1055061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 1056061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 1057061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Print (L"Get the gateway IP address: "); 1058061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (Ipv4Node.StaticIpAddress) { 1059061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&OldGatewayIp.v4, &Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS)); 1060061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = EditHIInputIP (&OldGatewayIp, &GatewayIp); 1061061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } else { 1062061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron Status = GetHIInputIP (&GatewayIp); 1063061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 1064061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (EFI_ERROR (Status)) { 1065061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron goto ErrorExit; 1066061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron } 1067152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1068152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1069152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Print (L"TFTP server IP address: "); 1070152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Copy remote IPv4 address into IPv4 or IPv6 union 1071152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CopyMem (&OldIp.v4, &Ipv4Node.RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS)); 1072152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1073152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Status = EditHIInputIP (&OldIp, &RemoteIp); 1074152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (EFI_ERROR (Status)) { 1075152286cea508549928b776e8a2ca62e089bc6790Ronald Cron goto ErrorExit; 1076152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1077152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1078152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Get the path of the boot file and its size in number of bytes 1079152286cea508549928b776e8a2ca62e089bc6790Ronald Cron FileNodePtr = Ipv4NodePtr + sizeof (IPv4_DEVICE_PATH); 1080152286cea508549928b776e8a2ca62e089bc6790Ronald Cron BootFilePathSize = DevicePathNodeLength (FileNodePtr) - SIZE_OF_FILEPATH_DEVICE_PATH; 1081152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1082152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1083152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Ask for update of the boot file path 1084152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1085152286cea508549928b776e8a2ca62e089bc6790Ronald Cron do { 1086152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Copy for 2-byte alignment of the Unicode string 1087152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CopyMem ( 1088152286cea508549928b776e8a2ca62e089bc6790Ronald Cron BootFilePath, FileNodePtr + SIZE_OF_FILEPATH_DEVICE_PATH, 1089152286cea508549928b776e8a2ca62e089bc6790Ronald Cron MIN (BootFilePathSize, BOOT_DEVICE_FILEPATH_MAX) 1090152286cea508549928b776e8a2ca62e089bc6790Ronald Cron ); 1091152286cea508549928b776e8a2ca62e089bc6790Ronald Cron BootFilePath[BOOT_DEVICE_FILEPATH_MAX - 1] = L'\0'; 1092152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1093152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Print (L"File path of the %s: ", FileName); 1094152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); 1095152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (EFI_ERROR (Status)) { 1096152286cea508549928b776e8a2ca62e089bc6790Ronald Cron goto ErrorExit; 1097152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1098152286cea508549928b776e8a2ca62e089bc6790Ronald Cron PathSize = StrSize (BootFilePath); 1099152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (PathSize > 2) { 1100152286cea508549928b776e8a2ca62e089bc6790Ronald Cron break; 1101152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1102152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Empty string, give the user another try 1103152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Print (L"Empty string - Invalid path\n"); 1104152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } while (PathSize <= 2) ; 1105152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1106152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1107152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Update the IPv4 node. IPv6 case not handled yet. 1108152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1109061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron if (IsDHCP) { 1110152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Ipv4Node.StaticIpAddress = FALSE; 1111061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ZeroMem (&Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS)); 1112061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ZeroMem (&Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); 1113061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron ZeroMem (&Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS)); 1114152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } else { 1115152286cea508549928b776e8a2ca62e089bc6790Ronald Cron Ipv4Node.StaticIpAddress = TRUE; 1116061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS)); 1117061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&Ipv4Node.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); 1118061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron CopyMem (&Ipv4Node.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS)); 1119152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1120061568e2d5f21aeafa942891b15768c57fa0ffacRonald Cron 1121152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS)); 1122152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH)); 1123152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1124152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1125152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Create the new file path node 1126152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1127152286cea508549928b776e8a2ca62e089bc6790Ronald Cron NewFilePathNode = (FILEPATH_DEVICE_PATH*)AllocatePool ( 1128152286cea508549928b776e8a2ca62e089bc6790Ronald Cron SIZE_OF_FILEPATH_DEVICE_PATH + 1129152286cea508549928b776e8a2ca62e089bc6790Ronald Cron PathSize 1130152286cea508549928b776e8a2ca62e089bc6790Ronald Cron ); 1131152286cea508549928b776e8a2ca62e089bc6790Ronald Cron NewFilePathNode->Header.Type = MEDIA_DEVICE_PATH; 1132152286cea508549928b776e8a2ca62e089bc6790Ronald Cron NewFilePathNode->Header.SubType = MEDIA_FILEPATH_DP; 1133152286cea508549928b776e8a2ca62e089bc6790Ronald Cron SetDevicePathNodeLength ( 1134152286cea508549928b776e8a2ca62e089bc6790Ronald Cron NewFilePathNode, 1135152286cea508549928b776e8a2ca62e089bc6790Ronald Cron SIZE_OF_FILEPATH_DEVICE_PATH + PathSize 1136152286cea508549928b776e8a2ca62e089bc6790Ronald Cron ); 1137152286cea508549928b776e8a2ca62e089bc6790Ronald Cron CopyMem (NewFilePathNode->PathName, BootFilePath, PathSize); 1138152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1139152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1140152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // Generate the new Device Path by replacing the file path node at address 1141152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // "FileNodePtr" by the new one "NewFilePathNode" and return its address. 1142152286cea508549928b776e8a2ca62e089bc6790Ronald Cron // 1143152286cea508549928b776e8a2ca62e089bc6790Ronald Cron SetDevicePathEndNode (FileNodePtr); 1144152286cea508549928b776e8a2ca62e089bc6790Ronald Cron *NewDevicePath = AppendDevicePathNode ( 1145152286cea508549928b776e8a2ca62e089bc6790Ronald Cron DevicePath, 1146152286cea508549928b776e8a2ca62e089bc6790Ronald Cron (CONST EFI_DEVICE_PATH_PROTOCOL*)NewFilePathNode 1147152286cea508549928b776e8a2ca62e089bc6790Ronald Cron ); 1148152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1149152286cea508549928b776e8a2ca62e089bc6790Ronald CronErrorExit: 1150152286cea508549928b776e8a2ca62e089bc6790Ronald Cron if (DevicePath != NULL) { 1151152286cea508549928b776e8a2ca62e089bc6790Ronald Cron FreePool (DevicePath) ; 1152152286cea508549928b776e8a2ca62e089bc6790Ronald Cron } 1153152286cea508549928b776e8a2ca62e089bc6790Ronald Cron 1154152286cea508549928b776e8a2ca62e089bc6790Ronald Cron return Status; 1155ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 1156ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 1157ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBOOLEAN 1158ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartinBdsLoadOptionTftpIsSupported ( 115922a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin IN EFI_DEVICE_PATH *DevicePath 1160ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin ) 1161ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin{ 1162ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_STATUS Status; 1163ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_HANDLE Handle; 1164ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_DEVICE_PATH *RemainingDevicePath; 1165ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_DEVICE_PATH *NextDevicePath; 1166ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol; 1167ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 116822a262c8eeace5e5e7e3e812a0b30ac49ea5b811oliviermartin Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); 1169ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR(Status)) { 1170ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 1171ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 1172ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 1173ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin // Validate the Remaining Device Path 1174ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (IsDevicePathEnd(RemainingDevicePath)) { 1175ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 1176ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 1177ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv4_DP) && 1178ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin !IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv6_DP)) { 1179ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 1180ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 1181ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin NextDevicePath = NextDevicePathNode (RemainingDevicePath); 1182ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (IsDevicePathEnd(NextDevicePath)) { 1183ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 1184ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 1185ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (!IS_DEVICE_PATH_NODE(NextDevicePath,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP)) { 1186ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 1187ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 1188ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin 1189ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol); 1190ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin if (EFI_ERROR (Status)) { 1191ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return FALSE; 1192ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } else { 1193ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin return TRUE; 1194ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin } 1195ea46ebbe6a5a579ff341071a13ae625e15edae64oliviermartin} 1196