summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2023-10-31 00:50:36 +0000
committerLeah Rowe <leah@libreboot.org>2023-10-31 07:30:02 +0000
commit9606c68c5b5becfb09da45e027e2398e5ff33dfa (patch)
tree4f6b5730d735cf2755c998ba59ca5bc20e4c21f1
parent34f5685337bb94751d36786467a0027b526f6346 (diff)
fix grub keyboard init on dell e6400 and e6430
also, enable seabios_withgrub on e6400, but not grubfirst; right now, we also support dgpu which would brick on grubfirst. on my tested nvidia model, loading grub from seabios worked, so i'm going to re-add seabios_grubfirst functionality like in older libreboot revisions, enabled selectively on a given target. e6430 currently only has igpu support anyway, but i've done the same thing there, in anticipation of future dgpu support. e6400 and e6430 ec report scancode set 2 with translation by default, but only actually output scancode set 1 grub is trying to use scancode set 2 without scancode translation, so the key inputs get messed up fix it by forcing scancode set 2 with translation, but only on coreboot; other build targets on GRUB will retain the same behaviour as before courtesy goes to Nicholas Chin who inspired me, and helped me to fix this. tested on Nicholas's E6400 and E6430, and my E6400; Riku also tested it on non-Dell, as did I (some thinkpads), and all seems OK. The new behaviour in coreboot GRUB is essentially no different to that of SeaBIOS, which does the same. Signed-off-by: Leah Rowe <leah@libreboot.org>
-rw-r--r--config/coreboot/e6400_4mb/target.cfg1
-rw-r--r--config/coreboot/e6430_12mb/target.cfg1
-rw-r--r--config/grub/patches/0003-keyboardfix/0001-at_keyboard-coreboot-force-scancodes2-translate.patch107
3 files changed, 109 insertions, 0 deletions
diff --git a/config/coreboot/e6400_4mb/target.cfg b/config/coreboot/e6400_4mb/target.cfg
index b5466aef..4cbaf904 100644
--- a/config/coreboot/e6400_4mb/target.cfg
+++ b/config/coreboot/e6400_4mb/target.cfg
@@ -5,5 +5,6 @@ payload_grub="n"
payload_grub_withseabios="n"
payload_seabios="y"
payload_memtest="y"
+payload_seabios_withgrub="y"
grub_scan_disk="ahci"
microcode_required="n"
diff --git a/config/coreboot/e6430_12mb/target.cfg b/config/coreboot/e6430_12mb/target.cfg
index 145aa712..7b790a99 100644
--- a/config/coreboot/e6430_12mb/target.cfg
+++ b/config/coreboot/e6430_12mb/target.cfg
@@ -4,5 +4,6 @@ arch="x86_64"
payload_grub="n"
payload_seabios_withgrub="n"
payload_seabios="y"
+payload_seabios_withgrub="y"
payload_memtest="y"
grub_scan_disk="ahci"
diff --git a/config/grub/patches/0003-keyboardfix/0001-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/grub/patches/0003-keyboardfix/0001-at_keyboard-coreboot-force-scancodes2-translate.patch
new file mode 100644
index 00000000..21e8630b
--- /dev/null
+++ b/config/grub/patches/0003-keyboardfix/0001-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
+