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