Compare commits

..

No commits in common. "51214ea1bf9144e2574e850f4f584da76fec65ad" and "40f55be587f28c4e037233a237c720bd2ceda2fd" have entirely different histories.

32 changed files with 789 additions and 1421 deletions

Binary file not shown.

View File

@ -13,10 +13,12 @@
.global stage1_main .global stage1_main
stage1_main: stage1_main:
# setup segments and stack # setup segments
xorw %ax, %ax movw $0, %ax
movw %ax, %ds movw %ax, %ds
movw %ax, %es movw %ax, %es
# setup stack
movw %ax, %ss movw %ax, %ss
movl $0x7C00, %esp movl $0x7C00, %esp
@ -51,8 +53,6 @@ stage2_main:
movw $hello_msg, %si movw $hello_msg, %si
call puts; call print_newline call puts; call print_newline
lgdt gdtr
call enter_unreal_mode call enter_unreal_mode
movw $unreal_enter_msg, %si movw $unreal_enter_msg, %si
call puts; call print_newline call puts; call print_newline
@ -86,32 +86,32 @@ stage2_main:
cli cli
# kernel entry point
movl %eax, %ecx
# setup kernel parameters
movl $0xD3C60CFF, %eax
movl $banan_boot_info, %ebx
# setup protected mode # setup protected mode
movl %cr0, %edx movl %cr0, %ebx
orb $1, %dl orb $1, %bl
movl %edx, %cr0 movl %ebx, %cr0
# jump to protected mode # jump to kernel in protected mode
ljmpl $0x18, $protected_mode ljmpl $0x18, $protected_mode
.code32 .code32
protected_mode: protected_mode:
# setup protected mode segments movw $0x10, %bx
movw $0x10, %dx movw %bx, %ds
movw %dx, %ds movw %bx, %es
movw %dx, %es movw %bx, %fs
movw %dx, %fs movw %bx, %gs
movw %dx, %gs movw %bx, %ss
movw %dx, %ss
movl %eax, %ecx
movl $0xD3C60CFF, %eax
movl $banan_boot_info, %ebx
xorl %edx, %edx
xorl %esi, %esi
xorl %edi, %edi
# jump to kernel entry
jmp *%ecx jmp *%ecx
@ -120,6 +120,8 @@ enter_unreal_mode:
cli cli
pushw %ds pushw %ds
lgdt gdtr
movl %cr0, %eax movl %cr0, %eax
orb $1, %al orb $1, %al
movl %eax, %cr0 movl %eax, %cr0
@ -150,9 +152,9 @@ start_kernel_load_msg:
gdt: gdt:
.quad 0x0000000000000000 .quad 0x0000000000000000
.quad 0x008F9A000000FFFF # 16-bit code .quad 0x00009A000000FFFF
.quad 0x00CF92000000FFFF # 32-bit data .quad 0x00CF92000000FFFF
.quad 0x00CF9A000000FFFF # 32-bit code .quad 0x00CF9A000000FFFF
gdtr: gdtr:
.short . - gdt - 1 .short . - gdt - 1
.quad gdt .quad gdt

View File

@ -32,8 +32,6 @@ set(KERNEL_SOURCES
kernel/FS/TmpFS/FileSystem.cpp kernel/FS/TmpFS/FileSystem.cpp
kernel/FS/TmpFS/Inode.cpp kernel/FS/TmpFS/Inode.cpp
kernel/FS/VirtualFileSystem.cpp kernel/FS/VirtualFileSystem.cpp
kernel/Input/KeyboardLayout.cpp
kernel/Input/KeyEvent.cpp
kernel/Input/PS2/Controller.cpp kernel/Input/PS2/Controller.cpp
kernel/Input/PS2/Device.cpp kernel/Input/PS2/Device.cpp
kernel/Input/PS2/Keyboard.cpp kernel/Input/PS2/Keyboard.cpp

View File

@ -11,6 +11,10 @@ namespace Kernel
ACPI_NoRootSDT, ACPI_NoRootSDT,
ACPI_NoSuchHeader, ACPI_NoSuchHeader,
ACPI_RootInvalid, ACPI_RootInvalid,
PS2_Timeout,
PS2_SelfTest,
PS2_Reset,
PS2_UnsupportedDevice,
Ext2_Invalid, Ext2_Invalid,
Ext2_Corrupted, Ext2_Corrupted,
Ext2_NoInodes, Ext2_NoInodes,

View File

@ -5,47 +5,6 @@
namespace Kernel::Input namespace Kernel::Input
{ {
/*
Key Code:
bits 4:0 column (from left)
bits 7:5 row (from top)
*/
#define BANAN_CONSTEVAL_STATIC_ASSERT(cond) do { int dummy = 1 / (cond); } while (false)
consteval uint8_t keycode_function(uint8_t index)
{
BANAN_CONSTEVAL_STATIC_ASSERT(index <= 0b11111);
return index;
}
consteval uint8_t keycode_normal(uint8_t row, uint8_t col)
{
BANAN_CONSTEVAL_STATIC_ASSERT(row <= 0b111 - 1);
BANAN_CONSTEVAL_STATIC_ASSERT(col < 0b11111 - 8);
return ((row + 1) << 5) | col;
}
consteval uint8_t keycode_numpad(uint8_t row, uint8_t col)
{
BANAN_CONSTEVAL_STATIC_ASSERT(row <= 0b111 - 1);
BANAN_CONSTEVAL_STATIC_ASSERT(col <= 8);
return ((row + 1) << 5) | (col + 0b11111 - 8);
}
enum ModifierKeycode
{
CapsLock = keycode_normal(2, 0),
NumLock = keycode_numpad(0, 0),
ScrollLock = keycode_function(20),
LShift = keycode_normal(3, 0),
RShift = keycode_normal(3, 12),
LCtrl = keycode_normal(4, 0),
RCtrl = keycode_normal(4, 5),
LAlt = keycode_normal(4, 2),
RAlt = keycode_normal(4, 4),
};
enum class Key enum class Key
{ {
Invalid, None, Invalid, None,
@ -55,9 +14,9 @@ namespace Kernel::Input
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
Insert, PrintScreen, Delete, Home, End, PageUp, PageDown, Enter, Space, Insert, PrintScreen, Delete, Home, End, PageUp, PageDown, Enter, Space,
ExclamationMark, DoubleQuote, Hashtag, Currency, Percent, Ampersand, Slash, Section, Half, ExclamationMark, DoubleQuote, Hashtag, Currency, Percent, Ampersand, Slash, Section, Half,
OpenParenthesis, CloseParenthesis, OpenSquareBracket, CloseSquareBracket, OpenCurlyBracket, CloseCurlyBracket, OpenBracet, CloseBracet, OpenBrace, CloseBrace, OpenCurlyBrace, CloseCurlyBrace,
Equals, QuestionMark, Plus, BackSlash, Acute, BackTick, TwoDots, Cedilla, Backspace, AtSign, Pound, Dollar, Euro, Equals, QuestionMark, Plus, BackSlash, Acute, BackTick, TwoDots, Backspace, AtSign, Pound, Dollar, Euro,
Escape, Tab, CapsLock, LeftShift, LeftCtrl, Super, LeftAlt, RightAlt, AltGr = RightAlt, RightCtrl, RightShift, Escape, Tab, CapsLock, LeftShift, LeftCtrl, Super, Alt, AltGr, RightCtrl, RightShift,
SingleQuote, Asterix, Caret, Tilde, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, SingleQuote, Asterix, Caret, Tilde, ArrowUp, ArrowDown, ArrowLeft, ArrowRight,
Comma, Semicolon, Period, Colon, Hyphen, Underscore, NumLock, ScrollLock, LessThan, GreaterThan, Pipe, Comma, Semicolon, Period, Colon, Hyphen, Underscore, NumLock, ScrollLock, LessThan, GreaterThan, Pipe,
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9, Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
@ -68,44 +27,73 @@ namespace Kernel::Input
struct KeyEvent struct KeyEvent
{ {
enum Modifier : uint16_t enum class Modifier : uint8_t
{ {
LShift = (1 << 0), Shift = (1 << 0),
RShift = (1 << 1), Ctrl = (1 << 1),
LCtrl = (1 << 2), Alt = (1 << 2),
RCtrl = (1 << 3), AltGr = (1 << 3),
LAlt = (1 << 4), CapsLock = (1 << 4),
RAlt = (1 << 5), NumLock = (1 << 5),
CapsLock = (1 << 6), ScrollLock = (1 << 6),
NumLock = (1 << 7), Released = (1 << 7),
ScrollLock = (1 << 8),
Pressed = (1 << 9),
}; };
bool lshift() const { return modifier & Modifier::LShift; } bool shift() const { return modifier & (uint8_t)Modifier::Shift; }
bool rshift() const { return modifier & Modifier::RShift; } bool ctrl() const { return modifier & (uint8_t)Modifier::Ctrl; }
bool shift() const { return lshift() || rshift(); } bool alt() const { return modifier & (uint8_t)Modifier::Alt; }
bool altgr() const { return modifier & (uint8_t)Modifier::AltGr; }
bool caps_lock() const { return modifier & (uint8_t)Modifier::CapsLock; }
bool num_lock() const { return modifier & (uint8_t)Modifier::NumLock; }
bool scroll_lock() const { return modifier & (uint8_t)Modifier::ScrollLock; }
bool released() const { return modifier & (uint8_t)Modifier::Released; }
bool pressed() const { return !released(); }
bool lctrl() const { return modifier & Modifier::LCtrl; } uint8_t modifier;
bool rctrl() const { return modifier & Modifier::RCtrl; } Key key;
bool ctrl() const { return lctrl() || rctrl(); }
bool lalt() const { return modifier & Modifier::LAlt; }
bool ralt() const { return modifier & Modifier::RAlt; }
bool alt() const { return lalt() || ralt(); }
bool caps_lock() const { return modifier & Modifier::CapsLock; }
bool num_lock() const { return modifier & Modifier::NumLock; }
bool scroll_lock() const { return modifier & Modifier::ScrollLock; }
bool pressed() const { return modifier & Modifier::Pressed; }
bool released() const { return !pressed(); }
uint16_t modifier;
uint8_t keycode;
}; };
Key key_event_to_key(KeyEvent); inline const char* key_event_to_utf8(KeyEvent event)
const char* key_to_utf8(Key key, uint16_t modifier); {
static constexpr const char* utf8_lower[] = {
nullptr, nullptr,
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"å", "ä", "ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
"(", ")", "[", "]", "{", "}",
"=", "?", "+", "\\", "´", "`", "¨", nullptr, "@", "£", "$", "",
nullptr, "\t", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"'", "*", "^", "~", nullptr, nullptr, nullptr, nullptr,
",", ";", ".", ":", "-", "_", nullptr, nullptr, "<", ">", "|",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"+", "-", "*", "/", nullptr, ",",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
};
static_assert((size_t)Key::Count == sizeof(utf8_lower) / sizeof(*utf8_lower));
static constexpr const char* utf8_upper[] = {
nullptr, nullptr,
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"Å", "Ä", "Ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
"(", ")", "[", "]", "{", "}",
"=", "?", "+", "\\", "´", "`", "¨", nullptr, "@", "£", "$", "",
nullptr, "\t", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"'", "*", "^", "~", nullptr, nullptr, nullptr, nullptr,
",", ";", ".", ":", "-", "_", nullptr, nullptr, "<", ">", "|",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"+", "-", "*", "/", nullptr, ",",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
};
static_assert((size_t)Key::Count == sizeof(utf8_upper) / sizeof(*utf8_lower));
return (event.shift() ^ event.caps_lock()) ? utf8_upper[(uint8_t)event.key] : utf8_lower[(uint8_t)event.key];
}
} }

View File

@ -1,30 +0,0 @@
#pragma once
#include <BAN/Array.h>
#include <BAN/UniqPtr.h>
#include <kernel/Input/KeyEvent.h>
namespace Kernel::Input
{
class KeyboardLayout
{
public:
static BAN::ErrorOr<void> initialize();
static KeyboardLayout& get();
Key get_key_from_event(KeyEvent);
BAN::ErrorOr<void> load_from_file(BAN::StringView path);
private:
KeyboardLayout();
private:
BAN::Array<Key, 0xFF> m_keycode_to_key_normal;
BAN::Array<Key, 0xFF> m_keycode_to_key_shift;
BAN::Array<Key, 0xFF> m_keycode_to_key_altgr;
friend class BAN::UniqPtr<KeyboardLayout>;
};
}

View File

@ -14,8 +14,8 @@ namespace Kernel::Input::PS2
enum Status : uint8_t enum Status : uint8_t
{ {
OUTPUT_STATUS = (1 << 0), OUTPUT_FULL = (1 << 0),
INPUT_STATUS = (1 << 1), INPUT_FULL = (1 << 1),
SYSTEM = (1 << 2), SYSTEM = (1 << 2),
DEVICE_OR_CONTROLLER = (1 << 3), DEVICE_OR_CONTROLLER = (1 << 3),
TIMEOUT_ERROR = (1 << 6), TIMEOUT_ERROR = (1 << 6),
@ -78,6 +78,13 @@ namespace Kernel::Input::PS2
KEY_ERROR_OR_BUFFER_OVERRUN2 = 0xFF, KEY_ERROR_OR_BUFFER_OVERRUN2 = 0xFF,
}; };
enum KBScancode : uint8_t
{
SET_SCANCODE_SET1 = 1,
SET_SCANCODE_SET2 = 2,
SET_SCANCODE_SET3 = 3,
};
enum KBLeds : uint8_t enum KBLeds : uint8_t
{ {
SCROLL_LOCK = (1 << 0), SCROLL_LOCK = (1 << 0),

View File

@ -1,11 +1,8 @@
#pragma once #pragma once
#include <BAN/CircularQueue.h> #include <BAN/CircularQueue.h>
#include <BAN/UniqPtr.h>
#include <kernel/Device/Device.h> #include <kernel/Device/Device.h>
#include <kernel/Input/PS2/Config.h>
#include <kernel/InterruptController.h> #include <kernel/InterruptController.h>
#include <kernel/SpinLock.h>
namespace Kernel::Input namespace Kernel::Input
{ {
@ -18,50 +15,18 @@ namespace Kernel::Input
static BAN::ErrorOr<void> initialize(); static BAN::ErrorOr<void> initialize();
static PS2Controller& get(); static PS2Controller& get();
bool append_command_queue(PS2Device*, uint8_t command, uint8_t response_size); void send_byte(const PS2Device*, uint8_t);
bool append_command_queue(PS2Device*, uint8_t command, uint8_t data, uint8_t response_size);
void update_command_queue();
// Returns true, if byte is used as command, if returns false, byte is meant to device
bool handle_command_byte(PS2Device*, uint8_t);
private: private:
PS2Controller() = default; PS2Controller() = default;
BAN::ErrorOr<void> initialize_impl(); BAN::ErrorOr<void> initialize_impl();
BAN::ErrorOr<void> initialize_device(uint8_t); BAN::ErrorOr<void> initialize_device(uint8_t);
BAN::ErrorOr<uint8_t> read_byte(); BAN::ErrorOr<void> reset_device(uint8_t);
BAN::ErrorOr<void> send_byte(uint16_t port, uint8_t byte); BAN::ErrorOr<void> set_scanning(uint8_t, bool);
BAN::ErrorOr<void> send_command(PS2::Command command);
BAN::ErrorOr<void> send_command(PS2::Command command, uint8_t data);
BAN::ErrorOr<void> device_send_byte(uint8_t device_index, uint8_t byte);
BAN::ErrorOr<void> device_send_byte_and_wait_ack(uint8_t device_index, uint8_t byte);
private: private:
struct Command PS2Device* m_devices[2] { nullptr, nullptr };
{
enum class State : uint8_t
{
NotSent,
Sending,
WaitingAck,
WaitingResponse,
};
State state;
uint8_t device_index;
uint8_t out_data[2];
uint8_t out_count;
uint8_t in_count;
uint8_t send_index;
};
private:
BAN::RefPtr<PS2Device> m_devices[2];
RecursiveSpinLock m_lock;
BAN::CircularQueue<Command, 128> m_command_queue;
uint64_t m_command_send_time { 0 };
}; };
} }

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <kernel/Input/PS2/Controller.h> #include <kernel/Input/PS2/Controller.h>
#include <kernel/InterruptController.h>
namespace Kernel::Input namespace Kernel::Input
{ {
@ -14,23 +13,33 @@ namespace Kernel::Input
virtual void send_initialize() = 0; virtual void send_initialize() = 0;
virtual void command_timedout(uint8_t* command_data, uint8_t command_size) = 0; bool append_command_queue(uint8_t command);
bool append_command_queue(uint8_t command, uint8_t data);
bool append_command_queue(uint8_t command, uint8_t response_size);
bool append_command_queue(uint8_t command, uint8_t data, uint8_t response_size);
virtual void handle_irq() final override; virtual void handle_irq() final override;
virtual void handle_byte(uint8_t) = 0; virtual void handle_byte(uint8_t) = 0;
virtual void handle_device_command_response(uint8_t) = 0;
virtual BAN::StringView name() const final override { return m_name; } virtual BAN::StringView name() const final override { return m_name; }
virtual dev_t rdev() const final override { return m_rdev; } virtual dev_t rdev() const final override { return m_rdev; }
virtual void update() final override { m_controller.update_command_queue(); } private:
void update();
private:
enum class State
{
Normal,
WaitingAck,
};
private: private:
const BAN::String m_name; const BAN::String m_name;
const dev_t m_rdev; const dev_t m_rdev;
PS2Controller& m_controller;
PS2Controller& m_controller;
State m_state = State::Normal;
BAN::CircularQueue<uint8_t, 10> m_command_queue;
}; };
} }

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <BAN/Array.h>
#include <BAN/CircularQueue.h>
#include <kernel/Input/KeyEvent.h> #include <kernel/Input/KeyEvent.h>
#include <kernel/Input/PS2/Device.h> #include <kernel/Input/PS2/Device.h>
#include <kernel/Input/PS2/Keymap.h> #include <kernel/Input/PS2/Keymap.h>
@ -16,16 +14,15 @@ namespace Kernel::Input
enum Command : uint8_t enum Command : uint8_t
{ {
SET_LEDS = 0xED, SET_LEDS = 0xED,
CONFIG_SCANCODE_SET = 0xF0 SCANCODE = 0xF0
}; };
public: public:
static BAN::ErrorOr<PS2Keyboard*> create(PS2Controller&); static BAN::ErrorOr<PS2Keyboard*> create(PS2Controller&);
virtual void send_initialize() override; virtual void send_initialize() override;
virtual void command_timedout(uint8_t* command_data, uint8_t command_size) final override;
virtual void handle_byte(uint8_t) final override; virtual void handle_byte(uint8_t) final override;
virtual void handle_device_command_response(uint8_t) final override;
private: private:
PS2Keyboard(PS2Controller& controller); PS2Keyboard(PS2Controller& controller);
@ -33,14 +30,12 @@ namespace Kernel::Input
void update_leds(); void update_leds();
private: private:
BAN::Array<uint8_t, 3> m_byte_buffer; uint8_t m_byte_buffer[10];
uint8_t m_byte_index { 0 }; uint8_t m_byte_index { 0 };
uint8_t m_scancode_set { 0xFF }; uint8_t m_modifiers { 0 };
uint16_t m_modifiers { 0 }; BAN::CircularQueue<KeyEvent, 10> m_event_queue;
BAN::CircularQueue<KeyEvent, 50> m_event_queue;
PS2Keymap m_keymap; PS2Keymap m_keymap;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <BAN/Array.h> #include <BAN/Vector.h>
#include <BAN/Optional.h> #include <kernel/Input/KeyEvent.h>
namespace Kernel::Input namespace Kernel::Input
{ {
@ -9,18 +9,15 @@ namespace Kernel::Input
class PS2Keymap class PS2Keymap
{ {
public: public:
void initialize(uint8_t scancode_set); PS2Keymap();
BAN::Optional<uint8_t> get_keycode(uint8_t scancode, bool extended) const; Key key_for_scancode_and_modifiers(uint32_t, uint8_t);
private: private:
void initialize_scancode_set1(); BAN::Vector<Key> m_normal_keymap;
void initialize_scancode_set2(); BAN::Vector<Key> m_shift_keymap;
void initialize_scancode_set3(); BAN::Vector<Key> m_altgr_keymap;
BAN::Vector<Key> m_extended_keymap;
private:
BAN::Array<uint8_t, 0xFF> m_scancode_to_keycode_normal;
BAN::Array<uint8_t, 0xFF> m_scancode_to_keycode_extended;
}; };
} }

View File

@ -19,9 +19,8 @@ namespace Kernel::Input
static BAN::ErrorOr<PS2Mouse*> create(PS2Controller&); static BAN::ErrorOr<PS2Mouse*> create(PS2Controller&);
virtual void send_initialize() override; virtual void send_initialize() override;
virtual void command_timedout(uint8_t* command_data, uint8_t command_size) final override {}
virtual void handle_byte(uint8_t) final override; virtual void handle_byte(uint8_t) final override;
virtual void handle_device_command_response(uint8_t) final override;
private: private:
PS2Mouse(PS2Controller& controller); PS2Mouse(PS2Controller& controller);
@ -36,7 +35,7 @@ namespace Kernel::Input
uint8_t m_mouse_id { 0x00 }; uint8_t m_mouse_id { 0x00 };
uint8_t m_button_mask { 0x00 }; uint8_t m_button_mask { 0x00 };
BAN::CircularQueue<MouseEvent, 128> m_event_queue; BAN::CircularQueue<MouseEvent, 25> m_event_queue;
Semaphore m_semaphore; Semaphore m_semaphore;

View File

@ -146,8 +146,6 @@ namespace Kernel
BAN::ErrorOr<long> sys_clock_gettime(clockid_t, timespec*); BAN::ErrorOr<long> sys_clock_gettime(clockid_t, timespec*);
BAN::ErrorOr<long> sys_load_keymap(const char* path);
TTY& tty() { ASSERT(m_controlling_terminal); return *m_controlling_terminal; } TTY& tty() { ASSERT(m_controlling_terminal); return *m_controlling_terminal; }
static Process& current() { return Thread::current().process(); } static Process& current() { return Thread::current().process(); }

View File

@ -48,7 +48,7 @@ namespace Kernel
bool add_signal(int signal); bool add_signal(int signal);
// blocks semaphore and returns either on unblock, eintr or spuriously // blocks semaphore and returns either on unblock, eintr or spuriously
BAN::ErrorOr<void> block_or_eintr(Semaphore&); [[nodiscard]] bool block_or_eintr(Semaphore&);
void set_return_rsp(uintptr_t& rsp) { m_return_rsp = &rsp; } void set_return_rsp(uintptr_t& rsp) { m_return_rsp = &rsp; }
void set_return_rip(uintptr_t& rip) { m_return_rip = &rip; } void set_return_rip(uintptr_t& rip) { m_return_rip = &rip; }

View File

@ -8,6 +8,10 @@ namespace Kernel
"ACPI could not find root SDT header"sv, "ACPI could not find root SDT header"sv,
"ACPI no such header"sv, "ACPI no such header"sv,
"ACPI root invalid", "ACPI root invalid",
"PS/2 device timeout"sv,
"PS/2 controller self test failed"sv,
"PS/2 reset failed"sv,
"PS/2 unsupported device"sv,
"Invalid ext2 filesystem"sv, "Invalid ext2 filesystem"sv,
"Ext2 filesystem corrupted"sv, "Ext2 filesystem corrupted"sv,
"Ext2 filesystem out of inodes"sv, "Ext2 filesystem out of inodes"sv,

View File

@ -6,7 +6,6 @@
#include <kernel/FS/TmpFS/Inode.h> #include <kernel/FS/TmpFS/Inode.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/Process.h> #include <kernel/Process.h>
#include <kernel/Scheduler.h>
#include <kernel/Storage/StorageDevice.h> #include <kernel/Storage/StorageDevice.h>
#include <kernel/Timer/Timer.h> #include <kernel/Timer/Timer.h>
@ -49,7 +48,8 @@ namespace Kernel
} }
); );
s_instance->m_device_lock.unlock(); s_instance->m_device_lock.unlock();
Scheduler::get().reschedule();
Kernel::SystemTimer::get().sleep(1);
} }
}, nullptr }, nullptr
); );

