panic: Refactor PS/2 keyboard initialization code

This commit is contained in:
EnderIce2 2024-10-26 03:24:29 +03:00
parent 462907828d
commit b6006e379d
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD

View File

@ -17,6 +17,7 @@
#include "keyboard.hpp" #include "keyboard.hpp"
#include <interface/aip.h>
#include <display.hpp> #include <display.hpp>
#include <convert.h> #include <convert.h>
#include <printf.h> #include <printf.h>
@ -103,28 +104,28 @@ nsa static inline int GetLetterFromScanCode(uint8_t ScanCode)
return KEY_INVALID; return KEY_INVALID;
} }
nsa void CrashKeyboardDriver::PS2Wait(bool Read) nsa void CrashKeyboardDriver::PS2Wait(bool Output)
{ {
TimeoutCallNumber++;
#if defined(a86) #if defined(a86)
int Timeout = 100000; TimeoutCallNumber++;
uint8_t Status = 0; int timeout = 100000;
while (Timeout--) PS2_STATUSES status = {.Raw = inb(PS2_STATUS)};
while (timeout--)
{ {
Status = inb(0x64); if (!Output)
if (Read)
{ {
if ((Status & 1) == 1) if (status.OutputBufferFull == 0)
return; return;
} }
else else
{ {
if ((Status & 2) == 0) if (status.InputBufferFull == 0)
return; return;
} }
status.Raw = inb(PS2_STATUS);
} }
ExPrint(WARN_COLOR "PS/2 controller timeout (%s;%d)\n" DEFAULT_COLOR, ExPrint(WARN_COLOR "PS/2 controller timeout (%s;%d)\n" DEFAULT_COLOR,
Read ? "read" : "write", TimeoutCallNumber - 1); Output ? "output" : "input", TimeoutCallNumber);
#endif // a86 #endif // a86
} }
@ -159,21 +160,27 @@ CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */
{ {
/* Disable Port 1 */ /* Disable Port 1 */
WaitWrite; WaitWrite;
outb(0x64, 0xAD); outb(PS2_CMD, PS2_CMD_DISABLE_PORT_1);
/* Disable Port 2 */ /* Disable Port 2 */
WaitWrite; WaitWrite;
outb(0x64, 0xA7); outb(PS2_CMD, PS2_CMD_DISABLE_PORT_2);
} }
ExPrint("."); ExPrint(".");
/* Flush */ /* Flush */
{ {
int Timeout = 100000; PS2_STATUSES status;
while ((inb(0x64) & 1) && Timeout-- > 0) int timeout = 0x500;
inb(0x60); while (timeout--)
{
status.Raw = inb(PS2_STATUS);
if (status.OutputBufferFull == 0)
break;
inb(PS2_DATA);
}
if (Timeout <= 0) if (timeout <= 0)
{ {
SetMessageLocation; SetMessageLocation;
ExPrint(ERROR_COLOR ExPrint(ERROR_COLOR
@ -181,32 +188,41 @@ CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */
CPU::Stop(); CPU::Stop();
} }
} }
ExPrint("."); ExPrint(".");
/* Test controller */ /* Test controller */
{ {
/* Save config */ /* Save config */
WaitWrite; WaitWrite;
outb(0x64, 0x20); outb(PS2_CMD, PS2_CMD_READ_CONFIG);
WaitRead; WaitRead;
uint8_t cfg = inb(0x60); PS2_CONFIGURATION cfg = {.Raw = inb(PS2_DATA)};
cfg.Port1Interrupt = 1;
cfg.Port2Interrupt = 1;
cfg.Port1Translation = 1;
/* Update config */
WaitWrite;
outb(PS2_CMD, PS2_DATA);
WaitWrite;
outb(PS2_DATA, cfg.Raw);
/* Test PS/2 controller */ /* Test PS/2 controller */
WaitWrite; WaitWrite;
outb(0x64, 0xAA); outb(PS2_CMD, PS2_CMD_TEST_CONTROLLER);
WaitRead; WaitRead;
uint8_t test = inb(0x60); uint8_t test = inb(PS2_DATA);
if (test != 0x55) if (test != PS2_TEST_PASSED)
{ {
if (test == 0xFA) if (test == PS2_ACK)
{ {
trace("PS/2 controller sent ACK to test request."); trace("PS/2 controller sent ACK to test request.");
WaitRead; WaitRead;
test = inb(0x60); test = inb(PS2_DATA);
} }
if (test != 0x55) if (test != PS2_TEST_PASSED)
{ {
SetMessageLocation; SetMessageLocation;
ExPrint(ERROR_COLOR ExPrint(ERROR_COLOR
@ -218,41 +234,41 @@ CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */
/* Restore config */ /* Restore config */
WaitWrite; WaitWrite;
outb(0x64, 0x60); outb(PS2_CMD, PS2_DATA);
WaitWrite; WaitWrite;
outb(0x60, cfg); outb(PS2_DATA, cfg.Raw);
} }
ExPrint("."); ExPrint(".");
/* Disable scanning; Enable port 1; Set default settings */ /* Disable scanning; Enable port 1; Set default settings */
{ {
/* Disable scanning */ /* Disable scanning */
outb(0x60, 0xF5); outb(PS2_DATA, PS2_KBD_CMD_DISABLE_SCANNING);
/* Enable Port 1 */ /* Enable Port 1 */
WaitWrite; WaitWrite;
outb(0x64, 0xAE); outb(PS2_CMD, PS2_CMD_ENABLE_PORT_1);
/* Set default settings */ /* Set default settings */
outb(0x60, 0xF6); outb(PS2_DATA, PS2_KBD_CMD_DEFAULTS);
} }
ExPrint("."); ExPrint(".");
/* Test port 1 */ /* Test port 1 */
{ {
WaitWrite; WaitWrite;
outb(0x64, 0xAB); outb(PS2_CMD, PS2_CMD_TEST_PORT_1);
WaitRead; WaitRead;
uint8_t test = inb(0x60); uint8_t test = inb(PS2_DATA);
if (test != 0x00) if (test != 0x00)
{ {
if (test == 0xFA) if (test == PS2_KBD_RESP_ACK)
{ {
trace("PS/2 keyboard sent ACK to test request."); trace("PS/2 keyboard sent ACK to test request.");
WaitRead; WaitRead;
test = inb(0x60); test = inb(PS2_DATA);
} }
if (test != 0x00) if (test != 0x00)
@ -269,55 +285,55 @@ CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */
/* Configure the controller */ /* Configure the controller */
{ {
/* Read Controller Configuration */ // /* Read Controller Configuration */
WaitWrite; // WaitWrite;
outb(0x64, 0x20); // outb(PS2_CMD, PS2_CMD_READ_CONFIG);
WaitRead; // WaitRead;
uint8_t cfg = inb(0x60); // uint8_t cfg = inb(PS2_DATA);
/* Enable Port 1 & Port 1 translation */ // /* Enable Port 1 & Port 1 translation */
cfg |= 0b01000001; // cfg |= 0b01000001;
/* Write Controller Configuration */ // /* Write Controller Configuration */
WaitWrite; // WaitWrite;
outb(0x64, 0x60); // outb(PS2_CMD, PS2_CMD_WRITE_CONFIG);
WaitWrite; // WaitWrite;
outb(0x60, cfg); // outb(PS2_DATA, cfg);
} }
ExPrint("."); ExPrint(".");
/* Enable port 1; Set scan code; Enable scanning */ /* Enable port 1; Set scan code; Enable scanning */
{ {
/* Enable Port 1 */ /* Enable Port 1 */
outb(0x64, 0xAE); outb(PS2_CMD, PS2_CMD_ENABLE_PORT_1);
/* Set scan code set 1 */ /* Set scan code set 1 */
WaitWrite; WaitWrite;
outb(0x60, 0xF0); outb(PS2_DATA, PS2_KBD_CMD_SCAN_CODE_SET);
WaitWrite; WaitWrite;
outb(0x60, 0x02); outb(PS2_DATA, PS2_KBD_SCAN_CODE_SET_2);
/* Check if we have scan code set 1 */ /* Check if we have scan code set 1 */
WaitWrite; WaitWrite;
outb(0x60, 0xF0); outb(PS2_DATA, PS2_KBD_CMD_SCAN_CODE_SET);
WaitWrite; WaitWrite;
outb(0x60, 0x00); outb(PS2_DATA, PS2_KBD_SCAN_CODE_GET_CURRENT);
/* Read scan code set */ /* Read scan code set */
WaitRead; WaitRead;
uint8_t scs = inb(0x60); uint8_t scs = inb(PS2_DATA);
if (scs == 0xFA || scs == 0xFE) if (scs == PS2_KBD_RESP_ACK || scs == PS2_KBD_RESP_RESEND)
{ {
if (scs == 0xFA) if (scs == PS2_KBD_RESP_ACK)
trace("PS/2 keyboard sent ACK to scan code set request."); trace("PS/2 keyboard sent ACK to scan code set request.");
if (scs == 0xFE) if (scs == PS2_KBD_RESP_RESEND)
trace("PS/2 keyboard sent RESEND to scan code set request."); trace("PS/2 keyboard sent RESEND to scan code set request.");
WaitRead; WaitRead;
scs = inb(0x60); scs = inb(PS2_DATA);
} }
if (scs != 0x41) if (scs != PS2_KBD_SC_SET_2)
{ {
SetMessageLocation; SetMessageLocation;
ExPrint(WARN_COLOR ExPrint(WARN_COLOR
@ -326,8 +342,18 @@ CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */
} }
/* Enable scanning */ /* Enable scanning */
outb(0x60, 0xF4); outb(PS2_DATA, PS2_KBD_CMD_ENABLE_SCANNING);
} }
#ifdef DEBUG
WaitWrite;
outb(PS2_CMD, PS2_CMD_READ_CONFIG);
WaitRead;
PS2_CONFIGURATION cfg = {.Raw = inb(PS2_DATA)};
debug("PS2 CONFIG:\nPort1int: %d\nPort2int: %d\nSysFlg: %d\nZ: %d\nP1clk: %d\nP2clk: %d\nP1trans: %d\nz: %d",
cfg.Port1Interrupt, cfg.Port2Interrupt, cfg.SystemFlag, cfg.Zero0, cfg.Port1Clock, cfg.Port2Clock, cfg.Port1Translation, cfg.Zero1);
#endif
ExPrint("."); ExPrint(".");
#endif // defined(a86) #endif // defined(a86)
@ -339,7 +365,8 @@ nsa void CrashKeyboardDriver::OnInterruptReceived(CPU::TrapFrame *Frame)
{ {
#if defined(a86) #if defined(a86)
UNUSED(Frame); UNUSED(Frame);
uint8_t scanCode = inb(0x60); uint8_t scanCode = inb(PS2_DATA);
if (scanCode == KEY_D_TAB || if (scanCode == KEY_D_TAB ||
scanCode == KEY_D_LCTRL || scanCode == KEY_D_LCTRL ||
scanCode == KEY_D_LALT || scanCode == KEY_D_LALT ||