Home | History | Annotate | Download | only in SemihostLib
      1 /** @file
      2 
      3   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
      4   Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 #include <Base.h>
     16 
     17 #include <Library/BaseLib.h>
     18 #include <Library/SemihostLib.h>
     19 
     20 #include "SemihostPrivate.h"
     21 
     22 BOOLEAN
     23 SemihostConnectionSupported (
     24   VOID
     25   )
     26 {
     27   return SEMIHOST_SUPPORTED;
     28 }
     29 
     30 RETURN_STATUS
     31 SemihostFileOpen (
     32   IN  CHAR8  *FileName,
     33   IN  UINT32 Mode,
     34   OUT UINTN  *FileHandle
     35   )
     36 {
     37   SEMIHOST_FILE_OPEN_BLOCK  OpenBlock;
     38   INT32                     Result;
     39 
     40   if (FileHandle == NULL) {
     41     return RETURN_INVALID_PARAMETER;
     42   }
     43 
     44   // Remove any leading separator (e.g.: '\'). EFI Shell adds one.
     45   if (*FileName == '\\') {
     46     FileName++;
     47   }
     48 
     49   OpenBlock.FileName    = FileName;
     50   OpenBlock.Mode        = Mode;
     51   OpenBlock.NameLength  = AsciiStrLen(FileName);
     52 
     53   Result = Semihost_SYS_OPEN(&OpenBlock);
     54 
     55   if (Result == -1) {
     56     return RETURN_NOT_FOUND;
     57   } else {
     58     *FileHandle = Result;
     59     return RETURN_SUCCESS;
     60   }
     61 }
     62 
     63 RETURN_STATUS
     64 SemihostFileSeek (
     65   IN UINTN  FileHandle,
     66   IN UINTN  Offset
     67   )
     68 {
     69   SEMIHOST_FILE_SEEK_BLOCK  SeekBlock;
     70   INT32                     Result;
     71 
     72   SeekBlock.Handle   = FileHandle;
     73   SeekBlock.Location = Offset;
     74 
     75   Result = Semihost_SYS_SEEK(&SeekBlock);
     76 
     77   // Semihosting does not behave as documented. It returns the offset on
     78   // success.
     79   if (Result < 0) {
     80     return RETURN_ABORTED;
     81   } else {
     82     return RETURN_SUCCESS;
     83   }
     84 }
     85 
     86 RETURN_STATUS
     87 SemihostFileRead (
     88   IN     UINTN  FileHandle,
     89   IN OUT UINTN  *Length,
     90   OUT    VOID   *Buffer
     91   )
     92 {
     93   SEMIHOST_FILE_READ_WRITE_BLOCK  ReadBlock;
     94   UINT32                          Result;
     95 
     96   if ((Length == NULL) || (Buffer == NULL)) {
     97     return RETURN_INVALID_PARAMETER;
     98   }
     99 
    100   ReadBlock.Handle = FileHandle;
    101   ReadBlock.Buffer = Buffer;
    102   ReadBlock.Length = *Length;
    103 
    104   Result = Semihost_SYS_READ(&ReadBlock);
    105 
    106   if ((*Length != 0) && (Result == *Length)) {
    107     return RETURN_ABORTED;
    108   } else {
    109     *Length -= Result;
    110     return RETURN_SUCCESS;
    111   }
    112 }
    113 
    114 RETURN_STATUS
    115 SemihostFileWrite (
    116   IN     UINTN  FileHandle,
    117   IN OUT UINTN  *Length,
    118   IN     VOID   *Buffer
    119   )
    120 {
    121   SEMIHOST_FILE_READ_WRITE_BLOCK  WriteBlock;
    122 
    123   if ((Length == NULL) || (Buffer == NULL)) {
    124     return RETURN_INVALID_PARAMETER;
    125   }
    126 
    127   WriteBlock.Handle = FileHandle;
    128   WriteBlock.Buffer = Buffer;
    129   WriteBlock.Length = *Length;
    130 
    131   *Length = Semihost_SYS_WRITE(&WriteBlock);
    132 
    133   if (*Length != 0)
    134     return RETURN_ABORTED;
    135   else
    136     return RETURN_SUCCESS;
    137 }
    138 
    139 RETURN_STATUS
    140 SemihostFileClose (
    141   IN UINTN  FileHandle
    142   )
    143 {
    144   INT32 Result = Semihost_SYS_CLOSE(&FileHandle);
    145 
    146   if (Result == -1) {
    147     return RETURN_INVALID_PARAMETER;
    148   } else {
    149     return RETURN_SUCCESS;
    150   }
    151 }
    152 
    153 RETURN_STATUS
    154 SemihostFileLength (
    155   IN  UINTN  FileHandle,
    156   OUT UINTN  *Length
    157   )
    158 {
    159   INT32       Result;
    160 
    161   if (Length == NULL) {
    162     return RETURN_INVALID_PARAMETER;
    163   }
    164 
    165   Result = Semihost_SYS_FLEN(&FileHandle);
    166 
    167   if (Result == -1) {
    168     return RETURN_ABORTED;
    169   } else {
    170     *Length = Result;
    171     return RETURN_SUCCESS;
    172   }
    173 }
    174 
    175 /**
    176   Get a temporary name for a file from the host running the debug agent.
    177 
    178   @param[out]  Buffer      Pointer to the buffer where the temporary name has to
    179                            be stored
    180   @param[in]   Identifier  File name identifier (integer in the range 0 to 255)
    181   @param[in]   Length      Length of the buffer to store the temporary name
    182 
    183   @retval  RETURN_SUCCESS            Temporary name returned
    184   @retval  RETURN_INVALID_PARAMETER  Invalid buffer address
    185   @retval  RETURN_ABORTED            Temporary name not returned
    186 
    187 **/
    188 RETURN_STATUS
    189 SemihostFileTmpName(
    190   OUT  VOID   *Buffer,
    191   IN   UINT8  Identifier,
    192   IN   UINTN  Length
    193   )
    194 {
    195   SEMIHOST_FILE_TMPNAME_BLOCK  TmpNameBlock;
    196   INT32                        Result;
    197 
    198   if (Buffer == NULL) {
    199     return RETURN_INVALID_PARAMETER;
    200   }
    201 
    202   TmpNameBlock.Buffer     = Buffer;
    203   TmpNameBlock.Identifier = Identifier;
    204   TmpNameBlock.Length     = Length;
    205 
    206   Result = Semihost_SYS_TMPNAME (&TmpNameBlock);
    207 
    208   if (Result != 0) {
    209     return  RETURN_ABORTED;
    210   } else {
    211     return  RETURN_SUCCESS;
    212   }
    213 }
    214 
    215 RETURN_STATUS
    216 SemihostFileRemove (
    217   IN CHAR8 *FileName
    218   )
    219 {
    220   SEMIHOST_FILE_REMOVE_BLOCK  RemoveBlock;
    221   UINT32                      Result;
    222 
    223   // Remove any leading separator (e.g.: '\'). EFI Shell adds one.
    224   if (*FileName == '\\') {
    225     FileName++;
    226   }
    227 
    228   RemoveBlock.FileName    = FileName;
    229   RemoveBlock.NameLength  = AsciiStrLen(FileName);
    230 
    231   Result = Semihost_SYS_REMOVE(&RemoveBlock);
    232 
    233   if (Result == 0) {
    234     return RETURN_SUCCESS;
    235   } else {
    236     return RETURN_ABORTED;
    237   }
    238 }
    239 
    240 /**
    241   Rename a specified file.
    242 
    243   @param[in]  FileName     Name of the file to rename.
    244   @param[in]  NewFileName  The new name of the file.
    245 
    246   @retval  RETURN_SUCCESS            File Renamed
    247   @retval  RETURN_INVALID_PARAMETER  Either the current or the new name is not specified
    248   @retval  RETURN_ABORTED            Rename failed
    249 
    250 **/
    251 RETURN_STATUS
    252 SemihostFileRename(
    253   IN  CHAR8  *FileName,
    254   IN  CHAR8  *NewFileName
    255   )
    256 {
    257   SEMIHOST_FILE_RENAME_BLOCK  RenameBlock;
    258   INT32                       Result;
    259 
    260   if ((FileName == NULL) || (NewFileName == NULL)) {
    261     return RETURN_INVALID_PARAMETER;
    262   }
    263 
    264   RenameBlock.FileName          = FileName;
    265   RenameBlock.FileNameLength    = AsciiStrLen (FileName);
    266   RenameBlock.NewFileName       = NewFileName;
    267   RenameBlock.NewFileNameLength = AsciiStrLen (NewFileName);
    268 
    269   Result = Semihost_SYS_RENAME (&RenameBlock);
    270 
    271   if (Result != 0) {
    272     return  RETURN_ABORTED;
    273   } else {
    274     return  RETURN_SUCCESS;
    275   }
    276 }
    277 
    278 CHAR8
    279 SemihostReadCharacter (
    280   VOID
    281   )
    282 {
    283   return Semihost_SYS_READC();
    284 }
    285 
    286 VOID
    287 SemihostWriteCharacter (
    288   IN CHAR8 Character
    289   )
    290 {
    291   Semihost_SYS_WRITEC(&Character);
    292 }
    293 
    294 VOID
    295 SemihostWriteString (
    296   IN CHAR8 *String
    297   )
    298 {
    299   Semihost_SYS_WRITE0(String);
    300 }
    301 
    302 UINT32
    303 SemihostSystem (
    304   IN CHAR8 *CommandLine
    305   )
    306 {
    307   SEMIHOST_SYSTEM_BLOCK SystemBlock;
    308 
    309   SystemBlock.CommandLine   = CommandLine;
    310   SystemBlock.CommandLength = AsciiStrLen(CommandLine);
    311 
    312   return Semihost_SYS_SYSTEM(&SystemBlock);
    313 }
    314