ATA driver hangs on initialization while polling BSY
Posted: Wed Feb 06, 2019 11:30 am
My code for a bootloader hangs while polling BSY before pretty much everywhere I poll BSY (i.e. BSY never seems to clear).
I've tried to search for similar problems, but haven't found anything that fixed it. Any help would be much appreciated.
Code: Select all
hdd_init:
mov al, 0x06
mov dx, 0x3f6
out dx, al ; do a software reset
mov dx, 0x1f7
in al, dx
in al, dx
in al, dx
in al, dx ; 400ns delay
in al, dx
cmp al, 0xff
je mfail ; drive missing error
poll0: in al, dx
test al, 0x40 ; test DRDY to make sure the drive is ready to switch
pause
; jz poll0 ; this hangs infinitely
dec dx
mov al, 0xa0
out dx, al ; select drive 0
mov dx, 0x1f1
xor al, al
out dx, al ; send 0 to features register
add dx, 6
in al, dx
in al, dx
in al, dx
in al, dx ; 400ns delay
in al, dx
cmp al, 0xff
je mfail ; drive missing error
test al, 0x01
jnz mfail ; drive select error
xor al, al
mov dx, 0x1f2
out dx, al
inc dx ; 0x1f3
out dx, al
inc dx ; 0x1f4
out dx, al
inc dx ; 0x1f5
out dx, al
mov al, 0xec
add dx, 2 ; 0x1f7
out dx, al ; send identify command
in al, dx
in al, dx
in al, dx
in al, dx ; 400ns delay
in al, dx
cmp al, 0
je mfail
sub dx, 2 ; 0x1f5
in al, dx
test al, al
jnz pfail
dec dx ; 0x1f4
in al, dx
test al, al
jnz pfail
poll5: pause
in al, dx
test al, 0x80
jnz poll5 ; wait for BSY to clear -- this may also hang
; now to find a gpt table
mov dx, 0x1f2
mov al, 1
out dx, al ; sector count
inc dx
mov al, 1
out dx, al ; low byte of LBA
inc dx
xor al, al
out dx, al
inc dx
xor al, al
out dx, al ; higher bytes of LBA
mov dx, 0x1f7
in al, dx
in al, dx
in al, dx
in al, dx ; 400ns delay
poll10: pause
in al, dx
and al, 0xc0
cmp al, 0x40
jne poll10 ; test RDY and BSY -- or this one hangs
mov al, 0x20
out dx, al ; read using LBA 28
in al, dx
in al, dx
in al, dx
in al, dx ; 400ns delay
in al, dx
test al, 0x01
je dfail
poll20: in al, dx
test al, 0x40 ; test RDY to make sure the drive is spun up
pause
jz poll20
poll30: in al, dx
test al, 0x80 ; test BSY to make sure the drive is preparing to read
pause
jz poll30
poll40: in al, dx
test al, 0x80 ; test BSY to make sure the drive is ready to read
pause
jnz poll40
poll50: in al, dx
test al, 0x08
pause
jnz poll50 ; test RDX to make sure the drive is really ready to read