]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/SemihostLib/SemihostLib.c
ArmPkg/SemihostFs: Various fixes for the file system
[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
82325f95 6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15#include <Base.h>\r
16\r
17#include <Library/BaseLib.h>\r
18#include <Library/SemihostLib.h>\r
19\r
20#include "SemihostPrivate.h"\r
21\r
22BOOLEAN\r
23SemihostConnectionSupported (\r
24 VOID\r
25 )\r
26{\r
27 return SEMIHOST_SUPPORTED;\r
28}\r
29\r
30RETURN_STATUS\r
31SemihostFileOpen (\r
32 IN CHAR8 *FileName,\r
33 IN UINT32 Mode,\r
c63626b7 34 OUT UINTN *FileHandle\r
82325f95 35 )\r
36{\r
37 SEMIHOST_FILE_OPEN_BLOCK OpenBlock;\r
38 INT32 Result;\r
39\r
40 if (FileHandle == NULL) {\r
41 return RETURN_INVALID_PARAMETER;\r
42 }\r
43\r
8fa3caf2 44 // Remove any leading separator (e.g.: '\'). EFI Shell adds one.\r
45 if (*FileName == '\\') {\r
46 FileName++;\r
47 }\r
48\r
82325f95 49 OpenBlock.FileName = FileName;\r
50 OpenBlock.Mode = Mode;\r
51 OpenBlock.NameLength = AsciiStrLen(FileName);\r
52\r
53 Result = Semihost_SYS_OPEN(&OpenBlock);\r
54\r
55 if (Result == -1) {\r
56 return RETURN_NOT_FOUND;\r
57 } else {\r
58 *FileHandle = Result;\r
59 return RETURN_SUCCESS;\r
60 }\r
61}\r
62\r
63RETURN_STATUS\r
64SemihostFileSeek (\r
c63626b7 65 IN UINTN FileHandle,\r
66 IN UINTN Offset\r
82325f95 67 )\r
68{\r
69 SEMIHOST_FILE_SEEK_BLOCK SeekBlock;\r
70 INT32 Result;\r
71\r
72 SeekBlock.Handle = FileHandle;\r
73 SeekBlock.Location = Offset;\r
74\r
75 Result = Semihost_SYS_SEEK(&SeekBlock);\r
76\r
d276ac10
HL
77 // Semihosting does not behave as documented. It returns the offset on\r
78 // success.\r
79 if (Result < 0) {\r
82325f95 80 return RETURN_ABORTED;\r
d276ac10
HL
81 } else {\r
82 return RETURN_SUCCESS;\r
82325f95 83 }\r
84}\r
85\r
86RETURN_STATUS\r
87SemihostFileRead (\r
c63626b7 88 IN UINTN FileHandle,\r
89 IN OUT UINTN *Length,\r
82325f95 90 OUT VOID *Buffer\r
91 )\r
92{\r
93 SEMIHOST_FILE_READ_WRITE_BLOCK ReadBlock;\r
94 UINT32 Result;\r
95\r
96 if ((Length == NULL) || (Buffer == NULL)) {\r
97 return RETURN_INVALID_PARAMETER;\r
98 }\r
99\r
100 ReadBlock.Handle = FileHandle;\r
101 ReadBlock.Buffer = Buffer;\r
102 ReadBlock.Length = *Length;\r
103\r
104 Result = Semihost_SYS_READ(&ReadBlock);\r
105\r
d276ac10 106 if ((*Length != 0) && (Result == *Length)) {\r
82325f95 107 return RETURN_ABORTED;\r
108 } else {\r
109 *Length -= Result;\r
110 return RETURN_SUCCESS;\r
111 }\r
112}\r
113\r
114RETURN_STATUS\r
115SemihostFileWrite (\r
c63626b7 116 IN UINTN FileHandle,\r
117 IN OUT UINTN *Length,\r
82325f95 118 IN VOID *Buffer\r
119 )\r
120{\r
121 SEMIHOST_FILE_READ_WRITE_BLOCK WriteBlock;\r
122\r
123 if ((Length == NULL) || (Buffer == NULL)) {\r
124 return RETURN_INVALID_PARAMETER;\r
125 }\r
126\r
127 WriteBlock.Handle = FileHandle;\r
128 WriteBlock.Buffer = Buffer;\r
129 WriteBlock.Length = *Length;\r
130\r
131 *Length = Semihost_SYS_WRITE(&WriteBlock);\r
d276ac10
HL
132\r
133 if (*Length != 0)\r
134 return RETURN_ABORTED;\r
135 else\r
136 return RETURN_SUCCESS;\r
82325f95 137}\r
138\r
139RETURN_STATUS\r
140SemihostFileClose (\r
c63626b7 141 IN UINTN FileHandle\r
82325f95 142 )\r
143{\r
144 INT32 Result = Semihost_SYS_CLOSE(&FileHandle);\r
145\r
146 if (Result == -1) {\r
147 return RETURN_INVALID_PARAMETER;\r
148 } else {\r
149 return RETURN_SUCCESS;\r
150 }\r
151}\r
152\r
153RETURN_STATUS\r
154SemihostFileLength (\r
c63626b7 155 IN UINTN FileHandle,\r
156 OUT UINTN *Length\r
82325f95 157 )\r
158{\r
159 INT32 Result;\r
160\r
161 if (Length == NULL) {\r
162 return RETURN_INVALID_PARAMETER;\r
163 }\r
164\r
165 Result = Semihost_SYS_FLEN(&FileHandle);\r
166\r
167 if (Result == -1) {\r
168 return RETURN_ABORTED;\r
169 } else {\r
170 *Length = Result;\r
171 return RETURN_SUCCESS;\r
172 }\r
173}\r
174\r
175RETURN_STATUS\r
176SemihostFileRemove (\r
177 IN CHAR8 *FileName\r
178 )\r
179{\r
180 SEMIHOST_FILE_REMOVE_BLOCK RemoveBlock;\r
181 UINT32 Result;\r
182\r
d276ac10
HL
183 // Remove any leading separator (e.g.: '\'). EFI Shell adds one.\r
184 if (*FileName == '\\') {\r
185 FileName++;\r
186 }\r
187\r
82325f95 188 RemoveBlock.FileName = FileName;\r
189 RemoveBlock.NameLength = AsciiStrLen(FileName);\r
190\r
191 Result = Semihost_SYS_REMOVE(&RemoveBlock);\r
192\r
193 if (Result == 0) {\r
194 return RETURN_SUCCESS;\r
195 } else {\r
196 return RETURN_ABORTED;\r
197 }\r
198}\r
199\r
200CHAR8\r
201SemihostReadCharacter (\r
202 VOID\r
203 )\r
204{\r
205 return Semihost_SYS_READC();\r
206}\r
207\r
208VOID\r
209SemihostWriteCharacter (\r
210 IN CHAR8 Character\r
211 )\r
212{\r
213 Semihost_SYS_WRITEC(&Character);\r
214}\r
215\r
216VOID\r
217SemihostWriteString (\r
218 IN CHAR8 *String\r
219 )\r
220{\r
221 Semihost_SYS_WRITE0(String);\r
222}\r
223 \r
224UINT32\r
225SemihostSystem (\r
226 IN CHAR8 *CommandLine\r
227 )\r
228{\r
229 SEMIHOST_SYSTEM_BLOCK SystemBlock;\r
230\r
231 SystemBlock.CommandLine = CommandLine;\r
232 SystemBlock.CommandLength = AsciiStrLen(CommandLine);\r
233\r
234 return Semihost_SYS_SYSTEM(&SystemBlock);\r
235}\r