Blame view

common/console.c 17.1 KB
47d1a6e1e   wdenk   Initial revision
1
2
3
4
  /*
   * (C) Copyright 2000
   * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
47d1a6e1e   wdenk   Initial revision
6
7
8
9
10
   */
  
  #include <common.h>
  #include <stdarg.h>
  #include <malloc.h>
91b136c79   Simon Glass   sandbox: Allow th...
11
  #include <os.h>
849d5d9cd   Joe Hershberger   env: Add a consol...
12
  #include <serial.h>
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
13
  #include <stdio_dev.h>
27b207fd0   wdenk   * Implement new m...
14
  #include <exports.h>
849d5d9cd   Joe Hershberger   env: Add a consol...
15
  #include <environment.h>
47d1a6e1e   wdenk   Initial revision
16

d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
17
  DECLARE_GLOBAL_DATA_PTR;
849d5d9cd   Joe Hershberger   env: Add a consol...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  static int on_console(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	int console = -1;
  
  	/* Check for console redirection */
  	if (strcmp(name, "stdin") == 0)
  		console = stdin;
  	else if (strcmp(name, "stdout") == 0)
  		console = stdout;
  	else if (strcmp(name, "stderr") == 0)
  		console = stderr;
  
  	/* if not actually setting a console variable, we don't care */
  	if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
  		return 0;
  
  	switch (op) {
  	case env_op_create:
  	case env_op_overwrite:
  
  #ifdef CONFIG_CONSOLE_MUX
  		if (iomux_doenv(console, value))
  			return 1;
  #else
  		/* Try assigning specified device */
  		if (console_assign(console, value) < 0)
  			return 1;
  #endif /* CONFIG_CONSOLE_MUX */
  		return 0;
  
  	case env_op_delete:
  		if ((flags & H_FORCE) == 0)
  			printf("Can't delete \"%s\"
  ", name);
  		return 1;
  
  	default:
  		return 0;
  	}
  }
  U_BOOT_ENV_CALLBACK(console, on_console);
e080d545f   Joe Hershberger   env: Add a silent...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  #ifdef CONFIG_SILENT_CONSOLE
  static int on_silent(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  #ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_SET
  	if (flags & H_INTERACTIVE)
  		return 0;
  #endif
  #ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC
  	if ((flags & H_INTERACTIVE) == 0)
  		return 0;
  #endif
  
  	if (value != NULL)
  		gd->flags |= GD_FLG_SILENT;
  	else
  		gd->flags &= ~GD_FLG_SILENT;
  
  	return 0;
  }
  U_BOOT_ENV_CALLBACK(silent, on_silent);
  #endif
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
82
  #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
47d1a6e1e   wdenk   Initial revision
83
84
85
86
87
  /*
   * if overwrite_console returns 1, the stdin, stderr and stdout
   * are switched to the serial port, else the settings in the
   * environment are used
   */
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
88
  #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
89
90
  extern int overwrite_console(void);
  #define OVERWRITE_CONSOLE overwrite_console()
47d1a6e1e   wdenk   Initial revision
91
  #else
83e40ba75   wdenk   * Patch by Detlev...
92
  #define OVERWRITE_CONSOLE 0
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
93
  #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
47d1a6e1e   wdenk   Initial revision
94

6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
95
  #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
47d1a6e1e   wdenk   Initial revision
96

52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
97
  static int console_setfile(int file, struct stdio_dev * dev)
47d1a6e1e   wdenk   Initial revision
98
99
100
101
102
103
104
105
106
107
108
109
  {
  	int error = 0;
  
  	if (dev == NULL)
  		return -1;
  
  	switch (file) {
  	case stdin:
  	case stdout:
  	case stderr:
  		/* Start new device */
  		if (dev->start) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
110
  			error = dev->start();
47d1a6e1e   wdenk   Initial revision
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  			/* If it's not started dont use it */
  			if (error < 0)
  				break;
  		}
  
  		/* Assign the new device (leaving the existing one started) */
  		stdio_devices[file] = dev;
  
  		/*
  		 * Update monitor functions
  		 * (to use the console stuff by other applications)
  		 */
  		switch (file) {
  		case stdin:
27b207fd0   wdenk   * Implement new m...
125
126
  			gd->jt[XF_getc] = dev->getc;
  			gd->jt[XF_tstc] = dev->tstc;
47d1a6e1e   wdenk   Initial revision
127
128
  			break;
  		case stdout:
27b207fd0   wdenk   * Implement new m...
129
130
131
  			gd->jt[XF_putc] = dev->putc;
  			gd->jt[XF_puts] = dev->puts;
  			gd->jt[XF_printf] = printf;
47d1a6e1e   wdenk   Initial revision
132
133
134
135
136
137
138
139
140
  			break;
  		}
  		break;
  
  	default:		/* Invalid file ID */
  		error = -1;
  	}
  	return error;
  }
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
141
142
  #if defined(CONFIG_CONSOLE_MUX)
  /** Console I/O multiplexing *******************************************/
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
143
144
  static struct stdio_dev *tstcdev;
  struct stdio_dev **console_devices[MAX_FILES];
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
145
146
147
148
149
150
151
152
  int cd_count[MAX_FILES];
  
  /*
   * This depends on tstc() always being called before getc().
   * This is guaranteed to be true because this routine is called
   * only from fgetc() which assures it.
   * No attempt is made to demultiplex multiple input sources.
   */
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
153
  static int console_getc(int file)
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
154
155
156
157
158
159
160
161
  {
  	unsigned char ret;
  
  	/* This is never called with testcdev == NULL */
  	ret = tstcdev->getc();
  	tstcdev = NULL;
  	return ret;
  }
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
162
  static int console_tstc(int file)
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
163
164
  {
  	int i, ret;
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
165
  	struct stdio_dev *dev;
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  
  	disable_ctrlc(1);
  	for (i = 0; i < cd_count[file]; i++) {
  		dev = console_devices[file][i];
  		if (dev->tstc != NULL) {
  			ret = dev->tstc();
  			if (ret > 0) {
  				tstcdev = dev;
  				disable_ctrlc(0);
  				return ret;
  			}
  		}
  	}
  	disable_ctrlc(0);
  
  	return 0;
  }
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
183
  static void console_putc(int file, const char c)
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
184
185
  {
  	int i;
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
186
  	struct stdio_dev *dev;
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
187
188
189
190
191
192
193
  
  	for (i = 0; i < cd_count[file]; i++) {
  		dev = console_devices[file][i];
  		if (dev->putc != NULL)
  			dev->putc(c);
  	}
  }
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
194
  static void console_puts(int file, const char *s)
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
195
196
  {
  	int i;
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
197
  	struct stdio_dev *dev;
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
198
199
200
201
202
203
204
  
  	for (i = 0; i < cd_count[file]; i++) {
  		dev = console_devices[file][i];
  		if (dev->puts != NULL)
  			dev->puts(s);
  	}
  }
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
205
206
207
208
209
  
  static inline void console_printdevs(int file)
  {
  	iomux_printdevs(file);
  }
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
210
  static inline void console_doenv(int file, struct stdio_dev *dev)
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  {
  	iomux_doenv(file, dev->name);
  }
  #else
  static inline int console_getc(int file)
  {
  	return stdio_devices[file]->getc();
  }
  
  static inline int console_tstc(int file)
  {
  	return stdio_devices[file]->tstc();
  }
  
  static inline void console_putc(int file, const char c)
  {
  	stdio_devices[file]->putc(c);
  }
  
  static inline void console_puts(int file, const char *s)
  {
  	stdio_devices[file]->puts(s);
  }
  
  static inline void console_printdevs(int file)
  {
  	printf("%s
  ", stdio_devices[file]->name);
  }
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
240
  static inline void console_doenv(int file, struct stdio_dev *dev)
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
241
242
243
  {
  	console_setfile(file, dev);
  }
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
244
  #endif /* defined(CONFIG_CONSOLE_MUX) */
47d1a6e1e   wdenk   Initial revision
245
  /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
d9c27253c   Wolfgang Denk   Make *printf() re...
246
  int serial_printf(const char *fmt, ...)
47d1a6e1e   wdenk   Initial revision
247
248
249
  {
  	va_list args;
  	uint i;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
250
  	char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1e   wdenk   Initial revision
251

ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
252
  	va_start(args, fmt);
47d1a6e1e   wdenk   Initial revision
253
254
255
256
  
  	/* For this to work, printbuffer must be larger than
  	 * anything we ever want to print.
  	 */
068af6f84   Sonny Rao   Make printf and v...
257
  	i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
258
  	va_end(args);
47d1a6e1e   wdenk   Initial revision
259

ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
260
  	serial_puts(printbuffer);
d9c27253c   Wolfgang Denk   Make *printf() re...
261
  	return i;
47d1a6e1e   wdenk   Initial revision
262
  }
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
263
  int fgetc(int file)
47d1a6e1e   wdenk   Initial revision
264
  {
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
265
266
267
268
269
270
271
272
273
274
275
  	if (file < MAX_FILES) {
  #if defined(CONFIG_CONSOLE_MUX)
  		/*
  		 * Effectively poll for input wherever it may be available.
  		 */
  		for (;;) {
  			/*
  			 * Upper layer may have already called tstc() so
  			 * check for that first.
  			 */
  			if (tstcdev != NULL)
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
276
277
  				return console_getc(file);
  			console_tstc(file);
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
278
279
280
281
282
283
284
285
286
  #ifdef CONFIG_WATCHDOG
  			/*
  			 * If the watchdog must be rate-limited then it should
  			 * already be handled in board-specific code.
  			 */
  			 udelay(1);
  #endif
  		}
  #else
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
287
  		return console_getc(file);
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
288
289
  #endif
  	}
47d1a6e1e   wdenk   Initial revision
290
291
292
  
  	return -1;
  }
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
293
  int ftstc(int file)
47d1a6e1e   wdenk   Initial revision
294
295
  {
  	if (file < MAX_FILES)
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
296
  		return console_tstc(file);
47d1a6e1e   wdenk   Initial revision
297
298
299
  
  	return -1;
  }
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
300
  void fputc(int file, const char c)
47d1a6e1e   wdenk   Initial revision
301
302
  {
  	if (file < MAX_FILES)
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
303
  		console_putc(file, c);
47d1a6e1e   wdenk   Initial revision
304
  }
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
305
  void fputs(int file, const char *s)
47d1a6e1e   wdenk   Initial revision
306
307
  {
  	if (file < MAX_FILES)
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
308
  		console_puts(file, s);
47d1a6e1e   wdenk   Initial revision
309
  }
d9c27253c   Wolfgang Denk   Make *printf() re...
310
  int fprintf(int file, const char *fmt, ...)
47d1a6e1e   wdenk   Initial revision
311
312
313
  {
  	va_list args;
  	uint i;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
314
  	char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1e   wdenk   Initial revision
315

ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
316
  	va_start(args, fmt);
47d1a6e1e   wdenk   Initial revision
317
318
319
320
  
  	/* For this to work, printbuffer must be larger than
  	 * anything we ever want to print.
  	 */
068af6f84   Sonny Rao   Make printf and v...
321
  	i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
322
  	va_end(args);
47d1a6e1e   wdenk   Initial revision
323
324
  
  	/* Send to desired file */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
325
  	fputs(file, printbuffer);
d9c27253c   Wolfgang Denk   Make *printf() re...
326
  	return i;
47d1a6e1e   wdenk   Initial revision
327
328
329
  }
  
  /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
330
  int getc(void)
47d1a6e1e   wdenk   Initial revision
331
  {
f5c3ba797   Mark Jackson   Allow console inp...
332
333
334
335
  #ifdef CONFIG_DISABLE_CONSOLE
  	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  		return 0;
  #endif
e3e454cd7   Graeme Russ   console: Squelch ...
336
337
  	if (!gd->have_console)
  		return 0;
47d1a6e1e   wdenk   Initial revision
338
339
  	if (gd->flags & GD_FLG_DEVINIT) {
  		/* Get from the standard input */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
340
  		return fgetc(stdin);
47d1a6e1e   wdenk   Initial revision
341
342
343
  	}
  
  	/* Send directly to the handler */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
344
  	return serial_getc();
47d1a6e1e   wdenk   Initial revision
345
  }
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
346
  int tstc(void)
47d1a6e1e   wdenk   Initial revision
347
  {
f5c3ba797   Mark Jackson   Allow console inp...
348
349
350
351
  #ifdef CONFIG_DISABLE_CONSOLE
  	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  		return 0;
  #endif
e3e454cd7   Graeme Russ   console: Squelch ...
352
353
  	if (!gd->have_console)
  		return 0;
47d1a6e1e   wdenk   Initial revision
354
355
  	if (gd->flags & GD_FLG_DEVINIT) {
  		/* Test the standard input */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
356
  		return ftstc(stdin);
47d1a6e1e   wdenk   Initial revision
357
358
359
  	}
  
  	/* Send directly to the handler */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
360
  	return serial_tstc();
47d1a6e1e   wdenk   Initial revision
361
  }
3fa4977a9   Simon Glass   Revert "Add board...
362
  #ifdef CONFIG_PRE_CONSOLE_BUFFER
9558b48af   Graeme Russ   console: Implemen...
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
  #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
  
  static void pre_console_putc(const char c)
  {
  	char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
  
  	buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
  }
  
  static void pre_console_puts(const char *s)
  {
  	while (*s)
  		pre_console_putc(*s++);
  }
  
  static void print_pre_console_buffer(void)
  {
  	unsigned long i = 0;
  	char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
  
  	if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
  		i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
  
  	while (i < gd->precon_buf_idx)
  		putc(buffer[CIRC_BUF_IDX(i++)]);
  }
  #else
  static inline void pre_console_putc(const char c) {}
  static inline void pre_console_puts(const char *s) {}
  static inline void print_pre_console_buffer(void) {}
  #endif
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
394
  void putc(const char c)
47d1a6e1e   wdenk   Initial revision
395
  {
91b136c79   Simon Glass   sandbox: Allow th...
396
397
398
399
400
401
  #ifdef CONFIG_SANDBOX
  	if (!gd) {
  		os_putc(c);
  		return;
  	}
  #endif
a6cccaea5   wdenk   * Patch by Wolter...
402
403
  #ifdef CONFIG_SILENT_CONSOLE
  	if (gd->flags & GD_FLG_SILENT)
f6e20fc6c   wdenk   Patch by Anders L...
404
  		return;
a6cccaea5   wdenk   * Patch by Wolter...
405
  #endif
f5c3ba797   Mark Jackson   Allow console inp...
406
407
408
409
  #ifdef CONFIG_DISABLE_CONSOLE
  	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  		return;
  #endif
e3e454cd7   Graeme Russ   console: Squelch ...
410
  	if (!gd->have_console)
9558b48af   Graeme Russ   console: Implemen...
411
  		return pre_console_putc(c);
e3e454cd7   Graeme Russ   console: Squelch ...
412

47d1a6e1e   wdenk   Initial revision
413
414
  	if (gd->flags & GD_FLG_DEVINIT) {
  		/* Send to the standard output */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
415
  		fputc(stdout, c);
47d1a6e1e   wdenk   Initial revision
416
417
  	} else {
  		/* Send directly to the handler */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
418
  		serial_putc(c);
47d1a6e1e   wdenk   Initial revision
419
420
  	}
  }
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
421
  void puts(const char *s)
47d1a6e1e   wdenk   Initial revision
422
  {
91b136c79   Simon Glass   sandbox: Allow th...
423
424
425
426
427
428
  #ifdef CONFIG_SANDBOX
  	if (!gd) {
  		os_puts(s);
  		return;
  	}
  #endif
a6cccaea5   wdenk   * Patch by Wolter...
429
430
431
432
  #ifdef CONFIG_SILENT_CONSOLE
  	if (gd->flags & GD_FLG_SILENT)
  		return;
  #endif
f5c3ba797   Mark Jackson   Allow console inp...
433
434
435
436
  #ifdef CONFIG_DISABLE_CONSOLE
  	if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  		return;
  #endif
e3e454cd7   Graeme Russ   console: Squelch ...
437
  	if (!gd->have_console)
9558b48af   Graeme Russ   console: Implemen...
438
  		return pre_console_puts(s);
e3e454cd7   Graeme Russ   console: Squelch ...
439

47d1a6e1e   wdenk   Initial revision
440
441
  	if (gd->flags & GD_FLG_DEVINIT) {
  		/* Send to the standard output */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
442
  		fputs(stdout, s);
47d1a6e1e   wdenk   Initial revision
443
444
  	} else {
  		/* Send directly to the handler */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
445
  		serial_puts(s);
47d1a6e1e   wdenk   Initial revision
446
447
  	}
  }
d9c27253c   Wolfgang Denk   Make *printf() re...
448
  int printf(const char *fmt, ...)
47d1a6e1e   wdenk   Initial revision
449
450
451
  {
  	va_list args;
  	uint i;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
452
  	char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1e   wdenk   Initial revision
453

91b136c79   Simon Glass   sandbox: Allow th...
454
  #if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER)
e3e454cd7   Graeme Russ   console: Squelch ...
455
456
  	if (!gd->have_console)
  		return 0;
9558b48af   Graeme Russ   console: Implemen...
457
  #endif
e3e454cd7   Graeme Russ   console: Squelch ...
458

ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
459
  	va_start(args, fmt);
47d1a6e1e   wdenk   Initial revision
460
461
462
463
  
  	/* For this to work, printbuffer must be larger than
  	 * anything we ever want to print.
  	 */
068af6f84   Sonny Rao   Make printf and v...
464
  	i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
465
  	va_end(args);
47d1a6e1e   wdenk   Initial revision
466
467
  
  	/* Print the string */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
468
  	puts(printbuffer);
d9c27253c   Wolfgang Denk   Make *printf() re...
469
  	return i;
47d1a6e1e   wdenk   Initial revision
470
  }
d9c27253c   Wolfgang Denk   Make *printf() re...
471
  int vprintf(const char *fmt, va_list args)
6dd652fa4   wdenk   Patches by Murray...
472
473
  {
  	uint i;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
474
  	char printbuffer[CONFIG_SYS_PBSIZE];
6dd652fa4   wdenk   Patches by Murray...
475

9558b48af   Graeme Russ   console: Implemen...
476
  #ifndef CONFIG_PRE_CONSOLE_BUFFER
e3e454cd7   Graeme Russ   console: Squelch ...
477
478
  	if (!gd->have_console)
  		return 0;
9558b48af   Graeme Russ   console: Implemen...
479
  #endif
e3e454cd7   Graeme Russ   console: Squelch ...
480

6dd652fa4   wdenk   Patches by Murray...
481
482
483
  	/* For this to work, printbuffer must be larger than
  	 * anything we ever want to print.
  	 */
068af6f84   Sonny Rao   Make printf and v...
484
  	i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
6dd652fa4   wdenk   Patches by Murray...
485
486
  
  	/* Print the string */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
487
  	puts(printbuffer);
d9c27253c   Wolfgang Denk   Make *printf() re...
488
  	return i;
6dd652fa4   wdenk   Patches by Murray...
489
  }
47d1a6e1e   wdenk   Initial revision
490
491
492
  /* test if ctrl-c was pressed */
  static int ctrlc_disabled = 0;	/* see disable_ctrl() */
  static int ctrlc_was_pressed = 0;
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
493
  int ctrlc(void)
47d1a6e1e   wdenk   Initial revision
494
  {
47d1a6e1e   wdenk   Initial revision
495
  	if (!ctrlc_disabled && gd->have_console) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
496
497
  		if (tstc()) {
  			switch (getc()) {
47d1a6e1e   wdenk   Initial revision
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  			case 0x03:		/* ^C - Control C */
  				ctrlc_was_pressed = 1;
  				return 1;
  			default:
  				break;
  			}
  		}
  	}
  	return 0;
  }
  
  /* pass 1 to disable ctrlc() checking, 0 to enable.
   * returns previous state
   */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