View File

@ -1,57 +0,0 @@
#include <BAN/Array.h>
#include <kernel/Input/KeyboardLayout.h>
#include <kernel/Input/KeyEvent.h>
namespace Kernel::Input
{
Key key_event_to_key(KeyEvent event)
{
return KeyboardLayout::get().get_key_from_event(event);
}
const char* key_to_utf8(Key key, uint16_t modifier)
{
static constexpr const char* utf8_lower[] = {
nullptr, nullptr,
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"å", "ä", "ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
"(", ")", "[", "]", "{", "}",
"=", "?", "+", "\\", "´", "`", "¨", "¸", nullptr, "@", "£", "$", "",
nullptr, "\t", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"'", "*", "^", "~", nullptr, nullptr, nullptr, nullptr,
",", ";", ".", ":", "-", "_", nullptr, nullptr, "<", ">", "|",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"+", "-", "*", "/", nullptr, ",",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
};
static_assert((size_t)Key::Count == sizeof(utf8_lower) / sizeof(*utf8_lower));
static constexpr const char* utf8_upper[] = {
nullptr, nullptr,
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"Å", "Ä", "Ö",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
"(", ")", "[", "]", "{", "}",
"=", "?", "+", "\\", "´", "`", "¨", "¸", nullptr, "@", "£", "$", "",
nullptr, "\t", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"'", "*", "^", "~", nullptr, nullptr, nullptr, nullptr,
",", ";", ".", ":", "-", "_", nullptr, nullptr, "<", ">", "|",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"+", "-", "*", "/", nullptr, ",",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
};
static_assert((size_t)Key::Count == sizeof(utf8_upper) / sizeof(*utf8_lower));
KeyEvent event { .modifier = modifier, .keycode = 0x00 };
return (event.shift() ^ event.caps_lock()) ? utf8_upper[static_cast<uint8_t>(key)] : utf8_lower[static_cast<uint8_t>(key)];
}
}

View File

