#include #include using namespace hilbert::kernel; struct [[gnu::packed]] exception_info_t { uint64_t rax; uint64_t rbx; uint64_t rcx; uint64_t rdx; uint64_t rdi; uint64_t rsi; uint64_t rbp; uint64_t rsp; uint64_t r8; uint64_t r9; uint64_t r10; uint64_t r11; uint64_t r12; uint64_t r13; uint64_t r14; uint64_t r15; uint64_t cr2; uint64_t cr3; uint64_t rip; uint64_t rflags; uint64_t error; uint8_t has_error;//0 or 1 uint8_t exception_number; }; extern exception_info_t exception_info; extern "C" [[noreturn]] void print_exception() { //so exception_info's type is known by gdb exception_info_t the_exception_info = exception_info; (void)the_exception_info; //TODO: log exception, and recover if possible. panic(0xba40bb); } static uint32_t current_flags = 0; #define SETBIT(field, bit, cond) \ field = (cond) ? (field | (bit)) : (field & ~(bit)); static void got_key(uint32_t key) { input::key_queue->insert(current_flags | key); input::got_input(); if (key == (input::BREAK | 0x77)) current_flags ^= input::NUM_LOCK; else if (key == (input::BREAK | 0x58)) current_flags ^= input::CAPS_LOCK; else if ((key & 0xff) == 0xa7) SETBIT(current_flags, input::RIGHT_WIN, !(key & input::BREAK)) else if ((key & 0xff) == 0x9f) SETBIT(current_flags, input::LEFT_WIN, !(key & input::BREAK)) else if ((key & 0xff) == 0x91) SETBIT(current_flags, input::RIGHT_ALT, !(key & input::BREAK)) else if ((key & 0xff) == 0x11) SETBIT(current_flags, input::LEFT_ALT, !(key & input::BREAK)) else if ((key & 0xff) == 0x94) SETBIT(current_flags, input::RIGHT_CTRL, !(key & input::BREAK)) else if ((key & 0xff) == 0x14) SETBIT(current_flags, input::LEFT_CTRL, !(key & input::BREAK)) else if ((key & 0xff) == 0x59) SETBIT(current_flags, input::RIGHT_SHIFT, !(key & input::BREAK)) else if ((key & 0xff) == 0x12) SETBIT(current_flags, input::LEFT_SHIFT, !(key & input::BREAK)) } static uint8_t key_so_far[8]; uint8_t key_so_far_len = 0; extern "C" void on_keyboard_interrupt(uint8_t byte) { key_so_far[key_so_far_len++] = byte; if (key_so_far_len == 1) { if (byte != 0xe0 && byte != 0xe1 && byte != 0xf0) { got_key(byte); key_so_far_len = 0; } } else if (key_so_far_len == 2) { if (key_so_far[0] == 0xe0 && byte != 0xf0 && byte != 0x12) { got_key(byte | 0x80); key_so_far_len = 0; } else if (key_so_far[0] == 0xf0) { got_key(input::BREAK | byte); key_so_far_len = 0; } } else if (key_so_far_len == 3) { if (key_so_far[0] == 0xe0 && key_so_far[1] == 0xf0 && byte != 0x7c) { got_key(input::BREAK | byte | 0x80); key_so_far_len = 0; } } else if (key_so_far_len == 4) { if (key_so_far[0] == 0xe0 && key_so_far[1] == 0x12 && key_so_far[2] == 0xe0 && byte == 0x7c) { got_key(0xe0); key_so_far_len = 0; } } else if (key_so_far_len == 6) { if (key_so_far[0] == 0xe0 && key_so_far[1] == 0xf0 && key_so_far[2] == 0x7c && key_so_far[3] == 0xe0 && key_so_far[4] == 0xf0 && byte == 0x12) { got_key(input::BREAK | 0xe0); key_so_far_len = 0; } } else if (key_so_far_len == 8) { if (key_so_far[0] == 0xe1 && key_so_far[1] == 0x14 && key_so_far[2] == 0x77 && key_so_far[3] == 0xe1 && key_so_far[2] == 0xf0 && key_so_far[3] == 0x14 && key_so_far[4] == 0xf0 && byte == 0x77) { got_key(0xe1); got_key(input::BREAK | 0xe1); } key_so_far_len = 0; } }