blob: 760273d54d75ba662d90dbc596a90edd6a8f976b [file] [log] [blame]
Kristofer Jonsson93175812022-04-21 19:27:11 +02001/*
2 * Copyright (c) 2019-2022 Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
Ledion Daja213f3ce2022-12-12 14:02:40 +010022#if !defined(__ARMCC_VERSION)
23#include <sys/stat.h>
24#endif
Kristofer Jonsson93175812022-04-21 19:27:11 +020025#include <time.h>
26
27#include "uart_stdout.h"
28
29// armclang retargeting
30#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
31#include <rt_misc.h>
32#include <rt_sys.h>
33
34/* Standard IO device handles. */
35#define STDIN 0x8001
36#define STDOUT 0x8002
37#define STDERR 0x8003
38
39#define RETARGET(fun) _sys##fun
40#define IO_OUTPUT(len) 0
41
42#else
43/*
44 * This type is used by the _ I/O functions to denote an open
45 * file.
46 */
47typedef int FILEHANDLE;
48
49/*
50 * Open a file. May return -1 if the file failed to open.
51 */
52extern FILEHANDLE _open(const char * /*name*/, int /*openmode*/);
53
54/* Standard IO device handles. */
55#define STDIN 0x00
56#define STDOUT 0x01
57#define STDERR 0x02
58
59#define RETARGET(fun) fun
60#define IO_OUTPUT(len) len
61
62#endif
63
64/* Standard IO device name defines. */
65const char __stdin_name[] __attribute__((aligned(4))) = "STDIN";
66const char __stdout_name[] __attribute__((aligned(4))) = "STDOUT";
67const char __stderr_name[] __attribute__((aligned(4))) = "STDERR";
68
69void _ttywrch(int ch) {
70 (void)fputc(ch, stdout);
71}
72
73FILEHANDLE RETARGET(_open)(const char *name, int openmode) {
74 (void)openmode;
75
76 if (strcmp(name, __stdin_name) == 0) {
77 return (STDIN);
78 }
79
80 if (strcmp(name, __stdout_name) == 0) {
81 return (STDOUT);
82 }
83
84 if (strcmp(name, __stderr_name) == 0) {
85 return (STDERR);
86 }
87
88 return -1;
89}
90
91int RETARGET(_write)(FILEHANDLE fh, const unsigned char *buf, unsigned int len, int mode) {
92 (void)mode;
93
94 switch (fh) {
95 case STDOUT:
96 case STDERR: {
97 int c;
98 unsigned int i;
99
100 for (i = 0; i < len; i++) {
101 c = fputc(buf[i], stdout);
102 if (c == EOF) {
103 return EOF;
104 }
105 }
106
107 return IO_OUTPUT(len);
108 }
109 default:
110 return EOF;
111 }
112}
113
114int RETARGET(_read)(FILEHANDLE fh, unsigned char *buf, unsigned int len, int mode) {
115 (void)mode;
116
117 switch (fh) {
118 case STDIN: {
119 int c;
120 unsigned int i;
121
122 for (i = 0; i < len; i++) {
123 c = fgetc(stdin);
124 if (c == EOF) {
125 return EOF;
126 }
127
128 buf[i] = (unsigned char)c;
129 }
130
131 return IO_OUTPUT(len);
132 }
133 default:
134 return EOF;
135 }
136}
137
138int RETARGET(_istty)(FILEHANDLE fh) {
139 switch (fh) {
140 case STDIN:
141 case STDOUT:
142 case STDERR:
143 return 1;
144 default:
145 return 0;
146 }
147}
148
149int RETARGET(_close)(FILEHANDLE fh) {
150 if (RETARGET(_istty(fh))) {
151 return 0;
152 }
153
154 return -1;
155}
156
157int RETARGET(_seek)(FILEHANDLE fh, long pos) {
158 (void)fh;
159 (void)pos;
160
161 return -1;
162}
163
164int RETARGET(_ensure)(FILEHANDLE fh) {
165 (void)fh;
166
167 return -1;
168}
169
170long RETARGET(_flen)(FILEHANDLE fh) {
171 if (RETARGET(_istty)(fh)) {
172 return 0;
173 }
174
175 return -1;
176}
177
Jonny Svärd76a45dd2022-10-24 17:40:19 +0200178#if __ARMCLIB_VERSION >= 6190004
179int RETARGET(_tmpnam2)(char *name, int sig, unsigned maxlen) {
180 (void)name;
181 (void)sig;
182 (void)maxlen;
183
184 return -1;
185}
186#else
Kristofer Jonsson93175812022-04-21 19:27:11 +0200187int RETARGET(_tmpnam)(char *name, int sig, unsigned maxlen) {
188 (void)name;
189 (void)sig;
190 (void)maxlen;
191
192 return 1;
193}
Jonny Svärd76a45dd2022-10-24 17:40:19 +0200194#endif
Kristofer Jonsson93175812022-04-21 19:27:11 +0200195
196char *RETARGET(_command_string)(char *cmd, int len) {
197 (void)len;
198
199 return cmd;
200}
201
202void RETARGET(_exit)(int return_code) {
203 char exit_code_buffer[64] = {0};
204 const char *p = exit_code_buffer;
205
206 /* Print out the exit code on the uart so any reader know how we exit. */
207 /* By appending 0x04, ASCII for end-of-transmission the FVP model exits,
208 * if the configuration parameter shutdown_on_eot on the uart is enabled.
209 * For some versions of FVP, the shutdown_on_eot is broken, but the same
210 * behaviour can be created by passing specifying a shutdown_tag= for the
211 * uart when starting the model so that is added last as well.
212 */
213
214 snprintf(exit_code_buffer,
215 sizeof(exit_code_buffer),
216 "Application exit code: %d.\n" // Let the readers know how we exit
217 "\04\n" // end-of-transmission
218 "EXITTHESIM\n", // shutdown_tag
219 return_code);
220
221 while (*p != '\0') {
222 UartPutc(*p++);
223 }
224
225 while (1) {}
226}
227
Ledion Daja213f3ce2022-12-12 14:02:40 +0100228#if !defined(__ARMCC_VERSION)
229int RETARGET(_fstat)(FILEHANDLE fh, struct stat *st) {
230 (void)fh;
231 (void)st;
232
233 return -1;
234}
235
236int RETARGET(_getpid)(void) {
237 return -1;
238}
239
240int RETARGET(_isatty)(FILEHANDLE fh) {
241 (void)fh;
242
243 return 0;
244}
245
246int RETARGET(_kill)(int pid, int sig) {
247 (void)pid;
248 (void)sig;
249
250 return -1;
251}
252
253int RETARGET(_lseek)(FILEHANDLE fh, int ptr, int dir) {
254 (void)fh;
255 (void)ptr;
256 (void)dir;
257
258 return -1;
259}
260#endif
261
Kristofer Jonsson93175812022-04-21 19:27:11 +0200262int system(const char *cmd) {
263 (void)cmd;
264
265 return 0;
266}
267
268time_t time(time_t *timer) {
269 time_t current;
270
271 current = 0; // To Do !! No RTC implemented
272
273 if (timer != NULL) {
274 *timer = current;
275 }
276
277 return current;
278}
279
280void _clock_init(void) {
281#if 0
282 // Example implementation based on SysTick
283 // For instance, use a counting var in a SysTick interrupt handler
284 // for clock() to use
285 SysTick->LOAD = (uint32_t) ((SystemCoreClock/100)-1UL);
286 NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
287 SysTick->VAL = 0UL;
288 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
289#endif
290}
291
292clock_t clock(void) {
293 return (clock_t)-1;
294}
295
296int remove(const char *arg) {
297 (void)arg;
298 return 0;
299}
300
301int rename(const char *oldn, const char *newn) {
302 (void)oldn;
303 (void)newn;
304 return 0;
305}
306
307int fputc(int ch, FILE *f) {
308 (void)(f);
309 return UartPutc(ch);
310}
311
312int fgetc(FILE *f) {
313 (void)f;
314 return UartPutc(UartGetc());
315}
316
317#ifndef ferror
318/* arm-none-eabi-gcc with newlib uses a define for ferror */
319int ferror(FILE *f) {
320 (void)f;
321 return EOF;
322}
323#endif