512
  int disable_ctrlc(int disable)
47d1a6e1e   wdenk   Initial revision
513
514
515
516
517
518
519
520
521
522
523
  {
  	int prev = ctrlc_disabled;	/* save previous state */
  
  	ctrlc_disabled = disable;
  	return prev;
  }
  
  int had_ctrlc (void)
  {
  	return ctrlc_was_pressed;
  }
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
524
  void clear_ctrlc(void)
47d1a6e1e   wdenk   Initial revision
525
526
527
528
529
530
531
532
533
534
535
536
  {
  	ctrlc_was_pressed = 0;
  }
  
  #ifdef CONFIG_MODEM_SUPPORT_DEBUG
  char	screen[1024];
  char *cursor = screen;
  int once = 0;
  inline void dbg(const char *fmt, ...)
  {
  	va_list	args;
  	uint	i;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
537
  	char	printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1e   wdenk   Initial revision
538
539
540
541
542
543
544
545
546
547
548
  
  	if (!once) {
  		memset(screen, 0, sizeof(screen));
  		once++;
  	}
  
  	va_start(args, fmt);
  
  	/* For this to work, printbuffer must be larger than
  	 * anything we ever want to print.
  	 */
068af6f84   Sonny Rao   Make printf and v...
549
  	i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args);
