gnuboot-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 03/20] GRUB: Force scancode set 2 with translation


From: Leah Rowe
Subject: [PATCH 03/20] GRUB: Force scancode set 2 with translation
Date: Sun, 14 Jan 2024 15:55:20 +0000

From: Leah Rowe <leah@libreboot.org>

Although GNU Boot does not yet support the Dell Latitude E6400,
its MEC5035 EC firmware emulates a PS/2 controller and it has
a bug where it always outputs scancode set 1, regardless of how
the keyboard controller is configured.

Without this patch, GRUB sets the keyboard controller to scancode
set 2 *without* translation, which the keyboard controller reports
is working (when it isn't).

With this patch, GRUB behaves in the same way as SeaBIOS and the
kernel, Linux. Without this patch, the keyboard input is completely
messed up in the GRUB payload on Dell Latitude E6400.

Signed-off-by: Leah Rowe <leah@libreboot.org>
---
 ...-coreboot-force-scancodes2-translate.patch | 107 ++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 
resources/grub/patches/0010-at_keyboard-coreboot-force-scancodes2-translate.patch

diff --git 
a/resources/grub/patches/0010-at_keyboard-coreboot-force-scancodes2-translate.patch
 
b/resources/grub/patches/0010-at_keyboard-coreboot-force-scancodes2-translate.patch
new file mode 100644
index 0000000..21e8630
--- /dev/null
+++ 
b/resources/grub/patches/0010-at_keyboard-coreboot-force-scancodes2-translate.patch
@@ -0,0 +1,107 @@
+From 96c0bbe5d406b616360a7fce7cee67d7692c0d6d Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Mon, 30 Oct 2023 22:19:21 +0000
+Subject: [PATCH 1/1] at_keyboard coreboot: force scancodes2+translate
+
+Scan code set 2 with translation should be assumed in
+every case, as the default starting position.
+
+However, GRUB is trying to detect and use other modes
+such as set 2 without translation, or set 1 without
+translation from set 2; it also detects no-mode and
+assumes mode 1, on really old keyboards.
+
+The current behaviour has been retained, for everything
+except GRUB_MACHINE_COREBOOT; for the latter, scan code
+set 2 with translation is hardcoded, and forced in code.
+
+This is required to make keyboard initialisation work on
+the MEC5035 EC used by the Dell Latitude E6400, when
+running GRUB as a coreboot payload on that laptop. The
+EC reports scancode set 2 with translation when probed,
+but actually only outputs scancode set 1.
+
+Since GRUB is attempting to use it without translation,
+and since the machine reports set 2 with translation,
+but only ever outputs set 1 scancodes, this results in
+wrong keypresses for every key.
+
+This fix fixed that, by forcing set 2 with translation,
+treating it as set 1, but only on coreboot. This is the
+same behaviour used in GNU+Linux systems and SeaBIOS.
+With this change, GRUB keyboard initialisation now works
+just fine on those machines.
+
+This has *also* been tested on other coreboot machines
+running GRUB; several HP EliteBooks, ThinkPads and
+Dell Precision T1650. All seems to work just fine.
+
+Signed-off-by: Leah Rowe <leah@libreboot.org>
+---
+ grub-core/term/at_keyboard.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
+index f8a129eb7..8207225c2 100644
+--- a/grub-core/term/at_keyboard.c
++++ b/grub-core/term/at_keyboard.c
+@@ -138,6 +138,7 @@ write_mode (int mode)
+   return (i != GRUB_AT_TRIES);
+ }
+ 
++#if !defined (GRUB_MACHINE_COREBOOT)
+ static int
+ query_mode (void)
+ {
+@@ -161,10 +162,12 @@ query_mode (void)
+     return 3;
+   return 0;
+ }
++#endif
+ 
+ static void
+ set_scancodes (void)
+ {
++#if !defined (GRUB_MACHINE_COREBOOT)
+   /* You must have visited computer museum. Keyboard without scancode set
+      knowledge. Assume XT. */
+   if (!grub_keyboard_orig_set)
+@@ -173,20 +176,33 @@ set_scancodes (void)
+       ps2_state.current_set = 1;
+       return;
+     }
++#endif
+ 
+ #if !USE_SCANCODE_SET
+   ps2_state.current_set = 1;
+   return;
+-#else
++#endif
+ 
++#if defined (GRUB_MACHINE_COREBOOT)
++  /* enable translation */
++  grub_keyboard_controller_write (grub_keyboard_controller_orig
++                                & ~KEYBOARD_AT_DISABLE);
++#else
++  /* if not coreboot, disable translation and try mode 2 first, before 1 */
+   grub_keyboard_controller_write (grub_keyboard_controller_orig
+                                 & ~KEYBOARD_AT_TRANSLATE
+                                 & ~KEYBOARD_AT_DISABLE);
++#endif
+ 
+   keyboard_controller_wait_until_ready ();
+   grub_outb (KEYBOARD_COMMAND_ENABLE, KEYBOARD_REG_DATA);
+-
+   write_mode (2);
++
++#if defined (GRUB_MACHINE_COREBOOT)
++  /* mode 2 with translation, so make grub treat as set 1 */
++  ps2_state.current_set = 1;
++#else
++  /* if not coreboot, translation isn't set; test 2 and fall back to 1 */
+   ps2_state.current_set = query_mode ();
+   grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set);
+   if (ps2_state.current_set == 2)
+-- 
+2.39.2
+
-- 
2.39.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]