Reputation: 98
I'm writing an x86_64 os and testing it on qemu pc. I'm trying to implement a mouse driver, but when I reach the end of the initialization function, I get a general protection fault. Another wierd thing that happens which I'm not sure is normal is that all call to wait_mouse end up timeouting (for testing purpouses I ignore the timeout, also because that is what the code I took did). Here is my code (which seems to be what every single hobby kernel online uses):
const MOUSE_PORT: u16 = 0x60;
const MOUSE_STATUS: u16 = 0x64;
const MOUSE_ABIT: u8 = 0x02;
const MOUSE_BBIT: u8 = 0x01;
const MOUSE_WRITE: u8 = 0xD4;
const MOUSE_F_BIT: u16 = 0x20;
const MOUSE_V_BIT: u16 = 0x08;
pub fn init() -> Result<(), &'static str> {
let mut status: u8 = 0;
unsafe {
asm!("cli");
}
mouse_wait(true)?;
outb(MOUSE_STATUS, 0xA8);
mouse_wait(true)?;
outb(MOUSE_STATUS, 0x20);
mouse_wait(false)?;
status = inb(0x60) | 2;
mouse_wait(true)?;
outb(MOUSE_STATUS, 0x60);
mouse_wait(true)?;
outb(MOUSE_PORT, status);
mouse_write(0xF6)?;
mouse_read()?;
mouse_write(0xF4)?;
mouse_read()?;
unsafe {
asm!("sti");
}
Ok(())
}
fn mouse_wait(a_type: bool) -> Result<(), &'static str> {
let mut timeout = 100000;
if !a_type {
while timeout > 0 {
if inb(MOUSE_STATUS) & MOUSE_BBIT == 1 {
return Ok(());
}
timeout -= 1;
}
} else {
while timeout > 0 {
if inb(MOUSE_STATUS) & MOUSE_ABIT != 0 {
return Ok(());
}
timeout -= 1;
}
}
// Err("Mouse timeout")
Ok(())
}
fn mouse_write(write: u8) -> Result<(), &'static str> {
mouse_wait(true)?;
outb(MOUSE_STATUS, MOUSE_WRITE);
mouse_wait(true)?;
outb(MOUSE_PORT, write);
Ok(())
}
fn mouse_read() -> Result<u8, &'static str> {
mouse_wait(false)?;
Ok(inb(MOUSE_PORT))
}
I looked at the instruction pointed to by the RIP
saved by the general protection fault, and it appears to be a pop
instruction right before the ret
of the initialization routine.
Here is what I get from qemu:
Servicing hardware INT=0x21
221: v=21 e=0000 i=0 cpl=0 IP=0008:000000000e097a07 pc=000000000e097a07 SP=0010:000000000fe96770 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000002cbb000 RCX=00000000000186a0 RDX=00000000801b0060
RSI=000000000e0a9118 RDI=0000000000000064 RBP=000000000fe96801 RSP=000000000fe96770
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000064 R13=000000000e98d000 R14=0000111100000000 R15=000000000fe967a8
RIP=000000000e097a07 RFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0028 000000000e0ae151 00000067 00008900 DPL=0 TSS64-avl
GDT= 000000000e0af2e8 00000037
IDT= 000000000e0ae1c8 00000fff
CR0=80010033 CR2=0000000000000000 CR3=0000000000449000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000001 CCD=0000000000000001 CCO=CLR
EFER=0000000000000d00
Servicing hardware INT=0x24
222: v=24 e=0000 i=0 cpl=0 IP=0008:000000000e097a07 pc=000000000e097a07 SP=0010:000000000fe96770 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000002cbb000 RCX=00000000000186a0 RDX=00000000801b0060
RSI=000000000e0a9118 RDI=0000000000000064 RBP=000000000fe96801 RSP=000000000fe96770
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000064 R13=000000000e98d000 R14=0000111100000000 R15=000000000fe967a8
RIP=000000000e097a07 RFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0028 000000000e0ae151 00000067 00008900 DPL=0 TSS64-avl
GDT= 000000000e0af2e8 00000037
IDT= 000000000e0ae1c8 00000fff
CR0=80010033 CR2=0000000000000000 CR3=0000000000449000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000044 CCD=0000000000000000 CCO=EFLAGS
EFER=0000000000000d00
check_exception old: 0xffffffff new 0xd
223: v=0d e=0122 i=0 cpl=0 IP=0008:000000000e097a07 pc=000000000e097a07 SP=0010:000000000fe96770 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000002cbb000 RCX=00000000000186a0 RDX=00000000801b0060
RSI=000000000e0a9118 RDI=0000000000000064 RBP=000000000fe96801 RSP=000000000fe96770
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000064 R13=000000000e98d000 R14=0000111100000000 R15=000000000fe967a8
RIP=000000000e097a07 RFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0028 000000000e0ae151 00000067 00008900 DPL=0 TSS64-avl
GDT= 000000000e0af2e8 00000037
IDT= 000000000e0ae1c8 00000fff
CR0=80010033 CR2=0000000000000000 CR3=0000000000449000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000044 CCD=0000000000000000 CCO=EFLAGS
EFER=0000000000000d00
I set the interrupt service routine at 44 (32 + 12) before calling the init function. At the moment it just prints "mouse!" and loops forever, without sending any EOI (which shouldn't be needed). Are there mabye any other ps2 configurations I need to do before calling init? Thanks for the help!
Upvotes: 0
Views: 94