Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 9072 → Rev 9074

/kernel/branches/kolibri-ahci/blkdev/ahci.inc
27,6 → 27,8
bit_AHCI_HBA_PxCMD_FR = 14
bit_AHCI_HBA_PxCMD_CR = 15
 
bit_AHCI_H2D_FLAG_CMD = 7
 
AHCI_HBA_PxSSTS_DET = 0xF
AHCI_HBA_PORT_IPM_ACTIVE = 1
AHCI_HBA_PxSSTS_DET_PRESENT = 3
90,7 → 92,7
vendor rd 4 ; 0x70 - 0x7F, vendor specific
ends
 
; Command header structure
; Command header structure, size = 32 bytes
struct HBA_CMD_HDR
_flags1 db ? ; 0bPWACCCCC, P - Prefetchable, W - Write (1: H2D, 0: D2H)
; A - ATAPI, C - Command FIS length in DWORDS, 2 ~ 16
105,6 → 107,7
rd 4 ; Reserved
ends
 
; Physical region descriptor table entry, size = 16 bytes
struct HBA_PRDT_ENTRY
dba dd ? ; Data base address
dbau dd ? ; Data base address upper 32 bits
127,6 → 130,7
fb dd ? ; FIS base
ctba_arr rd 32 ; ctba_arr[0] = clb[0].ctba, ... and so on.
port dd ? ; address of correspoding HBA_PORT structure
portno dd ? ; port index, 0..31
ends
 
; Register FIS – Host to Device
408,7 → 412,7
jnc .continue_detect_drives
 
mov edi, ebx
shl edi, BSF sizeof.HBA_PORT
imul edi, sizeof.HBA_PORT
add edi, HBA_MEM.ports
add edi, esi
; now edi - base of HBA_MEM.ports[ebx]
429,10 → 433,12
DEBUGF 1, "K: AHCI: found drive at port %d, signature = %x\n", ebx, [edi + HBA_PORT.signature]
 
mov ecx, ebx
shl ecx, BSF sizeof.PORT_DATA
imul ecx, sizeof.PORT_DATA
add ecx, port_data_arr
stdcall ahci_port_rebase, edi, ebx, ecx
 
stdcall ahci_port_identify, ecx
 
.continue_detect_drives:
inc ebx
jmp .detect_drives
445,6 → 451,105
ret
; -------------------------------------------------
 
modelstr rb 42
; Identify drive on port ; TODO check
; in: pdata - address of PORT_DATA structure
proc ahci_port_identify stdcall, pdata: dword
locals
cmdslot dd ?
cmdheader dd ?
cmdtable dd ?
buf_phys dd ?
buf_virt dd ?
endl
 
pushad
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]
 
.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
 
stdcall _memset, eax, 0, sizeof.HBA_CMD_TBL
 
call alloc_page
mov [buf_phys], eax
 
stdcall map_io_mem, eax, 4096, PG_NOCACHE + PG_SWR ; map to virt memory so we can work with it
mov [buf_virt], eax
 
mov eax, [cmdtable]
mov ebx, [buf_phys]
mov dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.dba], ebx
mov dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.dbau], 0
mov dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY._flags], 512 - 1 ; why -1 ?
mov eax, [cmdheader]
mov [eax + HBA_CMD_HDR.prdtl], 1
 
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
; if (port->signature == AHCI_PxSIG_ATAPI) cmd_fis->command = ATA_IDENTIFY_PACKET;
; else cmd_fis->command = ATA_IDENTIFY;
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], 0xEC ;ATA_IDENTIFY ;
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 0
 
; TODO Wait on previous command to complete. AHCIPortWait(bd->port_num, tS + 2);
mov ebx, 20 ;;;
call delay_hs ;;;
 
mov eax, [cmdslot]
bts [edi + HBA_PORT.command_issue], eax ; Issue the command
 
; TODO AHCIPortCmdWait(bd->port_num, cmd_slot);
mov ebx, 20 ;;;
call delay_hs ;;;
 
mov esi, [buf_virt]
add esi, 27*2
mov edi, modelstr
mov ecx, ((46-27)+1)*2
cld
rep movsb
mov byte [edi], 0
xor ecx, ecx
.reverse1:
cmp ecx, ((46-27)+1)*2
jae .reverse1_end
mov bl, byte [modelstr + ecx]
mov dl, byte [modelstr + ecx + 1]
mov byte [modelstr + ecx], dl
mov byte [modelstr + ecx + 1], bl
add ecx, 2
jmp .reverse1
.reverse1_end:
DEBUGF 1, "Ident data of port: model = %s\n", modelstr
 
.ret:
popad
ret
endp
 
; Start command engine
; in: eax - address of HBA_PORT structure
ahci_start_cmd:
535,6 → 640,8
 
mov eax, [port]
mov [edi + PORT_DATA.port], eax ; set pdata->port
mov eax, [portno] ; set pdata->portno
mov [edi + PORT_DATA.portno], eax
 
stdcall _memset, ebx, 0, 1024 ; zero out the command list