@ -1,346 +0,0 @@
#include <BAN/HashMap.h>
#include <kernel/FS/VirtualFileSystem.h>
#include <kernel/Input/KeyboardLayout.h>
#include <ctype.h>
namespace Kernel::Input
{
struct StringViewLower
{
BAN::StringView value;
StringViewLower(BAN::StringView sv)
: value(sv)
{ }
bool operator==(const StringViewLower& other) const
{
if (value.size() != other.value.size())
return false;
for (size_t i = 0; i < value.size(); i++)
if (tolower(value[i]) != tolower(other.value[i]))
return false;
return true;
}
};
struct StringViewLowerHash
{
BAN::hash_t operator()(const StringViewLower& value) const
{
constexpr BAN::hash_t FNV_offset_basis = 0x811c9dc5;
constexpr BAN::hash_t FNV_prime = 0x01000193;
BAN::hash_t hash = FNV_offset_basis;
for (size_t i = 0; i < value.value.size(); i++)
{
hash *= FNV_prime;
hash ^= (uint8_t)tolower(value.value[i]);
}
return hash;
}
};
static BAN::UniqPtr<KeyboardLayout> s_instance;
BAN::ErrorOr<void> KeyboardLayout::initialize()
{
ASSERT(!s_instance);
s_instance = TRY(BAN::UniqPtr<KeyboardLayout>::create());
return {};
}
KeyboardLayout& KeyboardLayout::get()
{
ASSERT(s_instance);
return *s_instance;
}
KeyboardLayout::KeyboardLayout()
{
for (auto& key : m_keycode_to_key_normal)
key = Key::None;
for (auto& key : m_keycode_to_key_shift)
key = Key::None;
for (auto& key : m_keycode_to_key_altgr)
key = Key::None;
}
Key KeyboardLayout::get_key_from_event(KeyEvent event)
{
if (event.shift())
return m_keycode_to_key_shift[event.keycode];
if (event.ralt())
return m_keycode_to_key_altgr[event.keycode];
return m_keycode_to_key_normal[event.keycode];
}
static BAN::Optional<uint8_t> parse_keycode(BAN::StringView str)
{
if (str.size() > 3)
return {};
uint16_t keycode = 0;
for (char c : str)
{
if (!isdigit(c))
return {};
keycode = (keycode * 10) + (c - '0');
}
if (keycode >= 0xFF)
return {};
return keycode;
}
static BAN::HashMap<StringViewLower, Key, StringViewLowerHash> s_name_to_key;
static BAN::ErrorOr<void> initialize_name_to_key();
static BAN::Optional<Key> parse_key(BAN::StringView name)
{
if (s_name_to_key.contains(name))
return s_name_to_key[name];
return {};
}
BAN::ErrorOr<void> KeyboardLayout::load_from_file(BAN::StringView path)
{
if (s_name_to_key.empty())
TRY(initialize_name_to_key());
auto inode = TRY(VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, 0)).inode;
BAN::String file_data;
TRY(file_data.resize(inode->size()));
TRY(inode->read(0, { reinterpret_cast<uint8_t*>(file_data.data()), file_data.size() }));
auto new_layout = TRY(BAN::UniqPtr<KeyboardLayout>::create());
auto lines = TRY(file_data.sv().split('\n'));
for (auto line : lines)
{
auto parts = TRY(line.split([](char c) -> bool { return isspace(c); }));
if (parts.empty() || parts.front().front() == '#')
continue;
if (parts.size() == 1)
{
dprintln("Invalid line in keymap '{}'", line);
dprintln(" format: KEYCODE KEY [MODIFIER=KEY]...");
continue;
}
auto keycode = parse_keycode(parts.front());
if (!keycode.has_value())
{
dprintln("Invalid keycode '{}', keycode must number between [0, 0xFF[", parts.front());
continue;
}
auto default_key = parse_key(parts[1]);
if (!default_key.has_value())
{
dprintln("Unrecognized key '{}'", parts[1]);
continue;
}
new_layout->m_keycode_to_key_normal[*keycode] = *default_key;
new_layout->m_keycode_to_key_shift[*keycode] = *default_key;
new_layout->m_keycode_to_key_altgr[*keycode] = *default_key;
for (size_t i = 2; i < parts.size(); i++)
{
auto pair = TRY(parts[i].split('='));
if (pair.size() != 2)
{
dprintln("Invalid modifier format '{}', modifier format: MODIFIRER=KEY", parts[i]);
continue;
}
auto key = parse_key(pair.back());
if (!key.has_value())
{
dprintln("Unrecognized key '{}'", pair.back());
continue;
}
if (pair.front() == "shift"sv)
new_layout->m_keycode_to_key_shift[*keycode] = *key;
else if (pair.front() == "altgr"sv)
new_layout->m_keycode_to_key_altgr[*keycode] = *key;
else
{
dprintln("Unrecognized modifier '{}'", pair.front());
continue;
}
}
}
m_keycode_to_key_normal = new_layout->m_keycode_to_key_normal;
m_keycode_to_key_shift = new_layout->m_keycode_to_key_shift;
m_keycode_to_key_altgr = new_layout->m_keycode_to_key_altgr;
return {};
}
static BAN::ErrorOr<void> initialize_name_to_key()
{
ASSERT(s_name_to_key.empty());
TRY(s_name_to_key.insert("A_Ring"sv, Key::A_Ring));
TRY(s_name_to_key.insert("A_Umlaut"sv, Key::A_Umlaut));
TRY(s_name_to_key.insert("A"sv, Key::A));
TRY(s_name_to_key.insert("Acute"sv, Key::Acute));
TRY(s_name_to_key.insert("AltGr"sv, Key::AltGr));
TRY(s_name_to_key.insert("Ampersand"sv, Key::Ampersand));
TRY(s_name_to_key.insert("ArrowDown"sv, Key::ArrowDown));
TRY(s_name_to_key.insert("ArrowLeft"sv, Key::ArrowLeft));
TRY(s_name_to_key.insert("ArrowRight"sv, Key::ArrowRight));
TRY(s_name_to_key.insert("ArrowUp"sv, Key::ArrowUp));
TRY(s_name_to_key.insert("Asterix"sv, Key::Asterix));
TRY(s_name_to_key.insert("AtSign"sv, Key::AtSign));
TRY(s_name_to_key.insert("B"sv, Key::B));
TRY(s_name_to_key.insert("BackSlash"sv, Key::BackSlash));
TRY(s_name_to_key.insert("Backspace"sv, Key::Backspace));
TRY(s_name_to_key.insert("BackTick"sv, Key::BackTick));
TRY(s_name_to_key.insert("C"sv, Key::C));
TRY(s_name_to_key.insert("Calculator"sv, Key::Calculator));
TRY(s_name_to_key.insert("CapsLock"sv, Key::CapsLock));
TRY(s_name_to_key.insert("Caret"sv, Key::Caret));
TRY(s_name_to_key.insert("Cedilla"sv, Key::Cedilla));
TRY(s_name_to_key.insert("CloseCurlyBracket"sv, Key::CloseCurlyBracket));
TRY(s_name_to_key.insert("CloseParenthesis"sv, Key::CloseParenthesis));
TRY(s_name_to_key.insert("CloseSquareBracket"sv, Key::CloseSquareBracket));
TRY(s_name_to_key.insert("Colon"sv, Key::Colon));
TRY(s_name_to_key.insert("Comma"sv, Key::Comma));
TRY(s_name_to_key.insert("Currency"sv, Key::Currency));
TRY(s_name_to_key.insert("D"sv, Key::D));
TRY(s_name_to_key.insert("Delete"sv, Key::Delete));
TRY(s_name_to_key.insert("Dollar"sv, Key::Dollar));
TRY(s_name_to_key.insert("DoubleQuote"sv, Key::DoubleQuote));
TRY(s_name_to_key.insert("E"sv, Key::E));
TRY(s_name_to_key.insert("End"sv, Key::End));
TRY(s_name_to_key.insert("Enter"sv, Key::Enter));
TRY(s_name_to_key.insert("Equals"sv, Key::Equals));
TRY(s_name_to_key.insert("Escape"sv, Key::Escape));
TRY(s_name_to_key.insert("Euro"sv, Key::Euro));
TRY(s_name_to_key.insert("Exclamation"sv, Key::ExclamationMark));
TRY(s_name_to_key.insert("ExclamationMark"sv, Key::ExclamationMark));
TRY(s_name_to_key.insert("F"sv, Key::F));
TRY(s_name_to_key.insert("F1"sv, Key::F1));
TRY(s_name_to_key.insert("F10"sv, Key::F10));
TRY(s_name_to_key.insert("F11"sv, Key::F11));
TRY(s_name_to_key.insert("F12"sv, Key::F12));
TRY(s_name_to_key.insert("F2"sv, Key::F2));
TRY(s_name_to_key.insert("F3"sv, Key::F3));
TRY(s_name_to_key.insert("F4"sv, Key::F4));
TRY(s_name_to_key.insert("F5"sv, Key::F5));
TRY(s_name_to_key.insert("F6"sv, Key::F6));
TRY(s_name_to_key.insert("F7"sv, Key::F7));
TRY(s_name_to_key.insert("F8"sv, Key::F8));
TRY(s_name_to_key.insert("F9"sv, Key::F9));
TRY(s_name_to_key.insert("G"sv, Key::G));
TRY(s_name_to_key.insert("GreaterThan"sv, Key::GreaterThan));
TRY(s_name_to_key.insert("H"sv, Key::H));
TRY(s_name_to_key.insert("Half"sv, Key::Half));
TRY(s_name_to_key.insert("Hashtag"sv, Key::Hashtag));
TRY(s_name_to_key.insert("Home"sv, Key::Home));
TRY(s_name_to_key.insert("Hyphen"sv, Key::Hyphen));
TRY(s_name_to_key.insert("I"sv, Key::I));
TRY(s_name_to_key.insert("Insert"sv, Key::Insert));
TRY(s_name_to_key.insert("J"sv, Key::J));
TRY(s_name_to_key.insert("K"sv, Key::K));
TRY(s_name_to_key.insert("Key0"sv, Key::_0));
TRY(s_name_to_key.insert("Key1"sv, Key::_1));
TRY(s_name_to_key.insert("Key2"sv, Key::_2));
TRY(s_name_to_key.insert("Key3"sv, Key::_3));
TRY(s_name_to_key.insert("Key4"sv, Key::_4));
TRY(s_name_to_key.insert("Key5"sv, Key::_5));
TRY(s_name_to_key.insert("Key6"sv, Key::_6));
TRY(s_name_to_key.insert("Key7"sv, Key::_7));
TRY(s_name_to_key.insert("Key8"sv, Key::_8));
TRY(s_name_to_key.insert("Key9"sv, Key::_9));
TRY(s_name_to_key.insert("L"sv, Key::L));
TRY(s_name_to_key.insert("LAlt"sv, Key::LeftAlt));
TRY(s_name_to_key.insert("LControl"sv, Key::LeftCtrl));
TRY(s_name_to_key.insert("LeftAlt"sv, Key::LeftAlt));
TRY(s_name_to_key.insert("LeftControl"sv, Key::LeftCtrl));
TRY(s_name_to_key.insert("LeftShift"sv, Key::LeftShift));
TRY(s_name_to_key.insert("LessThan"sv, Key::LessThan));
TRY(s_name_to_key.insert("LShift"sv, Key::LeftShift));
TRY(s_name_to_key.insert("M"sv, Key::M));
TRY(s_name_to_key.insert("MediaNext"sv, Key::MediaNext));
TRY(s_name_to_key.insert("MediaPlayPause"sv, Key::MediaPlayPause));
TRY(s_name_to_key.insert("MediaPrevious"sv, Key::MediaPrevious));
TRY(s_name_to_key.insert("MediaStop"sv, Key::MediaStop));
TRY(s_name_to_key.insert("N"sv, Key::N));
TRY(s_name_to_key.insert("None"sv, Key::None));
TRY(s_name_to_key.insert("NumLock"sv, Key::NumLock));
TRY(s_name_to_key.insert("Numpad0"sv, Key::Numpad0));
TRY(s_name_to_key.insert("Numpad1"sv, Key::Numpad1));
TRY(s_name_to_key.insert("Numpad2"sv, Key::Numpad2));
TRY(s_name_to_key.insert("Numpad3"sv, Key::Numpad3));
TRY(s_name_to_key.insert("Numpad4"sv, Key::Numpad4));
TRY(s_name_to_key.insert("Numpad5"sv, Key::Numpad5));
TRY(s_name_to_key.insert("Numpad6"sv, Key::Numpad6));
TRY(s_name_to_key.insert("Numpad7"sv, Key::Numpad7));
TRY(s_name_to_key.insert("Numpad8"sv, Key::Numpad8));
TRY(s_name_to_key.insert("Numpad9"sv, Key::Numpad9));
TRY(s_name_to_key.insert("NumpadDecimal"sv, Key::NumpadDecimal));
TRY(s_name_to_key.insert("NumpadDivide"sv, Key::NumpadDivide));
TRY(s_name_to_key.insert("NumpadEnter"sv, Key::NumpadEnter));
TRY(s_name_to_key.insert("NumpadMinus"sv, Key::NumpadMinus));
TRY(s_name_to_key.insert("NumpadMultiply"sv, Key::NumpadMultiply));
TRY(s_name_to_key.insert("NumpadPlus"sv, Key::NumpadPlus));
TRY(s_name_to_key.insert("O_Umlaut"sv, Key::O_Umlaut));
TRY(s_name_to_key.insert("O"sv, Key::O));
TRY(s_name_to_key.insert("OpenCurlyBracket"sv, Key::OpenCurlyBracket));
TRY(s_name_to_key.insert("OpenParenthesis"sv, Key::OpenParenthesis));
TRY(s_name_to_key.insert("OpenSquareBracket"sv, Key::OpenSquareBracket));
TRY(s_name_to_key.insert("P"sv, Key::P));
TRY(s_name_to_key.insert("PageDown"sv, Key::PageDown));
TRY(s_name_to_key.insert("PageUp"sv, Key::PageUp));
TRY(s_name_to_key.insert("Percent"sv, Key::Percent));
TRY(s_name_to_key.insert("Period"sv, Key::Period));
TRY(s_name_to_key.insert("Pipe"sv, Key::Pipe));
TRY(s_name_to_key.insert("Plus"sv, Key::Plus));
TRY(s_name_to_key.insert("Pound"sv, Key::Pound));
TRY(s_name_to_key.insert("PrintScreen"sv, Key::PrintScreen));
TRY(s_name_to_key.insert("Q"sv, Key::Q));
TRY(s_name_to_key.insert("Question"sv, Key::QuestionMark));
TRY(s_name_to_key.insert("QuestionMark"sv, Key::QuestionMark));
TRY(s_name_to_key.insert("R"sv, Key::R));
TRY(s_name_to_key.insert("RAlt"sv, Key::RightAlt));
TRY(s_name_to_key.insert("RControl"sv, Key::RightCtrl));
TRY(s_name_to_key.insert("RightAlt"sv, Key::RightAlt));
TRY(s_name_to_key.insert("RightControl"sv, Key::RightCtrl));
TRY(s_name_to_key.insert("RightShift"sv, Key::RightShift));
TRY(s_name_to_key.insert("RShift"sv, Key::RightShift));
TRY(s_name_to_key.insert("S"sv, Key::S));
TRY(s_name_to_key.insert("ScrollLock"sv, Key::ScrollLock));
TRY(s_name_to_key.insert("Section"sv, Key::Section));
TRY(s_name_to_key.insert("Semicolon"sv, Key::Semicolon));
TRY(s_name_to_key.insert("SingleQuote"sv, Key::SingleQuote));
TRY(s_name_to_key.insert("Slash"sv, Key::Slash));
TRY(s_name_to_key.insert("Space"sv, Key::Space));
TRY(s_name_to_key.insert("Super"sv, Key::Super));
TRY(s_name_to_key.insert("T"sv, Key::T));
TRY(s_name_to_key.insert("Tab"sv, Key::Tab));
TRY(s_name_to_key.insert("Tilde"sv, Key::Tilde));
TRY(s_name_to_key.insert("TwoDots"sv, Key::TwoDots));
TRY(s_name_to_key.insert("U"sv, Key::U));
TRY(s_name_to_key.insert("Underscore"sv, Key::Underscore));
TRY(s_name_to_key.insert("V"sv, Key::V));
TRY(s_name_to_key.insert("VolumeDown"sv, Key::VolumeDown));
TRY(s_name_to_key.insert("VolumeMute"sv, Key::VolumeMute));
TRY(s_name_to_key.insert("VolumeUp"sv, Key::VolumeUp));
TRY(s_name_to_key.insert("W"sv, Key::W));
TRY(s_name_to_key.insert("X"sv, Key::X));
TRY(s_name_to_key.insert("Y"sv, Key::Y));
TRY(s_name_to_key.insert("Z"sv, Key::Z));
return {};
}
}

View File

