mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:32:44 +00:00 
			
		
		
		
	Kernel: Move x86-specific HID code to the Arch/x86 directory
The i8042 controller with its attached devices, the PS2 keyboard and mouse, rely on x86-specific IO instructions to work. Therefore, move them to the Arch/x86 directory to make it easier to omit the handling code of these devices.
This commit is contained in:
		
							parent
							
								
									948be9674a
								
							
						
					
					
						commit
						c50a81e93e
					
				
					 11 changed files with 23 additions and 16 deletions
				
			
		
							
								
								
									
										116
									
								
								Kernel/Arch/x86/ISABus/HID/PS2KeyboardDevice.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								Kernel/Arch/x86/ISABus/HID/PS2KeyboardDevice.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,116 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | ||||
|  * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #include <AK/Types.h> | ||||
| #include <Kernel/Arch/x86/ISABus/HID/PS2KeyboardDevice.h> | ||||
| #include <Kernel/Debug.h> | ||||
| #include <Kernel/Devices/DeviceManagement.h> | ||||
| #include <Kernel/Devices/HID/HIDManagement.h> | ||||
| #include <Kernel/Scheduler.h> | ||||
| #include <Kernel/Sections.h> | ||||
| #include <Kernel/TTY/ConsoleManagement.h> | ||||
| #include <Kernel/WorkQueue.h> | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| #define IRQ_KEYBOARD 1 | ||||
| 
 | ||||
| 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)); | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
| } | ||||
| 
 | ||||
| UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<PS2KeyboardDevice>> PS2KeyboardDevice::try_to_initialize(I8042Controller const& ps2_controller) | ||||
| { | ||||
|     auto keyboard_device = TRY(DeviceManagement::try_create_device<PS2KeyboardDevice>(ps2_controller)); | ||||
| 
 | ||||
|     TRY(keyboard_device->initialize()); | ||||
| 
 | ||||
|     return keyboard_device; | ||||
| } | ||||
| 
 | ||||
| UNMAP_AFTER_INIT ErrorOr<void> PS2KeyboardDevice::initialize() | ||||
| { | ||||
|     return m_i8042_controller->reset_device(HIDDevice::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) | ||||
|     : IRQHandler(IRQ_KEYBOARD) | ||||
|     , KeyboardDevice() | ||||
|     , I8042Device(ps2_controller) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| // FIXME: UNMAP_AFTER_INIT might not be correct, because in practice PS/2 devices
 | ||||
| // are hot pluggable.
 | ||||
| UNMAP_AFTER_INIT PS2KeyboardDevice::~PS2KeyboardDevice() = default; | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Liav A
						Liav A