console.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112
  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. int console_in_puts(const char *str)
  638. {
  639. return membuff_put((struct membuff *)&gd->console_in, str, strlen(str));
  640. }
  641. #endif
  642. /* test if ctrl-c was pressed */
  643. static int ctrlc_disabled = 0; /* see disable_ctrl() */
  644. static int ctrlc_was_pressed = 0;
  645. int ctrlc(void)
  646. {
  647. if (!ctrlc_disabled && gd->have_console) {
  648. if (tstc()) {
  649. switch (getchar()) {
  650. case 0x03: /* ^C - Control C */
  651. ctrlc_was_pressed = 1;
  652. return 1;
  653. default:
  654. break;
  655. }
  656. }
  657. }
  658. return 0;
  659. }
  660. /* Reads user's confirmation.
  661. Returns 1 if user's input is "y", "Y", "yes" or "YES"
  662. */
  663. int confirm_yesno(void)
  664. {
  665. int i;
  666. char str_input[5];
  667. /* Flush input */
  668. while (tstc())
  669. getchar();
  670. i = 0;
  671. while (i < sizeof(str_input)) {
  672. str_input[i] = getchar();
  673. putc(str_input[i]);
  674. if (str_input[i] == '\r')
  675. break;
  676. i++;
  677. }
  678. putc('\n');
  679. if (strncmp(str_input, "y\r", 2) == 0 ||
  680. strncmp(str_input, "Y\r", 2) == 0 ||
  681. strncmp(str_input, "yes\r", 4) == 0 ||
  682. strncmp(str_input, "YES\r", 4) == 0)
  683. return 1;
  684. return 0;
  685. }
  686. /* pass 1 to disable ctrlc() checking, 0 to enable.
  687. * returns previous state
  688. */
  689. int disable_ctrlc(int disable)
  690. {
  691. int prev = ctrlc_disabled; /* save previous state */
  692. ctrlc_disabled = disable;
  693. return prev;
  694. }
  695. int had_ctrlc (void)
  696. {
  697. return ctrlc_was_pressed;
  698. }
  699. void clear_ctrlc(void)
  700. {
  701. ctrlc_was_pressed = 0;
  702. }
  703. /** U-Boot INIT FUNCTIONS *************************************************/
  704. struct stdio_dev *console_search_dev(int flags, const char *name)
  705. {
  706. struct stdio_dev *dev;
  707. dev = stdio_get_by_name(name);
  708. #ifdef CONFIG_VIDCONSOLE_AS_LCD
  709. if (!dev && !strcmp(name, CONFIG_VIDCONSOLE_AS_NAME))
  710. dev = stdio_get_by_name("vidconsole");
  711. #endif
  712. if (dev && (dev->flags & flags))
  713. return dev;
  714. return NULL;
  715. }
  716. int console_assign(int file, const char *devname)
  717. {
  718. int flag;
  719. struct stdio_dev *dev;
  720. /* Check for valid file */
  721. flag = stdio_file_to_flags(file);
  722. if (flag < 0)
  723. return flag;
  724. /* Check for valid device name */
  725. dev = console_search_dev(flag, devname);
  726. if (dev)
  727. return console_setfile(file, dev);
  728. return -1;
  729. }
  730. /* return true if the 'silent' flag is removed */
  731. static bool console_update_silent(void)
  732. {
  733. unsigned long flags = gd->flags;
  734. if (!IS_ENABLED(CONFIG_SILENT_CONSOLE))
  735. return false;
  736. if (env_get("silent")) {
  737. gd->flags |= GD_FLG_SILENT;
  738. return false;
  739. }
  740. gd->flags &= ~GD_FLG_SILENT;
  741. return !!(flags & GD_FLG_SILENT);
  742. }
  743. int console_announce_r(void)
  744. {
  745. #if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
  746. char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
  747. display_options_get_banner(false, buf, sizeof(buf));
  748. console_puts_select(stdout, false, buf);
  749. #endif
  750. return 0;
  751. }
  752. /* Called before relocation - use serial functions */
  753. int console_init_f(void)
  754. {
  755. gd->have_console = 1;
  756. console_update_silent();
  757. print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
  758. return 0;
  759. }
  760. void stdio_print_current_devices(void)
  761. {
  762. /* Print information */
  763. puts("In: ");
  764. if (stdio_devices[stdin] == NULL) {
  765. puts("No input devices available!\n");
  766. } else {
  767. printf ("%s\n", stdio_devices[stdin]->name);
  768. }
  769. puts("Out: ");
  770. if (stdio_devices[stdout] == NULL) {
  771. puts("No output devices available!\n");
  772. } else {
  773. printf ("%s\n", stdio_devices[stdout]->name);
  774. }
  775. puts("Err: ");
  776. if (stdio_devices[stderr] == NULL) {
  777. puts("No error devices available!\n");
  778. } else {
  779. printf ("%s\n", stdio_devices[stderr]->name);
  780. }
  781. }
  782. #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
  783. /* Called after the relocation - use desired console functions */
  784. int console_init_r(void)
  785. {
  786. char *stdinname, *stdoutname, *stderrname;
  787. struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
  788. int i;
  789. int iomux_err = 0;
  790. int flushpoint;
  791. /* update silent for env loaded from flash (initr_env) */
  792. if (console_update_silent())
  793. flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
  794. else
  795. flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
  796. /* set default handlers at first */
  797. gd->jt->getc = serial_getc;
  798. gd->jt->tstc = serial_tstc;
  799. gd->jt->putc = serial_putc;
  800. gd->jt->puts = serial_puts;
  801. gd->jt->printf = serial_printf;
  802. /* stdin stdout and stderr are in environment */
  803. /* scan for it */
  804. stdinname = env_get("stdin");
  805. stdoutname = env_get("stdout");
  806. stderrname = env_get("stderr");
  807. if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */
  808. inputdev = console_search_dev(DEV_FLAGS_INPUT, stdinname);
  809. outputdev = console_search_dev(DEV_FLAGS_OUTPUT, stdoutname);
  810. errdev = console_search_dev(DEV_FLAGS_OUTPUT, stderrname);
  811. if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
  812. iomux_err = iomux_doenv(stdin, stdinname);
  813. iomux_err += iomux_doenv(stdout, stdoutname);
  814. iomux_err += iomux_doenv(stderr, stderrname);
  815. if (!iomux_err)
  816. /* Successful, so skip all the code below. */
  817. goto done;
  818. }
  819. }
  820. /* if the devices are overwritten or not found, use default device */
  821. if (inputdev == NULL) {
  822. inputdev = console_search_dev(DEV_FLAGS_INPUT, "serial");
  823. }
  824. if (outputdev == NULL) {
  825. outputdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial");
  826. }
  827. if (errdev == NULL) {
  828. errdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial");
  829. }
  830. /* Initializes output console first */
  831. if (outputdev != NULL) {
  832. /* need to set a console if not done above. */
  833. console_doenv(stdout, outputdev);
  834. }
  835. if (errdev != NULL) {
  836. /* need to set a console if not done above. */
  837. console_doenv(stderr, errdev);
  838. }
  839. if (inputdev != NULL) {
  840. /* need to set a console if not done above. */
  841. console_doenv(stdin, inputdev);
  842. }
  843. done:
  844. if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
  845. stdio_print_current_devices();
  846. #ifdef CONFIG_VIDCONSOLE_AS_LCD
  847. if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_NAME))
  848. printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n",
  849. CONFIG_VIDCONSOLE_AS_NAME);
  850. #endif
  851. if (IS_ENABLED(CONFIG_SYS_CONSOLE_ENV_OVERWRITE)) {
  852. /* set the environment variables (will overwrite previous env settings) */
  853. for (i = 0; i < MAX_FILES; i++)
  854. env_set(stdio_names[i], stdio_devices[i]->name);
  855. }
  856. gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
  857. print_pre_console_buffer(flushpoint);
  858. return 0;
  859. }
  860. #else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
  861. /* Called after the relocation - use desired console functions */
  862. int console_init_r(void)
  863. {
  864. struct stdio_dev *inputdev = NULL, *outputdev = NULL;
  865. int i;
  866. struct list_head *list = stdio_get_list();
  867. struct list_head *pos;
  868. struct stdio_dev *dev;
  869. int flushpoint;
  870. /* update silent for env loaded from flash (initr_env) */
  871. if (console_update_silent())
  872. flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
  873. else
  874. flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
  875. /*
  876. * suppress all output if splash screen is enabled and we have
  877. * a bmp to display. We redirect the output from frame buffer
  878. * console to serial console in this case or suppress it if
  879. * "silent" mode was requested.
  880. */
  881. if (IS_ENABLED(CONFIG_SPLASH_SCREEN) && env_get("splashimage")) {
  882. if (!(gd->flags & GD_FLG_SILENT))
  883. outputdev = console_search_dev (DEV_FLAGS_OUTPUT, "serial");
  884. }
  885. /* Scan devices looking for input and output devices */
  886. list_for_each(pos, list) {
  887. dev = list_entry(pos, struct stdio_dev, list);
  888. if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
  889. inputdev = dev;
  890. }
  891. if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
  892. outputdev = dev;
  893. }
  894. if(inputdev && outputdev)
  895. break;
  896. }
  897. /* Initializes output console first */
  898. if (outputdev != NULL) {
  899. console_setfile_and_devices(stdout, outputdev);
  900. console_setfile_and_devices(stderr, outputdev);
  901. }
  902. /* Initializes input console */
  903. if (inputdev != NULL)
  904. console_setfile_and_devices(stdin, inputdev);
  905. if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
  906. stdio_print_current_devices();
  907. /* Setting environment variables */
  908. for (i = 0; i < MAX_FILES; i++) {
  909. env_set(stdio_names[i], stdio_devices[i]->name);
  910. }
  911. gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
  912. print_pre_console_buffer(flushpoint);
  913. return 0;
  914. }
  915. #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */