1) DMA LBA48 read and write for HDD

2) Some optimization of code

git-svn-id: svn://kolibrios.org@3712 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Marat Zakiyanov (Mario79) 2013-06-27 06:11:10 +00:00
parent 65d0cef44b
commit 93e7aee516
4 changed files with 302 additions and 305 deletions

View File

@ -11,7 +11,8 @@ $Revision$
; Low-level driver for HDD access ; Low-level driver for HDD access
; DMA support by Mario79 ; DMA support by Mario79
; Access through BIOS by diamond ; Access through BIOS by diamond
; LBA48 support by Mario79
;-----------------------------------------------------------------------------
align 4 align 4
hd_read: hd_read:
;----------------------------------------------------------- ;-----------------------------------------------------------
@ -21,23 +22,19 @@ hd_read:
and [hd_error], 0 and [hd_error], 0
push ecx esi edi ; scan cache push ecx esi edi ; scan cache
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
call calculate_cache call calculate_cache
add esi, 8 add esi, 8
mov edi, 1 mov edi, 1
hdreadcache: hdreadcache:
cmp dword [esi+4], 0 ; empty
cmp dword [esi+4], 0; empty
je nohdcache je nohdcache
cmp [esi], eax ; correct sector cmp [esi], eax ; correct sector
je yeshdcache je yeshdcache
nohdcache: nohdcache:
add esi, 8 add esi, 8
inc edi inc edi
dec ecx dec ecx
@ -49,12 +46,6 @@ hd_read:
; Read through BIOS? ; Read through BIOS?
cmp [hdpos], 0x80 cmp [hdpos], 0x80
jae .bios jae .bios
; hd_read_{dma,pio} use old ATA with 28 bit for sector number
; cmp eax, 0x10000000
; jb @f
; inc [hd_error]
; jmp return_01
;@@:
; DMA read is permitted if [allow_dma_access]=1 or 2 ; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2 cmp [allow_dma_access], 2
ja .nodma ja .nodma
@ -70,20 +61,17 @@ hd_read:
@@: @@:
cmp [hd_error], 0 cmp [hd_error], 0
jne return_01 jne return_01
; lea esi,[edi*8+HD_CACHE]
; push eax
call calculate_cache_1 call calculate_cache_1
lea esi, [edi*8+esi] lea esi, [edi*8+esi]
; pop eax
mov [esi], eax ; sector number mov [esi], eax ; sector number
mov dword [esi+4], 1; hd read - mark as same as in hd mov dword [esi+4], 1 ; hd read - mark as same as in hd
yeshdcache:
yeshdcache:
mov esi, edi mov esi, edi
shl esi, 9 shl esi, 9
; add esi,HD_CACHE+65536
push eax push eax
call calculate_cache_2 call calculate_cache_2
add esi, eax add esi, eax
@ -93,15 +81,16 @@ hd_read:
mov ecx, 512/4 mov ecx, 512/4
cld cld
rep movsd ; move data rep movsd ; move data
return_01:
return_01:
pop edi esi ecx pop edi esi ecx
ret ret
;-----------------------------------------------------------------------------
align 4 align 4
hd_read_pio: hd_read_pio:
push eax edx push eax edx
; Выбрать нужный диск ; Select the desired drive
mov edx, [hdbase] mov edx, [hdbase]
add edx, 6 ;адрес регистра головок add edx, 6 ;адрес регистра головок
mov al, byte [hdid] mov al, byte [hdid]
@ -116,6 +105,7 @@ hd_read_pio:
mov eax, [esp+4] mov eax, [esp+4]
cmp eax, 0x10000000 cmp eax, 0x10000000
jae .lba48 jae .lba48
;--------------------------------------
.lba28: .lba28:
pushfd pushfd
cli cli
@ -146,6 +136,7 @@ hd_read_pio:
out dx, al ; ATACommand регистр команд out dx, al ; ATACommand регистр команд
popfd popfd
jmp .continue jmp .continue
;--------------------------------------
.lba48: .lba48:
pushfd pushfd
cli cli
@ -162,7 +153,7 @@ hd_read_pio:
mov eax, [esp+4+4] mov eax, [esp+4+4]
rol eax, 8 rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24) out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax; because only 32 bit cache xor eax, eax ; because only 32 bit cache
inc edx inc edx
out dx, al ; LBA Mid Previous LBA (39:32) out dx, al ; LBA Mid Previous LBA (39:32)
inc edx inc edx
@ -179,21 +170,23 @@ hd_read_pio:
inc edx inc edx
mov al, byte [hdid] mov al, byte [hdid]
add al, 128+64+32 add al, 128+64+32
out dx, al; номер головки/номер диска out dx, al ; номер головки/номер диска
inc edx inc edx
mov al, 24h ; READ SECTOR(S) EXT mov al, 24h ; READ SECTOR(S) EXT
out dx, al; ATACommand регистр команд out dx, al ; ATACommand регистр команд
popfd popfd
;--------------------------------------
.continue: .continue:
call wait_for_sector_buffer call wait_for_sector_buffer
cmp [hd_error], 0 cmp [hd_error], 0
jne hd_read_error jne hd_read_error
pushfd
cli cli
push edi push edi
shl edi, 9 shl edi, 9
; add edi,HD_CACHE+65536
push eax push eax
call calculate_cache_2 call calculate_cache_2
add edi, eax add edi, eax
@ -204,27 +197,11 @@ hd_read_pio:
cld cld
rep insw rep insw
pop edi pop edi
sti popfd
pop edx eax pop edx eax
ret ret
;-----------------------------------------------------------------------------
disable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,2
; out dx,al
cli
ret
enable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,0
; out dx,al
sti
ret
align 4 align 4
hd_write: hd_write:
;----------------------------------------------------------- ;-----------------------------------------------------------
@ -233,51 +210,39 @@ hd_write:
;----------------------------------------------------------- ;-----------------------------------------------------------
push ecx esi edi push ecx esi edi
; check if the cache already has the sector and overwrite it ; check if the cache already has the sector and overwrite it
; mov ecx,cache_max
; mov esi,HD_CACHE+8
call calculate_cache call calculate_cache
add esi, 8 add esi, 8
mov edi, 1 mov edi, 1
hdwritecache: hdwritecache:
cmp dword [esi+4], 0 ; if cache slot is empty
cmp dword [esi+4], 0; if cache slot is empty
je not_in_cache_write je not_in_cache_write
cmp [esi], eax ; if the slot has the sector cmp [esi], eax ; if the slot has the sector
je yes_in_cache_write je yes_in_cache_write
not_in_cache_write: not_in_cache_write:
add esi, 8 add esi, 8
inc edi inc edi
dec ecx dec ecx
jnz hdwritecache jnz hdwritecache
; sector not found in cache ; sector not found in cache
; write the block to a new location ; write the block to a new location
call find_empty_slot ; ret in edi call find_empty_slot ; ret in edi
cmp [hd_error], 0 cmp [hd_error], 0
jne hd_write_access_denied jne hd_write_access_denied
; lea esi,[edi*8+HD_CACHE]
; push eax
call calculate_cache_1 call calculate_cache_1
lea esi, [edi*8+esi] lea esi, [edi*8+esi]
; pop eax
mov [esi], eax ; sector number mov [esi], eax ; sector number
yes_in_cache_write: yes_in_cache_write:
mov dword [esi+4], 2 ; write - differs from hd
mov dword [esi+4], 2; write - differs from hd
shl edi, 9 shl edi, 9
; add edi,HD_CACHE+65536
push eax push eax
call calculate_cache_2 call calculate_cache_2
add edi, eax add edi, eax
@ -287,20 +252,19 @@ hd_write:
mov ecx, 512/4 mov ecx, 512/4
cld cld
rep movsd ; move data rep movsd ; move data
hd_write_access_denied:
hd_write_access_denied:
pop edi esi ecx pop edi esi ecx
ret ret
;-----------------------------------------------------------------------------
align 4 align 4
cache_write_pio: cache_write_pio:
; call disable_ide_int ; Select the desired drive
; Выбрать нужный диск
mov edx, [hdbase] mov edx, [hdbase]
add edx, 6 ;адрес регистра головок add edx, 6 ;адрес регистра головок
mov al, byte [hdid] mov al, byte [hdid]
add al, 128+64+32 add al, 128+64+32
out dx, al; номер головки/номер диска out dx, al ; номер головки/номер диска
call wait_for_hd_idle call wait_for_hd_idle
cmp [hd_error], 0 cmp [hd_error], 0
@ -310,6 +274,7 @@ cache_write_pio:
mov eax, [esi] mov eax, [esi]
cmp eax, 0x10000000 cmp eax, 0x10000000
jae .lba48 jae .lba48
;--------------------------------------
.lba28: .lba28:
pushfd pushfd
cli cli
@ -340,6 +305,7 @@ cache_write_pio:
out dx, al ; ATACommand регистр команд out dx, al ; ATACommand регистр команд
popfd popfd
jmp .continue jmp .continue
;--------------------------------------
.lba48: .lba48:
pushfd pushfd
cli cli
@ -356,7 +322,7 @@ cache_write_pio:
mov eax, [esi] mov eax, [esi]
rol eax, 8 rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24) out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax; because only 32 bit cache xor eax, eax ; because only 32 bit cache
inc edx inc edx
out dx, al ; LBA Mid Previous LBA (39:32) out dx, al ; LBA Mid Previous LBA (39:32)
inc edx inc edx
@ -373,11 +339,12 @@ cache_write_pio:
inc edx inc edx
mov al, byte [hdid] mov al, byte [hdid]
add al, 128+64+32 add al, 128+64+32
out dx, al; номер головки/номер диска out dx, al ; номер головки/номер диска
inc edx inc edx
mov al, 34h ; WRITE SECTOR(S) EXT mov al, 34h ; WRITE SECTOR(S) EXT
out dx, al; ATACommand регистр команд out dx, al ; ATACommand регистр команд
popfd popfd
;--------------------------------------
.continue: .continue:
call wait_for_sector_buffer call wait_for_sector_buffer
@ -386,10 +353,11 @@ cache_write_pio:
push ecx esi push ecx esi
pushfd
cli cli
mov esi, edi mov esi, edi
shl esi, 9 shl esi, 9
; add esi,HD_CACHE+65536 ; esi = from memory position
push eax push eax
call calculate_cache_2 call calculate_cache_2
add esi, eax add esi, eax
@ -399,62 +367,42 @@ cache_write_pio:
mov edx, [hdbase] mov edx, [hdbase]
cld cld
rep outsw rep outsw
sti popfd
; call enable_ide_int
pop esi ecx pop esi ecx
ret ret
;-----------------------------------------------------------------------------
align 4
save_hd_wait_timeout: save_hd_wait_timeout:
push eax push eax
mov eax, [timer_ticks] mov eax, [timer_ticks]
add eax, 300 ; 3 sec timeout add eax, 300 ; 3 sec timeout
mov [hd_wait_timeout], eax mov [hd_wait_timeout], eax
pop eax pop eax
ret ret
;-----------------------------------------------------------------------------
align 4 align 4
check_hd_wait_timeout: check_hd_wait_timeout:
push eax push eax
mov eax, [hd_wait_timeout] mov eax, [hd_wait_timeout]
cmp [timer_ticks], eax cmp [timer_ticks], eax
jg hd_timeout_error jg hd_timeout_error
pop eax pop eax
mov [hd_error], 0 mov [hd_error], 0
ret ret
;-----------------------------------------------------------------------------
;iglobal
; hd_timeout_str db 'K : FS - HD timeout',0
; hd_read_str db 'K : FS - HD read error',0
; hd_write_str db 'K : FS - HD write error',0
; hd_lba_str db 'K : FS - HD LBA error',0
;endg
hd_timeout_error: hd_timeout_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_timeout_str
; call sys_msg_board_str
if lang eq sp if lang eq sp
DEBUGF 1,"K : FS - HD tiempo de espera agotado\n" DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
else else
DEBUGF 1,"K : FS - HD timeout\n" DEBUGF 1,"K : FS - HD timeout\n"
end if end if
mov [hd_error], 1 mov [hd_error], 1
pop eax pop eax
ret ret
;-----------------------------------------------------------------------------
hd_read_error: hd_read_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_read_str
; call sys_msg_board_str
if lang eq sp if lang eq sp
DEBUGF 1,"K : FS - HD error de lectura\n" DEBUGF 1,"K : FS - HD error de lectura\n"
else else
@ -462,58 +410,36 @@ hd_read_error:
end if end if
pop edx eax pop edx eax
ret ret
;-----------------------------------------------------------------------------
hd_write_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_write_str
; call sys_msg_board_str
if lang eq sp
DEBUGF 1,"K : FS - HD error de escritura\n"
else
DEBUGF 1,"K : FS - HD write error\n"
end if
ret
hd_write_error_dma: hd_write_error_dma:
; call clear_hd_cache pop esi
; call clear_application_table_status hd_write_error:
; mov esi, hd_write_str
; call sys_msg_board_str
if lang eq sp if lang eq sp
DEBUGF 1,"K : FS - HD error de escritura\n" DEBUGF 1,"K : FS - HD error de escritura\n"
else else
DEBUGF 1,"K : FS - HD write error\n" DEBUGF 1,"K : FS - HD write error\n"
end if end if
pop esi
ret ret
;-----------------------------------------------------------------------------
hd_lba_error: hd_lba_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_lba_str
; call sys_msg_board_str
if lang eq sp if lang eq sp
DEBUGF 1,"K : FS - HD error en LBA\n" DEBUGF 1,"K : FS - HD error en LBA\n"
else else
DEBUGF 1,"K : FS - HD LBA error\n" DEBUGF 1,"K : FS - HD LBA error\n"
end if end if
jmp LBA_read_ret jmp LBA_read_ret
;-----------------------------------------------------------------------------
align 4 align 4
wait_for_hd_idle: wait_for_hd_idle:
push eax edx push eax edx
call save_hd_wait_timeout call save_hd_wait_timeout
mov edx, [hdbase] mov edx, [hdbase]
add edx, 0x7 add edx, 0x7
;--------------------------------------
wfhil1: align 4
wfhil1:
call check_hd_wait_timeout call check_hd_wait_timeout
cmp [hd_error], 0 cmp [hd_error], 0
jne @f jne @f
@ -522,24 +448,21 @@ wait_for_hd_idle:
test al, 128 test al, 128
jnz wfhil1 jnz wfhil1
@@: @@:
pop edx eax pop edx eax
ret ret
;-----------------------------------------------------------------------------
align 4 align 4
wait_for_sector_buffer: wait_for_sector_buffer:
push eax edx push eax edx
mov edx, [hdbase] mov edx, [hdbase]
add edx, 0x7 add edx, 0x7
call save_hd_wait_timeout call save_hd_wait_timeout
;--------------------------------------
hdwait_sbuf: ; wait for sector buffer to be ready align 4
hdwait_sbuf: ; wait for sector buffer to be ready
call check_hd_wait_timeout call check_hd_wait_timeout
cmp [hd_error], 0 cmp [hd_error], 0
jne @f jne @f
@ -555,20 +478,20 @@ wait_for_sector_buffer:
test al, 1 ; previous command ended up with an error test al, 1 ; previous command ended up with an error
jz buf_wait_ok jz buf_wait_ok
@@: @@:
mov [hd_error], 1 mov [hd_error], 1
buf_wait_ok: buf_wait_ok:
pop edx eax pop edx eax
ret ret
;-----------------------------------------------------------------------------
; \begin{Mario79}
align 4 align 4
wait_for_sector_dma_ide0: wait_for_sector_dma_ide0:
push eax push eax
push edx push edx
call save_hd_wait_timeout call save_hd_wait_timeout
;--------------------------------------
align 4
.wait: .wait:
call change_task call change_task
cmp [irq14_func], hdd_irq14 cmp [irq14_func], hdd_irq14
@ -584,12 +507,14 @@ wait_for_sector_dma_ide0:
pop edx pop edx
pop eax pop eax
ret ret
;-----------------------------------------------------------------------------
align 4 align 4
wait_for_sector_dma_ide1: wait_for_sector_dma_ide1:
push eax push eax
push edx push edx
call save_hd_wait_timeout call save_hd_wait_timeout
;--------------------------------------
align 4
.wait: .wait:
call change_task call change_task
cmp [irq15_func], hdd_irq15 cmp [irq15_func], hdd_irq15
@ -606,7 +531,7 @@ wait_for_sector_dma_ide1:
pop edx pop edx
pop eax pop eax
ret ret
;-----------------------------------------------------------------------------
iglobal iglobal
align 4 align 4
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary ; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
@ -620,7 +545,7 @@ dma_hdpos dd 0
irq14_func dd hdd_irq_null irq14_func dd hdd_irq_null
irq15_func dd hdd_irq_null irq15_func dd hdd_irq_null
endg endg
;-----------------------------------------------------------------------------
uglobal uglobal
; all uglobals are zeroed at boot ; all uglobals are zeroed at boot
dma_process dd 0 dma_process dd 0
@ -633,7 +558,7 @@ dma_task_switched db 0
dma_hdd db 0 dma_hdd db 0
allow_dma_access db 0 allow_dma_access db 0
endg endg
;-----------------------------------------------------------------------------
align 4 align 4
hdd_irq14: hdd_irq14:
pushfd pushfd
@ -643,27 +568,12 @@ hdd_irq14:
mov dx, [IDEContrRegsBaseAddr] mov dx, [IDEContrRegsBaseAddr]
mov al, 0 mov al, 0
out dx, al out dx, al
; call update_counters
; mov ebx, [dma_process]
; cmp [CURRENT_TASK], ebx
; jz .noswitch
; mov [dma_task_switched], 1
; mov edi, [dma_slot_ptr]
; mov eax, [CURRENT_TASK]
; mov [dma_process], eax
; mov eax, [TASK_BASE]
; mov [dma_slot_ptr], eax
; mov [CURRENT_TASK], ebx
; mov [TASK_BASE], edi
; mov byte [DONT_SWITCH], 1
; call do_change_task
.noswitch:
popad popad
popfd popfd
align 4 align 4
hdd_irq_null: hdd_irq_null:
ret ret
;-----------------------------------------------------------------------------
align 4 align 4
hdd_irq15: hdd_irq15:
pushfd pushfd
@ -674,33 +584,12 @@ hdd_irq15:
add dx, 8 add dx, 8
mov al, 0 mov al, 0
out dx, al out dx, al
; call update_counters
; mov ebx, [dma_process]
; cmp [CURRENT_TASK], ebx
; jz .noswitch
; mov [dma_task_switched], 1
; mov edi, [dma_slot_ptr]
; mov eax, [CURRENT_TASK]
; mov [dma_process], eax
; mov eax, [TASK_BASE]
; mov [dma_slot_ptr], eax
; mov [CURRENT_TASK], ebx
; mov [TASK_BASE], edi
; mov byte [DONT_SWITCH], 1
; call do_change_task
.noswitch:
popad popad
popfd popfd
ret ret
;-----------------------------------------------------------------------------
align 4 align 4
hd_read_dma: hd_read_dma:
; hd_read_dma use old ATA with 28 bit for sector number
cmp eax, 0x10000000
jb @f
inc [hd_error]
ret
@@:
push eax push eax
push edx push edx
mov edx, [dma_hdpos] mov edx, [dma_hdpos]
@ -719,7 +608,7 @@ hd_read_dma:
push ecx esi edi push ecx esi edi
mov esi, eax mov esi, eax
shl edi, 9 shl edi, 9
; add edi, HD_CACHE+0x10000
push eax push eax
call calculate_cache_2 call calculate_cache_2
add edi, eax add edi, eax
@ -751,37 +640,97 @@ hd_read_dma:
add edx, 2 add edx, 2
mov al, 6 mov al, 6
out dx, al out dx, al
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
call wait_for_hd_idle call wait_for_hd_idle
cmp [hd_error], 0 cmp [hd_error], 0
jnz hd_read_error jnz hd_read_error
call disable_ide_int
; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4]
; -10h because the PreCache hits the boundary between lba28 and lba48
; 10h = 16 - size of PreCache
cmp eax, 0x10000000-10h
jae .lba48
;--------------------------------------
.lba28:
pushfd
cli
xor eax, eax xor eax, eax
mov edx, [hdbase] mov edx, [hdbase]
inc edx inc edx
out dx, al out dx, al ; ATA Features регистр "особенностей"
inc edx inc edx
mov eax, 10h mov eax, 10h ; Sector Counter = 16 ; PreCache
out dx, al out dx, al ; ATA Sector Counter счётчик секторов
inc edx inc edx
mov eax, [esp+4] mov eax, [esp+4+4]
out dx, al out dx, al ; LBA Low LBA (7:0)
shr eax, 8 shr eax, 8
inc edx inc edx
out dx, al out dx, al ; LBA Mid LBA (15:8)
shr eax, 8 shr eax, 8
inc edx inc edx
out dx, al out dx, al ; LBA High LBA (23:16)
shr eax, 8 shr eax, 8
inc edx inc edx
and al, 0xF and al, 0xF ; LBA (27:24)
add al, byte [hdid] add al, byte [hdid]
add al, 11100000b add al, 11100000b
out dx, al out dx, al ; номер головки/номер диска
inc edx inc edx
mov al, 0xC8 mov al, 0xC8 ; READ DMA
out dx, al out dx, al ; ATACommand регистр команд
jmp .continue
;--------------------------------------
.lba48:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al ; Features Previous Reserved
out dx, al ; Features Current Reserved
inc edx
out dx, al ; Sector Count Previous Sector count (15:8)
mov eax, 10h ; Sector Counter = 16 PreCache
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esp+4+4]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
inc edx
out dx, al ; LBA Mid Previous LBA (39:32)
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esp+4+4]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
out dx, al ; LBA Mid Current LBA (15:8)
shr eax, 8
inc edx
out dx, al ; LBA High Current LBA (23:16)
inc edx
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
inc edx
mov al, 25h ; READ DMA EXT
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
mov dx, [IDEContrRegsBaseAddr] mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0 mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jz @f jz @f
add dx, 8 add dx, 8
@@: @@:
@ -791,15 +740,17 @@ hd_read_dma:
mov [dma_process], eax mov [dma_process], eax
mov eax, [TASK_BASE] mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0 mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1 jnz .ide1
mov [irq14_func], hdd_irq14 mov [irq14_func], hdd_irq14
jmp @f jmp @f
.ide1: .ide1:
mov [irq15_func], hdd_irq15 mov [irq15_func], hdd_irq15
@@: @@:
call enable_ide_int popfd
cmp [hdbase], 0x1F0 mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1 jnz .wait_ide1
call wait_for_sector_dma_ide0 call wait_for_sector_dma_ide0
jmp @f jmp @f
@ -814,17 +765,17 @@ hd_read_dma:
pop eax pop eax
mov [dma_cur_sector], eax mov [dma_cur_sector], eax
jmp hd_read_dma jmp hd_read_dma
;-----------------------------------------------------------------------------
align 4 align 4
write_cache_sector: write_cache_sector:
mov [cache_chain_size], 1 mov [cache_chain_size], 1
mov [cache_chain_pos], edi mov [cache_chain_pos], edi
;--------------------------------------
align 4
write_cache_chain: write_cache_chain:
cmp [hdpos], 0x80 cmp [hdpos], 0x80
jae bd_write_cache_chain jae bd_write_cache_chain
mov eax, [cache_chain_ptr] mov eax, [cache_chain_ptr]
cmp dword[eax], 0x10000000
jae .bad
push esi push esi
mov eax, IDE_descriptor_table mov eax, IDE_descriptor_table
mov edx, eax mov edx, eax
@ -857,38 +808,98 @@ write_cache_chain:
add edx, 2 add edx, 2
mov al, 6 mov al, 6
out dx, al out dx, al
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
call wait_for_hd_idle call wait_for_hd_idle
cmp [hd_error], 0 cmp [hd_error], 0
jnz hd_write_error_dma jnz hd_write_error_dma
call disable_ide_int
; ATA with 28 or 48 bit for sector number?
mov esi, [cache_chain_ptr]
mov eax, [esi]
; -40h because the PreCache hits the boundary between lba28 and lba48
; 40h = 64 - the maximum number of sectors to be written for one command
cmp eax, 0x10000000-40h
jae .lba48
;--------------------------------------
.lba28:
pushfd
cli
xor eax, eax xor eax, eax
mov edx, [hdbase] mov edx, [hdbase]
inc edx inc edx
out dx, al out dx, al ; ATA Features регистр "особенностей"
inc edx inc edx
mov al, [cache_chain_size] mov al, [cache_chain_size] ; Sector Counter
out dx, al out dx, al ; ATA Sector Counter счётчик секторов
inc edx inc edx
mov esi, [cache_chain_ptr]
mov eax, [esi] mov eax, [esi]
out dx, al out dx, al ; LBA Low LBA (7:0)
shr eax, 8 shr eax, 8
inc edx inc edx
out dx, al out dx, al ; LBA Mid LBA (15:8)
shr eax, 8 shr eax, 8
inc edx inc edx
out dx, al out dx, al ; LBA High LBA (23:16)
shr eax, 8 shr eax, 8
inc edx inc edx
and al, 0xF and al, 0xF ; LBA (27:24)
add al, byte [hdid] add al, byte [hdid]
add al, 11100000b add al, 11100000b
out dx, al out dx, al ; номер головки/номер диска
inc edx inc edx
mov al, 0xCA mov al, 0xCA ; WRITE DMA
out dx, al out dx, al ; ATACommand регистр команд
jmp .continue
;--------------------------------------
.lba48:
pushfd
cli
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al ; Features Previous Reserved
out dx, al ; Features Current Reserved
inc edx
out dx, al ; Sector Count Previous Sector count (15:8)
mov al, [cache_chain_size] ; Sector Counter
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esi]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
inc edx
out dx, al ; LBA Mid Previous LBA (39:32)
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esi]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
out dx, al ; LBA Mid Current LBA (15:8)
shr eax, 8
inc edx
out dx, al ; LBA High Current LBA (23:16)
inc edx
mov al, byte [hdid]
add al, 128+64+32
out dx, al ; номер головки/номер диска
inc edx
mov al, 35h ; WRITE DMA EXT
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
mov dx, [IDEContrRegsBaseAddr] mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0 mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jz @f jz @f
add dx, 8 add dx, 8
@@: @@:
@ -898,16 +909,18 @@ write_cache_chain:
mov [dma_process], eax mov [dma_process], eax
mov eax, [TASK_BASE] mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0 mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1 jnz .ide1
mov [irq14_func], hdd_irq14 mov [irq14_func], hdd_irq14
jmp @f jmp @f
.ide1: .ide1:
mov [irq15_func], hdd_irq15 mov [irq15_func], hdd_irq15
@@: @@:
call enable_ide_int popfd
mov [dma_cur_sector], not 0x40 mov [dma_cur_sector], not 0x40
cmp [hdbase], 0x1F0 mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1 jnz .wait_ide1
call wait_for_sector_dma_ide0 call wait_for_sector_dma_ide0
jmp @f jmp @f
@ -918,10 +931,7 @@ write_cache_chain:
jnz hd_write_error_dma jnz hd_write_error_dma
pop esi pop esi
ret ret
.bad: ;-----------------------------------------------------------------------------
inc [hd_error]
ret
uglobal uglobal
IDEContrRegsBaseAddr dw ? IDEContrRegsBaseAddr dw ?
IDEContrProgrammingInterface dw ? IDEContrProgrammingInterface dw ?
@ -930,14 +940,15 @@ IDE_BAR1_val dw ?
IDE_BAR2_val dw ? IDE_BAR2_val dw ?
IDE_BAR3_val dw ? IDE_BAR3_val dw ?
endg endg
; \end{Mario79} ;-----------------------------------------------------------------------------
; \begin{diamond} ; \begin{diamond}
uglobal uglobal
bios_hdpos dd 0 ; 0 is invalid value for [hdpos] bios_hdpos dd 0 ; 0 is invalid value for [hdpos]
bios_cur_sector dd ? bios_cur_sector dd ?
bios_read_len dd ? bios_read_len dd ?
endg endg
;-----------------------------------------------------------------------------
align 4
bd_read: bd_read:
push eax push eax
push edx push edx
@ -957,7 +968,7 @@ bd_read:
push ecx esi edi push ecx esi edi
mov esi, eax mov esi, eax
shl edi, 9 shl edi, 9
; add edi, HD_CACHE+0x10000
push eax push eax
call calculate_cache_2 call calculate_cache_2
add edi, eax add edi, eax
@ -991,7 +1002,8 @@ bd_read:
.v86err: .v86err:
mov [hd_error], 1 mov [hd_error], 1
jmp hd_read_error jmp hd_read_error
;-----------------------------------------------------------------------------
align 4
bd_write_cache_chain: bd_write_cache_chain:
pusha pusha
mov esi, [cache_chain_pos] mov esi, [cache_chain_pos]
@ -1019,12 +1031,13 @@ bd_write_cache_chain:
popa popa
mov [hd_error], 1 mov [hd_error], 1
jmp hd_write_error jmp hd_write_error
;-----------------------------------------------------------------------------
uglobal uglobal
int13_regs_in rb sizeof.v86_regs int13_regs_in rb sizeof.v86_regs
int13_regs_out rb sizeof.v86_regs int13_regs_out rb sizeof.v86_regs
endg endg
;-----------------------------------------------------------------------------
align 4
int13_call: int13_call:
; Because this code uses fixed addresses, ; Because this code uses fixed addresses,
; it can not be run simultaniously by many threads. ; it can not be run simultaniously by many threads.
@ -1075,9 +1088,9 @@ int13_call:
@@: @@:
ret ret
; \end{diamond} ; \end{diamond}
;-----------------------------------------------------------------------------
align 4
reserve_hd1: reserve_hd1:
cli cli
cmp [hd1_status], 0 cmp [hd1_status], 0
je reserve_ok1 je reserve_ok1
@ -1086,8 +1099,7 @@ reserve_hd1:
call change_task call change_task
jmp reserve_hd1 jmp reserve_hd1
reserve_ok1: reserve_ok1:
push eax push eax
mov eax, [CURRENT_TASK] mov eax, [CURRENT_TASK]
shl eax, 5 shl eax, 5
@ -1096,12 +1108,12 @@ reserve_hd1:
pop eax pop eax
sti sti
ret ret
;******************************************** ;-----------------------------------------------------------------------------
uglobal uglobal
hd_in_cache db ? hd_in_cache db ?
endg endg
;-----------------------------------------------------------------------------
align 4
reserve_hd_channel: reserve_hd_channel:
; BIOS disk accesses are protected with common mutex hd1_status ; BIOS disk accesses are protected with common mutex hd1_status
; This must be modified when hd1_status will not be valid! ; This must be modified when hd1_status will not be valid!
@ -1140,7 +1152,7 @@ reserve_hd_channel:
sti sti
.ret: .ret:
ret ret
;-----------------------------------------------------------------------------
free_hd_channel: free_hd_channel:
; see comment at reserve_hd_channel ; see comment at reserve_hd_channel
cmp [hdpos], 0x80 cmp [hdpos], 0x80
@ -1154,4 +1166,4 @@ free_hd_channel:
.IDE_Channel_2: .IDE_Channel_2:
mov [IDE_Channel_2], 0 mov [IDE_Channel_2], 0
ret ret
;******************************************** ;-----------------------------------------------------------------------------

