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

View File

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

View File

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

View File

@ -5,47 +5,6 @@
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
{
Invalid, None,
@ -55,9 +14,9 @@ namespace Kernel::Input
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
Insert, PrintScreen, Delete, Home, End, PageUp, PageDown, Enter, Space,
ExclamationMark, DoubleQuote, Hashtag, Currency, Percent, Ampersand, Slash, Section, Half,
OpenParenthesis, CloseParenthesis, OpenSquareBracket, CloseSquareBracket, OpenCurlyBracket, CloseCurlyBracket,
Equals, QuestionMark, Plus, BackSlash, Acute, BackTick, TwoDots, Cedilla, Backspace, AtSign, Pound, Dollar, Euro,
Escape, Tab, CapsLock, LeftShift, LeftCtrl, Super, LeftAlt, RightAlt, AltGr = RightAlt, RightCtrl, RightShift,
OpenBracet, CloseBracet, OpenBrace, CloseBrace, OpenCurlyBrace, CloseCurlyBrace,
Equals, QuestionMark, Plus, BackSlash, Acute, BackTick, TwoDots, Backspace, AtSign, Pound, Dollar, Euro,
Escape, Tab, CapsLock, LeftShift, LeftCtrl, Super, Alt, AltGr, RightCtrl, RightShift,
SingleQuote, Asterix, Caret, Tilde, ArrowUp, ArrowDown, ArrowLeft, ArrowRight,
Comma, Semicolon, Period, Colon, Hyphen, Underscore, NumLock, ScrollLock, LessThan, GreaterThan, Pipe,
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
@ -68,44 +27,73 @@ namespace Kernel::Input
struct KeyEvent
{
enum Modifier : uint16_t
enum class Modifier : uint8_t
{
LShift = (1 << 0),
RShift = (1 << 1),
LCtrl = (1 << 2),
RCtrl = (1 << 3),
LAlt = (1 << 4),
RAlt = (1 << 5),
CapsLock = (1 << 6),
NumLock = (1 << 7),
ScrollLock = (1 << 8),
Pressed = (1 << 9),
Shift = (1 << 0),
Ctrl = (1 << 1),
Alt = (1 << 2),
AltGr = (1 << 3),
CapsLock = (1 << 4),
NumLock = (1 << 5),
ScrollLock = (1 << 6),
Released = (1 << 7),
};
bool lshift() const { return modifier & Modifier::LShift; }
bool rshift() const { return modifier & Modifier::RShift; }
bool shift() const { return lshift() || rshift(); }
bool shift() const { return modifier & (uint8_t)Modifier::Shift; }
bool ctrl() const { return modifier & (uint8_t)Modifier::Ctrl; }
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; }
bool rctrl() const { return modifier & Modifier::RCtrl; }
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;
uint8_t modifier;
Key key;
};
Key key_event_to_key(KeyEvent);
const char* key_to_utf8(Key key, uint16_t modifier);
inline const char* key_event_to_utf8(KeyEvent event)
{
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
{
OUTPUT_STATUS = (1 << 0),
INPUT_STATUS = (1 << 1),
OUTPUT_FULL = (1 << 0),
INPUT_FULL = (1 << 1),
SYSTEM = (1 << 2),
DEVICE_OR_CONTROLLER = (1 << 3),
TIMEOUT_ERROR = (1 << 6),
@ -78,6 +78,13 @@ namespace Kernel::Input::PS2
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
{
SCROLL_LOCK = (1 << 0),

View File

@ -1,11 +1,8 @@
#pragma once
#include <BAN/CircularQueue.h>
#include <BAN/UniqPtr.h>
#include <kernel/Device/Device.h>
#include <kernel/Input/PS2/Config.h>
#include <kernel/InterruptController.h>
#include <kernel/SpinLock.h>
namespace Kernel::Input
{
@ -18,50 +15,18 @@ namespace Kernel::Input
static BAN::ErrorOr<void> initialize();
static PS2Controller& get();
bool append_command_queue(PS2Device*, uint8_t command, uint8_t response_size);
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);
void send_byte(const PS2Device*, uint8_t);
private:
PS2Controller() = default;
BAN::ErrorOr<void> initialize_impl();
BAN::ErrorOr<void> initialize_device(uint8_t);
BAN::ErrorOr<uint8_t> read_byte();
BAN::ErrorOr<void> send_byte(uint16_t port, uint8_t byte);
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);
BAN::ErrorOr<void> reset_device(uint8_t);
BAN::ErrorOr<void> set_scanning(uint8_t, bool);
private:
struct Command
{
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 };
PS2Device* m_devices[2] { nullptr, nullptr };
};
}

