]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Ebl/Dir.c
Adding support for BeagleBoard.
[mirror_edk2.git] / EmbeddedPkg / Ebl / Dir.c
diff --git a/EmbeddedPkg/Ebl/Dir.c b/EmbeddedPkg/Ebl/Dir.c
new file mode 100644 (file)
index 0000000..4e9f7b9
--- /dev/null
@@ -0,0 +1,305 @@
+/** @file\r
+  Dir for EBL (Embedded Boot Loader)\r
+\r
+  Copyright (c) 2007, Intel Corporation<BR>\r
+  Portions copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
+\r
+\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  Module Name:  CmdTemplate.c\r
+\r
+  Search/Replace Dir with the name of your new command\r
+\r
+**/\r
+\r
+#include "Ebl.h"\r
+\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED   CHAR8 *gFvFileType[] = {\r
+  "All",\r
+  "Raw",\r
+  "Freeform",\r
+  "SEC",\r
+  "PeiCore",\r
+  "DxeCore",\r
+  "PEIM",\r
+  "Driver",\r
+  "Combo Driver",\r
+  "Application",\r
+  "NULL",\r
+  "FV"\r
+};\r
+\r
+\r
+/**\r
+  Perform a dir on a device. The device must support Simple File System Protocol\r
+  or the FV protocol. \r
+\r
+  Argv[0] - "dir"\r
+  Argv[1] - Device Name:path. Path is optional \r
+  Argv[2] - Optional filename to match on. A leading * means match substring\r
+  Argv[3] - Optional FV file type\r
+\r
+  dir fs1:\efi      ; perform a dir on fs1: device in the efi directory\r
+  dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but \r
+                      only print out files that contain the string *.efi\r
+  dir fv1:\         ; perform a dir on fv1: device in the efi directory \r
+                    NOTE: fv devices do not contian subdirs \r
+  dir fv1:\ * PEIM  ; will match all files of type SEC\r
+\r
+  @param  Argc   Number of command arguments in Argv\r
+  @param  Argv   Array of strings that represent the parsed command line. \r
+                 Argv[0] is the comamnd name\r
+\r
+  @return EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EblDirCmd (\r
+  IN UINTN  Argc,\r
+  IN CHAR8  **Argv\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_OPEN_FILE                 *File;\r
+  EFI_FILE_INFO                 *DirInfo;\r
+  UINTN                         ReadSize;\r
+  UINTN                         CurrentRow;  \r
+  CHAR16                        *MatchSubString;\r
+  EFI_STATUS                    GetNextFileStatus;\r
+  UINTN                         Key;\r
+  EFI_FV_FILETYPE               SearchType;\r
+  EFI_FV_FILETYPE               Type;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINTN                         Size;\r
+  EFI_GUID                      NameGuid;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
+  UINT32                        AuthenticationStatus;\r
+  VOID                          *Section;\r
+  UINTN                         SectionSize;\r
+  EFI_FV_FILETYPE               Index;\r
+  UINTN                         Length;\r
+  UINTN                         BestMatchCount;\r
+  CHAR16                        UnicodeFileName[MAX_CMD_LINE];\r
+\r
+\r
+  if (Argc <= 1) {\r
+    // CWD not currently supported \r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);\r
+  if (File == NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (File->Type == EfiOpenFirmwareVolume) {\r
+    // FV Dir\r
+\r
+    SearchType = EFI_FV_FILETYPE_ALL;\r
+    UnicodeFileName[0] = '\0';\r
+    MatchSubString = &UnicodeFileName[0];\r
+    if (Argc > 2) {\r
+      AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);\r
+      if (UnicodeFileName[0] == '*') {\r
+        // Handle *Name substring matching\r
+        MatchSubString = &UnicodeFileName[1];\r
+      }\r
+\r
+      // Handle file type matchs\r
+      if (Argc > 3) {\r
+        // match a specific file type, always last argument\r
+        Length = AsciiStrLen (Argv[3]);\r
+        for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {\r
+          if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {\r
+            // exact match\r
+            SearchType = Index;\r
+            break;\r
+          }\r
+\r
+          if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {\r
+            // partial match, so keep looking to make sure there is only one partial match\r
+            BestMatchCount++;\r
+            SearchType = Index;\r
+          }\r
+        }\r
+\r
+        if (BestMatchCount > 1) {\r
+          SearchType = EFI_FV_FILETYPE_ALL;\r
+        }\r
+      }\r
+    }\r
+\r
+    Fv = File->Fv;\r
+    Key = 0;\r
+    CurrentRow = 0;\r
+    do {\r
+      Type = SearchType;\r
+      GetNextFileStatus = Fv->GetNextFile (\r
+                                Fv, \r
+                                &Key,\r
+                                &Type,  \r
+                                &NameGuid, \r
+                                &Attributes, \r
+                                &Size\r
+                                );\r
+      if (!EFI_ERROR (GetNextFileStatus)) {\r
+         // Calculate size of entire file\r
+         Section = NULL;\r
+         Size = 0;\r
+         Status = Fv->ReadFile (\r
+                      Fv,\r
+                      &NameGuid, \r
+                      Section,\r
+                      &Size,\r
+                      &Type,\r
+                      &Attributes,\r
+                      &AuthenticationStatus\r
+                      );\r
+         if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {\r
+          // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid \r
+          Size = 0;\r
+         }\r
+\r
+        // read the UI seciton to do a name match.\r
+        Section = NULL;\r
+        Status = Fv->ReadSection (\r
+                        Fv,\r
+                        &NameGuid,\r
+                        EFI_SECTION_USER_INTERFACE,\r
+                        0,\r
+                        &Section,\r
+                        &SectionSize,\r
+                        &AuthenticationStatus\r
+                        );\r
+        if (!EFI_ERROR (Status)) {\r
+          if (StrStr (Section, MatchSubString) != NULL) {\r
+            AsciiPrint ("  %g %s %a %,d\n", &NameGuid, Section, gFvFileType[Type], Size);\r
+            if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
+              break;\r
+            }\r
+          }\r
+          FreePool (Section);\r
+        } else {\r
+          if (*MatchSubString == '\0') {\r
+            AsciiPrint ("  %g %a %,d\n", &NameGuid, gFvFileType[Type], Size);\r
+            if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
+              break;\r
+            }\r
+          }\r
+        }\r
+      }\r
+    } while (!EFI_ERROR (GetNextFileStatus));\r
+       \r
+  } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {\r
+    // Simple File System DIR\r
+\r
+    if (File->FsFileInfo ==  NULL) {\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    // Handle *Name substring matching\r
+    MatchSubString = NULL;\r
+    UnicodeFileName[0] = '\0';\r
+    if (Argc > 2) {\r
+      AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);\r
+      if (UnicodeFileName[0] == '*') {\r
+        MatchSubString = &UnicodeFileName[1];\r
+      }\r
+    } \r
+\r
+    File->FsFileHandle->SetPosition (File->FsFileHandle, 0);\r
+    for (CurrentRow = 0;;) {\r
+      // First read gets the size\r
+      DirInfo = NULL;\r
+      ReadSize = 0;\r
+      Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);\r
+      if (Status == EFI_BUFFER_TOO_SMALL) {\r
+        // Allocate the buffer for the real read\r
+        DirInfo = AllocatePool (ReadSize);\r
+        if (DirInfo == NULL) {\r
+          goto Done;\r
+        }\r
+        \r
+        // Read the data\r
+        Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);\r
+        if ((EFI_ERROR (Status)) || (ReadSize == 0)) {\r
+          break;\r
+        }\r
+      } else {\r
+        break;\r
+      }\r
+      \r
+      if (MatchSubString != NULL) {\r
+        if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {\r
+          // does not match *name argument, so skip\r
+          continue;\r
+        }\r
+      } else if (UnicodeFileName[0] != '\0') {\r
+        // is not an exact match for name argument, so skip\r
+        if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {\r
+          continue;\r
+        }\r
+      }\r
+\r
+      if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {\r
+        AsciiPrint ("         <DIR> %s\n", &DirInfo->FileName[0]);\r
+      } else {\r
+        AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);\r
+      }\r
+\r
+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {\r
+        break;\r
+      }\r
+      \r
+      FreePool (DirInfo);\r
+    }\r
+\r
+Done:\r
+    if (DirInfo != NULL) {\r
+      FreePool (DirInfo);\r
+    }\r
+  }\r
+\r
+  EfiClose (File);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] =\r
+{\r
+  {\r
+    "dir",\r
+    " dirdev [*match]; directory listing of dirdev. opt match a substring",\r
+    NULL,\r
+    EblDirCmd\r
+  }\r
+};\r
+\r
+\r
+/**\r
+  Initialize the commands in this in this file\r
+**/\r
+VOID\r
+EblInitializeDirCmd (\r
+  VOID\r
+  )\r
+{  \r
+  if (FeaturePcdGet (PcdEmbeddedDirCmd)) {\r
+    EblAddCommands (mCmdDirTemplate, sizeof (mCmdDirTemplate)/sizeof (EBL_COMMAND_TABLE));\r
+  }\r
+}\r
+\r