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