On initialization I disable all PS/2 ports and IRQs to PS/2 devices:
Code: Select all
int init_ps2_init() {
// todo: determine if even exists
init_make_reflock(&interrupt_lock);
init_reflock_acquire(&interrupt_lock);
init_ps2_disable();
init_ps2_flush();
...
}
Code: Select all
void init_ps2_disable_port(init_ps2_port_t port) {
...
outb(INIT_PS2_COMMAND, port == INIT_PS2_PORT_1 ? 0xAD : 0xA7);
uint8_t config_byte = init_ps2_read_config_byte();
init_ps2_write_config_byte(clear_bits(config_byte, port));
pic_mask_irq(port_status->irq);
...
}
Code: Select all
if (!pic_is_irq_masked(INIT_PS2_PORT1_IRQ)) {
pic_mask_irq(INIT_PS2_PORT1_IRQ);
}
if (!pic_is_irq_masked(INIT_PS2_PORT2_IRQ)) {
pic_mask_irq(INIT_PS2_PORT2_IRQ);
}
Code: Select all
int init_ps2_init() {
...
init_ps2_enable(false);
init_ps2_reset();
init_ps2_disable();
init_ps2_flush();
init_reflock_release(&interrupt_lock);
}
Now for the description of the problem. As it is said in the titile, it arises when a keyboard is being smashed during init phase.
Problem 1 (not critical) - Device identification sometimes fails. In QEMU I usually get 0xAB83 as keyboard signature, but upon failure it becomes 0xAB41. For mouse in normal case the signature is 0x00, and upon failure it is random.
Problem 2 (critical) - An unexpected (usually random) error value is returned *somewhere in initialization code* (I couldn't yet locate where exactly does it fail), which makes the system refuse to work with that port. The 1st port is shown offline and disabled in logs. Port 2 is shown as "not present" (the controller is wrongly determined to be not dual).