ps2kbd: initial implementation

This commit is contained in:
Matheus
2022-09-08 17:58:19 -03:00
parent d63b9512e7
commit c91e3cd12d
9 changed files with 104 additions and 0 deletions
+5
View File
@@ -10,7 +10,10 @@
// 0x21 -> lapic nmi
// 0x22 -> mmu invalidate page ipi
// ...
// 0x40 -> ps2 keyboard isr
// ...
// 0x80 -> timer
// ...
idtentry_t idt[256];
@@ -57,6 +60,8 @@ void idt_bspinit(){
idt_setentry(&idt[VECTOR_LAPICNMI], asmisr_lapicnmi, 0x28, FLAGS_PRESENT | FLAGS_TYPE_INTERRUPT, 0);
idt_setentry(&idt[VECTOR_TIMER], asmisr_timer, 0x28, FLAGS_PRESENT | FLAGS_TYPE_INTERRUPT, 0);
idt_setentry(&idt[VECTOR_PS2KBD], asmisr_ps2kbd, 0x28, FLAGS_PRESENT | FLAGS_TYPE_INTERRUPT, 0);
idt_reload();
+1
View File
@@ -27,6 +27,7 @@
#define VECTOR_PANIC 0x20
#define VECTOR_LAPICNMI 0x21
#define VECTOR_MMUINVAL 0x22
#define VECTOR_PS2KBD 0x40
#define VECTOR_TIMER 0x80
typedef struct{
+1
View File
@@ -10,6 +10,7 @@ extern void asmisr_pagefault();
extern void asmisr_panic();
extern void asmisr_lapicnmi();
extern void asmisr_mmuinval();
extern void asmisr_ps2kbd();
extern void asmisr_timer();
#endif
+6
View File
@@ -0,0 +1,6 @@
#ifndef _ARCH_PS2KBD_H_INCLUDE
#define _ARCH_PS2KBD_H_INCLUDE
void ps2kbd_init();
#endif
+1
View File
@@ -145,4 +145,5 @@ isr asmisr_general, isr_general
except asmisr_except, isr_except
isr asmisr_lapicnmi, isr_lapicnmi
isr asmisr_mmuinval, isr_mmuinval
isr asmisr_ps2kbd, isr_ps2kbd
isr asmisr_timer, isr_timer
+5
View File
@@ -30,6 +30,11 @@ void isr_mmuinval(){
apic_eoi();
}
void isr_ps2kbd(arch_regs* reg){
ps2kbd_irq();
apic_eoi();
}
void isr_timer(arch_regs* reg){
timer_irq(reg);
apic_eoi();
+2
View File
@@ -73,6 +73,8 @@ void kmain(){
keyboard_init();
ps2kbd_init();
sched_runinit();
_panic("End of kmain()", 0);
+81
View File
@@ -0,0 +1,81 @@
#include <arch/ps2kbd.h>
#include <arch/io.h>
#include <stdbool.h>
#include <arch/cls.h>
#include <arch/idt.h>
#include <arch/apic.h>
#include <kernel/keyboard.h>
#define PS2_PORT_DATA 0x60
#define PS2_PORT_COMMAND 0x64
#define PS2_PORT_STATUS 0x64
#define RESEND 0xFE
#define ACK 0xFA
#define ECHO 0xEE
#define KEYBOARDIRQ 1
static int kb;
static uint8_t ps2cmd(uint8_t cmd){
uint8_t response;
for(size_t i = 0; i < 3; ++i){
outb(PS2_PORT_DATA, cmd);
response = inb(PS2_PORT_DATA);
if(response != RESEND)
break;
}
return response;
}
static char asciitable[] = {
0, '\033', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 0, 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '4', '1', '2', '3', '0', '.', 0, 0, 0, 0, 0
};
void ps2kbd_irq(){
uint8_t scancode = inb(0x60);
if(scancode == 0xE0)
return; // TODO support extended scancodes
kbpacket_t packet;
// TODO convert scancode to keycode
packet.flags = 0;
if(scancode & 0x80){
packet.flags = KBPACKET_FLAGS_RELEASED;
scancode &= 0x7F;
}
packet.ascii = asciitable[scancode];
keyboard_packet(kb, &packet);
}
void ps2kbd_init(){
// maybe the ps/2 controller and keyboard should be initialised to a known state
// and not be assumed to be set up in a working manner by the firmware/bootloader
// this probably shouldn't assume the keyboard always being in the first port but oh well
// clear keyboard buffer data
inb(PS2_PORT_DATA);
if(ps2cmd(ECHO) != ECHO){
printf("No PS/2 keyboard found.\n");
return;
}
ioapic_setlegacyirq(KEYBOARDIRQ, VECTOR_PS2KBD, arch_getcls()->lapicid, false);
kb = keyboard_getnew();
}
+2
View File
@@ -1,6 +1,8 @@
#ifndef _KEYBOARD_H_INCLUDE
#define _KEYBOARD_H_INCLUDE
#define KBPACKET_FLAGS_RELEASED 1
#include <ringbuffer.h>
#include <kernel/event.h>