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 #ifdef __LP64__ 730 env_setenv("efi-systype", EV_VOLATILE, "64", env_noset, env_nounset); 731 snprintf(var, sizeof (var), "0x%016lx", (uintptr_t)ST); 732 #else 733 env_setenv("efi-systype", EV_VOLATILE, "32", env_noset, env_nounset); 734 snprintf(var, sizeof (var), "0x%08x", (uintptr_t)ST); 735 #endif 736 env_setenv("efi-systab", EV_VOLATILE, var, env_noset, env_nounset); 737 } 738 739 COMMAND_SET(efishow, "efi-show", "print some or all EFI variables", 740 command_efi_show); 741 742 static int 743 efi_print_other_value(uint8_t *data, UINTN datasz) 744 { 745 UINTN i; 746 bool is_ascii = true; 747 748 printf(" = "); 749 for (i = 0; i < datasz - 1; i++) { 750 /* 751 * Quick hack to see if this ascii-ish string is printable 752 * range plus tab, cr and lf. 753 */ 754 if ((data[i] < 32 || data[i] > 126) && 755 data[i] != 9 && data[i] != 10 && data[i] != 13) { 756 is_ascii = false; 757 break; 758 } 759 } 760 if (data[datasz - 1] != '\0') 761 is_ascii = false; 762 if (is_ascii == true) { 763 printf("%s", data); 764 if (pager_output("\n")) 765 return (CMD_WARN); 766 } else { 767 if (pager_output("\n")) 768 return (CMD_WARN); 769 /* 770 * Dump hex bytes grouped by 4. 771 */ 772 for (i = 0; i < datasz; i++) { 773 printf("%02x ", data[i]); 774 if ((i + 1) % 4 == 0) 775 printf(" "); 776 if ((i + 1) % 20 == 0) { 777 if (pager_output("\n")) 778 return (CMD_WARN); 779 } 780 } 781 if (pager_output("\n")) 782 return (CMD_WARN); 783 } 784 785 return (CMD_OK); 786 } 787 788 /* This appears to be some sort of UEFI shell alias table. */ 789 static int 790 efi_print_shell_str(const CHAR16 *varnamearg __unused, uint8_t *data, 791 UINTN datasz __unused) 792 { 793 printf(" = %S", (CHAR16 *)data); 794 if (pager_output("\n")) 795 return (CMD_WARN); 796 return (CMD_OK); 797 } 798 799 const char * 800 efi_memory_type(EFI_MEMORY_TYPE type) 801 { 802 const char *types[] = { 803 "Reserved", 804 "LoaderCode", 805 "LoaderData", 806 "BootServicesCode", 807 "BootServicesData", 808 "RuntimeServicesCode", 809 "RuntimeServicesData", 810 "ConventionalMemory", 811 "UnusableMemory", 812 "ACPIReclaimMemory", 813 "ACPIMemoryNVS", 814 "MemoryMappedIO", 815 "MemoryMappedIOPortSpace", 816 "PalCode", 817 "PersistentMemory" 818 }; 819 820 switch (type) { 821 case EfiReservedMemoryType: 822 case EfiLoaderCode: 823 case EfiLoaderData: 824 case EfiBootServicesCode: 825 case EfiBootServicesData: 826 case EfiRuntimeServicesCode: 827 case EfiRuntimeServicesData: 828 case EfiConventionalMemory: 829 case EfiUnusableMemory: 830 case EfiACPIReclaimMemory: 831 case EfiACPIMemoryNVS: 832 case EfiMemoryMappedIO: 833 case EfiMemoryMappedIOPortSpace: 834 case EfiPalCode: 835 case EfiPersistentMemory: 836 return (types[type]); 837 default: 838 return ("Unknown"); 839 } 840 } 841 842 /* Print memory type table. */ 843 static int 844 efi_print_mem_type(const CHAR16 *varnamearg __unused, uint8_t *data, 845 UINTN datasz) 846 { 847 int i, n; 848 EFI_MEMORY_TYPE_INFORMATION *ti; 849 850 ti = (EFI_MEMORY_TYPE_INFORMATION *)data; 851 if (pager_output(" = \n")) 852 return (CMD_WARN); 853 854 n = datasz / sizeof (EFI_MEMORY_TYPE_INFORMATION); 855 for (i = 0; i < n && ti[i].NumberOfPages != 0; i++) { 856 printf("\t%23s pages: %u", efi_memory_type(ti[i].Type), 857 ti[i].NumberOfPages); 858 if (pager_output("\n")) 859 return (CMD_WARN); 860 } 861 862 return (CMD_OK); 863 } 864 865 /* 866 * Print illumos variables. 867 * We have LoaderPath and LoaderDev as CHAR16 strings. 868 */ 869 static int 870 efi_print_illumos(const CHAR16 *varnamearg, uint8_t *data, 871 UINTN datasz __unused) 872 { 873 int rv = -1; 874 char *var = NULL; 875 876 if (ucs2_to_utf8(varnamearg, &var) != 0) 877 return (CMD_ERROR); 878 879 if (strcmp("LoaderPath", var) == 0 || 880 strcmp("LoaderDev", var) == 0) { 881 printf(" = "); 882 printf("%S", (CHAR16 *)data); 883 884 if (pager_output("\n")) 885 rv = CMD_WARN; 886 else 887 rv = CMD_OK; 888 } 889 890 free(var); 891 return (rv); 892 } 893 894 /* Print global variables. */ 895 static int 896 efi_print_global(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) 897 { 898 int rv = -1; 899 char *var = NULL; 900 901 if (ucs2_to_utf8(varnamearg, &var) != 0) 902 return (CMD_ERROR); 903 904 if (strcmp("AuditMode", var) == 0) { 905 printf(" = "); 906 printf("0x%x", *data); /* 8-bit int */ 907 goto done; 908 } 909 910 if (strcmp("BootOptionSupport", var) == 0) { 911 printf(" = "); 912 printf("0x%x", *((uint32_t *)data)); /* UINT32 */ 913 goto done; 914 } 915 916 if (strcmp("BootCurrent", var) == 0 || 917 strcmp("BootNext", var) == 0 || 918 strcmp("Timeout", var) == 0) { 919 printf(" = "); 920 printf("%u", *((uint16_t *)data)); /* UINT16 */ 921 goto done; 922 } 923 924 if (strcmp("BootOrder", var) == 0 || 925 strcmp("DriverOrder", var) == 0) { 926 int i; 927 UINT16 *u16 = (UINT16 *)data; 928 929 printf(" ="); 930 for (i = 0; i < datasz / sizeof (UINT16); i++) 931 printf(" %u", u16[i]); 932 goto done; 933 } 934 if (strncmp("Boot", var, 4) == 0 || 935 strncmp("Driver", var, 5) == 0 || 936 strncmp("SysPrep", var, 7) == 0 || 937 strncmp("OsRecovery", var, 10) == 0) { 938 UINT16 filepathlistlen; 939 CHAR16 *text; 940 int desclen; 941 EFI_DEVICE_PATH *dp; 942 943 data += sizeof (UINT32); 944 filepathlistlen = *(uint16_t *)data; 945 data += sizeof (UINT16); 946 text = (CHAR16 *)data; 947 948 for (desclen = 0; text[desclen] != 0; desclen++) 949 ; 950 if (desclen != 0) { 951 /* Add terminating zero and we have CHAR16. */ 952 desclen = (desclen + 1) * 2; 953 } 954 955 printf(" = "); 956 printf("%S", text); 957 if (filepathlistlen != 0) { 958 /* Output pathname from new line. */ 959 if (pager_output("\n")) { 960 rv = CMD_WARN; 961 goto done; 962 } 963 dp = malloc(filepathlistlen); 964 if (dp == NULL) 965 goto done; 966 967 memcpy(dp, data + desclen, filepathlistlen); 968 text = efi_devpath_name(dp); 969 if (text != NULL) { 970 printf("\t%S", text); 971 efi_free_devpath_name(text); 972 } 973 free(dp); 974 } 975 goto done; 976 } 977 978 if (strcmp("ConIn", var) == 0 || 979 strcmp("ConInDev", var) == 0 || 980 strcmp("ConOut", var) == 0 || 981 strcmp("ConOutDev", var) == 0 || 982 strcmp("ErrOut", var) == 0 || 983 strcmp("ErrOutDev", var) == 0) { 984 CHAR16 *text; 985 986 printf(" = "); 987 text = efi_devpath_name((EFI_DEVICE_PATH *)data); 988 if (text != NULL) { 989 printf("%S", text); 990 efi_free_devpath_name(text); 991 } 992 goto done; 993 } 994 995 if (strcmp("PlatformLang", var) == 0 || 996 strcmp("PlatformLangCodes", var) == 0 || 997 strcmp("LangCodes", var) == 0 || 998 strcmp("Lang", var) == 0) { 999 printf(" = "); 1000 printf("%s", data); /* ASCII string */ 1001 goto done; 1002 } 1003 1004 /* 1005 * Feature bitmap from firmware to OS. 1006 * Older UEFI provides UINT32, newer UINT64. 1007 */ 1008 if (strcmp("OsIndicationsSupported", var) == 0) { 1009 printf(" = "); 1010 if (datasz == 4) 1011 printf("0x%x", *((uint32_t *)data)); 1012 else 1013 printf("0x%jx", *((uint64_t *)data)); 1014 goto done; 1015 } 1016 1017 /* Fallback for anything else. */ 1018 rv = efi_print_other_value(data, datasz); 1019 done: 1020 if (rv == -1) { 1021 if (pager_output("\n")) 1022 rv = CMD_WARN; 1023 else 1024 rv = CMD_OK; 1025 } 1026 free(var); 1027 return (rv); 1028 } 1029 1030 static void 1031 efi_print_var_attr(UINT32 attr) 1032 { 1033 bool comma = false; 1034 1035 if (attr & EFI_VARIABLE_NON_VOLATILE) { 1036 printf("NV"); 1037 comma = true; 1038 } 1039 if (attr & EFI_VARIABLE_BOOTSERVICE_ACCESS) { 1040 if (comma == true) 1041 printf(","); 1042 printf("BS"); 1043 comma = true; 1044 } 1045 if (attr & EFI_VARIABLE_RUNTIME_ACCESS) { 1046 if (comma == true) 1047 printf(","); 1048 printf("RS"); 1049 comma = true; 1050 } 1051 if (attr & EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 1052 if (comma == true) 1053 printf(","); 1054 printf("HR"); 1055 comma = true; 1056 } 1057 if (attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { 1058 if (comma == true) 1059 printf(","); 1060 printf("AT"); 1061 comma = true; 1062 } 1063 } 1064 1065 static int 1066 efi_print_var(CHAR16 *varnamearg, EFI_GUID *matchguid, int lflag) 1067 { 1068 UINTN datasz; 1069 EFI_STATUS status; 1070 UINT32 attr; 1071 char *str; 1072 uint8_t *data; 1073 int rv = CMD_OK; 1074 1075 str = NULL; 1076 datasz = 0; 1077 status = RS->GetVariable(varnamearg, matchguid, &attr, &datasz, NULL); 1078 if (status != EFI_BUFFER_TOO_SMALL) { 1079 printf("Can't get the variable: error %#lx\n", 1080 DECODE_ERROR(status)); 1081 return (CMD_ERROR); 1082 } 1083 data = malloc(datasz); 1084 if (data == NULL) { 1085 printf("Out of memory\n"); 1086 return (CMD_ERROR); 1087 } 1088 1089 status = RS->GetVariable(varnamearg, matchguid, &attr, &datasz, data); 1090 if (status != EFI_SUCCESS) { 1091 printf("Can't get the variable: error %#lx\n", 1092 DECODE_ERROR(status)); 1093 free(data); 1094 return (CMD_ERROR); 1095 } 1096 1097 if (efi_guid_to_name(matchguid, &str) == false) { 1098 rv = CMD_ERROR; 1099 goto done; 1100 } 1101 printf("%s ", str); 1102 efi_print_var_attr(attr); 1103 printf(" %S", varnamearg); 1104 1105 if (lflag == 0) { 1106 if (strcmp(str, "global") == 0) 1107 rv = efi_print_global(varnamearg, data, datasz); 1108 else if (strcmp(str, "illumos") == 0) 1109 rv = efi_print_illumos(varnamearg, data, datasz); 1110 else if (strcmp(str, 1111 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME) == 0) 1112 rv = efi_print_mem_type(varnamearg, data, datasz); 1113 else if (strcmp(str, 1114 "47c7b227-c42a-11d2-8e57-00a0c969723b") == 0) 1115 rv = efi_print_shell_str(varnamearg, data, datasz); 1116 else if (strcmp(str, MTC_VARIABLE_NAME) == 0) { 1117 printf(" = "); 1118 printf("%u", *((uint32_t *)data)); /* UINT32 */ 1119 rv = CMD_OK; 1120 if (pager_output("\n")) 1121 rv = CMD_WARN; 1122 } else 1123 rv = efi_print_other_value(data, datasz); 1124 } else if (pager_output("\n")) 1125 rv = CMD_WARN; 1126 1127 done: 1128 free(str); 1129 free(data); 1130 return (rv); 1131 } 1132 1133 static int 1134 command_efi_show(int argc, char *argv[]) 1135 { 1136 /* 1137 * efi-show [-a] 1138 * print all the env 1139 * efi-show -g UUID 1140 * print all the env vars tagged with UUID 1141 * efi-show -v var 1142 * search all the env vars and print the ones matching var 1143 * efi-show -g UUID -v var 1144 * efi-show UUID var 1145 * print all the env vars that match UUID and var 1146 */ 1147 /* NB: We assume EFI_GUID is the same as uuid_t */ 1148 int aflag = 0, gflag = 0, lflag = 0, vflag = 0; 1149 int ch, rv; 1150 unsigned i; 1151 EFI_STATUS status; 1152 EFI_GUID varguid = ZERO_GUID; 1153 EFI_GUID matchguid = ZERO_GUID; 1154 CHAR16 *varname; 1155 CHAR16 *newnm; 1156 CHAR16 varnamearg[128]; 1157 UINTN varalloc; 1158 UINTN varsz; 1159 1160 optind = 1; 1161 optreset = 1; 1162 opterr = 1; 1163 1164 while ((ch = getopt(argc, argv, "ag:lv:")) != -1) { 1165 switch (ch) { 1166 case 'a': 1167 aflag = 1; 1168 break; 1169 case 'g': 1170 gflag = 1; 1171 if (efi_name_to_guid(optarg, &matchguid) == false) { 1172 printf("uuid %s could not be parsed\n", optarg); 1173 return (CMD_ERROR); 1174 } 1175 break; 1176 case 'l': 1177 lflag = 1; 1178 break; 1179 case 'v': 1180 vflag = 1; 1181 if (strlen(optarg) >= nitems(varnamearg)) { 1182 printf("Variable %s is longer than %zu " 1183 "characters\n", optarg, nitems(varnamearg)); 1184 return (CMD_ERROR); 1185 } 1186 cpy8to16(optarg, varnamearg, nitems(varnamearg)); 1187 break; 1188 default: 1189 return (CMD_ERROR); 1190 } 1191 } 1192 1193 if (argc == 1) /* default is -a */ 1194 aflag = 1; 1195 1196 if (aflag && (gflag || vflag)) { 1197 printf("-a isn't compatible with -g or -v\n"); 1198 return (CMD_ERROR); 1199 } 1200 1201 if (aflag && optind < argc) { 1202 printf("-a doesn't take any args\n"); 1203 return (CMD_ERROR); 1204 } 1205 1206 argc -= optind; 1207 argv += optind; 1208 1209 pager_open(); 1210 if (vflag && gflag) { 1211 rv = efi_print_var(varnamearg, &matchguid, lflag); 1212 if (rv == CMD_WARN) 1213 rv = CMD_OK; 1214 pager_close(); 1215 return (rv); 1216 } 1217 1218 if (argc == 2) { 1219 optarg = argv[0]; 1220 if (strlen(optarg) >= nitems(varnamearg)) { 1221 printf("Variable %s is longer than %zu characters\n", 1222 optarg, nitems(varnamearg)); 1223 pager_close(); 1224 return (CMD_ERROR); 1225 } 1226 for (i = 0; i < strlen(optarg); i++) 1227 varnamearg[i] = optarg[i]; 1228 varnamearg[i] = 0; 1229 optarg = argv[1]; 1230 if (efi_name_to_guid(optarg, &matchguid) == false) { 1231 printf("uuid %s could not be parsed\n", optarg); 1232 pager_close(); 1233 return (CMD_ERROR); 1234 } 1235 rv = efi_print_var(varnamearg, &matchguid, lflag); 1236 if (rv == CMD_WARN) 1237 rv = CMD_OK; 1238 pager_close(); 1239 return (rv); 1240 } 1241 1242 if (argc > 0) { 1243 printf("Too many args: %d\n", argc); 1244 pager_close(); 1245 return (CMD_ERROR); 1246 } 1247 1248 /* 1249 * Initiate the search -- note the standard takes pain 1250 * to specify the initial call must be a poiner to a NULL 1251 * character. 1252 */ 1253 varalloc = 1024; 1254 varname = malloc(varalloc); 1255 if (varname == NULL) { 1256 printf("Can't allocate memory to get variables\n"); 1257 pager_close(); 1258 return (CMD_ERROR); 1259 } 1260 varname[0] = 0; 1261 while (1) { 1262 varsz = varalloc; 1263 status = RS->GetNextVariableName(&varsz, varname, &varguid); 1264 if (status == EFI_BUFFER_TOO_SMALL) { 1265 varalloc = varsz; 1266 newnm = realloc(varname, varalloc); 1267 if (newnm == NULL) { 1268 printf("Can't allocate memory to get " 1269 "variables\n"); 1270 rv = CMD_ERROR; 1271 break; 1272 } 1273 varname = newnm; 1274 continue; /* Try again with bigger buffer */ 1275 } 1276 if (status == EFI_NOT_FOUND) { 1277 rv = CMD_OK; 1278 break; 1279 } 1280 if (status != EFI_SUCCESS) { 1281 rv = CMD_ERROR; 1282 break; 1283 } 1284 1285 if (aflag) { 1286 rv = efi_print_var(varname, &varguid, lflag); 1287 if (rv != CMD_OK) { 1288 if (rv == CMD_WARN) 1289 rv = CMD_OK; 1290 break; 1291 } 1292 continue; 1293 } 1294 if (vflag) { 1295 if (wcscmp(varnamearg, varname) == 0) { 1296 rv = efi_print_var(varname, &varguid, lflag); 1297 if (rv != CMD_OK) { 1298 if (rv == CMD_WARN) 1299 rv = CMD_OK; 1300 break; 1301 } 1302 continue; 1303 } 1304 } 1305 if (gflag) { 1306 rv = uuid_equal((uuid_t *)&varguid, 1307 (uuid_t *)&matchguid, NULL); 1308 if (rv != 0) { 1309 rv = efi_print_var(varname, &varguid, lflag); 1310 if (rv != CMD_OK) { 1311 if (rv == CMD_WARN) 1312 rv = CMD_OK; 1313 break; 1314 } 1315 continue; 1316 } 1317 } 1318 } 1319 free(varname); 1320 pager_close(); 1321 1322 return (rv); 1323 } 1324 1325 COMMAND_SET(efiset, "efi-set", "set EFI variables", command_efi_set); 1326 1327 static int 1328 command_efi_set(int argc, char *argv[]) 1329 { 1330 char *uuid, *var, *val; 1331 CHAR16 wvar[128]; 1332 EFI_GUID guid; 1333 #if defined(ENABLE_UPDATES) 1334 EFI_STATUS err; 1335 #endif 1336 1337 if (argc != 4) { 1338 printf("efi-set uuid var new-value\n"); 1339 return (CMD_ERROR); 1340 } 1341 uuid = argv[1]; 1342 var = argv[2]; 1343 val = argv[3]; 1344 if (efi_name_to_guid(uuid, &guid) == false) { 1345 printf("Invalid uuid %s\n", uuid); 1346 return (CMD_ERROR); 1347 } 1348 cpy8to16(var, wvar, nitems(wvar)); 1349 #if defined(ENABLE_UPDATES) 1350 err = RS->SetVariable(wvar, &guid, EFI_VARIABLE_NON_VOLATILE | 1351 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1352 strlen(val) + 1, val); 1353 if (EFI_ERROR(err)) { 1354 printf("Failed to set variable: error %lu\n", 1355 DECODE_ERROR(err)); 1356 return (CMD_ERROR); 1357 } 1358 #else 1359 printf("would set %s %s = %s\n", uuid, var, val); 1360 #endif 1361 return (CMD_OK); 1362 } 1363 1364 COMMAND_SET(efiunset, "efi-unset", "delete / unset EFI variables", 1365 command_efi_unset); 1366 1367 static int 1368 command_efi_unset(int argc, char *argv[]) 1369 { 1370 char *uuid, *var; 1371 CHAR16 wvar[128]; 1372 EFI_GUID guid; 1373 #if defined(ENABLE_UPDATES) 1374 EFI_STATUS err; 1375 #endif 1376 1377 if (argc != 3) { 1378 printf("efi-unset uuid var\n"); 1379 return (CMD_ERROR); 1380 } 1381 uuid = argv[1]; 1382 var = argv[2]; 1383 if (efi_name_to_guid(uuid, &guid) == false) { 1384 printf("Invalid uuid %s\n", uuid); 1385 return (CMD_ERROR); 1386 } 1387 cpy8to16(var, wvar, nitems(wvar)); 1388 #if defined(ENABLE_UPDATES) 1389 err = RS->SetVariable(wvar, &guid, 0, 0, NULL); 1390 if (EFI_ERROR(err)) { 1391 printf("Failed to unset variable: error %lu\n", 1392 DECODE_ERROR(err)); 1393 return (CMD_ERROR); 1394 } 1395 #else 1396 printf("would unset %s %s \n", uuid, var); 1397 #endif 1398 return (CMD_OK); 1399 } 1400 1401 /* 1402 * Loader interaction words and extras 1403 * 1404 * efi-setenv ( value n name n guid n attr -- 0 | -1) 1405 * efi-getenv ( guid n addr n -- addr' n' | -1 ) 1406 * efi-unsetenv ( name n guid n'' -- ) 1407 */ 1408 1409 /* 1410 * efi-setenv 1411 * efi-setenv ( value n name n guid n attr -- 0 | -1) 1412 * 1413 * Set environment variables using the SetVariable EFI runtime service. 1414 * 1415 * Value and guid are passed through in binary form (so guid needs to be 1416 * converted to binary form from its string form). Name is converted from 1417 * ASCII to CHAR16. Since ficl doesn't have support for internationalization, 1418 * there's no native CHAR16 interface provided. 1419 * 1420 * attr is an int in the bitmask of the following attributes for this variable. 1421 * 1422 * 1 Non volatile 1423 * 2 Boot service access 1424 * 4 Run time access 1425 * (corresponding to the same bits in the UEFI spec). 1426 */ 1427 static void 1428 ficlEfiSetenv(ficlVm *pVM) 1429 { 1430 char *value = NULL, *guid = NULL; 1431 CHAR16 *name = NULL; 1432 int i; 1433 char *namep, *valuep, *guidp; 1434 int names, values, guids, attr; 1435 EFI_STATUS status; 1436 uuid_t u; 1437 uint32_t ustatus; 1438 char *error = NULL; 1439 ficlStack *pStack = ficlVmGetDataStack(pVM); 1440 1441 FICL_STACK_CHECK(pStack, 6, 0); 1442 1443 attr = ficlStackPopInteger(pStack); 1444 guids = ficlStackPopInteger(pStack); 1445 guidp = (char *)ficlStackPopPointer(pStack); 1446 names = ficlStackPopInteger(pStack); 1447 namep = (char *)ficlStackPopPointer(pStack); 1448 values = ficlStackPopInteger(pStack); 1449 valuep = (char *)ficlStackPopPointer(pStack); 1450 1451 guid = ficlMalloc(guids); 1452 if (guid == NULL) 1453 goto out; 1454 memcpy(guid, guidp, guids); 1455 uuid_from_string(guid, &u, &ustatus); 1456 if (ustatus != uuid_s_ok) { 1457 switch (ustatus) { 1458 case uuid_s_bad_version: 1459 error = "uuid: bad string"; 1460 break; 1461 case uuid_s_invalid_string_uuid: 1462 error = "uuid: invalid string"; 1463 break; 1464 case uuid_s_no_memory: 1465 error = "Out of memory"; 1466 break; 1467 default: 1468 error = "uuid: Unknown error"; 1469 break; 1470 } 1471 ficlStackPushInteger(pStack, -1); 1472 goto out; 1473 } 1474 1475 name = ficlMalloc((names + 1) * sizeof (CHAR16)); 1476 if (name == NULL) { 1477 error = "Out of memory"; 1478 goto out; 1479 } 1480 for (i = 0; i < names; i++) 1481 name[i] = namep[i]; 1482 name[names] = 0; 1483 1484 value = ficlMalloc(values + 1); 1485 if (value == NULL) { 1486 error = "Out of memory"; 1487 goto out; 1488 } 1489 memcpy(value, valuep, values); 1490 1491 status = RS->SetVariable(name, (EFI_GUID *)&u, attr, values, value); 1492 if (status == EFI_SUCCESS) { 1493 ficlStackPushInteger(pStack, 0); 1494 } else { 1495 ficlStackPushInteger(pStack, -1); 1496 error = "Error: SetVariable failed"; 1497 } 1498 1499 out: 1500 ficlFree(name); 1501 ficlFree(value); 1502 ficlFree(guid); 1503 if (error != NULL) 1504 ficlVmThrowError(pVM, error); 1505 } 1506 1507 static void 1508 ficlEfiGetenv(ficlVm *pVM) 1509 { 1510 char *name, *value; 1511 char *namep; 1512 int names; 1513 1514 FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 2); 1515 1516 names = ficlStackPopInteger(ficlVmGetDataStack(pVM)); 1517 namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM)); 1518 1519 name = ficlMalloc(names+1); 1520 if (name == NULL) 1521 ficlVmThrowError(pVM, "Error: out of memory"); 1522 strncpy(name, namep, names); 1523 name[names] = '\0'; 1524 1525 value = getenv(name); 1526 ficlFree(name); 1527 1528 if (value != NULL) { 1529 ficlStackPushPointer(ficlVmGetDataStack(pVM), value); 1530 ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(value)); 1531 } else { 1532 ficlStackPushInteger(ficlVmGetDataStack(pVM), -1); 1533 } 1534 } 1535 1536 static void 1537 ficlEfiUnsetenv(ficlVm *pVM) 1538 { 1539 char *name; 1540 char *namep; 1541 int names; 1542 1543 FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0); 1544 1545 names = ficlStackPopInteger(ficlVmGetDataStack(pVM)); 1546 namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM)); 1547 1548 name = ficlMalloc(names+1); 1549 if (name == NULL) 1550 ficlVmThrowError(pVM, "Error: out of memory"); 1551 strncpy(name, namep, names); 1552 name[names] = '\0'; 1553 1554 unsetenv(name); 1555 ficlFree(name); 1556 } 1557 1558 /* 1559 * Build platform extensions into the system dictionary 1560 */ 1561 static void 1562 ficlEfiCompilePlatform(ficlSystem *pSys) 1563 { 1564 ficlDictionary *dp = ficlSystemGetDictionary(pSys); 1565 1566 FICL_SYSTEM_ASSERT(pSys, dp); 1567 1568 ficlDictionarySetPrimitive(dp, "efi-setenv", ficlEfiSetenv, 1569 FICL_WORD_DEFAULT); 1570 ficlDictionarySetPrimitive(dp, "efi-getenv", ficlEfiGetenv, 1571 FICL_WORD_DEFAULT); 1572 ficlDictionarySetPrimitive(dp, "efi-unsetenv", ficlEfiUnsetenv, 1573 FICL_WORD_DEFAULT); 1574 } 1575 1576 FICL_COMPILE_SET(ficlEfiCompilePlatform); 1577