]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/SemihostLib/SemihostLib.c
UefiCpuPkg: Change complex DEBUG_CODE() to DEBUG_CODE_BEGIN/END()
[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
58bba221 4 Copyright (c) 2013 - 2021, Arm Limited. All rights reserved.<BR>\r
d276ac10 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
b9d49769 47 Result = SEMIHOST_SYS_OPEN (&OpenBlock);\r
82325f95 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
b9d49769 69 Result = SEMIHOST_SYS_SEEK (&SeekBlock);\r
82325f95 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
b9d49769 98 Result = SEMIHOST_SYS_READ (&ReadBlock);\r
82325f95 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
b9d49769 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
b9d49769 138 if (SEMIHOST_SYS_CLOSE (&FileHandle) == -1) {\r
82325f95 139 return RETURN_INVALID_PARAMETER;\r
140 } else {\r
141 return RETURN_SUCCESS;\r
142 }\r
143}\r
144\r
145RETURN_STATUS\r
146SemihostFileLength (\r
c63626b7 147 IN UINTN FileHandle,\r
148 OUT UINTN *Length\r
82325f95 149 )\r
150{\r
151 INT32 Result;\r
152\r
153 if (Length == NULL) {\r
154 return RETURN_INVALID_PARAMETER;\r
155 }\r
156\r
b9d49769 157 Result = SEMIHOST_SYS_FLEN (&FileHandle);\r
82325f95 158\r
159 if (Result == -1) {\r
160 return RETURN_ABORTED;\r
161 } else {\r
162 *Length = Result;\r
163 return RETURN_SUCCESS;\r
164 }\r
165}\r
166\r
5521b5cc
RC
167/**\r
168 Get a temporary name for a file from the host running the debug agent.\r
169\r
170 @param[out] Buffer Pointer to the buffer where the temporary name has to\r
171 be stored\r
172 @param[in] Identifier File name identifier (integer in the range 0 to 255)\r
173 @param[in] Length Length of the buffer to store the temporary name\r
174\r
175 @retval RETURN_SUCCESS Temporary name returned\r
176 @retval RETURN_INVALID_PARAMETER Invalid buffer address\r
177 @retval RETURN_ABORTED Temporary name not returned\r
178\r
179**/\r
180RETURN_STATUS\r
181SemihostFileTmpName(\r
182 OUT VOID *Buffer,\r
183 IN UINT8 Identifier,\r
184 IN UINTN Length\r
185 )\r
186{\r
187 SEMIHOST_FILE_TMPNAME_BLOCK TmpNameBlock;\r
188 INT32 Result;\r
189\r
190 if (Buffer == NULL) {\r
191 return RETURN_INVALID_PARAMETER;\r
192 }\r
193\r
194 TmpNameBlock.Buffer = Buffer;\r
195 TmpNameBlock.Identifier = Identifier;\r
196 TmpNameBlock.Length = Length;\r
197\r
b9d49769 198 Result = SEMIHOST_SYS_TMPNAME (&TmpNameBlock);\r
5521b5cc
RC
199\r
200 if (Result != 0) {\r
201 return RETURN_ABORTED;\r
202 } else {\r
203 return RETURN_SUCCESS;\r
204 }\r
205}\r
206\r
82325f95 207RETURN_STATUS\r
208SemihostFileRemove (\r
209 IN CHAR8 *FileName\r
210 )\r
211{\r
212 SEMIHOST_FILE_REMOVE_BLOCK RemoveBlock;\r
213 UINT32 Result;\r
214\r
d276ac10
HL
215 // Remove any leading separator (e.g.: '\'). EFI Shell adds one.\r
216 if (*FileName == '\\') {\r
217 FileName++;\r
218 }\r
219\r
82325f95 220 RemoveBlock.FileName = FileName;\r
221 RemoveBlock.NameLength = AsciiStrLen(FileName);\r
222\r
b9d49769 223 Result = SEMIHOST_SYS_REMOVE (&RemoveBlock);\r
82325f95 224\r
225 if (Result == 0) {\r
226 return RETURN_SUCCESS;\r
227 } else {\r
228 return RETURN_ABORTED;\r
229 }\r
230}\r
231\r
5521b5cc
RC
232/**\r
233 Rename a specified file.\r
234\r
235 @param[in] FileName Name of the file to rename.\r
236 @param[in] NewFileName The new name of the file.\r
237\r
238 @retval RETURN_SUCCESS File Renamed\r
239 @retval RETURN_INVALID_PARAMETER Either the current or the new name is not specified\r
240 @retval RETURN_ABORTED Rename failed\r
241\r
242**/\r
243RETURN_STATUS\r
244SemihostFileRename(\r
245 IN CHAR8 *FileName,\r
246 IN CHAR8 *NewFileName\r
247 )\r
248{\r
249 SEMIHOST_FILE_RENAME_BLOCK RenameBlock;\r
250 INT32 Result;\r
251\r
252 if ((FileName == NULL) || (NewFileName == NULL)) {\r
253 return RETURN_INVALID_PARAMETER;\r
254 }\r
255\r
256 RenameBlock.FileName = FileName;\r
257 RenameBlock.FileNameLength = AsciiStrLen (FileName);\r
258 RenameBlock.NewFileName = NewFileName;\r
259 RenameBlock.NewFileNameLength = AsciiStrLen (NewFileName);\r
260\r
b9d49769 261 Result = SEMIHOST_SYS_RENAME (&RenameBlock);\r
5521b5cc
RC
262\r
263 if (Result != 0) {\r
264 return RETURN_ABORTED;\r
265 } else {\r
266 return RETURN_SUCCESS;\r
267 }\r
268}\r
269\r
82325f95 270CHAR8\r
271SemihostReadCharacter (\r
272 VOID\r
273 )\r
274{\r
b9d49769 275 return SEMIHOST_SYS_READC ();\r
82325f95 276}\r
277\r
278VOID\r
279SemihostWriteCharacter (\r
280 IN CHAR8 Character\r
281 )\r
282{\r
b9d49769 283 SEMIHOST_SYS_WRITEC (&Character);\r
82325f95 284}\r
285\r
286VOID\r
287SemihostWriteString (\r
288 IN CHAR8 *String\r
289 )\r
290{\r
b9d49769 291 SEMIHOST_SYS_WRITE0 (String);\r
82325f95 292}\r
3402aac7 293\r
82325f95 294UINT32\r
295SemihostSystem (\r
296 IN CHAR8 *CommandLine\r
297 )\r
298{\r
299 SEMIHOST_SYSTEM_BLOCK SystemBlock;\r
300\r
301 SystemBlock.CommandLine = CommandLine;\r
302 SystemBlock.CommandLength = AsciiStrLen(CommandLine);\r
303\r
b9d49769 304 return SEMIHOST_SYS_SYSTEM (&SystemBlock);\r
82325f95 305}\r