From 37a04b739aec60344d7997523aebadaffdde2d88 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Fri, 18 Feb 2022 23:50:39 +0000 Subject: [PATCH] Kernel: Only do i8042 existence check via probing as a fallback This caused an initialization failure of the i8042 when I tested on bare metal. We cannot entirely get rid of this method as QEMU for example doesn't indicate the existence of an i8042 via ACPI, but we can get away with only doing the manual probing if ACPI is disabled or we didn't get a 'yes' from it. Increasing the number of maximum loops did eventually lead to a successful return from the function, but would later fail the actual self test. --- Kernel/Devices/HID/HIDManagement.cpp | 14 +++++++++++--- Kernel/Devices/HID/I8042Controller.cpp | 2 +- Kernel/Devices/HID/I8042Controller.h | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Kernel/Devices/HID/HIDManagement.cpp b/Kernel/Devices/HID/HIDManagement.cpp index 873e5f8070..1d45324d0e 100644 --- a/Kernel/Devices/HID/HIDManagement.cpp +++ b/Kernel/Devices/HID/HIDManagement.cpp @@ -107,12 +107,20 @@ UNMAP_AFTER_INIT ErrorOr HIDManagement::enumerate() // set to emulate PS/2, we should not initialize the PS/2 controller. if (kernel_command_line().disable_ps2_controller()) return {}; - if (ACPI::Parser::the() && !ACPI::Parser::the()->have_8042()) - return {}; m_i8042_controller = I8042Controller::initialize(); + // Note: If ACPI is disabled or doesn't indicate that we have an i8042, we + // still perform a manual existence check via probing, which is relevant on + // QEMU, for example. This probing check is known to not work on bare metal + // in all cases, so if we can get a 'yes' from ACPI, we skip it. + auto has_i8042_controller = false; + if (ACPI::Parser::the() && ACPI::Parser::the()->have_8042()) + has_i8042_controller = true; + else if (m_i8042_controller->check_existence_via_probing({})) + has_i8042_controller = true; + // Note: If we happen to not have i8042 just return "gracefully" for now. - if (!m_i8042_controller->check_existence({})) + if (!has_i8042_controller) return {}; TRY(m_i8042_controller->detect_devices()); if (m_i8042_controller->mouse()) diff --git a/Kernel/Devices/HID/I8042Controller.cpp b/Kernel/Devices/HID/I8042Controller.cpp index a302449be0..a970d0312d 100644 --- a/Kernel/Devices/HID/I8042Controller.cpp +++ b/Kernel/Devices/HID/I8042Controller.cpp @@ -31,7 +31,7 @@ UNMAP_AFTER_INIT I8042Controller::I8042Controller() { } -UNMAP_AFTER_INIT bool I8042Controller::check_existence(Badge) +UNMAP_AFTER_INIT bool I8042Controller::check_existence_via_probing(Badge) { { SpinlockLocker lock(m_lock); diff --git a/Kernel/Devices/HID/I8042Controller.h b/Kernel/Devices/HID/I8042Controller.h index 98b85a9e85..f6d250b7b1 100644 --- a/Kernel/Devices/HID/I8042Controller.h +++ b/Kernel/Devices/HID/I8042Controller.h @@ -143,7 +143,7 @@ public: RefPtr keyboard() const; // Note: This function exists only for the initialization process of the controller - bool check_existence(Badge); + bool check_existence_via_probing(Badge); private: I8042Controller();