diff options
Diffstat (limited to 'kernel/src/drivers/ps2ctrl.c')
-rw-r--r-- | kernel/src/drivers/ps2ctrl.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/kernel/src/drivers/ps2ctrl.c b/kernel/src/drivers/ps2ctrl.c new file mode 100644 index 0000000..527435d --- /dev/null +++ b/kernel/src/drivers/ps2ctrl.c @@ -0,0 +1,99 @@ +#include <panic.h> +#include <sys.h> + +#include "print.h" +#include "ps2ctrl.h" +#include "interrupt/pic.h" + +#define STATUS_OUT_BUF ((uint8_t)0x01) +#define STATUS_IN_BUF ((uint8_t)0x02) + +#define CONFIG_INT_0 ((uint8_t)0x01) +#define CONFIG_INT_1 ((uint8_t)0x02) +#define CONFIG_SYS ((uint8_t)0x04) +#define CONFIG_CLOCK_0 ((uint8_t)0x10) +#define CONFIG_CLOCK_1 ((uint8_t)0x20) +#define CONFIG_TRANS ((uint8_t)0x40) + +static bool is_init = false; + +uint8_t ps2ctrl_in(void) { + while((ps2ctrl_in_status() & STATUS_OUT_BUF) == 0) { + io_wait(); + } + return inb(0x60); +} + +uint8_t ps2ctrl_in_status(void) { + return inb(0x64); +} + +void ps2ctrl_out_cmd(uint8_t cmd) { + while((ps2ctrl_in_status() & STATUS_IN_BUF) != 0) { + io_wait(); + } + outb(0x64, cmd); +} + +void ps2ctrl_out_data(uint8_t data) { + while((ps2ctrl_in_status() & STATUS_IN_BUF) != 0) { + io_wait(); + } + outb(0x60, data); +} + +void ps2ctrl_set_port2(void) { + outb(0x64, 0xD4); +} + +void ps2ctrl_init(void) { + + debugk("Loading PS/2 Controller"); + + is_init = false; + + pic_mask(1); // keyboard + pic_mask(12); // mouse + + inb(0x60); + + // self-test + ps2ctrl_out_cmd(0xAA); + uint8_t response = ps2ctrl_in(); + if(response != 0x55) { + errork("PS/2 controller failed to initialize"); + return; + } + + // set config + ps2ctrl_out_cmd(0x20); + uint8_t config = ps2ctrl_in(); + config = (config | CONFIG_INT_0 | CONFIG_INT_1) & ~CONFIG_TRANS; + // config = 0xFF; + ps2ctrl_out_cmd(0x60); + ps2ctrl_out_data(config); + + // enable port 0 + ps2ctrl_out_cmd(0xAE); + + // enable port 2 + ps2ctrl_out_cmd(0xA9); + response = ps2ctrl_in(); + if (response == 0x01) { + errork("PS/2 port 2 not supported"); + return; + } + + ps2ctrl_out_cmd(0xA8); + + is_init = true; + + pic_unmask(1); + pic_unmask(12); + + succek("Loaded PS/2 Controller"); +} + +bool ps2ctrl_is_init(void) { + return is_init; +} |