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 if (gd->flags & GD_FLG_DEVINIT) { 166 /* Get from the standard input */ 167 return fgetc (stdin); 168 } 169 170 /* Send directly to the handler */ 171 return serial_getc (); 172 } 173 174 int tstc (void) 175 { 176 if (gd->flags & GD_FLG_DEVINIT) { 177 /* Test the standard input */ 178 return ftstc (stdin); 179 } 180 181 /* Send directly to the handler */ 182 return serial_tstc (); 183 } 184 185 void putc (const char c) 186 { 187 #ifdef CONFIG_SILENT_CONSOLE 188 if (gd->flags & GD_FLG_SILENT) 189 return; 190 #endif 191 192 if (gd->flags & GD_FLG_DEVINIT) { 193 /* Send to the standard output */ 194 fputc (stdout, c); 195 } else { 196 /* Send directly to the handler */ 197 serial_putc (c); 198 } 199 } 200 201 void puts (const char *s) 202 { 203 #ifdef CONFIG_SILENT_CONSOLE 204 if (gd->flags & GD_FLG_SILENT) 205 return; 206 #endif 207 208 if (gd->flags & GD_FLG_DEVINIT) { 209 /* Send to the standard output */ 210 fputs (stdout, s); 211 } else { 212 /* Send directly to the handler */ 213 serial_puts (s); 214 } 215 } 216 217 void printf (const char *fmt, ...) 218 { 219 va_list args; 220 uint i; 221 char printbuffer[CFG_PBSIZE]; 222 223 va_start (args, fmt); 224 225 /* For this to work, printbuffer must be larger than 226 * anything we ever want to print. 227 */ 228 i = vsprintf (printbuffer, fmt, args); 229 va_end (args); 230 231 /* Print the string */ 232 puts (printbuffer); 233 } 234 235 void vprintf (const char *fmt, va_list args) 236 { 237 uint i; 238 char printbuffer[CFG_PBSIZE]; 239 240 /* For this to work, printbuffer must be larger than 241 * anything we ever want to print. 242 */ 243 i = vsprintf (printbuffer, fmt, args); 244 245 /* Print the string */ 246 puts (printbuffer); 247 } 248 249 /* test if ctrl-c was pressed */ 250 static int ctrlc_disabled = 0; /* see disable_ctrl() */ 251 static int ctrlc_was_pressed = 0; 252 int ctrlc (void) 253 { 254 if (!ctrlc_disabled && gd->have_console) { 255 if (tstc ()) { 256 switch (getc ()) { 257 case 0x03: /* ^C - Control C */ 258 ctrlc_was_pressed = 1; 259 return 1; 260 default: 261 break; 262 } 263 } 264 } 265 return 0; 266 } 267 268 /* pass 1 to disable ctrlc() checking, 0 to enable. 269 * returns previous state 270 */ 271 int disable_ctrlc (int disable) 272 { 273 int prev = ctrlc_disabled; /* save previous state */ 274 275 ctrlc_disabled = disable; 276 return prev; 277 } 278 279 int had_ctrlc (void) 280 { 281 return ctrlc_was_pressed; 282 } 283 284 void clear_ctrlc (void) 285 { 286 ctrlc_was_pressed = 0; 287 } 288 289 #ifdef CONFIG_MODEM_SUPPORT_DEBUG 290 char screen[1024]; 291 char *cursor = screen; 292 int once = 0; 293 inline void dbg(const char *fmt, ...) 294 { 295 va_list args; 296 uint i; 297 char printbuffer[CFG_PBSIZE]; 298 299 if (!once) { 300 memset(screen, 0, sizeof(screen)); 301 once++; 302 } 303 304 va_start(args, fmt); 305 306 /* For this to work, printbuffer must be larger than 307 * anything we ever want to print. 308 */ 309 i = vsprintf(printbuffer, fmt, args); 310 va_end(args); 311 312 if ((screen + sizeof(screen) - 1 - cursor) < strlen(printbuffer)+1) { 313 memset(screen, 0, sizeof(screen)); 314 cursor = screen; 315 } 316 sprintf(cursor, printbuffer); 317 cursor += strlen(printbuffer); 318 319 } 320 #else 321 inline void dbg(const char *fmt, ...) 322 { 323 } 324 #endif 325 326 /** U-Boot INIT FUNCTIONS *************************************************/ 327 328 int console_assign (int file, char *devname) 329 { 330 int flag, i; 331 332 /* Check for valid file */ 333 switch (file) { 334 case stdin: 335 flag = DEV_FLAGS_INPUT; 336 break; 337 case stdout: 338 case stderr: 339 flag = DEV_FLAGS_OUTPUT; 340 break; 341 default: 342 return -1; 343 } 344 345 /* Check for valid device name */ 346 347 for (i = 1; i <= ListNumItems (devlist); i++) { 348 device_t *dev = ListGetPtrToItem (devlist, i); 349 350 if (strcmp (devname, dev->name) == 0) { 351 if (dev->flags & flag) 352 return console_setfile (file, dev); 353 354 return -1; 355 } 356 } 357 358 return -1; 359 } 360 361 /* Called before relocation - use serial functions */ 362 int console_init_f (void) 363 { 364 gd->have_console = 1; 365 366 #ifdef CONFIG_SILENT_CONSOLE 367 if (getenv("silent") != NULL) 368 gd->flags |= GD_FLG_SILENT; 369 #endif 370 371 return (0); 372 } 373 374 #if defined(CFG_CONSOLE_IS_IN_ENV) || defined(CONFIG_SPLASH_SCREEN) || defined(CONFIG_SILENT_CONSOLE) 375 /* search a device */ 376 device_t *search_device (int flags, char *name) 377 { 378 int i, items; 379 device_t *dev = NULL; 380 381 items = ListNumItems (devlist); 382 if (name == NULL) 383 return dev; 384 385 for (i = 1; i <= items; i++) { 386 dev = ListGetPtrToItem (devlist, i); 387 if ((dev->flags & flags) && (strcmp (name, dev->name) == 0)) { 388 break; 389 } 390 } 391 return dev; 392 } 393 #endif /* CFG_CONSOLE_IS_IN_ENV || CONFIG_SPLASH_SCREEN */ 394 395 #ifdef CFG_CONSOLE_IS_IN_ENV 396 /* Called after the relocation - use desired console functions */ 397 int console_init_r (void) 398 { 399 char *stdinname, *stdoutname, *stderrname; 400 device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL; 401 #ifdef CFG_CONSOLE_ENV_OVERWRITE 402 int i; 403 #endif /* CFG_CONSOLE_ENV_OVERWRITE */ 404 405 /* set default handlers at first */ 406 gd->jt[XF_getc] = serial_getc; 407 gd->jt[XF_tstc] = serial_tstc; 408 gd->jt[XF_putc] = serial_putc; 409 gd->jt[XF_puts] = serial_puts; 410 gd->jt[XF_printf] = serial_printf; 411 412 /* stdin stdout and stderr are in environment */ 413 /* scan for it */ 414 stdinname = getenv ("stdin"); 415 stdoutname = getenv ("stdout"); 416 stderrname = getenv ("stderr"); 417 418 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */ 419 inputdev = search_device (DEV_FLAGS_INPUT, stdinname); 420 outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname); 421 errdev = search_device (DEV_FLAGS_OUTPUT, stderrname); 422 } 423 /* if the devices are overwritten or not found, use default device */ 424 if (inputdev == NULL) { 425 inputdev = search_device (DEV_FLAGS_INPUT, "serial"); 426 } 427 if (outputdev == NULL) { 428 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 429 } 430 if (errdev == NULL) { 431 errdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 432 } 433 /* Initializes output console first */ 434 if (outputdev != NULL) { 435 console_setfile (stdout, outputdev); 436 } 437 if (errdev != NULL) { 438 console_setfile (stderr, errdev); 439 } 440 if (inputdev != NULL) { 441 console_setfile (stdin, inputdev); 442 } 443 444 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 445 446 #ifndef CFG_CONSOLE_INFO_QUIET 447 /* Print information */ 448 puts ("In: "); 449 if (stdio_devices[stdin] == NULL) { 450 puts ("No input devices available!\n"); 451 } else { 452 printf ("%s\n", stdio_devices[stdin]->name); 453 } 454 455 puts ("Out: "); 456 if (stdio_devices[stdout] == NULL) { 457 puts ("No output devices available!\n"); 458 } else { 459 printf ("%s\n", stdio_devices[stdout]->name); 460 } 461 462 puts ("Err: "); 463 if (stdio_devices[stderr] == NULL) { 464 puts ("No error devices available!\n"); 465 } else { 466 printf ("%s\n", stdio_devices[stderr]->name); 467 } 468 #endif /* CFG_CONSOLE_INFO_QUIET */ 469 470 #ifdef CFG_CONSOLE_ENV_OVERWRITE 471 /* set the environment variables (will overwrite previous env settings) */ 472 for (i = 0; i < 3; i++) { 473 setenv (stdio_names[i], stdio_devices[i]->name); 474 } 475 #endif /* CFG_CONSOLE_ENV_OVERWRITE */ 476 477 #if 0 478 /* If nothing usable installed, use only the initial console */ 479 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 480 return (0); 481 #endif 482 return (0); 483 } 484 485 #else /* CFG_CONSOLE_IS_IN_ENV */ 486 487 /* Called after the relocation - use desired console functions */ 488 int console_init_r (void) 489 { 490 device_t *inputdev = NULL, *outputdev = NULL; 491 int i, items = ListNumItems (devlist); 492 493 #ifdef CONFIG_SPLASH_SCREEN 494 /* suppress all output if splash screen is enabled and we have 495 a bmp to display */ 496 if (getenv("splashimage") != NULL) 497 gd->flags |= GD_FLG_SILENT; 498 #endif 499 500 /* Scan devices looking for input and output devices */ 501 for (i = 1; 502 (i <= items) && ((inputdev == NULL) || (outputdev == NULL)); 503 i++ 504 ) { 505 device_t *dev = ListGetPtrToItem (devlist, i); 506 507 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { 508 inputdev = dev; 509 } 510 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { 511 outputdev = dev; 512 } 513 } 514 515 /* Initializes output console first */ 516 if (outputdev != NULL) { 517 console_setfile (stdout, outputdev); 518 console_setfile (stderr, outputdev); 519 } 520 521 /* Initializes input console */ 522 if (inputdev != NULL) { 523 console_setfile (stdin, inputdev); 524 } 525 526 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 527 528 #ifndef CFG_CONSOLE_INFO_QUIET 529 /* Print information */ 530 puts ("In: "); 531 if (stdio_devices[stdin] == NULL) { 532 puts ("No input devices available!\n"); 533 } else { 534 printf ("%s\n", stdio_devices[stdin]->name); 535 } 536 537 puts ("Out: "); 538 if (stdio_devices[stdout] == NULL) { 539 puts ("No output devices available!\n"); 540 } else { 541 printf ("%s\n", stdio_devices[stdout]->name); 542 } 543 544 puts ("Err: "); 545 if (stdio_devices[stderr] == NULL) { 546 puts ("No error devices available!\n"); 547 } else { 548 printf ("%s\n", stdio_devices[stderr]->name); 549 } 550 #endif /* CFG_CONSOLE_INFO_QUIET */ 551 552 /* Setting environment variables */ 553 for (i = 0; i < 3; i++) { 554 setenv (stdio_names[i], stdio_devices[i]->name); 555 } 556 557 #if 0 558 /* If nothing usable installed, use only the initial console */ 559 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 560 return (0); 561 #endif 562 563 return (0); 564 } 565 566 #endif /* CFG_CONSOLE_IS_IN_ENV */ 567