View File

@ -1,7 +1,6 @@
#pragma once
#include <kernel/Input/PS2/Controller.h>
#include <kernel/InterruptController.h>
namespace Kernel::Input
{
@ -14,23 +13,33 @@ namespace Kernel::Input
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, uint8_t response_size);
bool append_command_queue(uint8_t command, uint8_t data, uint8_t response_size);
bool append_command_queue(uint8_t command);
bool append_command_queue(uint8_t command, uint8_t data);
virtual void handle_irq() final override;
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 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:
const BAN::String m_name;
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
#include <BAN/Array.h>
#include <BAN/CircularQueue.h>
#include <kernel/Input/KeyEvent.h>
#include <kernel/Input/PS2/Device.h>
#include <kernel/Input/PS2/Keymap.h>
@ -16,16 +14,15 @@ namespace Kernel::Input
enum Command : uint8_t
{
SET_LEDS = 0xED,
CONFIG_SCANCODE_SET = 0xF0
SCANCODE = 0xF0
};
public:
static BAN::ErrorOr<PS2Keyboard*> create(PS2Controller&);
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_device_command_response(uint8_t) final override;
private:
PS2Keyboard(PS2Controller& controller);
@ -33,14 +30,12 @@ namespace Kernel::Input
void update_leds();
private:
BAN::Array<uint8_t, 3> m_byte_buffer;
uint8_t m_byte_buffer[10];
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, 50> m_event_queue;
BAN::CircularQueue<KeyEvent, 10> m_event_queue;
PS2Keymap m_keymap;

View File

@ -1,7 +1,7 @@
#pragma once
#include <BAN/Array.h>
#include <BAN/Optional.h>
#include <BAN/Vector.h>
#include <kernel/Input/KeyEvent.h>
namespace Kernel::Input
{
@ -9,18 +9,15 @@ namespace Kernel::Input
class PS2Keymap
{
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:
void initialize_scancode_set1();
void initialize_scancode_set2();
void initialize_scancode_set3();
private:
BAN::Array<uint8_t, 0xFF> m_scancode_to_keycode_normal;
BAN::Array<uint8_t, 0xFF> m_scancode_to_keycode_extended;
BAN::Vector<Key> m_normal_keymap;
BAN::Vector<Key> m_shift_keymap;
BAN::Vector<Key> m_altgr_keymap;
BAN::Vector<Key> m_extended_keymap;
};
}

View File

@ -19,9 +19,8 @@ namespace Kernel::Input
static BAN::ErrorOr<PS2Mouse*> create(PS2Controller&);
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_device_command_response(uint8_t) final override;
private:
PS2Mouse(PS2Controller& controller);
@ -36,7 +35,7 @@ namespace Kernel::Input
uint8_t m_mouse_id { 0x00 };
uint8_t m_button_mask { 0x00 };
BAN::CircularQueue<MouseEvent, 128> m_event_queue;
BAN::CircularQueue<MouseEvent, 25> m_event_queue;
Semaphore m_semaphore;

View File

@ -146,8 +146,6 @@ namespace Kernel
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; }
static Process& current() { return Thread::current().process(); }

View File

@ -48,7 +48,7 @@ namespace Kernel
bool add_signal(int signal);
// 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_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 no such header"sv,
"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,
"Ext2 filesystem corrupted"sv,
"Ext2 filesystem out of inodes"sv,

View File

