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