[U-Boot] [PATCH 1/1] efi_loader: query serial console size reliably

Heinrich Schuchardt xypron.glpk at gmx.de
Sat Sep 15 21:52:07 UTC 2018


Not all terminals understand CSI [18t for querying the console size.
We should adhere to escape sequences documented in the console_codes
manpage and the ECMA-48 standard.

So here we follow a different approach. We position the cursor to the
bottom right and query its position. Before leaving the function we
restore the original cursor position.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 lib/efi_loader/efi_console.c | 50 ++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index b487288785..1c9899b121 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -177,32 +177,56 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
 	return (mode->rows == rows) && (mode->columns == cols);
 }
 
+/**
+ * query_console_serial() - query console size
+ *
+ * @rows	pointer to return number of rows
+ * @columns	pointer to return number of columns
+ * Returns	0 on success
+ */
 static int query_console_serial(int *rows, int *cols)
 {
-	/* Ask the terminal about its size */
-	int n[3];
+	int ret = 0;
+	int n[2];
 	u64 timeout;
 
 	/* Empty input buffer */
 	while (tstc())
 		getc();
 
-	printf(ESC"[18t");
+	/*
+	 * Not all terminals understand CSI [18t for querying the console size.
+	 * We should adhere to escape sequences documented in the console_codes
+	 * manpage and the ECMA-48 standard.
+	 *
+	 * So here we follow a different approach. We position the cursor to the
+	 * bottom right and query its position. Before leaving the function we
+	 * restore the original cursor position.
+	 */
+	printf(ESC "7"		/* Save cursor position */
+	       ESC "[r"		/* Set scrolling region to full window */
+	       ESC "[999;999H"	/* Move to bottom right corner */
+	       ESC "[6n");	/* Query cursor position */
 
-	/* Check if we have a terminal that understands */
+	/* Allow up to one second for a response */
 	timeout = timer_get_us() + 1000000;
 	while (!tstc())
-		if (timer_get_us() > timeout)
-			return -1;
-
-	/* Read {depth,rows,cols} */
-	if (term_read_reply(n, 3, 't'))
-		return -1;
+		if (timer_get_us() > timeout) {
+			ret = -1;
+			goto out;
+		}
 
-	*cols = n[2];
-	*rows = n[1];
+	/* Read {rows,cols} */
+	if (term_read_reply(n, 2, 'R')) {
+		ret = 1;
+		goto out;
+	}
 
-	return 0;
+	*cols = n[1];
+	*rows = n[0];
+out:
+	printf(ESC "8");	/* Restore cursor position */
+	return ret;
 }
 
 /*
-- 
2.18.0



More information about the U-Boot mailing list