--- /dev/null
+/*
+ * File to implement an full version of EFI_BOOT_SERVICES, to go beyond
+ * what GNU-EFI provides. These functions were taken, with modification,
+ * from various EDK2 and earlier files (see comments preceding the
+ * functions and other blocks of code). The original source files
+ * bore the following copyright notice:
+ *
+ * Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ * This program and the accompanying materials are licensed and made available under
+ * the terms and conditions of the BSD License that accompanies this distribution.
+ * The full text of the license may be found at
+ * http://opensource.org/licenses/bsd-license.php.
+ *
+ * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ *
+ */
+
+#include "bootsvcs.h"
+#include "refit_call_wrapper.h"
+
+// Following "global" constants are from AutoGen.c....
+EFI_GUID gEfiLoadedImageProtocolGuid = { 0x5B1B31A1, 0x9562, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
+EFI_GUID gEfiDriverBindingProtocolGuid = { 0x18A031AB, 0xB443, 0x4D1A, { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 }};
+EFI_GUID gEfiDriverConfiguration2ProtocolGuid = { 0xBFD7DC1D, 0x24F1, 0x40D9, { 0x82, 0xE7, 0x2E, 0x09, 0xBB, 0x6B, 0x4E, 0xBE }};
+EFI_GUID gEfiDriverConfigurationProtocolGuid = { 0x107A772B, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
+EFI_GUID gEfiDriverDiagnosticsProtocolGuid = { 0x0784924F, 0xE296, 0x11D4, { 0x9A, 0x49, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
+EFI_GUID gEfiDriverDiagnostics2ProtocolGuid = { 0x4D330321, 0x025F, 0x4AAC, { 0x90, 0xD8, 0x5E, 0xD9, 0x00, 0x17, 0x3B, 0x63 }};
+EFI_GUID gEfiComponentNameProtocolGuid = { 0x107A772C, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
+EFI_GUID gEfiComponentName2ProtocolGuid = { 0x6A7A5CFF, 0xE8D9, 0x4F70, { 0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14 }};
+EFI_GUID gEfiDevicePathProtocolGuid = { 0x09576E91, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
+
+// Below is from http://git.etherboot.org/?p=mirror/efi/shell/.git;a=commitdiff;h=b1b0c63423cac54dc964c2930e04aebb46a946ec;
+// Seems to have been replaced by ParseHandleDatabaseByRelationshipWithType(), but the latter isn't working for me....
+EFI_STATUS
+LibScanHandleDatabase (
+ EFI_HANDLE DriverBindingHandle, OPTIONAL
+ UINT32 *DriverBindingHandleIndex, OPTIONAL
+ EFI_HANDLE ControllerHandle, OPTIONAL
+ UINT32 *ControllerHandleIndex, OPTIONAL
+ UINTN *HandleCount,
+ EFI_HANDLE **HandleBuffer,
+ UINT32 **HandleType
+ )
+
+{
+ EFI_STATUS Status;
+ UINTN HandleIndex;
+ EFI_GUID **ProtocolGuidArray;
+ UINTN ArrayCount;
+ UINTN ProtocolIndex;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
+ UINTN OpenInfoCount;
+ UINTN OpenInfoIndex;
+ UINTN ChildIndex;
+ BOOLEAN DriverBindingHandleIndexValid;
+ BOOLEAN ControllerHandleIndexValid;
+
+ DriverBindingHandleIndexValid = FALSE;
+ if (DriverBindingHandleIndex != NULL) {
+ *DriverBindingHandleIndex = 0xffffffff;
+ }
+
+ ControllerHandleIndexValid = FALSE;
+ if (ControllerHandleIndex != NULL) {
+ *ControllerHandleIndex = 0xffffffff;
+ }
+
+ *HandleCount = 0;
+ *HandleBuffer = NULL;
+ *HandleType = NULL;
+
+ //
+ // Retrieve the list of all handles from the handle database
+ //
+
+ Status = refit_call5_wrapper(gBS->LocateHandleBuffer,
+ AllHandles,
+ NULL,
+ NULL,
+ HandleCount,
+ HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ *HandleType = AllocatePool (*HandleCount * sizeof (UINT32));
+ if (*HandleType == NULL) {
+ goto Error;
+ }
+
+ for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
+ //
+ // Assume that the handle type is unknown
+ //
+ (*HandleType)[HandleIndex] = EFI_HANDLE_TYPE_UNKNOWN;
+
+ if (DriverBindingHandle != NULL &&
+ DriverBindingHandleIndex != NULL &&
+ (*HandleBuffer)[HandleIndex] == DriverBindingHandle
+ ) {
+ *DriverBindingHandleIndex = (UINT32) HandleIndex;
+ DriverBindingHandleIndexValid = TRUE;
+ }
+
+ if (ControllerHandle != NULL && ControllerHandleIndex != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
+ *ControllerHandleIndex = (UINT32) HandleIndex;
+ ControllerHandleIndexValid = TRUE;
+ }
+
+ }
+
+ for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
+ //
+ // Retrieve the list of all the protocols on each handle
+ //
+
+ Status = refit_call3_wrapper(gBS->ProtocolsPerHandle,
+ (*HandleBuffer)[HandleIndex],
+ &ProtocolGuidArray,
+ &ArrayCount
+ );
+ if (!EFI_ERROR (Status)) {
+
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) == 0) {
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_IMAGE_HANDLE;
+ }
+
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) == 0) {
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE;
+ }
+
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) == 0) {
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE;
+ }
+
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) == 0) {
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE;
+ }
+
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) == 0) {
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE;
+ }
+
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) == 0) {
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DEVICE_HANDLE;
+ }
+ //
+ // Retrieve the list of agents that have opened each protocol
+ //
+
+ Status = refit_call4_wrapper(gBS->OpenProtocolInformation,
+ (*HandleBuffer)[HandleIndex],
+ ProtocolGuidArray[ProtocolIndex],
+ &OpenInfo,
+ &OpenInfoCount
+ );
+ if (!EFI_ERROR (Status)) {
+
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+ if (DriverBindingHandle != NULL && OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ //
+ // Mark the device handle as being managed by the driver specified by DriverBindingHandle
+ //
+ (*HandleType)[HandleIndex] |= (EFI_HANDLE_TYPE_DEVICE_HANDLE | EFI_HANDLE_TYPE_CONTROLLER_HANDLE);
+ //
+ // Mark the DriverBindingHandle as being a driver that is managing at least one controller
+ //
+ if (DriverBindingHandleIndexValid) {
+ (*HandleType)[*DriverBindingHandleIndex] |= EFI_HANDLE_TYPE_DEVICE_DRIVER;
+ }
+ }
+
+ if ((
+ OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ ) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ ) {
+ //
+ // Mark the DriverBindingHandle as being a driver that is managing at least one child controller
+ //
+ if (DriverBindingHandleIndexValid) {
+ (*HandleType)[*DriverBindingHandleIndex] |= EFI_HANDLE_TYPE_BUS_DRIVER;
+ }
+ }
+
+ if (ControllerHandle != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
+ if ((
+ OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ ) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ ) {
+ for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
+ if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].ControllerHandle) {
+ (*HandleType)[ChildIndex] |= (EFI_HANDLE_TYPE_DEVICE_HANDLE | EFI_HANDLE_TYPE_CHILD_HANDLE);
+ }
+ }
+ }
+ }
+ }
+
+ if (DriverBindingHandle == NULL && OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
+ if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
+ (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_DEVICE_DRIVER;
+ }
+ }
+ }
+
+ if ((
+ OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ ) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ ) {
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_PARENT_HANDLE;
+ for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
+ if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {
+ (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_BUS_DRIVER;
+ }
+ }
+ }
+ }
+ }
+
+ FreePool (OpenInfo);
+ }
+ }
+
+ FreePool (ProtocolGuidArray);
+ }
+ }
+
+ return EFI_SUCCESS;
+
+Error:
+ if (*HandleType != NULL) {
+ FreePool (*HandleType);
+ }
+
+ if (*HandleBuffer != NULL) {
+ FreePool (*HandleBuffer);
+ }
+
+ *HandleCount = 0;
+ *HandleBuffer = NULL;
+ *HandleType = NULL;
+
+ return Status;
+} /* EFI_STATUS LibScanHandleDatabase() */
--- /dev/null
+/*
+ * File to implement an full version of EFI_BOOT_SERVICES, to go beyond
+ * what GNU-EFI provides. Most of the data structures in this file are taken
+ * from the Tianocore UDK's UefiSpec.h file or HandleParsingLib.h files.
+ * The EFI_DEVICE_PATH_PROTOCOL definition is from
+ * http://wiki.phoenix.com/wiki/index.php/EFI_DEVICE_PATH_PROTOCOL.
+ * The UefiSpec.h and HandleParsingLib files include the following copyright
+ * notice:
+ *
+ * Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ * This program and the accompanying materials are licensed and made available under
+ * the terms and conditions of the BSD License that accompanies this distribution.
+ * The full text of the license may be found at
+ * http://opensource.org/licenses/bsd-license.php.
+ *
+ * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ *
+ */
+
+#include <efi/efi.h>
+#include <efi/efilib.h>
+
+#ifndef _MY_BOOT_SERVICES_FILE
+#define _MY_BOOT_SERVICES_FILE
+
+typedef struct _EFI_DEVICE_PATH_PROTOCOL {
+ UINT8 Type;
+ UINT8 SubType;
+ UINT8 Length[2];
+} EFI_DEVICE_PATH_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONNECT_CONTROLLER)(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle, OPTIONAL
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, OPTIONAL
+ IN BOOLEAN Recursive
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle, OPTIONAL
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID * Protocol,
+ OUT VOID **Interface,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle, OPTIONAL
+ IN UINT32 Attributes
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID * Protocol,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle
+);
+
+typedef struct {
+ EFI_HANDLE AgentHandle;
+ EFI_HANDLE ControllerHandle;
+ UINT32 Attributes;
+ UINT32 OpenCount;
+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION) (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID * Protocol,
+ IN EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PROTOCOLS_PER_HANDLE) (
+ IN EFI_HANDLE UserHandle,
+ OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID * Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_PROTOCOL) (
+ EFI_GUID * Protocol,
+ VOID *Registration, OPTIONAL
+ VOID **Interface
+);
+
+///
+/// EFI Boot Services Table.
+///
+typedef struct _MY_BOOT_SERVICES {
+ ///
+ /// The table header for the EFI Boot Services Table.
+ ///
+ EFI_TABLE_HEADER Hdr;
+
+ //
+ // Task Priority Services
+ //
+ EFI_RAISE_TPL RaiseTPL;
+ EFI_RESTORE_TPL RestoreTPL;
+
+ //
+ // Memory Services
+ //
+ EFI_ALLOCATE_PAGES AllocatePages;
+ EFI_FREE_PAGES FreePages;
+ EFI_GET_MEMORY_MAP GetMemoryMap;
+ EFI_ALLOCATE_POOL AllocatePool;
+ EFI_FREE_POOL FreePool;
+
+ //
+ // Event & Timer Services
+ //
+ EFI_CREATE_EVENT CreateEvent;
+ EFI_SET_TIMER SetTimer;
+ EFI_WAIT_FOR_EVENT WaitForEvent;
+ EFI_SIGNAL_EVENT SignalEvent;
+ EFI_CLOSE_EVENT CloseEvent;
+ EFI_CHECK_EVENT CheckEvent;
+
+ //
+ // Protocol Handler Services
+ //
+ EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
+ EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
+ EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
+ EFI_HANDLE_PROTOCOL HandleProtocol;
+ VOID *Reserved;
+ EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
+ EFI_LOCATE_HANDLE LocateHandle;
+ EFI_LOCATE_DEVICE_PATH LocateDevicePath;
+ EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;
+
+ //
+ // Image Services
+ //
+ EFI_IMAGE_LOAD LoadImage;
+ EFI_IMAGE_START StartImage;
+ EFI_EXIT Exit;
+ EFI_IMAGE_UNLOAD UnloadImage;
+ EFI_EXIT_BOOT_SERVICES ExitBootServices;
+
+ //
+ // Miscellaneous Services
+ //
+ EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
+ EFI_STALL Stall;
+ EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
+
+ //
+ // DriverSupport Services
+ //
+ EFI_CONNECT_CONTROLLER ConnectController;
+ EFI_DISCONNECT_CONTROLLER DisconnectController;
+
+ //
+ // Open and Close Protocol Services
+ //
+ EFI_OPEN_PROTOCOL OpenProtocol;
+ EFI_CLOSE_PROTOCOL CloseProtocol;
+ EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;
+
+ //
+ // Library Services
+ //
+ EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;
+ EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
+ EFI_LOCATE_PROTOCOL LocateProtocol;
+// EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;
+// EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;
+//
+// //
+// // 32-bit CRC Services
+// //
+// EFI_CALCULATE_CRC32 CalculateCrc32;
+//
+// //
+// // Miscellaneous Services
+// //
+// EFI_COPY_MEM CopyMem;
+// EFI_SET_MEM SetMem;
+// EFI_CREATE_EVENT_EX CreateEventEx;
+} MY_BOOT_SERVICES;
+
+// Below is from http://git.etherboot.org/?p=mirror/efi/shell/.git;a=commitdiff;h=b1b0c63423cac54dc964c2930e04aebb46a946ec;
+// Seems to have been replaced by ParseHandleDatabaseByRelationshipWithType(), but the latter isn't working for me....
+EFI_STATUS
+LibScanHandleDatabase (
+ EFI_HANDLE DriverBindingHandle, OPTIONAL
+ UINT32 *DriverBindingHandleIndex, OPTIONAL
+ EFI_HANDLE ControllerHandle, OPTIONAL
+ UINT32 *ControllerHandleIndex, OPTIONAL
+ UINTN *HandleCount,
+ EFI_HANDLE **HandleBuffer,
+ UINT32 **HandleType
+ );
+
+extern MY_BOOT_SERVICES *gBS;
+
+#define EFI_HANDLE_TYPE_UNKNOWN 0x000
+#define EFI_HANDLE_TYPE_IMAGE_HANDLE 0x001
+#define EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE 0x002
+#define EFI_HANDLE_TYPE_DEVICE_DRIVER 0x004
+#define EFI_HANDLE_TYPE_BUS_DRIVER 0x008
+#define EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE 0x010
+#define EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE 0x020
+#define EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE 0x040
+#define EFI_HANDLE_TYPE_DEVICE_HANDLE 0x080
+#define EFI_HANDLE_TYPE_PARENT_HANDLE 0x100
+#define EFI_HANDLE_TYPE_CONTROLLER_HANDLE 0x200
+#define EFI_HANDLE_TYPE_CHILD_HANDLE 0x400
+
+
+// Below from EfiApi.h
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
+
+
+#endif