47d1a6e1e   wdenk   Initial revision
550
  	va_end(args);
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
551
552
  	if ((screen + sizeof(screen) - 1 - cursor)
  	    < strlen(printbuffer) + 1) {
47d1a6e1e   wdenk   Initial revision
553
554
555
556
557
558
559
560
561
562
563
564
565
566
  		memset(screen, 0, sizeof(screen));
  		cursor = screen;
  	}
  	sprintf(cursor, printbuffer);
  	cursor += strlen(printbuffer);
  
  }
  #else
  inline void dbg(const char *fmt, ...)
  {
  }
  #endif
  
  /** U-Boot INIT FUNCTIONS *************************************************/
d7be3056d   Mike Frysinger   stdio: constify "...
567
  struct stdio_dev *search_device(int flags, const char *name)
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
568
  {
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
569
  	struct stdio_dev *dev;
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
570

52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
571
  	dev = stdio_get_by_name(name);
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
572

ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
573
  	if (dev && (dev->flags & flags))
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
574
575
576
577
  		return dev;
  
  	return NULL;
  }
d7be3056d   Mike Frysinger   stdio: constify "...
578
  int console_assign(int file, const char *devname)
47d1a6e1e   wdenk   Initial revision
579
  {
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
580
  	int flag;
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
581
  	struct stdio_dev *dev;
47d1a6e1e   wdenk   Initial revision
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
  
  	/* Check for valid file */
  	switch (file) {
  	case stdin:
  		flag = DEV_FLAGS_INPUT;
  		break;
  	case stdout:
  	case stderr:
  		flag = DEV_FLAGS_OUTPUT;
  		break;
  	default:
  		return -1;
  	}
  
  	/* Check for valid device name */
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
597
  	dev = search_device(flag, devname);
47d1a6e1e   wdenk   Initial revision
598

ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
599
600
  	if (dev)
  		return console_setfile(file, dev);
47d1a6e1e   wdenk   Initial revision
601
602
603
604
605
  
  	return -1;
  }
  
  /* Called before relocation - use serial functions */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
