console.c 24 KB

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