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