mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-28 13:43:45 +03:00
Kernel: Allow boot without mouse attached by checking for presence
This commit is contained in:
parent
8faeead753
commit
e60577aab6
Notes:
sideshowbarker
2024-07-19 12:43:27 +09:00
Author: https://github.com/deoxxa Commit: https://github.com/SerenityOS/serenity/commit/e60577aab61 Pull-request: https://github.com/SerenityOS/serenity/pull/443
@ -10,8 +10,16 @@
|
|||||||
#define I8042_MOUSE_BUFFER 0x20
|
#define I8042_MOUSE_BUFFER 0x20
|
||||||
#define I8042_KEYBOARD_BUFFER 0x00
|
#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_GET_DEVICE_ID 0xF2
|
||||||
#define PS2MOUSE_SET_SAMPLE_RATE 0xF3
|
#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
|
#define PS2MOUSE_INTELLIMOUSE_ID 0x03
|
||||||
|
|
||||||
@ -128,23 +136,53 @@ u8 PS2MouseDevice::wait_then_read(u8 port)
|
|||||||
void PS2MouseDevice::initialize()
|
void PS2MouseDevice::initialize()
|
||||||
{
|
{
|
||||||
// Enable PS aux port
|
// 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
|
// Enable interrupts
|
||||||
wait_then_write(0x64, 0x20);
|
wait_then_write(I8042_STATUS, 0x20);
|
||||||
|
|
||||||
// Enable the PS/2 mouse IRQ (12).
|
// Enable the PS/2 mouse IRQ (12).
|
||||||
// NOTE: The keyboard uses IRQ 1 (and is enabled by bit 0 in this register).
|
// NOTE: The keyboard uses IRQ 1 (and is enabled by bit 0 in this register).
|
||||||
u8 status = wait_then_read(0x60) | 2;
|
u8 status = wait_then_read(I8042_BUFFER) | 2;
|
||||||
wait_then_write(0x64, 0x60);
|
wait_then_write(I8042_STATUS, 0x60);
|
||||||
wait_then_write(0x60, status);
|
wait_then_write(I8042_BUFFER, status);
|
||||||
|
|
||||||
// Set default settings.
|
// Set default settings.
|
||||||
mouse_write(0xf6);
|
mouse_write(PS2MOUSE_SET_DEFAULTS);
|
||||||
expect_ack();
|
expect_ack();
|
||||||
|
|
||||||
// Enable.
|
// Enable.
|
||||||
mouse_write(0xf4);
|
mouse_write(PS2MOUSE_ENABLE_PACKET_STREAMING);
|
||||||
expect_ack();
|
expect_ack();
|
||||||
|
|
||||||
mouse_write(PS2MOUSE_GET_DEVICE_ID);
|
mouse_write(PS2MOUSE_GET_DEVICE_ID);
|
||||||
@ -190,7 +228,7 @@ void PS2MouseDevice::expect_ack()
|
|||||||
void PS2MouseDevice::prepare_for_input()
|
void PS2MouseDevice::prepare_for_input()
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (IO::in8(0x64) & 1)
|
if (IO::in8(I8042_STATUS) & 1)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +236,7 @@ void PS2MouseDevice::prepare_for_input()
|
|||||||
void PS2MouseDevice::prepare_for_output()
|
void PS2MouseDevice::prepare_for_output()
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!(IO::in8(0x64) & 2))
|
if (!(IO::in8(I8042_STATUS) & 2))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,15 +244,15 @@ void PS2MouseDevice::prepare_for_output()
|
|||||||
void PS2MouseDevice::mouse_write(u8 data)
|
void PS2MouseDevice::mouse_write(u8 data)
|
||||||
{
|
{
|
||||||
prepare_for_output();
|
prepare_for_output();
|
||||||
IO::out8(0x64, 0xd4);
|
IO::out8(I8042_STATUS, 0xd4);
|
||||||
prepare_for_output();
|
prepare_for_output();
|
||||||
IO::out8(0x60, data);
|
IO::out8(I8042_BUFFER, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 PS2MouseDevice::mouse_read()
|
u8 PS2MouseDevice::mouse_read()
|
||||||
{
|
{
|
||||||
prepare_for_input();
|
prepare_for_input();
|
||||||
return IO::in8(0x60);
|
return IO::in8(I8042_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PS2MouseDevice::can_read(FileDescription&) const
|
bool PS2MouseDevice::can_read(FileDescription&) const
|
||||||
|
@ -27,6 +27,8 @@ private:
|
|||||||
virtual const char* class_name() const override { return "PS2MouseDevice"; }
|
virtual const char* class_name() const override { return "PS2MouseDevice"; }
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
void check_device_presence();
|
||||||
|
void initialize_device();
|
||||||
void prepare_for_input();
|
void prepare_for_input();
|
||||||
void prepare_for_output();
|
void prepare_for_output();
|
||||||
void mouse_write(u8);
|
void mouse_write(u8);
|
||||||
@ -36,6 +38,7 @@ private:
|
|||||||
void parse_data_packet();
|
void parse_data_packet();
|
||||||
void expect_ack();
|
void expect_ack();
|
||||||
|
|
||||||
|
bool m_device_present { false };
|
||||||
CircularQueue<MousePacket, 100> m_queue;
|
CircularQueue<MousePacket, 100> m_queue;
|
||||||
u8 m_data_state { 0 };
|
u8 m_data_state { 0 };
|
||||||
u8 m_data[4];
|
u8 m_data[4];
|
||||||
|
Loading…
Reference in New Issue
Block a user