Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110748862
D4797.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D4797.id.diff
View Options
Index: head/sys/boot/efi/libefi/Makefile
===================================================================
--- head/sys/boot/efi/libefi/Makefile
+++ head/sys/boot/efi/libefi/Makefile
@@ -21,5 +21,6 @@
# Handle FreeBSD specific %b and %D printf format specifiers
CFLAGS+= ${FORMAT_EXTENSIONS}
+CFLAGS+= -DTERM_EMU
.include <bsd.lib.mk>
Index: head/sys/boot/efi/libefi/efi_console.c
===================================================================
--- head/sys/boot/efi/libefi/efi_console.c
+++ head/sys/boot/efi/libefi/efi_console.c
@@ -35,6 +35,69 @@
static SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
static SIMPLE_INPUT_INTERFACE *conin;
+#ifdef TERM_EMU
+#define DEFAULT_FGCOLOR EFI_LIGHTGRAY
+#define DEFAULT_BGCOLOR EFI_BLACK
+
+#define MAXARGS 8
+static int args[MAXARGS], argc;
+static int fg_c, bg_c, curx, cury;
+static int esc;
+
+void get_pos(int *x, int *y);
+void curs_move(int *_x, int *_y, int x, int y);
+static void CL(int);
+#endif
+
+static void efi_cons_probe(struct console *);
+static int efi_cons_init(int);
+void efi_cons_putchar(int);
+int efi_cons_getchar(void);
+void efi_cons_efiputchar(int);
+int efi_cons_poll(void);
+
+struct console efi_console = {
+ "efi",
+ "EFI console",
+ 0,
+ efi_cons_probe,
+ efi_cons_init,
+ efi_cons_putchar,
+ efi_cons_getchar,
+ efi_cons_poll
+};
+
+#ifdef TERM_EMU
+
+/* Get cursor position. */
+void
+get_pos(int *x, int *y)
+{
+ *x = conout->Mode->CursorColumn;
+ *y = conout->Mode->CursorRow;
+}
+
+/* Move cursor to x rows and y cols (0-based). */
+void
+curs_move(int *_x, int *_y, int x, int y)
+{
+ conout->SetCursorPosition(conout, x, y);
+ if (_x != NULL)
+ *_x = conout->Mode->CursorColumn;
+ if (_y != NULL)
+ *_y = conout->Mode->CursorRow;
+}
+
+/* Clear internal state of the terminal emulation code. */
+void
+end_term(void)
+{
+ esc = 0;
+ argc = -1;
+}
+
+#endif
+
static void
efi_cons_probe(struct console *cp)
{
@@ -46,22 +109,314 @@
static int
efi_cons_init(int arg)
{
- conout->SetAttribute(conout, EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK));
+ conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
+ DEFAULT_BGCOLOR));
+#ifdef TERM_EMU
+ end_term();
+ get_pos(&curx, &cury);
+ curs_move(&curx, &cury, curx, cury);
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+#endif
+ conout->EnableCursor(conout, TRUE);
return 0;
}
+static void
+efi_cons_rawputchar(int c)
+{
+ int i;
+ UINTN x, y;
+ conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
+
+ if (c == '\t')
+ /* XXX lame tab expansion */
+ for (i = 0; i < 8; i++)
+ efi_cons_rawputchar(' ');
+ else {
+#ifndef TERM_EMU
+ if (c == '\n')
+ efi_cons_efiputchar('\r');
+ else
+ efi_cons_efiputchar(c);
+#else
+ switch (c) {
+ case '\r':
+ curx = 0;
+ curs_move(&curx, &cury, curx, cury);
+ return;
+ case '\n':
+ cury++;
+ if (cury >= y) {
+ efi_cons_efiputchar('\n');
+ cury--;
+ } else
+ curs_move(&curx, &cury, curx, cury);
+ return;
+ case '\b':
+ if (curx > 0) {
+ curx--;
+ curs_move(&curx, &cury, curx, cury);
+ }
+ return;
+ default:
+ efi_cons_efiputchar(c);
+ curx++;
+ if (curx > x-1) {
+ curx = 0;
+ cury++;
+ }
+ if (cury > y-1) {
+ curx = 0;
+ cury--;
+ }
+ }
+ curs_move(&curx, &cury, curx, cury);
+#endif
+ }
+}
+
+/* Gracefully exit ESC-sequence processing in case of misunderstanding. */
+static void
+bail_out(int c)
+{
+ char buf[16], *ch;
+ int i;
+
+ if (esc) {
+ efi_cons_rawputchar('\033');
+ if (esc != '\033')
+ efi_cons_rawputchar(esc);
+ for (i = 0; i <= argc; ++i) {
+ sprintf(buf, "%d", args[i]);
+ ch = buf;
+ while (*ch)
+ efi_cons_rawputchar(*ch++);
+ }
+ }
+ efi_cons_rawputchar(c);
+ end_term();
+}
+
+/* Clear display from current position to end of screen. */
+static void
+CD(void) {
+ int i;
+ UINTN x, y;
+
+ get_pos(&curx, &cury);
+ if (curx == 0 && cury == 0) {
+ conout->ClearScreen(conout);
+ end_term();
+ return;
+ }
+
+ conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
+ CL(0); /* clear current line from cursor to end */
+ for (i = cury + 1; i < y-1; i++) {
+ curs_move(NULL, NULL, 0, i);
+ CL(0);
+ }
+ curs_move(NULL, NULL, curx, cury);
+ end_term();
+}
+
+/*
+ * Absolute cursor move to args[0] rows and args[1] columns
+ * (the coordinates are 1-based).
+ */
+static void
+CM(void)
+{
+ if (args[0] > 0)
+ args[0]--;
+ if (args[1] > 0)
+ args[1]--;
+ curs_move(&curx, &cury, args[1], args[0]);
+ end_term();
+}
+
+/* Home cursor (left top corner), also called from mode command. */
void
-efi_cons_putchar(int c)
+HO(void)
{
- CHAR16 buf[2];
+ argc = 1;
+ args[0] = args[1] = 1;
+ CM();
+}
- if (c == '\n')
- efi_cons_putchar('\r');
+/* Clear line from current position to end of line */
+static void
+CL(int direction)
+{
+ int i, len;
+ UINTN x, y;
+ CHAR16 *line;
+
+ conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
+ switch (direction) {
+ case 0: /* from cursor to end */
+ len = x - curx + 1;
+ break;
+ case 1: /* from beginning to cursor */
+ len = curx;
+ break;
+ case 2: /* entire line */
+ len = x;
+ break;
+ }
- buf[0] = c;
- buf[1] = 0;
+ if (cury == y - 1)
+ len--;
- conout->OutputString(conout, buf);
+ line = malloc(len * sizeof (CHAR16));
+ if (line == NULL) {
+ printf("out of memory\n");
+ return;
+ }
+ for (i = 0; i < len; i++)
+ line[i] = ' ';
+ line[len-1] = 0;
+
+ if (direction != 0)
+ curs_move(NULL, NULL, 0, cury);
+
+ conout->OutputString(conout, line);
+ /* restore cursor position */
+ curs_move(NULL, NULL, curx, cury);
+ free(line);
+ end_term();
+}
+
+static void
+get_arg(int c)
+{
+ if (argc < 0)
+ argc = 0;
+ args[argc] *= 10;
+ args[argc] += c - '0';
+}
+
+/* Emulate basic capabilities of cons25 terminal */
+static void
+efi_term_emu(int c)
+{
+ static int ansi_col[] = {
+ 0, 4, 2, 6, 1, 5, 3, 7
+ };
+ int t, i;
+
+ switch (esc) {
+ case 0:
+ switch (c) {
+ case '\033':
+ esc = c;
+ break;
+ default:
+ efi_cons_rawputchar(c);
+ break;
+ }
+ break;
+ case '\033':
+ switch (c) {
+ case '[':
+ esc = c;
+ args[0] = 0;
+ argc = -1;
+ break;
+ default:
+ bail_out(c);
+ break;
+ }
+ break;
+ case '[':
+ switch (c) {
+ case ';':
+ if (argc < 0)
+ argc = 0;
+ else if (argc + 1 >= MAXARGS)
+ bail_out(c);
+ else
+ args[++argc] = 0;
+ break;
+ case 'H': /* ho = \E[H */
+ if (argc < 0)
+ HO();
+ else if (argc == 1)
+ CM();
+ else
+ bail_out(c);
+ break;
+ case 'J': /* cd = \E[J */
+ if (argc < 0)
+ CD();
+ else
+ bail_out(c);
+ break;
+ case 'm':
+ if (argc < 0) {
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ }
+ for (i = 0; i <= argc; ++i) {
+ switch (args[i]) {
+ case 0: /* back to normal */
+ fg_c = DEFAULT_FGCOLOR;
+ bg_c = DEFAULT_BGCOLOR;
+ break;
+ case 1: /* bold */
+ fg_c |= 0x8;
+ break;
+ case 4: /* underline */
+ case 5: /* blink */
+ bg_c |= 0x8;
+ break;
+ case 7: /* reverse */
+ t = fg_c;
+ fg_c = bg_c;
+ bg_c = t;
+ break;
+ case 30: case 31: case 32: case 33:
+ case 34: case 35: case 36: case 37:
+ fg_c = ansi_col[args[i] - 30];
+ break;
+ case 39: /* normal */
+ fg_c = DEFAULT_FGCOLOR;
+ break;
+ case 40: case 41: case 42: case 43:
+ case 44: case 45: case 46: case 47:
+ bg_c = ansi_col[args[i] - 40];
+ break;
+ case 49: /* normal */
+ bg_c = DEFAULT_BGCOLOR;
+ break;
+ }
+ }
+ conout->SetAttribute(conout, EFI_TEXT_ATTR(fg_c, bg_c));
+ end_term();
+ break;
+ default:
+ if (isdigit(c))
+ get_arg(c);
+ else
+ bail_out(c);
+ break;
+ }
+ break;
+ default:
+ bail_out(c);
+ break;
+ }
+}
+
+void
+efi_cons_putchar(int c)
+{
+#ifdef TERM_EMU
+ efi_term_emu(c);
+#else
+ efi_cons_rawputchar(c);
+#endif
}
int
@@ -77,6 +432,12 @@
BS->WaitForEvent(1, &conin->WaitForKey, &junk);
status = conin->ReadKeyStroke(conin, &key);
}
+ switch (key.ScanCode) {
+ case 0x17: /* ESC */
+ return (0x1b); /* esc */
+ }
+
+ /* this can return */
return (key.UnicodeChar);
}
@@ -87,13 +448,36 @@
return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
}
-struct console efi_console = {
- "efi",
- "EFI console",
- 0,
- efi_cons_probe,
- efi_cons_init,
- efi_cons_putchar,
- efi_cons_getchar,
- efi_cons_poll
-};
+/* Plain direct access to EFI OutputString(). */
+void
+efi_cons_efiputchar(int c)
+{
+ CHAR16 buf[2];
+
+ /*
+ * translate box chars to unicode
+ */
+ switch (c) {
+ /* single frame */
+ case 0xb3: buf[0] = BOXDRAW_VERTICAL; break;
+ case 0xbf: buf[0] = BOXDRAW_DOWN_LEFT; break;
+ case 0xc0: buf[0] = BOXDRAW_UP_RIGHT; break;
+ case 0xc4: buf[0] = BOXDRAW_HORIZONTAL; break;
+ case 0xda: buf[0] = BOXDRAW_DOWN_RIGHT; break;
+ case 0xd9: buf[0] = BOXDRAW_UP_LEFT; break;
+
+ /* double frame */
+ case 0xba: buf[0] = BOXDRAW_DOUBLE_VERTICAL; break;
+ case 0xbb: buf[0] = BOXDRAW_DOUBLE_DOWN_LEFT; break;
+ case 0xbc: buf[0] = BOXDRAW_DOUBLE_UP_LEFT; break;
+ case 0xc8: buf[0] = BOXDRAW_DOUBLE_UP_RIGHT; break;
+ case 0xc9: buf[0] = BOXDRAW_DOUBLE_DOWN_RIGHT; break;
+ case 0xcd: buf[0] = BOXDRAW_DOUBLE_HORIZONTAL; break;
+
+ default:
+ buf[0] = c;
+ }
+ buf[1] = 0; /* terminate string */
+
+ conout->OutputString(conout, buf);
+}
Index: head/sys/boot/efi/loader/main.c
===================================================================
--- head/sys/boot/efi/loader/main.c
+++ head/sys/boot/efi/loader/main.c
@@ -334,6 +334,7 @@
char rowenv[8];
EFI_STATUS status;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+ extern void HO(void);
conout = ST->ConOut;
@@ -355,7 +356,7 @@
}
sprintf(rowenv, "%u", (unsigned)rows);
setenv("LINES", rowenv, 1);
-
+ HO(); /* set cursor */
return (CMD_OK);
}
Index: head/sys/boot/ficl/amd64/sysdep.c
===================================================================
--- head/sys/boot/ficl/amd64/sysdep.c
+++ head/sys/boot/ficl/amd64/sysdep.c
@@ -55,7 +55,7 @@
IGNORE(pVM);
while(*msg != 0)
- putchar(*(msg++));
+ putchar((unsigned char)*(msg++));
if (fNewline)
putchar('\n');
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 23, 2:45 PM (5 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16774125
Default Alt Text
D4797.id.diff (9 KB)
Attached To
Mode
D4797: add beastie support for loader.efi
Attached
Detach File
Event Timeline
Log In to Comment