]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/SemihostLib/SemihostLib.c
MdeModulePkg/MdeModulePkg.dsc: add MM_STANDALONE FTW and variable modules
[mirror_edk2.git] / ArmPkg / Library / SemihostLib / SemihostLib.c
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 }