summaryrefslogtreecommitdiff
path: root/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c
diff options
context:
space:
mode:
Diffstat (limited to 'EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c')
-rw-r--r--EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c b/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c
new file mode 100644
index 0000000000..5aed594b6e
--- /dev/null
+++ b/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c
@@ -0,0 +1,138 @@
+/** @file
+ Emulator Thunk to abstract OS services from pure EFI code
+
+ Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 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
+ which 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 <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Protocol/EmuIoThunk.h>
+
+
+#define EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('E','m','u','T')
+
+typedef struct {
+ UINTN Signature;
+ EMU_IO_THUNK_PROTOCOL Data;
+ BOOLEAN EmuBusDriver;
+ LIST_ENTRY Link;
+} EMU_IO_THUNK_PROTOCOL_DATA;
+
+LIST_ENTRY mThunkList = INITIALIZE_LIST_HEAD_VARIABLE (mThunkList);
+
+
+EFI_STATUS
+EFIAPI
+AddThunkProtocol (
+ IN EMU_IO_THUNK_PROTOCOL *ThunkIo,
+ IN CHAR16 *ConfigString,
+ IN BOOLEAN EmuBusDriver
+ )
+{
+ CHAR16 *StartString;
+ CHAR16 *SubString;
+ UINTN Instance;
+ EMU_IO_THUNK_PROTOCOL_DATA *Private;
+
+ if (ThunkIo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = 0;
+ StartString = AllocatePool (StrSize (ConfigString));
+ StrCpy (StartString, ConfigString);
+ while (*StartString != '\0') {
+
+ //
+ // Find the end of the sub string
+ //
+ SubString = StartString;
+ while (*SubString != '\0' && *SubString != '!') {
+ SubString++;
+ }
+
+ if (*SubString == '!') {
+ //
+ // Replace token with '\0' to make sub strings. If this is the end
+ // of the string SubString will already point to NULL.
+ //
+ *SubString = '\0';
+ SubString++;
+ }
+
+ Private = AllocatePool (sizeof (EMU_IO_THUNK_PROTOCOL_DATA));
+ if (Private == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Private->Signature = EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE;
+ Private->EmuBusDriver = EmuBusDriver;
+
+ CopyMem (&Private->Data, ThunkIo, sizeof (EMU_IO_THUNK_PROTOCOL));
+ Private->Data.Instance = Instance++;
+ Private->Data.ConfigString = StartString;
+
+ InsertTailList (&mThunkList, &Private->Link);
+
+ //
+ // Parse Next sub string. This will point to '\0' if we are at the end.
+ //
+ StartString = SubString;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+GetNextThunkProtocol (
+ IN BOOLEAN EmuBusDriver,
+ OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL
+ )
+{
+ LIST_ENTRY *Link;
+ EMU_IO_THUNK_PROTOCOL_DATA *Private;
+
+ if (mThunkList.ForwardLink == &mThunkList) {
+ // Skip parsing an empty list
+ return EFI_NOT_FOUND;
+ }
+
+ for (Link = mThunkList.ForwardLink; Link != &mThunkList; Link = Link->ForwardLink) {
+ Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE);
+ if (EmuBusDriver & !Private->EmuBusDriver) {
+ continue;
+ } else if (*Instance == NULL) {
+ // Find 1st match in list
+ *Instance = &Private->Data;
+ return EFI_SUCCESS;
+ } else if (*Instance == &Private->Data) {
+ // Matched previous call so look for valid next entry
+ Link = Link->ForwardLink;
+ if (Link == &mThunkList) {
+ return EFI_NOT_FOUND;
+ }
+ Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE);
+ *Instance = &Private->Data;
+ return EFI_SUCCESS;
+ }
+ }
+
+
+ return EFI_NOT_FOUND;
+}
+