606
  int console_init_f(void)
47d1a6e1e   wdenk   Initial revision
607
  {
47d1a6e1e   wdenk   Initial revision
608
  	gd->have_console = 1;
f72da3406   wdenk   Added config opti...
609
610
611
612
613
  
  #ifdef CONFIG_SILENT_CONSOLE
  	if (getenv("silent") != NULL)
  		gd->flags |= GD_FLG_SILENT;
  #endif
9558b48af   Graeme Russ   console: Implemen...
614
  	print_pre_console_buffer();
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
615
  	return 0;
47d1a6e1e   wdenk   Initial revision
616
  }
7e3be7cf3   Jean-Christophe PLAGNIOL-VILLARD   console: unify pr...
617
618
  void stdio_print_current_devices(void)
  {
7e3be7cf3   Jean-Christophe PLAGNIOL-VILLARD   console: unify pr...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  	/* Print information */
  	puts("In:    ");
  	if (stdio_devices[stdin] == NULL) {
  		puts("No input devices available!
  ");
  	} else {
  		printf ("%s
  ", stdio_devices[stdin]->name);
  	}
  
  	puts("Out:   ");
  	if (stdio_devices[stdout] == NULL) {
  		puts("No output devices available!
  ");
  	} else {
  		printf ("%s
  ", stdio_devices[stdout]->name);
  	}
  
  	puts("Err:   ");
  	if (stdio_devices[stderr] == NULL) {
  		puts("No error devices available!
  ");
  	} else {
  		printf ("%s
  ", stdio_devices[stderr]->name);
  	}
7e3be7cf3   Jean-Christophe PLAGNIOL-VILLARD   console: unify pr...
646
  }
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
647
  #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
47d1a6e1e   wdenk   Initial revision
648
  /* Called after the relocation - use desired console functions */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
649
  int console_init_r(void)
47d1a6e1e   wdenk   Initial revision
650
651
  {
  	char *stdinname, *stdoutname, *stderrname;
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
652
  	struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
653
  #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
6e5923851   wdenk   * Cleanup, minor ...
654
  	int i;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
655
  #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
656
657
658
  #ifdef CONFIG_CONSOLE_MUX
  	int iomux_err = 0;
  #endif
47d1a6e1e   wdenk   Initial revision
659
660
  
  	/* set default handlers at first */
27b207fd0   wdenk   * Implement new m...
661
662
663
664
665
  	gd->jt[XF_getc] = serial_getc;
  	gd->jt[XF_tstc] = serial_tstc;
  	gd->jt[XF_putc] = serial_putc;
  	gd->jt[XF_puts] = serial_puts;
  	gd->jt[XF_printf] = serial_printf;
47d1a6e1e   wdenk   Initial revision
666
667
668
  
  	/* stdin stdout and stderr are in environment */
  	/* scan for it */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
669
670
671
  	stdinname  = getenv("stdin");
  	stdoutname = getenv("stdout");
  	stderrname = getenv("stderr");
47d1a6e1e   wdenk   Initial revision
672

53677ef18   Wolfgang Denk   Big white-space c...
673
  	if (OVERWRITE_CONSOLE == 0) {	/* if not overwritten by config switch */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
674
675
676
  		inputdev  = search_device(DEV_FLAGS_INPUT,  stdinname);
  		outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
  		errdev    = search_device(DEV_FLAGS_OUTPUT, stderrname);
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
677
678
679
680
681
682
683
684
  #ifdef CONFIG_CONSOLE_MUX
  		iomux_err = iomux_doenv(stdin, stdinname);
  		iomux_err += iomux_doenv(stdout, stdoutname);
  		iomux_err += iomux_doenv(stderr, stderrname);
  		if (!iomux_err)
  			/* Successful, so skip all the code below. */
  			goto done;
  #endif
47d1a6e1e   wdenk   Initial revision
685
686
687
  	}
  	/* if the devices are overwritten or not found, use default device */
  	if (inputdev == NULL) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
688
  		inputdev  = search_device(DEV_FLAGS_INPUT,  "serial");
47d1a6e1e   wdenk   Initial revision
689
690
  	}
  	if (outputdev == NULL) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
691
  		outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
47d1a6e1e   wdenk   Initial revision
692
693
  	}
  	if (errdev == NULL) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
694
  		errdev    = search_device(DEV_FLAGS_OUTPUT, "serial");
47d1a6e1e   wdenk   Initial revision
695
696
697
  	}
  	/* Initializes output console first */
  	if (outputdev != NULL) {
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
698
  		/* need to set a console if not done above. */
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
699
  		console_doenv(stdout, outputdev);
47d1a6e1e   wdenk   Initial revision
700
701
  	}
  	if (errdev != NULL) {
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
702
  		/* need to set a console if not done above. */
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
703
  		console_doenv(stderr, errdev);
47d1a6e1e   wdenk   Initial revision
704
705
  	}
  	if (inputdev != NULL) {
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
706
  		/* need to set a console if not done above. */
5f0320108   Jean-Christophe PLAGNIOL-VILLARD   common/console: a...
707
  		console_doenv(stdin, inputdev);
47d1a6e1e   wdenk   Initial revision
708
  	}
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
709
710
711
  #ifdef CONFIG_CONSOLE_MUX
  done:
  #endif
78c112c9f   Simon Glass   console: Enable f...
712
  #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
7e3be7cf3   Jean-Christophe PLAGNIOL-VILLARD   console: unify pr...
713
  	stdio_print_current_devices();
78c112c9f   Simon Glass   console: Enable f...
714
  #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
47d1a6e1e   wdenk   Initial revision
715

6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
716
  #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
47d1a6e1e   wdenk   Initial revision
717
718
  	/* set the environment variables (will overwrite previous env settings) */
  	for (i = 0; i < 3; i++) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
719
  		setenv(stdio_names[i], stdio_devices[i]->name);
47d1a6e1e   wdenk   Initial revision
720
  	}
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
721
  #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
47d1a6e1e   wdenk   Initial revision
722

c4e0057fa   Joe Hershberger   env: Refactor do_...
723
  	gd->flags |= GD_FLG_DEVINIT;	/* device initialization completed */
47d1a6e1e   wdenk   Initial revision
724
725
726
  #if 0
  	/* If nothing usable installed, use only the initial console */
  	if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
727
  		return 0;
47d1a6e1e   wdenk   Initial revision
728
  #endif
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
729
  	return 0;
47d1a6e1e   wdenk   Initial revision
730
  }
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
731
  #else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
47d1a6e1e   wdenk   Initial revision
732
733
  
  /* Called after the relocation - use desired console functions */
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
734
  int console_init_r(void)
47d1a6e1e   wdenk   Initial revision
735
  {
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
736
  	struct stdio_dev *inputdev = NULL, *outputdev = NULL;
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
737
  	int i;
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
738
  	struct list_head *list = stdio_get_list();
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
739
  	struct list_head *pos;
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
740
  	struct stdio_dev *dev;
47d1a6e1e   wdenk   Initial revision
741

d791b1dc3   wdenk   * Make sure Block...
742
  #ifdef CONFIG_SPLASH_SCREEN
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
743
744
  	/*
  	 * suppress all output if splash screen is enabled and we have
a74908161   Anatolij Gustschin   console.c: fix pr...
745
746
747
  	 * a bmp to display. We redirect the output from frame buffer
  	 * console to serial console in this case or suppress it if
  	 * "silent" mode was requested.
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
748
  	 */
a74908161   Anatolij Gustschin   console.c: fix pr...
749
750
751
752
  	if (getenv("splashimage") != NULL) {
  		if (!(gd->flags & GD_FLG_SILENT))
  			outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
  	}
f72da3406   wdenk   Added config opti...
753
  #endif
47d1a6e1e   wdenk   Initial revision
754
  	/* Scan devices looking for input and output devices */
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
755
  	list_for_each(pos, list) {
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
756
  		dev = list_entry(pos, struct stdio_dev, list);
47d1a6e1e   wdenk   Initial revision
757
758
759
760
761
762
763
  
  		if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
  			inputdev = dev;
  		}
  		if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
  			outputdev = dev;
  		}
c1de7a6da   Jean-Christophe PLAGNIOL-VILLARD   devices: merge to...
764
765
  		if(inputdev && outputdev)
  			break;
47d1a6e1e   wdenk   Initial revision
766
767
768
769
  	}
  
  	/* Initializes output console first */
  	if (outputdev != NULL) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
770
771
  		console_setfile(stdout, outputdev);
  		console_setfile(stderr, outputdev);
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
772
773
774
775
  #ifdef CONFIG_CONSOLE_MUX
  		console_devices[stdout][0] = outputdev;
  		console_devices[stderr][0] = outputdev;
  #endif
47d1a6e1e   wdenk   Initial revision
776
777
778
779
  	}
  
  	/* Initializes input console */
  	if (inputdev != NULL) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
