kolibri-ahci:

- added ahci_port_identify (it works!)
- other fixes
- todo: fix dirty codestyle)

git-svn-id: svn://kolibrios.org@9074 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Rustem Gimadutdinov (rgimad) 2021-07-21 23:00:47 +00:00
parent f73a566b8b
commit 39368a57b4

View File

@ -27,6 +27,8 @@ bit_AHCI_HBA_PxCMD_FRE = 4
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 @@ struct HBA_PORT
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 @@ struct HBA_CMD_HDR
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 @@ struct PORT_DATA
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 @@ ahci_init:
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 @@ ahci_init:
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 @@ ahci_init:
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 @@ proc ahci_port_rebase stdcall, port: dword, portno: dword, pdata: dword
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