blob: 3355e2ed6432587765bd7a4a699c0413d9696838 [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
175int RETARGET(_tmpnam)(char *name, int sig, unsigned maxlen) {
176 (void)name;
177 (void)sig;
178 (void)maxlen;
179
180 return 1;
181}
182
183char *RETARGET(_command_string)(char *cmd, int len) {
184 (void)len;
185
186 return cmd;
187}
188
189void RETARGET(_exit)(int return_code) {
190 char exit_code_buffer[64] = {0};
191 const char *p = exit_code_buffer;
192
193 /* Print out the exit code on the uart so any reader know how we exit. */
194 /* By appending 0x04, ASCII for end-of-transmission the FVP model exits,
195 * if the configuration parameter shutdown_on_eot on the uart is enabled.
196 * For some versions of FVP, the shutdown_on_eot is broken, but the same
197 * behaviour can be created by passing specifying a shutdown_tag= for the
198 * uart when starting the model so that is added last as well.
199 */
200
201 snprintf(exit_code_buffer,
202 sizeof(exit_code_buffer),
203 "Application exit code: %d.\n" // Let the readers know how we exit
204 "\04\n" // end-of-transmission
205 "EXITTHESIM\n", // shutdown_tag
206 return_code);
207
208 while (*p != '\0') {
209 UartPutc(*p++);
210 }
211
212 while (1) {}
213}
214
215int system(const char *cmd) {
216 (void)cmd;
217
218 return 0;
219}
220
221time_t time(time_t *timer) {
222 time_t current;
223
224 current = 0; // To Do !! No RTC implemented
225
226 if (timer != NULL) {
227 *timer = current;
228 }
229
230 return current;
231}
232
233void _clock_init(void) {
234#if 0
235 // Example implementation based on SysTick
236 // For instance, use a counting var in a SysTick interrupt handler
237 // for clock() to use
238 SysTick->LOAD = (uint32_t) ((SystemCoreClock/100)-1UL);
239 NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
240 SysTick->VAL = 0UL;
241 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
242#endif
243}
244
245clock_t clock(void) {
246 return (clock_t)-1;
247}
248
249int remove(const char *arg) {
250 (void)arg;
251 return 0;
252}
253
254int rename(const char *oldn, const char *newn) {
255 (void)oldn;
256 (void)newn;
257 return 0;
258}
259
260int fputc(int ch, FILE *f) {
261 (void)(f);
262 return UartPutc(ch);
263}
264
265int fgetc(FILE *f) {
266 (void)f;
267 return UartPutc(UartGetc());
268}
269
270#ifndef ferror
271/* arm-none-eabi-gcc with newlib uses a define for ferror */
272int ferror(FILE *f) {
273 (void)f;
274 return EOF;
275}
276#endif