summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConrad Pankoff <deoxxa@fknsrs.biz>2019-08-12 20:49:17 +1000
committerAndreas Kling <awesomekling@gmail.com>2019-08-12 12:51:52 +0200
commite60577aab61bcf1a159094e8e9148d4ea1b503de (patch)
tree56afbc9335130d00d353091730a1219006e317bb
parent8faeead7536321d4b7625615585e74db48108dd0 (diff)
downloadserenity-e60577aab61bcf1a159094e8e9148d4ea1b503de.zip
Kernel: Allow boot without mouse attached by checking for presence
-rw-r--r--Kernel/Devices/PS2MouseDevice.cpp62
-rw-r--r--Kernel/Devices/PS2MouseDevice.h3
2 files changed, 53 insertions, 12 deletions
diff --git a/Kernel/Devices/PS2MouseDevice.cpp b/Kernel/Devices/PS2MouseDevice.cpp
index 26a2083280..2fa2822df0 100644
--- a/Kernel/Devices/PS2MouseDevice.cpp
+++ b/Kernel/Devices/PS2MouseDevice.cpp
@@ -10,8 +10,16 @@
#define I8042_MOUSE_BUFFER 0x20
#define I8042_KEYBOARD_BUFFER 0x00
+#define PS2MOUSE_SET_RESOLUTION 0xE8
+#define PS2MOUSE_STATUS_REQUEST 0xE9
+#define PS2MOUSE_REQUEST_SINGLE_PACKET 0xEB
#define PS2MOUSE_GET_DEVICE_ID 0xF2
#define PS2MOUSE_SET_SAMPLE_RATE 0xF3
+#define PS2MOUSE_ENABLE_PACKET_STREAMING 0xF4
+#define PS2MOUSE_DISABLE_PACKET_STREAMING 0xF5
+#define PS2MOUSE_SET_DEFAULTS 0xF6
+#define PS2MOUSE_RESEND 0xFE
+#define PS2MOUSE_RESET 0xFF
#define PS2MOUSE_INTELLIMOUSE_ID 0x03
@@ -128,23 +136,53 @@ u8 PS2MouseDevice::wait_then_read(u8 port)
void PS2MouseDevice::initialize()
{
// Enable PS aux port
- wait_then_write(0x64, 0xa8);
+ wait_then_write(I8042_STATUS, 0xa8);
+
+ check_device_presence();
+
+ if (m_device_present)
+ initialize_device();
+}
+
+void PS2MouseDevice::check_device_presence()
+{
+ mouse_write(PS2MOUSE_REQUEST_SINGLE_PACKET);
+ u8 maybe_ack = mouse_read();
+ if (maybe_ack == I8042_ACK) {
+ m_device_present = true;
+ kprintf("PS2MouseDevice: Device detected\n");
+
+ // the mouse will send a packet of data, since that's what we asked
+ // for. we don't care about the content.
+ mouse_read();
+ mouse_read();
+ mouse_read();
+ } else {
+ m_device_present = false;
+ kprintf("PS2MouseDevice: Device not detected\n");
+ }
+}
+
+void PS2MouseDevice::initialize_device()
+{
+ if (!m_device_present)
+ return;
// Enable interrupts
- wait_then_write(0x64, 0x20);
+ wait_then_write(I8042_STATUS, 0x20);
// Enable the PS/2 mouse IRQ (12).
// NOTE: The keyboard uses IRQ 1 (and is enabled by bit 0 in this register).
- u8 status = wait_then_read(0x60) | 2;
- wait_then_write(0x64, 0x60);
- wait_then_write(0x60, status);
+ u8 status = wait_then_read(I8042_BUFFER) | 2;
+ wait_then_write(I8042_STATUS, 0x60);
+ wait_then_write(I8042_BUFFER, status);
// Set default settings.
- mouse_write(0xf6);
+ mouse_write(PS2MOUSE_SET_DEFAULTS);
expect_ack();
// Enable.
- mouse_write(0xf4);
+ mouse_write(PS2MOUSE_ENABLE_PACKET_STREAMING);
expect_ack();
mouse_write(PS2MOUSE_GET_DEVICE_ID);
@@ -190,7 +228,7 @@ void PS2MouseDevice::expect_ack()
void PS2MouseDevice::prepare_for_input()
{
for (;;) {
- if (IO::in8(0x64) & 1)
+ if (IO::in8(I8042_STATUS) & 1)
return;
}
}
@@ -198,7 +236,7 @@ void PS2MouseDevice::prepare_for_input()
void PS2MouseDevice::prepare_for_output()
{
for (;;) {
- if (!(IO::in8(0x64) & 2))
+ if (!(IO::in8(I8042_STATUS) & 2))
return;
}
}
@@ -206,15 +244,15 @@ void PS2MouseDevice::prepare_for_output()
void PS2MouseDevice::mouse_write(u8 data)
{
prepare_for_output();
- IO::out8(0x64, 0xd4);
+ IO::out8(I8042_STATUS, 0xd4);
prepare_for_output();
- IO::out8(0x60, data);
+ IO::out8(I8042_BUFFER, data);
}
u8 PS2MouseDevice::mouse_read()
{
prepare_for_input();
- return IO::in8(0x60);
+ return IO::in8(I8042_BUFFER);
}
bool PS2MouseDevice::can_read(FileDescription&) const
diff --git a/Kernel/Devices/PS2MouseDevice.h b/Kernel/Devices/PS2MouseDevice.h
index 1a91f556a9..c16cb6eb67 100644
--- a/Kernel/Devices/PS2MouseDevice.h
+++ b/Kernel/Devices/PS2MouseDevice.h
@@ -27,6 +27,8 @@ private:
virtual const char* class_name() const override { return "PS2MouseDevice"; }
void initialize();
+ void check_device_presence();
+ void initialize_device();
void prepare_for_input();
void prepare_for_output();
void mouse_write(u8);
@@ -36,6 +38,7 @@ private:
void parse_data_packet();
void expect_ack();
+ bool m_device_present { false };
CircularQueue<MousePacket, 100> m_queue;
u8 m_data_state { 0 };
u8 m_data[4];