SemihostLib.c revision d276ac10f184aea06b5b484c8eeef88c5d6df881
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 22BOOLEAN 23SemihostConnectionSupported ( 24 VOID 25 ) 26{ 27 return SEMIHOST_SUPPORTED; 28} 29 30RETURN_STATUS 31SemihostFileOpen ( 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 63RETURN_STATUS 64SemihostFileSeek ( 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 86RETURN_STATUS 87SemihostFileRead ( 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 114RETURN_STATUS 115SemihostFileWrite ( 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 139RETURN_STATUS 140SemihostFileClose ( 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 153RETURN_STATUS 154SemihostFileLength ( 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 175RETURN_STATUS 176SemihostFileRemove ( 177 IN CHAR8 *FileName 178 ) 179{ 180 SEMIHOST_FILE_REMOVE_BLOCK RemoveBlock; 181 UINT32 Result; 182 183 // Remove any leading separator (e.g.: '\'). EFI Shell adds one. 184 if (*FileName == '\\') { 185 FileName++; 186 } 187 188 RemoveBlock.FileName = FileName; 189 RemoveBlock.NameLength = AsciiStrLen(FileName); 190 191 Result = Semihost_SYS_REMOVE(&RemoveBlock); 192 193 if (Result == 0) { 194 return RETURN_SUCCESS; 195 } else { 196 return RETURN_ABORTED; 197 } 198} 199 200CHAR8 201SemihostReadCharacter ( 202 VOID 203 ) 204{ 205 return Semihost_SYS_READC(); 206} 207 208VOID 209SemihostWriteCharacter ( 210 IN CHAR8 Character 211 ) 212{ 213 Semihost_SYS_WRITEC(&Character); 214} 215 216VOID 217SemihostWriteString ( 218 IN CHAR8 *String 219 ) 220{ 221 Semihost_SYS_WRITE0(String); 222} 223 224UINT32 225SemihostSystem ( 226 IN CHAR8 *CommandLine 227 ) 228{ 229 SEMIHOST_SYSTEM_BLOCK SystemBlock; 230 231 SystemBlock.CommandLine = CommandLine; 232 SystemBlock.CommandLength = AsciiStrLen(CommandLine); 233 234 return Semihost_SYS_SYSTEM(&SystemBlock); 235} 236