]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Ebl/EfiDevice.c
MmcDxe: Adding eMMC support
[mirror_edk2.git] / EmbeddedPkg / Ebl / EfiDevice.c
index e129a3cb8caad84fdb68b542dfaca993cabbb442..c623bd8b7e17782e030a2cead28c301a2fbb8cda 100644 (file)
@@ -1,10 +1,10 @@
 /** @file\r
   EBL commands for EFI and PI Devices\r
 \r
-  Copyright (c) 2007, Intel Corporation<BR>\r
-  Portions copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
+  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
 \r
-  All rights reserved. This program and the accompanying materials\r
+  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
@@ -31,13 +31,22 @@ EblPrintFsInfo (
   IN  EFI_OPEN_FILE   *File\r
   )\r
 {\r
+  CHAR16 *Str;\r
+\r
   if (File == NULL) {\r
     return;\r
   }\r
 \r
   AsciiPrint ("  %a: ", File->DeviceName);\r
   if (File->FsInfo != NULL) {\r
-    AsciiPrint ("%s: ", File->FsInfo->VolumeLabel);\r
+    for (Str = File->FsInfo->VolumeLabel; *Str != '\0'; Str++) {\r
+      if (*Str == ' ') {\r
+        // UI makes you enter _ for space, so make the printout match that\r
+        *Str = '_';\r
+      }\r
+      AsciiPrint ("%c", *Str);\r
+    }\r
+    AsciiPrint (":");\r
     if (File->FsInfo->ReadOnly) {\r
       AsciiPrint ("ReadOnly");\r
     }\r
@@ -102,24 +111,24 @@ EblPrintBlkIoInfo (
           EfiClose (FsFile);\r
           break;\r
         }\r
+        EfiClose (FsFile);\r
       }\r
-      EfiClose (FsFile);\r
     }\r
   }\r
 \r
   // Print out useful Block IO media properties\r
-  if (File->FsBlockIoMedia.RemovableMedia) {\r
+  if (File->FsBlockIoMedia->RemovableMedia) {\r
     AsciiPrint ("Removable ");\r
   }\r
-  if (!File->FsBlockIoMedia.MediaPresent) {\r
-    AsciiPrint ("No Media ");\r
-  }\r
-  if (File->FsBlockIoMedia.LogicalPartition) {\r
-    AsciiPrint ("Partition ");\r
+  if (!File->FsBlockIoMedia->MediaPresent) {\r
+    AsciiPrint ("No Media\n");\r
+  } else {\r
+    if (File->FsBlockIoMedia->LogicalPartition) {\r
+      AsciiPrint ("Partition ");\r
+    }\r
+    DeviceSize = MultU64x32 (File->FsBlockIoMedia->LastBlock + 1, File->FsBlockIoMedia->BlockSize);\r
+    AsciiPrint ("Size = 0x%lX\n", DeviceSize);\r
   }\r
-  DeviceSize = MultU64x32 (File->FsBlockIoMedia.LastBlock + 1, File->FsBlockIoMedia.BlockSize);\r
-  AsciiPrint ("Size = 0x%lX\n", DeviceSize);\r
-\r
   EfiClose (File);\r
 }\r
 \r
@@ -187,7 +196,7 @@ EblPrintLoadFileInfo (
 \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
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -203,10 +212,11 @@ EblDeviceCmd (
   UINTN         Max;\r
 \r
   CurrentRow = 0;\r
-  \r
+\r
   // Need to call here to make sure Device Counts are valid\r
   EblUpdateDeviceLists ();\r
 \r
+  // Now we can print out the info...\r
   Max = EfiGetDeviceCounts (EfiOpenFirmwareVolume);\r
   if (Max != 0) {\r
     AsciiPrint ("Firmware Volume Devices:\n");\r
@@ -269,7 +279,7 @@ EblDeviceCmd (
 \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
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -343,7 +353,7 @@ EblStartCmd (
 \r
 /**\r
   Load a Firmware Volume (FV) into memory from a device. This causes drivers in\r
-  the FV to be dispatched if the dependancies of the drivers are met.\r
+  the FV to be dispatched if the dependencies of the drivers are met.\r
   \r
   Argv[0] - "loadfv"\r
   Argv[1] - device name and path\r
@@ -354,7 +364,7 @@ EblStartCmd (
 \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
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -393,7 +403,9 @@ EblLoadFvCmd (
     }\r
       \r
     Status = gDS->ProcessFirmwareVolume (FvStart, FvSize, &FvHandle);\r
-    FreePool (FvStart);\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (FvStart);\r
+    } \r
   }\r
   return Status;\r
 }\r
@@ -402,13 +414,13 @@ EblLoadFvCmd (
 /**\r
   Perform an EFI connect to connect devices that follow the EFI driver model. \r
   If it is a PI system also call the dispatcher in case a new FV was made\r
-  availible by one of the connect EFI drivers (this is not a common case).\r
+  available by one of the connect EFI drivers (this is not a common case).\r
   \r
   Argv[0] - "connect"\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
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -530,7 +542,7 @@ CHAR8 *gMemMapType[] = {
 \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
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -616,7 +628,7 @@ EblMemMapCmd (
 \r
 \r
 /**\r
-  Load a file into memory and optionally jump to it. A load addres can be \r
+  Load a file into memory and optionally jump to it. A load address can be\r
   specified or automatically allocated. A quoted command line can optionally\r
   be passed into the image. \r
 \r
@@ -632,14 +644,14 @@ EblMemMapCmd (
     in "EblCmdX Arg2 Arg3 Arg4" as the arguments.\r
 \r
   go fv0:\EblCmdX  *  0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0 \r
-    to location allocated by this comamnd and call the entry point at offset 0x10 \r
+    to location allocated by this command and call the entry point at offset 0x10\r
     passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments.\r
 \r
   go fv1:\EblCmdX  0x10000; Load EblCmdX to address 0x10000 and return\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
+                 Argv[0] is the command name\r
 \r
   @return EFI_SUCCESS\r
 \r
@@ -675,7 +687,7 @@ EblGoCmd (
     // * Means allocate the buffer\r
     Status = EfiReadAllocatePool (File, &Address, &Size);\r
     \r
-    // EntryPoint is relatvie to the start of the image \r
+    // EntryPoint is relative to the start of the image\r
     EntryPoint = (EBL_COMMMAND)((UINTN)EntryPoint + (UINTN)Address);\r
 \r
   } else {\r
@@ -720,19 +732,64 @@ EblFileCopyCmd (
   VOID          *Buffer      = NULL;\r
   UINTN         Size;\r
   UINTN         Offset;\r
-  UINTN         Chunk = FILE_COPY_CHUNK;\r
-  \r
+  UINTN         Chunk        = FILE_COPY_CHUNK;\r
+  UINTN         FileNameLen;\r
+  CHAR8*        DestFileName;\r
+  CHAR8*        SrcFileName;\r
+  CHAR8*        SrcPtr;\r
+\r
   if (Argc < 3) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r
+  DestFileName = Argv[2];\r
+  FileNameLen = AsciiStrLen (DestFileName);\r
+\r
+  // Check if the destination file name looks like a directory\r
+  if ((DestFileName[FileNameLen-1] == '\\') || (DestFileName[FileNameLen-1] == ':')) {\r
+    // Set the pointer after the source drive (eg: after fs1:)\r
+    SrcPtr = AsciiStrStr (Argv[1], ":");\r
+    if (SrcPtr == NULL) {\r
+      SrcPtr = Argv[1];\r
+    } else {\r
+      SrcPtr++;\r
+      if (*SrcPtr == '\\') {\r
+        SrcPtr++;\r
+      }\r
+    }\r
+\r
+    if (*SrcPtr == '\0') {\r
+      AsciiPrint("Source file incorrect.\n");\r
+    }\r
+\r
+    // Skip the Source Directories\r
+    while (1) {\r
+      SrcFileName = SrcPtr;\r
+      SrcPtr = AsciiStrStr (SrcPtr,"\\");\r
+      if (SrcPtr != NULL) {\r
+        SrcPtr++;\r
+      } else {\r
+        break;\r
+      }\r
+    }\r
+\r
+    if (*SrcFileName == '\0') {\r
+      AsciiPrint("Source file incorrect (Error 2).\n");\r
+    }\r
+\r
+    // Construct the destination filepath\r
+    DestFileName = (CHAR8*)AllocatePool (FileNameLen + AsciiStrLen (SrcFileName) + 1);\r
+    AsciiStrCpy (DestFileName, Argv[2]);\r
+    AsciiStrCat (DestFileName, SrcFileName);\r
+  }\r
+\r
   Source = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);\r
   if (Source == NULL) {\r
     AsciiPrint("Source file open error.\n");\r
     return EFI_NOT_FOUND;\r
   }\r
   \r
-  Destination = EfiOpen(Argv[2], EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);\r
+  Destination = EfiOpen(DestFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);\r
   if (Destination == NULL) {\r
     AsciiPrint("Destination file open error.\n");\r
     return EFI_NOT_FOUND;\r
@@ -750,13 +807,13 @@ EblFileCopyCmd (
     \r
     Status = EfiRead(Source, Buffer, &Chunk);\r
     if (EFI_ERROR(Status)) {\r
-      AsciiPrint("Read file error\n");\r
+      AsciiPrint("Read file error %r\n", Status);\r
       goto Exit;\r
     }\r
 \r
     Status = EfiWrite(Destination, Buffer, &Chunk);\r
     if (EFI_ERROR(Status)) {\r
-      AsciiPrint("Write file error\n");\r
+      AsciiPrint("Write file error %r\n", Status);\r
       goto Exit;\r
     }    \r
   }\r
@@ -767,17 +824,18 @@ EblFileCopyCmd (
     \r
     Status = EfiRead(Source, Buffer, &Chunk);\r
     if (EFI_ERROR(Status)) {\r
-      AsciiPrint("Read file error\n");\r
+      AsciiPrint("Read file error %r\n", Status);\r
       goto Exit;\r
     }\r
 \r
     Status = EfiWrite(Destination, Buffer, &Chunk);\r
     if (EFI_ERROR(Status)) {\r
-      AsciiPrint("Write file error\n");\r
+      AsciiPrint("Write file error %r\n", Status);\r
       goto Exit;\r
     }    \r
   }\r
 \r
+\r
 Exit:\r
   if (Source != NULL) {\r
     Status = EfiClose(Source);\r
@@ -785,12 +843,16 @@ Exit:
       AsciiPrint("Source close error %r\n", Status);\r
     }\r
   }\r
-  \r
   if (Destination != NULL) {\r
     Status = EfiClose(Destination);\r
     if (EFI_ERROR(Status)) {\r
       AsciiPrint("Destination close error %r\n", Status);\r
     }\r
+\r
+    // Case when we have concated the filename to the destination directory\r
+    if (DestFileName != Argv[2]) {\r
+      FreePool (DestFileName);\r
+    }\r
   }\r
   \r
   if (Buffer != NULL) {\r
@@ -960,7 +1022,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDeviceTemplate[] =
   },\r
   {\r
     "cp",\r
-    " file1 file2; copy file",\r
+    " file1 file2; copy file only.",\r
     NULL,\r
     EblFileCopyCmd\r
   },\r