feature (PS/2): finished up initialization process
This commit is contained in:
parent
c5cbf51e75
commit
fb66944b0e
|
@ -9,13 +9,15 @@
|
|||
#define PS2_CONTROLLER_STATUS_PORT 0x64
|
||||
#define PS2_CONTROLLER_COMMAND_PORT 0x64
|
||||
|
||||
#define PS2_CONTROLLER_TIMEOUT 0xFFFFFF
|
||||
#define PS2_CONTROLLER_TIMEOUT 0xFFFFF
|
||||
|
||||
void ps2_controller_init ();
|
||||
uint8_t ps2_controller_command (uint8_t command);
|
||||
uint8_t ps2_controller_command_with_data (uint8_t command, uint8_t data);
|
||||
bool ps2_controller_command_has_response (uint8_t command);
|
||||
bool ps2_controller_wait_until_ready_for_input ();
|
||||
bool ps2_controller_wait_until_ready_for_output ();
|
||||
uint8_t ps2_controller_read_data ();
|
||||
void ps2_controller_write_data (uint8_t data);
|
||||
|
||||
#endif //NOX_CONTROLLER_H
|
||||
|
|
|
@ -31,7 +31,7 @@ typedef enum {
|
|||
PS2_KEYBOARD_RESPONSE_KEY_DETECTION_ERROR_2 = 0xFF
|
||||
} ps2_keyboard_response_E;
|
||||
|
||||
uint8_t ps2_keyboard_command (ps2_keyboard_command_E command, uint8_t data);
|
||||
uint8_t ps2_keyboard_command (ps2_keyboard_command_E command);
|
||||
void ps2_keyboard_init ();
|
||||
void ps2_keyboard_read ();
|
||||
string_t ps2_keyboard_command_to_string (ps2_keyboard_command_E command);
|
||||
|
|
|
@ -44,15 +44,15 @@ void kernel_init(boot_info_T* boot_info) {
|
|||
|
||||
sysconfig_default_init();
|
||||
|
||||
scheduler_init(boot_info);
|
||||
|
||||
acpi_init(boot_info);
|
||||
|
||||
pci_init();
|
||||
|
||||
ps2_controller_init();
|
||||
|
||||
scheduler_init(boot_info);
|
||||
|
||||
tty_init();
|
||||
|
||||
ps2_controller_init();
|
||||
}
|
||||
|
||||
void kmain(boot_info_T boot_info) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "boot/config.h"
|
||||
|
||||
void ps2_controller_init() {
|
||||
// check if the ps/2 controller exists
|
||||
if (g_sysconfig->ps2_acpi_validation) {
|
||||
if (!(g_acpi_table_fadt->ia_boot_architecture_flags & (1 << 1))) {
|
||||
log(LOG_ERROR, "<PS2> ps2 controller initialization failed (ps2 controller not set in fadt boot flags)");
|
||||
|
@ -17,12 +18,48 @@ void ps2_controller_init() {
|
|||
log(LOG_WARNING, "<PS2> skipping ps2 controller existence acpi check (disabled by sysconfig)");
|
||||
}
|
||||
|
||||
// disable ps/2 devices
|
||||
ps2_controller_command(0xAD); // keyboard
|
||||
ps2_controller_command(0xA7); // mouse
|
||||
|
||||
// clear buffer
|
||||
while (io_in_byte(PS2_CONTROLLER_STATUS_PORT) & 0b00000001) {
|
||||
io_in_byte(PS2_CONTROLLER_DATA_PORT);
|
||||
}
|
||||
|
||||
// set the configuration byte
|
||||
uint8_t config_byte = ps2_controller_command(0x20);
|
||||
bool dual_channel = (config_byte & 0b00100000);
|
||||
config_byte &= 0b10111100;
|
||||
ps2_controller_command_with_data(0x60, config_byte);
|
||||
|
||||
// performing self test
|
||||
if (ps2_controller_command(0xAA) != 0x55) {
|
||||
log(LOG_ERROR, "<PS2> controller driver init failed (controller self test failed)");
|
||||
return;
|
||||
}
|
||||
// restore the config byte, due to a possible reset by the self test
|
||||
ps2_controller_command_with_data(0x60, config_byte);
|
||||
|
||||
// check if the controller supports 2 channels
|
||||
if (dual_channel) {
|
||||
ps2_controller_command(0xA8);
|
||||
dual_channel = !(ps2_controller_command(0x20) & 0b00100000);
|
||||
ps2_controller_command(0xA7);
|
||||
}
|
||||
|
||||
// perform interface tests
|
||||
if (ps2_controller_command(0xAB) > 0 && (!dual_channel || ps2_controller_command(0xA9) > 0)) {
|
||||
log(LOG_ERROR, "<PS2> controller driver init failed (interface tests failed)");
|
||||
}
|
||||
|
||||
// init devices
|
||||
ps2_keyboard_init();
|
||||
}
|
||||
|
||||
uint8_t ps2_controller_command(uint8_t command) {
|
||||
io_out_byte(PS2_CONTROLLER_COMMAND_PORT, command);
|
||||
if (!ps2_controller_wait_until_ready_for_output()) {
|
||||
if (ps2_controller_command_has_response(command) && !ps2_controller_wait_until_ready_for_output()) {
|
||||
return 0;
|
||||
}
|
||||
return io_in_byte(PS2_CONTROLLER_DATA_PORT);
|
||||
|
@ -34,12 +71,21 @@ uint8_t ps2_controller_command_with_data(uint8_t command, uint8_t data) {
|
|||
return 0;
|
||||
}
|
||||
io_out_byte(PS2_CONTROLLER_DATA_PORT, data);
|
||||
if (!ps2_controller_wait_until_ready_for_output()) {
|
||||
if (ps2_controller_command_has_response(command) && !ps2_controller_wait_until_ready_for_output()) {
|
||||
return 0;
|
||||
}
|
||||
return io_in_byte(PS2_CONTROLLER_DATA_PORT);
|
||||
}
|
||||
|
||||
bool ps2_controller_command_has_response(uint8_t command) {
|
||||
if (command >= 0x20 && command <= 0x3F) return true;
|
||||
if (command >= 0xA9 && command <= 0xAC) return true;
|
||||
if (command == 0xC0) return true;
|
||||
if (command == 0xD0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ps2_controller_wait_until_ready_for_input() {
|
||||
uint32_t timeout = 0;
|
||||
while (io_in_byte(PS2_CONTROLLER_STATUS_PORT) & 0b00000010) {
|
||||
|
@ -54,7 +100,6 @@ bool ps2_controller_wait_until_ready_for_input() {
|
|||
|
||||
bool ps2_controller_wait_until_ready_for_output() {
|
||||
uint32_t timeout = 0;
|
||||
log(LOG_DEBUG, "status register: 0b%.8b", io_in_byte(PS2_CONTROLLER_STATUS_PORT));
|
||||
while (!(io_in_byte(PS2_CONTROLLER_STATUS_PORT) & 0b00000001)) {
|
||||
if (timeout > PS2_CONTROLLER_TIMEOUT) {
|
||||
log(LOG_WARNING, "<PS2 Controller> Controller not ready for output (timeout)");
|
||||
|
@ -68,3 +113,7 @@ bool ps2_controller_wait_until_ready_for_output() {
|
|||
uint8_t ps2_controller_read_data() {
|
||||
return io_in_byte(PS2_CONTROLLER_DATA_PORT);
|
||||
}
|
||||
|
||||
void ps2_controller_write_data(uint8_t data) {
|
||||
io_out_byte(PS2_CONTROLLER_DATA_PORT, data);
|
||||
}
|
||||
|
|
|
@ -12,13 +12,24 @@ char scancode_set_1[] = " 1234567890-= qwertyuiop[] asdfghjkl;'` \\zxcvbnm,./
|
|||
bool shift_enabled = false;
|
||||
bool extended_key = false;
|
||||
|
||||
uint8_t ps2_keyboard_command(ps2_keyboard_command_E command, uint8_t data) {
|
||||
uint8_t ps2_keyboard_command(ps2_keyboard_command_E command) {
|
||||
uint8_t response = PS2_KEYBOARD_RESPONSE_RESEND;
|
||||
uint8_t tries = 0;
|
||||
|
||||
while (response == PS2_KEYBOARD_RESPONSE_RESEND) {
|
||||
response = ps2_controller_command(command);
|
||||
log(LOG_DEBUG, "<PS2> '%s' + 0x%xb -> 0x%xb", ps2_keyboard_command_to_string(command), data, response);
|
||||
if (!ps2_controller_wait_until_ready_for_input()) {
|
||||
return 0;
|
||||
}
|
||||
ps2_controller_write_data(command);
|
||||
if (!ps2_controller_wait_until_ready_for_output()) {
|
||||
return 0;
|
||||
}
|
||||
while (io_in_byte(PS2_CONTROLLER_STATUS_PORT) & 0b00000001) {
|
||||
response = ps2_controller_read_data();
|
||||
}
|
||||
|
||||
|
||||
log(LOG_DEBUG, "<PS2> '%s' -> 0x%xb", ps2_keyboard_command_to_string(command), response);
|
||||
tries++;
|
||||
|
||||
if (tries >= 3) {
|
||||
|
@ -32,10 +43,20 @@ uint8_t ps2_keyboard_command(ps2_keyboard_command_E command, uint8_t data) {
|
|||
|
||||
void ps2_keyboard_init() {
|
||||
|
||||
// uint8_t data = ps2_keyboard_command(PS2_KEYBOARD_COMMAND_ECHO, 0);
|
||||
// log(LOG_DEBUG, "response: 0x%xb", data);
|
||||
// re-enable the ps/2 keyboard
|
||||
ps2_controller_command(0xAE);
|
||||
|
||||
io_in_byte(PS2_CONTROLLER_DATA_PORT);
|
||||
// reset the keyboard
|
||||
ps2_keyboard_command(PS2_KEYBOARD_COMMAND_SELF_TEST);
|
||||
|
||||
// set scancode set to 1
|
||||
ps2_keyboard_command(PS2_KEYBOARD_COMMAND_SET_SCANCODE_SET);
|
||||
ps2_keyboard_command(1);
|
||||
|
||||
// enable keyboard interrupt on ps/2 controller
|
||||
uint8_t config_byte = ps2_controller_command(0x20);
|
||||
config_byte |= 0b00000001;
|
||||
ps2_controller_command_with_data(0x60, config_byte);
|
||||
|
||||
pic_unmask_irq(IRQ_KEYBOARD);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue