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