console.c 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000
  4. * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
  5. */
  6. #include <common.h>
  7. #include <console.h>
  8. #include <debug_uart.h>
  9. #include <dm.h>
  10. #include <env.h>
  11. #include <stdarg.h>
  12. #include <iomux.h>
  13. #include <malloc.h>
  14. #include <mapmem.h>
  15. #include <os.h>
  16. #include <serial.h>
  17. #include <stdio_dev.h>
  18. #include <exports.h>
  19. #include <env_internal.h>
  20. #include <watchdog.h>
  21. DECLARE_GLOBAL_DATA_PTR;
  22. static int on_console(const char *name, const char *value, enum env_op op,
  23. int flags)
  24. {
  25. int console = -1;
  26. /* Check for console redirection */
  27. if (strcmp(name, "stdin") == 0)
  28. console = stdin;
  29. else if (strcmp(name, "stdout") == 0)
  30. console = stdout;
  31. else if (strcmp(name, "stderr") == 0)
  32. console = stderr;
  33. /* if not actually setting a console variable, we don't care */
  34. if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
  35. return 0;
  36. switch (op) {
  37. case env_op_create:
  38. case env_op_overwrite:
  39. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  40. if (iomux_doenv(console, value))
  41. return 1;
  42. #else
  43. /* Try assigning specified device */
  44. if (console_assign(console, value) < 0)
  45. return 1;
  46. #endif
  47. return 0;
  48. case env_op_delete:
  49. if ((flags & H_FORCE) == 0)
  50. printf("Can't delete \"%s\"\n", name);
  51. return 1;
  52. default:
  53. return 0;
  54. }
  55. }
  56. U_BOOT_ENV_CALLBACK(console, on_console);
  57. #ifdef CONFIG_SILENT_CONSOLE
  58. static int on_silent(const char *name, const char *value, enum env_op op,
  59. int flags)
  60. {
  61. #if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET)
  62. if (flags & H_INTERACTIVE)
  63. return 0;
  64. #endif
  65. #if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC)
  66. if ((flags & H_INTERACTIVE) == 0)
  67. return 0;
  68. #endif
  69. if (value != NULL)
  70. gd->flags |= GD_FLG_SILENT;
  71. else
  72. gd->flags &= ~GD_FLG_SILENT;
  73. return 0;
  74. }
  75. U_BOOT_ENV_CALLBACK(silent, on_silent);
  76. #endif
  77. #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
  78. /*
  79. * if overwrite_console returns 1, the stdin, stderr and stdout
  80. * are switched to the serial port, else the settings in the
  81. * environment are used
  82. */
  83. #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
  84. extern int overwrite_console(void);
  85. #define OVERWRITE_CONSOLE overwrite_console()
  86. #else
  87. #define OVERWRITE_CONSOLE 0
  88. #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
  89. #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
  90. static int console_setfile(int file, struct stdio_dev * dev)
  91. {
  92. int error = 0;
  93. if (dev == NULL)
  94. return -1;
  95. switch (file) {
  96. case stdin:
  97. case stdout:
  98. case stderr:
  99. /* Start new device */
  100. if (dev->start) {
  101. error = dev->start(dev);
  102. /* If it's not started dont use it */
  103. if (error < 0)
  104. break;
  105. }
  106. /* Assign the new device (leaving the existing one started) */
  107. stdio_devices[file] = dev;
  108. /*
  109. * Update monitor functions
  110. * (to use the console stuff by other applications)
  111. */
  112. switch (file) {
  113. case stdin:
  114. gd->jt->getc = getc;
  115. gd->jt->tstc = tstc;
  116. break;
  117. case stdout:
  118. gd->jt->putc = putc;
  119. gd->jt->puts = puts;
  120. gd->jt->printf = printf;
  121. break;
  122. }
  123. break;
  124. default: /* Invalid file ID */
  125. error = -1;
  126. }
  127. return error;
  128. }
  129. /**
  130. * console_dev_is_serial() - Check if a stdio device is a serial device
  131. *
  132. * @sdev: Device to check
  133. * @return true if this device is in the serial uclass (or for pre-driver-model,
  134. * whether it is called "serial".
  135. */
  136. static bool console_dev_is_serial(struct stdio_dev *sdev)
  137. {
  138. bool is_serial;
  139. #ifdef CONFIG_DM_SERIAL
  140. if (sdev->flags & DEV_FLAGS_DM) {
  141. struct udevice *dev = sdev->priv;
  142. is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL;
  143. } else
  144. #endif
  145. is_serial = !strcmp(sdev->name, "serial");
  146. return is_serial;
  147. }
  148. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  149. /** Console I/O multiplexing *******************************************/
  150. static struct stdio_dev *tstcdev;
  151. struct stdio_dev **console_devices[MAX_FILES];
  152. int cd_count[MAX_FILES];
  153. /*
  154. * This depends on tstc() always being called before getc().
  155. * This is guaranteed to be true because this routine is called
  156. * only from fgetc() which assures it.
  157. * No attempt is made to demultiplex multiple input sources.
  158. */
  159. static int console_getc(int file)
  160. {
  161. unsigned char ret;
  162. /* This is never called with testcdev == NULL */
  163. ret = tstcdev->getc(tstcdev);
  164. tstcdev = NULL;
  165. return ret;
  166. }
  167. static int console_tstc(int file)
  168. {
  169. int i, ret;
  170. struct stdio_dev *dev;
  171. int prev;
  172. prev = disable_ctrlc(1);
  173. for (i = 0; i < cd_count[file]; i++) {
  174. dev = console_devices[file][i];
  175. if (dev->tstc != NULL) {
  176. ret = dev->tstc(dev);
  177. if (ret > 0) {
  178. tstcdev = dev;
  179. disable_ctrlc(prev);
  180. return ret;
  181. }
  182. }
  183. }
  184. disable_ctrlc(prev);
  185. return 0;
  186. }
  187. static void console_putc(int file, const char c)
  188. {
  189. int i;
  190. struct stdio_dev *dev;
  191. for (i = 0; i < cd_count[file]; i++) {
  192. dev = console_devices[file][i];
  193. if (dev->putc != NULL)
  194. dev->putc(dev, c);
  195. }
  196. }
  197. static void console_puts_noserial(int file, const char *s)
  198. {
  199. int i;
  200. struct stdio_dev *dev;
  201. for (i = 0; i < cd_count[file]; i++) {
  202. dev = console_devices[file][i];
  203. if (dev->puts != NULL && !console_dev_is_serial(dev))
  204. dev->puts(dev, s);
  205. }
  206. }
  207. static void console_puts(int file, const char *s)
  208. {
  209. int i;
  210. struct stdio_dev *dev;
  211. for (i = 0; i < cd_count[file]; i++) {
  212. dev = console_devices[file][i];
  213. if (dev->puts != NULL)
  214. dev->puts(dev, s);
  215. }
  216. }
  217. #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
  218. static inline void console_doenv(int file, struct stdio_dev *dev)
  219. {
  220. iomux_doenv(file, dev->name);
  221. }
  222. #endif
  223. #else
  224. static inline int console_getc(int file)
  225. {
  226. return stdio_devices[file]->getc(stdio_devices[file]);
  227. }
  228. static inline int console_tstc(int file)
  229. {
  230. return stdio_devices[file]->tstc(stdio_devices[file]);
  231. }
  232. static inline void console_putc(int file, const char c)
  233. {
  234. stdio_devices[file]->putc(stdio_devices[file], c);
  235. }
  236. static inline void console_puts_noserial(int file, const char *s)
  237. {
  238. if (!console_dev_is_serial(stdio_devices[file]))
  239. stdio_devices[file]->puts(stdio_devices[file], s);
  240. }
  241. static inline void console_puts(int file, const char *s)
  242. {
  243. stdio_devices[file]->puts(stdio_devices[file], s);
  244. }
  245. #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
  246. static inline void console_doenv(int file, struct stdio_dev *dev)
  247. {
  248. console_setfile(file, dev);
  249. }
  250. #endif
  251. #endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
  252. /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
  253. int serial_printf(const char *fmt, ...)
  254. {
  255. va_list args;
  256. uint i;
  257. char printbuffer[CONFIG_SYS_PBSIZE];
  258. va_start(args, fmt);
  259. /* For this to work, printbuffer must be larger than
  260. * anything we ever want to print.
  261. */
  262. i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
  263. va_end(args);
  264. serial_puts(printbuffer);
  265. return i;
  266. }
  267. int fgetc(int file)
  268. {
  269. if (file < MAX_FILES) {
  270. /*
  271. * Effectively poll for input wherever it may be available.
  272. */
  273. for (;;) {
  274. WATCHDOG_RESET();
  275. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  276. /*
  277. * Upper layer may have already called tstc() so
  278. * check for that first.
  279. */
  280. if (tstcdev != NULL)
  281. return console_getc(file);
  282. console_tstc(file);
  283. #else
  284. if (console_tstc(file))
  285. return console_getc(file);
  286. #endif
  287. #ifdef CONFIG_WATCHDOG
  288. /*
  289. * If the watchdog must be rate-limited then it should
  290. * already be handled in board-specific code.
  291. */
  292. udelay(1);
  293. #endif
  294. }
  295. }
  296. return -1;
  297. }
  298. int ftstc(int file)
  299. {
  300. if (file < MAX_FILES)
  301. return console_tstc(file);
  302. return -1;
  303. }
  304. void fputc(int file, const char c)
  305. {
  306. if (file < MAX_FILES)
  307. console_putc(file, c);
  308. }
  309. void fputs(int file, const char *s)
  310. {
  311. if (file < MAX_FILES)
  312. console_puts(file, s);
  313. }
  314. int fprintf(int file, const char *fmt, ...)
  315. {
  316. va_list args;
  317. uint i;
  318. char printbuffer[CONFIG_SYS_PBSIZE];
  319. va_start(args, fmt);
  320. /* For this to work, printbuffer must be larger than
  321. * anything we ever want to print.
  322. */
  323. i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
  324. va_end(args);
  325. /* Send to desired file */
  326. fputs(file, printbuffer);
  327. return i;
  328. }
  329. /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
  330. int getc(void)
  331. {
  332. #ifdef CONFIG_DISABLE_CONSOLE
  333. if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  334. return 0;
  335. #endif
  336. if (!gd->have_console)
  337. return 0;
  338. #ifdef CONFIG_CONSOLE_RECORD
  339. if (gd->console_in.start) {
  340. int ch;
  341. ch = membuff_getbyte((struct membuff *)&gd->console_in);
  342. if (ch != -1)
  343. return 1;
  344. }
  345. #endif
  346. if (gd->flags & GD_FLG_DEVINIT) {
  347. /* Get from the standard input */
  348. return fgetc(stdin);
  349. }
  350. /* Send directly to the handler */
  351. return serial_getc();
  352. }
  353. int tstc(void)
  354. {
  355. #ifdef CONFIG_DISABLE_CONSOLE
  356. if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  357. return 0;
  358. #endif
  359. if (!gd->have_console)
  360. return 0;
  361. #ifdef CONFIG_CONSOLE_RECORD
  362. if (gd->console_in.start) {
  363. if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1)
  364. return 1;
  365. }
  366. #endif
  367. if (gd->flags & GD_FLG_DEVINIT) {
  368. /* Test the standard input */
  369. return ftstc(stdin);
  370. }
  371. /* Send directly to the handler */
  372. return serial_tstc();
  373. }
  374. #define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0
  375. #define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1
  376. #if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
  377. #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
  378. static void pre_console_putc(const char c)
  379. {
  380. char *buffer;
  381. buffer = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
  382. buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
  383. unmap_sysmem(buffer);
  384. }
  385. static void pre_console_puts(const char *s)
  386. {
  387. while (*s)
  388. pre_console_putc(*s++);
  389. }
  390. static void print_pre_console_buffer(int flushpoint)
  391. {
  392. unsigned long in = 0, out = 0;
  393. char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
  394. char *buf_in;
  395. #ifdef CONFIG_SILENT_CONSOLE
  396. if (gd->flags & GD_FLG_SILENT)
  397. return;
  398. #endif
  399. buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
  400. if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
  401. in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
  402. while (in < gd->precon_buf_idx)
  403. buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)];
  404. unmap_sysmem(buf_in);
  405. buf_out[out] = 0;
  406. switch (flushpoint) {
  407. case PRE_CONSOLE_FLUSHPOINT1_SERIAL:
  408. puts(buf_out);
  409. break;
  410. case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
  411. console_puts_noserial(stdout, buf_out);
  412. break;
  413. }
  414. }
  415. #else
  416. static inline void pre_console_putc(const char c) {}
  417. static inline void pre_console_puts(const char *s) {}
  418. static inline void print_pre_console_buffer(int flushpoint) {}
  419. #endif
  420. void putc(const char c)
  421. {
  422. #ifdef CONFIG_SANDBOX
  423. /* sandbox can send characters to stdout before it has a console */
  424. if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
  425. os_putc(c);
  426. return;
  427. }
  428. #endif
  429. #ifdef CONFIG_DEBUG_UART
  430. /* if we don't have a console yet, use the debug UART */
  431. if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
  432. printch(c);
  433. return;
  434. }
  435. #endif
  436. if (!gd)
  437. return;
  438. #ifdef CONFIG_CONSOLE_RECORD
  439. if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
  440. membuff_putbyte((struct membuff *)&gd->console_out, c);
  441. #endif
  442. #ifdef CONFIG_SILENT_CONSOLE
  443. if (gd->flags & GD_FLG_SILENT) {
  444. if (!(gd->flags & GD_FLG_DEVINIT))
  445. pre_console_putc(c);
  446. return;
  447. }
  448. #endif
  449. #ifdef CONFIG_DISABLE_CONSOLE
  450. if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  451. return;
  452. #endif
  453. if (!gd->have_console)
  454. return pre_console_putc(c);
  455. if (gd->flags & GD_FLG_DEVINIT) {
  456. /* Send to the standard output */
  457. fputc(stdout, c);
  458. } else {
  459. /* Send directly to the handler */
  460. pre_console_putc(c);
  461. serial_putc(c);
  462. }
  463. }
  464. void puts(const char *s)
  465. {
  466. #ifdef CONFIG_SANDBOX
  467. /* sandbox can send characters to stdout before it has a console */
  468. if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
  469. os_puts(s);
  470. return;
  471. }
  472. #endif
  473. #ifdef CONFIG_DEBUG_UART
  474. if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
  475. while (*s) {
  476. int ch = *s++;
  477. printch(ch);
  478. }
  479. return;
  480. }
  481. #endif
  482. if (!gd)
  483. return;
  484. #ifdef CONFIG_CONSOLE_RECORD
  485. if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
  486. membuff_put((struct membuff *)&gd->console_out, s, strlen(s));
  487. #endif
  488. #ifdef CONFIG_SILENT_CONSOLE
  489. if (gd->flags & GD_FLG_SILENT) {
  490. if (!(gd->flags & GD_FLG_DEVINIT))
  491. pre_console_puts(s);
  492. return;
  493. }
  494. #endif
  495. #ifdef CONFIG_DISABLE_CONSOLE
  496. if (gd->flags & GD_FLG_DISABLE_CONSOLE)
  497. return;
  498. #endif
  499. if (!gd->have_console)
  500. return pre_console_puts(s);
  501. if (gd->flags & GD_FLG_DEVINIT) {
  502. /* Send to the standard output */
  503. fputs(stdout, s);
  504. } else {
  505. /* Send directly to the handler */
  506. pre_console_puts(s);
  507. serial_puts(s);
  508. }
  509. }
  510. #ifdef CONFIG_CONSOLE_RECORD
  511. int console_record_init(void)
  512. {
  513. int ret;
  514. ret = membuff_new((struct membuff *)&gd->console_out,
  515. CONFIG_CONSOLE_RECORD_OUT_SIZE);
  516. if (ret)
  517. return ret;
  518. ret = membuff_new((struct membuff *)&gd->console_in,
  519. CONFIG_CONSOLE_RECORD_IN_SIZE);
  520. return ret;
  521. }
  522. void console_record_reset(void)
  523. {
  524. membuff_purge((struct membuff *)&gd->console_out);
  525. membuff_purge((struct membuff *)&gd->console_in);
  526. }
  527. void console_record_reset_enable(void)
  528. {
  529. console_record_reset();
  530. gd->flags |= GD_FLG_RECORD;
  531. }
  532. int console_record_readline(char *str, int maxlen)
  533. {
  534. return membuff_readline((struct membuff *)&gd->console_out, str,
  535. maxlen, ' ');
  536. }
  537. int console_record_avail(void)
  538. {
  539. return membuff_avail((struct membuff *)&gd->console_out);
  540. }
  541. #endif
  542. /* test if ctrl-c was pressed */
  543. static int ctrlc_disabled = 0; /* see disable_ctrl() */
  544. static int ctrlc_was_pressed = 0;
  545. int ctrlc(void)
  546. {
  547. if (!ctrlc_disabled && gd->have_console) {
  548. if (tstc()) {
  549. switch (getc()) {
  550. case 0x03: /* ^C - Control C */
  551. ctrlc_was_pressed = 1;
  552. return 1;
  553. default:
  554. break;
  555. }
  556. }
  557. }
  558. return 0;
  559. }
  560. /* Reads user's confirmation.
  561. Returns 1 if user's input is "y", "Y", "yes" or "YES"
  562. */
  563. int confirm_yesno(void)
  564. {
  565. int i;
  566. char str_input[5];
  567. /* Flush input */
  568. while (tstc())
  569. getc();
  570. i = 0;
  571. while (i < sizeof(str_input)) {
  572. str_input[i] = getc();
  573. putc(str_input[i]);
  574. if (str_input[i] == '\r')
  575. break;
  576. i++;
  577. }
  578. putc('\n');
  579. if (strncmp(str_input, "y\r", 2) == 0 ||
  580. strncmp(str_input, "Y\r", 2) == 0 ||
  581. strncmp(str_input, "yes\r", 4) == 0 ||
  582. strncmp(str_input, "YES\r", 4) == 0)
  583. return 1;
  584. return 0;
  585. }
  586. /* pass 1 to disable ctrlc() checking, 0 to enable.
  587. * returns previous state
  588. */
  589. int disable_ctrlc(int disable)
  590. {
  591. int prev = ctrlc_disabled; /* save previous state */
  592. ctrlc_disabled = disable;
  593. return prev;
  594. }
  595. int had_ctrlc (void)
  596. {
  597. return ctrlc_was_pressed;
  598. }
  599. void clear_ctrlc(void)
  600. {
  601. ctrlc_was_pressed = 0;
  602. }
  603. /** U-Boot INIT FUNCTIONS *************************************************/
  604. struct stdio_dev *search_device(int flags, const char *name)
  605. {
  606. struct stdio_dev *dev;
  607. dev = stdio_get_by_name(name);
  608. #ifdef CONFIG_VIDCONSOLE_AS_LCD
  609. if (!dev && !strcmp(name, "lcd"))
  610. dev = stdio_get_by_name("vidconsole");
  611. #endif
  612. if (dev && (dev->flags & flags))
  613. return dev;
  614. return NULL;
  615. }
  616. int console_assign(int file, const char *devname)
  617. {
  618. int flag;
  619. struct stdio_dev *dev;
  620. /* Check for valid file */
  621. switch (file) {
  622. case stdin:
  623. flag = DEV_FLAGS_INPUT;
  624. break;
  625. case stdout:
  626. case stderr:
  627. flag = DEV_FLAGS_OUTPUT;
  628. break;
  629. default:
  630. return -1;
  631. }
  632. /* Check for valid device name */
  633. dev = search_device(flag, devname);
  634. if (dev)
  635. return console_setfile(file, dev);
  636. return -1;
  637. }
  638. /* return true if the 'silent' flag is removed */
  639. static bool console_update_silent(void)
  640. {
  641. #ifdef CONFIG_SILENT_CONSOLE
  642. if (env_get("silent")) {
  643. gd->flags |= GD_FLG_SILENT;
  644. } else {
  645. unsigned long flags = gd->flags;
  646. gd->flags &= ~GD_FLG_SILENT;
  647. return !!(flags & GD_FLG_SILENT);
  648. }
  649. #endif
  650. return false;
  651. }
  652. int console_announce_r(void)
  653. {
  654. #if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
  655. char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
  656. display_options_get_banner(false, buf, sizeof(buf));
  657. console_puts_noserial(stdout, buf);
  658. #endif
  659. return 0;
  660. }
  661. /* Called before relocation - use serial functions */
  662. int console_init_f(void)
  663. {
  664. gd->have_console = 1;
  665. console_update_silent();
  666. print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
  667. return 0;
  668. }
  669. void stdio_print_current_devices(void)
  670. {
  671. /* Print information */
  672. puts("In: ");
  673. if (stdio_devices[stdin] == NULL) {
  674. puts("No input devices available!\n");
  675. } else {
  676. printf ("%s\n", stdio_devices[stdin]->name);
  677. }
  678. puts("Out: ");
  679. if (stdio_devices[stdout] == NULL) {
  680. puts("No output devices available!\n");
  681. } else {
  682. printf ("%s\n", stdio_devices[stdout]->name);
  683. }
  684. puts("Err: ");
  685. if (stdio_devices[stderr] == NULL) {
  686. puts("No error devices available!\n");
  687. } else {
  688. printf ("%s\n", stdio_devices[stderr]->name);
  689. }
  690. }
  691. #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
  692. /* Called after the relocation - use desired console functions */
  693. int console_init_r(void)
  694. {
  695. char *stdinname, *stdoutname, *stderrname;
  696. struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
  697. #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
  698. int i;
  699. #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
  700. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  701. int iomux_err = 0;
  702. #endif
  703. int flushpoint;
  704. /* update silent for env loaded from flash (initr_env) */
  705. if (console_update_silent())
  706. flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
  707. else
  708. flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
  709. /* set default handlers at first */
  710. gd->jt->getc = serial_getc;
  711. gd->jt->tstc = serial_tstc;
  712. gd->jt->putc = serial_putc;
  713. gd->jt->puts = serial_puts;
  714. gd->jt->printf = serial_printf;
  715. /* stdin stdout and stderr are in environment */
  716. /* scan for it */
  717. stdinname = env_get("stdin");
  718. stdoutname = env_get("stdout");
  719. stderrname = env_get("stderr");
  720. if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */
  721. inputdev = search_device(DEV_FLAGS_INPUT, stdinname);
  722. outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
  723. errdev = search_device(DEV_FLAGS_OUTPUT, stderrname);
  724. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  725. iomux_err = iomux_doenv(stdin, stdinname);
  726. iomux_err += iomux_doenv(stdout, stdoutname);
  727. iomux_err += iomux_doenv(stderr, stderrname);
  728. if (!iomux_err)
  729. /* Successful, so skip all the code below. */
  730. goto done;
  731. #endif
  732. }
  733. /* if the devices are overwritten or not found, use default device */
  734. if (inputdev == NULL) {
  735. inputdev = search_device(DEV_FLAGS_INPUT, "serial");
  736. }
  737. if (outputdev == NULL) {
  738. outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
  739. }
  740. if (errdev == NULL) {
  741. errdev = search_device(DEV_FLAGS_OUTPUT, "serial");
  742. }
  743. /* Initializes output console first */
  744. if (outputdev != NULL) {
  745. /* need to set a console if not done above. */
  746. console_doenv(stdout, outputdev);
  747. }
  748. if (errdev != NULL) {
  749. /* need to set a console if not done above. */
  750. console_doenv(stderr, errdev);
  751. }
  752. if (inputdev != NULL) {
  753. /* need to set a console if not done above. */
  754. console_doenv(stdin, inputdev);
  755. }
  756. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  757. done:
  758. #endif
  759. #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
  760. stdio_print_current_devices();
  761. #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
  762. #ifdef CONFIG_VIDCONSOLE_AS_LCD
  763. if (strstr(stdoutname, "lcd"))
  764. printf("Warning: Please change 'lcd' to 'vidconsole' in stdout/stderr environment vars\n");
  765. #endif
  766. #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
  767. /* set the environment variables (will overwrite previous env settings) */
  768. for (i = 0; i < MAX_FILES; i++) {
  769. env_set(stdio_names[i], stdio_devices[i]->name);
  770. }
  771. #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
  772. gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
  773. #if 0
  774. /* If nothing usable installed, use only the initial console */
  775. if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
  776. return 0;
  777. #endif
  778. print_pre_console_buffer(flushpoint);
  779. return 0;
  780. }
  781. #else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
  782. /* Called after the relocation - use desired console functions */
  783. int console_init_r(void)
  784. {
  785. struct stdio_dev *inputdev = NULL, *outputdev = NULL;
  786. int i;
  787. struct list_head *list = stdio_get_list();
  788. struct list_head *pos;
  789. struct stdio_dev *dev;
  790. int flushpoint;
  791. /* update silent for env loaded from flash (initr_env) */
  792. if (console_update_silent())
  793. flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
  794. else
  795. flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
  796. #ifdef CONFIG_SPLASH_SCREEN
  797. /*
  798. * suppress all output if splash screen is enabled and we have
  799. * a bmp to display. We redirect the output from frame buffer
  800. * console to serial console in this case or suppress it if
  801. * "silent" mode was requested.
  802. */
  803. if (env_get("splashimage") != NULL) {
  804. if (!(gd->flags & GD_FLG_SILENT))
  805. outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
  806. }
  807. #endif
  808. /* Scan devices looking for input and output devices */
  809. list_for_each(pos, list) {
  810. dev = list_entry(pos, struct stdio_dev, list);
  811. if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
  812. inputdev = dev;
  813. }
  814. if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
  815. outputdev = dev;
  816. }
  817. if(inputdev && outputdev)
  818. break;
  819. }
  820. /* Initializes output console first */
  821. if (outputdev != NULL) {
  822. console_setfile(stdout, outputdev);
  823. console_setfile(stderr, outputdev);
  824. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  825. console_devices[stdout][0] = outputdev;
  826. console_devices[stderr][0] = outputdev;
  827. #endif
  828. }
  829. /* Initializes input console */
  830. if (inputdev != NULL) {
  831. console_setfile(stdin, inputdev);
  832. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  833. console_devices[stdin][0] = inputdev;
  834. #endif
  835. }
  836. #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
  837. stdio_print_current_devices();
  838. #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
  839. /* Setting environment variables */
  840. for (i = 0; i < MAX_FILES; i++) {
  841. env_set(stdio_names[i], stdio_devices[i]->name);
  842. }
  843. gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
  844. #if 0
  845. /* If nothing usable installed, use only the initial console */
  846. if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
  847. return 0;
  848. #endif
  849. print_pre_console_buffer(flushpoint);
  850. return 0;
  851. }
  852. #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */