1 /* 2 * Copyright (c) 2015 Netflix, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 28 #include <stand.h> 29 #include <string.h> 30 #include <efi.h> 31 #include <efichar.h> 32 #include <efilib.h> 33 #include <eficonsctl.h> 34 #include <Guid/Acpi.h> 35 #include <Guid/ConsoleInDevice.h> 36 #include <Guid/ConsoleOutDevice.h> 37 #include <Guid/DebugImageInfoTable.h> 38 #include <Guid/DxeServices.h> 39 #include <Guid/Fdt.h> 40 #include <Guid/GlobalVariable.h> 41 #include <Guid/Gpt.h> 42 #include <Guid/HobList.h> 43 #include <Guid/MemoryTypeInformation.h> 44 #include <Guid/Mps.h> 45 #include <Guid/MtcVendor.h> 46 #include <Guid/SmBios.h> 47 #include <Guid/StandardErrorDevice.h> 48 #include <Guid/ZeroGuid.h> 49 #include <Pi/PiStatusCode.h> 50 #include <Protocol/AbsolutePointer.h> 51 #include <Protocol/AdapterInformation.h> 52 #include <Protocol/Arp.h> 53 #include <Protocol/AtaPassThru.h> 54 #include <Protocol/Bds.h> 55 #include <Protocol/BlockIo.h> 56 #include <Protocol/BlockIo2.h> 57 #include <Protocol/BusSpecificDriverOverride.h> 58 #include <Protocol/Capsule.h> 59 #include <Protocol/ComponentName.h> 60 #include <Protocol/ComponentName2.h> 61 #include <Protocol/Cpu.h> 62 #include <Protocol/CpuIo2.h> 63 #include <Protocol/DataHub.h> 64 #include <Protocol/Decompress.h> 65 #include <Protocol/DeviceIo.h> 66 #include <Protocol/DevicePath.h> 67 #include <Protocol/DevicePathFromText.h> 68 #include <Protocol/DevicePathToText.h> 69 #include <Protocol/DevicePathUtilities.h> 70 #include <Protocol/Dhcp4.h> 71 #include <Protocol/Dhcp6.h> 72 #include <Protocol/DiskInfo.h> 73 #include <Protocol/DiskIo.h> 74 #include <Protocol/DiskIo2.h> 75 #include <Protocol/Dpc.h> 76 #include <Protocol/DriverBinding.h> 77 #include <Protocol/DriverConfiguration.h> 78 #include <Protocol/DriverConfiguration2.h> 79 #include <Protocol/DriverDiagnostics.h> 80 #include <Protocol/DriverDiagnostics2.h> 81 #include <Protocol/DriverFamilyOverride.h> 82 #include <Protocol/DriverHealth.h> 83 #include <Protocol/DriverSupportedEfiVersion.h> 84 #include <Protocol/Ebc.h> 85 #include <Protocol/EdidActive.h> 86 #include <Protocol/EdidDiscovered.h> 87 #include <Pi/PiFirmwareVolume.h> 88 #include <Protocol/FirmwareVolumeBlock.h> 89 #include <Uefi/UefiInternalFormRepresentation.h> 90 #include <Protocol/FormBrowser2.h> 91 #include <Protocol/GraphicsOutput.h> 92 #include <Protocol/HiiConfigAccess.h> 93 #include <Protocol/HiiConfigKeyword.h> 94 #include <Protocol/HiiConfigRouting.h> 95 #include <Protocol/HiiFont.h> 96 #include <Protocol/HiiImage.h> 97 #include <Protocol/HiiDatabase.h> 98 #include <Protocol/HiiString.h> 99 #include <Protocol/IdeControllerInit.h> 100 #include <Protocol/Ip4.h> 101 #include <Protocol/Ip4Config.h> 102 #include <Protocol/Ip4Config2.h> 103 #include <Protocol/Ip6.h> 104 #include <Protocol/Ip6Config.h> 105 #include <Protocol/IpSec.h> 106 #include <Protocol/IpSecConfig.h> 107 #include <Protocol/IsaAcpi.h> 108 #include <Protocol/IsaIo.h> 109 #include <Protocol/Kms.h> 110 #include <Protocol/Legacy8259.h> 111 #include <Protocol/LoadFile.h> 112 #include <Protocol/LoadFile2.h> 113 #include <Protocol/Metronome.h> 114 #include <Protocol/MonotonicCounter.h> 115 #include <Pi/PiMultiPhase.h> 116 #include <Protocol/MpService.h> 117 #include <Protocol/Mtftp4.h> 118 #include <Protocol/Mtftp6.h> 119 #include <Protocol/NetworkInterfaceIdentifier.h> 120 #include <Protocol/NvmExpressPassthru.h> 121 #include <Protocol/PciIo.h> 122 #include <Protocol/Pcd.h> 123 #include <Protocol/PciEnumerationComplete.h> 124 #include <Protocol/PciRootBridgeIo.h> 125 #include <Protocol/PiPcd.h> 126 #include <Protocol/PlatformDriverOverride.h> 127 #include <Protocol/PlatformToDriverConfiguration.h> 128 #include <Protocol/Print2.h> 129 #include <Protocol/PxeBaseCode.h> 130 #include <Protocol/PxeBaseCodeCallBack.h> 131 #include <Protocol/RealTimeClock.h> 132 #include <Protocol/ReportStatusCodeHandler.h> 133 #include <Protocol/Reset.h> 134 #include <Protocol/Rng.h> 135 #include <Protocol/Runtime.h> 136 #include <Protocol/ScsiIo.h> 137 #include <Protocol/ScsiPassThru.h> 138 #include <Protocol/ScsiPassThruExt.h> 139 #include <Protocol/Security.h> 140 #include <Protocol/Security2.h> 141 #include <Protocol/SecurityPolicy.h> 142 #include <Protocol/SerialIo.h> 143 #include <Protocol/SimpleFileSystem.h> 144 #include <Protocol/SimplePointer.h> 145 #include <Protocol/SimpleTextIn.h> 146 #include <Protocol/SimpleTextInEx.h> 147 #include <Protocol/SimpleTextOut.h> 148 #include <Protocol/SmartCardReader.h> 149 #include <Protocol/StatusCode.h> 150 #include <Protocol/StorageSecurityCommand.h> 151 #include <Protocol/Tcg2Protocol.h> 152 #include <Protocol/Tcp4.h> 153 #include <Protocol/Tcp6.h> 154 #include <Protocol/Timer.h> 155 #include <Protocol/Udp4.h> 156 #include <Protocol/Udp6.h> 157 #include <Protocol/UgaDraw.h> 158 #include <Protocol/UgaIo.h> 159 #include <Protocol/UnicodeCollation.h> 160 #include <Protocol/UsbIo.h> 161 #include <Protocol/Usb2HostController.h> 162 #include <Protocol/Variable.h> 163 #include <Protocol/VariableWrite.h> 164 #include <Protocol/VlanConfig.h> 165 #include <Protocol/WatchdogTimer.h> 166 #include <Protocol/IsaAcpi.h> 167 #include <Protocol/IsaIo.h> 168 #include <Protocol/SerialIo.h> 169 #include <Protocol/SuperIo.h> 170 #include <uuid.h> 171 #include <stdbool.h> 172 #include <sys/param.h> 173 #include "bootstrap.h" 174 #include "ficl.h" 175 176 /* 177 * About ENABLE_UPDATES 178 * 179 * The UEFI variables are identified only by GUID and name, there is no 180 * way to (auto)detect the type for the value, so we need to process the 181 * variables case by case, as we do learn about them. 182 * 183 * While showing the variable name and the value is safe, we must not store 184 * random values nor allow removing (random) variables. 185 * 186 * Since we do have stub code to set/unset the variables, I do want to keep 187 * it to make the future development a bit easier, but the updates are disabled 188 * by default till: 189 * a) the validation and data translation to values is properly implemented 190 * b) We have established which variables we do allow to be updated. 191 * Therefore the set/unset code is included only for developers aid. 192 */ 193 194 /* If GUID is not defined elsewhere, define it here. */ 195 EFI_GUID gEfiAbsolutePointerProtocolGuid = EFI_ABSOLUTE_POINTER_PROTOCOL_GUID; 196 EFI_GUID gEfiAdapterInformationProtocolGuid = 197 EFI_ADAPTER_INFORMATION_PROTOCOL_GUID; 198 EFI_GUID gEfiAtaPassThruProtocolGuid = EFI_ATA_PASS_THRU_PROTOCOL_GUID; 199 EFI_GUID gEfiBdsArchProtocolGuid = EFI_BDS_ARCH_PROTOCOL_GUID; 200 EFI_GUID gEfiBusSpecificDriverOverrideProtocolGuid = 201 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID; 202 EFI_GUID gEfiCapsuleArchProtocolGuid = EFI_CAPSULE_ARCH_PROTOCOL_GUID; 203 EFI_GUID gEfiComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID; 204 EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID; 205 EFI_GUID gEfiCpuArchProtocolGuid = EFI_CPU_ARCH_PROTOCOL_GUID; 206 EFI_GUID gEfiCpuIo2ProtocolGuid = EFI_CPU_IO2_PROTOCOL_GUID; 207 EFI_GUID gEfiDataHubProtocolGuid = EFI_DATA_HUB_PROTOCOL_GUID; 208 EFI_GUID gEfiDebugImageInfoTableGuid = EFI_DEBUG_IMAGE_INFO_TABLE_GUID; 209 EFI_GUID gEfiDecompressProtocolGuid = EFI_DECOMPRESS_PROTOCOL_GUID; 210 EFI_GUID gEfiDeviceIoProtocolGuid = EFI_DEVICE_IO_PROTOCOL_GUID; 211 EFI_GUID gEfiDhcp4ProtocolGuid = EFI_DHCP4_PROTOCOL_GUID; 212 EFI_GUID gEfiDhcp4ServiceBindingProtocolGuid = 213 EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID; 214 EFI_GUID gEfiDhcp6ProtocolGuid = EFI_DHCP4_PROTOCOL_GUID; 215 EFI_GUID gEfiDhcp6ServiceBindingProtocolGuid = 216 EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID; 217 EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID; 218 EFI_GUID gEfiDiskIoProtocolGuid = EFI_DISK_IO_PROTOCOL_GUID; 219 EFI_GUID gEfiDiskIo2ProtocolGuid = EFI_DISK_IO2_PROTOCOL_GUID; 220 EFI_GUID gEfiDpcProtocolGuid = EFI_DPC_PROTOCOL_GUID; 221 EFI_GUID gEfiDriverConfigurationProtocolGuid = 222 EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID; 223 EFI_GUID gEfiDriverConfiguration2ProtocolGuid = 224 EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID; 225 EFI_GUID gEfiDriverDiagnosticsProtocolGuid = 226 EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID; 227 EFI_GUID gEfiDriverDiagnostics2ProtocolGuid = 228 EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID; 229 EFI_GUID gEfiDriverFamilyOverrideProtocolGuid = 230 EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID; 231 EFI_GUID gEfiDriverHealthProtocolGuid = 232 EFI_DRIVER_HEALTH_PROTOCOL_GUID; 233 EFI_GUID gEfiDriverSupportedEfiVersionProtocolGuid = 234 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL_GUID; 235 EFI_GUID gEfiDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID; 236 EFI_GUID gEfiEbcProtocolGuid = EFI_EBC_INTERPRETER_PROTOCOL_GUID; 237 EFI_GUID gEfiFormBrowser2ProtocolGuid = EFI_FORM_BROWSER2_PROTOCOL_GUID; 238 EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid = 239 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID; 240 EFI_GUID gEfiFirmwareVolumeBlock2ProtocolGuid = 241 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL_GUID; 242 EFI_GUID gEfiHiiConfigAccessProtocolGuid = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID; 243 EFI_GUID gEfiConfigKeywordHandlerProtocolGuid = 244 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL_GUID; 245 EFI_GUID gEfiHiiConfigRoutingProtocolGuid = 246 EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID; 247 EFI_GUID gEfiHiiFontProtocolGuid = EFI_HII_FONT_PROTOCOL_GUID; 248 EFI_GUID gEfiHiiImageProtocolGuid = EFI_HII_IMAGE_PROTOCOL_GUID; 249 EFI_GUID gEfiHiiStringProtocolGuid = EFI_HII_STRING_PROTOCOL_GUID; 250 EFI_GUID gEfiHiiDatabaseProtocolGuid = EFI_HII_DATABASE_PROTOCOL_GUID; 251 EFI_GUID gEfiHobListGuid = HOB_LIST_GUID; 252 EFI_GUID gEfiIdeControllerInitProtocolGuid = 253 EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID; 254 EFI_GUID gEfiIp4ProtocolGuid = EFI_IP4_PROTOCOL_GUID; 255 EFI_GUID gEfiIp4ServiceBindingProtocolGuid = 256 EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID; 257 EFI_GUID gEfiIp4ConfigProtocolGuid = EFI_IP4_CONFIG_PROTOCOL_GUID; 258 EFI_GUID gEfiIp4Config2ProtocolGuid = EFI_IP4_CONFIG2_PROTOCOL_GUID; 259 EFI_GUID gEfiIp6ProtocolGuid = EFI_IP6_PROTOCOL_GUID; 260 EFI_GUID gEfiIp6ServiceBindingProtocolGuid = 261 EFI_IP6_SERVICE_BINDING_PROTOCOL_GUID; 262 EFI_GUID gEfiIp6ConfigProtocolGuid = EFI_IP6_CONFIG_PROTOCOL_GUID; 263 EFI_GUID gEfiIpSecProtocolGuid = EFI_IPSEC_PROTOCOL_GUID; 264 EFI_GUID gEfiIpSec2ProtocolGuid = EFI_IPSEC2_PROTOCOL_GUID; 265 EFI_GUID gEfiIpSecConfigProtocolGuid = EFI_IPSEC_CONFIG_PROTOCOL_GUID; 266 EFI_GUID gEfiIsaAcpiProtocolGuid = EFI_ISA_ACPI_PROTOCOL_GUID; 267 EFI_GUID gEfiKmsProtocolGuid = EFI_KMS_PROTOCOL_GUID; 268 EFI_GUID gEfiLegacy8259ProtocolGuid = EFI_LEGACY_8259_PROTOCOL_GUID; 269 EFI_GUID gEfiLoadFileProtocolGuid = EFI_LOAD_FILE_PROTOCOL_GUID; 270 EFI_GUID gEfiLoadFile2ProtocolGuid = EFI_LOAD_FILE2_PROTOCOL_GUID; 271 EFI_GUID gEfiManagedNetworkProtocolGuid = EFI_MANAGED_NETWORK_PROTOCOL_GUID; 272 EFI_GUID gEfiManagedNetworkServiceBindingProtocolGuid = 273 EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID; 274 EFI_GUID gEfiMemoryTypeInformationGuid = EFI_MEMORY_TYPE_INFORMATION_GUID; 275 EFI_GUID gEfiMetronomeArchProtocolGuid = EFI_METRONOME_ARCH_PROTOCOL_GUID; 276 EFI_GUID gEfiMonotonicCounterArchProtocolGuid = 277 EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID; 278 EFI_GUID gEfiMpServiceProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID; 279 EFI_GUID gEfiMpsTableGuid = MPS_TABLE_GUID; 280 EFI_GUID gEfiMtftp4ProtocolGuid = EFI_MTFTP4_PROTOCOL_GUID; 281 EFI_GUID gEfiMtftp4ServiceBindingProtocolGuid = 282 EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID; 283 EFI_GUID gEfiMtftp6ProtocolGuid = EFI_MTFTP6_PROTOCOL_GUID; 284 EFI_GUID gEfiMtftp6ServiceBindingProtocolGuid = 285 EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID; 286 EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid = 287 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID; 288 EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid_31 = 289 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID_31; 290 EFI_GUID gEfiNvmExpressPassThruProtocolGuid = 291 EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL_GUID; 292 EFI_GUID gEfiPartTypeLegacyMbrGuid = EFI_PART_TYPE_LEGACY_MBR_GUID; 293 EFI_GUID gEfiPartTypeSystemPartGuid = EFI_PART_TYPE_EFI_SYSTEM_PART_GUID; 294 EFI_GUID gEfiPcdProtocolGuid = EFI_PCD_PROTOCOL_GUID; 295 EFI_GUID gEfiPciEnumerationCompleteProtocolGuid = 296 EFI_PCI_ENUMERATION_COMPLETE_GUID; 297 EFI_GUID gEfiPciRootBridgeIoProtocolGuid = 298 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; 299 EFI_GUID gEfiPlatformDriverOverrideProtocolGuid = 300 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID; 301 EFI_GUID gEfiPlatformToDriverConfigurationProtocolGuid = 302 EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL_GUID; 303 EFI_GUID gEfiPrint2SProtocolGuid = EFI_PRINT2_PROTOCOL_GUID; 304 EFI_GUID gEfiPxeBaseCodeProtocolGuid = EFI_PXE_BASE_CODE_PROTOCOL_GUID; 305 EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid = 306 EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID; 307 EFI_GUID gEfiRealTimeClockArchProtocolGuid = 308 EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID; 309 EFI_GUID gEfiResetArchProtocolGuid = EFI_RESET_ARCH_PROTOCOL_GUID; 310 EFI_GUID gEfiRngProtocolGuid = EFI_RNG_PROTOCOL_GUID; 311 EFI_GUID gEfiRuntimeArchProtocolGuid = EFI_RUNTIME_ARCH_PROTOCOL_GUID; 312 EFI_GUID gEfiScsiIoProtocolGuid = EFI_SCSI_IO_PROTOCOL_GUID; 313 EFI_GUID gEfiScsiPassThruProtocolGuid = EFI_SCSI_PASS_THRU_PROTOCOL_GUID; 314 EFI_GUID gEfiExtScsiPassThruProtocolGuid = 315 EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID; 316 EFI_GUID gEfiSecurityArchProtocolGuid = EFI_SECURITY_ARCH_PROTOCOL_GUID; 317 EFI_GUID gEfiSecurity2ArchProtocolGuid = EFI_SECURITY2_ARCH_PROTOCOL_GUID; 318 EFI_GUID gEfiSecurityPolicyProtocolGuid = EFI_SECURITY_POLICY_PROTOCOL_GUID; 319 EFI_GUID gEfiSimpleFileSystemProtocolGuid = 320 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; 321 EFI_GUID gEfiSimplePointerProtocolGuid = EFI_SIMPLE_POINTER_PROTOCOL_GUID; 322 EFI_GUID gEfiSmartCardReaderProtocolGuid = EFI_SMART_CARD_READER_PROTOCOL_GUID; 323 EFI_GUID gEfiStatusCodeRuntimeProtocolGuid = 324 EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID; 325 EFI_GUID gEfiStorageSecurityCommandProtocolGuid = 326 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL_GUID; 327 EFI_GUID gEfiTcg2ProtocolGuid = EFI_TCG2_PROTOCOL_GUID; 328 EFI_GUID gEfiTcp4ProtocolGuid = EFI_TCP4_PROTOCOL_GUID; 329 EFI_GUID gEfiTcp4ServiceBindingProtocolGuid = 330 EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID; 331 EFI_GUID gEfiTcp6ProtocolGuid = EFI_TCP6_PROTOCOL_GUID; 332 EFI_GUID gEfiTcp6ServiceBindingProtocolGuid = 333 EFI_TCP6_SERVICE_BINDING_PROTOCOL_GUID; 334 EFI_GUID gEfiTimerArchProtocolGuid = EFI_TIMER_ARCH_PROTOCOL_GUID; 335 EFI_GUID gEfiUdp4ProtocolGuid = EFI_UDP4_PROTOCOL_GUID; 336 EFI_GUID gEfiUdp4ServiceBindingProtocolGuid = 337 EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID; 338 EFI_GUID gEfiUdp6ProtocolGuid = EFI_UDP6_PROTOCOL_GUID; 339 EFI_GUID gEfiUdp6ServiceBindingProtocolGuid = 340 EFI_UDP6_SERVICE_BINDING_PROTOCOL_GUID; 341 EFI_GUID gEfiUnicodeCollationProtocolGuid = EFI_UNICODE_COLLATION_PROTOCOL_GUID; 342 EFI_GUID gEfiUnicodeCollation2ProtocolGuid = 343 EFI_UNICODE_COLLATION_PROTOCOL2_GUID; 344 EFI_GUID gEfiUsbIoProtocolGuid = EFI_USB_IO_PROTOCOL_GUID; 345 EFI_GUID gEfiUsb2HcProtocolGuid = EFI_USB2_HC_PROTOCOL_GUID; 346 EFI_GUID gEfiVariableArchProtocolGuid = EFI_VARIABLE_ARCH_PROTOCOL_GUID; 347 EFI_GUID gEfiVariableWriteArchProtocolGuid = 348 EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID; 349 EFI_GUID gEfiWatchdogTimerArchProtocolGuid = 350 EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID; 351 EFI_GUID gFdtTableGuid = FDT_TABLE_GUID; 352 EFI_GUID gLzmaCompress = LZMA_COMPRESS_GUID; 353 EFI_GUID gMtcVendorGuid = MTC_VENDOR_GUID; 354 EFI_GUID gPcdProtocolGuid = PCD_PROTOCOL_GUID; 355 356 static struct efi_uuid_mapping { 357 const char *efi_guid_name; 358 EFI_GUID *efi_guid; 359 } efi_uuid_mapping[] = { 360 { .efi_guid_name = "global", 361 .efi_guid = &gEfiGlobalVariableGuid }, 362 { .efi_guid_name = "illumos", 363 .efi_guid = &gillumosBootVarGuid }, 364 /* EFI Systab entry names. */ 365 { .efi_guid_name = "MPS Table", 366 .efi_guid = &gEfiMpsTableGuid }, 367 { .efi_guid_name = "ACPI Table", 368 .efi_guid = &gEfiAcpiTableGuid }, 369 { .efi_guid_name = "ACPI 2.0 Table", 370 .efi_guid = &gEfiAcpi20TableGuid }, 371 { .efi_guid_name = "ATA pass thru", 372 .efi_guid = &gEfiAtaPassThruProtocolGuid }, 373 { .efi_guid_name = "SMBIOS Table", 374 .efi_guid = &gEfiSmbiosTableGuid }, 375 { .efi_guid_name = "SMBIOS3 Table", 376 .efi_guid = &gEfiSmbios3TableGuid }, 377 { .efi_guid_name = "DXE Table", 378 .efi_guid = &gEfiDxeServicesTableGuid }, 379 { .efi_guid_name = "HOB List Table", 380 .efi_guid = &gEfiHobListGuid }, 381 { .efi_guid_name = EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, 382 .efi_guid = &gEfiMemoryTypeInformationGuid }, 383 { .efi_guid_name = "Debug Image Info Table", 384 .efi_guid = &gEfiDebugImageInfoTableGuid }, 385 { .efi_guid_name = "FDT Table", 386 .efi_guid = &gFdtTableGuid }, 387 /* 388 * Protocol names for debug purposes. 389 * Can be removed along with lsefi command. 390 */ 391 { .efi_guid_name = "absolute pointer", 392 .efi_guid = &gEfiAbsolutePointerProtocolGuid }, 393 { .efi_guid_name = "device path", 394 .efi_guid = &gEfiDevicePathProtocolGuid }, 395 { .efi_guid_name = "block io", 396 .efi_guid = &gEfiBlockIoProtocolGuid }, 397 { .efi_guid_name = "block io2", 398 .efi_guid = &gEfiBlockIo2ProtocolGuid }, 399 { .efi_guid_name = "disk io", 400 .efi_guid = &gEfiDiskIoProtocolGuid }, 401 { .efi_guid_name = "disk io2", 402 .efi_guid = &gEfiDiskIo2ProtocolGuid }, 403 { .efi_guid_name = "disk info", 404 .efi_guid = &gEfiDiskInfoProtocolGuid }, 405 { .efi_guid_name = "simple fs", 406 .efi_guid = &gEfiSimpleFileSystemProtocolGuid }, 407 { .efi_guid_name = "load file", 408 .efi_guid = &gEfiLoadFileProtocolGuid }, 409 { .efi_guid_name = "load file2", 410 .efi_guid = &gEfiLoadFile2ProtocolGuid }, 411 { .efi_guid_name = "device io", 412 .efi_guid = &gEfiDeviceIoProtocolGuid }, 413 { .efi_guid_name = "unicode collation", 414 .efi_guid = &gEfiUnicodeCollationProtocolGuid }, 415 { .efi_guid_name = "unicode collation2", 416 .efi_guid = &gEfiUnicodeCollation2ProtocolGuid }, 417 { .efi_guid_name = "simple network", 418 .efi_guid = &gEfiSimpleNetworkProtocolGuid }, 419 { .efi_guid_name = "simple pointer", 420 .efi_guid = &gEfiSimplePointerProtocolGuid }, 421 { .efi_guid_name = "simple text output", 422 .efi_guid = &gEfiSimpleTextOutProtocolGuid }, 423 { .efi_guid_name = "simple text input", 424 .efi_guid = &gEfiSimpleTextInProtocolGuid }, 425 { .efi_guid_name = "simple text ex input", 426 .efi_guid = &gEfiSimpleTextInputExProtocolGuid }, 427 { .efi_guid_name = "console control", 428 .efi_guid = &gEfiConsoleControlProtocolGuid }, 429 { .efi_guid_name = "stdin", 430 .efi_guid = &gEfiConsoleInDeviceGuid }, 431 { .efi_guid_name = "stdout", 432 .efi_guid = &gEfiConsoleOutDeviceGuid }, 433 { .efi_guid_name = "stderr", 434 .efi_guid = &gEfiStandardErrorDeviceGuid }, 435 { .efi_guid_name = "GOP", 436 .efi_guid = &gEfiGraphicsOutputProtocolGuid }, 437 { .efi_guid_name = "UGA draw", 438 .efi_guid = &gEfiUgaDrawProtocolGuid }, 439 { .efi_guid_name = "UGA io", 440 .efi_guid = &gEfiUgaIoProtocolGuid }, 441 { .efi_guid_name = "PXE base code", 442 .efi_guid = &gEfiPxeBaseCodeProtocolGuid }, 443 { .efi_guid_name = "PXE base code callback", 444 .efi_guid = &gEfiPxeBaseCodeCallbackProtocolGuid }, 445 { .efi_guid_name = "serial io", 446 .efi_guid = &gEfiSerialIoProtocolGuid }, 447 { .efi_guid_name = "serial device type", 448 .efi_guid = &gEfiSerialTerminalDeviceTypeGuid }, 449 { .efi_guid_name = "loaded image", 450 .efi_guid = &gEfiLoadedImageProtocolGuid }, 451 { .efi_guid_name = "loaded image device path", 452 .efi_guid = &gEfiLoadedImageDevicePathProtocolGuid }, 453 { .efi_guid_name = "ISA ACPI", 454 .efi_guid = &gEfiIsaAcpiProtocolGuid }, 455 { .efi_guid_name = "ISA io", 456 .efi_guid = &gEfiIsaIoProtocolGuid }, 457 { .efi_guid_name = "Super io", .efi_guid = &gEfiSioProtocolGuid }, 458 { .efi_guid_name = "IDE controller init", 459 .efi_guid = &gEfiIdeControllerInitProtocolGuid }, 460 { .efi_guid_name = "PCI", 461 .efi_guid = &gEfiPciIoProtocolGuid }, 462 { .efi_guid_name = "PCI enumeration", 463 .efi_guid = &gEfiPciEnumerationCompleteProtocolGuid }, 464 { .efi_guid_name = "PCI root bridge", 465 .efi_guid = &gEfiPciRootBridgeIoProtocolGuid }, 466 { .efi_guid_name = "driver binding", 467 .efi_guid = &gEfiDriverBindingProtocolGuid }, 468 { .efi_guid_name = "driver configuration", 469 .efi_guid = &gEfiDriverConfigurationProtocolGuid }, 470 { .efi_guid_name = "driver configuration2", 471 .efi_guid = &gEfiDriverConfiguration2ProtocolGuid }, 472 { .efi_guid_name = "driver diagnostics", 473 .efi_guid = &gEfiDriverDiagnosticsProtocolGuid }, 474 { .efi_guid_name = "driver diagnostics2", 475 .efi_guid = &gEfiDriverDiagnostics2ProtocolGuid }, 476 { .efi_guid_name = "driver override", 477 .efi_guid = &gEfiPlatformDriverOverrideProtocolGuid }, 478 { .efi_guid_name = "bus specific driver override", 479 .efi_guid = &gEfiBusSpecificDriverOverrideProtocolGuid }, 480 { .efi_guid_name = "platform to driver configuration", 481 .efi_guid = &gEfiPlatformToDriverConfigurationProtocolGuid }, 482 { .efi_guid_name = "driver supported EFI version", 483 .efi_guid = &gEfiDriverSupportedEfiVersionProtocolGuid }, 484 { .efi_guid_name = "driver family override", 485 .efi_guid = &gEfiDriverFamilyOverrideProtocolGuid }, 486 { .efi_guid_name = "driver health", 487 .efi_guid = &gEfiDriverHealthProtocolGuid }, 488 { .efi_guid_name = "adapter information", 489 .efi_guid = &gEfiAdapterInformationProtocolGuid }, 490 { .efi_guid_name = "VLAN config", 491 .efi_guid = &gEfiVlanConfigProtocolGuid }, 492 { .efi_guid_name = "ARP service binding", 493 .efi_guid = &gEfiArpServiceBindingProtocolGuid }, 494 { .efi_guid_name = "ARP", 495 .efi_guid = &gEfiArpProtocolGuid }, 496 { .efi_guid_name = "IPv4 service binding", 497 .efi_guid = &gEfiIp4ServiceBindingProtocolGuid }, 498 { .efi_guid_name = "IPv4", 499 .efi_guid = &gEfiIp4ProtocolGuid }, 500 { .efi_guid_name = "IPv4 config", 501 .efi_guid = &gEfiIp4ConfigProtocolGuid }, 502 { .efi_guid_name = "IPv4 config2", 503 .efi_guid = &gEfiIp4Config2ProtocolGuid }, 504 { .efi_guid_name = "IPv6 service binding", 505 .efi_guid = &gEfiIp6ServiceBindingProtocolGuid }, 506 { .efi_guid_name = "IPv6", 507 .efi_guid = &gEfiIp6ProtocolGuid }, 508 { .efi_guid_name = "IPv6 config", 509 .efi_guid = &gEfiIp6ConfigProtocolGuid }, 510 { .efi_guid_name = "NVMe pass thru", 511 .efi_guid = &gEfiNvmExpressPassThruProtocolGuid }, 512 { .efi_guid_name = "UDPv4", 513 .efi_guid = &gEfiUdp4ProtocolGuid }, 514 { .efi_guid_name = "UDPv4 service binding", 515 .efi_guid = &gEfiUdp4ServiceBindingProtocolGuid }, 516 { .efi_guid_name = "UDPv6", 517 .efi_guid = &gEfiUdp6ProtocolGuid }, 518 { .efi_guid_name = "UDPv6 service binding", 519 .efi_guid = &gEfiUdp6ServiceBindingProtocolGuid }, 520 { .efi_guid_name = "TCPv4", 521 .efi_guid = &gEfiTcp4ProtocolGuid }, 522 { .efi_guid_name = "TCPv4 service binding", 523 .efi_guid = &gEfiTcp4ServiceBindingProtocolGuid }, 524 { .efi_guid_name = "TCPv6", 525 .efi_guid = &gEfiTcp6ProtocolGuid }, 526 { .efi_guid_name = "TCPv6 service binding", 527 .efi_guid = &gEfiTcp6ServiceBindingProtocolGuid }, 528 { .efi_guid_name = "EFI System partition", 529 .efi_guid = &gEfiPartTypeSystemPartGuid }, 530 { .efi_guid_name = "MBR legacy", 531 .efi_guid = &gEfiPartTypeLegacyMbrGuid }, 532 { .efi_guid_name = "USB io", 533 .efi_guid = &gEfiUsbIoProtocolGuid }, 534 { .efi_guid_name = "USB2 HC", 535 .efi_guid = &gEfiUsb2HcProtocolGuid }, 536 { .efi_guid_name = "component name", 537 .efi_guid = &gEfiComponentNameProtocolGuid }, 538 { .efi_guid_name = "component name2", 539 .efi_guid = &gEfiComponentName2ProtocolGuid }, 540 { .efi_guid_name = "decompress", 541 .efi_guid = &gEfiDecompressProtocolGuid }, 542 { .efi_guid_name = "ebc interpreter", 543 .efi_guid = &gEfiEbcProtocolGuid }, 544 { .efi_guid_name = "network interface identifier", 545 .efi_guid = &gEfiNetworkInterfaceIdentifierProtocolGuid }, 546 { .efi_guid_name = "network interface identifier_31", 547 .efi_guid = &gEfiNetworkInterfaceIdentifierProtocolGuid_31 }, 548 { .efi_guid_name = "managed network service binding", 549 .efi_guid = &gEfiManagedNetworkServiceBindingProtocolGuid }, 550 { .efi_guid_name = "managed network", 551 .efi_guid = &gEfiManagedNetworkProtocolGuid }, 552 { .efi_guid_name = "form browser", 553 .efi_guid = &gEfiFormBrowser2ProtocolGuid }, 554 { .efi_guid_name = "HII config access", 555 .efi_guid = &gEfiHiiConfigAccessProtocolGuid }, 556 { .efi_guid_name = "HII config keyword handler", 557 .efi_guid = &gEfiConfigKeywordHandlerProtocolGuid }, 558 { .efi_guid_name = "HII config routing", 559 .efi_guid = &gEfiHiiConfigRoutingProtocolGuid }, 560 { .efi_guid_name = "HII database", 561 .efi_guid = &gEfiHiiDatabaseProtocolGuid }, 562 { .efi_guid_name = "HII string", 563 .efi_guid = &gEfiHiiStringProtocolGuid }, 564 { .efi_guid_name = "HII image", 565 .efi_guid = &gEfiHiiImageProtocolGuid }, 566 { .efi_guid_name = "HII font", 567 .efi_guid = &gEfiHiiFontProtocolGuid }, 568 { .efi_guid_name = "MTFTP3 service binding", 569 .efi_guid = &gEfiMtftp4ServiceBindingProtocolGuid }, 570 { .efi_guid_name = "MTFTP4", 571 .efi_guid = &gEfiMtftp4ProtocolGuid }, 572 { .efi_guid_name = "MTFTP6 service binding", 573 .efi_guid = &gEfiMtftp6ServiceBindingProtocolGuid }, 574 { .efi_guid_name = "MTFTP6", 575 .efi_guid = &gEfiMtftp6ProtocolGuid }, 576 { .efi_guid_name = "DHCP4 service binding", 577 .efi_guid = &gEfiDhcp4ServiceBindingProtocolGuid }, 578 { .efi_guid_name = "DHCP4", 579 .efi_guid = &gEfiDhcp4ProtocolGuid }, 580 { .efi_guid_name = "DHCP6 service binding", 581 .efi_guid = &gEfiDhcp6ServiceBindingProtocolGuid }, 582 { .efi_guid_name = "DHCP6", 583 .efi_guid = &gEfiDhcp6ProtocolGuid }, 584 { .efi_guid_name = "SCSI io", 585 .efi_guid = &gEfiScsiIoProtocolGuid }, 586 { .efi_guid_name = "SCSI pass thru", 587 .efi_guid = &gEfiScsiPassThruProtocolGuid }, 588 { .efi_guid_name = "SCSI pass thru ext", 589 .efi_guid = &gEfiExtScsiPassThruProtocolGuid }, 590 { .efi_guid_name = "Capsule arch", 591 .efi_guid = &gEfiCapsuleArchProtocolGuid }, 592 { .efi_guid_name = "monotonic counter arch", 593 .efi_guid = &gEfiMonotonicCounterArchProtocolGuid }, 594 { .efi_guid_name = "realtime clock arch", 595 .efi_guid = &gEfiRealTimeClockArchProtocolGuid }, 596 { .efi_guid_name = "variable arch", 597 .efi_guid = &gEfiVariableArchProtocolGuid }, 598 { .efi_guid_name = "variable write arch", 599 .efi_guid = &gEfiVariableWriteArchProtocolGuid }, 600 { .efi_guid_name = "watchdog timer arch", 601 .efi_guid = &gEfiWatchdogTimerArchProtocolGuid }, 602 { .efi_guid_name = "BDS arch", 603 .efi_guid = &gEfiBdsArchProtocolGuid }, 604 { .efi_guid_name = "metronome arch", 605 .efi_guid = &gEfiMetronomeArchProtocolGuid }, 606 { .efi_guid_name = "timer arch", 607 .efi_guid = &gEfiTimerArchProtocolGuid }, 608 { .efi_guid_name = "DPC", 609 .efi_guid = &gEfiDpcProtocolGuid }, 610 { .efi_guid_name = "print2", 611 .efi_guid = &gEfiPrint2SProtocolGuid }, 612 { .efi_guid_name = "device path to text", 613 .efi_guid = &gEfiDevicePathToTextProtocolGuid }, 614 { .efi_guid_name = "reset arch", 615 .efi_guid = &gEfiResetArchProtocolGuid }, 616 { .efi_guid_name = "CPU arch", 617 .efi_guid = &gEfiCpuArchProtocolGuid }, 618 { .efi_guid_name = "CPU IO2", 619 .efi_guid = &gEfiCpuIo2ProtocolGuid }, 620 { .efi_guid_name = "Legacy 8259", 621 .efi_guid = &gEfiLegacy8259ProtocolGuid }, 622 { .efi_guid_name = "Security arch", 623 .efi_guid = &gEfiSecurityArchProtocolGuid }, 624 { .efi_guid_name = "Security2 arch", 625 .efi_guid = &gEfiSecurity2ArchProtocolGuid }, 626 { .efi_guid_name = "Security Policy", 627 .efi_guid = &gEfiSecurityPolicyProtocolGuid }, 628 { .efi_guid_name = "Runtime arch", 629 .efi_guid = &gEfiRuntimeArchProtocolGuid }, 630 { .efi_guid_name = "status code runtime", 631 .efi_guid = &gEfiStatusCodeRuntimeProtocolGuid }, 632 { .efi_guid_name = "storage security command", 633 .efi_guid = &gEfiStorageSecurityCommandProtocolGuid }, 634 { .efi_guid_name = "data hub", 635 .efi_guid = &gEfiDataHubProtocolGuid }, 636 { .efi_guid_name = "PCD", 637 .efi_guid = &gPcdProtocolGuid }, 638 { .efi_guid_name = "EFI PCD", 639 .efi_guid = &gEfiPcdProtocolGuid }, 640 { .efi_guid_name = "firmware volume block", 641 .efi_guid = &gEfiFirmwareVolumeBlockProtocolGuid }, 642 { .efi_guid_name = "firmware volume2", 643 .efi_guid = &gEfiFirmwareVolumeBlock2ProtocolGuid }, 644 { .efi_guid_name = "lzma compress", 645 .efi_guid = &gLzmaCompress }, 646 { .efi_guid_name = "MP services", 647 .efi_guid = &gEfiMpServiceProtocolGuid }, 648 { .efi_guid_name = MTC_VARIABLE_NAME, 649 .efi_guid = &gMtcVendorGuid }, 650 { .efi_guid_name = "Active EDID", 651 .efi_guid = &gEfiEdidActiveProtocolGuid }, 652 { .efi_guid_name = "Discovered EDID", 653 .efi_guid = &gEfiEdidDiscoveredProtocolGuid }, 654 { .efi_guid_name = "key management service", 655 .efi_guid = &gEfiKmsProtocolGuid }, 656 { .efi_guid_name = "smart card reader", 657 .efi_guid = &gEfiSmartCardReaderProtocolGuid }, 658 { .efi_guid_name = "rng source", 659 .efi_guid = &gEfiRngProtocolGuid }, 660 { .efi_guid_name = "IPsec config", 661 .efi_guid = &gEfiIpSecConfigProtocolGuid }, 662 { .efi_guid_name = "IPsec", 663 .efi_guid = &gEfiIpSecProtocolGuid }, 664 { .efi_guid_name = "IPsec2", 665 .efi_guid = &gEfiIpSec2ProtocolGuid }, 666 { .efi_guid_name = "TCG2 tpm", 667 .efi_guid = &gEfiTcg2ProtocolGuid } 668 }; 669 670 bool 671 efi_guid_to_str(const EFI_GUID *guid, char **sp) 672 { 673 uint32_t status; 674 675 uuid_to_string((const uuid_t *)guid, sp, &status); 676 return (status == uuid_s_ok ? true : false); 677 } 678 679 bool 680 efi_str_to_guid(const char *s, EFI_GUID *guid) 681 { 682 uint32_t status; 683 684 uuid_from_string(s, (uuid_t *)guid, &status); 685 return (status == uuid_s_ok ? true : false); 686 } 687 688 bool 689 efi_name_to_guid(const char *name, EFI_GUID *guid) 690 { 691 uint32_t i; 692 693 for (i = 0; i < nitems(efi_uuid_mapping); i++) { 694 if (strcasecmp(name, efi_uuid_mapping[i].efi_guid_name) == 0) { 695 *guid = *efi_uuid_mapping[i].efi_guid; 696 return (true); 697 } 698 } 699 return (efi_str_to_guid(name, guid)); 700 } 701 702 bool 703 efi_guid_to_name(EFI_GUID *guid, char **name) 704 { 705 uint32_t i; 706 int rv; 707 708 for (i = 0; i < nitems(efi_uuid_mapping); i++) { 709 rv = uuid_equal((uuid_t *)guid, 710 (uuid_t *)efi_uuid_mapping[i].efi_guid, NULL); 711 if (rv != 0) { 712 *name = strdup(efi_uuid_mapping[i].efi_guid_name); 713 if (*name == NULL) 714 return (false); 715 return (true); 716 } 717 } 718 return (efi_guid_to_str(guid, name)); 719 } 720 721 void 722 efi_init_environment(void) 723 { 724 char var[128]; 725 726 snprintf(var, sizeof (var), "%d.%02d", ST->Hdr.Revision >> 16, 727 ST->Hdr.Revision & 0xffff); 728 env_setenv("efi-version", EV_VOLATILE, var, env_noset, env_nounset); 729 } 730 731 COMMAND_SET(efishow, "efi-show", "print some or all EFI variables", 732 command_efi_show); 733 734 static int 735 efi_print_other_value(uint8_t *data, UINTN datasz) 736 { 737 UINTN i; 738 bool is_ascii = true; 739 740 printf(" = "); 741 for (i = 0; i < datasz - 1; i++) { 742 /* 743 * Quick hack to see if this ascii-ish string is printable 744 * range plus tab, cr and lf. 745 */ 746 if ((data[i] < 32 || data[i] > 126) && 747 data[i] != 9 && data[i] != 10 && data[i] != 13) { 748 is_ascii = false; 749 break; 750 } 751 } 752 if (data[datasz - 1] != '\0') 753 is_ascii = false; 754 if (is_ascii == true) { 755 printf("%s", data); 756 if (pager_output("\n")) 757 return (CMD_WARN); 758 } else { 759 if (pager_output("\n")) 760 return (CMD_WARN); 761 /* 762 * Dump hex bytes grouped by 4. 763 */ 764 for (i = 0; i < datasz; i++) { 765 printf("%02x ", data[i]); 766 if ((i + 1) % 4 == 0) 767 printf(" "); 768 if ((i + 1) % 20 == 0) { 769 if (pager_output("\n")) 770 return (CMD_WARN); 771 } 772 } 773 if (pager_output("\n")) 774 return (CMD_WARN); 775 } 776 777 return (CMD_OK); 778 } 779 780 /* This appears to be some sort of UEFI shell alias table. */ 781 static int 782 efi_print_shell_str(const CHAR16 *varnamearg __unused, uint8_t *data, 783 UINTN datasz __unused) 784 { 785 printf(" = %S", (CHAR16 *)data); 786 if (pager_output("\n")) 787 return (CMD_WARN); 788 return (CMD_OK); 789 } 790 791 const char * 792 efi_memory_type(EFI_MEMORY_TYPE type) 793 { 794 const char *types[] = { 795 "Reserved", 796 "LoaderCode", 797 "LoaderData", 798 "BootServicesCode", 799 "BootServicesData", 800 "RuntimeServicesCode", 801 "RuntimeServicesData", 802 "ConventionalMemory", 803 "UnusableMemory", 804 "ACPIReclaimMemory", 805 "ACPIMemoryNVS", 806 "MemoryMappedIO", 807 "MemoryMappedIOPortSpace", 808 "PalCode", 809 "PersistentMemory" 810 }; 811 812 switch (type) { 813 case EfiReservedMemoryType: 814 case EfiLoaderCode: 815 case EfiLoaderData: 816 case EfiBootServicesCode: 817 case EfiBootServicesData: 818 case EfiRuntimeServicesCode: 819 case EfiRuntimeServicesData: 820 case EfiConventionalMemory: 821 case EfiUnusableMemory: 822 case EfiACPIReclaimMemory: 823 case EfiACPIMemoryNVS: 824 case EfiMemoryMappedIO: 825 case EfiMemoryMappedIOPortSpace: 826 case EfiPalCode: 827 case EfiPersistentMemory: 828 return (types[type]); 829 default: 830 return ("Unknown"); 831 } 832 } 833 834 /* Print memory type table. */ 835 static int 836 efi_print_mem_type(const CHAR16 *varnamearg __unused, uint8_t *data, 837 UINTN datasz) 838 { 839 int i, n; 840 EFI_MEMORY_TYPE_INFORMATION *ti; 841 842 ti = (EFI_MEMORY_TYPE_INFORMATION *)data; 843 if (pager_output(" = \n")) 844 return (CMD_WARN); 845 846 n = datasz / sizeof (EFI_MEMORY_TYPE_INFORMATION); 847 for (i = 0; i < n && ti[i].NumberOfPages != 0; i++) { 848 printf("\t%23s pages: %u", efi_memory_type(ti[i].Type), 849 ti[i].NumberOfPages); 850 if (pager_output("\n")) 851 return (CMD_WARN); 852 } 853 854 return (CMD_OK); 855 } 856 857 /* 858 * Print illumos variables. 859 * We have LoaderPath and LoaderDev as CHAR16 strings. 860 */ 861 static int 862 efi_print_illumos(const CHAR16 *varnamearg, uint8_t *data, 863 UINTN datasz __unused) 864 { 865 int rv = -1; 866 char *var = NULL; 867 868 if (ucs2_to_utf8(varnamearg, &var) != 0) 869 return (CMD_ERROR); 870 871 if (strcmp("LoaderPath", var) == 0 || 872 strcmp("LoaderDev", var) == 0) { 873 printf(" = "); 874 printf("%S", (CHAR16 *)data); 875 876 if (pager_output("\n")) 877 rv = CMD_WARN; 878 else 879 rv = CMD_OK; 880 } 881 882 free(var); 883 return (rv); 884 } 885 886 /* Print global variables. */ 887 static int 888 efi_print_global(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) 889 { 890 int rv = -1; 891 char *var = NULL; 892 893 if (ucs2_to_utf8(varnamearg, &var) != 0) 894 return (CMD_ERROR); 895 896 if (strcmp("AuditMode", var) == 0) { 897 printf(" = "); 898 printf("0x%x", *data); /* 8-bit int */ 899 goto done; 900 } 901 902 if (strcmp("BootOptionSupport", var) == 0) { 903 printf(" = "); 904 printf("0x%x", *((uint32_t *)data)); /* UINT32 */ 905 goto done; 906 } 907 908 if (strcmp("BootCurrent", var) == 0 || 909 strcmp("BootNext", var) == 0 || 910 strcmp("Timeout", var) == 0) { 911 printf(" = "); 912 printf("%u", *((uint16_t *)data)); /* UINT16 */ 913 goto done; 914 } 915 916 if (strcmp("BootOrder", var) == 0 || 917 strcmp("DriverOrder", var) == 0) { 918 int i; 919 UINT16 *u16 = (UINT16 *)data; 920 921 printf(" ="); 922 for (i = 0; i < datasz / sizeof (UINT16); i++) 923 printf(" %u", u16[i]); 924 goto done; 925 } 926 if (strncmp("Boot", var, 4) == 0 || 927 strncmp("Driver", var, 5) == 0 || 928 strncmp("SysPrep", var, 7) == 0 || 929 strncmp("OsRecovery", var, 10) == 0) { 930 UINT16 filepathlistlen; 931 CHAR16 *text; 932 int desclen; 933 EFI_DEVICE_PATH *dp; 934 935 data += sizeof (UINT32); 936 filepathlistlen = *(uint16_t *)data; 937 data += sizeof (UINT16); 938 text = (CHAR16 *)data; 939 940 for (desclen = 0; text[desclen] != 0; desclen++) 941 ; 942 if (desclen != 0) { 943 /* Add terminating zero and we have CHAR16. */ 944 desclen = (desclen + 1) * 2; 945 } 946 947 printf(" = "); 948 printf("%S", text); 949 if (filepathlistlen != 0) { 950 /* Output pathname from new line. */ 951 if (pager_output("\n")) { 952 rv = CMD_WARN; 953 goto done; 954 } 955 dp = malloc(filepathlistlen); 956 if (dp == NULL) 957 goto done; 958 959 memcpy(dp, data + desclen, filepathlistlen); 960 text = efi_devpath_name(dp); 961 if (text != NULL) { 962 printf("\t%S", text); 963 efi_free_devpath_name(text); 964 } 965 free(dp); 966 } 967 goto done; 968 } 969 970 if (strcmp("ConIn", var) == 0 || 971 strcmp("ConInDev", var) == 0 || 972 strcmp("ConOut", var) == 0 || 973 strcmp("ConOutDev", var) == 0 || 974 strcmp("ErrOut", var) == 0 || 975 strcmp("ErrOutDev", var) == 0) { 976 CHAR16 *text; 977 978 printf(" = "); 979 text = efi_devpath_name((EFI_DEVICE_PATH *)data); 980 if (text != NULL) { 981 printf("%S", text); 982 efi_free_devpath_name(text); 983 } 984 goto done; 985 } 986 987 if (strcmp("PlatformLang", var) == 0 || 988 strcmp("PlatformLangCodes", var) == 0 || 989 strcmp("LangCodes", var) == 0 || 990 strcmp("Lang", var) == 0) { 991 printf(" = "); 992 printf("%s", data); /* ASCII string */ 993 goto done; 994 } 995 996 /* 997 * Feature bitmap from firmware to OS. 998 * Older UEFI provides UINT32, newer UINT64. 999 */ 1000 if (strcmp("OsIndicationsSupported", var) == 0) { 1001 printf(" = "); 1002 if (datasz == 4) 1003 printf("0x%x", *((uint32_t *)data)); 1004 else 1005 printf("0x%jx", *((uint64_t *)data)); 1006 goto done; 1007 } 1008 1009 /* Fallback for anything else. */ 1010 rv = efi_print_other_value(data, datasz); 1011 done: 1012 if (rv == -1) { 1013 if (pager_output("\n")) 1014 rv = CMD_WARN; 1015 else 1016 rv = CMD_OK; 1017 } 1018 free(var); 1019 return (rv); 1020 } 1021 1022 static void 1023 efi_print_var_attr(UINT32 attr) 1024 { 1025 bool comma = false; 1026 1027 if (attr & EFI_VARIABLE_NON_VOLATILE) { 1028 printf("NV"); 1029 comma = true; 1030 } 1031 if (attr & EFI_VARIABLE_BOOTSERVICE_ACCESS) { 1032 if (comma == true) 1033 printf(","); 1034 printf("BS"); 1035 comma = true; 1036 } 1037 if (attr & EFI_VARIABLE_RUNTIME_ACCESS) { 1038 if (comma == true) 1039 printf(","); 1040 printf("RS"); 1041 comma = true; 1042 } 1043 if (attr & EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 1044 if (comma == true) 1045 printf(","); 1046 printf("HR"); 1047 comma = true; 1048 } 1049 if (attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { 1050 if (comma == true) 1051 printf(","); 1052 printf("AT"); 1053 comma = true; 1054 } 1055 } 1056 1057 static int 1058 efi_print_var(CHAR16 *varnamearg, EFI_GUID *matchguid, int lflag) 1059 { 1060 UINTN datasz; 1061 EFI_STATUS status; 1062 UINT32 attr; 1063 char *str; 1064 uint8_t *data; 1065 int rv = CMD_OK; 1066 1067 str = NULL; 1068 datasz = 0; 1069 status = RS->GetVariable(varnamearg, matchguid, &attr, &datasz, NULL); 1070 if (status != EFI_BUFFER_TOO_SMALL) { 1071 printf("Can't get the variable: error %#lx\n", 1072 DECODE_ERROR(status)); 1073 return (CMD_ERROR); 1074 } 1075 data = malloc(datasz); 1076 if (data == NULL) { 1077 printf("Out of memory\n"); 1078 return (CMD_ERROR); 1079 } 1080 1081 status = RS->GetVariable(varnamearg, matchguid, &attr, &datasz, data); 1082 if (status != EFI_SUCCESS) { 1083 printf("Can't get the variable: error %#lx\n", 1084 DECODE_ERROR(status)); 1085 free(data); 1086 return (CMD_ERROR); 1087 } 1088 1089 if (efi_guid_to_name(matchguid, &str) == false) { 1090 rv = CMD_ERROR; 1091 goto done; 1092 } 1093 printf("%s ", str); 1094 efi_print_var_attr(attr); 1095 printf(" %S", varnamearg); 1096 1097 if (lflag == 0) { 1098 if (strcmp(str, "global") == 0) 1099 rv = efi_print_global(varnamearg, data, datasz); 1100 else if (strcmp(str, "illumos") == 0) 1101 rv = efi_print_illumos(varnamearg, data, datasz); 1102 else if (strcmp(str, 1103 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME) == 0) 1104 rv = efi_print_mem_type(varnamearg, data, datasz); 1105 else if (strcmp(str, 1106 "47c7b227-c42a-11d2-8e57-00a0c969723b") == 0) 1107 rv = efi_print_shell_str(varnamearg, data, datasz); 1108 else if (strcmp(str, MTC_VARIABLE_NAME) == 0) { 1109 printf(" = "); 1110 printf("%u", *((uint32_t *)data)); /* UINT32 */ 1111 rv = CMD_OK; 1112 if (pager_output("\n")) 1113 rv = CMD_WARN; 1114 } else 1115 rv = efi_print_other_value(data, datasz); 1116 } else if (pager_output("\n")) 1117 rv = CMD_WARN; 1118 1119 done: 1120 free(str); 1121 free(data); 1122 return (rv); 1123 } 1124 1125 static int 1126 command_efi_show(int argc, char *argv[]) 1127 { 1128 /* 1129 * efi-show [-a] 1130 * print all the env 1131 * efi-show -g UUID 1132 * print all the env vars tagged with UUID 1133 * efi-show -v var 1134 * search all the env vars and print the ones matching var 1135 * efi-show -g UUID -v var 1136 * efi-show UUID var 1137 * print all the env vars that match UUID and var 1138 */ 1139 /* NB: We assume EFI_GUID is the same as uuid_t */ 1140 int aflag = 0, gflag = 0, lflag = 0, vflag = 0; 1141 int ch, rv; 1142 unsigned i; 1143 EFI_STATUS status; 1144 EFI_GUID varguid = ZERO_GUID; 1145 EFI_GUID matchguid = ZERO_GUID; 1146 CHAR16 *varname; 1147 CHAR16 *newnm; 1148 CHAR16 varnamearg[128]; 1149 UINTN varalloc; 1150 UINTN varsz; 1151 1152 optind = 1; 1153 optreset = 1; 1154 opterr = 1; 1155 1156 while ((ch = getopt(argc, argv, "ag:lv:")) != -1) { 1157 switch (ch) { 1158 case 'a': 1159 aflag = 1; 1160 break; 1161 case 'g': 1162 gflag = 1; 1163 if (efi_name_to_guid(optarg, &matchguid) == false) { 1164 printf("uuid %s could not be parsed\n", optarg); 1165 return (CMD_ERROR); 1166 } 1167 break; 1168 case 'l': 1169 lflag = 1; 1170 break; 1171 case 'v': 1172 vflag = 1; 1173 if (strlen(optarg) >= nitems(varnamearg)) { 1174 printf("Variable %s is longer than %zu " 1175 "characters\n", optarg, nitems(varnamearg)); 1176 return (CMD_ERROR); 1177 } 1178 cpy8to16(optarg, varnamearg, nitems(varnamearg)); 1179 break; 1180 default: 1181 return (CMD_ERROR); 1182 } 1183 } 1184 1185 if (argc == 1) /* default is -a */ 1186 aflag = 1; 1187 1188 if (aflag && (gflag || vflag)) { 1189 printf("-a isn't compatible with -g or -v\n"); 1190 return (CMD_ERROR); 1191 } 1192 1193 if (aflag && optind < argc) { 1194 printf("-a doesn't take any args\n"); 1195 return (CMD_ERROR); 1196 } 1197 1198 argc -= optind; 1199 argv += optind; 1200 1201 pager_open(); 1202 if (vflag && gflag) { 1203 rv = efi_print_var(varnamearg, &matchguid, lflag); 1204 if (rv == CMD_WARN) 1205 rv = CMD_OK; 1206 pager_close(); 1207 return (rv); 1208 } 1209 1210 if (argc == 2) { 1211 optarg = argv[0]; 1212 if (strlen(optarg) >= nitems(varnamearg)) { 1213 printf("Variable %s is longer than %zu characters\n", 1214 optarg, nitems(varnamearg)); 1215 pager_close(); 1216 return (CMD_ERROR); 1217 } 1218 for (i = 0; i < strlen(optarg); i++) 1219 varnamearg[i] = optarg[i]; 1220 varnamearg[i] = 0; 1221 optarg = argv[1]; 1222 if (efi_name_to_guid(optarg, &matchguid) == false) { 1223 printf("uuid %s could not be parsed\n", optarg); 1224 pager_close(); 1225 return (CMD_ERROR); 1226 } 1227 rv = efi_print_var(varnamearg, &matchguid, lflag); 1228 if (rv == CMD_WARN) 1229 rv = CMD_OK; 1230 pager_close(); 1231 return (rv); 1232 } 1233 1234 if (argc > 0) { 1235 printf("Too many args: %d\n", argc); 1236 pager_close(); 1237 return (CMD_ERROR); 1238 } 1239 1240 /* 1241 * Initiate the search -- note the standard takes pain 1242 * to specify the initial call must be a poiner to a NULL 1243 * character. 1244 */ 1245 varalloc = 1024; 1246 varname = malloc(varalloc); 1247 if (varname == NULL) { 1248 printf("Can't allocate memory to get variables\n"); 1249 pager_close(); 1250 return (CMD_ERROR); 1251 } 1252 varname[0] = 0; 1253 while (1) { 1254 varsz = varalloc; 1255 status = RS->GetNextVariableName(&varsz, varname, &varguid); 1256 if (status == EFI_BUFFER_TOO_SMALL) { 1257 varalloc = varsz; 1258 newnm = realloc(varname, varalloc); 1259 if (newnm == NULL) { 1260 printf("Can't allocate memory to get " 1261 "variables\n"); 1262 rv = CMD_ERROR; 1263 break; 1264 } 1265 varname = newnm; 1266 continue; /* Try again with bigger buffer */ 1267 } 1268 if (status == EFI_NOT_FOUND) { 1269 rv = CMD_OK; 1270 break; 1271 } 1272 if (status != EFI_SUCCESS) { 1273 rv = CMD_ERROR; 1274 break; 1275 } 1276 1277 if (aflag) { 1278 rv = efi_print_var(varname, &varguid, lflag); 1279 if (rv != CMD_OK) { 1280 if (rv == CMD_WARN) 1281 rv = CMD_OK; 1282 break; 1283 } 1284 continue; 1285 } 1286 if (vflag) { 1287 if (wcscmp(varnamearg, varname) == 0) { 1288 rv = efi_print_var(varname, &varguid, lflag); 1289 if (rv != CMD_OK) { 1290 if (rv == CMD_WARN) 1291 rv = CMD_OK; 1292 break; 1293 } 1294 continue; 1295 } 1296 } 1297 if (gflag) { 1298 rv = uuid_equal((uuid_t *)&varguid, 1299 (uuid_t *)&matchguid, NULL); 1300 if (rv != 0) { 1301 rv = efi_print_var(varname, &varguid, lflag); 1302 if (rv != CMD_OK) { 1303 if (rv == CMD_WARN) 1304 rv = CMD_OK; 1305 break; 1306 } 1307 continue; 1308 } 1309 } 1310 } 1311 free(varname); 1312 pager_close(); 1313 1314 return (rv); 1315 } 1316 1317 COMMAND_SET(efiset, "efi-set", "set EFI variables", command_efi_set); 1318 1319 static int 1320 command_efi_set(int argc, char *argv[]) 1321 { 1322 char *uuid, *var, *val; 1323 CHAR16 wvar[128]; 1324 EFI_GUID guid; 1325 #if defined(ENABLE_UPDATES) 1326 EFI_STATUS err; 1327 #endif 1328 1329 if (argc != 4) { 1330 printf("efi-set uuid var new-value\n"); 1331 return (CMD_ERROR); 1332 } 1333 uuid = argv[1]; 1334 var = argv[2]; 1335 val = argv[3]; 1336 if (efi_name_to_guid(uuid, &guid) == false) { 1337 printf("Invalid uuid %s\n", uuid); 1338 return (CMD_ERROR); 1339 } 1340 cpy8to16(var, wvar, nitems(wvar)); 1341 #if defined(ENABLE_UPDATES) 1342 err = RS->SetVariable(wvar, &guid, EFI_VARIABLE_NON_VOLATILE | 1343 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1344 strlen(val) + 1, val); 1345 if (EFI_ERROR(err)) { 1346 printf("Failed to set variable: error %lu\n", 1347 DECODE_ERROR(err)); 1348 return (CMD_ERROR); 1349 } 1350 #else 1351 printf("would set %s %s = %s\n", uuid, var, val); 1352 #endif 1353 return (CMD_OK); 1354 } 1355 1356 COMMAND_SET(efiunset, "efi-unset", "delete / unset EFI variables", 1357 command_efi_unset); 1358 1359 static int 1360 command_efi_unset(int argc, char *argv[]) 1361 { 1362 char *uuid, *var; 1363 CHAR16 wvar[128]; 1364 EFI_GUID guid; 1365 #if defined(ENABLE_UPDATES) 1366 EFI_STATUS err; 1367 #endif 1368 1369 if (argc != 3) { 1370 printf("efi-unset uuid var\n"); 1371 return (CMD_ERROR); 1372 } 1373 uuid = argv[1]; 1374 var = argv[2]; 1375 if (efi_name_to_guid(uuid, &guid) == false) { 1376 printf("Invalid uuid %s\n", uuid); 1377 return (CMD_ERROR); 1378 } 1379 cpy8to16(var, wvar, nitems(wvar)); 1380 #if defined(ENABLE_UPDATES) 1381 err = RS->SetVariable(wvar, &guid, 0, 0, NULL); 1382 if (EFI_ERROR(err)) { 1383 printf("Failed to unset variable: error %lu\n", 1384 DECODE_ERROR(err)); 1385 return (CMD_ERROR); 1386 } 1387 #else 1388 printf("would unset %s %s \n", uuid, var); 1389 #endif 1390 return (CMD_OK); 1391 } 1392 1393 /* 1394 * Loader interaction words and extras 1395 * 1396 * efi-setenv ( value n name n guid n attr -- 0 | -1) 1397 * efi-getenv ( guid n addr n -- addr' n' | -1 ) 1398 * efi-unsetenv ( name n guid n'' -- ) 1399 */ 1400 1401 /* 1402 * efi-setenv 1403 * efi-setenv ( value n name n guid n attr -- 0 | -1) 1404 * 1405 * Set environment variables using the SetVariable EFI runtime service. 1406 * 1407 * Value and guid are passed through in binary form (so guid needs to be 1408 * converted to binary form from its string form). Name is converted from 1409 * ASCII to CHAR16. Since ficl doesn't have support for internationalization, 1410 * there's no native CHAR16 interface provided. 1411 * 1412 * attr is an int in the bitmask of the following attributes for this variable. 1413 * 1414 * 1 Non volatile 1415 * 2 Boot service access 1416 * 4 Run time access 1417 * (corresponding to the same bits in the UEFI spec). 1418 */ 1419 static void 1420 ficlEfiSetenv(ficlVm *pVM) 1421 { 1422 char *value = NULL, *guid = NULL; 1423 CHAR16 *name = NULL; 1424 int i; 1425 char *namep, *valuep, *guidp; 1426 int names, values, guids, attr; 1427 EFI_STATUS status; 1428 uuid_t u; 1429 uint32_t ustatus; 1430 char *error = NULL; 1431 ficlStack *pStack = ficlVmGetDataStack(pVM); 1432 1433 FICL_STACK_CHECK(pStack, 6, 0); 1434 1435 attr = ficlStackPopInteger(pStack); 1436 guids = ficlStackPopInteger(pStack); 1437 guidp = (char *)ficlStackPopPointer(pStack); 1438 names = ficlStackPopInteger(pStack); 1439 namep = (char *)ficlStackPopPointer(pStack); 1440 values = ficlStackPopInteger(pStack); 1441 valuep = (char *)ficlStackPopPointer(pStack); 1442 1443 guid = ficlMalloc(guids); 1444 if (guid == NULL) 1445 goto out; 1446 memcpy(guid, guidp, guids); 1447 uuid_from_string(guid, &u, &ustatus); 1448 if (ustatus != uuid_s_ok) { 1449 switch (ustatus) { 1450 case uuid_s_bad_version: 1451 error = "uuid: bad string"; 1452 break; 1453 case uuid_s_invalid_string_uuid: 1454 error = "uuid: invalid string"; 1455 break; 1456 case uuid_s_no_memory: 1457 error = "Out of memory"; 1458 break; 1459 default: 1460 error = "uuid: Unknown error"; 1461 break; 1462 } 1463 ficlStackPushInteger(pStack, -1); 1464 goto out; 1465 } 1466 1467 name = ficlMalloc((names + 1) * sizeof (CHAR16)); 1468 if (name == NULL) { 1469 error = "Out of memory"; 1470 goto out; 1471 } 1472 for (i = 0; i < names; i++) 1473 name[i] = namep[i]; 1474 name[names] = 0; 1475 1476 value = ficlMalloc(values + 1); 1477 if (value == NULL) { 1478 error = "Out of memory"; 1479 goto out; 1480 } 1481 memcpy(value, valuep, values); 1482 1483 status = RS->SetVariable(name, (EFI_GUID *)&u, attr, values, value); 1484 if (status == EFI_SUCCESS) { 1485 ficlStackPushInteger(pStack, 0); 1486 } else { 1487 ficlStackPushInteger(pStack, -1); 1488 error = "Error: SetVariable failed"; 1489 } 1490 1491 out: 1492 ficlFree(name); 1493 ficlFree(value); 1494 ficlFree(guid); 1495 if (error != NULL) 1496 ficlVmThrowError(pVM, error); 1497 } 1498 1499 static void 1500 ficlEfiGetenv(ficlVm *pVM) 1501 { 1502 char *name, *value; 1503 char *namep; 1504 int names; 1505 1506 FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 2); 1507 1508 names = ficlStackPopInteger(ficlVmGetDataStack(pVM)); 1509 namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM)); 1510 1511 name = ficlMalloc(names+1); 1512 if (name == NULL) 1513 ficlVmThrowError(pVM, "Error: out of memory"); 1514 strncpy(name, namep, names); 1515 name[names] = '\0'; 1516 1517 value = getenv(name); 1518 ficlFree(name); 1519 1520 if (value != NULL) { 1521 ficlStackPushPointer(ficlVmGetDataStack(pVM), value); 1522 ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(value)); 1523 } else { 1524 ficlStackPushInteger(ficlVmGetDataStack(pVM), -1); 1525 } 1526 } 1527 1528 static void 1529 ficlEfiUnsetenv(ficlVm *pVM) 1530 { 1531 char *name; 1532 char *namep; 1533 int names; 1534 1535 FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0); 1536 1537 names = ficlStackPopInteger(ficlVmGetDataStack(pVM)); 1538 namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM)); 1539 1540 name = ficlMalloc(names+1); 1541 if (name == NULL) 1542 ficlVmThrowError(pVM, "Error: out of memory"); 1543 strncpy(name, namep, names); 1544 name[names] = '\0'; 1545 1546 unsetenv(name); 1547 ficlFree(name); 1548 } 1549 1550 /* 1551 * Build platform extensions into the system dictionary 1552 */ 1553 static void 1554 ficlEfiCompilePlatform(ficlSystem *pSys) 1555 { 1556 ficlDictionary *dp = ficlSystemGetDictionary(pSys); 1557 1558 FICL_SYSTEM_ASSERT(pSys, dp); 1559 1560 ficlDictionarySetPrimitive(dp, "efi-setenv", ficlEfiSetenv, 1561 FICL_WORD_DEFAULT); 1562 ficlDictionarySetPrimitive(dp, "efi-getenv", ficlEfiGetenv, 1563 FICL_WORD_DEFAULT); 1564 ficlDictionarySetPrimitive(dp, "efi-unsetenv", ficlEfiUnsetenv, 1565 FICL_WORD_DEFAULT); 1566 } 1567 1568 FICL_COMPILE_SET(ficlEfiCompilePlatform); 1569