@ -10,212 +10,65 @@
#include <kernel/IO.h> #include <kernel/IO.h>
#include <kernel/Timer/Timer.h> #include <kernel/Timer/Timer.h>
#define DEBUG_PS2 1
namespace Kernel::Input namespace Kernel::Input
{ {
static constexpr uint64_t s_ps2_timeout_ms = 100; static constexpr uint64_t s_device_timeout_ms = 100;
static void controller_send_command(PS2::Command command)
{
IO::outb(PS2::IOPort::COMMAND, command);
}
static void controller_send_command(PS2::Command command, uint8_t data)
{
IO::outb(PS2::IOPort::COMMAND, command);
while (IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_FULL)
continue;
IO::outb(PS2::IOPort::DATA, data);
}
static uint8_t wait_and_read()
{
while (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_FULL))
continue;
return IO::inb(PS2::IOPort::DATA);
}
static BAN::ErrorOr<void> device_send_byte(uint8_t device, uint8_t byte)
{
if (device == 1)
IO::outb(PS2::IOPort::COMMAND, PS2::Command::WRITE_TO_SECOND_PORT);
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_device_timeout_ms;
while (SystemTimer::get().ms_since_boot() < timeout)
{
if (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_FULL))
{
IO::outb(PS2::IOPort::DATA, byte);
return {};
}
}
return BAN::Error::from_error_code(ErrorCode::PS2_Timeout);
}
static BAN::ErrorOr<uint8_t> device_read_byte()
{
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_device_timeout_ms;
while (SystemTimer::get().ms_since_boot() < timeout)
if (IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_FULL)
return IO::inb(PS2::IOPort::DATA);
return BAN::Error::from_error_code(ErrorCode::PS2_Timeout);
}
static BAN::ErrorOr<void> device_wait_ack()
{
while (TRY(device_read_byte()) != PS2::Response::ACK)
continue;;
return {};
}
static PS2Controller* s_instance = nullptr; static PS2Controller* s_instance = nullptr;
BAN::ErrorOr<void> PS2Controller::send_byte(uint16_t port, uint8_t byte)
{
ASSERT(interrupts_enabled());
LockGuard _(m_lock);
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_ps2_timeout_ms;
while (SystemTimer::get().ms_since_boot() < timeout)
{
if (IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_STATUS)
continue;
IO::outb(port, byte);
return {};
}
return BAN::Error::from_errno(ETIMEDOUT);
}
BAN::ErrorOr<uint8_t> PS2Controller::read_byte()
{
ASSERT(interrupts_enabled());
LockGuard _(m_lock);
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_ps2_timeout_ms;
while (SystemTimer::get().ms_since_boot() < timeout)
{
if (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_STATUS))
continue;
return IO::inb(PS2::IOPort::DATA);
}
return BAN::Error::from_errno(ETIMEDOUT);
}
BAN::ErrorOr<void> PS2Controller::send_command(PS2::Command command)
{
LockGuard _(m_lock);
TRY(send_byte(PS2::IOPort::COMMAND, command));
return {};
}
BAN::ErrorOr<void> PS2Controller::send_command(PS2::Command command, uint8_t data)
{
LockGuard _(m_lock);
TRY(send_byte(PS2::IOPort::COMMAND, command));
TRY(send_byte(PS2::IOPort::DATA, data));
return {};
}
BAN::ErrorOr<void> PS2Controller::device_send_byte(uint8_t device_index, uint8_t byte)
{
LockGuard _(m_lock);
if (device_index == 1)
TRY(send_byte(PS2::IOPort::COMMAND, PS2::Command::WRITE_TO_SECOND_PORT));
TRY(send_byte(PS2::IOPort::DATA, byte));
return {};
}
BAN::ErrorOr<void> PS2Controller::device_send_byte_and_wait_ack(uint8_t device_index, uint8_t byte)
{
LockGuard _(m_lock);
for (;;)
{
TRY(device_send_byte(device_index, byte));
uint8_t response = TRY(read_byte());
if (response == PS2::Response::RESEND)
continue;
if (response == PS2::Response::ACK)
break;
dwarnln_if(DEBUG_PS2, "PS/2 device on port {} did not respond with expected ACK, got {2H}", device_index, byte);
return BAN::Error::from_errno(EBADMSG);
}
return {};
}
bool PS2Controller::append_command_queue(PS2Device* device, uint8_t command, uint8_t response_size)
{
// NOTE: command queue push/pop must be done without interrupts
CriticalScope _;
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
if (m_command_queue.size() + 1 >= m_command_queue.capacity())
{
dprintln("PS/2 command queue full");
return false;
}
m_command_queue.push(Command {
.state = Command::State::NotSent,
.device_index = (device == m_devices[0].ptr()) ? uint8_t(0) : uint8_t(1),
.out_data = { command, 0x00 },
.out_count = 1,
.in_count = response_size,
.send_index = 0
});
return true;
}
bool PS2Controller::append_command_queue(PS2Device* device, uint8_t command, uint8_t data, uint8_t response_size)
{
// NOTE: command queue push/pop must be done without interrupts
CriticalScope _;
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
if (m_command_queue.size() + 1 >= m_command_queue.capacity())
{
dprintln("PS/2 command queue full");
return false;
}
m_command_queue.push(Command {
.state = Command::State::NotSent,
.device_index = (device == m_devices[0].ptr()) ? uint8_t(0) : uint8_t(1),
.out_data = { command, data },
.out_count = 2,
.in_count = response_size,
.send_index = 0
});
return true;
}
void PS2Controller::update_command_queue()
{
ASSERT(interrupts_enabled());
if (m_command_queue.empty())
return;
auto& command = m_command_queue.front();
if (command.state == Command::State::WaitingResponse || command.state == Command::State::WaitingAck)
{
if (SystemTimer::get().ms_since_boot() >= m_command_send_time + s_ps2_timeout_ms)
{
dwarnln_if(DEBUG_PS2, "Command timedout");
m_devices[command.device_index]->command_timedout(command.out_data, command.out_count);
m_command_queue.pop();
}
return;
}
ASSERT(command.send_index < command.out_count);
command.state = Command::State::WaitingAck;
m_command_send_time = SystemTimer::get().ms_since_boot();
if (auto ret = device_send_byte(command.device_index, command.out_data[command.send_index]); ret.is_error())
{
command.state = Command::State::Sending;
dwarnln_if(DEBUG_PS2, "PS/2 send command byte: {}", ret.error());
}
}
bool PS2Controller::handle_command_byte(PS2Device* device, uint8_t byte)
{
// NOTE: command queue push/pop must be done without interrupts
ASSERT(!interrupts_enabled());
if (m_command_queue.empty())
return false;
auto& command = m_command_queue.front();
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
if (command.device_index != (device == m_devices[0].ptr()) ? 0 : 1)
return false;
switch (command.state)
{
case Command::State::NotSent:
{
return false;
}
case Command::State::Sending:
{
dwarnln_if(DEBUG_PS2, "PS/2 device sent byte while middle of command send");
return false;
}
case Command::State::WaitingResponse:
{
if (--command.in_count <= 0)
m_command_queue.pop();
return false;
}
case Command::State::WaitingAck:
{
switch (byte)
{
case PS2::Response::ACK:
{
if (++command.send_index < command.out_count)
command.state = Command::State::Sending;
else if (command.in_count > 0)
command.state = Command::State::WaitingResponse;
else
m_command_queue.pop();
return true;
}
case PS2::Response::RESEND:
command.state = Command::State::Sending;
return true;
default:
dwarnln_if(DEBUG_PS2, "PS/2 expected ACK got {2H}", byte);
command.state = Command::State::Sending;
return true;
}
break;
}
}
ASSERT_NOT_REACHED();
}
BAN::ErrorOr<void> PS2Controller::initialize() BAN::ErrorOr<void> PS2Controller::initialize()
{ {
ASSERT(s_instance == nullptr); ASSERT(s_instance == nullptr);
@ -236,96 +89,88 @@ namespace Kernel::Input
BAN::ErrorOr<void> PS2Controller::initialize_impl() BAN::ErrorOr<void> PS2Controller::initialize_impl()
{ {
// FIXME: Initialise USB Controllers // Step 1: Initialise USB Controllers
// FIXME
// Determine if the PS/2 Controller Exists // Step 2: Determine if the PS/2 Controller Exists
auto* fadt = static_cast<const ACPI::FADT*>(ACPI::get().get_header("FACP"sv, 0)); // FIXME
if (fadt && fadt->revision > 1 && !(fadt->iapc_boot_arch & (1 << 1)))
{
dwarnln_if(DEBUG_PS2, "No PS/2 available");
return {};
}
// Disable Devices // Step 3: Disable Devices
TRY(send_command(PS2::Command::DISABLE_FIRST_PORT)); controller_send_command(PS2::Command::DISABLE_FIRST_PORT);
TRY(send_command(PS2::Command::DISABLE_SECOND_PORT)); controller_send_command(PS2::Command::DISABLE_SECOND_PORT);
// Flush The Output Buffer // Step 4: Flush The Output Buffer
while (!read_byte().is_error()) IO::inb(PS2::IOPort::DATA);
continue;
// Set the Controller Configuration Byte // Step 5: Set the Controller Configuration Byte
TRY(send_command(PS2::Command::READ_CONFIG)); controller_send_command(PS2::Command::READ_CONFIG);
uint8_t config = TRY(read_byte()); uint8_t config = wait_and_read();
config &= ~PS2::Config::INTERRUPT_FIRST_PORT; config &= ~PS2::Config::INTERRUPT_FIRST_PORT;
config &= ~PS2::Config::INTERRUPT_SECOND_PORT; config &= ~PS2::Config::INTERRUPT_SECOND_PORT;
config &= ~PS2::Config::TRANSLATION_FIRST_PORT; config &= ~PS2::Config::TRANSLATION_FIRST_PORT;
TRY(send_command(PS2::Command::WRITE_CONFIG, config)); controller_send_command(PS2::Command::WRITE_CONFIG, config);
// Perform Controller Self Test // Step 6: Perform Controller Self Test
TRY(send_command(PS2::Command::TEST_CONTROLLER)); controller_send_command(PS2::Command::TEST_CONTROLLER);
if (TRY(read_byte()) != PS2::Response::TEST_CONTROLLER_PASS) if (wait_and_read() != PS2::Response::TEST_CONTROLLER_PASS)
{ return BAN::Error::from_error_code(ErrorCode::PS2_SelfTest);
dwarnln_if(DEBUG_PS2, "PS/2 Controller test failed");
return BAN::Error::from_errno(ENODEV);
}
// NOTE: self test might reset the device so we set the config byte again // NOTE: self test might reset the device so we set the config byte again
TRY(send_command(PS2::Command::WRITE_CONFIG, config)); controller_send_command(PS2::Command::WRITE_CONFIG, config);
// Determine If There Are 2 Channels // Step 7: Determine If There Are 2 Channels
bool valid_ports[2] { true, false }; bool valid_ports[2] { true, false };
if (config & PS2::Config::CLOCK_SECOND_PORT) if (config & PS2::Config::CLOCK_SECOND_PORT)
{ {
TRY(send_command(PS2::Command::ENABLE_SECOND_PORT)); controller_send_command(PS2::Command::ENABLE_SECOND_PORT);
TRY(send_command(PS2::Command::READ_CONFIG)); controller_send_command(PS2::Command::READ_CONFIG);
if (!(TRY(read_byte()) & PS2::Config::CLOCK_SECOND_PORT)) if (!(wait_and_read() & PS2::Config::CLOCK_SECOND_PORT))
{
valid_ports[1] = true; valid_ports[1] = true;
TRY(send_command(PS2::Command::DISABLE_SECOND_PORT)); controller_send_command(PS2::Command::DISABLE_SECOND_PORT);
}
} }
// Perform Interface Tests // Step 8: Perform Interface Tests
TRY(send_command(PS2::Command::TEST_FIRST_PORT)); controller_send_command(PS2::Command::TEST_FIRST_PORT);
if (TRY(read_byte()) != PS2::Response::TEST_FIRST_PORT_PASS) if (wait_and_read() != PS2::Response::TEST_FIRST_PORT_PASS)
{
dwarnln_if(DEBUG_PS2, "PS/2 first port test failed");
valid_ports[0] = false; valid_ports[0] = false;
}
if (valid_ports[1]) if (valid_ports[1])
{ {
TRY(send_command(PS2::Command::TEST_SECOND_PORT)); controller_send_command(PS2::Command::TEST_SECOND_PORT);
if (TRY(read_byte()) != PS2::Response::TEST_SECOND_PORT_PASS) if (wait_and_read() != PS2::Response::TEST_SECOND_PORT_PASS)
{
dwarnln_if(DEBUG_PS2, "PS/2 second port test failed");
valid_ports[1] = false; valid_ports[1] = false;
}
} }
if (!valid_ports[0] && !valid_ports[1]) if (!valid_ports[0] && !valid_ports[1])
return {}; return {};
// Initialize devices // Step 9: Enable Devices (and disable scanning)
for (uint8_t device = 0; device < 2; device++) for (uint8_t device = 0; device < 2; device++)
{ {
if (!valid_ports[device]) if (!valid_ports[device])
continue; continue;
if (auto ret = send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT); ret.is_error()) controller_send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT);
{ if (set_scanning(device, false).is_error())
dwarnln_if(DEBUG_PS2, "PS/2 device enable failed: {}", ret.error()); valid_ports[device] = false;
continue;
}
if (auto res = initialize_device(device); res.is_error())
{
dwarnln_if(DEBUG_PS2, "PS/2 device initialization failed: {}", res.error());
(void)send_command(device == 0 ? PS2::Command::DISABLE_FIRST_PORT : PS2::Command::DISABLE_SECOND_PORT);
continue;
}
} }
if (!m_devices[0] && !m_devices[1]) // Step 10: Reset Devices
return {}; for (uint8_t device = 0; device < 2; device++)
{
if (!valid_ports[device])
continue;
if (reset_device(device).is_error())
valid_ports[device] = false;
if (set_scanning(device, false).is_error())
valid_ports[device] = false;
}
// Step 11: Initialize Device Drivers
for (uint8_t device = 0; device < 2; device++)
{
if (!valid_ports[device])
continue;
if (auto res = initialize_device(device); res.is_error())
dprintln("{}", res.error());
}
// Enable irqs on valid devices
if (m_devices[0]) if (m_devices[0])
{ {
m_devices[0]->set_irq(PS2::IRQ::DEVICE0); m_devices[0]->set_irq(PS2::IRQ::DEVICE0);
@ -339,12 +184,11 @@ namespace Kernel::Input
config |= PS2::Config::INTERRUPT_SECOND_PORT; config |= PS2::Config::INTERRUPT_SECOND_PORT;
} }
TRY(send_command(PS2::Command::WRITE_CONFIG, config)); controller_send_command(PS2::Command::WRITE_CONFIG, config);
// Send device initialization sequence after interrupts are enabled
for (uint8_t device = 0; device < 2; device++) for (uint8_t device = 0; device < 2; device++)
{ {
if (!m_devices[device]) if (m_devices[device] == nullptr)
continue; continue;
m_devices[device]->send_initialize(); m_devices[device]->send_initialize();
DevFileSystem::get().add_device(m_devices[device]); DevFileSystem::get().add_device(m_devices[device]);
@ -355,30 +199,14 @@ namespace Kernel::Input
BAN::ErrorOr<void> PS2Controller::initialize_device(uint8_t device) BAN::ErrorOr<void> PS2Controller::initialize_device(uint8_t device)
{ {
// Reset device TRY(device_send_byte(device, PS2::DeviceCommand::IDENTIFY));
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::RESET)); TRY(device_wait_ack());
if (TRY(read_byte()) != PS2::Response::SELF_TEST_PASS)
{
dwarnln_if(DEBUG_PS2, "PS/2 device self test failed");
return BAN::Error::from_errno(ENODEV);
}
while (!read_byte().is_error())
continue;
// Disable scanning and flush buffer
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::DISABLE_SCANNING));
while (!read_byte().is_error())
continue;
// Identify device
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::IDENTIFY));
// Read up to 2 identification bytes
uint8_t bytes[2] {}; uint8_t bytes[2] {};
uint8_t index = 0; uint8_t index = 0;
for (uint8_t i = 0; i < 2; i++) for (uint8_t i = 0; i < 2; i++)
{ {
auto res = read_byte(); auto res = device_read_byte();
if (res.is_error()) if (res.is_error())
break; break;
bytes[index++] = res.value(); bytes[index++] = res.value();
@ -386,22 +214,38 @@ namespace Kernel::Input
// Standard PS/2 Mouse // Standard PS/2 Mouse
if (index == 1 && (bytes[0] == 0x00)) if (index == 1 && (bytes[0] == 0x00))
{
dprintln_if(DEBUG_PS2, "PS/2 found mouse");
m_devices[device] = TRY(PS2Mouse::create(*this)); m_devices[device] = TRY(PS2Mouse::create(*this));
return {};
}
// MF2 Keyboard // MF2 Keyboard
if (index == 2 && (bytes[0] == 0xAB && (bytes[1] == 0x83 || bytes[1] == 0x41))) else if (index == 2 && (bytes[0] == 0xAB && bytes[1] == 0x83))
{
dprintln_if(DEBUG_PS2, "PS/2 found keyboard");
m_devices[device] = TRY(PS2Keyboard::create(*this)); m_devices[device] = TRY(PS2Keyboard::create(*this));
return {};
}
dprintln_if(DEBUG_PS2, "PS/2 unsupported device {2H} {2H} ({} bytes) on port {}", bytes[0], bytes[1], index, device); if (m_devices[device])
return BAN::Error::from_errno(ENOTSUP); return {};
return BAN::Error::from_error_code(ErrorCode::PS2_UnsupportedDevice);
}
void PS2Controller::send_byte(const PS2Device* device, uint8_t byte)
{
ASSERT(device != nullptr && (device == m_devices[0] || device == m_devices[1]));
uint8_t device_index = (device == m_devices[0]) ? 0 : 1;
MUST(device_send_byte(device_index, byte));
}
BAN::ErrorOr<void> PS2Controller::reset_device(uint8_t device)
{
TRY(device_send_byte(device, PS2::DeviceCommand::RESET));
TRY(device_wait_ack());
if (TRY(device_read_byte()) != PS2::Response::SELF_TEST_PASS)
return BAN::Error::from_error_code(ErrorCode::PS2_Reset);
return {};
}
BAN::ErrorOr<void> PS2Controller::set_scanning(uint8_t device, bool enabled)
{
TRY(device_send_byte(device, enabled ? PS2::DeviceCommand::ENABLE_SCANNING : PS2::DeviceCommand::DISABLE_SCANNING));
TRY(device_wait_ack());
return {};
} }
} }

