atkbc: Better test for old chromebooks

Older Chromebooks have issues in their embedded controller (EC) firmware
which need working around in atkbd and atkbdc. On these systems, rather
than use a standard EC, Google used their own arm-based EC. For a while,
its firmware incorrectly implemented the i8042, requiring workaroundsd
in the driver.

Implement a heuristic recommended by MrChromebox <mrchromebox@gmail.com>
to detect them: If the bios.version starts with Google_, or the maker is
either Google or GOOGLE, assume that it's a chromebook with the affected
bios. While this isn't strictly true, the number of updated systems
without the bug is very small and this will exclude all the non-Google
coreboot user that use a standard EC. There's no simple way to test the
hardware to see if it's implemented with the buggy EC.

Sponsored by:		Netflix
Reviewed by:		jon@thesoo.org, MrChromebox
Differential Revision:	https://reviews.freebsd.org/D40789
This commit is contained in:
Warner Losh 2023-06-29 08:24:55 -06:00
parent b5b9eaa962
commit 319d2bf407
2 changed files with 35 additions and 11 deletions

View file

@ -27,6 +27,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 14.x IS SLOW:
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20230629:
The heuristic for detecting old chromebooks with an EC bug that requires
atkbdc driver workarounds has changed. There should be no functional
change, but if your old chromebook's keyboard stops working, please
file a PR and assign it to imp.
20230623:
OpenSSL has been updated to version 3.0, including changes throughout
the base system. It is important to rebuild third-party software

View file

@ -109,21 +109,37 @@ struct atkbdc_quirks {
const char *bios_vendor;
const char *maker;
const char *product;
const char *version;
int quirk;
};
/* Old chromebooks running coreboot with i8042 emulation quirks */
#define CHROMEBOOK_WORKAROUND \
(KBDC_QUIRK_KEEP_ACTIVATED | KBDC_QUIRK_IGNORE_PROBE_RESULT | \
KBDC_QUIRK_RESET_AFTER_PROBE | KBDC_QUIRK_SETLEDS_ON_INIT)
static struct atkbdc_quirks quirks[] = {
{"coreboot", "System76", NULL, 0},
{"coreboot", "Purism", NULL, 0},
{"coreboot", NULL, NULL,
KBDC_QUIRK_KEEP_ACTIVATED | KBDC_QUIRK_IGNORE_PROBE_RESULT |
KBDC_QUIRK_RESET_AFTER_PROBE | KBDC_QUIRK_SETLEDS_ON_INIT},
/*
* Older chromebooks running coreboot have an EC that imperfectly emulates
* i8042 w/o fixes to its firmware. Since we can't probe for the problem,
* include all chromebooks by matching 'Google_' in the bios version string
* or a maker of either 'Google' or 'GOOGLE'. This is imperfect, but catches
* all chromebooks while omitting non-Google systems from System76 and
* Purism.
*/
{"coreboot", NULL, NULL, "Google_", CHROMEBOOK_WORKAROUND},
{"coreboot", "GOOGLE", NULL, NULL, CHROMEBOOK_WORKAROUND},
{"coreboot", "Google", NULL, NULL, CHROMEBOOK_WORKAROUND},
/* KBDC hangs on Lenovo X120e and X121e after disabling AUX MUX */
{NULL, "LENOVO", NULL, KBDC_QUIRK_DISABLE_MUX_PROBE},
{NULL, "LENOVO", NULL, NULL, KBDC_QUIRK_DISABLE_MUX_PROBE},
};
#define QUIRK_STR_MATCH(s1, s2) (s1 == NULL || \
(s2 != NULL && !strcmp(s1, s2)))
#define QUIRK_STR_EQUAL(s1, s2) \
(s1 == NULL || \
(s2 != NULL && strcmp(s1, s2) == 0))
#define QUIRK_STR_MATCH(s1, s2) \
(s1 == NULL || \
(s2 != NULL && strncmp(s1, s2, strlen(s1)) == 0))
static int
atkbdc_getquirks(void)
@ -132,11 +148,13 @@ atkbdc_getquirks(void)
char *bios_vendor = kern_getenv("smbios.bios.vendor");
char *maker = kern_getenv("smbios.system.maker");
char *product = kern_getenv("smbios.system.product");
char *version = kern_getenv("smbios.bios.version");
for (i = 0; i < nitems(quirks); i++)
if (QUIRK_STR_MATCH(quirks[i].bios_vendor, bios_vendor) &&
QUIRK_STR_MATCH(quirks[i].maker, maker) &&
QUIRK_STR_MATCH(quirks[i].product, product))
if (QUIRK_STR_EQUAL(quirks[i].bios_vendor, bios_vendor) &&
QUIRK_STR_EQUAL(quirks[i].maker, maker) &&
QUIRK_STR_EQUAL(quirks[i].product, product) &&
QUIRK_STR_MATCH(quirks[i].version, version))
return (quirks[i].quirk);
return (0);