Home | History | Annotate | Download | only in ThunkProtocolList
      1 /** @file
      2   Emulator Thunk to abstract OS services from pure EFI code
      3 
      4   Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
      5   Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
      6 
      7   This program and the accompanying materials
      8   are licensed and made available under the terms and conditions of the BSD License
      9   which accompanies this distribution.  The full text of the license may be found at
     10   http://opensource.org/licenses/bsd-license.php
     11 
     12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #include <Uefi.h>
     18 #include <Library/BaseLib.h>
     19 #include <Library/BaseMemoryLib.h>
     20 #include <Library/DebugLib.h>
     21 #include <Library/MemoryAllocationLib.h>
     22 
     23 #include <Protocol/EmuIoThunk.h>
     24 
     25 
     26 #define EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('E','m','u','T')
     27 
     28 typedef struct {
     29   UINTN                 Signature;
     30   EMU_IO_THUNK_PROTOCOL Data;
     31   BOOLEAN               EmuBusDriver;
     32   LIST_ENTRY            Link;
     33 } EMU_IO_THUNK_PROTOCOL_DATA;
     34 
     35 LIST_ENTRY  mThunkList = INITIALIZE_LIST_HEAD_VARIABLE (mThunkList);
     36 
     37 
     38 EFI_STATUS
     39 EFIAPI
     40 AddThunkProtocol (
     41   IN  EMU_IO_THUNK_PROTOCOL   *ThunkIo,
     42   IN  CHAR16                  *ConfigString,
     43   IN  BOOLEAN                 EmuBusDriver
     44   )
     45 {
     46   CHAR16                      *StartString;
     47   CHAR16                      *SubString;
     48   UINTN                       Instance;
     49   EMU_IO_THUNK_PROTOCOL_DATA  *Private;
     50 
     51   if (ThunkIo == NULL) {
     52     return EFI_INVALID_PARAMETER;
     53   }
     54 
     55   Instance = 0;
     56   StartString = AllocatePool (StrSize (ConfigString));
     57   StrCpy (StartString, ConfigString);
     58   while (*StartString != '\0') {
     59 
     60     //
     61     // Find the end of the sub string
     62     //
     63     SubString = StartString;
     64     while (*SubString != '\0' && *SubString != '!') {
     65       SubString++;
     66     }
     67 
     68     if (*SubString == '!') {
     69       //
     70       // Replace token with '\0' to make sub strings. If this is the end
     71       //  of the string SubString will already point to NULL.
     72       //
     73       *SubString = '\0';
     74       SubString++;
     75     }
     76 
     77     Private = AllocatePool (sizeof (EMU_IO_THUNK_PROTOCOL_DATA));
     78     if (Private == NULL) {
     79       return EFI_OUT_OF_RESOURCES;
     80     }
     81     Private->Signature          = EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE;
     82     Private->EmuBusDriver       = EmuBusDriver;
     83 
     84     CopyMem (&Private->Data, ThunkIo, sizeof (EMU_IO_THUNK_PROTOCOL));
     85     Private->Data.Instance      = Instance++;
     86     Private->Data.ConfigString  = StartString;
     87 
     88     InsertTailList (&mThunkList, &Private->Link);
     89 
     90     //
     91     // Parse Next sub string. This will point to '\0' if we are at the end.
     92     //
     93     StartString = SubString;
     94   }
     95 
     96   return EFI_SUCCESS;
     97 }
     98 
     99 
    100 EFI_STATUS
    101 EFIAPI
    102 GetNextThunkProtocol (
    103   IN  BOOLEAN                 EmuBusDriver,
    104   OUT EMU_IO_THUNK_PROTOCOL   **Instance  OPTIONAL
    105   )
    106 {
    107   LIST_ENTRY                   *Link;
    108   EMU_IO_THUNK_PROTOCOL_DATA   *Private;
    109 
    110   if (mThunkList.ForwardLink == &mThunkList) {
    111     // Skip parsing an empty list
    112     return EFI_NOT_FOUND;
    113   }
    114 
    115   for (Link = mThunkList.ForwardLink; Link != &mThunkList; Link = Link->ForwardLink) {
    116     Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE);
    117     if (EmuBusDriver & !Private->EmuBusDriver) {
    118       continue;
    119     } else if (*Instance == NULL) {
    120       // Find 1st match in list
    121       *Instance = &Private->Data;
    122       return EFI_SUCCESS;
    123     } else if (*Instance == &Private->Data) {
    124       // Matched previous call so look for valid next entry
    125       Link = Link->ForwardLink;
    126       if (Link == &mThunkList) {
    127         return EFI_NOT_FOUND;
    128       }
    129       Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE);
    130       *Instance = &Private->Data;
    131       return EFI_SUCCESS;
    132     }
    133   }
    134 
    135 
    136   return EFI_NOT_FOUND;
    137 }
    138 
    139