View File

@ -15,21 +15,74 @@ namespace Kernel::Input
, m_controller(controller) , m_controller(controller)
{ } { }
bool PS2Device::append_command_queue(uint8_t command, uint8_t response_size) bool PS2Device::append_command_queue(uint8_t command)
{ {
return m_controller.append_command_queue(this, command, response_size); if (m_command_queue.size() + 1 >= m_command_queue.capacity())
{
dprintln("PS/2 command queue full");
return false;
}
m_command_queue.push(command);
update();
return true;
} }
bool PS2Device::append_command_queue(uint8_t command, uint8_t data, uint8_t response_size) bool PS2Device::append_command_queue(uint8_t command, uint8_t data)
{ {
return m_controller.append_command_queue(this, command, data, response_size); if (m_command_queue.size() + 2 >= m_command_queue.capacity())
{
dprintln("PS/2 command queue full");
return false;
}
m_command_queue.push(command);
m_command_queue.push(data);
update();
return true;
} }
void PS2Device::handle_irq() void PS2Device::handle_irq()
{ {
uint8_t byte = IO::inb(PS2::IOPort::DATA); uint8_t byte = IO::inb(PS2::IOPort::DATA);
if (!m_controller.handle_command_byte(this, byte))
handle_byte(byte); // NOTE: This implementation does not allow using commands
// that respond with more bytes than ACK
switch (m_state)
{
case State::WaitingAck:
{
switch (byte)
{
case PS2::Response::ACK:
m_command_queue.pop();
m_state = State::Normal;
break;
case PS2::Response::RESEND:
m_state = State::Normal;
break;
default:
handle_device_command_response(byte);
break;
}
break;
}
case State::Normal:
{
handle_byte(byte);
break;
}
}
update();
}
void PS2Device::update()
{
if (m_state == State::WaitingAck)
return;
if (m_command_queue.empty())
return;
m_state = State::WaitingAck;
m_controller.send_byte(this, m_command_queue.front());
} }
} }

View File

