blob: 7c53ba140fa269a716a80ebada88ec83c6f78c77 [file] [log] [blame]
Kristofer Jonsson74226102022-05-25 16:55:24 +02001/*
2 * Copyright (c) 2019-2022 Arm Limited.
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>
22#include <time.h>
23
24#include "uart_stdout.h"
25
26// armclang retargeting
27#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
28#include <rt_misc.h>
29#include <rt_sys.h>
30
31/* Standard IO device handles. */
32#define STDIN 0x8001
33#define STDOUT 0x8002
34#define STDERR 0x8003
35
36#define RETARGET(fun) _sys##fun
37#define IO_OUTPUT(len) 0
38
39#else
40/*
41 * This type is used by the _ I/O functions to denote an open
42 * file.
43 */
44typedef int FILEHANDLE;
45
46/*
47 * Open a file. May return -1 if the file failed to open.
48 */
49extern FILEHANDLE _open(const char * /*name*/, int /*openmode*/);
50
51/* Standard IO device handles. */
52#define STDIN 0x00
53#define STDOUT 0x01
54#define STDERR 0x02
55
56#define RETARGET(fun) fun
57#define IO_OUTPUT(len) len
58
59#endif
60
61/* Standard IO device name defines. */
62const char __stdin_name[] __attribute__((aligned(4))) = "STDIN";
63const char __stdout_name[] __attribute__((aligned(4))) = "STDOUT";
64const char __stderr_name[] __attribute__((aligned(4))) = "STDERR";
65
66void _ttywrch(int ch) {
67 (void)fputc(ch, stdout);
68}
69
70FILEHANDLE RETARGET(_open)(const char *name, int openmode) {
71 (void)openmode;
72
73 if (strcmp(name, __stdin_name) == 0) {
74 return (STDIN);
75 }
76
77 if (strcmp(name, __stdout_name) == 0) {
78 return (STDOUT);
79 }
80
81 if (strcmp(name, __stderr_name) == 0) {
82 return (STDERR);
83 }
84
85 return -1;
86}
87
88int RETARGET(_write)(FILEHANDLE fh, const unsigned char *buf, unsigned int len, int mode) {
89 (void)mode;
90
91 switch (fh) {
92 case STDOUT:
93 case STDERR: {
94 int c;
95 unsigned int i;
96
97 for (i = 0; i < len; i++) {
98 c = fputc(buf[i], stdout);
99 if (c == EOF) {
100 return EOF;
101 }
102 }
103
104 return IO_OUTPUT(len);
105 }
106 default:
107 return EOF;
108 }
109}
110
111int RETARGET(_read)(FILEHANDLE fh, unsigned char *buf, unsigned int len, int mode) {
112 (void)mode;
113
114 switch (fh) {
115 case STDIN: {
116 int c;
117 unsigned int i;
118
119 for (i = 0; i < len; i++) {
120 c = fgetc(stdin);
121 if (c == EOF) {
122 return EOF;
123 }
124
125 buf[i] = (unsigned char)c;
126 }
127
128 return IO_OUTPUT(len);
129 }
130 default:
131 return EOF;
132 }
133}
134
135int RETARGET(_istty)(FILEHANDLE fh) {
136 switch (fh) {
137 case STDIN:
138 case STDOUT:
139 case STDERR:
140 return 1;
141 default:
142 return 0;
143 }
144}
145
146int RETARGET(_close)(FILEHANDLE fh) {
147 if (RETARGET(_istty(fh))) {
148 return 0;
149 }
150
151 return -1;
152}
153
154int RETARGET(_seek)(FILEHANDLE fh, long pos) {
155 (void)fh;
156 (void)pos;
157
158 return -1;
159}
160
161int RETARGET(_ensure)(FILEHANDLE fh) {
162 (void)fh;
163
164 return -1;
165}
166
167long RETARGET(_flen)(FILEHANDLE fh) {
168 if (RETARGET(_istty)(fh)) {
169 return 0;
170 }
171
172 return -1;
173}
174
Jonny Svärd76a45dd2022-10-24 17:40:19 +0200175#if __ARMCLIB_VERSION >= 6190004
176int RETARGET(_tmpnam2)(char *name, int sig, unsigned maxlen) {
177 (void)name;
178 (void)sig;
179 (void)maxlen;
180
181 return -1;
182}
183#else
Kristofer Jonsson74226102022-05-25 16:55:24 +0200184int RETARGET(_tmpnam)(char *name, int sig, unsigned maxlen) {
185 (void)name;
186 (void)sig;
187 (void)maxlen;
188
189 return 1;
190}
Jonny Svärd76a45dd2022-10-24 17:40:19 +0200191#endif
Kristofer Jonsson74226102022-05-25 16:55:24 +0200192
193char *RETARGET(_command_string)(char *cmd, int len) {
194 (void)len;
195
196 return cmd;
197}
198
199void RETARGET(_exit)(int return_code) {
200 char exit_code_buffer[64] = {0};
201 const char *p = exit_code_buffer;
202
203 /* Print out the exit code on the uart so any reader know how we exit. */
204 /* By appending 0x04, ASCII for end-of-transmission the FVP model exits,
205 * if the configuration parameter shutdown_on_eot on the uart is enabled.
206 * For some versions of FVP, the shutdown_on_eot is broken, but the same
207 * behaviour can be created by passing specifying a shutdown_tag= for the
208 * uart when starting the model so that is added last as well.
209 */
210
211 snprintf(exit_code_buffer,
212 sizeof(exit_code_buffer),
213 "Application exit code: %d.\n" // Let the readers know how we exit
214 "\04\n" // end-of-transmission
215 "EXITTHESIM\n", // shutdown_tag
216 return_code);
217
218 while (*p != '\0') {
219 UartPutc(*p++);
220 }
221
222 while (1) {}
223}
224
225int system(const char *cmd) {
226 (void)cmd;
227
228 return 0;
229}
230
231time_t time(time_t *timer) {
232 time_t current;
233
234 current = 0; // To Do !! No RTC implemented
235
236 if (timer != NULL) {
237 *timer = current;
238 }
239
240 return current;
241}
242
243void _clock_init(void) {
244#if 0
245 // Example implementation based on SysTick
246 // For instance, use a counting var in a SysTick interrupt handler
247 // for clock() to use
248 SysTick->LOAD = (uint32_t) ((SystemCoreClock/100)-1UL);
249 NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
250 SysTick->VAL = 0UL;
251 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
252#endif
253}
254
255clock_t clock(void) {
256 return (clock_t)-1;
257}
258
259int remove(const char *arg) {
260 (void)arg;
261 return 0;
262}
263
264int rename(const char *oldn, const char *newn) {
265 (void)oldn;
266 (void)newn;
267 return 0;
268}
269
270int fputc(int ch, FILE *f) {
271 (void)(f);
272 return UartPutc(ch);
273}
274
275int fgetc(FILE *f) {
276 (void)f;
277 return UartPutc(UartGetc());
278}
279
280#ifndef ferror
281/* arm-none-eabi-gcc with newlib uses a define for ferror */
282int ferror(FILE *f) {
283 (void)f;
284 return EOF;
285}
286#endif