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