View File

@ -136,14 +136,7 @@ found_slot_access_denied:
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
clear_hd_cache:
ret
;--------------------------------------------------------------------
align 4
calculate_cache: calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [hdpos], 1 cmp [hdpos], 1
@ -221,7 +214,6 @@ calculate_cache:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
calculate_cache_1: calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [hdpos], 1 cmp [hdpos], 1
@ -290,7 +282,6 @@ calculate_cache_1:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
calculate_cache_2: calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [hdpos], 1 cmp [hdpos], 1
@ -644,9 +635,6 @@ clear_CD_cache:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache: cd_calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [cdpos], 1 cmp [cdpos], 1
@ -697,7 +685,6 @@ cd_calculate_cache:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_1: cd_calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [cdpos], 1 cmp [cdpos], 1
@ -740,7 +727,6 @@ cd_calculate_cache_1:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_2: cd_calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 4 - IDE3
.ide0: .ide0:
cmp [cdpos], 1 cmp [cdpos], 1

View File

@ -405,12 +405,13 @@ sayerr:
; class 1 = mass storage ; class 1 = mass storage
; subclass 1 = IDE controller ; subclass 1 = IDE controller
; a) class 1, subclass 1, programming interface 0x80 ; a) class 1, subclass 1, programming interface 0x80
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103 mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x80 mov ecx, 1*10000h + 1*100h + 0x80
mov [es:BOOT_IDE_PI_16], cx mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0 xor si, si ; device index = 0
int 0x1A int 0x1A
jnc .found_1 jnc .found_1 ; Parallel IDE Controller
; b) class 1, subclass 1, programming interface 0x8f ; b) class 1, subclass 1, programming interface 0x8f
mov ax, 0xB103 mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8f mov ecx, 1*10000h + 1*100h + 0x8f
@ -426,12 +427,13 @@ sayerr:
int 0x1A int 0x1A
jnc .found jnc .found
; d) class 1, subclass 1, programming interface 0x8A ; d) class 1, subclass 1, programming interface 0x8A
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103 mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8A mov ecx, 1*10000h + 1*100h + 0x8A
mov [es:BOOT_IDE_PI_16], cx mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0 xor si, si ; device index = 0
int 0x1A int 0x1A
jnc .found jnc .found_1 ; Parallel IDE Controller
jmp .nopci jmp .nopci
.found_1: .found_1:
@ -448,7 +450,7 @@ sayerr:
.found: .found:
; get memory base BAR0 ; get memory base BAR0
mov ax, 0xB10A mov ax, 0xB10A
mov di, 0x10 ; memory base is config register at 0x20 mov di, 0x10 ; memory base is config register at 0x10
push cx push cx
int 0x1A int 0x1A
jc .no_BAR0 ;.nopci jc .no_BAR0 ;.nopci
@ -457,7 +459,7 @@ sayerr:
pop cx pop cx
; get memory base BAR1 ; get memory base BAR1
mov ax, 0xB10A mov ax, 0xB10A
mov di, 0x14 ; memory base is config register at 0x20 mov di, 0x14 ; memory base is config register at 0x14
push cx push cx
int 0x1A int 0x1A
jc .no_BAR1 ;.nopci jc .no_BAR1 ;.nopci
@ -466,7 +468,7 @@ sayerr:
pop cx pop cx
; get memory base BAR2 ; get memory base BAR2
mov ax, 0xB10A mov ax, 0xB10A
mov di, 0x18 ; memory base is config register at 0x20 mov di, 0x18 ; memory base is config register at 0x18
push cx push cx
int 0x1A int 0x1A
jc .no_BAR2 ;.nopci jc .no_BAR2 ;.nopci
@ -475,7 +477,7 @@ sayerr:
pop cx pop cx
; get memory base BAR3 ; get memory base BAR3
mov ax, 0xB10A mov ax, 0xB10A
mov di, 0x1C ; memory base is config register at 0x20 mov di, 0x1C ; memory base is config register at 0x1c
push cx push cx
int 0x1A int 0x1A
jc .no_BAR3 ;.nopci jc .no_BAR3 ;.nopci

View File

@ -206,7 +206,4 @@ clear_ide_cache:
ret ret
end_get_cache: end_get_cache:
; mov [cache_ide0_pointer],HD_CACHE
; mov [cache_ide0_system_data],HD_CACHE+65536
; mov [cache_ide0_system_sad_size],1919
popa popa