@ -3,7 +3,6 @@
#include <kernel/FS/DevFS/FileSystem.h> #include <kernel/FS/DevFS/FileSystem.h>
#include <kernel/Input/PS2/Config.h> #include <kernel/Input/PS2/Config.h>
#include <kernel/Input/PS2/Keyboard.h> #include <kernel/Input/PS2/Keyboard.h>
#include <kernel/Thread.h>
#define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask))) #define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask)))
#define TOGGLE_MASK(byte, mask) ((byte) ^ (mask)) #define TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
@ -25,121 +24,90 @@ namespace Kernel::Input
void PS2Keyboard::send_initialize() void PS2Keyboard::send_initialize()
{ {
constexpr uint8_t wanted_scancode_set = 3; append_command_queue(Command::SET_LEDS, 0x00);
append_command_queue(Command::SET_LEDS, 0x00, 0); append_command_queue(Command::SCANCODE, PS2::KBScancode::SET_SCANCODE_SET2);
append_command_queue(Command::CONFIG_SCANCODE_SET, wanted_scancode_set, 0); append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING);
append_command_queue(Command::CONFIG_SCANCODE_SET, 0, 1);
} }
void PS2Keyboard::command_timedout(uint8_t* command_data, uint8_t command_size) void PS2Keyboard::handle_device_command_response(uint8_t byte)
{ {
if (command_size == 0) switch (byte)
return;
if (command_data[0] == Command::CONFIG_SCANCODE_SET && m_scancode_set >= 0xFE)
{ {
dwarnln("Could not detect scancode set, assuming 1"); case PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN1:
m_scancode_set = 1; case PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN2:
m_keymap.initialize(m_scancode_set); dwarnln("Key detection error or internal buffer overrun");
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0); break;
default:
dwarnln("Unhandeled byte {2H}", byte);
break;
} }
} }
void PS2Keyboard::handle_byte(uint8_t byte) void PS2Keyboard::handle_byte(uint8_t byte)
{ {
if (byte == PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN1 || byte == PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN2)
{
dwarnln("Key detection error or internal buffer overrun");
return;
}
if (m_scancode_set == 0xFF)
{
append_command_queue(Command::CONFIG_SCANCODE_SET, 0, 1);
m_scancode_set = 0xFE;
return;
}
if (m_scancode_set == 0xFE)
{
if (1 <= byte && byte <= 3)
{
m_scancode_set = byte;
dprintln("Using scancode set {}", m_scancode_set);
}
else
{
dwarnln("Could not detect scancode set, assuming 1");
m_scancode_set = 1;
}
m_keymap.initialize(m_scancode_set);
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0);
return;
}
if (m_byte_index >= 3)
{
dwarnln("PS/2 corrupted key packet");
m_byte_index = 0;
return;
}
m_byte_buffer[m_byte_index++] = byte; m_byte_buffer[m_byte_index++] = byte;
if (byte == 0xE0) if (byte == 0xE0 || byte == 0xF0)
return;
if ((m_scancode_set == 2 || m_scancode_set == 3) && byte == 0xF0)
return; return;
uint32_t scancode = 0;
bool extended = false; bool extended = false;
bool released = false; bool released = false;
uint8_t index = 0; for (uint8_t i = 0; i < m_byte_index; i++)
// in all scancode sets, extended scancode is indicated by byte 0xE0
if (index < m_byte_index && m_byte_buffer[index] == 0xE0)
{ {
extended = true; if (m_byte_buffer[i] == 0xE0)
index++; extended = true;
} else if (m_byte_buffer[i] == 0xF0)
// in scancode set 1, released key is indicated by bit 7 set released = true;
if (m_scancode_set == 1 && (m_byte_buffer[index] & 0x80)) else
{ scancode = (scancode << 8) | m_byte_buffer[i];
released = true;
m_byte_buffer[index] &= 0x7F;
}
// in scancode set 2 and 3, released key is indicated by byte 0xF0
if ((m_scancode_set == 2 || m_scancode_set == 3) && m_byte_buffer[index] == 0xF0)
{
released = true;
index++;
} }
bool corrupted = (index + 1 != m_byte_index); if (extended)
scancode |= 0x80000000;
m_byte_index = 0; m_byte_index = 0;
if (corrupted) Key key = m_keymap.key_for_scancode_and_modifiers(scancode, m_modifiers);
if (key == Key::None)
return;
if (key == Input::Key::Invalid)
{ {
dwarnln("PS/2 corrupted key packet"); dprintln("unknown key for scancode {2H} {}", scancode & 0x7FFFFFFF, extended ? 'E' : ' ');
return; return;
} }
auto keycode = m_keymap.get_keycode(m_byte_buffer[index], extended); uint8_t modifier_mask = 0;
if (!keycode.has_value()) uint8_t toggle_mask = 0;
return; switch (key)
uint16_t modifier_mask = 0;
uint16_t toggle_mask = 0;
switch (keycode.value())
{ {
case ModifierKeycode::LShift: modifier_mask = KeyEvent::Modifier::LShift; break; case Input::Key::LeftShift:
case ModifierKeycode::RShift: modifier_mask = KeyEvent::Modifier::RShift; break; case Input::Key::RightShift:
case ModifierKeycode::LCtrl: modifier_mask = KeyEvent::Modifier::LCtrl; break; modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Shift;
case ModifierKeycode::RCtrl: modifier_mask = KeyEvent::Modifier::RCtrl; break; break;
case ModifierKeycode::LAlt: modifier_mask = KeyEvent::Modifier::LAlt; break; case Input::Key::LeftCtrl:
case ModifierKeycode::RAlt: modifier_mask = KeyEvent::Modifier::RAlt; break; case Input::Key::RightCtrl:
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Ctrl;
case ModifierKeycode::ScrollLock: toggle_mask = KeyEvent::Modifier::ScrollLock; break; break;
case ModifierKeycode::NumLock: toggle_mask = KeyEvent::Modifier::NumLock; break; case Input::Key::Alt:
case ModifierKeycode::CapsLock: toggle_mask = KeyEvent::Modifier::CapsLock; break; modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Alt;
break;
case Input::Key::AltGr:
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::AltGr;
break;;
case Input::Key::ScrollLock:
toggle_mask = (uint8_t)Input::KeyEvent::Modifier::ScrollLock;
break;
case Input::Key::NumLock:
toggle_mask = (uint8_t)Input::KeyEvent::Modifier::NumLock;
break;
case Input::Key::CapsLock:
toggle_mask = (uint8_t)Input::KeyEvent::Modifier::CapsLock;
break;
default:
break;
} }
if (modifier_mask) if (modifier_mask)
@ -150,15 +118,15 @@ namespace Kernel::Input
m_modifiers |= modifier_mask; m_modifiers |= modifier_mask;
} }
if (toggle_mask) if (toggle_mask && !released)
{ {
m_modifiers ^= toggle_mask; m_modifiers ^= toggle_mask;
update_leds(); update_leds();
} }
KeyEvent event; Input::KeyEvent event;
event.modifier = m_modifiers | (released ? 0 : KeyEvent::Modifier::Pressed); event.modifier = m_modifiers | (released ? (uint8_t)Input::KeyEvent::Modifier::Released : 0);
event.keycode = keycode.value(); event.key = key;
if (m_event_queue.full()) if (m_event_queue.full())
{ {
@ -173,13 +141,13 @@ namespace Kernel::Input
void PS2Keyboard::update_leds() void PS2Keyboard::update_leds()
{ {
uint8_t new_leds = 0; uint8_t new_leds = 0;
if (m_modifiers & +Input::KeyEvent::Modifier::ScrollLock) if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::ScrollLock)
new_leds |= PS2::KBLeds::SCROLL_LOCK; new_leds |= PS2::KBLeds::SCROLL_LOCK;
if (m_modifiers & +Input::KeyEvent::Modifier::NumLock) if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::NumLock)
new_leds |= PS2::KBLeds::NUM_LOCK; new_leds |= PS2::KBLeds::NUM_LOCK;
if (m_modifiers & +Input::KeyEvent::Modifier::CapsLock) if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::CapsLock)
new_leds |= PS2::KBLeds::CAPS_LOCK; new_leds |= PS2::KBLeds::CAPS_LOCK;
append_command_queue(Command::SET_LEDS, new_leds, 0); append_command_queue(Command::SET_LEDS, new_leds);
} }
BAN::ErrorOr<size_t> PS2Keyboard::read_impl(off_t, BAN::ByteSpan buffer) BAN::ErrorOr<size_t> PS2Keyboard::read_impl(off_t, BAN::ByteSpan buffer)
@ -190,7 +158,7 @@ namespace Kernel::Input
while (true) while (true)
{ {
if (m_event_queue.empty()) if (m_event_queue.empty())
TRY(Thread::current().block_or_eintr(m_semaphore)); m_semaphore.block();
CriticalScope _; CriticalScope _;
if (m_event_queue.empty()) if (m_event_queue.empty())

View File

@ -1,361 +1,360 @@
#include <kernel/Input/KeyEvent.h>
#include <kernel/Input/PS2/Keymap.h> #include <kernel/Input/PS2/Keymap.h>
namespace Kernel::Input namespace Kernel::Input
{ {
void PS2Keymap::initialize(uint8_t scancode_set) PS2Keymap::PS2Keymap()
{ {
memset(m_scancode_to_keycode_normal.data(), 0xFF, m_scancode_to_keycode_normal.size()); MUST(m_normal_keymap.resize(0xFF, Key::Invalid));
memset(m_scancode_to_keycode_extended.data(), 0xFF, m_scancode_to_keycode_extended.size()); m_normal_keymap[0x01] = Key::F9;
if (scancode_set == 1) m_normal_keymap[0x03] = Key::F5;
return initialize_scancode_set1(); m_normal_keymap[0x04] = Key::F3;
if (scancode_set == 2) m_normal_keymap[0x05] = Key::F1;
return initialize_scancode_set2(); m_normal_keymap[0x06] = Key::F2;
if (scancode_set == 3) m_normal_keymap[0x07] = Key::F11;
return initialize_scancode_set3(); m_normal_keymap[0x09] = Key::F10;
ASSERT_NOT_REACHED(); m_normal_keymap[0x0A] = Key::F8;
m_normal_keymap[0x0B] = Key::F6;
m_normal_keymap[0x0C] = Key::F4;
m_normal_keymap[0x0D] = Key::Tab;
m_normal_keymap[0x0E] = Key::Section;
m_normal_keymap[0x11] = Key::Alt;
m_normal_keymap[0x12] = Key::LeftShift;
m_normal_keymap[0x14] = Key::LeftCtrl;
m_normal_keymap[0x15] = Key::Q;
m_normal_keymap[0x16] = Key::_1;
m_normal_keymap[0x1A] = Key::Z;
m_normal_keymap[0x1B] = Key::S;
m_normal_keymap[0x1C] = Key::A;
m_normal_keymap[0x1D] = Key::W;
m_normal_keymap[0x1E] = Key::_2;
m_normal_keymap[0x21] = Key::C;
m_normal_keymap[0x22] = Key::X;
m_normal_keymap[0x23] = Key::D;
m_normal_keymap[0x24] = Key::E;
m_normal_keymap[0x25] = Key::_4;
m_normal_keymap[0x26] = Key::_3;
m_normal_keymap[0x29] = Key::Space;
m_normal_keymap[0x2A] = Key::V;
m_normal_keymap[0x2B] = Key::F;
m_normal_keymap[0x2C] = Key::T;
m_normal_keymap[0x2D] = Key::R;
m_normal_keymap[0x2E] = Key::_5;
m_normal_keymap[0x31] = Key::N;
m_normal_keymap[0x32] = Key::B;
m_normal_keymap[0x33] = Key::H;
m_normal_keymap[0x34] = Key::G;
m_normal_keymap[0x35] = Key::Y;
m_normal_keymap[0x36] = Key::_6;
m_normal_keymap[0x3A] = Key::M;
m_normal_keymap[0x3B] = Key::J;
m_normal_keymap[0x3C] = Key::U;
m_normal_keymap[0x3D] = Key::_7;
m_normal_keymap[0x3E] = Key::_8;
m_normal_keymap[0x41] = Key::Comma;
m_normal_keymap[0x42] = Key::K;
m_normal_keymap[0x43] = Key::I;
m_normal_keymap[0x44] = Key::O;
m_normal_keymap[0x45] = Key::_0;
m_normal_keymap[0x46] = Key::_9;
m_normal_keymap[0x49] = Key::Period;
m_normal_keymap[0x4A] = Key::Hyphen;
m_normal_keymap[0x4B] = Key::L;
m_normal_keymap[0x4C] = Key::O_Umlaut;
m_normal_keymap[0x4D] = Key::P;
m_normal_keymap[0x4E] = Key::Plus;
m_normal_keymap[0x52] = Key::A_Umlaut;
m_normal_keymap[0x54] = Key::A_Ring;
m_normal_keymap[0x55] = Key::Acute;
m_normal_keymap[0x58] = Key::CapsLock;
m_normal_keymap[0x59] = Key::RightShift;
m_normal_keymap[0x59] = Key::RightShift;
m_normal_keymap[0x5A] = Key::Enter;
m_normal_keymap[0x5B] = Key::TwoDots;
m_normal_keymap[0x5D] = Key::SingleQuote;
m_normal_keymap[0x61] = Key::LessThan;
m_normal_keymap[0x66] = Key::Backspace;
m_normal_keymap[0x69] = Key::Numpad1;
m_normal_keymap[0x6B] = Key::Numpad4;
m_normal_keymap[0x6C] = Key::Numpad7;
m_normal_keymap[0x70] = Key::Numpad0;
m_normal_keymap[0x71] = Key::NumpadDecimal;
m_normal_keymap[0x72] = Key::Numpad2;
m_normal_keymap[0x73] = Key::Numpad5;
m_normal_keymap[0x74] = Key::Numpad6;
m_normal_keymap[0x75] = Key::Numpad8;
m_normal_keymap[0x76] = Key::Escape;
m_normal_keymap[0x77] = Key::NumLock;
m_normal_keymap[0x78] = Key::F11;
m_normal_keymap[0x79] = Key::NumpadPlus;
m_normal_keymap[0x7A] = Key::Numpad3;
m_normal_keymap[0x7B] = Key::NumpadMinus;
m_normal_keymap[0x7C] = Key::NumpadMultiply;
m_normal_keymap[0x7D] = Key::Numpad9;
m_normal_keymap[0x83] = Key::F7;
MUST(m_shift_keymap.resize(0xFF, Key::Invalid));
m_shift_keymap[0x01] = Key::F9;
m_shift_keymap[0x03] = Key::F5;
m_shift_keymap[0x04] = Key::F3;
m_shift_keymap[0x05] = Key::F1;
m_shift_keymap[0x06] = Key::F2;
m_shift_keymap[0x07] = Key::F11;
m_shift_keymap[0x09] = Key::F10;
m_shift_keymap[0x0A] = Key::F8;
m_shift_keymap[0x0B] = Key::F6;
m_shift_keymap[0x0C] = Key::F4;
m_shift_keymap[0x0D] = Key::Tab;
m_shift_keymap[0x0E] = Key::Half;
m_shift_keymap[0x11] = Key::Alt;
m_shift_keymap[0x12] = Key::LeftShift;
m_shift_keymap[0x14] = Key::LeftCtrl;
m_shift_keymap[0x15] = Key::Q;
m_shift_keymap[0x16] = Key::ExclamationMark;
m_shift_keymap[0x1A] = Key::Z;
m_shift_keymap[0x1B] = Key::S;
m_shift_keymap[0x1C] = Key::A;
m_shift_keymap[0x1D] = Key::W;
m_shift_keymap[0x1E] = Key::DoubleQuote;
m_shift_keymap[0x21] = Key::C;
m_shift_keymap[0x22] = Key::X;
m_shift_keymap[0x23] = Key::D;
m_shift_keymap[0x24] = Key::E;
m_shift_keymap[0x25] = Key::Currency;
m_shift_keymap[0x26] = Key::Hashtag;
m_shift_keymap[0x29] = Key::Space;
m_shift_keymap[0x2A] = Key::V;
m_shift_keymap[0x2B] = Key::F;
m_shift_keymap[0x2C] = Key::T;
m_shift_keymap[0x2D] = Key::R;
m_shift_keymap[0x2E] = Key::Percent;
m_shift_keymap[0x31] = Key::N;
m_shift_keymap[0x32] = Key::B;
m_shift_keymap[0x33] = Key::H;
m_shift_keymap[0x34] = Key::G;
m_shift_keymap[0x35] = Key::Y;
m_shift_keymap[0x36] = Key::Ampersand;
m_shift_keymap[0x3A] = Key::M;
m_shift_keymap[0x3B] = Key::J;
m_shift_keymap[0x3C] = Key::U;
m_shift_keymap[0x3D] = Key::Slash;
m_shift_keymap[0x3E] = Key::OpenBracet;
m_shift_keymap[0x41] = Key::Semicolon;
m_shift_keymap[0x42] = Key::K;
m_shift_keymap[0x43] = Key::I;
m_shift_keymap[0x44] = Key::O;
m_shift_keymap[0x45] = Key::Equals;
m_shift_keymap[0x46] = Key::CloseBracet;
m_shift_keymap[0x49] = Key::Colon;
m_shift_keymap[0x4A] = Key::Underscore;
m_shift_keymap[0x4B] = Key::L;
m_shift_keymap[0x4C] = Key::O_Umlaut;
m_shift_keymap[0x4D] = Key::P;
m_shift_keymap[0x4E] = Key::QuestionMark;
m_shift_keymap[0x52] = Key::A_Umlaut;
m_shift_keymap[0x54] = Key::A_Ring;
m_shift_keymap[0x55] = Key::BackTick;
m_shift_keymap[0x58] = Key::CapsLock;
m_shift_keymap[0x59] = Key::RightShift;
m_shift_keymap[0x59] = Key::RightShift;
m_shift_keymap[0x5A] = Key::Enter;
m_shift_keymap[0x5B] = Key::Caret;
m_shift_keymap[0x5D] = Key::Asterix;
m_shift_keymap[0x61] = Key::GreaterThan;
m_shift_keymap[0x66] = Key::Backspace;
m_shift_keymap[0x69] = Key::Numpad1;
m_shift_keymap[0x6B] = Key::Numpad4;
m_shift_keymap[0x6C] = Key::Numpad7;
m_shift_keymap[0x70] = Key::Numpad0;
m_shift_keymap[0x71] = Key::NumpadDecimal;
m_shift_keymap[0x72] = Key::Numpad2;
m_shift_keymap[0x73] = Key::Numpad5;
m_shift_keymap[0x74] = Key::Numpad6;
m_shift_keymap[0x75] = Key::Numpad8;
m_shift_keymap[0x76] = Key::Escape;
m_shift_keymap[0x77] = Key::NumLock;
m_shift_keymap[0x78] = Key::F11;
m_shift_keymap[0x79] = Key::NumpadPlus;
m_shift_keymap[0x7A] = Key::Numpad3;
m_shift_keymap[0x7B] = Key::NumpadMinus;
m_shift_keymap[0x7C] = Key::NumpadMultiply;
m_shift_keymap[0x7D] = Key::Numpad9;
m_shift_keymap[0x83] = Key::F7;
MUST(m_altgr_keymap.resize(0xFF, Key::Invalid));
m_altgr_keymap[0x01] = Key::F9;
m_altgr_keymap[0x03] = Key::F5;
m_altgr_keymap[0x04] = Key::F3;
m_altgr_keymap[0x05] = Key::F1;
m_altgr_keymap[0x06] = Key::F2;
m_altgr_keymap[0x07] = Key::F11;
m_altgr_keymap[0x09] = Key::F10;
m_altgr_keymap[0x0A] = Key::F8;
m_altgr_keymap[0x0B] = Key::F6;
m_altgr_keymap[0x0C] = Key::F4;
m_altgr_keymap[0x0D] = Key::Tab;
m_altgr_keymap[0x0E] = Key::None;
m_altgr_keymap[0x11] = Key::Alt;
m_altgr_keymap[0x12] = Key::LeftShift;
m_altgr_keymap[0x14] = Key::LeftCtrl;
m_altgr_keymap[0x15] = Key::Q;
m_altgr_keymap[0x16] = Key::None;
m_altgr_keymap[0x1A] = Key::Z;
m_altgr_keymap[0x1B] = Key::S;
m_altgr_keymap[0x1C] = Key::A;
m_altgr_keymap[0x1D] = Key::W;
m_altgr_keymap[0x1E] = Key::AtSign;
m_altgr_keymap[0x21] = Key::C;
m_altgr_keymap[0x22] = Key::X;
m_altgr_keymap[0x23] = Key::D;
m_altgr_keymap[0x24] = Key::Euro;
m_altgr_keymap[0x25] = Key::Dollar;
m_altgr_keymap[0x26] = Key::Pound;
m_altgr_keymap[0x29] = Key::Space;
m_altgr_keymap[0x2A] = Key::V;
m_altgr_keymap[0x2B] = Key::F;
m_altgr_keymap[0x2C] = Key::T;
m_altgr_keymap[0x2D] = Key::R;
m_altgr_keymap[0x2E] = Key::None;
m_altgr_keymap[0x31] = Key::N;
m_altgr_keymap[0x32] = Key::B;
m_altgr_keymap[0x33] = Key::H;
m_altgr_keymap[0x34] = Key::G;
m_altgr_keymap[0x35] = Key::Y;
m_altgr_keymap[0x36] = Key::None;
m_altgr_keymap[0x3A] = Key::M;
m_altgr_keymap[0x3B] = Key::J;
m_altgr_keymap[0x3C] = Key::U;
m_altgr_keymap[0x3D] = Key::OpenCurlyBrace;
m_altgr_keymap[0x3E] = Key::OpenBrace;
m_altgr_keymap[0x41] = Key::None;
m_altgr_keymap[0x42] = Key::K;
m_altgr_keymap[0x43] = Key::I;
m_altgr_keymap[0x44] = Key::O;
m_altgr_keymap[0x45] = Key::CloseCurlyBrace;
m_altgr_keymap[0x46] = Key::CloseBrace;
m_altgr_keymap[0x49] = Key::None;
m_altgr_keymap[0x4A] = Key::None;
m_altgr_keymap[0x4B] = Key::L;
m_altgr_keymap[0x4C] = Key::O_Umlaut;
m_altgr_keymap[0x4D] = Key::P;
m_altgr_keymap[0x4E] = Key::BackSlash;
m_altgr_keymap[0x52] = Key::A_Umlaut;
m_altgr_keymap[0x54] = Key::A_Ring;
m_altgr_keymap[0x55] = Key::None;
m_altgr_keymap[0x58] = Key::CapsLock;
m_altgr_keymap[0x59] = Key::RightShift;
m_altgr_keymap[0x59] = Key::RightShift;
m_altgr_keymap[0x5A] = Key::Enter;
m_altgr_keymap[0x5B] = Key::Tilde;
m_altgr_keymap[0x5D] = Key::None;
m_altgr_keymap[0x61] = Key::Pipe;
m_altgr_keymap[0x66] = Key::Backspace;
m_altgr_keymap[0x69] = Key::Numpad1;
m_altgr_keymap[0x6B] = Key::Numpad4;
m_altgr_keymap[0x6C] = Key::Numpad7;
m_altgr_keymap[0x70] = Key::Numpad0;
m_altgr_keymap[0x71] = Key::NumpadDecimal;
m_altgr_keymap[0x72] = Key::Numpad2;
m_altgr_keymap[0x73] = Key::Numpad5;
m_altgr_keymap[0x74] = Key::Numpad6;
m_altgr_keymap[0x75] = Key::Numpad8;
m_altgr_keymap[0x76] = Key::Escape;
m_altgr_keymap[0x77] = Key::NumLock;
m_altgr_keymap[0x78] = Key::F11;
m_altgr_keymap[0x79] = Key::NumpadPlus;
m_altgr_keymap[0x7A] = Key::Numpad3;
m_altgr_keymap[0x7B] = Key::NumpadMinus;
m_altgr_keymap[0x7C] = Key::NumpadMultiply;
m_altgr_keymap[0x7D] = Key::Numpad9;
m_altgr_keymap[0x83] = Key::F7;
MUST(m_extended_keymap.resize(0xFF, Key::Invalid));
m_extended_keymap[0x11] = Key::AltGr;
m_extended_keymap[0x14] = Key::RightCtrl;
m_extended_keymap[0x15] = Key::MediaPrevious;
m_extended_keymap[0x1F] = Key::Super;
m_extended_keymap[0x21] = Key::VolumeUp;
m_extended_keymap[0x23] = Key::VolumeMute;
m_extended_keymap[0x2B] = Key::Calculator;
m_extended_keymap[0x32] = Key::VolumeDown;
m_extended_keymap[0x34] = Key::MediaPlayPause;
m_extended_keymap[0x3B] = Key::MediaStop;
m_extended_keymap[0x4A] = Key::NumpadDivide;
m_extended_keymap[0x4D] = Key::MediaNext;
m_extended_keymap[0x5A] = Key::NumpadEnter;
m_extended_keymap[0x69] = Key::End;
m_extended_keymap[0x6B] = Key::ArrowLeft;
m_extended_keymap[0x6C] = Key::Home;
m_extended_keymap[0x70] = Key::Insert;
m_extended_keymap[0x71] = Key::Delete;
m_extended_keymap[0x72] = Key::ArrowDown;
m_extended_keymap[0x74] = Key::ArrowRight;
m_extended_keymap[0x75] = Key::ArrowUp;
m_extended_keymap[0x7A] = Key::PageUp;
m_extended_keymap[0x7D] = Key::PageDown;
} }
BAN::Optional<uint8_t> PS2Keymap::get_keycode(uint8_t scancode, bool extended) const Key PS2Keymap::key_for_scancode_and_modifiers(uint32_t scancode, uint8_t modifiers)
{ {
uint8_t keycode = extended ? m_scancode_to_keycode_extended[scancode] : m_scancode_to_keycode_normal[scancode]; bool extended = scancode & 0x80000000;
if (keycode == 0xFF) scancode &= 0x7FFFFFFF;
KeyEvent dummy;
dummy.modifier = modifiers;
auto& keymap = extended ? m_extended_keymap :
dummy.shift() ? m_shift_keymap :
dummy.altgr() ? m_altgr_keymap :
m_normal_keymap;
if (scancode >= keymap.size())
return Key::Invalid;
Key key = keymap[scancode];
if (!dummy.num_lock() || dummy.shift() || dummy.ctrl() || dummy.alt())
{ {
dprintln("unknown {2H} {}", scancode, extended ? 'E' : ' '); switch (key)
return {}; {
case Key::Numpad0:
key = Key::Insert;
break;
case Key::Numpad1:
key = Key::End;
break;
case Key::Numpad2:
key = Key::ArrowDown;
break;
case Key::Numpad3:
key = Key::PageDown;
break;
case Key::Numpad4:
key = Key::ArrowLeft;
break;
case Key::Numpad5:
key = Key::None;
break;
case Key::Numpad6:
key = Key::ArrowRight;
break;
case Key::Numpad7:
key = Key::Home;
break;
case Key::Numpad8:
key = Key::ArrowUp;
break;
case Key::Numpad9:
key = Key::PageUp;
break;
case Key::NumpadDecimal:
key = Key::Delete;
break;
default:
break;
}
} }
return keycode;
}
void PS2Keymap::initialize_scancode_set1() return key;
{
m_scancode_to_keycode_normal[0x29] = keycode_normal(0, 0);
m_scancode_to_keycode_normal[0x02] = keycode_normal(0, 1);
m_scancode_to_keycode_normal[0x03] = keycode_normal(0, 2);
m_scancode_to_keycode_normal[0x04] = keycode_normal(0, 3);
m_scancode_to_keycode_normal[0x05] = keycode_normal(0, 4);
m_scancode_to_keycode_normal[0x06] = keycode_normal(0, 5);
m_scancode_to_keycode_normal[0x07] = keycode_normal(0, 6);
m_scancode_to_keycode_normal[0x08] = keycode_normal(0, 7);
m_scancode_to_keycode_normal[0x09] = keycode_normal(0, 8);
m_scancode_to_keycode_normal[0x0A] = keycode_normal(0, 9);
m_scancode_to_keycode_normal[0x0B] = keycode_normal(0, 10);
m_scancode_to_keycode_normal[0x0C] = keycode_normal(0, 11);
m_scancode_to_keycode_normal[0x0D] = keycode_normal(0, 12);
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 13);
m_scancode_to_keycode_normal[0x0F] = keycode_normal(1, 0);
m_scancode_to_keycode_normal[0x10] = keycode_normal(1, 1);
m_scancode_to_keycode_normal[0x11] = keycode_normal(1, 2);
m_scancode_to_keycode_normal[0x12] = keycode_normal(1, 3);
m_scancode_to_keycode_normal[0x13] = keycode_normal(1, 4);
m_scancode_to_keycode_normal[0x14] = keycode_normal(1, 5);
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 6);
m_scancode_to_keycode_normal[0x16] = keycode_normal(1, 7);
m_scancode_to_keycode_normal[0x17] = keycode_normal(1, 8);
m_scancode_to_keycode_normal[0x18] = keycode_normal(1, 9);
m_scancode_to_keycode_normal[0x19] = keycode_normal(1, 10);
m_scancode_to_keycode_normal[0x1A] = keycode_normal(1, 11);
m_scancode_to_keycode_normal[0x1B] = keycode_normal(1, 12);
m_scancode_to_keycode_normal[0x3A] = keycode_normal(2, 0);
m_scancode_to_keycode_normal[0x1E] = keycode_normal(2, 1);
m_scancode_to_keycode_normal[0x1F] = keycode_normal(2, 2);
m_scancode_to_keycode_normal[0x20] = keycode_normal(2, 3);
m_scancode_to_keycode_normal[0x21] = keycode_normal(2, 4);
m_scancode_to_keycode_normal[0x22] = keycode_normal(2, 5);
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 6);
m_scancode_to_keycode_normal[0x24] = keycode_normal(2, 7);
m_scancode_to_keycode_normal[0x25] = keycode_normal(2, 8);
m_scancode_to_keycode_normal[0x26] = keycode_normal(2, 9);
m_scancode_to_keycode_normal[0x27] = keycode_normal(2, 10);
m_scancode_to_keycode_normal[0x28] = keycode_normal(2, 11);
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 12);
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 13);
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 0);
m_scancode_to_keycode_normal[0x56] = keycode_normal(3, 1);
m_scancode_to_keycode_normal[0x2C] = keycode_normal(3, 2);
m_scancode_to_keycode_normal[0x2D] = keycode_normal(3, 3);
m_scancode_to_keycode_normal[0x2E] = keycode_normal(3, 4);
m_scancode_to_keycode_normal[0x2F] = keycode_normal(3, 5);
m_scancode_to_keycode_normal[0x30] = keycode_normal(3, 6);
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 8);
m_scancode_to_keycode_normal[0x33] = keycode_normal(3, 9);
m_scancode_to_keycode_normal[0x34] = keycode_normal(3, 10);
m_scancode_to_keycode_normal[0x35] = keycode_normal(3, 11);
m_scancode_to_keycode_normal[0x36] = keycode_normal(3, 12);
m_scancode_to_keycode_normal[0x1D] = keycode_normal(4, 0);
m_scancode_to_keycode_extended[0x5B] = keycode_normal(4, 1);
m_scancode_to_keycode_normal[0x38] = keycode_normal(4, 2);
m_scancode_to_keycode_normal[0x39] = keycode_normal(4, 3);
m_scancode_to_keycode_extended[0x38] = keycode_normal(4, 4);
m_scancode_to_keycode_extended[0x1D] = keycode_normal(4, 5);
m_scancode_to_keycode_normal[0x45] = keycode_numpad(0, 0);
m_scancode_to_keycode_extended[0x35] = keycode_numpad(0, 1);
m_scancode_to_keycode_normal[0x37] = keycode_numpad(0, 2);
m_scancode_to_keycode_normal[0x4A] = keycode_numpad(0, 3);
m_scancode_to_keycode_normal[0x47] = keycode_numpad(1, 0);
m_scancode_to_keycode_normal[0x48] = keycode_numpad(1, 1);
m_scancode_to_keycode_normal[0x49] = keycode_numpad(1, 2);
m_scancode_to_keycode_normal[0x4E] = keycode_numpad(1, 3);
m_scancode_to_keycode_normal[0x4B] = keycode_numpad(2, 0);
m_scancode_to_keycode_normal[0x4C] = keycode_numpad(2, 1);
m_scancode_to_keycode_normal[0x4D] = keycode_numpad(2, 2);
m_scancode_to_keycode_normal[0x4F] = keycode_numpad(3, 0);
m_scancode_to_keycode_normal[0x50] = keycode_numpad(3, 1);
m_scancode_to_keycode_normal[0x51] = keycode_numpad(3, 2);
m_scancode_to_keycode_extended[0x1C] = keycode_numpad(3, 3);
m_scancode_to_keycode_normal[0x52] = keycode_numpad(4, 0);
m_scancode_to_keycode_normal[0x53] = keycode_numpad(4, 1);
m_scancode_to_keycode_normal[0x01] = keycode_function( 0);
m_scancode_to_keycode_normal[0x3B] = keycode_function( 1);
m_scancode_to_keycode_normal[0x3C] = keycode_function( 2);
m_scancode_to_keycode_normal[0x3D] = keycode_function( 3);
m_scancode_to_keycode_normal[0x3E] = keycode_function( 4);
m_scancode_to_keycode_normal[0x3F] = keycode_function( 5);
m_scancode_to_keycode_normal[0x40] = keycode_function( 6);
m_scancode_to_keycode_normal[0x41] = keycode_function( 7);
m_scancode_to_keycode_normal[0x42] = keycode_function( 8);
m_scancode_to_keycode_normal[0x43] = keycode_function( 9);
m_scancode_to_keycode_normal[0x44] = keycode_function(10);
m_scancode_to_keycode_normal[0x57] = keycode_function(11);
m_scancode_to_keycode_normal[0x58] = keycode_function(12);
m_scancode_to_keycode_extended[0x52] = keycode_function(13);
//m_scancode_to_keycode_normal[0x] = keycode_function(14);
m_scancode_to_keycode_extended[0x53] = keycode_function(15);
m_scancode_to_keycode_extended[0x47] = keycode_function(16);
m_scancode_to_keycode_extended[0x4F] = keycode_function(17);
m_scancode_to_keycode_extended[0x49] = keycode_function(18);
m_scancode_to_keycode_extended[0x51] = keycode_function(19);
m_scancode_to_keycode_normal[0x46] = keycode_function(20);
// Arrow keys
m_scancode_to_keycode_extended[0x48] = keycode_normal(5, 0);
m_scancode_to_keycode_extended[0x4B] = keycode_normal(5, 1);
m_scancode_to_keycode_extended[0x50] = keycode_normal(5, 2);
m_scancode_to_keycode_extended[0x4D] = keycode_normal(5, 3);
}
void PS2Keymap::initialize_scancode_set2()
{
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 0);
m_scancode_to_keycode_normal[0x16] = keycode_normal(0, 1);
m_scancode_to_keycode_normal[0x1E] = keycode_normal(0, 2);
m_scancode_to_keycode_normal[0x26] = keycode_normal(0, 3);
m_scancode_to_keycode_normal[0x25] = keycode_normal(0, 4);
m_scancode_to_keycode_normal[0x2E] = keycode_normal(0, 5);
m_scancode_to_keycode_normal[0x36] = keycode_normal(0, 6);
m_scancode_to_keycode_normal[0x3D] = keycode_normal(0, 7);
m_scancode_to_keycode_normal[0x3E] = keycode_normal(0, 8);
m_scancode_to_keycode_normal[0x46] = keycode_normal(0, 9);
m_scancode_to_keycode_normal[0x45] = keycode_normal(0, 10);
m_scancode_to_keycode_normal[0x4E] = keycode_normal(0, 11);
m_scancode_to_keycode_normal[0x55] = keycode_normal(0, 12);
m_scancode_to_keycode_normal[0x66] = keycode_normal(0, 13);
m_scancode_to_keycode_normal[0x0D] = keycode_normal(1, 0);
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 1);
m_scancode_to_keycode_normal[0x1D] = keycode_normal(1, 2);
m_scancode_to_keycode_normal[0x24] = keycode_normal(1, 3);
m_scancode_to_keycode_normal[0x2D] = keycode_normal(1, 4);
m_scancode_to_keycode_normal[0x2C] = keycode_normal(1, 5);
m_scancode_to_keycode_normal[0x35] = keycode_normal(1, 6);
m_scancode_to_keycode_normal[0x3C] = keycode_normal(1, 7);
m_scancode_to_keycode_normal[0x43] = keycode_normal(1, 8);
m_scancode_to_keycode_normal[0x44] = keycode_normal(1, 9);
m_scancode_to_keycode_normal[0x4D] = keycode_normal(1, 10);
m_scancode_to_keycode_normal[0x54] = keycode_normal(1, 11);
m_scancode_to_keycode_normal[0x5B] = keycode_normal(1, 12);
m_scancode_to_keycode_normal[0x58] = keycode_normal(2, 0);
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 1);
m_scancode_to_keycode_normal[0x1B] = keycode_normal(2, 2);
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 3);
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 4);
m_scancode_to_keycode_normal[0x34] = keycode_normal(2, 5);
m_scancode_to_keycode_normal[0x33] = keycode_normal(2, 6);
m_scancode_to_keycode_normal[0x3B] = keycode_normal(2, 7);
m_scancode_to_keycode_normal[0x42] = keycode_normal(2, 8);
m_scancode_to_keycode_normal[0x4B] = keycode_normal(2, 9);
m_scancode_to_keycode_normal[0x4C] = keycode_normal(2, 10);
m_scancode_to_keycode_normal[0x52] = keycode_normal(2, 11);
m_scancode_to_keycode_normal[0x5D] = keycode_normal(2, 12);
m_scancode_to_keycode_normal[0x5A] = keycode_normal(2, 13);
m_scancode_to_keycode_normal[0x12] = keycode_normal(3, 0);
m_scancode_to_keycode_normal[0x61] = keycode_normal(3, 1);
m_scancode_to_keycode_normal[0x1A] = keycode_normal(3, 2);
m_scancode_to_keycode_normal[0x22] = keycode_normal(3, 3);
m_scancode_to_keycode_normal[0x21] = keycode_normal(3, 4);
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 5);
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 6);
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
m_scancode_to_keycode_normal[0x3A] = keycode_normal(3, 8);
m_scancode_to_keycode_normal[0x41] = keycode_normal(3, 9);
m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10);
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11);
m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12);
m_scancode_to_keycode_normal[0x14] = keycode_normal(4, 1);
m_scancode_to_keycode_extended[0x1F] = keycode_normal(4, 2);
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 3);
m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 4);
m_scancode_to_keycode_extended[0x11] = keycode_normal(4, 5);
m_scancode_to_keycode_extended[0x14] = keycode_normal(4, 6);
m_scancode_to_keycode_normal[0x77] = keycode_numpad(0, 0);
m_scancode_to_keycode_extended[0x4A] = keycode_numpad(0, 1);
m_scancode_to_keycode_normal[0x7C] = keycode_numpad(0, 2);
m_scancode_to_keycode_normal[0x7B] = keycode_numpad(0, 3);
m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 0);
m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 1);
m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 2);
m_scancode_to_keycode_normal[0x79] = keycode_numpad(1, 3);
m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 0);
m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 1);
m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 2);
m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 0);
m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 1);
m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 2);
m_scancode_to_keycode_extended[0x5A] = keycode_numpad(3, 3);
m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 0);
m_scancode_to_keycode_normal[0x71] = keycode_numpad(4, 1);
m_scancode_to_keycode_normal[0x76] = keycode_function( 0);
m_scancode_to_keycode_normal[0x05] = keycode_function( 1);
m_scancode_to_keycode_normal[0x06] = keycode_function( 2);
m_scancode_to_keycode_normal[0x04] = keycode_function( 3);
m_scancode_to_keycode_normal[0x0C] = keycode_function( 4);
m_scancode_to_keycode_normal[0x03] = keycode_function( 5);
m_scancode_to_keycode_normal[0x0B] = keycode_function( 6);
m_scancode_to_keycode_normal[0x83] = keycode_function( 7);
m_scancode_to_keycode_normal[0x0A] = keycode_function( 8);
m_scancode_to_keycode_normal[0x01] = keycode_function( 9);
m_scancode_to_keycode_normal[0x09] = keycode_function(10);
m_scancode_to_keycode_normal[0x78] = keycode_function(11);
m_scancode_to_keycode_normal[0x07] = keycode_function(12);
m_scancode_to_keycode_extended[0x70] = keycode_function(13);
//m_scancode_to_keycode_normal[0x] = keycode_function(14);
m_scancode_to_keycode_extended[0x71] = keycode_function(15);
m_scancode_to_keycode_extended[0x6C] = keycode_function(16);
m_scancode_to_keycode_extended[0x69] = keycode_function(17);
m_scancode_to_keycode_extended[0x7D] = keycode_function(18);
m_scancode_to_keycode_extended[0x7A] = keycode_function(19);
m_scancode_to_keycode_normal[0x7E] = keycode_function(20);
// Arrow keys
m_scancode_to_keycode_extended[0x75] = keycode_normal(5, 0);
m_scancode_to_keycode_extended[0x6B] = keycode_normal(5, 1);
m_scancode_to_keycode_extended[0x72] = keycode_normal(5, 2);
m_scancode_to_keycode_extended[0x74] = keycode_normal(5, 3);
}
void PS2Keymap::initialize_scancode_set3()
{
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 0);
m_scancode_to_keycode_normal[0x16] = keycode_normal(0, 1);
m_scancode_to_keycode_normal[0x1E] = keycode_normal(0, 2);
m_scancode_to_keycode_normal[0x26] = keycode_normal(0, 3);
m_scancode_to_keycode_normal[0x25] = keycode_normal(0, 4);
m_scancode_to_keycode_normal[0x2E] = keycode_normal(0, 5);
m_scancode_to_keycode_normal[0x36] = keycode_normal(0, 6);
m_scancode_to_keycode_normal[0x3D] = keycode_normal(0, 7);
m_scancode_to_keycode_normal[0x3E] = keycode_normal(0, 8);
m_scancode_to_keycode_normal[0x46] = keycode_normal(0, 9);
m_scancode_to_keycode_normal[0x45] = keycode_normal(0, 10);
m_scancode_to_keycode_normal[0x4E] = keycode_normal(0, 11);
m_scancode_to_keycode_normal[0x55] = keycode_normal(0, 12);
m_scancode_to_keycode_normal[0x66] = keycode_normal(0, 13);
m_scancode_to_keycode_normal[0x0D] = keycode_normal(1, 0);
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 1);
m_scancode_to_keycode_normal[0x1D] = keycode_normal(1, 2);
m_scancode_to_keycode_normal[0x24] = keycode_normal(1, 3);
m_scancode_to_keycode_normal[0x2D] = keycode_normal(1, 4);
m_scancode_to_keycode_normal[0x2C] = keycode_normal(1, 5);
m_scancode_to_keycode_normal[0x35] = keycode_normal(1, 6);
m_scancode_to_keycode_normal[0x3C] = keycode_normal(1, 7);
m_scancode_to_keycode_normal[0x43] = keycode_normal(1, 8);
m_scancode_to_keycode_normal[0x44] = keycode_normal(1, 9);
m_scancode_to_keycode_normal[0x4D] = keycode_normal(1, 10);
m_scancode_to_keycode_normal[0x54] = keycode_normal(1, 11);
m_scancode_to_keycode_normal[0x5B] = keycode_normal(1, 12);
m_scancode_to_keycode_normal[0x14] = keycode_normal(2, 0);
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 1);
m_scancode_to_keycode_normal[0x1B] = keycode_normal(2, 2);
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 3);
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 4);
m_scancode_to_keycode_normal[0x34] = keycode_normal(2, 5);
m_scancode_to_keycode_normal[0x33] = keycode_normal(2, 6);
m_scancode_to_keycode_normal[0x3B] = keycode_normal(2, 7);
m_scancode_to_keycode_normal[0x42] = keycode_normal(2, 8);
m_scancode_to_keycode_normal[0x4B] = keycode_normal(2, 9);
m_scancode_to_keycode_normal[0x4C] = keycode_normal(2, 10);
m_scancode_to_keycode_normal[0x52] = keycode_normal(2, 11);
m_scancode_to_keycode_normal[0x5C] = keycode_normal(2, 12);
m_scancode_to_keycode_normal[0x5A] = keycode_normal(2, 13);
m_scancode_to_keycode_normal[0x12] = keycode_normal(3, 0);
m_scancode_to_keycode_normal[0x13] = keycode_normal(3, 1);
m_scancode_to_keycode_normal[0x1A] = keycode_normal(3, 2);
m_scancode_to_keycode_normal[0x22] = keycode_normal(3, 3);
m_scancode_to_keycode_normal[0x21] = keycode_normal(3, 4);
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 5);
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 6);
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
m_scancode_to_keycode_normal[0x3A] = keycode_normal(3, 8);
m_scancode_to_keycode_normal[0x41] = keycode_normal(3, 9);
m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10);
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11);
m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12);
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 0);
m_scancode_to_keycode_normal[0x8B] = keycode_normal(4, 1);
m_scancode_to_keycode_normal[0x19] = keycode_normal(4, 2);
m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 3);
m_scancode_to_keycode_normal[0x39] = keycode_normal(4, 4);
m_scancode_to_keycode_normal[0x58] = keycode_normal(4, 5);
m_scancode_to_keycode_normal[0x76] = keycode_numpad(0, 0);
//m_scancode_to_keycode_normal[0x] = keycode_numpad(0, 1);
m_scancode_to_keycode_normal[0x7E] = keycode_numpad(0, 2);
//m_scancode_to_keycode_normal[0x] = keycode_numpad(0, 3);
m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 1);
m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 2);
m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 3);
m_scancode_to_keycode_normal[0x7C] = keycode_numpad(1, 4);
m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 1);
m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 2);
m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 3);
m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 1);
m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 2);
m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 3);
m_scancode_to_keycode_normal[0x79] = keycode_numpad(3, 4);
m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 1);
m_scancode_to_keycode_normal[0x71] = keycode_numpad(4, 2);
m_scancode_to_keycode_normal[0x08] = keycode_function(0);
m_scancode_to_keycode_normal[0x07] = keycode_function(1);
m_scancode_to_keycode_normal[0x0F] = keycode_function(2);
m_scancode_to_keycode_normal[0x17] = keycode_function(3);
m_scancode_to_keycode_normal[0x1F] = keycode_function(4);
m_scancode_to_keycode_normal[0x27] = keycode_function(5);
m_scancode_to_keycode_normal[0x2F] = keycode_function(6);
m_scancode_to_keycode_normal[0x37] = keycode_function(7);
m_scancode_to_keycode_normal[0x3F] = keycode_function(8);
m_scancode_to_keycode_normal[0x47] = keycode_function(9);
m_scancode_to_keycode_normal[0x4F] = keycode_function(10);
m_scancode_to_keycode_normal[0x56] = keycode_function(11);
m_scancode_to_keycode_normal[0x5E] = keycode_function(12);
m_scancode_to_keycode_normal[0x67] = keycode_function(13);
m_scancode_to_keycode_normal[0x57] = keycode_function(14);
m_scancode_to_keycode_normal[0x64] = keycode_function(15);
m_scancode_to_keycode_normal[0x6E] = keycode_function(16);
m_scancode_to_keycode_normal[0x65] = keycode_function(17);
m_scancode_to_keycode_normal[0x6F] = keycode_function(18);
m_scancode_to_keycode_normal[0x6D] = keycode_function(19);
m_scancode_to_keycode_normal[0x5F] = keycode_function(20);
// Arrow keys
m_scancode_to_keycode_normal[0x63] = keycode_normal(5, 0);
m_scancode_to_keycode_normal[0x61] = keycode_normal(5, 1);
m_scancode_to_keycode_normal[0x60] = keycode_normal(5, 2);
m_scancode_to_keycode_normal[0x6A] = keycode_normal(5, 3);
} }
} }

