From ccaf2737f82968816c5ec962f936a593686cfb72 Mon Sep 17 00:00:00 2001 From: aqua Date: Wed, 2 Nov 2022 09:34:31 +0200 Subject: Add ps2_ctrl_8042 --- Makefile | 2 +- devices/Makefile | 2 +- devices/keyboard.h | 4 +++ devices/mouse.c | 30 +++++++++++++++++++ devices/mouse.h | 3 ++ devices/pckbd.c | 54 +++++++++++++++++++++++++++++++++ devices/pic_8259.c | 12 ++++++-- devices/ps2_ctrl.h | 4 +++ devices/ps2_ctrl_8042.c | 43 +++++++++++++++++++++++++++ devices/ps2_keyboard.c | 69 ------------------------------------------ devices/ps2_keyboard.h | 4 --- devices/vga.c | 79 +++++++++++++++++++++++++------------------------ devices/vga.h | 4 +-- i686/idt.h | 1 + i686/isr.c | 9 +++++- i686/lidt.c | 3 +- src/kernel.c | 7 +++++ 17 files changed, 209 insertions(+), 121 deletions(-) create mode 100644 devices/keyboard.h create mode 100644 devices/mouse.c create mode 100644 devices/mouse.h create mode 100644 devices/pckbd.c create mode 100644 devices/ps2_ctrl.h create mode 100644 devices/ps2_ctrl_8042.c delete mode 100644 devices/ps2_keyboard.c delete mode 100644 devices/ps2_keyboard.h diff --git a/Makefile b/Makefile index 9937467..6adc710 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ all: @${MAKE} ARCH=${ARCH} -C src all run: glitch.iso - qemu-system-i386 -cdrom glitch.iso -accel kvm -d cpu_reset -display gtk,zoom-to-fit=on + qemu-system-i386 -cdrom glitch.iso -cpu pentium3 -d cpu_reset -display gtk,zoom-to-fit=on clean: @${MAKE} ARCH=${ARCH} -C lib clean diff --git a/devices/Makefile b/devices/Makefile index 30935c5..4ee04ca 100644 --- a/devices/Makefile +++ b/devices/Makefile @@ -2,7 +2,7 @@ include ../Makefile.config CCFLAGS += -I. -I../${ARCH} -I../lib -devs,SRCS = pic_8259.c uart_16550.c vga.c ps2_keyboard.c +devs,SRCS = pic_8259.c uart_16550.c vga.c ps2_ctrl_8042.c pckbd.c mouse.c include ../rules.mk diff --git a/devices/keyboard.h b/devices/keyboard.h new file mode 100644 index 0000000..5f4fcc2 --- /dev/null +++ b/devices/keyboard.h @@ -0,0 +1,4 @@ +#pragma once + +void ps2_keyboard_init(); +void ps2_keyboard_irq_handler(); diff --git a/devices/mouse.c b/devices/mouse.c new file mode 100644 index 0000000..92f3f08 --- /dev/null +++ b/devices/mouse.c @@ -0,0 +1,30 @@ +#include "mouse.h" +#include +#include +#include + +// TODO: All output to port 0x60 or 0x64 must be preceded by waiting for bit 1 (value=2) of port 0x64 to become clear. +// TODO: Similarly, bytes cannot be read from port 0x60 until bit 0 (value=1) of port 0x64 is set. + +void +mouse_init() +{ + // Sending a command or data byte to the mouse (to port 0x60) must be preceded by sending a 0xD4 byte to port 0x64 + // (with appropriate waits on port 0x64, bit 1, before sending each output byte). Note: this 0xD4 byte does not + // generate any ACK, from either the keyboard or mouse. + + // enable second ps/2 + // outb(0x64, 0xa8); + + // outb(0x64, 0xd4); + // outb(0x60, 0xf4); + // printf("mouse_init: enable streaming(0xf4): %x\n", inb(0x60)); + + /* + outb(0x64, 0xd4); + while (inb(0x64) & 0x1) + ; + outb(0x60, 0xf2); + printf("mouse_init: mouse_id(0xf2 %x): %x\n", inb(0x60), inb(0x60)); + */ +} diff --git a/devices/mouse.h b/devices/mouse.h new file mode 100644 index 0000000..a34ecb4 --- /dev/null +++ b/devices/mouse.h @@ -0,0 +1,3 @@ +#pragma once + +void mouse_init(); diff --git a/devices/pckbd.c b/devices/pckbd.c new file mode 100644 index 0000000..f3dcb6c --- /dev/null +++ b/devices/pckbd.c @@ -0,0 +1,54 @@ +#include "keyboard.h" +#include "ps2_ctrl.h" +#include "vga.h" +#include +#include +#include + +const char scancodes[2][68] = {{'E', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', + 'T', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', + 'C', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 'L', + '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 'R', 'P', 'A', + ' ', 'C', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}, + {'E', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', 'T', 'Q', 'W', + 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 'C', 'A', 'S', 'D', 'F', 'G', + 'H', 'J', 'K', 'L', ':', '"', '~', 'L', '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', + '>', '?', 'R', 'P', 'A', ' ', 'C', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}}; +int shift_case = 0; + +void +ps2_keyboard_init() +{ +} + +void +ps2_keyboard_irq_handler() +{ + const uint8_t key = ps2_ctrl_read(); + + switch (key) { + case 0x2a: // left shift down + case 0x36: // right shift down + shift_case = 1; + return; + + case 0xaa: // left shift up + case 0xb6: // right shift up + shift_case = 0; + return; + + case 0x5b: // left meta + case 0x5c: // right meta + return; + + case 0x58: // F12 + vga_clear(VGA_COLOR_LIGHT_BLUE, VGA_COLOR_LIGHT_GREY); + return; + } + + if (key >= 0x80) return; + + if (key < (sizeof(scancodes[0]) / sizeof(const char))) printf("%c", scancodes[shift_case][key - 1]); + else + printf("key pressed: %x\n", key); +} diff --git a/devices/pic_8259.c b/devices/pic_8259.c index 62164d3..d3a2f6a 100644 --- a/devices/pic_8259.c +++ b/devices/pic_8259.c @@ -36,9 +36,15 @@ pic_init() void pic_enable() { - // PIC masks - outb(0xfc, PIC1 + DATA); - outb(0xff, PIC2 + DATA); + unsigned char mask1 = 0xff; + mask1 &= ~(1 << 0); // irq0 timer + mask1 &= ~(1 << 1); // irq1 keyboard + // mask1 &= ~(1 << 2); // irq1 cascade + outb(mask1, PIC1 + DATA); + + unsigned char mask2 = 0xff; + // mask2 &= ~(1 << 4); // irq12 mouse + outb(mask2, PIC2 + DATA); enable_interrupts(); } diff --git a/devices/ps2_ctrl.h b/devices/ps2_ctrl.h new file mode 100644 index 0000000..9bed4f2 --- /dev/null +++ b/devices/ps2_ctrl.h @@ -0,0 +1,4 @@ +#pragma once + +void ps2_ctrl_init(); +unsigned char ps2_ctrl_read(); diff --git a/devices/ps2_ctrl_8042.c b/devices/ps2_ctrl_8042.c new file mode 100644 index 0000000..4157bd8 --- /dev/null +++ b/devices/ps2_ctrl_8042.c @@ -0,0 +1,43 @@ +#include "ps2_ctrl.h" +#include +#include +#include + +const uint8_t comm_port = 0x64; // r status register + // w command register +const uint8_t comm_enable_first_ps2 = 0xae; +const uint8_t comm_read_ctrl_config = 0x20; +const uint8_t comm_write_ctrl_config = 0x60; + +const uint8_t data_port = 0x60; // rw +const uint8_t data_enable_scanning = 0xf4; + +void +ps2_ctrl_init() +{ + // eat all previous keystrikes + while (inb(comm_port) & 0x1) inb(data_port); + + outb(0x64, 0xaa); + printf("8042: self test 0xaa: %x\n", inb(0x60)); + outb(0x64, 0xab); + printf("8042: port1 test 0xab: %x\n", inb(0x60)); + outb(0x64, 0xa9); + printf("8042: port2 test 0xa9: %x\n", inb(0x60)); + + // printf("8042: init keyboard\n"); + + outb(comm_port, comm_enable_first_ps2); + outb(comm_port, comm_read_ctrl_config); + const uint8_t conf = (inb(data_port) | 1) & ~0x10; + outb(comm_port, comm_write_ctrl_config); + outb(data_port, conf); + outb(data_port, data_enable_scanning); + +} + +unsigned char +ps2_ctrl_read() +{ + return inb(0x60); +} diff --git a/devices/ps2_keyboard.c b/devices/ps2_keyboard.c deleted file mode 100644 index 4ebcc65..0000000 --- a/devices/ps2_keyboard.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "ps2_keyboard.h" -#include "vga.h" -#include -#include -#include - -const uint8_t comm_port = 0x64; // r status register - // w command register -const uint8_t comm_enable_first_ps2 = 0xae; -const uint8_t comm_read_ctrl_config = 0x20; -const uint8_t comm_write_ctrl_config = 0x60; -const uint8_t data_port = 0x60; // rw -const uint8_t data_enable_scanning = 0xf4; - -const char scancodes[2][68] = {{'E', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', - 'T', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', - 'C', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 'L', - '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 'R', 'P', 'A', - ' ', 'C', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}, - {'E', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 'T', 'Q', 'W', - 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 'C', 'A', 'S', 'D', 'F', 'G', - 'H', 'J', 'K', 'L', ':', '"', '~', 'L', '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', - '>', '?', 'R', 'P', 'A', ' ', 'C', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}}; -int shift_case = 0; - -void -ps2_keyboard_init() -{ - // eat all previous keystrikes - while (inb(comm_port) & 0x1) inb(data_port); - outb(comm_port, comm_enable_first_ps2); - outb(comm_port, comm_read_ctrl_config); - const uint8_t conf = (inb(data_port) | 1) & ~0x10; - outb(comm_port, comm_write_ctrl_config); - outb(data_port, conf); - outb(data_port, data_enable_scanning); -} - -void -ps2_keyboard_irq_handler() -{ - const uint8_t key = inb(data_port); - - switch (key) { - case 0x2a: // left shift down - case 0x36: // right shift down - shift_case = 1; - return; - - case 0xaa: // left shift up - case 0xb6: // right shift up - shift_case = 0; - return; - - case 0x5b: // left meta - case 0x5c: // right meta - return; - - case 0x58: // F12 - vga_clear(VGA_COLOR_LIGHT_BLUE, VGA_COLOR_LIGHT_GREY); - return; - } - - if (key >= 0x80) return; - - if (key < (sizeof(scancodes[0]) / sizeof(const char))) printf("%c", scancodes[shift_case][key - 1]); - else - printf("key pressed: %x\n", key); -} diff --git a/devices/ps2_keyboard.h b/devices/ps2_keyboard.h deleted file mode 100644 index 5f4fcc2..0000000 --- a/devices/ps2_keyboard.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -void ps2_keyboard_init(); -void ps2_keyboard_irq_handler(); diff --git a/devices/vga.c b/devices/vga.c index 93231ea..aeda483 100644 --- a/devices/vga.c +++ b/devices/vga.c @@ -2,6 +2,15 @@ #include #include +const uint16_t cga_idx_port = 0x3d4; +const uint16_t cga_dat_port = 0x3d5; + +const uint8_t cursor_start = 0xa; +const uint8_t cursor_end = 0xb; +const uint8_t cursor_addr_h = 0xe; +const uint8_t cursor_addr_l = 0xf; +const uint8_t cursor_hide = 0x20; + struct __attribute__((packed)) VGAEntry { unsigned char text; uint8_t foreground : 4; @@ -16,6 +25,37 @@ struct VGAEntry *buffer; int col = 0; int row = 0; +// *** Cursor *** +void +vga_enable_cursor(unsigned char start, unsigned char end) +{ + outb(cga_idx_port, cursor_start); + outb(cga_dat_port, (inb(cga_dat_port) & 0xc0) | start); + + outb(cga_idx_port, cursor_end); + outb(cga_dat_port, (inb(cga_dat_port) & 0xe0) | end); +} + +void +vga_disable_cursor() +{ + outb(cga_idx_port, cursor_start); + outb(cga_dat_port, cursor_hide); +} + +void +vga_update_cursor() +{ + const uint16_t pos = row * width + col; + + outb(cga_idx_port, cursor_addr_l); + outb(cga_dat_port, pos & 0xff); + + outb(cga_idx_port, cursor_addr_h); + outb(cga_dat_port, (pos >> 8) & 0xff); +} + +// *** Text Mode *** void vga_init() { @@ -90,42 +130,3 @@ vga_puts(const char *string, int len) else for (int i = 0; i < len; ++i) { vga_putc(string[i]); } } - -// Cursor -const uint16_t cga_idx_port = 0x3d4; -const uint16_t cga_dat_port = 0x3d5; - -const uint8_t cursor_start = 0xa; -const uint8_t cursor_end = 0xb; -const uint8_t cursor_addr_h = 0xe; -const uint8_t cursor_addr_l = 0xf; -const uint8_t cursor_hide = 0x20; - -void -vga_enable_cursor(unsigned char start, unsigned char end) -{ - outb(cga_idx_port, cursor_start); - outb(cga_dat_port, (inb(cga_dat_port) & 0xc0) | start); - - outb(cga_idx_port, cursor_end); - outb(cga_dat_port, (inb(cga_dat_port) & 0xe0) | end); -} - -void -vga_disable_cursor() -{ - outb(cga_idx_port, cursor_start); - outb(cga_dat_port, cursor_hide); -} - -void -vga_update_cursor() -{ - const uint16_t pos = row * width + col; - - outb(cga_idx_port, cursor_addr_l); - outb(cga_dat_port, pos & 0xff); - - outb(cga_idx_port, cursor_addr_h); - outb(cga_dat_port, (pos >> 8) & 0xff); -} diff --git a/devices/vga.h b/devices/vga.h index 63de309..7a295a2 100644 --- a/devices/vga.h +++ b/devices/vga.h @@ -26,6 +26,6 @@ void vga_clear(enum vga_color foreground, enum vga_color background); void vga_putc(char a); void vga_puts(const char *string, int len); -void vga_enable_cursor(unsigned char start, unsigned char end); -void vga_disable_cursor(); +// void vga_enable_cursor(unsigned char start, unsigned char end); +// void vga_disable_cursor(); void vga_update_cursor(); diff --git a/i686/idt.h b/i686/idt.h index f96e2b1..45744dc 100644 --- a/i686/idt.h +++ b/i686/idt.h @@ -17,6 +17,7 @@ void abort_handler(struct interrupt_frame *frame); void syscall_handler(struct interrupt_frame *frame); void irq0x00(struct interrupt_frame *frame); // timer interrupt void irq0x01(struct interrupt_frame *frame); // keyboard interrupt +void irq0x0c(struct interrupt_frame *frame); // mouse interrupt /* lidt.c */ void idt_install(); diff --git a/i686/isr.c b/i686/isr.c index 3f99425..6fbe200 100644 --- a/i686/isr.c +++ b/i686/isr.c @@ -36,5 +36,12 @@ __attribute__((interrupt)) void irq0x01(struct interrupt_frame *) { ps2_keyboard_irq_handler(); - pic_clear(0x00); + pic_clear(0x01); +} + +__attribute__((interrupt)) void +irq0x0c(struct interrupt_frame *) +{ + printf("irq 0x0c\n"); + pic_clear(0x0c); } diff --git a/i686/lidt.c b/i686/lidt.c index 5cb66b6..8a70bf3 100644 --- a/i686/lidt.c +++ b/i686/lidt.c @@ -41,9 +41,10 @@ idt_install() for (int i = 0; i <= 0x13; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); // irq 0x20~0x2f + for (int i = 0x22; i <= 0x2f; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); Gate(&interrupt_table[0x20], &irq0x00, 0x10); Gate(&interrupt_table[0x21], &irq0x01, 0x10); - for (int i = 0x22; i <= 0x2f; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + Gate(&interrupt_table[0x2c], &irq0x0c, 0x10); // syscall 0x80 Gate(&interrupt_table[0x80], &abort_handler, 0x10); diff --git a/src/kernel.c b/src/kernel.c index 4698d7a..5305b12 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -4,7 +4,10 @@ // description: kernel entry point //===================================================================== +#include "devices/keyboard.h" +#include "devices/mouse.h" #include "devices/pic.h" +#include "devices/ps2_ctrl.h" #include "devices/uart_16550.h" #include "devices/vga.h" #include "mem.h" @@ -30,6 +33,10 @@ void kmain() { pic_enable(); printf("interrupts enabled\n"); + ps2_ctrl_init(); + ps2_keyboard_init(); + // mouse_init(); + /* alloc4M(); char *c = (char *)0xc0700000; -- cgit v1.2.1