@ -6,7 +6,6 @@
#include <kernel/FS/TmpFS/Inode.h>
#include <kernel/LockGuard.h>
#include <kernel/Process.h>
#include <kernel/Scheduler.h>
#include <kernel/Storage/StorageDevice.h>
#include <kernel/Timer/Timer.h>
@ -49,7 +48,8 @@ namespace Kernel
}
);
s_instance->m_device_lock.unlock();
Scheduler::get().reschedule();
Kernel::SystemTimer::get().sleep(1);
}
}, 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/Timer/Timer.h>
#define DEBUG_PS2 1
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;
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()
{
ASSERT(s_instance == nullptr);
@ -236,96 +89,88 @@ namespace Kernel::Input
BAN::ErrorOr<void> PS2Controller::initialize_impl()
{
// FIXME: Initialise USB Controllers
// Step 1: Initialise USB Controllers
// FIXME
// Determine if the PS/2 Controller Exists
auto* fadt = static_cast<const ACPI::FADT*>(ACPI::get().get_header("FACP"sv, 0));
if (fadt && fadt->revision > 1 && !(fadt->iapc_boot_arch & (1 << 1)))
{
dwarnln_if(DEBUG_PS2, "No PS/2 available");
return {};
}
// Step 2: Determine if the PS/2 Controller Exists
// FIXME
// Disable Devices
TRY(send_command(PS2::Command::DISABLE_FIRST_PORT));
TRY(send_command(PS2::Command::DISABLE_SECOND_PORT));
// Step 3: Disable Devices
controller_send_command(PS2::Command::DISABLE_FIRST_PORT);
controller_send_command(PS2::Command::DISABLE_SECOND_PORT);
// Flush The Output Buffer
while (!read_byte().is_error())
continue;
// Step 4: Flush The Output Buffer
IO::inb(PS2::IOPort::DATA);
// Set the Controller Configuration Byte
TRY(send_command(PS2::Command::READ_CONFIG));
uint8_t config = TRY(read_byte());
// Step 5: Set the Controller Configuration Byte
controller_send_command(PS2::Command::READ_CONFIG);
uint8_t config = wait_and_read();
config &= ~PS2::Config::INTERRUPT_FIRST_PORT;
config &= ~PS2::Config::INTERRUPT_SECOND_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
TRY(send_command(PS2::Command::TEST_CONTROLLER));
if (TRY(read_byte()) != PS2::Response::TEST_CONTROLLER_PASS)
{
dwarnln_if(DEBUG_PS2, "PS/2 Controller test failed");
return BAN::Error::from_errno(ENODEV);
}
// Step 6: Perform Controller Self Test
controller_send_command(PS2::Command::TEST_CONTROLLER);
if (wait_and_read() != PS2::Response::TEST_CONTROLLER_PASS)
return BAN::Error::from_error_code(ErrorCode::PS2_SelfTest);
// 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 };
if (config & PS2::Config::CLOCK_SECOND_PORT)
{
TRY(send_command(PS2::Command::ENABLE_SECOND_PORT));
TRY(send_command(PS2::Command::READ_CONFIG));
if (!(TRY(read_byte()) & PS2::Config::CLOCK_SECOND_PORT))
{
controller_send_command(PS2::Command::ENABLE_SECOND_PORT);
controller_send_command(PS2::Command::READ_CONFIG);
if (!(wait_and_read() & PS2::Config::CLOCK_SECOND_PORT))
valid_ports[1] = true;
TRY(send_command(PS2::Command::DISABLE_SECOND_PORT));
}
controller_send_command(PS2::Command::DISABLE_SECOND_PORT);
}
// Perform Interface Tests
TRY(send_command(PS2::Command::TEST_FIRST_PORT));
if (TRY(read_byte()) != PS2::Response::TEST_FIRST_PORT_PASS)
{
dwarnln_if(DEBUG_PS2, "PS/2 first port test failed");
// Step 8: Perform Interface Tests
controller_send_command(PS2::Command::TEST_FIRST_PORT);
if (wait_and_read() != PS2::Response::TEST_FIRST_PORT_PASS)
valid_ports[0] = false;
}
if (valid_ports[1])
{
TRY(send_command(PS2::Command::TEST_SECOND_PORT));
if (TRY(read_byte()) != PS2::Response::TEST_SECOND_PORT_PASS)
{
dwarnln_if(DEBUG_PS2, "PS/2 second port test failed");
controller_send_command(PS2::Command::TEST_SECOND_PORT);
if (wait_and_read() != PS2::Response::TEST_SECOND_PORT_PASS)
valid_ports[1] = false;
}
}
if (!valid_ports[0] && !valid_ports[1])
return {};
// Initialize devices
// Step 9: Enable Devices (and disable scanning)
for (uint8_t device = 0; device < 2; device++)
{
if (!valid_ports[device])
continue;
if (auto ret = send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT); ret.is_error())
{
dwarnln_if(DEBUG_PS2, "PS/2 device enable failed: {}", ret.error());
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;
}
controller_send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT);
if (set_scanning(device, false).is_error())
valid_ports[device] = false;
}
if (!m_devices[0] && !m_devices[1])
return {};
// Step 10: Reset Devices
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])
{
m_devices[0]->set_irq(PS2::IRQ::DEVICE0);
@ -339,12 +184,11 @@ namespace Kernel::Input
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++)
{
if (!m_devices[device])
if (m_devices[device] == nullptr)
continue;
m_devices[device]->send_initialize();
DevFileSystem::get().add_device(m_devices[device]);
@ -355,30 +199,14 @@ namespace Kernel::Input
BAN::ErrorOr<void> PS2Controller::initialize_device(uint8_t device)
{
// Reset device
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::RESET));
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;
TRY(device_send_byte(device, PS2::DeviceCommand::IDENTIFY));
TRY(device_wait_ack());
// 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 index = 0;
for (uint8_t i = 0; i < 2; i++)
{
auto res = read_byte();
auto res = device_read_byte();
if (res.is_error())
break;
bytes[index++] = res.value();
@ -386,22 +214,38 @@ namespace Kernel::Input
// Standard PS/2 Mouse
if (index == 1 && (bytes[0] == 0x00))
{
dprintln_if(DEBUG_PS2, "PS/2 found mouse");
m_devices[device] = TRY(PS2Mouse::create(*this));
return {};
}
// MF2 Keyboard
if (index == 2 && (bytes[0] == 0xAB && (bytes[1] == 0x83 || bytes[1] == 0x41)))
{
dprintln_if(DEBUG_PS2, "PS/2 found keyboard");
else if (index == 2 && (bytes[0] == 0xAB && bytes[1] == 0x83))
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);
return BAN::Error::from_errno(ENOTSUP);
if (m_devices[device])
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)
{ }
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()
{
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/Input/PS2/Config.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 TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
@ -25,121 +24,90 @@ namespace Kernel::Input
void PS2Keyboard::send_initialize()
{
constexpr uint8_t wanted_scancode_set = 3;
append_command_queue(Command::SET_LEDS, 0x00, 0);
append_command_queue(Command::CONFIG_SCANCODE_SET, wanted_scancode_set, 0);
append_command_queue(Command::CONFIG_SCANCODE_SET, 0, 1);
append_command_queue(Command::SET_LEDS, 0x00);
append_command_queue(Command::SCANCODE, PS2::KBScancode::SET_SCANCODE_SET2);
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING);
}
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)
return;
if (command_data[0] == Command::CONFIG_SCANCODE_SET && m_scancode_set >= 0xFE)
switch (byte)
{
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);
case PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN1:
case PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN2:
dwarnln("Key detection error or internal buffer overrun");
break;
default:
dwarnln("Unhandeled byte {2H}", byte);
break;
}
}
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;
if (byte == 0xE0)
return;
if ((m_scancode_set == 2 || m_scancode_set == 3) && byte == 0xF0)
if (byte == 0xE0 || byte == 0xF0)
return;
uint32_t scancode = 0;
bool extended = false;
bool released = false;
uint8_t index = 0;
// in all scancode sets, extended scancode is indicated by byte 0xE0
if (index < m_byte_index && m_byte_buffer[index] == 0xE0)
for (uint8_t i = 0; i < m_byte_index; i++)
{
extended = true;
index++;
}
// in scancode set 1, released key is indicated by bit 7 set
if (m_scancode_set == 1 && (m_byte_buffer[index] & 0x80))
{
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++;
if (m_byte_buffer[i] == 0xE0)
extended = true;
else if (m_byte_buffer[i] == 0xF0)
released = true;
else
scancode = (scancode << 8) | m_byte_buffer[i];
}
bool corrupted = (index + 1 != m_byte_index);
if (extended)
scancode |= 0x80000000;
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;
}
auto keycode = m_keymap.get_keycode(m_byte_buffer[index], extended);
if (!keycode.has_value())
return;
uint16_t modifier_mask = 0;
uint16_t toggle_mask = 0;
switch (keycode.value())
uint8_t modifier_mask = 0;
uint8_t toggle_mask = 0;
switch (key)
{
case ModifierKeycode::LShift: modifier_mask = KeyEvent::Modifier::LShift; break;
case ModifierKeycode::RShift: modifier_mask = KeyEvent::Modifier::RShift; break;
case ModifierKeycode::LCtrl: modifier_mask = KeyEvent::Modifier::LCtrl; break;
case ModifierKeycode::RCtrl: modifier_mask = KeyEvent::Modifier::RCtrl; break;
case ModifierKeycode::LAlt: modifier_mask = KeyEvent::Modifier::LAlt; break;
case ModifierKeycode::RAlt: modifier_mask = KeyEvent::Modifier::RAlt; break;
case ModifierKeycode::ScrollLock: toggle_mask = KeyEvent::Modifier::ScrollLock; break;
case ModifierKeycode::NumLock: toggle_mask = KeyEvent::Modifier::NumLock; break;
case ModifierKeycode::CapsLock: toggle_mask = KeyEvent::Modifier::CapsLock; break;
case Input::Key::LeftShift:
case Input::Key::RightShift:
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Shift;
break;
case Input::Key::LeftCtrl:
case Input::Key::RightCtrl:
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Ctrl;
break;
case Input::Key::Alt:
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)
@ -150,15 +118,15 @@ namespace Kernel::Input
m_modifiers |= modifier_mask;
}
if (toggle_mask)
if (toggle_mask && !released)
{
m_modifiers ^= toggle_mask;
update_leds();
}
KeyEvent event;
event.modifier = m_modifiers | (released ? 0 : KeyEvent::Modifier::Pressed);
event.keycode = keycode.value();
Input::KeyEvent event;
event.modifier = m_modifiers | (released ? (uint8_t)Input::KeyEvent::Modifier::Released : 0);
event.key = key;
if (m_event_queue.full())
{
@ -173,13 +141,13 @@ namespace Kernel::Input
void PS2Keyboard::update_leds()
{
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;
if (m_modifiers & +Input::KeyEvent::Modifier::NumLock)
if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::NumLock)
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;
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)
@ -190,7 +158,7 @@ namespace Kernel::Input
while (true)
{
if (m_event_queue.empty())
TRY(Thread::current().block_or_eintr(m_semaphore));
m_semaphore.block();
CriticalScope _;
if (m_event_queue.empty())

View File

@ -1,361 +1,360 @@
#include <kernel/Input/KeyEvent.h>
#include <kernel/Input/PS2/Keymap.h>
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());
memset(m_scancode_to_keycode_extended.data(), 0xFF, m_scancode_to_keycode_extended.size());
if (scancode_set == 1)
return initialize_scancode_set1();
if (scancode_set == 2)
return initialize_scancode_set2();
if (scancode_set == 3)
return initialize_scancode_set3();
ASSERT_NOT_REACHED();
MUST(m_normal_keymap.resize(0xFF, Key::Invalid));
m_normal_keymap[0x01] = Key::F9;
m_normal_keymap[0x03] = Key::F5;
m_normal_keymap[0x04] = Key::F3;
m_normal_keymap[0x05] = Key::F1;
m_normal_keymap[0x06] = Key::F2;
m_normal_keymap[0x07] = Key::F11;
m_normal_keymap[0x09] = Key::F10;
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];
if (keycode == 0xFF)
bool extended = scancode & 0x80000000;
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' : ' ');
return {};
switch (key)
{
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()
{
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);
return key;
}
}

