Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 9142 → Rev 9143

/kernel/branches/kolibri-ahci/blkdev/ahci.inc
322,7 → 322,7
dd 0 ; no close function
dd 0 ; no closemedia function
dd ahci_querymedia
dd 0;ahci_read
dd ahci_read
dd 0;ahci_write
dd 0 ; no flush function
dd 0 ; use default cache size
564,8 → 564,9
cmp [ecx + PORT_DATA.drive_type], AHCI_DEV_SATA
jne .after_add_disk ; skip adding disk code
; register disk in system:
stdcall ahci_read_first_sector, ecx
 
;stdcall ahci_read_first_sector, ecx
 
push ecx
mov eax, [hd_counter]
xor edx, edx
883,6 → 884,212
tmpstr2 rb 16
;----------------------------------------------------------
 
 
; Read sectors
; return value: 0 = success, otherwise = error
proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsectors_ptr:dword
locals
cmdslot dd ?
cmdheader dd ?
cmdtable dd ?
numsectors dd ?
buffer_pos dd ?
buffer_length dd ?
endl
 
pushad
 
mov ecx, ahci_mutex
call mutex_lock
 
; xor ecx, ecx
; mov esi, [buffer]
; .print_data:
; cmp ecx, 512
; jae .end_print_data
 
; mov al, byte [esi + ecx]
; mov byte [tmpstr], al
; mov byte [tmpstr + 1], 0
; DEBUGF 1, "0x%x(%s) ", al:2, tmpstr
 
; inc ecx
; jmp .print_data
; .end_print_data:
; DEBUGF 1, "\n"
 
mov eax, [numsectors_ptr]
mov eax, [eax]
mov [numsectors], eax
 
DEBUGF 1, " ahci_read: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u\n", [buffer], [startsector], [startsector + 4], eax
 
mov esi, [pdata] ; esi - address of PORT_DATA struct of port
mov edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
mov eax, edi
call ahci_find_cmdslot
cmp eax, -1
jne .cmdslot_found
 
DEBUGF 1, "No free cmdslot on port %u\n", [esi + PORT_DATA.portno]
jmp .ret
 
.cmdslot_found:
mov [cmdslot], eax
DEBUGF 1, "Found free cmdslot %u on port %u\n", [cmdslot], [esi + PORT_DATA.portno]
 
shl eax, BSF sizeof.HBA_CMD_HDR
add eax, [esi + PORT_DATA.clb]
mov [cmdheader], eax ; address of virtual mapping of command header
mov eax, [cmdslot]
mov eax, [esi + eax*4 + PORT_DATA.ctba_arr]
mov [cmdtable], eax ; address of virtual mapping of command table of command header
 
mov eax, [cmdheader]
and [eax + HBA_CMD_HDR.flags1], not 0x1F ; zero out lower 5 bits, they will be used for cfl
or [eax + HBA_CMD_HDR.flags1], (sizeof.FIS_REG_H2D / 4) ; set command fis length in dwords
movzx bx, [eax + HBA_CMD_HDR.flags1]
btr bx, 6 ; flag W = 0
mov [eax + HBA_CMD_HDR.flags1], bl
movzx bx, [eax + HBA_CMD_HDR.flags2]
btr bx, 2 ; flag C = 0
mov [eax + HBA_CMD_HDR.flags2], bl
 
mov ebx, [numsectors]
shl ebx, 9 ; *= 512
mov [buffer_length], ebx
dec ebx
shr ebx, 12 ; /= 4096
inc ebx
mov [eax + HBA_CMD_HDR.prdtl], bx
;DEBUGF 1, " prdtl = %u\n", [eax + HBA_CMD_HDR.prdtl]:2
; zero out the command table with its prdt entries
dec ebx
shl ebx, BSF sizeof.HBA_PRDT_ENTRY
add ebx, sizeof.HBA_CMD_TBL
stdcall _memset, [cmdtable], 0, ebx
DEBUGF 1, " prdtl = %u\n", [eax + HBA_CMD_HDR.prdtl]:2
;jmp .ret
 