780
  		console_setfile(stdin, inputdev);
16a28ef21   Gary Jennejohn   IOMUX: Add consol...
781
782
783
  #ifdef CONFIG_CONSOLE_MUX
  		console_devices[stdin][0] = inputdev;
  #endif
47d1a6e1e   wdenk   Initial revision
784
  	}
78c112c9f   Simon Glass   console: Enable f...
785
  #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
7e3be7cf3   Jean-Christophe PLAGNIOL-VILLARD   console: unify pr...
786
  	stdio_print_current_devices();
78c112c9f   Simon Glass   console: Enable f...
787
  #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
47d1a6e1e   wdenk   Initial revision
788
789
790
  
  	/* Setting environment variables */
  	for (i = 0; i < 3; i++) {
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
791
  		setenv(stdio_names[i], stdio_devices[i]->name);
47d1a6e1e   wdenk   Initial revision
792
  	}
c4e0057fa   Joe Hershberger   env: Refactor do_...
793
  	gd->flags |= GD_FLG_DEVINIT;	/* device initialization completed */
47d1a6e1e   wdenk   Initial revision
794
795
796
  #if 0
  	/* If nothing usable installed, use only the initial console */
  	if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
797
  		return 0;
47d1a6e1e   wdenk   Initial revision
798
  #endif
ec6f14994   Jean-Christophe PLAGNIOL-VILLARD   common/console: c...
799
  	return 0;
47d1a6e1e   wdenk   Initial revision
800
  }
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
801
  #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */