forked from Bananymous/banan-os
Kernel: Move PS2Device to its own file
This commit is contained in:
parent
8f8d6bddc0
commit
891ced4da2
|
@ -33,6 +33,7 @@ set(KERNEL_SOURCES
|
||||||
kernel/FS/TmpFS/Inode.cpp
|
kernel/FS/TmpFS/Inode.cpp
|
||||||
kernel/FS/VirtualFileSystem.cpp
|
kernel/FS/VirtualFileSystem.cpp
|
||||||
kernel/Input/PS2Controller.cpp
|
kernel/Input/PS2Controller.cpp
|
||||||
|
kernel/Input/PS2Device.cpp
|
||||||
kernel/Input/PS2Keyboard.cpp
|
kernel/Input/PS2Keyboard.cpp
|
||||||
kernel/Input/PS2Keymap.cpp
|
kernel/Input/PS2Keymap.cpp
|
||||||
kernel/InterruptController.cpp
|
kernel/InterruptController.cpp
|
||||||
|
|
|
@ -7,42 +7,7 @@
|
||||||
namespace Kernel::Input
|
namespace Kernel::Input
|
||||||
{
|
{
|
||||||
|
|
||||||
class PS2Controller;
|
class PS2Device;
|
||||||
|
|
||||||
class PS2Device : public CharacterDevice, public Interruptable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PS2Device(PS2Controller&);
|
|
||||||
virtual ~PS2Device() {}
|
|
||||||
|
|
||||||
virtual void send_initialize() = 0;
|
|
||||||
|
|
||||||
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 override { return m_name; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void update();
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class State
|
|
||||||
{
|
|
||||||
Normal,
|
|
||||||
WaitingAck,
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
const BAN::String m_name;
|
|
||||||
|
|
||||||
PS2Controller& m_controller;
|
|
||||||
State m_state = State::Normal;
|
|
||||||
BAN::CircularQueue<uint8_t, 10> m_command_queue;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PS2Controller
|
class PS2Controller
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include <kernel/Input/PS2Controller.h>
|
||||||
|
|
||||||
|
namespace Kernel::Input
|
||||||
|
{
|
||||||
|
|
||||||
|
class PS2Device : public CharacterDevice, public Interruptable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PS2Device(PS2Controller&);
|
||||||
|
virtual ~PS2Device() {}
|
||||||
|
|
||||||
|
virtual void send_initialize() = 0;
|
||||||
|
|
||||||
|
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; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class State
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
WaitingAck,
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
const BAN::String m_name;
|
||||||
|
const dev_t m_rdev;
|
||||||
|
|
||||||
|
PS2Controller& m_controller;
|
||||||
|
State m_state = State::Normal;
|
||||||
|
BAN::CircularQueue<uint8_t, 10> m_command_queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/Input/KeyEvent.h>
|
#include <kernel/Input/KeyEvent.h>
|
||||||
#include <kernel/Input/PS2Controller.h>
|
#include <kernel/Input/PS2Device.h>
|
||||||
#include <kernel/Input/PS2Keymap.h>
|
#include <kernel/Input/PS2Keymap.h>
|
||||||
#include <kernel/Semaphore.h>
|
#include <kernel/Semaphore.h>
|
||||||
|
|
||||||
|
@ -41,15 +41,9 @@ namespace Kernel::Input
|
||||||
|
|
||||||
Semaphore m_semaphore;
|
Semaphore m_semaphore;
|
||||||
|
|
||||||
public:
|
|
||||||
virtual dev_t rdev() const override { return m_rdev; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
||||||
virtual bool has_data_impl() const override;
|
virtual bool has_data_impl() const override;
|
||||||
|
|
||||||
private:
|
|
||||||
const dev_t m_rdev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -248,72 +248,4 @@ namespace Kernel::Input
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
PS2Device::PS2Device(PS2Controller& controller)
|
|
||||||
: CharacterDevice(0440, 0, 901)
|
|
||||||
, m_name(BAN::String::formatted("input{}", DevFileSystem::get().get_next_input_device()))
|
|
||||||
, m_controller(controller)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool PS2Device::append_command_queue(uint8_t command)
|
|
||||||
{
|
|
||||||
if (m_command_queue.size() + 1 >= m_command_queue.capacity())
|
|
||||||
return false;
|
|
||||||
m_command_queue.push(command);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PS2Device::append_command_queue(uint8_t command, uint8_t data)
|
|
||||||
{
|
|
||||||
if (m_command_queue.size() + 2 >= m_command_queue.capacity())
|
|
||||||
return false;
|
|
||||||
m_command_queue.push(command);
|
|
||||||
m_command_queue.push(data);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS2Device::handle_irq()
|
|
||||||
{
|
|
||||||
uint8_t byte = IO::inb(PS2::IOPort::DATA);
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
#include <kernel/FS/DevFS/FileSystem.h>
|
||||||
|
#include <kernel/Input/PS2Config.h>
|
||||||
|
#include <kernel/Input/PS2Device.h>
|
||||||
|
#include <kernel/IO.h>
|
||||||
|
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
|
namespace Kernel::Input
|
||||||
|
{
|
||||||
|
|
||||||
|
PS2Device::PS2Device(PS2Controller& controller)
|
||||||
|
: CharacterDevice(0440, 0, 901)
|
||||||
|
, m_name(BAN::String::formatted("input{}", DevFileSystem::get().get_next_input_device()))
|
||||||
|
, m_rdev(makedev(DevFileSystem::get().get_next_dev(), 0))
|
||||||
|
, m_controller(controller)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool PS2Device::append_command_queue(uint8_t command)
|
||||||
|
{
|
||||||
|
if (m_command_queue.size() + 1 >= m_command_queue.capacity())
|
||||||
|
return false;
|
||||||
|
m_command_queue.push(command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PS2Device::append_command_queue(uint8_t command, uint8_t data)
|
||||||
|
{
|
||||||
|
if (m_command_queue.size() + 2 >= m_command_queue.capacity())
|
||||||
|
return false;
|
||||||
|
m_command_queue.push(command);
|
||||||
|
m_command_queue.push(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS2Device::handle_irq()
|
||||||
|
{
|
||||||
|
uint8_t byte = IO::inb(PS2::IOPort::DATA);
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,11 +3,8 @@
|
||||||
#include <kernel/FS/DevFS/FileSystem.h>
|
#include <kernel/FS/DevFS/FileSystem.h>
|
||||||
#include <kernel/Input/PS2Config.h>
|
#include <kernel/Input/PS2Config.h>
|
||||||
#include <kernel/Input/PS2Keyboard.h>
|
#include <kernel/Input/PS2Keyboard.h>
|
||||||
#include <kernel/IO.h>
|
|
||||||
#include <kernel/Timer/Timer.h>
|
#include <kernel/Timer/Timer.h>
|
||||||
|
|
||||||
#include <sys/sysmacros.h>
|
|
||||||
|
|
||||||
#define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask)))
|
#define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask)))
|
||||||
#define TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
|
#define TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
|
||||||
|
|
||||||
|
@ -24,7 +21,6 @@ namespace Kernel::Input
|
||||||
|
|
||||||
PS2Keyboard::PS2Keyboard(PS2Controller& controller)
|
PS2Keyboard::PS2Keyboard(PS2Controller& controller)
|
||||||
: PS2Device(controller)
|
: PS2Device(controller)
|
||||||
, m_rdev(makedev(DevFileSystem::get().get_next_dev(), 0))
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void PS2Keyboard::send_initialize()
|
void PS2Keyboard::send_initialize()
|
||||||
|
|
Loading…
Reference in New Issue