console.c 22 KB

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