GMMOS: I2C keyboards, and every keyboard at once
The second micro driver: i2c_hid.c with everything but reading a keyboard's input reports taken out. No ACPI -- AML cannot run on a dead kernel -- so the live driver hands over what it found at boot (i2c_hid_keyboards): the DesignWare controller, the address, the report size, the AMD GPIO pin if there is one, and the parsed report descriptor. No power commands, no reset, a read-only transfer. usb_hid.c's report-protocol rewrite is split out as hid_boot_report(), which does nothing but rewrite, and kernel/gmmos/hidkeys.c turns boot reports into keys for this and the USB micro drivers to come. GMMOS now probes every micro driver and polls all that answer. Not run: QEMU has no DesignWare I2C, and the laptops at hand have PS/2 keyboards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
cb9b06d46f
commit
c6d90e69fa
8 changed files with 387 additions and 17 deletions
|
|
@ -47,7 +47,30 @@ static addr_t *pcs;
|
|||
static int npcs;
|
||||
|
||||
static int sw, sh, cw, ch;
|
||||
static const struct gmmos_kbd *kbd;
|
||||
// Every micro driver, in the order they are tried. All that answer are
|
||||
// polled: a laptop has its own keyboard and maybe a USB one on the side.
|
||||
static const struct gmmos_kbd *const drivers[] = { &gmmos_ps2, &gmmos_i2c };
|
||||
static const struct gmmos_kbd *kbds[NELEM(drivers)];
|
||||
static int nkbd;
|
||||
|
||||
static int
|
||||
poll_keys(void)
|
||||
{
|
||||
for (int i = 0; i < nkbd; i++) {
|
||||
int k = kbds[i]->poll();
|
||||
if (k)
|
||||
return k;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_lights(int on)
|
||||
{
|
||||
for (int i = 0; i < nkbd; i++)
|
||||
if (kbds[i]->leds)
|
||||
kbds[i]->leds(on);
|
||||
}
|
||||
|
||||
enum { MAIN, QRPAGES, LOG, TERM };
|
||||
static int mode = MAIN;
|
||||
|
|
@ -493,6 +516,7 @@ cmd_help(void)
|
|||
tline("pci PCI devices");
|
||||
tline("mem ADDR [LEN] bytes at a kernel address; both in hex (80, up to 400)");
|
||||
tline("uptime how long it ran, and how long since");
|
||||
tline("keyboards which keyboards GMMOS is reading");
|
||||
tline("clear empty this screen");
|
||||
tline("restart restart the machine");
|
||||
tline("poweroff power it off");
|
||||
|
|
@ -763,6 +787,10 @@ run(void)
|
|||
else if (streq(w, "pci")) cmd_pci();
|
||||
else if (streq(w, "mem")) cmd_mem(arg);
|
||||
else if (streq(w, "uptime")) cmd_uptime();
|
||||
else if (streq(w, "keyboards")) {
|
||||
for (int i = 0; i < nkbd; i++)
|
||||
tline(kbds[i]->name);
|
||||
}
|
||||
else if (streq(w, "clear")) tn = 0;
|
||||
else if (streq(w, "restart") || streq(w, "reboot")) restart();
|
||||
else if (streq(w, "poweroff")) {
|
||||
|
|
@ -829,7 +857,7 @@ draw_status(void)
|
|||
sb_putc(&sb, ':');
|
||||
sb_putc(&sb, (char)('0' + left % 60 / 10));
|
||||
sb_putc(&sb, (char)('0' + left % 10));
|
||||
sb_puts(&sb, kbd ? ". Any key keeps it on." : ".");
|
||||
sb_puts(&sb, nkbd ? ". Any key keeps it on." : ".");
|
||||
} else {
|
||||
sb_puts(&sb, "Staying on. Nothing here is lost until it restarts.");
|
||||
}
|
||||
|
|
@ -837,7 +865,7 @@ draw_status(void)
|
|||
textn(x, y + step, sbz(&sb), (sw * 2 / 3 - x) / cw, PSOGM_DIM);
|
||||
|
||||
gfx_fill_rect(x, y + step * 3, sw - x, ch + 2, PSOGM_BG);
|
||||
if (kbd)
|
||||
if (nkbd)
|
||||
textn(x, y + step * 3,
|
||||
"Space log as QR L read the log T terminal R restart P power off",
|
||||
(sw - x) / cw, PSOGM_FG);
|
||||
|
|
@ -961,8 +989,9 @@ gmmos_run(char *r, addr_t *p, int n)
|
|||
rows = (sh - my * 2) / ch;
|
||||
|
||||
log_snapshot();
|
||||
if (gmmos_ps2.probe())
|
||||
kbd = &gmmos_ps2;
|
||||
for (int i = 0; i < (int)NELEM(drivers); i++)
|
||||
if (drivers[i]->probe())
|
||||
kbds[nkbd++] = drivers[i];
|
||||
tline("GMMOS, the Guru Meditation Micro OS. The kernel is dead; this is what");
|
||||
tline("runs after it. help lists the commands.");
|
||||
draw_status();
|
||||
|
|
@ -971,10 +1000,10 @@ gmmos_run(char *r, addr_t *p, int n)
|
|||
int lights = 0, keyed = 0;
|
||||
|
||||
for (;;) {
|
||||
int k = kbd ? kbd->poll() : 0;
|
||||
int k = poll_keys();
|
||||
if (k) {
|
||||
if (!keyed && kbd->leds) {
|
||||
kbd->leds(0); // somebody is here: the lights have done their job
|
||||
if (!keyed) {
|
||||
set_lights(0); // somebody is here: the lights have done their job
|
||||
lights = 0;
|
||||
}
|
||||
keyed = 1;
|
||||
|
|
@ -1001,10 +1030,10 @@ gmmos_run(char *r, addr_t *p, int n)
|
|||
}
|
||||
// The lights until somebody presses a key, as panic_blink did: on a
|
||||
// machine whose screen is black, they are all there is to say it died.
|
||||
if (!keyed && kbd && kbd->leds && t - last_blink >= 333) {
|
||||
if (!keyed && t - last_blink >= 333) {
|
||||
last_blink = t;
|
||||
lights = !lights;
|
||||
kbd->leds(lights);
|
||||
set_lights(lights);
|
||||
}
|
||||
if (!boot_verbose && !cancelled && t - entered_ms >= OFF_MS) {
|
||||
acpi_poweroff_now();
|
||||
|
|
|
|||
Loading…
Reference in a new issue