xor ecx, ecx
movzx edx, [eax + HBA_CMD_HDR.prdtl]
dec edx
mov eax, [buffer]
mov [buffer_pos], eax
 
.prdt_fill:
cmp ecx, edx
jae .prdt_fill_end
mov ebx, [buffer_pos]
and ebx, 0xFFF
call get_pg_addr ; eax = phys addr
add eax, ebx
DEBUGF 1, " PHYS = 0x%x\n", eax
mov ebx, ecx
shl ebx, BSF sizeof.HBA_PRDT_ENTRY
add ebx, [cmdtable]
add ebx, HBA_CMD_TBL.prdt_entry ; now ebx - address of ecx'th prdt_entry
 
mov [ebx + HBA_PRDT_ENTRY.dba], eax
mov [ebx + HBA_PRDT_ENTRY.dbau], 0
and [ebx + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count
or [ebx + HBA_PRDT_ENTRY.flags], 4096 - 1 ; reason why -1 see in spec on this field
; or [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 1 shl 31 ; enable interrupt on completion
add [buffer_pos], 4096
sub [buffer_length], 4096
 
inc ecx
jmp .prdt_fill
.prdt_fill_end:
 
mov ebx, [buffer_pos]
and ebx, 0xFFF
call get_pg_addr ; eax = phys addr
add eax, ebx
DEBUGF 1, " PHYS. = 0x%x\n", eax
DEBUGF 1, " ecx = 0x%x\n", ecx
mov ebx, ecx
shl ebx, BSF sizeof.HBA_PRDT_ENTRY
add ebx, [cmdtable]
add ebx, HBA_CMD_TBL.prdt_entry ; now ebx - address of ecx'th prdt_entry
mov [ebx + HBA_PRDT_ENTRY.dba], eax
mov [ebx + HBA_PRDT_ENTRY.dbau], 0
and [ebx + HBA_PRDT_ENTRY.flags], not 0x3FFFFF ; zero out lower 22 bits, they used for byte count
mov eax, [buffer_length]
dec eax
DEBUGF 1, " DBC. = %u\n", eax
or [ebx + HBA_PRDT_ENTRY.flags], eax ; reason why -1 see in spec on this field
; or [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.flags], 1 shl 31 ; enable interrupt on completion
 
mov eax, [cmdtable]
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.fis_type], FIS_TYPE_REG_H2D
movzx ebx, byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags]
bts ebx, bit_AHCI_H2D_FLAG_CMD ; Set Command bit in H2D FIS.
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.flags], bl
 
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], ATA_CMD_READ_DMA_EX
 
mov ebx, dword [startsector]
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba0], bl
shr ebx, 8
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba1], bl
shr ebx, 8
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba2], bl
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 1 shl 6 ; LBA mode
shr ebx, 8
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba3], bl
mov ebx, dword [startsector + 4]
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba4], bl
shr ebx, 8
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.lba5], bl
 
mov ebx, [numsectors]
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.countl], bl
shr ebx, 8
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.counth], bl
 
; Wait on previous command to complete, before issuing new command.
stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT
 
mov eax, [cmdslot]
bts [edi + HBA_PORT.command_issue], eax ; Issue the command
 
; Wait for command completion
stdcall ahci_port_cmd_wait, edi, eax;, AHCI_PORT_CMD_TIMEOUT
 
DEBUGF 1, "sata_error register = 0x%x\n", [edi + HBA_PORT.sata_error]
 
DEBUGF 1, "reading completed\n"
 
xor ecx, ecx
mov esi, [buffer]
.print_data:
cmp ecx, 512
jae .end_print_data
 
mov al, byte [esi + ecx]
mov byte [tmpstr], al
mov byte [tmpstr + 1], 0
DEBUGF 1, "0x%x(%s) ", al:2, tmpstr
 
inc ecx
jmp .print_data
.end_print_data:
DEBUGF 1, "\n"
 
.ret:
mov ecx, ahci_mutex
call mutex_unlock
 
popad
xor eax, eax
ret
endp
tmpstr rb 16
 
; Start command engine
; in: eax - address of HBA_PORT structure
ahci_start_cmd: