1 /* 2 * (C) Copyright 2000 3 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <stdarg.h> 26 #include <malloc.h> 27 #include <console.h> 28 #include <exports.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 #ifdef CONFIG_AMIGAONEG3SE 33 int console_changed = 0; 34 #endif 35 36 #ifdef CFG_CONSOLE_IS_IN_ENV 37 /* 38 * if overwrite_console returns 1, the stdin, stderr and stdout 39 * are switched to the serial port, else the settings in the 40 * environment are used 41 */ 42 #ifdef CFG_CONSOLE_OVERWRITE_ROUTINE 43 extern int overwrite_console (void); 44 #define OVERWRITE_CONSOLE overwrite_console () 45 #else 46 #define OVERWRITE_CONSOLE 0 47 #endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */ 48 49 #endif /* CFG_CONSOLE_IS_IN_ENV */ 50 51 static int console_setfile (int file, device_t * dev) 52 { 53 int error = 0; 54 55 if (dev == NULL) 56 return -1; 57 58 switch (file) { 59 case stdin: 60 case stdout: 61 case stderr: 62 /* Start new device */ 63 if (dev->start) { 64 error = dev->start (); 65 /* If it's not started dont use it */ 66 if (error < 0) 67 break; 68 } 69 70 /* Assign the new device (leaving the existing one started) */ 71 stdio_devices[file] = dev; 72 73 /* 74 * Update monitor functions 75 * (to use the console stuff by other applications) 76 */ 77 switch (file) { 78 case stdin: 79 gd->jt[XF_getc] = dev->getc; 80 gd->jt[XF_tstc] = dev->tstc; 81 break; 82 case stdout: 83 gd->jt[XF_putc] = dev->putc; 84 gd->jt[XF_puts] = dev->puts; 85 gd->jt[XF_printf] = printf; 86 break; 87 } 88 break; 89 90 default: /* Invalid file ID */ 91 error = -1; 92 } 93 return error; 94 } 95 96 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ 97 98 void serial_printf (const char *fmt, ...) 99 { 100 va_list args; 101 uint i; 102 char printbuffer[CFG_PBSIZE]; 103 104 va_start (args, fmt); 105 106 /* For this to work, printbuffer must be larger than 107 * anything we ever want to print. 108 */ 109 i = vsprintf (printbuffer, fmt, args); 110 va_end (args); 111 112 serial_puts (printbuffer); 113 } 114 115 int fgetc (int file) 116 { 117 if (file < MAX_FILES) 118 return stdio_devices[file]->getc (); 119 120 return -1; 121 } 122 123 int ftstc (int file) 124 { 125 if (file < MAX_FILES) 126 return stdio_devices[file]->tstc (); 127 128 return -1; 129 } 130 131 void fputc (int file, const char c) 132 { 133 if (file < MAX_FILES) 134 stdio_devices[file]->putc (c); 135 } 136 137 void fputs (int file, const char *s) 138 { 139 if (file < MAX_FILES) 140 stdio_devices[file]->puts (s); 141 } 142 143 void fprintf (int file, const char *fmt, ...) 144 { 145 va_list args; 146 uint i; 147 char printbuffer[CFG_PBSIZE]; 148 149 va_start (args, fmt); 150 151 /* For this to work, printbuffer must be larger than 152 * anything we ever want to print. 153 */ 154 i = vsprintf (printbuffer, fmt, args); 155 va_end (args); 156 157 /* Send to desired file */ 158 fputs (file, printbuffer); 159 } 160 161 /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ 162 163 int getc (void) 164 { 165 #ifdef CONFIG_DISABLE_CONSOLE 166 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 167 return 0; 168 #endif 169 170 if (gd->flags & GD_FLG_DEVINIT) { 171 /* Get from the standard input */ 172 return fgetc (stdin); 173 } 174 175 /* Send directly to the handler */ 176 return serial_getc (); 177 } 178 179 int tstc (void) 180 { 181 #ifdef CONFIG_DISABLE_CONSOLE 182 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 183 return 0; 184 #endif 185 186 if (gd->flags & GD_FLG_DEVINIT) { 187 /* Test the standard input */ 188 return ftstc (stdin); 189 } 190 191 /* Send directly to the handler */ 192 return serial_tstc (); 193 } 194 195 void putc (const char c) 196 { 197 #ifdef CONFIG_SILENT_CONSOLE 198 if (gd->flags & GD_FLG_SILENT) 199 return; 200 #endif 201 202 #ifdef CONFIG_DISABLE_CONSOLE 203 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 204 return; 205 #endif 206 207 if (gd->flags & GD_FLG_DEVINIT) { 208 /* Send to the standard output */ 209 fputc (stdout, c); 210 } else { 211 /* Send directly to the handler */ 212 serial_putc (c); 213 } 214 } 215 216 void puts (const char *s) 217 { 218 #ifdef CONFIG_SILENT_CONSOLE 219 if (gd->flags & GD_FLG_SILENT) 220 return; 221 #endif 222 223 #ifdef CONFIG_DISABLE_CONSOLE 224 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 225 return; 226 #endif 227 228 if (gd->flags & GD_FLG_DEVINIT) { 229 /* Send to the standard output */ 230 fputs (stdout, s); 231 } else { 232 /* Send directly to the handler */ 233 serial_puts (s); 234 } 235 } 236 237 void printf (const char *fmt, ...) 238 { 239 va_list args; 240 uint i; 241 char printbuffer[CFG_PBSIZE]; 242 243 va_start (args, fmt); 244 245 /* For this to work, printbuffer must be larger than 246 * anything we ever want to print. 247 */ 248 i = vsprintf (printbuffer, fmt, args); 249 va_end (args); 250 251 /* Print the string */ 252 puts (printbuffer); 253 } 254 255 void vprintf (const char *fmt, va_list args) 256 { 257 uint i; 258 char printbuffer[CFG_PBSIZE]; 259 260 /* For this to work, printbuffer must be larger than 261 * anything we ever want to print. 262 */ 263 i = vsprintf (printbuffer, fmt, args); 264 265 /* Print the string */ 266 puts (printbuffer); 267 } 268 269 /* test if ctrl-c was pressed */ 270 static int ctrlc_disabled = 0; /* see disable_ctrl() */ 271 static int ctrlc_was_pressed = 0; 272 int ctrlc (void) 273 { 274 if (!ctrlc_disabled && gd->have_console) { 275 if (tstc ()) { 276 switch (getc ()) { 277 case 0x03: /* ^C - Control C */ 278 ctrlc_was_pressed = 1; 279 return 1; 280 default: 281 break; 282 } 283 } 284 } 285 return 0; 286 } 287 288 /* pass 1 to disable ctrlc() checking, 0 to enable. 289 * returns previous state 290 */ 291 int disable_ctrlc (int disable) 292 { 293 int prev = ctrlc_disabled; /* save previous state */ 294 295 ctrlc_disabled = disable; 296 return prev; 297 } 298 299 int had_ctrlc (void) 300 { 301 return ctrlc_was_pressed; 302 } 303 304 void clear_ctrlc (void) 305 { 306 ctrlc_was_pressed = 0; 307 } 308 309 #ifdef CONFIG_MODEM_SUPPORT_DEBUG 310 char screen[1024]; 311 char *cursor = screen; 312 int once = 0; 313 inline void dbg(const char *fmt, ...) 314 { 315 va_list args; 316 uint i; 317 char printbuffer[CFG_PBSIZE]; 318 319 if (!once) { 320 memset(screen, 0, sizeof(screen)); 321 once++; 322 } 323 324 va_start(args, fmt); 325 326 /* For this to work, printbuffer must be larger than 327 * anything we ever want to print. 328 */ 329 i = vsprintf(printbuffer, fmt, args); 330 va_end(args); 331 332 if ((screen + sizeof(screen) - 1 - cursor) < strlen(printbuffer)+1) { 333 memset(screen, 0, sizeof(screen)); 334 cursor = screen; 335 } 336 sprintf(cursor, printbuffer); 337 cursor += strlen(printbuffer); 338 339 } 340 #else 341 inline void dbg(const char *fmt, ...) 342 { 343 } 344 #endif 345 346 /** U-Boot INIT FUNCTIONS *************************************************/ 347 348 device_t *search_device (int flags, char *name) 349 { 350 device_t *dev; 351 352 dev = device_get_by_name(name); 353 354 if(dev && (dev->flags & flags)) 355 return dev; 356 357 return NULL; 358 } 359 360 int console_assign (int file, char *devname) 361 { 362 int flag; 363 device_t *dev; 364 365 /* Check for valid file */ 366 switch (file) { 367 case stdin: 368 flag = DEV_FLAGS_INPUT; 369 break; 370 case stdout: 371 case stderr: 372 flag = DEV_FLAGS_OUTPUT; 373 break; 374 default: 375 return -1; 376 } 377 378 /* Check for valid device name */ 379 380 dev = search_device(flag, devname); 381 382 if(dev) 383 return console_setfile (file, dev); 384 385 return -1; 386 } 387 388 /* Called before relocation - use serial functions */ 389 int console_init_f (void) 390 { 391 gd->have_console = 1; 392 393 #ifdef CONFIG_SILENT_CONSOLE 394 if (getenv("silent") != NULL) 395 gd->flags |= GD_FLG_SILENT; 396 #endif 397 398 return (0); 399 } 400 401 #ifdef CFG_CONSOLE_IS_IN_ENV 402 /* Called after the relocation - use desired console functions */ 403 int console_init_r (void) 404 { 405 char *stdinname, *stdoutname, *stderrname; 406 device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL; 407 #ifdef CFG_CONSOLE_ENV_OVERWRITE 408 int i; 409 #endif /* CFG_CONSOLE_ENV_OVERWRITE */ 410 411 /* set default handlers at first */ 412 gd->jt[XF_getc] = serial_getc; 413 gd->jt[XF_tstc] = serial_tstc; 414 gd->jt[XF_putc] = serial_putc; 415 gd->jt[XF_puts] = serial_puts; 416 gd->jt[XF_printf] = serial_printf; 417 418 /* stdin stdout and stderr are in environment */ 419 /* scan for it */ 420 stdinname = getenv ("stdin"); 421 stdoutname = getenv ("stdout"); 422 stderrname = getenv ("stderr"); 423 424 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */ 425 inputdev = search_device (DEV_FLAGS_INPUT, stdinname); 426 outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname); 427 errdev = search_device (DEV_FLAGS_OUTPUT, stderrname); 428 } 429 /* if the devices are overwritten or not found, use default device */ 430 if (inputdev == NULL) { 431 inputdev = search_device (DEV_FLAGS_INPUT, "serial"); 432 } 433 if (outputdev == NULL) { 434 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 435 } 436 if (errdev == NULL) { 437 errdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 438 } 439 /* Initializes output console first */ 440 if (outputdev != NULL) { 441 console_setfile (stdout, outputdev); 442 } 443 if (errdev != NULL) { 444 console_setfile (stderr, errdev); 445 } 446 if (inputdev != NULL) { 447 console_setfile (stdin, inputdev); 448 } 449 450 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 451 452 #ifndef CFG_CONSOLE_INFO_QUIET 453 /* Print information */ 454 puts ("In: "); 455 if (stdio_devices[stdin] == NULL) { 456 puts ("No input devices available!\n"); 457 } else { 458 printf ("%s\n", stdio_devices[stdin]->name); 459 } 460 461 puts ("Out: "); 462 if (stdio_devices[stdout] == NULL) { 463 puts ("No output devices available!\n"); 464 } else { 465 printf ("%s\n", stdio_devices[stdout]->name); 466 } 467 468 puts ("Err: "); 469 if (stdio_devices[stderr] == NULL) { 470 puts ("No error devices available!\n"); 471 } else { 472 printf ("%s\n", stdio_devices[stderr]->name); 473 } 474 #endif /* CFG_CONSOLE_INFO_QUIET */ 475 476 #ifdef CFG_CONSOLE_ENV_OVERWRITE 477 /* set the environment variables (will overwrite previous env settings) */ 478 for (i = 0; i < 3; i++) { 479 setenv (stdio_names[i], stdio_devices[i]->name); 480 } 481 #endif /* CFG_CONSOLE_ENV_OVERWRITE */ 482 483 #if 0 484 /* If nothing usable installed, use only the initial console */ 485 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 486 return (0); 487 #endif 488 return (0); 489 } 490 491 #else /* CFG_CONSOLE_IS_IN_ENV */ 492 493 /* Called after the relocation - use desired console functions */ 494 int console_init_r (void) 495 { 496 device_t *inputdev = NULL, *outputdev = NULL; 497 int i; 498 struct list_head *list = device_get_list(); 499 struct list_head *pos; 500 device_t *dev; 501 502 #ifdef CONFIG_SPLASH_SCREEN 503 /* suppress all output if splash screen is enabled and we have 504 a bmp to display */ 505 if (getenv("splashimage") != NULL) 506 gd->flags |= GD_FLG_SILENT; 507 #endif 508 509 /* Scan devices looking for input and output devices */ 510 list_for_each(pos, list) { 511 dev = list_entry(pos, device_t, list); 512 513 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { 514 inputdev = dev; 515 } 516 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { 517 outputdev = dev; 518 } 519 if(inputdev && outputdev) 520 break; 521 } 522 523 /* Initializes output console first */ 524 if (outputdev != NULL) { 525 console_setfile (stdout, outputdev); 526 console_setfile (stderr, outputdev); 527 } 528 529 /* Initializes input console */ 530 if (inputdev != NULL) { 531 console_setfile (stdin, inputdev); 532 } 533 534 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 535 536 #ifndef CFG_CONSOLE_INFO_QUIET 537 /* Print information */ 538 puts ("In: "); 539 if (stdio_devices[stdin] == NULL) { 540 puts ("No input devices available!\n"); 541 } else { 542 printf ("%s\n", stdio_devices[stdin]->name); 543 } 544 545 puts ("Out: "); 546 if (stdio_devices[stdout] == NULL) { 547 puts ("No output devices available!\n"); 548 } else { 549 printf ("%s\n", stdio_devices[stdout]->name); 550 } 551 552 puts ("Err: "); 553 if (stdio_devices[stderr] == NULL) { 554 puts ("No error devices available!\n"); 555 } else { 556 printf ("%s\n", stdio_devices[stderr]->name); 557 } 558 #endif /* CFG_CONSOLE_INFO_QUIET */ 559 560 /* Setting environment variables */ 561 for (i = 0; i < 3; i++) { 562 setenv (stdio_names[i], stdio_devices[i]->name); 563 } 564 565 #if 0 566 /* If nothing usable installed, use only the initial console */ 567 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 568 return (0); 569 #endif 570 571 return (0); 572 } 573 574 #endif /* CFG_CONSOLE_IS_IN_ENV */ 575