efi_console.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * EFI application console interface
  4. *
  5. * Copyright (c) 2016 Alexander Graf
  6. */
  7. #include <common.h>
  8. #include <charset.h>
  9. #include <malloc.h>
  10. #include <time.h>
  11. #include <dm/device.h>
  12. #include <efi_loader.h>
  13. #include <env.h>
  14. #include <stdio_dev.h>
  15. #include <video_console.h>
  16. #define EFI_COUT_MODE_2 2
  17. #define EFI_MAX_COUT_MODE 3
  18. struct cout_mode {
  19. unsigned long columns;
  20. unsigned long rows;
  21. int present;
  22. };
  23. static struct cout_mode efi_cout_modes[] = {
  24. /* EFI Mode 0 is 80x25 and always present */
  25. {
  26. .columns = 80,
  27. .rows = 25,
  28. .present = 1,
  29. },
  30. /* EFI Mode 1 is always 80x50 */
  31. {
  32. .columns = 80,
  33. .rows = 50,
  34. .present = 0,
  35. },
  36. /* Value are unknown until we query the console */
  37. {
  38. .columns = 0,
  39. .rows = 0,
  40. .present = 0,
  41. },
  42. };
  43. const efi_guid_t efi_guid_text_input_ex_protocol =
  44. EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
  45. const efi_guid_t efi_guid_text_input_protocol =
  46. EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
  47. const efi_guid_t efi_guid_text_output_protocol =
  48. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
  49. #define cESC '\x1b'
  50. #define ESC "\x1b"
  51. /* Default to mode 0 */
  52. static struct simple_text_output_mode efi_con_mode = {
  53. .max_mode = 1,
  54. .mode = 0,
  55. .attribute = 0,
  56. .cursor_column = 0,
  57. .cursor_row = 0,
  58. .cursor_visible = 1,
  59. };
  60. static int term_get_char(s32 *c)
  61. {
  62. u64 timeout;
  63. /* Wait up to 100 ms for a character */
  64. timeout = timer_get_us() + 100000;
  65. while (!tstc())
  66. if (timer_get_us() > timeout)
  67. return 1;
  68. *c = getc();
  69. return 0;
  70. }
  71. /**
  72. * Receive and parse a reply from the terminal.
  73. *
  74. * @n: array of return values
  75. * @num: number of return values expected
  76. * @end_char: character indicating end of terminal message
  77. * Return: non-zero indicates error
  78. */
  79. static int term_read_reply(int *n, int num, char end_char)
  80. {
  81. s32 c;
  82. int i = 0;
  83. if (term_get_char(&c) || c != cESC)
  84. return -1;
  85. if (term_get_char(&c) || c != '[')
  86. return -1;
  87. n[0] = 0;
  88. while (1) {
  89. if (!term_get_char(&c)) {
  90. if (c == ';') {
  91. i++;
  92. if (i >= num)
  93. return -1;
  94. n[i] = 0;
  95. continue;
  96. } else if (c == end_char) {
  97. break;
  98. } else if (c > '9' || c < '0') {
  99. return -1;
  100. }
  101. /* Read one more decimal position */
  102. n[i] *= 10;
  103. n[i] += c - '0';
  104. } else {
  105. return -1;
  106. }
  107. }
  108. if (i != num - 1)
  109. return -1;
  110. return 0;
  111. }
  112. /**
  113. * efi_cout_output_string() - write Unicode string to console
  114. *
  115. * This function implements the OutputString service of the simple text output
  116. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  117. * for details.
  118. *
  119. * @this: simple text output protocol
  120. * @string: u16 string
  121. * Return: status code
  122. */
  123. static efi_status_t EFIAPI efi_cout_output_string(
  124. struct efi_simple_text_output_protocol *this,
  125. const efi_string_t string)
  126. {
  127. struct simple_text_output_mode *con = &efi_con_mode;
  128. struct cout_mode *mode = &efi_cout_modes[con->mode];
  129. char *buf, *pos;
  130. u16 *p;
  131. efi_status_t ret = EFI_SUCCESS;
  132. EFI_ENTRY("%p, %p", this, string);
  133. if (!this || !string) {
  134. ret = EFI_INVALID_PARAMETER;
  135. goto out;
  136. }
  137. buf = malloc(utf16_utf8_strlen(string) + 1);
  138. if (!buf) {
  139. ret = EFI_OUT_OF_RESOURCES;
  140. goto out;
  141. }
  142. pos = buf;
  143. utf16_utf8_strcpy(&pos, string);
  144. fputs(stdout, buf);
  145. free(buf);
  146. /*
  147. * Update the cursor position.
  148. *
  149. * The UEFI spec provides advance rules for U+0000, U+0008, U+000A,
  150. * and U000D. All other control characters are ignored. Any non-control
  151. * character increase the column by one.
  152. */
  153. for (p = string; *p; ++p) {
  154. switch (*p) {
  155. case '\b': /* U+0008, backspace */
  156. if (con->cursor_column)
  157. con->cursor_column--;
  158. break;
  159. case '\n': /* U+000A, newline */
  160. con->cursor_column = 0;
  161. con->cursor_row++;
  162. break;
  163. case '\r': /* U+000D, carriage-return */
  164. con->cursor_column = 0;
  165. break;
  166. case 0xd800 ... 0xdbff:
  167. /*
  168. * Ignore high surrogates, we do not want to count a
  169. * Unicode character twice.
  170. */
  171. break;
  172. default:
  173. /* Exclude control codes */
  174. if (*p > 0x1f)
  175. con->cursor_column++;
  176. break;
  177. }
  178. if (con->cursor_column >= mode->columns) {
  179. con->cursor_column = 0;
  180. con->cursor_row++;
  181. }
  182. /*
  183. * When we exceed the row count the terminal will scroll up one
  184. * line. We have to adjust the cursor position.
  185. */
  186. if (con->cursor_row >= mode->rows && con->cursor_row)
  187. con->cursor_row--;
  188. }
  189. out:
  190. return EFI_EXIT(ret);
  191. }
  192. /**
  193. * efi_cout_test_string() - test writing Unicode string to console
  194. *
  195. * This function implements the TestString service of the simple text output
  196. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  197. * for details.
  198. *
  199. * As in OutputString we simply convert UTF-16 to UTF-8 there are no unsupported
  200. * code points and we can always return EFI_SUCCESS.
  201. *
  202. * @this: simple text output protocol
  203. * @string: u16 string
  204. * Return: status code
  205. */
  206. static efi_status_t EFIAPI efi_cout_test_string(
  207. struct efi_simple_text_output_protocol *this,
  208. const efi_string_t string)
  209. {
  210. EFI_ENTRY("%p, %p", this, string);
  211. return EFI_EXIT(EFI_SUCCESS);
  212. }
  213. /**
  214. * cout_mode_matches() - check if mode has given terminal size
  215. *
  216. * @mode: text mode
  217. * @rows: number of rows
  218. * @cols: number of columns
  219. * Return: true if number of rows and columns matches the mode and
  220. * the mode is present
  221. */
  222. static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
  223. {
  224. if (!mode->present)
  225. return false;
  226. return (mode->rows == rows) && (mode->columns == cols);
  227. }
  228. /**
  229. * query_console_serial() - query console size
  230. *
  231. * When using a serial console or the net console we can only devise the
  232. * terminal size by querying the terminal using ECMA-48 control sequences.
  233. *
  234. * @rows: pointer to return number of rows
  235. * @cols: pointer to return number of columns
  236. * Returns: 0 on success
  237. */
  238. static int query_console_serial(int *rows, int *cols)
  239. {
  240. int ret = 0;
  241. int n[2];
  242. /* Empty input buffer */
  243. while (tstc())
  244. getc();
  245. /*
  246. * Not all terminals understand CSI [18t for querying the console size.
  247. * We should adhere to escape sequences documented in the console_codes
  248. * man page and the ECMA-48 standard.
  249. *
  250. * So here we follow a different approach. We position the cursor to the
  251. * bottom right and query its position. Before leaving the function we
  252. * restore the original cursor position.
  253. */
  254. printf(ESC "7" /* Save cursor position */
  255. ESC "[r" /* Set scrolling region to full window */
  256. ESC "[999;999H" /* Move to bottom right corner */
  257. ESC "[6n"); /* Query cursor position */
  258. /* Read {rows,cols} */
  259. if (term_read_reply(n, 2, 'R')) {
  260. ret = 1;
  261. goto out;
  262. }
  263. *cols = n[1];
  264. *rows = n[0];
  265. out:
  266. printf(ESC "8"); /* Restore cursor position */
  267. return ret;
  268. }
  269. /**
  270. * query_console_size() - update the mode table.
  271. *
  272. * By default the only mode available is 80x25. If the console has at least 50
  273. * lines, enable mode 80x50. If we can query the console size and it is neither
  274. * 80x25 nor 80x50, set it as an additional mode.
  275. */
  276. static void query_console_size(void)
  277. {
  278. const char *stdout_name = env_get("stdout");
  279. int rows = 25, cols = 80;
  280. if (stdout_name && !strcmp(stdout_name, "vidconsole") &&
  281. IS_ENABLED(CONFIG_DM_VIDEO)) {
  282. struct stdio_dev *stdout_dev =
  283. stdio_get_by_name("vidconsole");
  284. struct udevice *dev = stdout_dev->priv;
  285. struct vidconsole_priv *priv =
  286. dev_get_uclass_priv(dev);
  287. rows = priv->rows;
  288. cols = priv->cols;
  289. } else if (query_console_serial(&rows, &cols)) {
  290. return;
  291. }
  292. /* Test if we can have Mode 1 */
  293. if (cols >= 80 && rows >= 50) {
  294. efi_cout_modes[1].present = 1;
  295. efi_con_mode.max_mode = 2;
  296. }
  297. /*
  298. * Install our mode as mode 2 if it is different
  299. * than mode 0 or 1 and set it as the currently selected mode
  300. */
  301. if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
  302. !cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
  303. efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
  304. efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
  305. efi_cout_modes[EFI_COUT_MODE_2].present = 1;
  306. efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
  307. efi_con_mode.mode = EFI_COUT_MODE_2;
  308. }
  309. }
  310. /**
  311. * efi_cout_query_mode() - get terminal size for a text mode
  312. *
  313. * This function implements the QueryMode service of the simple text output
  314. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  315. * for details.
  316. *
  317. * @this: simple text output protocol
  318. * @mode_number: mode number to retrieve information on
  319. * @columns: number of columns
  320. * @rows: number of rows
  321. * Return: status code
  322. */
  323. static efi_status_t EFIAPI efi_cout_query_mode(
  324. struct efi_simple_text_output_protocol *this,
  325. unsigned long mode_number, unsigned long *columns,
  326. unsigned long *rows)
  327. {
  328. EFI_ENTRY("%p, %ld, %p, %p", this, mode_number, columns, rows);
  329. if (mode_number >= efi_con_mode.max_mode)
  330. return EFI_EXIT(EFI_UNSUPPORTED);
  331. if (efi_cout_modes[mode_number].present != 1)
  332. return EFI_EXIT(EFI_UNSUPPORTED);
  333. if (columns)
  334. *columns = efi_cout_modes[mode_number].columns;
  335. if (rows)
  336. *rows = efi_cout_modes[mode_number].rows;
  337. return EFI_EXIT(EFI_SUCCESS);
  338. }
  339. static const struct {
  340. unsigned int fg;
  341. unsigned int bg;
  342. } color[] = {
  343. { 30, 40 }, /* 0: black */
  344. { 34, 44 }, /* 1: blue */
  345. { 32, 42 }, /* 2: green */
  346. { 36, 46 }, /* 3: cyan */
  347. { 31, 41 }, /* 4: red */
  348. { 35, 45 }, /* 5: magenta */
  349. { 33, 43 }, /* 6: brown, map to yellow as EDK2 does*/
  350. { 37, 47 }, /* 7: light gray, map to white */
  351. };
  352. /**
  353. * efi_cout_set_attribute() - set fore- and background color
  354. *
  355. * This function implements the SetAttribute service of the simple text output
  356. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  357. * for details.
  358. *
  359. * @this: simple text output protocol
  360. * @attribute: foreground color - bits 0-3, background color - bits 4-6
  361. * Return: status code
  362. */
  363. static efi_status_t EFIAPI efi_cout_set_attribute(
  364. struct efi_simple_text_output_protocol *this,
  365. unsigned long attribute)
  366. {
  367. unsigned int bold = EFI_ATTR_BOLD(attribute);
  368. unsigned int fg = EFI_ATTR_FG(attribute);
  369. unsigned int bg = EFI_ATTR_BG(attribute);
  370. EFI_ENTRY("%p, %lx", this, attribute);
  371. efi_con_mode.attribute = attribute;
  372. if (attribute)
  373. printf(ESC"[%u;%u;%um", bold, color[fg].fg, color[bg].bg);
  374. else
  375. printf(ESC"[0;37;40m");
  376. return EFI_EXIT(EFI_SUCCESS);
  377. }
  378. /**
  379. * efi_cout_clear_screen() - clear screen
  380. *
  381. * This function implements the ClearScreen service of the simple text output
  382. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  383. * for details.
  384. *
  385. * @this: pointer to the protocol instance
  386. * Return: status code
  387. */
  388. static efi_status_t EFIAPI efi_cout_clear_screen(
  389. struct efi_simple_text_output_protocol *this)
  390. {
  391. EFI_ENTRY("%p", this);
  392. /*
  393. * The Linux console wants both a clear and a home command. The video
  394. * uclass does not support <ESC>[H without coordinates, yet.
  395. */
  396. printf(ESC "[2J" ESC "[1;1H");
  397. efi_con_mode.cursor_column = 0;
  398. efi_con_mode.cursor_row = 0;
  399. return EFI_EXIT(EFI_SUCCESS);
  400. }
  401. /**
  402. * efi_cout_clear_set_mode() - set text model
  403. *
  404. * This function implements the SetMode service of the simple text output
  405. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  406. * for details.
  407. *
  408. * @this: pointer to the protocol instance
  409. * @mode_number: number of the text mode to set
  410. * Return: status code
  411. */
  412. static efi_status_t EFIAPI efi_cout_set_mode(
  413. struct efi_simple_text_output_protocol *this,
  414. unsigned long mode_number)
  415. {
  416. EFI_ENTRY("%p, %ld", this, mode_number);
  417. if (mode_number >= efi_con_mode.max_mode)
  418. return EFI_EXIT(EFI_UNSUPPORTED);
  419. if (!efi_cout_modes[mode_number].present)
  420. return EFI_EXIT(EFI_UNSUPPORTED);
  421. efi_con_mode.mode = mode_number;
  422. EFI_CALL(efi_cout_clear_screen(this));
  423. return EFI_EXIT(EFI_SUCCESS);
  424. }
  425. /**
  426. * efi_cout_reset() - reset the terminal
  427. *
  428. * This function implements the Reset service of the simple text output
  429. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  430. * for details.
  431. *
  432. * @this: pointer to the protocol instance
  433. * @extended_verification: if set an extended verification may be executed
  434. * Return: status code
  435. */
  436. static efi_status_t EFIAPI efi_cout_reset(
  437. struct efi_simple_text_output_protocol *this,
  438. char extended_verification)
  439. {
  440. EFI_ENTRY("%p, %d", this, extended_verification);
  441. /* Clear screen */
  442. EFI_CALL(efi_cout_clear_screen(this));
  443. /* Set default colors */
  444. efi_con_mode.attribute = 0x07;
  445. printf(ESC "[0;37;40m");
  446. return EFI_EXIT(EFI_SUCCESS);
  447. }
  448. /**
  449. * efi_cout_set_cursor_position() - reset the terminal
  450. *
  451. * This function implements the SetCursorPosition service of the simple text
  452. * output protocol. See the Unified Extensible Firmware Interface (UEFI)
  453. * specification for details.
  454. *
  455. * @this: pointer to the protocol instance
  456. * @column: column to move to
  457. * @row: row to move to
  458. * Return: status code
  459. */
  460. static efi_status_t EFIAPI efi_cout_set_cursor_position(
  461. struct efi_simple_text_output_protocol *this,
  462. unsigned long column, unsigned long row)
  463. {
  464. efi_status_t ret = EFI_SUCCESS;
  465. struct simple_text_output_mode *con = &efi_con_mode;
  466. struct cout_mode *mode = &efi_cout_modes[con->mode];
  467. EFI_ENTRY("%p, %ld, %ld", this, column, row);
  468. /* Check parameters */
  469. if (!this) {
  470. ret = EFI_INVALID_PARAMETER;
  471. goto out;
  472. }
  473. if (row >= mode->rows || column >= mode->columns) {
  474. ret = EFI_UNSUPPORTED;
  475. goto out;
  476. }
  477. /*
  478. * Set cursor position by sending CSI H.
  479. * EFI origin is [0, 0], terminal origin is [1, 1].
  480. */
  481. printf(ESC "[%d;%dH", (int)row + 1, (int)column + 1);
  482. efi_con_mode.cursor_column = column;
  483. efi_con_mode.cursor_row = row;
  484. out:
  485. return EFI_EXIT(ret);
  486. }
  487. /**
  488. * efi_cout_enable_cursor() - enable the cursor
  489. *
  490. * This function implements the EnableCursor service of the simple text output
  491. * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
  492. * for details.
  493. *
  494. * @this: pointer to the protocol instance
  495. * @enable: if true enable, if false disable the cursor
  496. * Return: status code
  497. */
  498. static efi_status_t EFIAPI efi_cout_enable_cursor(
  499. struct efi_simple_text_output_protocol *this,
  500. bool enable)
  501. {
  502. EFI_ENTRY("%p, %d", this, enable);
  503. printf(ESC"[?25%c", enable ? 'h' : 'l');
  504. efi_con_mode.cursor_visible = !!enable;
  505. return EFI_EXIT(EFI_SUCCESS);
  506. }
  507. struct efi_simple_text_output_protocol efi_con_out = {
  508. .reset = efi_cout_reset,
  509. .output_string = efi_cout_output_string,
  510. .test_string = efi_cout_test_string,
  511. .query_mode = efi_cout_query_mode,
  512. .set_mode = efi_cout_set_mode,
  513. .set_attribute = efi_cout_set_attribute,
  514. .clear_screen = efi_cout_clear_screen,
  515. .set_cursor_position = efi_cout_set_cursor_position,
  516. .enable_cursor = efi_cout_enable_cursor,
  517. .mode = (void*)&efi_con_mode,
  518. };
  519. /**
  520. * struct efi_cin_notify_function - registered console input notify function
  521. *
  522. * @link: link to list
  523. * @key: key to notify
  524. * @function: function to call
  525. */
  526. struct efi_cin_notify_function {
  527. struct list_head link;
  528. struct efi_key_data key;
  529. efi_status_t (EFIAPI *function)
  530. (struct efi_key_data *key_data);
  531. };
  532. static bool key_available;
  533. static struct efi_key_data next_key;
  534. static LIST_HEAD(cin_notify_functions);
  535. /**
  536. * set_shift_mask() - set shift mask
  537. *
  538. * @mod: Xterm shift mask
  539. * @key_state: receives the state of the shift, alt, control, and logo keys
  540. */
  541. void set_shift_mask(int mod, struct efi_key_state *key_state)
  542. {
  543. key_state->key_shift_state = EFI_SHIFT_STATE_VALID;
  544. if (mod) {
  545. --mod;
  546. if (mod & 1)
  547. key_state->key_shift_state |= EFI_LEFT_SHIFT_PRESSED;
  548. if (mod & 2)
  549. key_state->key_shift_state |= EFI_LEFT_ALT_PRESSED;
  550. if (mod & 4)
  551. key_state->key_shift_state |= EFI_LEFT_CONTROL_PRESSED;
  552. if (!mod || (mod & 8))
  553. key_state->key_shift_state |= EFI_LEFT_LOGO_PRESSED;
  554. }
  555. }
  556. /**
  557. * analyze_modifiers() - analyze modifiers (shift, alt, ctrl) for function keys
  558. *
  559. * This gets called when we have already parsed CSI.
  560. *
  561. * @key_state: receives the state of the shift, alt, control, and logo keys
  562. * Return: the unmodified code
  563. */
  564. static int analyze_modifiers(struct efi_key_state *key_state)
  565. {
  566. int c, mod = 0, ret = 0;
  567. c = getc();
  568. if (c != ';') {
  569. ret = c;
  570. if (c == '~')
  571. goto out;
  572. c = getc();
  573. }
  574. for (;;) {
  575. switch (c) {
  576. case '0'...'9':
  577. mod *= 10;
  578. mod += c - '0';
  579. /* fall through */
  580. case ';':
  581. c = getc();
  582. break;
  583. default:
  584. goto out;
  585. }
  586. }
  587. out:
  588. set_shift_mask(mod, key_state);
  589. if (!ret)
  590. ret = c;
  591. return ret;
  592. }
  593. /**
  594. * efi_cin_read_key() - read a key from the console input
  595. *
  596. * @key: - key received
  597. * Return: - status code
  598. */
  599. static efi_status_t efi_cin_read_key(struct efi_key_data *key)
  600. {
  601. struct efi_input_key pressed_key = {
  602. .scan_code = 0,
  603. .unicode_char = 0,
  604. };
  605. s32 ch;
  606. if (console_read_unicode(&ch))
  607. return EFI_NOT_READY;
  608. key->key_state.key_shift_state = EFI_SHIFT_STATE_INVALID;
  609. key->key_state.key_toggle_state = EFI_TOGGLE_STATE_INVALID;
  610. /* We do not support multi-word codes */
  611. if (ch >= 0x10000)
  612. ch = '?';
  613. switch (ch) {
  614. case 0x1b:
  615. /*
  616. * Xterm Control Sequences
  617. * https://www.xfree86.org/4.8.0/ctlseqs.html
  618. */
  619. ch = getc();
  620. switch (ch) {
  621. case cESC: /* ESC */
  622. pressed_key.scan_code = 23;
  623. break;
  624. case 'O': /* F1 - F4, End */
  625. ch = getc();
  626. /* consider modifiers */
  627. if (ch == 'F') { /* End */
  628. pressed_key.scan_code = 6;
  629. break;
  630. } else if (ch < 'P') {
  631. set_shift_mask(ch - '0', &key->key_state);
  632. ch = getc();
  633. }
  634. pressed_key.scan_code = ch - 'P' + 11;
  635. break;
  636. case '[':
  637. ch = getc();
  638. switch (ch) {
  639. case 'A'...'D': /* up, down right, left */
  640. pressed_key.scan_code = ch - 'A' + 1;
  641. break;
  642. case 'F': /* End */
  643. pressed_key.scan_code = 6;
  644. break;
  645. case 'H': /* Home */
  646. pressed_key.scan_code = 5;
  647. break;
  648. case '1':
  649. ch = analyze_modifiers(&key->key_state);
  650. switch (ch) {
  651. case '1'...'5': /* F1 - F5 */
  652. pressed_key.scan_code = ch - '1' + 11;
  653. break;
  654. case '6'...'9': /* F5 - F8 */
  655. pressed_key.scan_code = ch - '6' + 15;
  656. break;
  657. case 'A'...'D': /* up, down right, left */
  658. pressed_key.scan_code = ch - 'A' + 1;
  659. break;
  660. case 'F': /* End */
  661. pressed_key.scan_code = 6;
  662. break;
  663. case 'H': /* Home */
  664. pressed_key.scan_code = 5;
  665. break;
  666. case '~': /* Home */
  667. pressed_key.scan_code = 5;
  668. break;
  669. }
  670. break;
  671. case '2':
  672. ch = analyze_modifiers(&key->key_state);
  673. switch (ch) {
  674. case '0'...'1': /* F9 - F10 */
  675. pressed_key.scan_code = ch - '0' + 19;
  676. break;
  677. case '3'...'4': /* F11 - F12 */
  678. pressed_key.scan_code = ch - '3' + 21;
  679. break;
  680. case '~': /* INS */
  681. pressed_key.scan_code = 7;
  682. break;
  683. }
  684. break;
  685. case '3': /* DEL */
  686. pressed_key.scan_code = 8;
  687. analyze_modifiers(&key->key_state);
  688. break;
  689. case '5': /* PG UP */
  690. pressed_key.scan_code = 9;
  691. analyze_modifiers(&key->key_state);
  692. break;
  693. case '6': /* PG DOWN */
  694. pressed_key.scan_code = 10;
  695. analyze_modifiers(&key->key_state);
  696. break;
  697. } /* [ */
  698. break;
  699. default:
  700. /* ALT key */
  701. set_shift_mask(3, &key->key_state);
  702. }
  703. break;
  704. case 0x7f:
  705. /* Backspace */
  706. ch = 0x08;
  707. }
  708. if (pressed_key.scan_code) {
  709. key->key_state.key_shift_state |= EFI_SHIFT_STATE_VALID;
  710. } else {
  711. pressed_key.unicode_char = ch;
  712. /*
  713. * Assume left control key for control characters typically
  714. * entered using the control key.
  715. */
  716. if (ch >= 0x01 && ch <= 0x1f) {
  717. key->key_state.key_shift_state |=
  718. EFI_SHIFT_STATE_VALID;
  719. switch (ch) {
  720. case 0x01 ... 0x07:
  721. case 0x0b ... 0x0c:
  722. case 0x0e ... 0x1f:
  723. key->key_state.key_shift_state |=
  724. EFI_LEFT_CONTROL_PRESSED;
  725. }
  726. }
  727. }
  728. key->key = pressed_key;
  729. return EFI_SUCCESS;
  730. }
  731. /**
  732. * efi_cin_notify() - notify registered functions
  733. */
  734. static void efi_cin_notify(void)
  735. {
  736. struct efi_cin_notify_function *item;
  737. list_for_each_entry(item, &cin_notify_functions, link) {
  738. bool match = true;
  739. /* We do not support toggle states */
  740. if (item->key.key.unicode_char || item->key.key.scan_code) {
  741. if (item->key.key.unicode_char !=
  742. next_key.key.unicode_char ||
  743. item->key.key.scan_code != next_key.key.scan_code)
  744. match = false;
  745. }
  746. if (item->key.key_state.key_shift_state &&
  747. item->key.key_state.key_shift_state !=
  748. next_key.key_state.key_shift_state)
  749. match = false;
  750. if (match)
  751. /* We don't bother about the return code */
  752. EFI_CALL(item->function(&next_key));
  753. }
  754. }
  755. /**
  756. * efi_cin_check() - check if keyboard input is available
  757. */
  758. static void efi_cin_check(void)
  759. {
  760. efi_status_t ret;
  761. if (key_available) {
  762. efi_signal_event(efi_con_in.wait_for_key);
  763. return;
  764. }
  765. if (tstc()) {
  766. ret = efi_cin_read_key(&next_key);
  767. if (ret == EFI_SUCCESS) {
  768. key_available = true;
  769. /* Notify registered functions */
  770. efi_cin_notify();
  771. /* Queue the wait for key event */
  772. if (key_available)
  773. efi_signal_event(efi_con_in.wait_for_key);
  774. }
  775. }
  776. }
  777. /**
  778. * efi_cin_empty_buffer() - empty input buffer
  779. */
  780. static void efi_cin_empty_buffer(void)
  781. {
  782. while (tstc())
  783. getc();
  784. key_available = false;
  785. }
  786. /**
  787. * efi_cin_reset_ex() - reset console input
  788. *
  789. * @this: - the extended simple text input protocol
  790. * @extended_verification: - extended verification
  791. *
  792. * This function implements the reset service of the
  793. * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
  794. *
  795. * See the Unified Extensible Firmware Interface (UEFI) specification for
  796. * details.
  797. *
  798. * Return: old value of the task priority level
  799. */
  800. static efi_status_t EFIAPI efi_cin_reset_ex(
  801. struct efi_simple_text_input_ex_protocol *this,
  802. bool extended_verification)
  803. {
  804. efi_status_t ret = EFI_SUCCESS;
  805. EFI_ENTRY("%p, %d", this, extended_verification);
  806. /* Check parameters */
  807. if (!this) {
  808. ret = EFI_INVALID_PARAMETER;
  809. goto out;
  810. }
  811. efi_cin_empty_buffer();
  812. out:
  813. return EFI_EXIT(ret);
  814. }
  815. /**
  816. * efi_cin_read_key_stroke_ex() - read key stroke
  817. *
  818. * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
  819. * @key_data: key read from console
  820. * Return: status code
  821. *
  822. * This function implements the ReadKeyStrokeEx service of the
  823. * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
  824. *
  825. * See the Unified Extensible Firmware Interface (UEFI) specification for
  826. * details.
  827. */
  828. static efi_status_t EFIAPI efi_cin_read_key_stroke_ex(
  829. struct efi_simple_text_input_ex_protocol *this,
  830. struct efi_key_data *key_data)
  831. {
  832. efi_status_t ret = EFI_SUCCESS;
  833. EFI_ENTRY("%p, %p", this, key_data);
  834. /* Check parameters */
  835. if (!this || !key_data) {
  836. ret = EFI_INVALID_PARAMETER;
  837. goto out;
  838. }
  839. /* We don't do interrupts, so check for timers cooperatively */
  840. efi_timer_check();
  841. /* Enable console input after ExitBootServices */
  842. efi_cin_check();
  843. if (!key_available) {
  844. ret = EFI_NOT_READY;
  845. goto out;
  846. }
  847. /*
  848. * CTRL+A - CTRL+Z have to be signaled as a - z.
  849. * SHIFT+CTRL+A - SHIFT+CTRL+Z have to be signaled as A - Z.
  850. */
  851. switch (next_key.key.unicode_char) {
  852. case 0x01 ... 0x07:
  853. case 0x0b ... 0x0c:
  854. case 0x0e ... 0x1a:
  855. if (!(next_key.key_state.key_toggle_state &
  856. EFI_CAPS_LOCK_ACTIVE) ^
  857. !(next_key.key_state.key_shift_state &
  858. (EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)))
  859. next_key.key.unicode_char += 0x40;
  860. else
  861. next_key.key.unicode_char += 0x60;
  862. }
  863. *key_data = next_key;
  864. key_available = false;
  865. efi_con_in.wait_for_key->is_signaled = false;
  866. out:
  867. return EFI_EXIT(ret);
  868. }
  869. /**
  870. * efi_cin_set_state() - set toggle key state
  871. *
  872. * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
  873. * @key_toggle_state: pointer to key toggle state
  874. * Return: status code
  875. *
  876. * This function implements the SetState service of the
  877. * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
  878. *
  879. * See the Unified Extensible Firmware Interface (UEFI) specification for
  880. * details.
  881. */
  882. static efi_status_t EFIAPI efi_cin_set_state(
  883. struct efi_simple_text_input_ex_protocol *this,
  884. u8 *key_toggle_state)
  885. {
  886. EFI_ENTRY("%p, %p", this, key_toggle_state);
  887. /*
  888. * U-Boot supports multiple console input sources like serial and
  889. * net console for which a key toggle state cannot be set at all.
  890. *
  891. * According to the UEFI specification it is allowable to not implement
  892. * this service.
  893. */
  894. return EFI_EXIT(EFI_UNSUPPORTED);
  895. }
  896. /**
  897. * efi_cin_register_key_notify() - register key notification function
  898. *
  899. * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
  900. * @key_data: key to be notified
  901. * @key_notify_function: function to be called if the key is pressed
  902. * @notify_handle: handle for unregistering the notification
  903. * Return: status code
  904. *
  905. * This function implements the SetState service of the
  906. * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
  907. *
  908. * See the Unified Extensible Firmware Interface (UEFI) specification for
  909. * details.
  910. */
  911. static efi_status_t EFIAPI efi_cin_register_key_notify(
  912. struct efi_simple_text_input_ex_protocol *this,
  913. struct efi_key_data *key_data,
  914. efi_status_t (EFIAPI *key_notify_function)(
  915. struct efi_key_data *key_data),
  916. void **notify_handle)
  917. {
  918. efi_status_t ret = EFI_SUCCESS;
  919. struct efi_cin_notify_function *notify_function;
  920. EFI_ENTRY("%p, %p, %p, %p",
  921. this, key_data, key_notify_function, notify_handle);
  922. /* Check parameters */
  923. if (!this || !key_data || !key_notify_function || !notify_handle) {
  924. ret = EFI_INVALID_PARAMETER;
  925. goto out;
  926. }
  927. EFI_PRINT("u+%04x, sc %04x, sh %08x, tg %02x\n",
  928. key_data->key.unicode_char,
  929. key_data->key.scan_code,
  930. key_data->key_state.key_shift_state,
  931. key_data->key_state.key_toggle_state);
  932. notify_function = calloc(1, sizeof(struct efi_cin_notify_function));
  933. if (!notify_function) {
  934. ret = EFI_OUT_OF_RESOURCES;
  935. goto out;
  936. }
  937. notify_function->key = *key_data;
  938. notify_function->function = key_notify_function;
  939. list_add_tail(&notify_function->link, &cin_notify_functions);
  940. *notify_handle = notify_function;
  941. out:
  942. return EFI_EXIT(ret);
  943. }
  944. /**
  945. * efi_cin_unregister_key_notify() - unregister key notification function
  946. *
  947. * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
  948. * @notification_handle: handle received when registering
  949. * Return: status code
  950. *
  951. * This function implements the SetState service of the
  952. * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
  953. *
  954. * See the Unified Extensible Firmware Interface (UEFI) specification for
  955. * details.
  956. */
  957. static efi_status_t EFIAPI efi_cin_unregister_key_notify(
  958. struct efi_simple_text_input_ex_protocol *this,
  959. void *notification_handle)
  960. {
  961. efi_status_t ret = EFI_INVALID_PARAMETER;
  962. struct efi_cin_notify_function *item, *notify_function =
  963. notification_handle;
  964. EFI_ENTRY("%p, %p", this, notification_handle);
  965. /* Check parameters */
  966. if (!this || !notification_handle)
  967. goto out;
  968. list_for_each_entry(item, &cin_notify_functions, link) {
  969. if (item == notify_function) {
  970. ret = EFI_SUCCESS;
  971. break;
  972. }
  973. }
  974. if (ret != EFI_SUCCESS)
  975. goto out;
  976. /* Remove the notify function */
  977. list_del(&notify_function->link);
  978. free(notify_function);
  979. out:
  980. return EFI_EXIT(ret);
  981. }
  982. /**
  983. * efi_cin_reset() - drain the input buffer
  984. *
  985. * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
  986. * @extended_verification: allow for exhaustive verification
  987. * Return: status code
  988. *
  989. * This function implements the Reset service of the
  990. * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
  991. *
  992. * See the Unified Extensible Firmware Interface (UEFI) specification for
  993. * details.
  994. */
  995. static efi_status_t EFIAPI efi_cin_reset
  996. (struct efi_simple_text_input_protocol *this,
  997. bool extended_verification)
  998. {
  999. efi_status_t ret = EFI_SUCCESS;
  1000. EFI_ENTRY("%p, %d", this, extended_verification);
  1001. /* Check parameters */
  1002. if (!this) {
  1003. ret = EFI_INVALID_PARAMETER;
  1004. goto out;
  1005. }
  1006. efi_cin_empty_buffer();
  1007. out:
  1008. return EFI_EXIT(ret);
  1009. }
  1010. /**
  1011. * efi_cin_read_key_stroke() - read key stroke
  1012. *
  1013. * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
  1014. * @key: key read from console
  1015. * Return: status code
  1016. *
  1017. * This function implements the ReadKeyStroke service of the
  1018. * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
  1019. *
  1020. * See the Unified Extensible Firmware Interface (UEFI) specification for
  1021. * details.
  1022. */
  1023. static efi_status_t EFIAPI efi_cin_read_key_stroke
  1024. (struct efi_simple_text_input_protocol *this,
  1025. struct efi_input_key *key)
  1026. {
  1027. efi_status_t ret = EFI_SUCCESS;
  1028. EFI_ENTRY("%p, %p", this, key);
  1029. /* Check parameters */
  1030. if (!this || !key) {
  1031. ret = EFI_INVALID_PARAMETER;
  1032. goto out;
  1033. }
  1034. /* We don't do interrupts, so check for timers cooperatively */
  1035. efi_timer_check();
  1036. /* Enable console input after ExitBootServices */
  1037. efi_cin_check();
  1038. if (!key_available) {
  1039. ret = EFI_NOT_READY;
  1040. goto out;
  1041. }
  1042. *key = next_key.key;
  1043. key_available = false;
  1044. efi_con_in.wait_for_key->is_signaled = false;
  1045. out:
  1046. return EFI_EXIT(ret);
  1047. }
  1048. static struct efi_simple_text_input_ex_protocol efi_con_in_ex = {
  1049. .reset = efi_cin_reset_ex,
  1050. .read_key_stroke_ex = efi_cin_read_key_stroke_ex,
  1051. .wait_for_key_ex = NULL,
  1052. .set_state = efi_cin_set_state,
  1053. .register_key_notify = efi_cin_register_key_notify,
  1054. .unregister_key_notify = efi_cin_unregister_key_notify,
  1055. };
  1056. struct efi_simple_text_input_protocol efi_con_in = {
  1057. .reset = efi_cin_reset,
  1058. .read_key_stroke = efi_cin_read_key_stroke,
  1059. .wait_for_key = NULL,
  1060. };
  1061. static struct efi_event *console_timer_event;
  1062. /*
  1063. * efi_console_timer_notify() - notify the console timer event
  1064. *
  1065. * @event: console timer event
  1066. * @context: not used
  1067. */
  1068. static void EFIAPI efi_console_timer_notify(struct efi_event *event,
  1069. void *context)
  1070. {
  1071. EFI_ENTRY("%p, %p", event, context);
  1072. efi_cin_check();
  1073. EFI_EXIT(EFI_SUCCESS);
  1074. }
  1075. /**
  1076. * efi_key_notify() - notify the wait for key event
  1077. *
  1078. * @event: wait for key event
  1079. * @context: not used
  1080. */
  1081. static void EFIAPI efi_key_notify(struct efi_event *event, void *context)
  1082. {
  1083. EFI_ENTRY("%p, %p", event, context);
  1084. efi_cin_check();
  1085. EFI_EXIT(EFI_SUCCESS);
  1086. }
  1087. /**
  1088. * efi_console_register() - install the console protocols
  1089. *
  1090. * This function is called from do_bootefi_exec().
  1091. *
  1092. * Return: status code
  1093. */
  1094. efi_status_t efi_console_register(void)
  1095. {
  1096. efi_status_t r;
  1097. efi_handle_t console_output_handle;
  1098. efi_handle_t console_input_handle;
  1099. /* Set up mode information */
  1100. query_console_size();
  1101. /* Create handles */
  1102. r = efi_create_handle(&console_output_handle);
  1103. if (r != EFI_SUCCESS)
  1104. goto out_of_memory;
  1105. r = efi_add_protocol(console_output_handle,
  1106. &efi_guid_text_output_protocol, &efi_con_out);
  1107. if (r != EFI_SUCCESS)
  1108. goto out_of_memory;
  1109. systab.con_out_handle = console_output_handle;
  1110. systab.stderr_handle = console_output_handle;
  1111. r = efi_create_handle(&console_input_handle);
  1112. if (r != EFI_SUCCESS)
  1113. goto out_of_memory;
  1114. r = efi_add_protocol(console_input_handle,
  1115. &efi_guid_text_input_protocol, &efi_con_in);
  1116. if (r != EFI_SUCCESS)
  1117. goto out_of_memory;
  1118. systab.con_in_handle = console_input_handle;
  1119. r = efi_add_protocol(console_input_handle,
  1120. &efi_guid_text_input_ex_protocol, &efi_con_in_ex);
  1121. if (r != EFI_SUCCESS)
  1122. goto out_of_memory;
  1123. /* Create console events */
  1124. r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_key_notify,
  1125. NULL, NULL, &efi_con_in.wait_for_key);
  1126. if (r != EFI_SUCCESS) {
  1127. printf("ERROR: Failed to register WaitForKey event\n");
  1128. return r;
  1129. }
  1130. efi_con_in_ex.wait_for_key_ex = efi_con_in.wait_for_key;
  1131. r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
  1132. efi_console_timer_notify, NULL, NULL,
  1133. &console_timer_event);
  1134. if (r != EFI_SUCCESS) {
  1135. printf("ERROR: Failed to register console event\n");
  1136. return r;
  1137. }
  1138. /* 5000 ns cycle is sufficient for 2 MBaud */
  1139. r = efi_set_timer(console_timer_event, EFI_TIMER_PERIODIC, 50);
  1140. if (r != EFI_SUCCESS)
  1141. printf("ERROR: Failed to set console timer\n");
  1142. return r;
  1143. out_of_memory:
  1144. printf("ERROR: Out of memory\n");
  1145. return r;
  1146. }