diff options
Diffstat (limited to 'Kernel/Arch/x86_64/ISABus/HID')
-rw-r--r-- | Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.cpp | 77 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.h | 18 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.cpp | 38 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.h | 15 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.cpp | 19 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.h | 6 |
6 files changed, 59 insertions, 114 deletions
diff --git a/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.cpp b/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.cpp index 1f7b3140b2..4b4ea60e7d 100644 --- a/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.cpp +++ b/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.cpp @@ -10,10 +10,8 @@ #include <Kernel/Debug.h> #include <Kernel/Devices/DeviceManagement.h> #include <Kernel/Devices/HID/Management.h> -#include <Kernel/Scheduler.h> +#include <Kernel/Devices/HID/ScanCodeEvent.h> #include <Kernel/Sections.h> -#include <Kernel/TTY/ConsoleManagement.h> -#include <Kernel/WorkQueue.h> namespace Kernel { @@ -23,89 +21,46 @@ void PS2KeyboardDevice::irq_handle_byte_read(u8 byte) { u8 ch = byte & 0x7f; bool pressed = !(byte & 0x80); - - m_entropy_source.add_random_event(byte); - if (byte == 0xe0) { m_has_e0_prefix = true; return; } - if ((m_modifiers == (Mod_Alt | Mod_Shift) || m_modifiers == (Mod_Ctrl | Mod_Alt | Mod_Shift)) && byte == 0x58) { - // Alt+Shift+F12 pressed, dump some kernel state to the debug console. - ConsoleManagement::the().switch_to_debug(); - Scheduler::dump_scheduler_state(m_modifiers == (Mod_Ctrl | Mod_Alt | Mod_Shift)); - } + ScanCodeEvent event {}; + event.pressed = pressed; + event.e0_prefix = m_has_e0_prefix; + m_has_e0_prefix = false; dbgln_if(KEYBOARD_DEBUG, "Keyboard::irq_handle_byte_read: {:#02x} {}", ch, (pressed ? "down" : "up")); - switch (ch) { - case 0x38: - if (m_has_e0_prefix) - update_modifier(Mod_AltGr, pressed); - else - update_modifier(Mod_Alt, pressed); - break; - case 0x1d: - update_modifier(Mod_Ctrl, pressed); - break; - case 0x5b: - m_left_super_pressed = pressed; - update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed); - break; - case 0x5c: - m_right_super_pressed = pressed; - update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed); - break; - case 0x2a: - m_left_shift_pressed = pressed; - update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); - break; - case 0x36: - m_right_shift_pressed = pressed; - update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); - break; - } - switch (ch) { - case I8042Response::Acknowledge: - break; - default: - if ((m_modifiers & Mod_Alt) != 0 && ch >= 2 && ch <= ConsoleManagement::s_max_virtual_consoles + 1) { - // FIXME: Do something sanely here if we can't allocate a work queue? - MUST(g_io_work->try_queue([ch]() { - ConsoleManagement::the().switch_to(ch - 0x02); - })); - } - key_state_changed(ch, pressed); - } + event.scan_code_value = ch; + m_keyboard_device->handle_scan_code_input_event(event); } bool PS2KeyboardDevice::handle_irq(RegisterState const&) { // The controller will read the data and call irq_handle_byte_read // for the appropriate device - return m_i8042_controller->irq_process_input_buffer(HIDDevice::Type::Keyboard); + return m_i8042_controller->irq_process_input_buffer(instrument_type()); } -UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<PS2KeyboardDevice>> PS2KeyboardDevice::try_to_initialize(I8042Controller const& ps2_controller) +UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<PS2KeyboardDevice>> PS2KeyboardDevice::try_to_initialize(I8042Controller const& ps2_controller, KeyboardDevice const& keyboard_device) { - auto keyboard_device = TRY(DeviceManagement::try_create_device<PS2KeyboardDevice>(ps2_controller)); - - TRY(keyboard_device->initialize()); - - return keyboard_device; + auto device = TRY(adopt_nonnull_own_or_enomem(new (nothrow) PS2KeyboardDevice(ps2_controller, keyboard_device))); + TRY(device->initialize()); + return device; } UNMAP_AFTER_INIT ErrorOr<void> PS2KeyboardDevice::initialize() { - return m_i8042_controller->reset_device(HIDDevice::Type::Keyboard); + return m_i8042_controller->reset_device(PS2Device::Type::Keyboard); } // FIXME: UNMAP_AFTER_INIT might not be correct, because in practice PS/2 devices // are hot pluggable. -UNMAP_AFTER_INIT PS2KeyboardDevice::PS2KeyboardDevice(I8042Controller const& ps2_controller) +UNMAP_AFTER_INIT PS2KeyboardDevice::PS2KeyboardDevice(I8042Controller const& ps2_controller, KeyboardDevice const& keyboard_device) : IRQHandler(IRQ_KEYBOARD) - , KeyboardDevice() - , I8042Device(ps2_controller) + , PS2Device(ps2_controller) + , m_keyboard_device(keyboard_device) { } diff --git a/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.h b/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.h index 7faedbe921..4c459f49c8 100644 --- a/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.h +++ b/Kernel/Arch/x86_64/ISABus/HID/PS2KeyboardDevice.h @@ -10,39 +10,39 @@ #include <AK/Types.h> #include <Kernel/API/KeyCode.h> #include <Kernel/Arch/x86_64/ISABus/I8042Controller.h> -#include <Kernel/Devices/HID/KeyboardDevice.h> #include <Kernel/Interrupts/IRQHandler.h> #include <Kernel/Random.h> namespace Kernel { class PS2KeyboardDevice final : public IRQHandler - , public KeyboardDevice - , public I8042Device { + , public PS2Device { friend class DeviceManagement; public: - static ErrorOr<NonnullLockRefPtr<PS2KeyboardDevice>> try_to_initialize(I8042Controller const&); + static ErrorOr<NonnullOwnPtr<PS2KeyboardDevice>> try_to_initialize(I8042Controller const&, KeyboardDevice const&); virtual ~PS2KeyboardDevice() override; ErrorOr<void> initialize(); - virtual StringView purpose() const override { return class_name(); } + virtual StringView purpose() const override { return "PS2KeyboardDevice"sv; } - // ^I8042Device + // ^PS2Device virtual void irq_handle_byte_read(u8 byte) override; virtual void enable_interrupts() override { enable_irq(); } + virtual Type instrument_type() const override { return Type::Keyboard; } private: - explicit PS2KeyboardDevice(I8042Controller const&); + PS2KeyboardDevice(I8042Controller const&, KeyboardDevice const&); // ^IRQHandler virtual bool handle_irq(RegisterState const&) override; - // ^CharacterDevice - virtual StringView class_name() const override { return "KeyboardDevice"sv; } + bool m_has_e0_prefix { false }; + + NonnullRefPtr<KeyboardDevice> const m_keyboard_device; }; } diff --git a/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.cpp b/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.cpp index a00f33948c..a646dfda36 100644 --- a/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.cpp +++ b/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.cpp @@ -17,10 +17,10 @@ namespace Kernel { #define PS2MOUSE_INTELLIMOUSE_ID 0x03 #define PS2MOUSE_INTELLIMOUSE_EXPLORER_ID 0x04 -UNMAP_AFTER_INIT PS2MouseDevice::PS2MouseDevice(I8042Controller const& ps2_controller) +UNMAP_AFTER_INIT PS2MouseDevice::PS2MouseDevice(I8042Controller const& ps2_controller, MouseDevice const& mouse_device) : IRQHandler(IRQ_MOUSE) - , MouseDevice() - , I8042Device(ps2_controller) + , PS2Device(ps2_controller) + , m_mouse_device(mouse_device) { } @@ -35,21 +35,14 @@ bool PS2MouseDevice::handle_irq(RegisterState const&) void PS2MouseDevice::irq_handle_byte_read(u8 byte) { - auto commit_packet = [&] { + auto commit_packet = [this]() { m_data_state = 0; dbgln_if(PS2MOUSE_DEBUG, "PS2Mouse: {}, {} {} {}", m_data.bytes[1], m_data.bytes[2], (m_data.bytes[0] & 1) ? "Left" : "", (m_data.bytes[0] & 2) ? "Right" : ""); - - m_entropy_source.add_random_event(m_data.dword); - - { - SpinlockLocker lock(m_queue_lock); - m_queue.enqueue(parse_data_packet(m_data)); - } - evaluate_block_conditions(); + m_mouse_device->handle_mouse_packet_input_event(parse_data_packet(m_data)); }; VERIFY(m_data_state < sizeof(m_data.bytes) / sizeof(m_data.bytes[0])); @@ -59,25 +52,26 @@ void PS2MouseDevice::irq_handle_byte_read(u8 byte) case 0: if (!(byte & 0x08)) { dbgln("PS2Mouse: Stream out of sync."); - break; + return; } ++m_data_state; - break; + return; case 1: ++m_data_state; - break; + return; case 2: if (m_has_wheel) { ++m_data_state; - break; + return; } commit_packet(); - break; + return; case 3: VERIFY(m_has_wheel); commit_packet(); - break; + return; } + VERIFY_NOT_REACHED(); } MousePacket PS2MouseDevice::parse_data_packet(RawPacket const& raw_packet) @@ -173,11 +167,11 @@ ErrorOr<void> PS2MouseDevice::set_sample_rate(u8 rate) return {}; } -UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<PS2MouseDevice>> PS2MouseDevice::try_to_initialize(I8042Controller const& ps2_controller) +UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<PS2MouseDevice>> PS2MouseDevice::try_to_initialize(I8042Controller const& ps2_controller, MouseDevice const& mouse_device) { - auto mouse_device = TRY(DeviceManagement::try_create_device<PS2MouseDevice>(ps2_controller)); - TRY(mouse_device->initialize()); - return mouse_device; + auto device = TRY(adopt_nonnull_own_or_enomem(new (nothrow) PS2MouseDevice(ps2_controller, mouse_device))); + TRY(device->initialize()); + return device; } UNMAP_AFTER_INIT ErrorOr<void> PS2MouseDevice::initialize() diff --git a/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.h b/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.h index 177097f5f3..c77830bd60 100644 --- a/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.h +++ b/Kernel/Arch/x86_64/ISABus/HID/PS2MouseDevice.h @@ -9,33 +9,32 @@ #include <AK/CircularQueue.h> #include <Kernel/API/MousePacket.h> #include <Kernel/Arch/x86_64/ISABus/I8042Controller.h> -#include <Kernel/Devices/HID/MouseDevice.h> #include <Kernel/Interrupts/IRQHandler.h> #include <Kernel/Random.h> namespace Kernel { class PS2MouseDevice : public IRQHandler - , public MouseDevice - , public I8042Device { + , public PS2Device { friend class DeviceManagement; public: - static ErrorOr<NonnullLockRefPtr<PS2MouseDevice>> try_to_initialize(I8042Controller const&); + static ErrorOr<NonnullOwnPtr<PS2MouseDevice>> try_to_initialize(I8042Controller const&, MouseDevice const&); ErrorOr<void> initialize(); virtual ~PS2MouseDevice() override; - virtual StringView purpose() const override { return class_name(); } + virtual StringView purpose() const override { return "PS2MouseDevice"sv; } - // ^I8042Device + // ^PS2Device virtual void irq_handle_byte_read(u8 byte) override; virtual void enable_interrupts() override { enable_irq(); } + virtual Type instrument_type() const override { return Type::Mouse; } protected: - explicit PS2MouseDevice(I8042Controller const&); + PS2MouseDevice(I8042Controller const&, MouseDevice const&); // ^IRQHandler virtual bool handle_irq(RegisterState const&) override; @@ -58,6 +57,8 @@ protected: RawPacket m_data; bool m_has_wheel { false }; bool m_has_five_buttons { false }; + + NonnullRefPtr<MouseDevice> const m_mouse_device; }; } diff --git a/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.cpp b/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.cpp index ec6029b5b0..7bc88266c0 100644 --- a/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.cpp +++ b/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.cpp @@ -11,16 +11,16 @@ namespace Kernel { -UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<VMWareMouseDevice>> VMWareMouseDevice::try_to_initialize(I8042Controller const& ps2_controller) +UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<VMWareMouseDevice>> VMWareMouseDevice::try_to_initialize(I8042Controller const& ps2_controller, MouseDevice const& mouse_device) { // FIXME: return the correct error if (!VMWareBackdoor::the()) return Error::from_errno(EIO); if (!VMWareBackdoor::the()->vmmouse_is_absolute()) return Error::from_errno(EIO); - auto mouse_device = TRY(DeviceManagement::try_create_device<VMWareMouseDevice>(ps2_controller)); - TRY(mouse_device->initialize()); - return mouse_device; + auto device = TRY(adopt_nonnull_own_or_enomem(new (nothrow) VMWareMouseDevice(ps2_controller, mouse_device))); + TRY(device->initialize()); + return device; } void VMWareMouseDevice::irq_handle_byte_read(u8) @@ -42,17 +42,12 @@ void VMWareMouseDevice::irq_handle_byte_read(u8) VERIFY(number_of_mouse_event_bytes % 4 == 0); auto mouse_packet = backdoor->receive_mouse_packet(); - m_entropy_source.add_random_event(mouse_packet); - { - SpinlockLocker lock(m_queue_lock); - m_queue.enqueue(mouse_packet); - } + m_mouse_device->handle_mouse_packet_input_event(mouse_packet); } - evaluate_block_conditions(); } -VMWareMouseDevice::VMWareMouseDevice(I8042Controller const& ps2_controller) - : PS2MouseDevice(ps2_controller) +VMWareMouseDevice::VMWareMouseDevice(I8042Controller const& ps2_controller, MouseDevice const& mouse_device) + : PS2MouseDevice(ps2_controller, mouse_device) { } VMWareMouseDevice::~VMWareMouseDevice() = default; diff --git a/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.h b/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.h index b0d753cc78..34104b447b 100644 --- a/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.h +++ b/Kernel/Arch/x86_64/ISABus/HID/VMWareMouseDevice.h @@ -18,14 +18,14 @@ namespace Kernel { class VMWareMouseDevice final : public PS2MouseDevice { public: friend class DeviceManagement; - static ErrorOr<NonnullLockRefPtr<VMWareMouseDevice>> try_to_initialize(I8042Controller const&); + static ErrorOr<NonnullOwnPtr<VMWareMouseDevice>> try_to_initialize(I8042Controller const&, MouseDevice const&); virtual ~VMWareMouseDevice() override; - // ^I8042Device + // ^PS2Device virtual void irq_handle_byte_read(u8 byte) override; private: - explicit VMWareMouseDevice(I8042Controller const&); + VMWareMouseDevice(I8042Controller const&, MouseDevice const&); }; } |