keyboard
This commit is contained in:
parent
20b96b2086
commit
02abf375d3
14
Makefile
14
Makefile
|
@ -43,7 +43,12 @@ default: run
|
||||||
|
|
||||||
.FORCE:
|
.FORCE:
|
||||||
|
|
||||||
include/shade/version.h: .FORCE
|
bin/shade.iso: bin/shade.bin
|
||||||
|
cp bin/shade.bin src/iso/boot/shade.bin
|
||||||
|
grub-mkrescue src/iso/ -o $@
|
||||||
|
rm src/iso/boot/shade.bin
|
||||||
|
|
||||||
|
bin/shade.bin: $(sboot_object_files) $(kernel_object_files) $(libc_object_files)
|
||||||
echo "#ifndef VERSION_H" > include/shade/version.h
|
echo "#ifndef VERSION_H" > include/shade/version.h
|
||||||
echo "#define VERSION_H" >> include/shade/version.h
|
echo "#define VERSION_H" >> include/shade/version.h
|
||||||
echo "// This file was autogenerated by the shadeOS build system. It should not be modified." >> include/shade/version.h
|
echo "// This file was autogenerated by the shadeOS build system. It should not be modified." >> include/shade/version.h
|
||||||
|
@ -53,13 +58,6 @@ include/shade/version.h: .FORCE
|
||||||
echo "#define SHADE_OS_COMPILE_DATE \"$(date)\"" >> include/shade/version.h
|
echo "#define SHADE_OS_COMPILE_DATE \"$(date)\"" >> include/shade/version.h
|
||||||
echo "#define SHADE_OS_CODENAME \"$(codename)\"" >> include/shade/version.h
|
echo "#define SHADE_OS_CODENAME \"$(codename)\"" >> include/shade/version.h
|
||||||
echo "#endif" >> include/shade/version.h
|
echo "#endif" >> include/shade/version.h
|
||||||
|
|
||||||
bin/shade.iso: bin/shade.bin
|
|
||||||
cp bin/shade.bin src/iso/boot/shade.bin
|
|
||||||
grub-mkrescue src/iso/ -o $@
|
|
||||||
rm src/iso/boot/shade.bin
|
|
||||||
|
|
||||||
bin/shade.bin: $(sboot_object_files) $(kernel_object_files) $(libc_object_files)
|
|
||||||
mkdir -p "$(@D)"
|
mkdir -p "$(@D)"
|
||||||
$(LD) $(LDFLAGS) -n -T $(shade_bin_ldfile) $^ -o $@
|
$(LD) $(LDFLAGS) -n -T $(shade_bin_ldfile) $^ -o $@
|
||||||
grub-file --is-x86-multiboot2 $@
|
grub-file --is-x86-multiboot2 $@
|
||||||
|
|
BIN
bin/shade.bin
BIN
bin/shade.bin
Binary file not shown.
BIN
bin/shade.iso
BIN
bin/shade.iso
Binary file not shown.
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef KEYBOARD_H
|
||||||
|
#define KEYBOARD_H
|
||||||
|
|
||||||
|
void init_keyboard();
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,61 +5,38 @@
|
||||||
|
|
||||||
#define ERR_MAX 5
|
#define ERR_MAX 5
|
||||||
|
|
||||||
|
#define IRQ_MIN 0x20
|
||||||
|
#define IRQ_MAX 0x2f
|
||||||
|
|
||||||
|
#define IRQ0 0x20
|
||||||
|
#define IRQ1 0x21
|
||||||
|
#define IRQ2 0x22
|
||||||
|
#define IRQ3 0x23
|
||||||
|
#define IRQ4 0x24
|
||||||
|
#define IRQ5 0x25
|
||||||
|
#define IRQ6 0x26
|
||||||
|
#define IRQ7 0x27
|
||||||
|
#define IRQ8 0x28
|
||||||
|
#define IRQ9 0x29
|
||||||
|
#define IRQ10 0x2a
|
||||||
|
#define IRQ11 0x2b
|
||||||
|
#define IRQ12 0x2c
|
||||||
|
#define IRQ13 0x2d
|
||||||
|
#define IRQ14 0x2e
|
||||||
|
#define IRQ15 0x2f
|
||||||
|
|
||||||
static int err_count = 0;
|
static int err_count = 0;
|
||||||
|
|
||||||
typedef struct {
|
static void (*interrupt_handlers[256]) (uint8_t vector, uint16_t err);
|
||||||
struct {
|
|
||||||
uint64_t resv0;
|
|
||||||
uint64_t resv1;
|
|
||||||
uint64_t resv2;
|
|
||||||
uint64_t resv3;
|
|
||||||
} broken;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint64_t resv0;
|
|
||||||
uint64_t resv1;
|
|
||||||
uint64_t resv2;
|
|
||||||
uint64_t resv3;
|
|
||||||
uint64_t resv4;
|
|
||||||
uint64_t resv5;
|
|
||||||
} broken_2;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint64_t resv0;
|
|
||||||
uint64_t error_code;
|
|
||||||
uint64_t resv1;
|
|
||||||
uint64_t vector;
|
|
||||||
uint64_t resv2;
|
|
||||||
uint64_t resv3;
|
|
||||||
uint64_t resv4;
|
|
||||||
uint64_t resv5;
|
|
||||||
} base_frame;
|
|
||||||
} isr_xframe_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
List of pushed things in order:
|
|
||||||
error_code
|
|
||||||
vector
|
|
||||||
rbp
|
|
||||||
rax
|
|
||||||
rbx
|
|
||||||
rcx
|
|
||||||
rdx
|
|
||||||
rsi
|
|
||||||
rdi
|
|
||||||
cr0
|
|
||||||
cr2
|
|
||||||
cr3
|
|
||||||
cr4
|
|
||||||
ds
|
|
||||||
0
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
void exception_handler(uint8_t vector, uint16_t err);
|
void exception_handler(uint8_t vector, uint16_t err);
|
||||||
|
|
||||||
__attribute__((noreturn))
|
int register_interrupt_handler(int vector, void (*handler)(uint8_t, uint16_t));
|
||||||
void interrupt_handler(isr_xframe_t frame);
|
int unregister_interrupt_handler(int vector);
|
||||||
|
|
||||||
|
void default_handler(uint8_t vector, uint16_t err);
|
||||||
|
|
||||||
|
void fill_isr();
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -27,6 +27,22 @@
|
||||||
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
|
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
|
||||||
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
|
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
|
||||||
|
|
||||||
|
#define IRQ_PIT 0
|
||||||
|
#define IRQ_KEYBOARD 1
|
||||||
|
#define IRQ_INTERNAL 2
|
||||||
|
#define IRQ_COM2 3
|
||||||
|
#define IRQ_COM1 4
|
||||||
|
#define IRQ_LPT2 5
|
||||||
|
#define IRQ_FLOPPY 6
|
||||||
|
#define IRQ_LPT1 7
|
||||||
|
#define IRQ_CMOS 8
|
||||||
|
#define IRQ_UNUSED 9
|
||||||
|
#define IRQ_UNUSED 10
|
||||||
|
#define IRQ_UNUSED 11
|
||||||
|
#define IRQ_PS2_MOUSE 12
|
||||||
|
#define IRQ_FPU 13
|
||||||
|
#define IRQ_ATA_PRIMARY 14
|
||||||
|
#define IRQ_ATA_SECONDARY 15
|
||||||
|
|
||||||
void pic_send_eoi(uint8_t irq);
|
void pic_send_eoi(uint8_t irq);
|
||||||
void pic_remap(int offset1, int offset2);
|
void pic_remap(int offset1, int offset2);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// This file was autogenerated by the shadeOS build system. It should not be modified.
|
// This file was autogenerated by the shadeOS build system. It should not be modified.
|
||||||
#define SHADE_OS_KERNEL_VERSION "0.1.1-alpha"
|
#define SHADE_OS_KERNEL_VERSION "0.1.1-alpha"
|
||||||
#define SHADE_OS_KERNEL "shade-development"
|
#define SHADE_OS_KERNEL "shade-development"
|
||||||
#define SHADE_OS_BUILD "b4e6b2e"
|
#define SHADE_OS_BUILD "20b96b2"
|
||||||
#define SHADE_OS_COMPILE_DATE "Sun May 15 05:41:17 PM EDT 2022"
|
#define SHADE_OS_COMPILE_DATE "Sun May 15 07:01:51 PM EDT 2022"
|
||||||
#define SHADE_OS_CODENAME "willow"
|
#define SHADE_OS_CODENAME "willow"
|
||||||
#endif
|
#endif
|
||||||
|
|
Binary file not shown.
|
@ -1,7 +1,10 @@
|
||||||
#include <shade/platform/ports.h>
|
#include <shade/platform/ports.h>
|
||||||
#include <shade/platform/drivers/vga_text_mode.h>
|
#include <shade/platform/drivers/vga_text_mode.h>
|
||||||
#include <shade/platform/interrupts/idt.h>
|
#include <shade/platform/interrupts/idt.h>
|
||||||
|
#include <shade/platform/interrupts/isr.h>
|
||||||
#include <shade/platform/interrupts/pic.h>
|
#include <shade/platform/interrupts/pic.h>
|
||||||
|
#include <shade/platform/drivers/keyboard.h>
|
||||||
|
#include <shade/platform/ports.h>
|
||||||
#include <shade/version.h>
|
#include <shade/version.h>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
#include <shade/kmsg.h>
|
#include <shade/kmsg.h>
|
||||||
|
@ -37,8 +40,20 @@ void kmain() {
|
||||||
kprintf("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n");
|
kprintf("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n");
|
||||||
|
|
||||||
pic_remap(0x20, 0x28);
|
pic_remap(0x20, 0x28);
|
||||||
|
fill_isr(); // ISR must be filled before interrupts are enabled
|
||||||
idt_assemble();
|
idt_assemble();
|
||||||
kmsg_ok("Enabled interrupts\n");
|
kmsg_ok("Enabled interrupts");
|
||||||
|
|
||||||
|
init_keyboard();
|
||||||
|
|
||||||
|
idt_disable_interrupts();
|
||||||
|
outb(0x21,0xfd);
|
||||||
|
outb(0xa1,0xff);
|
||||||
|
idt_enable_interrupts();
|
||||||
|
|
||||||
|
kmsg_ok("Enabled keyboard");
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("int $2");
|
||||||
|
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
}
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
#include <shade/platform/drivers/keyboard.h>
|
||||||
|
#include <shade/platform/ports.h>
|
||||||
|
#include <shade/platform/interrupts/isr.h>
|
||||||
|
#include <shade/platform/interrupts/pic.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <printf.h>
|
||||||
|
|
||||||
|
void keyboard_callback(uint8_t vector, uint16_t err) {
|
||||||
|
// PIC leaves scancode in port 0x60
|
||||||
|
uint8_t scancode = inb(0x60);
|
||||||
|
print_letter(scancode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_keyboard() {
|
||||||
|
register_interrupt_handler(IRQ1, keyboard_callback);
|
||||||
|
pic_unmask_irq(IRQ_KEYBOARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_letter(uint8_t scancode) {
|
||||||
|
switch (scancode) {
|
||||||
|
case 0x0:
|
||||||
|
kprintf("ERROR");
|
||||||
|
break;
|
||||||
|
case 0x1:
|
||||||
|
kprintf("ESC");
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
kprintf("1");
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
kprintf("2");
|
||||||
|
break;
|
||||||
|
case 0x4:
|
||||||
|
kprintf("3");
|
||||||
|
break;
|
||||||
|
case 0x5:
|
||||||
|
kprintf("4");
|
||||||
|
break;
|
||||||
|
case 0x6:
|
||||||
|
kprintf("5");
|
||||||
|
break;
|
||||||
|
case 0x7:
|
||||||
|
kprintf("6");
|
||||||
|
break;
|
||||||
|
case 0x8:
|
||||||
|
kprintf("7");
|
||||||
|
break;
|
||||||
|
case 0x9:
|
||||||
|
kprintf("8");
|
||||||
|
break;
|
||||||
|
case 0x0A:
|
||||||
|
kprintf("9");
|
||||||
|
break;
|
||||||
|
case 0x0B:
|
||||||
|
kprintf("0");
|
||||||
|
break;
|
||||||
|
case 0x0C:
|
||||||
|
kprintf("-");
|
||||||
|
break;
|
||||||
|
case 0x0D:
|
||||||
|
kprintf("+");
|
||||||
|
break;
|
||||||
|
case 0x0E:
|
||||||
|
kprintf("Backspace");
|
||||||
|
break;
|
||||||
|
case 0x0F:
|
||||||
|
kprintf("Tab");
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
kprintf("Q");
|
||||||
|
break;
|
||||||
|
case 0x11:
|
||||||
|
kprintf("W");
|
||||||
|
break;
|
||||||
|
case 0x12:
|
||||||
|
kprintf("E");
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
kprintf("R");
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
|
kprintf("T");
|
||||||
|
break;
|
||||||
|
case 0x15:
|
||||||
|
kprintf("Y");
|
||||||
|
break;
|
||||||
|
case 0x16:
|
||||||
|
kprintf("U");
|
||||||
|
break;
|
||||||
|
case 0x17:
|
||||||
|
kprintf("I");
|
||||||
|
break;
|
||||||
|
case 0x18:
|
||||||
|
kprintf("O");
|
||||||
|
break;
|
||||||
|
case 0x19:
|
||||||
|
kprintf("P");
|
||||||
|
break;
|
||||||
|
case 0x1A:
|
||||||
|
kprintf("[");
|
||||||
|
break;
|
||||||
|
case 0x1B:
|
||||||
|
kprintf("]");
|
||||||
|
break;
|
||||||
|
case 0x1C:
|
||||||
|
kprintf("ENTER");
|
||||||
|
break;
|
||||||
|
case 0x1D:
|
||||||
|
kprintf("LCtrl");
|
||||||
|
break;
|
||||||
|
case 0x1E:
|
||||||
|
kprintf("A");
|
||||||
|
break;
|
||||||
|
case 0x1F:
|
||||||
|
kprintf("S");
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
kprintf("D");
|
||||||
|
break;
|
||||||
|
case 0x21:
|
||||||
|
kprintf("F");
|
||||||
|
break;
|
||||||
|
case 0x22:
|
||||||
|
kprintf("G");
|
||||||
|
break;
|
||||||
|
case 0x23:
|
||||||
|
kprintf("H");
|
||||||
|
break;
|
||||||
|
case 0x24:
|
||||||
|
kprintf("J");
|
||||||
|
break;
|
||||||
|
case 0x25:
|
||||||
|
kprintf("K");
|
||||||
|
break;
|
||||||
|
case 0x26:
|
||||||
|
kprintf("L");
|
||||||
|
break;
|
||||||
|
case 0x27:
|
||||||
|
kprintf(";");
|
||||||
|
break;
|
||||||
|
case 0x28:
|
||||||
|
kprintf("'");
|
||||||
|
break;
|
||||||
|
case 0x29:
|
||||||
|
kprintf("`");
|
||||||
|
break;
|
||||||
|
case 0x2A:
|
||||||
|
kprintf("LShift");
|
||||||
|
break;
|
||||||
|
case 0x2B:
|
||||||
|
kprintf("\\");
|
||||||
|
break;
|
||||||
|
case 0x2C:
|
||||||
|
kprintf("Z");
|
||||||
|
break;
|
||||||
|
case 0x2D:
|
||||||
|
kprintf("X");
|
||||||
|
break;
|
||||||
|
case 0x2E:
|
||||||
|
kprintf("C");
|
||||||
|
break;
|
||||||
|
case 0x2F:
|
||||||
|
kprintf("V");
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
kprintf("B");
|
||||||
|
break;
|
||||||
|
case 0x31:
|
||||||
|
kprintf("N");
|
||||||
|
break;
|
||||||
|
case 0x32:
|
||||||
|
kprintf("M");
|
||||||
|
break;
|
||||||
|
case 0x33:
|
||||||
|
kprintf(",");
|
||||||
|
break;
|
||||||
|
case 0x34:
|
||||||
|
kprintf(".");
|
||||||
|
break;
|
||||||
|
case 0x35:
|
||||||
|
kprintf("/");
|
||||||
|
break;
|
||||||
|
case 0x36:
|
||||||
|
kprintf("Rshift");
|
||||||
|
break;
|
||||||
|
case 0x37:
|
||||||
|
kprintf("Keypad *");
|
||||||
|
break;
|
||||||
|
case 0x38:
|
||||||
|
kprintf("LAlt");
|
||||||
|
break;
|
||||||
|
case 0x39:
|
||||||
|
kprintf("Spc");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* 'keuyp' event corresponds to the 'keydown' + 0x80
|
||||||
|
* it may still be a scancode we haven't implemented yet, or
|
||||||
|
* maybe a control/escape sequence */
|
||||||
|
/*
|
||||||
|
if (scancode <= 0x7f) {
|
||||||
|
kprintf("Unknown key down");
|
||||||
|
} else if (scancode <= 0x39 + 0x80) {
|
||||||
|
kprintf("key up ");
|
||||||
|
print_letter(scancode - 0x80);
|
||||||
|
} else kprintf("Unknown key up");
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,35 @@
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
#include <shade/platform/interrupts/isr.h>
|
#include <shade/platform/interrupts/isr.h>
|
||||||
|
#include <shade/platform/interrupts/pic.h>
|
||||||
|
|
||||||
void exception_handler(uint8_t vector, uint16_t err) {
|
void exception_handler(uint8_t vector, uint16_t err) {
|
||||||
|
(*interrupt_handlers[vector])(vector, err);
|
||||||
|
if (vector >= IRQ_MIN && vector <= IRQ_MAX) {
|
||||||
|
// needs EOI
|
||||||
|
pic_send_eoi(vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int register_interrupt_handler(int vector, void (*handler)(uint8_t, uint16_t)) {
|
||||||
|
interrupt_handlers[vector] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unregister_interrupt_handler(int vector) {
|
||||||
|
interrupt_handlers[vector] = default_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void default_handler(uint8_t vector, uint16_t err) {
|
||||||
kprintf(" %i: cpu: check_exception 0x%x err_code => %x\n", err_count, vector, err);
|
kprintf(" %i: cpu: check_exception 0x%x err_code => %x\n", err_count, vector, err);
|
||||||
|
kprintf(" %i: cpu: no irq for vector 0x%x\n", err_count, vector);
|
||||||
err_count++;
|
err_count++;
|
||||||
if (err_count > ERR_MAX) {
|
if (err_count > ERR_MAX) {
|
||||||
kprintf("cpu: ierr hit err_max, halt\n");
|
kprintf("cpu: ierr hit err_max, halt\n");
|
||||||
__asm__ __volatile__("cli; hlt");
|
__asm__ __volatile__("cli; hlt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fill_isr() {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
register_interrupt_handler(i, default_handler);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#include <shade/platform/interrupts/pic.h>
|
#include <shade/platform/interrupts/pic.h>
|
||||||
#include <shade/platform/ports.h>
|
#include <shade/platform/ports.h>
|
||||||
|
#include <shade/platform/interrupts/idt.h>
|
||||||
|
|
||||||
void pic_send_eoi(uint8_t irq) {
|
void pic_send_eoi(uint8_t irq) {
|
||||||
if (irq >= 8) {
|
if (irq >= 8) {
|
||||||
|
@ -37,6 +38,7 @@ void pic_remap(int offset1, int offset2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pic_mask_irq(uint8_t irq) {
|
void pic_mask_irq(uint8_t irq) {
|
||||||
|
idt_disable_interrupts();
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
|
|
||||||
|
@ -48,9 +50,11 @@ void pic_mask_irq(uint8_t irq) {
|
||||||
}
|
}
|
||||||
value = inb(port) | (1 << irq);
|
value = inb(port) | (1 << irq);
|
||||||
outb(port, value);
|
outb(port, value);
|
||||||
|
idt_enable_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pic_unmask_irq(uint8_t irq) {
|
void pic_unmask_irq(uint8_t irq) {
|
||||||
|
idt_disable_interrupts();
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
|
|
||||||
|
@ -62,6 +66,7 @@ void pic_unmask_irq(uint8_t irq) {
|
||||||
}
|
}
|
||||||
value = inb(port) & ~(1 << irq);
|
value = inb(port) & ~(1 << irq);
|
||||||
outb(port, value);
|
outb(port, value);
|
||||||
|
idt_enable_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t __pic_get_irq_reg(int ocw3) {
|
static uint16_t __pic_get_irq_reg(int ocw3) {
|
||||||
|
|
Loading…
Reference in New Issue