ps2 init complete, can receive keyboard presses

This commit is contained in:
2026-06-13 19:53:57 -04:00
parent 3ecbcdf369
commit 2ab98fe582
11 changed files with 240 additions and 21 deletions

70
kernel/drivers/ps2/ps2.c Normal file
View File

@@ -0,0 +1,70 @@
#include <stdint.h>
#include <drivers/ps2/ps2.h>
extern void ps2_wait_input_empty(void);
extern void ps2_wait_output_full(void);
extern void ps2_write_command(uint8_t);
extern uint8_t ps2_read_data(void);
extern void ps2_write_data(uint8_t);
extern void ps2_flush_output_buffer(void);
extern void io_wait(void);
static uint8_t read_ccb() {
ps2_write_command(CMD_READ_CCB);
io_wait();
return ps2_read_data();
}
static void write_ccb(uint8_t ccb) {
ps2_write_command(CMD_WRITE_CCB);
io_wait();
ps2_write_data(ccb);
io_wait();
}
static int perform_self_test() {
ps2_write_command(CMD_SELF_TEST);
io_wait();
return ps2_read_data();
}
static int test_port_1() {
ps2_write_command(CMD_TEST_P1);
io_wait();
return ps2_read_data();
}
static void enable_port_1() {
ps2_write_command(CMD_ENABLE_P1);
io_wait();
}
int init_ps2() {
ps2_write_command(CMD_DISABLE_P1);
ps2_write_command(CMD_DISABLE_P2);
ps2_flush_output_buffer();
uint8_t ccb = read_ccb();
ccb = ccb & 0xEC;
write_ccb(ccb);
int result = perform_self_test();
if (result != SELF_TEST_SUCCESS) {
return -1;
}
result = test_port_1();
if (result != PORT_TEST_SUCCESS) {
return -1;
}
enable_port_1();
ccb = read_ccb();
ccb |= 0x01; // this enables interrupts for port 1, which we want
write_ccb(ccb);
return 0;
}

19
kernel/drivers/ps2/ps2.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef KPS2_H
#define KPS2_H
#define PS2_DATA 0x60
#define PS2_STATUS 0x64
#define PS2_COMMAND 0x64
#define CMD_DISABLE_P1 0xAD
#define CMD_DISABLE_P2 0xAE
#define CMD_READ_CCB 0x20
#define CMD_WRITE_CCB 0x60
#define CMD_SELF_TEST 0xAA
#define CMD_TEST_P1 0xAB
#define CMD_ENABLE_P1 0xAE
#define SELF_TEST_SUCCESS 0x55
#define PORT_TEST_SUCCESS 0x00
#endif

View File

@@ -0,0 +1,87 @@
#include "drivers/ps2/ps2.h"
.code32
.global ps2_wait_input_empty
.global ps2_wait_output_full
.global ps2_write_command
.global ps2_read_data
.global ps2_write_data
.global ps2_flush_output_buffer
.extern io_wait
# helpers
ps2_wait_input_empty: #(void) -> void
push %ebp
mov %esp, %ebp
1:
inb $PS2_STATUS, %al
andb $0x02, %al
jnz 1b
leave
ret
ps2_wait_output_full: #(void) -> void
push %ebp
mov %esp, %ebp
1:
inb $PS2_STATUS, %al
andb $0x01, %al
jz 1b
leave
ret
ps2_write_command: #(uint8_t command) -> void
push %ebp
mov %esp, %ebp
call ps2_wait_input_empty
xor %eax, %eax
movb 8(%ebp), %al
outb %al, $PS2_COMMAND
leave
ret
ps2_read_data: #(void) -> uint8_t
push %ebp
mov %esp, %ebp
call ps2_wait_output_full
xor %eax, %eax
inb $PS2_DATA, %al
leave
ret
ps2_write_data: #(uint8_t) -> void
push %ebp
mov %esp, %ebp
call ps2_wait_input_empty
xor %eax, %eax
movb 8(%ebp), %al
outb %al, $PS2_DATA
leave
ret
ps2_flush_output_buffer: #(void) -> void
push %ebp
mov %esp, %ebp
1:
inb $PS2_STATUS, %al
andb $0x01, %al
jz 2f
inb $PS2_DATA, %al
jmp 1b
2:
leave
ret