mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-28 05:08:22 +00:00
ps2kbd: initial implementation
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _ARCH_PS2KBD_H_INCLUDE
|
||||
#define _ARCH_PS2KBD_H_INCLUDE
|
||||
|
||||
void ps2kbd_init();
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -73,6 +73,8 @@ void kmain(){
|
||||
|
||||
keyboard_init();
|
||||
|
||||
ps2kbd_init();
|
||||
|
||||
sched_runinit();
|
||||
|
||||
_panic("End of kmain()", 0);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _KEYBOARD_H_INCLUDE
|
||||
#define _KEYBOARD_H_INCLUDE
|
||||
|
||||
#define KBPACKET_FLAGS_RELEASED 1
|
||||
|
||||
#include <ringbuffer.h>
|
||||
#include <kernel/event.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user