EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
EFI_GUID EfiRootAcpiTableGuid = EFI_ACPI_20_TABLE_GUID;
EFI_GUID EfiRootAcpiTable10Guid = EFI_ACPI_TABLE_GUID;
+EFI_GUID EfiGlobalVariable = EFI_GLOBAL_VARIABLE;
+EFI_GUID BlpEfiSecureBootPrivateNamespace = { 0x77FA9ABD , 0x0359, 0x4D32, { 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B } };
WCHAR BlScratchBuffer[8192];
+BOOLEAN BlpFirmwareChecked;
+BOOLEAN BlpFirmwareEnabled;
+
/* FUNCTIONS *****************************************************************/
EFI_DEVICE_PATH *
}
}
- /* This now contains the deepeest (leaf) node */
+ /* This now contains the deepest (leaf) node */
return DevicePath;
}
}
else
{
- /* FIXME: @TODO: Not yet supported */
+ /* Switch to real mode */
+ BlpArchSwitchContext(BlRealMode);
+
+ /* Call EFI directly */
+ if (EfiConOut != NULL)
+ {
+ EfiConOut->OutputString(EfiConOut, BlScratchBuffer);
+ }
+
+ /* Switch back to protected mode */
+ BlpArchSwitchContext(BlProtectedMode);
}
/* All done */
return Status;
}
+NTSTATUS
+EfiGetVariable (
+ _In_ PWCHAR VariableName,
+ _In_ EFI_GUID* VendorGuid,
+ _Out_opt_ PULONG Attributes,
+ _Inout_ PULONG DataSize,
+ _Out_ PVOID Data
+ )
+{
+ EFI_STATUS EfiStatus;
+ NTSTATUS Status;
+ BL_ARCH_MODE OldMode;
+ ULONG LocalAttributes;
+
+ /* Are we in protected mode? */
+ OldMode = CurrentExecutionContext->Mode;
+ if (OldMode != BlRealMode)
+ {
+ /* FIXME: Not yet implemented */
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* Call the runtime API */
+ EfiStatus = EfiRT->GetVariable(VariableName,
+ VendorGuid,
+ (UINT32*)&LocalAttributes,
+ (UINTN*)DataSize,
+ Data);
+
+ /* Switch back to protected mode if we came from there */
+ if (OldMode != BlRealMode)
+ {
+ BlpArchSwitchContext(OldMode);
+ }
+
+ /* Return attributes back to the caller if asked to */
+ if (Attributes)
+ {
+ *Attributes = LocalAttributes;
+ }
+
+ /* Convert the error to an NTSTATUS and return it */
+ Status = EfiGetNtStatusCode(EfiStatus);
+ return Status;
+}
+
+NTSTATUS
+BlpSecureBootEFIIsEnabled (
+ VOID
+ )
+{
+ NTSTATUS Status;
+ BOOLEAN SetupMode, SecureBoot;
+ ULONG DataSize;
+
+ /* Assume setup mode enabled, and no secure boot */
+ SecureBoot = FALSE;
+ SetupMode = TRUE;
+
+ /* Get the SetupMode variable */
+ DataSize = sizeof(SetupMode);
+ Status = EfiGetVariable(L"SetupMode",
+ &EfiGlobalVariable,
+ NULL,
+ &DataSize,
+ &SetupMode);
+ if (NT_SUCCESS(Status))
+ {
+ /* If it worked, get the SecureBoot variable */
+ DataSize = sizeof(SecureBoot);
+ Status = EfiGetVariable(L"SecureBoot",
+ &EfiGlobalVariable,
+ NULL,
+ &DataSize,
+ &SecureBoot);
+ if (NT_SUCCESS(Status))
+ {
+ /* In setup mode or without secureboot turned on, return failure */
+ if ((SecureBoot != TRUE) || (SetupMode))
+ {
+ Status = STATUS_INVALID_SIGNATURE;
+ }
+
+ // BlpSbdiStateFlags |= 8u;
+ }
+ }
+
+ /* Return secureboot status */
+ return Status;
+}
+
+NTSTATUS
+BlSecureBootIsEnabled (
+ _Out_ PBOOLEAN SecureBootEnabled
+ )
+{
+ NTSTATUS Status;
+
+ /* Have we checked before ? */
+ if (!BlpFirmwareChecked)
+ {
+ /* First time checking */
+ Status = BlpSecureBootEFIIsEnabled();
+ if NT_SUCCESS(Status)
+ {
+ /* Yep, it's on */
+ BlpFirmwareEnabled = TRUE;
+ }
+
+ /* Don't check again */
+ BlpFirmwareChecked = TRUE;
+ }
+
+ /* Return the firmware result */
+ *SecureBootEnabled = BlpFirmwareEnabled;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BlSecureBootCheckForFactoryReset (
+ VOID
+ )
+{
+ BOOLEAN SecureBootEnabled;
+ NTSTATUS Status;
+ ULONG DataSize;
+
+ /* Initialize locals */
+ DataSize = 0;
+ SecureBootEnabled = FALSE;
+
+ /* Check if secureboot is enabled */
+ Status = BlSecureBootIsEnabled(&SecureBootEnabled);
+ if (!(NT_SUCCESS(Status)) || !(SecureBootEnabled))
+ {
+ /* It's not. Check if there's a revocation list */
+ Status = EfiGetVariable(L"RevocationList",
+ &BlpEfiSecureBootPrivateNamespace,
+ NULL,
+ &DataSize,
+ NULL);
+ if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL))
+ {
+ /* We don't support this yet */
+ EfiPrintf(L"Not yet supported\r\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+ }
+
+ /* Return back to the caller */
+ return Status;
+}
+
NTSTATUS
EfiConInReset (
VOID
{
BL_ARCH_MODE OldMode;
EFI_STATUS EfiStatus;
+ PHYSICAL_ADDRESS MemoryMapSizePhysical, MemoryMapPhysical, MapKeyPhysical;
+ PHYSICAL_ADDRESS DescriptorSizePhysical, DescriptorVersionPhysical;
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
- /* FIXME: Not yet implemented */
- return STATUS_NOT_IMPLEMENTED;
+ /* Convert all of the addresses to physical */
+ BlMmTranslateVirtualAddress(MemoryMapSize, &MemoryMapSizePhysical);
+ MemoryMapSize = (UINTN*)MemoryMapSizePhysical.LowPart;
+ BlMmTranslateVirtualAddress(MemoryMap, &MemoryMapPhysical);
+ MemoryMap = (EFI_MEMORY_DESCRIPTOR*)MemoryMapPhysical.LowPart;
+ BlMmTranslateVirtualAddress(MapKey, &MapKeyPhysical);
+ MapKey = (UINTN*)MapKeyPhysical.LowPart;
+ BlMmTranslateVirtualAddress(DescriptorSize, &DescriptorSizePhysical);
+ DescriptorSize = (UINTN*)DescriptorSizePhysical.LowPart;
+ BlMmTranslateVirtualAddress(DescriptorVersion, &DescriptorVersionPhysical);
+ DescriptorVersion = (UINTN*)DescriptorVersionPhysical.LowPart;
+
+ /* Switch to real mode */
+ BlpArchSwitchContext(BlProtectedMode);
}
/* Make the EFI call */
if ((ModeChanged) && (NT_SUCCESS(Status)))
{
/* FIXME @TODO: Should be BlStatusPrint */
- EfiPrintf(L"Console video mode set to 0x%x\r\r\n", Mode);
+ EfiPrintf(L"Console video mode set to 0x%x\r\n", Mode);
}
/* Convert the error to an NTSTATUS */
EfiRT->ResetSystem(ResetType, EFI_SUCCESS, 0, NULL);
}
+NTSTATUS
+EfiConnectController (
+ _In_ EFI_HANDLE ControllerHandle
+ )
+{
+ BL_ARCH_MODE OldMode;
+ EFI_STATUS EfiStatus;
+
+ /* Is this EFI 1.02? */
+ if (EfiST->Hdr.Revision == EFI_1_02_SYSTEM_TABLE_REVISION)
+ {
+ /* This function didn't exist back then */
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ /* Are we in protected mode? */
+ OldMode = CurrentExecutionContext->Mode;
+ if (OldMode != BlRealMode)
+ {
+ /* FIXME: Not yet implemented */
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* Make the EFI call */
+ EfiStatus = EfiBS->ConnectController(ControllerHandle, NULL, NULL, TRUE);
+
+ /* Switch back to protected mode if we came from there */
+ if (OldMode != BlRealMode)
+ {
+ BlpArchSwitchContext(OldMode);
+ }
+
+ /* Convert the error to an NTSTATUS */
+ return EfiGetNtStatusCode(EfiStatus);
+}
+
NTSTATUS
EfiAllocatePages (
_In_ ULONG Type,
NTSTATUS Status;
ULONGLONG Pages, StartPage, EndPage;
UINTN EfiMemoryMapSize, MapKey, DescriptorSize, DescriptorVersion;
- EFI_PHYSICAL_ADDRESS EfiBuffer;
+ EFI_PHYSICAL_ADDRESS EfiBuffer = 0;
EFI_MEMORY_DESCRIPTOR* EfiMemoryMap;
EFI_STATUS EfiStatus;
BL_ARCH_MODE OldMode;
/* Loop the EFI memory map */
#if 0
- EfiPrintf(L"UEFI MEMORY MAP\n\r\n");
+ EfiPrintf(L"UEFI MEMORY MAP\r\n\r\n");
EfiPrintf(L"TYPE START END ATTRIBUTES\r\n");
EfiPrintf(L"===============================================================\r\n");
#endif
Status = MmMdAddDescriptorToList(MemoryMap,
Descriptor,
BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG |
- (Flags & BL_MM_FLAG_REQUEST_COALESCING) ?
- BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG : 0);
+ ((Flags & BL_MM_FLAG_REQUEST_COALESCING) ?
+ BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG : 0));
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Failed to add full descriptor: %lx\r\n", Status);
NTSTATUS Status = STATUS_SUCCESS;
EFI_KEY_TOGGLE_STATE KeyToggleState;
- /* Check if we have vaild firmware data */
+ /* Check if we have valid firmware data */
if (!(FirmwareData) || !(FirmwareData->Version))
{
return STATUS_INVALID_PARAMETER;
/* FIXME: Not supported */
Status = STATUS_NOT_SUPPORTED;
}
- else if (FirmwareData->Version >= 2)
+ else if (FirmwareData->Version >= BL_FIRMWARE_DESCRIPTOR_VERSION)
{
/* Version 2 -- save the data */
EfiFirmwareData = *FirmwareData;
return Status;
}
+NTSTATUS
+BlFwGetParameters (
+ _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
+ )
+{
+ /* Make sure we got an argument */
+ if (!Parameters)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Copy the static data */
+ *Parameters = *EfiFirmwareParameters;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BlFwEnumerateDevice (
+ _In_ PBL_DEVICE_DESCRIPTOR Device
+ )
+{
+ NTSTATUS Status;
+ ULONG PathProtocols, BlockProtocols;
+ EFI_HANDLE* PathArray;
+ EFI_HANDLE* BlockArray;
+
+ /* Initialize locals */
+ BlockArray = NULL;
+ PathArray = NULL;
+ PathProtocols = 0;
+ BlockProtocols = 0;
+
+ /* Enumeration only makes sense on disks or partitions */
+ if ((Device->DeviceType != DiskDevice) &&
+ (Device->DeviceType != LegacyPartitionDevice) &&
+ (Device->DeviceType != PartitionDevice))
+ {
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ /* Enumerate the list of device paths */
+ Status = EfiLocateHandleBuffer(ByProtocol,
+ &EfiDevicePathProtocol,
+ &PathProtocols,
+ &PathArray);
+ if (NT_SUCCESS(Status))
+ {
+ /* Loop through each one */
+ Status = STATUS_NOT_FOUND;
+ while (PathProtocols)
+ {
+ /* Attempt to connect the driver for this device epath */
+ Status = EfiConnectController(PathArray[--PathProtocols]);
+ if (NT_SUCCESS(Status))
+ {
+ /* Now enumerate any block I/O devices the driver added */
+ Status = EfiLocateHandleBuffer(ByProtocol,
+ &EfiBlockIoProtocol,
+ &BlockProtocols,
+ &BlockArray);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ /* Loop through each one */
+ while (BlockProtocols)
+ {
+ /* Check if one of the new devices is the one we want */
+ Status = BlockIoEfiCompareDevice(Device,
+ BlockArray[--BlockProtocols]);
+ if (NT_SUCCESS(Status))
+ {
+ /* Yep, all done */
+ goto Quickie;
+ }
+ }
+
+ /* Move on to the next device path */
+ BlMmFreeHeap(BlockArray);
+ BlockArray = NULL;
+ }
+ }
+ }
+
+Quickie:
+ /* We're done -- free the array of device path protocols, if any */
+ if (PathArray)
+ {
+ BlMmFreeHeap(PathArray);
+ }
+
+ /* We're done -- free the array of block I/O protocols, if any */
+ if (BlockArray)
+ {
+ BlMmFreeHeap(BlockArray);
+ }
+
+ /* Return if we found the device or not */
+ return Status;
+}
/*++
* @name EfiGetEfiStatusCode