mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-28 16:17:51 +01:00
PS2Keyboard: Janky ps2 driver
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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})
|
||||
|
||||
251
src/arch/x86/PS2Keyboard.cpp
Normal file
251
src/arch/x86/PS2Keyboard.cpp
Normal 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;
|
||||
}
|
||||
32
src/arch/x86/PS2Keyboard.hpp
Normal file
32
src/arch/x86/PS2Keyboard.hpp
Normal 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
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user