diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-11 02:28:53 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-11 02:28:53 +0100 |
commit | e740f1195a2f0525296626862b2f7b66a6b5348e (patch) | |
tree | 92204a0db95610b49b3a6c071e59d0dcfaae263a | |
parent | d1ceb4b6038c1047988977f93f1ab5510dcf3d70 (diff) | |
download | serenity-e740f1195a2f0525296626862b2f7b66a6b5348e.zip |
Add a simple PS/2 mouse device.
It's not hooked up to anything just yet, but it does read movement deltas.
-rw-r--r-- | Kernel/Makefile | 1 | ||||
-rw-r--r-- | Kernel/PS2MouseDevice.cpp | 113 | ||||
-rw-r--r-- | Kernel/PS2MouseDevice.h | 28 | ||||
-rw-r--r-- | Kernel/init.cpp | 5 |
4 files changed, 146 insertions, 1 deletions
diff --git a/Kernel/Makefile b/Kernel/Makefile index 813ce41d7b..96aaac4d16 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -25,6 +25,7 @@ KERNEL_OBJS = \ ELFImage.o \ ELFLoader.o \ KSyms.o \ + PS2MouseDevice.o \ WindowComposer.o VFS_OBJS = \ diff --git a/Kernel/PS2MouseDevice.cpp b/Kernel/PS2MouseDevice.cpp new file mode 100644 index 0000000000..c829c60539 --- /dev/null +++ b/Kernel/PS2MouseDevice.cpp @@ -0,0 +1,113 @@ +#include "PS2MouseDevice.h" +#include "IO.h" + +PS2MouseDevice::PS2MouseDevice() + : IRQHandler(12) + , CharacterDevice(10, 1) +{ + initialize(); +} + +PS2MouseDevice::~PS2MouseDevice() +{ +} + +void PS2MouseDevice::handle_irq() +{ + m_data[m_data_state] = IO::in8(0x60); + switch (m_data_state) { + case 0: + case 1: + ++m_data_state; + break; + case 2: + m_data_state = 0; + dbgprintf("PS2Mouse: %d, %d\n", m_data[1], m_data[2]); + break; + } +} + +void PS2MouseDevice::wait_then_write(byte port, byte data) +{ + prepare_for_output(); + IO::out8(port, data); +} + +byte PS2MouseDevice::wait_then_read(byte port) +{ + prepare_for_input(); + return IO::in8(port); +} + +void PS2MouseDevice::initialize() +{ + // Enable PS aux port + wait_then_write(0x64, 0xa8); + + // Enable interrupts + wait_then_write(0x64, 0x20); + + byte status = wait_then_read(0x60) | 2; + wait_then_write(0x64, 0x60); + wait_then_write(0x60, status); + + // Set default settings. + mouse_write(0xf6); + byte ack1 = mouse_read(); + ASSERT(ack1 == 0xfa); + + // Enable. + mouse_write(0xf4); + byte ack2 = mouse_read(); + ASSERT(ack2 == 0xfa); + + enable_irq(); +} + +void PS2MouseDevice::prepare_for_input() +{ + for (;;) { + if (IO::in8(0x64) & 1) + return; + } +} + +void PS2MouseDevice::prepare_for_output() +{ + for (;;) { + if (!(IO::in8(0x64) & 2)) + return; + } +} + +void PS2MouseDevice::mouse_write(byte data) +{ + prepare_for_output(); + IO::out8(0x64, 0xd4); + prepare_for_output(); + IO::out8(0x60, data); +} + +byte PS2MouseDevice::mouse_read() +{ + prepare_for_input(); + return IO::in8(0x60); +} + +bool PS2MouseDevice::has_data_available_for_reading() const +{ + ASSERT_NOT_REACHED(); + return false; +} + +ssize_t PS2MouseDevice::read(byte* buffer, size_t buffer_size) +{ + ASSERT_NOT_REACHED(); + return 0; +} + +ssize_t PS2MouseDevice::write(const byte *buffer, size_t buffer_size) +{ + ASSERT_NOT_REACHED(); + return 0; +} diff --git a/Kernel/PS2MouseDevice.h b/Kernel/PS2MouseDevice.h new file mode 100644 index 0000000000..d7587949d4 --- /dev/null +++ b/Kernel/PS2MouseDevice.h @@ -0,0 +1,28 @@ +#pragma once + +#include <VirtualFileSystem/CharacterDevice.h> +#include "IRQHandler.h" + +class PS2MouseDevice final : public IRQHandler, public CharacterDevice { +public: + PS2MouseDevice(); + virtual ~PS2MouseDevice() override; + +private: + virtual bool has_data_available_for_reading() const override; + virtual ssize_t read(byte* buffer, size_t buffer_size) override; + virtual ssize_t write(const byte* buffer, size_t buffer_size) override; + + virtual void handle_irq() override; + + void initialize(); + void prepare_for_input(); + void prepare_for_output(); + void mouse_write(byte); + byte mouse_read(); + void wait_then_write(byte port, byte data); + byte wait_then_read(byte port); + + byte m_data_state { 0 }; + signed_byte m_data[3]; +}; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 3b6074d21a..76d36780c2 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -20,6 +20,7 @@ #include "RTC.h" #include "VirtualConsole.h" #include "Scheduler.h" +#include "PS2MouseDevice.h" #define SPAWN_MULTIPLE_SHELLS //#define STRESS_TEST_SPAWNING @@ -31,6 +32,7 @@ VirtualConsole* tty1; VirtualConsole* tty2; VirtualConsole* tty3; Keyboard* keyboard; +PS2MouseDevice* ps2mouse; #ifdef STRESS_TEST_SPAWNING static void spawn_stress() NORETURN; @@ -71,7 +73,7 @@ static void init_stage2() vfs->register_character_device(*dev_random); vfs->register_character_device(*keyboard); - + vfs->register_character_device(*ps2mouse); vfs->register_character_device(*tty0); vfs->register_character_device(*tty1); vfs->register_character_device(*tty2); @@ -125,6 +127,7 @@ void init() idt_init(); keyboard = new Keyboard; + ps2mouse = new PS2MouseDevice; VirtualConsole::initialize(); tty0 = new VirtualConsole(0, VirtualConsole::AdoptCurrentVGABuffer); |