PS2Keyboard: Janky ps2 driver

This commit is contained in:
2024-04-29 00:20:28 +02:00
parent df13f41be2
commit a81ac96e30
8 changed files with 313 additions and 6 deletions

View File

@@ -42,9 +42,9 @@ int _close(int file) {
return _do_syscall(SYSCALL_CLOSE_ID, file, 0, 0);
}
char **environ; /* pointer to array of char * strings that define the current environment variables */
char **environ = 0; /* pointer to array of char * strings that define the current environment variables */
int _execve(char *name, char **argv, char **env) {
int _execve(char *name, char **argv, char **env) {
return _do_syscall(SYSCALL_EXECVE_ID, (uint64_t) name, (uint64_t) argv, (uint64_t) env);
}
@@ -53,6 +53,7 @@ int _fork() {
}
int _getpid() {
return -1;
}
int _isatty(int file) { return file == 0 || file == 1 || file == 2; }
@@ -62,9 +63,11 @@ int _fstat(int file, struct stat *st) {
}
int _kill(int pid, int sig) {
return -1;
}
int _link(char *old, char *new) {
return -1;
}
int _lseek(int file, int ptr, int dir) {
@@ -84,12 +87,19 @@ caddr_t _sbrk(int incr) {
}
int _stat(const char *file, struct stat *st) {
return -1;
}
clock_t _times(struct tms *buf) {
buf->tms_cstime = 0;
buf->tms_cutime = 0;
buf->tms_stime = 0;
buf->tms_utime = 0;
return 0;
}
int _unlink(char *name) {
return -1;
}
int _wait(int *status) {
@@ -118,6 +128,9 @@ int usleep(useconds_t useconds) {
int _gettimeofday(struct timeval *restrict p, void *restrict z) {
p->tv_sec = 0;
p->tv_usec = 0;
return 0;
}
void print_mem() {

View File

@@ -27,6 +27,7 @@ target_sources(kernel.elf PRIVATE
limine_modules.cpp
handle_exception.cpp
LimineFramebuffer.cpp
PS2Keyboard.cpp
)
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -0,0 +1,251 @@
//
// Created by Stepan Usatiuk on 28.04.2024.
//
#include "PS2Keyboard.hpp"
#include <io.hpp>
#define PORTD 0x60 // COM1
#define PORTS 0x64 // COM1
#define PORTC 0x64 // COM1
static void wait_in() {
while ((inb(PORTS) & 1) == 0) {
__builtin_ia32_pause();
}
}
static void wait_out() {
while (inb(PORTS) & 2) {
__builtin_ia32_pause();
}
}
static void outb_wait(uint16_t port, uint8_t val) {
wait_out();
outb(port, val);
}
static uint8_t inb_wait(uint16_t port) {
wait_in();
return inb(port);
}
void PS2Keyboard::this_pooler() {
mutex.lock();
while (true) {
isrcv.wait(mutex);
wait_in();
bool read_something = false;
while ((inb(PORTS) & 1) != 0) {
int read = inb_wait(PORTD);
char r = -1;
if (read == 0xF0) {
inb_wait(PORTD);
continue;
}
switch (read) {
case 0x1C:
r = 'a';
break;
case 0x24:
r = 'e';
break;
case 0x2C:
r = 't';
break;
case 0x34:
r = 'g';
break;
case 0x3C:
r = 'u';
break;
case 0x44:
r = 'o';
break;
case 0x15:
r = 'q';
break;
case 0x1D:
r = 'w';
break;
case 0x21:
r = 'c';
break;
case 0x29:
r = ' ';
break;
case 0x2D:
r = 'r';
break;
case 0x31:
r = 'n';
break;
case 0x35:
r = 'y';
break;
case 0x4D:
r = 'p';
break;
case 0x1A:
r = 'z';
break;
case 0x22:
r = 'x';
break;
case 0x2A:
r = 'v';
break;
case 0x32:
r = 'b';
break;
case 0x3A:
r = 'm';
break;
case 0x42:
r = 'k';
break;
case 0x1B:
r = 's';
break;
case 0x23:
r = 'd';
break;
case 0x2B:
r = 'f';
break;
case 0x33:
r = 'h';
break;
case 0x3B:
r = 'j';
break;
case 0x43:
r = 'i';
break;
case 0x4B:
r = 'l';
break;
case 0x54:
r = '(';
break;
case 0x5B:
r = ')';
break;
case 0x5A: {
read_something = true;
if (!buf.full())
buf.push_back((char) '\n');
if (!buf.full())
buf.push_back((char) '\r');
break;
}
case 0x16:
r = '1';
break;
case 0x1E:
r = '2';
break;
case 0x26:
r = '3';
break;
case 0x25:
r = '4';
break;
case 0x2E:
r = '5';
break;
case 0x36:
r = '6';
break;
case 0x3D:
r = '7';
break;
case 0x3E:
r = '8';
break;
case 0x46:
r = '9';
break;
}
if (r != -1) {
read_something = true;
if (!buf.full())
buf.push_back((char) r);
}
}
if (read_something)
readercv.notify_all();
}
mutex.unlock();
}
PS2Keyboard::PS2Keyboard() {
outb_wait(PORTC, 0xAD); // Disable 1
outb_wait(PORTC, 0xA7); // Disable 2
inb(PORTD);
outb_wait(PORTC, 0x20); // Read conf
uint8_t old_conf = inb_wait(PORTD);
old_conf &= ~(1 << 0 | 1 << 1 | 1 << 6);
outb_wait(PORTC, 0x60); // Write conf
outb_wait(PORTD, old_conf);
outb_wait(PORTC, 0xAA);
assert(inb_wait(PORTD) == 0x55);
outb_wait(PORTC, 0xAB);
assert(inb_wait(PORTD) == 0x00);
outb_wait(PORTC, 0xAE);
outb_wait(PORTC, 0x20); // Read conf
old_conf = inb_wait(PORTD);
old_conf |= 1; // Enable IRQ1
outb_wait(PORTC, 0x60); // Write conf
outb_wait(PORTD, old_conf);
outb_wait(PORTD, 0xFF); // Reset
assert(inb_wait(PORTD) == 0xFA);
outb_wait(PORTD, 0xF6); // Set default
assert(inb_wait(PORTD) == 0xFA);
outb_wait(PORTD, 0xF0); // Scancode
assert(inb_wait(PORTD) == 0xFA);
outb_wait(PORTD, 2); // Scancode 2
assert(inb_wait(PORTD) == 0xFA);
outb_wait(PORTD, 0xF4); // Scan
assert(inb_wait(PORTD) == 0xFA);
for (int i = 0; i < 256; i++) states[i] = false;
Task *task = new Task(Task::TaskMode::TASKMODE_KERN, (void (*)(void))(&PS2Keyboard::this_pooler), "ps2kbd");
task->_frame.rdi = reinterpret_cast<uint64_t>(this);
task->start();
attach_interrupt(1, &PS2Keyboard::isr, this);
Arch::IDT::IRQ_clear_mask(1);
}
void PS2Keyboard::isr(void *tty) {
((PS2Keyboard *) tty)->this_isr();
}
void PS2Keyboard::this_isr() {
isrcv.notify_one();
}
char PS2Keyboard::readchar() {
mutex.lock();
while (buf.empty()) {
readercv.wait(mutex);
}
char ret = buf.pop_back();
mutex.unlock();
return ret;
}

View File

@@ -0,0 +1,32 @@
//
// Created by Stepan Usatiuk on 28.04.2024.
//
#ifndef PS2KEYBOARD_HPP
#define PS2KEYBOARD_HPP
#include <CircularBuffer.hpp>
#include <cv.hpp>
#include <mutex.hpp>
class PS2Keyboard {
// TODO: Possibly there should be 2 mutexes?
Mutex mutex;
CV readercv;
CV isrcv;
static void isr(void *tty);
void this_isr();
void this_pooler();
char process_scancode(int);
bool states[256];
CircularBuffer<char, 512> buf;
public:
PS2Keyboard();
char readchar();
};
#endif //PS2KEYBOARD_HPP

View File

@@ -173,7 +173,10 @@ namespace Arch::IDT {
Scheduler::switch_task(frame);
PIC_sendEOI(0);
}
extern "C" void pic1_irq_real_1() {
extern "C" __attribute__((force_align_arg_pointer)) void pic1_irq_real_1() {
if (handlers[1] != nullptr) {
handlers[1](handlers_args[1]);
}
PIC_sendEOI(1);
}
extern "C" void pic1_irq_real_2() {

View File

@@ -34,10 +34,10 @@
#include <LimineFramebuffer.hpp>
void templates_tester() {
GlobalTtyManager.all_tty_putstr("Testing templates\n");
// GlobalTtyManager.all_tty_putstr("Testing templates\n");
for (int i = 0; i < 5; i++)
test_templates();
GlobalTtyManager.all_tty_putstr("Testing templates OK\n");
// GlobalTtyManager.all_tty_putstr("Testing templates OK\n");
}
void vfs_tester() {
@@ -46,9 +46,9 @@ void vfs_tester() {
}
void ktask_main() {
GlobalTtyManager.add_tty(new SerialTty());
for (int i = 0; i < framebuffer_count; i++)
GlobalTtyManager.add_tty(new FbTty(new LimineFramebuffer(&framebuffers[i])));
GlobalTtyManager.add_tty(new SerialTty());
(new Task(Task::TaskMode::TASKMODE_KERN, templates_tester, "templates_tester"))->start();
(new Task(Task::TaskMode::TASKMODE_KERN, templates_tester, "templates_tester2"))->start();

View File

@@ -32,6 +32,10 @@ void FbTty::putstr(const char *str) {
}
}
char FbTty::readchar() {
char r = kbd.readchar();
if (r != '\r')
putchar(r);
return r;
}
void FbTty::next_col() {
_cur_col++;

View File

@@ -4,6 +4,7 @@
#ifndef FBTTY_HPP
#define FBTTY_HPP
#include <PS2Keyboard.hpp>
#include <Tty.hpp>
@@ -28,6 +29,8 @@ private:
void next_col();
void next_row();
PS2Keyboard kbd;
};