1/** @file
2  This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware
3  volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.
4
5  It will expose a single directory, containing one file for each file in the firmware
6  volume. If a file has a UI section, its contents will be used as a filename.
7  Otherwise, a string representation of the GUID will be used.
8  Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)
9  will have ".efi" added to their filename.
10
11  Its primary intended use is to be able to start EFI applications embedded in FVs
12  from the UEFI shell. It is entirely read-only.
13
14Copyright (c) 2014, ARM Limited. All rights reserved.
15Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
16
17This program and the accompanying materials
18are licensed and made available under the terms and conditions of the BSD License
19which accompanies this distribution.  The full text of the license may be found at
20http://opensource.org/licenses/bsd-license.php
21
22THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
23WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24
25**/
26
27#include "FvSimpleFileSystemInternal.h"
28
29EFI_UNICODE_COLLATION_PROTOCOL          *mUnicodeCollation = NULL;
30
31//
32// A Guid string is 32 hex characters with 4 hyphens and a NULL-terminated char: 37 characters total
33//
34#define GUID_STRING_SIZE                (37 * sizeof (CHAR16))
35
36#define FVFS_VOLUME_LABEL_PREFIX        L"Firmware Volume: "
37#define FVFS_VOLUME_LABEL_SIZE          (sizeof (FVFS_VOLUME_LABEL_PREFIX) + GUID_STRING_SIZE - sizeof (CHAR16))
38#define FVFS_FALLBACK_VOLUME_LABEL      L"Firmware Volume"
39
40//
41// Template for EFI_SIMPLE_FILE_SYSTEM_PROTOCOL data structure.
42//
43EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mSimpleFsTemplate = {
44  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
45  FvSimpleFileSystemOpenVolume
46};
47
48//
49// Template for EFI_DRIVER_BINDING_PROTOCOL data structure.
50//
51EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = {
52  FvSimpleFileSystemDriverSupported,
53  FvSimpleFileSystemDriverStart,
54  FvSimpleFileSystemDriverStop,
55  0,
56  NULL,
57  NULL
58};
59
60/**
61  Open the root directory on a volume.
62
63  @param  This     A pointer to the volume to open the root directory.
64  @param  RootFile A pointer to the location to return the opened file handle for the
65                   root directory.
66
67  @retval EFI_SUCCESS          The device was opened.
68  @retval EFI_UNSUPPORTED      This volume does not support the requested file system type.
69  @retval EFI_NO_MEDIA         The device has no medium.
70  @retval EFI_DEVICE_ERROR     The device reported an error.
71  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
72  @retval EFI_ACCESS_DENIED    The service denied access to the file.
73  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
74  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
75                               longer supported. Any existing file handles for this volume are
76                               no longer valid. To access the files on the new medium, the
77                               volume must be reopened with OpenVolume().
78
79**/
80EFI_STATUS
81EFIAPI
82FvSimpleFileSystemOpenVolume (
83  IN     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
84     OUT EFI_FILE_PROTOCOL               **RootFile
85  )
86{
87  EFI_STATUS                      Status;
88  FV_FILESYSTEM_FILE              *Root;
89  CHAR16                          *UiSection;
90  EFI_GUID                        NameGuid;
91  EFI_FV_FILE_ATTRIBUTES          Attributes;
92  UINT32                          Authentication;
93  UINTN                           Key;
94  EFI_FV_FILETYPE                 FileType;
95  UINTN                           Size;
96  FV_FILESYSTEM_INSTANCE          *Instance;
97  FV_FILESYSTEM_FILE_INFO         *FvFileInfo;
98  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FvProtocol;
99  CHAR16                          *Name;
100  UINTN                           NameLen;
101  UINTN                           NumChars;
102  UINTN                           DestMax;
103
104  Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This);
105  Status = EFI_SUCCESS;
106
107  if (Instance->Root == NULL) {
108    //
109    // Allocate file structure for root file
110    //
111    Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
112    if (Root == NULL) {
113      return EFI_OUT_OF_RESOURCES;
114    }
115
116    Instance->Root  = Root;
117    Root->Instance  = Instance;
118    Root->Signature = FVFS_FILE_SIGNATURE;
119    CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
120    Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO));
121    if (Root->FvFileInfo == NULL) {
122        return EFI_OUT_OF_RESOURCES;
123    }
124    Root->FvFileInfo->FileInfo.Size      = sizeof (EFI_FILE_INFO);
125    Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY;
126
127    //
128    // Populate the instance's list of files. We consider anything a file that
129    // has a UI_SECTION, which we consider to be its filename.
130    //
131    FvProtocol = Instance->FvProtocol;
132    //
133    // Allocate Key
134    //
135    Key = 0;
136
137    do {
138      FileType = EFI_FV_FILETYPE_ALL;
139
140      Status = FvProtocol->GetNextFile (
141                             FvProtocol,
142                             &Key,
143                             &FileType,
144                             &NameGuid,
145                             &Attributes,
146                             &Size
147                             );
148      if (EFI_ERROR (Status)) {
149        ASSERT (Status == EFI_NOT_FOUND);
150        break;
151      }
152
153      //
154      // Get a file's name: If it has a UI section, use that, otherwise use
155      // its NameGuid.
156      //
157      UiSection = NULL;
158      Status = FvProtocol->ReadSection (
159                             FvProtocol,
160                             &NameGuid,
161                             EFI_SECTION_USER_INTERFACE,
162                             0,
163                             (VOID **)&UiSection,
164                             &Size,
165                             &Authentication
166                             );
167      if (!EFI_ERROR (Status)) {
168        Name = UiSection;
169      } else {
170        Name = AllocateZeroPool (GUID_STRING_SIZE);
171        if (Name == NULL) {
172          return EFI_OUT_OF_RESOURCES;
173        }
174        NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid);
175        ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE);
176      }
177
178      //
179      // Found a file.
180      // Allocate a file structure and populate it.
181      //
182      NameLen = StrSize (Name);
183      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
184        NameLen += StrSize (L".efi") - sizeof (CHAR16);
185      }
186
187      FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16));
188      if (FvFileInfo == NULL) {
189        return EFI_OUT_OF_RESOURCES;
190      }
191
192      FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE;
193      InitializeListHead (&FvFileInfo->Link);
194      CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID));
195      FvFileInfo->Type = FileType;
196
197      //
198      // Add ".efi" to filenames of drivers and applications.
199      //
200      DestMax = NameLen / sizeof (CHAR16);
201      Status  = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name));
202      ASSERT_EFI_ERROR (Status);
203
204      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
205        Status  = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi"));
206        ASSERT_EFI_ERROR (Status);
207      }
208
209      FvFileInfo->FileInfo.Size     = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16);
210      Status = FvFsGetFileSize (FvProtocol, FvFileInfo);
211      ASSERT_EFI_ERROR (Status);
212      FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize;
213      FvFileInfo->FileInfo.Attribute    = EFI_FILE_READ_ONLY;
214
215      InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link);
216
217      FreePool (Name);
218
219    } while (TRUE);
220
221    if (Status == EFI_NOT_FOUND) {
222      Status = EFI_SUCCESS;
223    }
224  }
225
226  Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
227  *RootFile = &Instance->Root->FileProtocol;
228  return Status;
229}
230
231/**
232  Worker function to initialize Unicode Collation support.
233
234  It tries to locate Unicode Collation (2) protocol and matches it with current
235  platform language code.
236
237  @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.
238  @param  ProtocolGuid         The pointer to Unicode Collation (2) protocol GUID.
239  @param  VariableName         The name of the RFC 4646 or ISO 639-2 language variable.
240  @param  DefaultLanguage      The default language in case the RFC 4646 or ISO 639-2 language is absent.
241
242  @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.
243  @retval Others               The Unicode Collation (2) protocol has not been located.
244
245**/
246EFI_STATUS
247InitializeUnicodeCollationSupportWorker (
248  IN       EFI_HANDLE             AgentHandle,
249  IN       EFI_GUID               *ProtocolGuid,
250  IN CONST CHAR16                 *VariableName,
251  IN CONST CHAR8                  *DefaultLanguage
252  )
253{
254  EFI_STATUS                      ReturnStatus;
255  EFI_STATUS                      Status;
256  UINTN                           NumHandles;
257  UINTN                           Index;
258  EFI_HANDLE                      *Handles;
259  EFI_UNICODE_COLLATION_PROTOCOL  *Uci;
260  BOOLEAN                         Iso639Language;
261  CHAR8                           *Language;
262  CHAR8                           *BestLanguage;
263
264  Status = gBS->LocateHandleBuffer (
265                  ByProtocol,
266                  ProtocolGuid,
267                  NULL,
268                  &NumHandles,
269                  &Handles
270                  );
271  if (EFI_ERROR (Status)) {
272    return Status;
273  }
274
275  Iso639Language = (BOOLEAN) (ProtocolGuid == &gEfiUnicodeCollationProtocolGuid);
276  GetEfiGlobalVariable2 (VariableName, (VOID**) &Language, NULL);
277
278  ReturnStatus = EFI_UNSUPPORTED;
279  for (Index = 0; Index < NumHandles; Index++) {
280    //
281    // Open Unicode Collation Protocol
282    //
283    Status = gBS->OpenProtocol (
284                    Handles[Index],
285                    ProtocolGuid,
286                    (VOID **) &Uci,
287                    AgentHandle,
288                    NULL,
289                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
290                    );
291    if (EFI_ERROR (Status)) {
292      continue;
293    }
294
295    //
296    // Find the best matching matching language from the supported languages
297    // of Unicode Collation (2) protocol.
298    //
299    BestLanguage = GetBestLanguage (
300                     Uci->SupportedLanguages,
301                     Iso639Language,
302                     (Language == NULL) ? "" : Language,
303                     DefaultLanguage,
304                     NULL
305                     );
306    if (BestLanguage != NULL) {
307      FreePool (BestLanguage);
308      mUnicodeCollation = Uci;
309      ReturnStatus = EFI_SUCCESS;
310      break;
311    }
312  }
313
314  if (Language != NULL) {
315    FreePool (Language);
316  }
317
318  FreePool (Handles);
319
320  return ReturnStatus;
321}
322
323/**
324  Initialize Unicode Collation support.
325
326  It tries to locate Unicode Collation 2 protocol and matches it with current
327  platform language code. If for any reason the first attempt fails, it then tries to
328  use Unicode Collation Protocol.
329
330  @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.
331
332  @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.
333  @retval Others               The Unicode Collation (2) protocol has not been located.
334
335**/
336EFI_STATUS
337InitializeUnicodeCollationSupport (
338  IN EFI_HANDLE    AgentHandle
339  )
340{
341
342  EFI_STATUS       Status;
343
344  Status = EFI_UNSUPPORTED;
345
346  //
347  // First try to use RFC 4646 Unicode Collation 2 Protocol.
348  //
349  Status = InitializeUnicodeCollationSupportWorker (
350             AgentHandle,
351             &gEfiUnicodeCollation2ProtocolGuid,
352             L"PlatformLang",
353             (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
354             );
355  //
356  // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back
357  // on the ISO 639-2 Unicode Collation Protocol.
358  //
359  if (EFI_ERROR (Status)) {
360    Status = InitializeUnicodeCollationSupportWorker (
361               AgentHandle,
362               &gEfiUnicodeCollationProtocolGuid,
363               L"Lang",
364               (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang)
365               );
366  }
367
368  return Status;
369}
370
371/**
372  Test to see if this driver supports ControllerHandle.
373
374  @param  DriverBinding       Protocol instance pointer.
375  @param  ControllerHandle    Handle of device to test
376  @param  RemainingDevicePath Optional parameter use to pick a specific child
377                              device to start.
378
379  @retval EFI_SUCCESS         This driver supports this device
380  @retval EFI_ALREADY_STARTED This driver is already running on this device
381  @retval other               This driver does not support this device
382
383**/
384EFI_STATUS
385EFIAPI
386FvSimpleFileSystemDriverSupported (
387  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,
388  IN  EFI_HANDLE                   ControllerHandle,
389  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
390  )
391{
392  return gBS->OpenProtocol (
393                ControllerHandle,
394                &gEfiFirmwareVolume2ProtocolGuid,
395                NULL,
396                gImageHandle,
397                ControllerHandle,
398                EFI_OPEN_PROTOCOL_TEST_PROTOCOL
399                );
400}
401
402/**
403  Start this driver on ControllerHandle by opening a FV protocol and
404  installing a SimpleFileSystem protocol on ControllerHandle.
405
406  @param  DriverBinding        Protocol instance pointer.
407  @param  ControllerHandle     Handle of device to bind driver to
408  @param  RemainingDevicePath  Optional parameter use to pick a specific child
409                               device to start.
410
411  @retval EFI_SUCCESS          This driver is added to ControllerHandle
412  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
413  @retval other                This driver does not support this device
414
415**/
416EFI_STATUS
417EFIAPI
418FvSimpleFileSystemDriverStart (
419  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,
420  IN  EFI_HANDLE                   ControllerHandle,
421  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
422  )
423{
424  EFI_STATUS                       Status;
425  EFI_FIRMWARE_VOLUME2_PROTOCOL    *FvProtocol;
426  FV_FILESYSTEM_INSTANCE           *Instance;
427  EFI_DEVICE_PATH_PROTOCOL         *FvDevicePath;
428  EFI_GUID                         *FvGuid;
429  UINTN                            NumChars;
430
431  Status = InitializeUnicodeCollationSupport (DriverBinding->DriverBindingHandle);
432  if (EFI_ERROR (Status)) {
433    return Status;
434  }
435
436  //
437  // Open FV protocol
438  //
439  Status = gBS->OpenProtocol (
440                  ControllerHandle,
441                  &gEfiFirmwareVolume2ProtocolGuid,
442                  (VOID **) &FvProtocol,
443                  gImageHandle,
444                  ControllerHandle,
445                  EFI_OPEN_PROTOCOL_BY_DRIVER
446                  );
447  if (EFI_ERROR (Status)) {
448    return Status;
449  }
450
451  //
452  // Create an instance
453  //
454  Instance = AllocateZeroPool (sizeof (FV_FILESYSTEM_INSTANCE));
455  if (Instance == NULL) {
456    return EFI_OUT_OF_RESOURCES;
457  }
458
459  Instance->Root = NULL;
460  Instance->FvProtocol = FvProtocol;
461  Instance->Signature = FVFS_INSTANCE_SIGNATURE;
462  InitializeListHead (&Instance->FileInfoHead);
463  InitializeListHead (&Instance->FileHead);
464  CopyMem (&Instance->SimpleFs, &mSimpleFsTemplate, sizeof (mSimpleFsTemplate));
465
466  Status = gBS->InstallProtocolInterface(
467                  &ControllerHandle,
468                  &gEfiSimpleFileSystemProtocolGuid,
469                  EFI_NATIVE_INTERFACE,
470                  &Instance->SimpleFs
471                  );
472
473  //
474  // Decide on a filesystem volume label, which will include the FV's guid.
475  // Get the device path to find the FV's GUID
476  //
477  Instance->VolumeLabel = NULL;
478  Status =  gBS->OpenProtocol (
479                   ControllerHandle,
480                   &gEfiDevicePathProtocolGuid,
481                   (VOID **) &FvDevicePath,
482                   gImageHandle,
483                   ControllerHandle,
484                   EFI_OPEN_PROTOCOL_BY_DRIVER
485                   );
486  if (!EFI_ERROR (Status)) {
487    //
488    // Iterate over device path until we find a firmware volume node
489    //
490    while (!IsDevicePathEndType (FvDevicePath)) {
491      if (DevicePathType (FvDevicePath) == MEDIA_DEVICE_PATH &&
492          DevicePathSubType (FvDevicePath) == MEDIA_PIWG_FW_VOL_DP) {
493        //
494        // Allocate the volume label
495        //
496        Instance->VolumeLabel = AllocateZeroPool (FVFS_VOLUME_LABEL_SIZE);
497        //
498        // Check the allocation was successful
499        //
500        if (Instance->VolumeLabel != NULL) {
501          //
502          // Extract the FV's guid
503          //
504          FvGuid = &((MEDIA_FW_VOL_DEVICE_PATH *) FvDevicePath)->FvName;
505          //
506          // Build the volume label string
507          //
508          NumChars = UnicodeSPrint (
509                       Instance->VolumeLabel,
510                       FVFS_VOLUME_LABEL_SIZE,
511                       FVFS_VOLUME_LABEL_PREFIX L"%g",
512                       FvGuid
513                       );
514          ASSERT ((NumChars + 1) * sizeof (CHAR16) == FVFS_VOLUME_LABEL_SIZE);
515        }
516        break;
517      }
518      FvDevicePath = NextDevicePathNode (FvDevicePath);
519    }
520  }
521  //
522  // If we didn't decide on a volume label, set a fallback one
523  //
524  if (Instance->VolumeLabel == NULL) {
525    Instance->VolumeLabel = AllocateCopyPool (
526                              sizeof (FVFS_FALLBACK_VOLUME_LABEL),
527                              FVFS_FALLBACK_VOLUME_LABEL
528                              );
529  }
530
531  return Status;
532}
533
534/**
535  Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing
536  the FV protocol on ControllerHandle.
537
538  @param  DriverBinding     Protocol instance pointer.
539  @param  ControllerHandle  Handle of device to stop driver on
540  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
541                            children is zero stop the entire bus driver.
542  @param  ChildHandleBuffer List of Child Handles to Stop.
543
544  @retval EFI_SUCCESS       This driver is removed ControllerHandle
545  @retval other             This driver was not removed from this device
546
547**/
548EFI_STATUS
549EFIAPI
550FvSimpleFileSystemDriverStop (
551  IN  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding,
552  IN  EFI_HANDLE                        ControllerHandle,
553  IN  UINTN                             NumberOfChildren,
554  IN  EFI_HANDLE                        *ChildHandleBuffer OPTIONAL
555  )
556{
557  EFI_STATUS                       Status;
558  FV_FILESYSTEM_INSTANCE           *Instance;
559  FV_FILESYSTEM_FILE_INFO          *FvFileInfo;
560  LIST_ENTRY                       *Entry;
561  LIST_ENTRY                       *DelEntry;
562  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *SimpleFile;
563
564  Status = gBS->OpenProtocol (
565                  ControllerHandle,
566                  &gEfiSimpleFileSystemProtocolGuid,
567                  (VOID **) &SimpleFile,
568                  DriverBinding->DriverBindingHandle,
569                  ControllerHandle,
570                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
571                  );
572  if (EFI_ERROR (Status)) {
573    return Status;
574  }
575
576  Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (SimpleFile);
577
578  if (IsListEmpty (&Instance->FileHead) == FALSE) {
579    //
580    // Not all opened files are closed
581    //
582    return EFI_DEVICE_ERROR;
583  }
584
585  //
586  // Close and uninstall protocols.
587  //
588  Status = gBS->CloseProtocol (
589                   ControllerHandle,
590                   &gEfiFirmwareVolume2ProtocolGuid,
591                   gImageHandle,
592                   ControllerHandle
593                   );
594  ASSERT_EFI_ERROR (Status);
595
596  Status = gBS->UninstallProtocolInterface (
597                  ControllerHandle,
598                  &gEfiSimpleFileSystemProtocolGuid,
599                  &Instance->SimpleFs
600                  );
601  ASSERT_EFI_ERROR (Status);
602
603  //
604  // Free file structures
605  //
606  if (!IsListEmpty (&Instance->FileInfoHead)) {
607    //
608    // Free the Subtask list.
609    //
610    for(Entry = Instance->FileInfoHead.ForwardLink;
611        Entry != (&Instance->FileInfoHead);
612       ) {
613      DelEntry   = Entry;
614      Entry      = Entry->ForwardLink;
615      FvFileInfo = FVFS_FILE_INFO_FROM_LINK (DelEntry);
616
617      RemoveEntryList (DelEntry);
618      FreePool (FvFileInfo);
619    }
620  }
621
622  if (Instance->Root != NULL) {
623    //
624    // Root->Name is statically allocated, no need to free.
625    //
626    if (Instance->Root->FvFileInfo != NULL) {
627      FreePool (Instance->Root->FvFileInfo);
628    }
629    FreePool (Instance->Root);
630  }
631
632  //
633  // Free Instance
634  //
635  if (Instance->VolumeLabel != NULL) {
636    FreePool (Instance->VolumeLabel);
637  }
638  FreePool (Instance);
639
640  return EFI_SUCCESS;
641}
642
643/**
644  The user Entry Point for module FvSimpleFileSystem. The user code starts with this function.
645
646  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
647  @param[in] SystemTable    A pointer to the EFI System Table.
648
649  @retval EFI_SUCCESS       The entry point is executed successfully.
650  @retval other             Some error occurs when executing this entry point.
651
652**/
653EFI_STATUS
654EFIAPI
655FvSimpleFileSystemEntryPoint (
656  IN EFI_HANDLE               ImageHandle,
657  IN EFI_SYSTEM_TABLE         *SystemTable
658  )
659{
660  EFI_STATUS Status;
661
662  //
663  // Install driver model protocol(s).
664  //
665  Status = EfiLibInstallDriverBindingComponentName2 (
666             ImageHandle,
667             SystemTable,
668             &mDriverBinding,
669             ImageHandle,
670             &gFvSimpleFileSystemComponentName,
671             &gFvSimpleFileSystemComponentName2
672             );
673  ASSERT_EFI_ERROR (Status);
674
675  return Status;
676}
677