TianoCore EDK2 master
Loading...
Searching...
No Matches
SemihostLib.c
Go to the documentation of this file.
1
9#include <Base.h>
10
11#include <Library/BaseLib.h>
12#include <Library/SemihostLib.h>
13
14#include "SemihostPrivate.h"
15
16BOOLEAN
17SemihostConnectionSupported (
18 VOID
19 )
20{
21 return SEMIHOST_SUPPORTED;
22}
23
24RETURN_STATUS
25SemihostFileOpen (
26 IN CHAR8 *FileName,
27 IN UINT32 Mode,
28 OUT UINTN *FileHandle
29 )
30{
32 INT32 Result;
33
34 if (FileHandle == NULL) {
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
57RETURN_STATUS
58SemihostFileSeek (
59 IN UINTN FileHandle,
60 IN UINTN Offset
61 )
62{
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
80RETURN_STATUS
81SemihostFileRead (
82 IN UINTN FileHandle,
83 IN OUT UINTN *Length,
84 OUT VOID *Buffer
85 )
86{
88 UINT32 Result;
89
90 if ((Length == NULL) || (Buffer == NULL)) {
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
108RETURN_STATUS
109SemihostFileWrite (
110 IN UINTN FileHandle,
111 IN OUT UINTN *Length,
112 IN VOID *Buffer
113 )
114{
116
117 if ((Length == NULL) || (Buffer == NULL)) {
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
134RETURN_STATUS
135SemihostFileClose (
136 IN UINTN FileHandle
137 )
138{
139 if (SEMIHOST_SYS_CLOSE (&FileHandle) == -1) {
141 } else {
142 return RETURN_SUCCESS;
143 }
144}
145
146RETURN_STATUS
147SemihostFileLength (
148 IN UINTN FileHandle,
149 OUT UINTN *Length
150 )
151{
152 INT32 Result;
153
154 if (Length == NULL) {
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
181RETURN_STATUS
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) {
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
208RETURN_STATUS
209SemihostFileRemove (
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
244RETURN_STATUS
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)) {
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
271CHAR8
272SemihostReadCharacter (
273 VOID
274 )
275{
276 return SEMIHOST_SYS_READC ();
277}
278
279VOID
280SemihostWriteCharacter (
281 IN CHAR8 Character
282 )
283{
284 SEMIHOST_SYS_WRITEC (&Character);
285}
286
287VOID
288SemihostWriteString (
289 IN CHAR8 *String
290 )
291{
292 SEMIHOST_SYS_WRITE0 (String);
293}
294
295UINT32
296SemihostSystem (
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}
UINT64 UINTN
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
#define NULL
Definition: Base.h:319
#define RETURN_ABORTED
Definition: Base.h:1177
#define RETURN_NOT_FOUND
Definition: Base.h:1142
#define RETURN_SUCCESS
Definition: Base.h:1066
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
RETURN_STATUS SemihostFileTmpName(OUT VOID *Buffer, IN UINT8 Identifier, IN UINTN Length)
Definition: SemihostLib.c:182
RETURN_STATUS SemihostFileRename(IN CHAR8 *FileName, IN CHAR8 *NewFileName)
Definition: SemihostLib.c:245