View File

@ -3,7 +3,6 @@
#include <kernel/FS/DevFS/FileSystem.h> #include <kernel/FS/DevFS/FileSystem.h>
#include <kernel/Input/PS2/Config.h> #include <kernel/Input/PS2/Config.h>
#include <kernel/Input/PS2/Mouse.h> #include <kernel/Input/PS2/Mouse.h>
#include <kernel/Thread.h>
#define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask))) #define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask)))
#define TOGGLE_MASK(byte, mask) ((byte) ^ (mask)) #define TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
@ -26,10 +25,10 @@ namespace Kernel::Input
void PS2Mouse::send_initialize() void PS2Mouse::send_initialize()
{ {
// Query extensions // Query extensions
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0); append_command_queue(Command::SET_SAMPLE_RATE, 200);
append_command_queue(Command::SET_SAMPLE_RATE, 100, 0); append_command_queue(Command::SET_SAMPLE_RATE, 100);
append_command_queue(Command::SET_SAMPLE_RATE, 80, 0); append_command_queue(Command::SET_SAMPLE_RATE, 80);
append_command_queue(PS2::DeviceCommand::IDENTIFY, 1); append_command_queue(PS2::DeviceCommand::IDENTIFY);
} }
void PS2Mouse::initialize_extensions(uint8_t byte) void PS2Mouse::initialize_extensions(uint8_t byte)
@ -48,10 +47,10 @@ namespace Kernel::Input
else else
{ {
m_mouse_id = 0x03; m_mouse_id = 0x03;
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0); append_command_queue(Command::SET_SAMPLE_RATE, 200);
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0); append_command_queue(Command::SET_SAMPLE_RATE, 200);
append_command_queue(Command::SET_SAMPLE_RATE, 80, 0); append_command_queue(Command::SET_SAMPLE_RATE, 80);
append_command_queue(PS2::DeviceCommand::IDENTIFY, 1); append_command_queue(PS2::DeviceCommand::IDENTIFY);
} }
break; break;
case 0x04: case 0x04:
@ -65,8 +64,18 @@ namespace Kernel::Input
if (m_enabled) if (m_enabled)
{ {
append_command_queue(Command::SET_SAMPLE_RATE, 100, 0); append_command_queue(Command::SET_SAMPLE_RATE, 100);
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0); append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING);
}
}
void PS2Mouse::handle_device_command_response(uint8_t byte)
{
switch (byte)
{
default:
dwarnln("Unhandeled byte {2H}", byte);
break;
} }
} }
@ -179,7 +188,7 @@ namespace Kernel::Input
while (true) while (true)
{ {
if (m_event_queue.empty()) if (m_event_queue.empty())
TRY(Thread::current().block_or_eintr(m_semaphore)); m_semaphore.block();
CriticalScope _; CriticalScope _;
if (m_event_queue.empty()) if (m_event_queue.empty())

View File

@ -5,7 +5,6 @@
#include <kernel/FS/ProcFS/FileSystem.h> #include <kernel/FS/ProcFS/FileSystem.h>
#include <kernel/FS/VirtualFileSystem.h> #include <kernel/FS/VirtualFileSystem.h>
#include <kernel/IDT.h> #include <kernel/IDT.h>
#include <kernel/Input/KeyboardLayout.h>
#include <kernel/InterruptController.h> #include <kernel/InterruptController.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/Memory/FileBackedRegion.h> #include <kernel/Memory/FileBackedRegion.h>
@ -1254,17 +1253,6 @@ namespace Kernel
return 0; return 0;
} }
BAN::ErrorOr<long> Process::sys_load_keymap(const char* path)
{
LockGuard _(m_lock);
TRY(validate_string_access(path));
auto absolute_path = TRY(absolute_path_of(path));
TRY(Input::KeyboardLayout::get().load_from_file(absolute_path));
return 0;
}
BAN::ErrorOr<long> Process::sys_signal(int signal, void (*handler)(int)) BAN::ErrorOr<long> Process::sys_signal(int signal, void (*handler)(int))
{ {
if (signal < _SIGMIN || signal > _SIGMAX) if (signal < _SIGMIN || signal > _SIGMAX)

View File

@ -210,9 +210,6 @@ namespace Kernel
case SYS_CHOWN: case SYS_CHOWN:
ret = Process::current().sys_chown((const char*)arg1, (uid_t)arg2, (gid_t)arg3); ret = Process::current().sys_chown((const char*)arg1, (uid_t)arg2, (gid_t)arg3);
break; break;
case SYS_LOAD_KEYMAP:
ret = Process::current().sys_load_keymap((const char*)arg1);
break;
default: default:
dwarnln("Unknown syscall {}", syscall); dwarnln("Unknown syscall {}", syscall);
break; break;

View File

@ -127,13 +127,12 @@ namespace Kernel
if (event.released()) if (event.released())
return; return;
Input::Key key = Input::key_event_to_key(event); const char* ansi_c_str = Input::key_event_to_utf8(event);
const char* ansi_c_str = Input::key_to_utf8(key, event.modifier);
if (event.ctrl()) if (event.ctrl())
{ {
ansi_c_str = nullptr; ansi_c_str = nullptr;
switch (key) switch (event.key)
{ {
case Input::Key::A: ansi_c_str = "\x01"; break; case Input::Key::A: ansi_c_str = "\x01"; break;
case Input::Key::B: ansi_c_str = "\x02"; break; case Input::Key::B: ansi_c_str = "\x02"; break;
@ -166,7 +165,7 @@ namespace Kernel
} }
else else
{ {
switch (key) switch (event.key)
{ {
case Input::Key::Enter: case Input::Key::Enter:
case Input::Key::NumpadEnter: case Input::Key::NumpadEnter:
@ -323,11 +322,11 @@ namespace Kernel
uint32_t depth = m_lock.lock_depth(); uint32_t depth = m_lock.lock_depth();
for (uint32_t i = 0; i < depth; i++) for (uint32_t i = 0; i < depth; i++)
m_lock.unlock(); m_lock.unlock();
auto eintr = Thread::current().block_or_eintr(m_output.semaphore); bool eintr = Thread::current().block_or_eintr(m_output.semaphore);
for (uint32_t i = 0; i < depth; i++) for (uint32_t i = 0; i < depth; i++)
m_lock.lock(); m_lock.lock();
if (eintr.is_error()) if (eintr)
return eintr.release_error(); return BAN::Error::from_errno(EINTR);
} }
if (m_output.bytes == 0) if (m_output.bytes == 0)

View File

@ -343,14 +343,12 @@ namespace Kernel
return false; return false;
} }
BAN::ErrorOr<void> Thread::block_or_eintr(Semaphore& semaphore) bool Thread::block_or_eintr(Semaphore& semaphore)
{ {
if (is_interrupted_by_signal()) if (is_interrupted_by_signal())
return BAN::Error::from_errno(EINTR); return true;
semaphore.block(); semaphore.block();
if (is_interrupted_by_signal()) return is_interrupted_by_signal();
return BAN::Error::from_errno(EINTR);
return {};
} }
void Thread::validate_stack() const void Thread::validate_stack() const

View File

@ -8,7 +8,6 @@
#include <kernel/FS/VirtualFileSystem.h> #include <kernel/FS/VirtualFileSystem.h>
#include <kernel/GDT.h> #include <kernel/GDT.h>
#include <kernel/IDT.h> #include <kernel/IDT.h>
#include <kernel/Input/KeyboardLayout.h>
#include <kernel/Input/PS2/Controller.h> #include <kernel/Input/PS2/Controller.h>
#include <kernel/InterruptController.h> #include <kernel/InterruptController.h>
#include <kernel/kprint.h> #include <kernel/kprint.h>
@ -177,19 +176,12 @@ static void init2(void*)
DevFileSystem::get().initialize_device_updater(); DevFileSystem::get().initialize_device_updater();
#if 0
dprintln("sleeping for 5 seconds");
SystemTimer::get().sleep(5000);
#endif
PCI::PCIManager::initialize(); PCI::PCIManager::initialize();
dprintln("PCI initialized"); dprintln("PCI initialized");
VirtualFileSystem::initialize(cmdline.root); VirtualFileSystem::initialize(cmdline.root);
dprintln("VFS initialized"); dprintln("VFS initialized");
// Initialize empty keymap
MUST(Input::KeyboardLayout::initialize());
if (auto res = PS2Controller::initialize(); res.is_error()) if (auto res = PS2Controller::initialize(); res.is_error())
dprintln("{}", res.error()); dprintln("{}", res.error());

View File

@ -34,8 +34,6 @@ return value: 0 on success, -1 on failure and errno set to the error
int tty_ctrl(int fildes, int command, int flags); int tty_ctrl(int fildes, int command, int flags);
int poweroff(int command); int poweroff(int command);
int load_keymap(const char* path);
__END_DECLS __END_DECLS
#endif #endif

View File

@ -62,7 +62,6 @@ __BEGIN_DECLS
#define SYS_MSYNC 61 #define SYS_MSYNC 61
#define SYS_PREAD 62 #define SYS_PREAD 62
#define SYS_CHOWN 63 #define SYS_CHOWN 63
#define SYS_LOAD_KEYMAP 64
__END_DECLS __END_DECLS

View File

@ -11,8 +11,3 @@ int poweroff(int command)
{ {
return syscall(SYS_POWEROFF, command); return syscall(SYS_POWEROFF, command);
} }
int load_keymap(const char* path)
{
return syscall(SYS_LOAD_KEYMAP, path);
}

View File

@ -8,7 +8,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/banan-os.h>
#include <termios.h> #include <termios.h>
void initialize_stdio() void initialize_stdio()
@ -26,9 +25,6 @@ int main()
if (signal(SIGINT, [](int) {}) == SIG_ERR) if (signal(SIGINT, [](int) {}) == SIG_ERR)
perror("signal"); perror("signal");
if (load_keymap("/usr/share/keymaps/fi.keymap") == -1)
perror("load_keymap");
bool first = true; bool first = true;
termios termios; termios termios;