View File

@ -3,7 +3,6 @@
#include <kernel/FS/DevFS/FileSystem.h>
#include <kernel/Input/PS2/Config.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 TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
@ -26,10 +25,10 @@ namespace Kernel::Input
void PS2Mouse::send_initialize()
{
// Query extensions
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0);
append_command_queue(Command::SET_SAMPLE_RATE, 100, 0);
append_command_queue(Command::SET_SAMPLE_RATE, 80, 0);
append_command_queue(PS2::DeviceCommand::IDENTIFY, 1);
append_command_queue(Command::SET_SAMPLE_RATE, 200);
append_command_queue(Command::SET_SAMPLE_RATE, 100);
append_command_queue(Command::SET_SAMPLE_RATE, 80);
append_command_queue(PS2::DeviceCommand::IDENTIFY);
}
void PS2Mouse::initialize_extensions(uint8_t byte)
@ -48,10 +47,10 @@ namespace Kernel::Input
else
{
m_mouse_id = 0x03;
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0);
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0);
append_command_queue(Command::SET_SAMPLE_RATE, 80, 0);
append_command_queue(PS2::DeviceCommand::IDENTIFY, 1);
append_command_queue(Command::SET_SAMPLE_RATE, 200);
append_command_queue(Command::SET_SAMPLE_RATE, 200);
append_command_queue(Command::SET_SAMPLE_RATE, 80);
append_command_queue(PS2::DeviceCommand::IDENTIFY);
}
break;
case 0x04:
@ -65,8 +64,18 @@ namespace Kernel::Input
if (m_enabled)
{
append_command_queue(Command::SET_SAMPLE_RATE, 100, 0);
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0);
append_command_queue(Command::SET_SAMPLE_RATE, 100);
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)
{
if (m_event_queue.empty())
TRY(Thread::current().block_or_eintr(m_semaphore));
m_semaphore.block();
CriticalScope _;
if (m_event_queue.empty())

View File

@ -5,7 +5,6 @@
#include <kernel/FS/ProcFS/FileSystem.h>
#include <kernel/FS/VirtualFileSystem.h>
#include <kernel/IDT.h>
#include <kernel/Input/KeyboardLayout.h>
#include <kernel/InterruptController.h>
#include <kernel/LockGuard.h>
#include <kernel/Memory/FileBackedRegion.h>
@ -1254,17 +1253,6 @@ namespace Kernel
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))
{
if (signal < _SIGMIN || signal > _SIGMAX)

View File

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

View File

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

View File

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

View File

@ -8,7 +8,6 @@
#include <kernel/FS/VirtualFileSystem.h>
#include <kernel/GDT.h>
#include <kernel/IDT.h>
#include <kernel/Input/KeyboardLayout.h>
#include <kernel/Input/PS2/Controller.h>
#include <kernel/InterruptController.h>
#include <kernel/kprint.h>
@ -177,19 +176,12 @@ static void init2(void*)
DevFileSystem::get().initialize_device_updater();
#if 0
dprintln("sleeping for 5 seconds");
SystemTimer::get().sleep(5000);
#endif
PCI::PCIManager::initialize();
dprintln("PCI initialized");
VirtualFileSystem::initialize(cmdline.root);
dprintln("VFS initialized");
// Initialize empty keymap
MUST(Input::KeyboardLayout::initialize());
if (auto res = PS2Controller::initialize(); res.is_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 poweroff(int command);
int load_keymap(const char* path);
__END_DECLS
#endif

View File

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

View File

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