AHCI: Full multiple controller support.

Fix using hardcoded ctr1_data in three functions, use corresponding controller instead.
Add pointer to parent controller to PORT_DATA structure,
Other small changes

git-svn-id: svn://kolibrios.org@9272 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Rustem Gimadutdinov (rgimad) 2021-11-15 16:48:27 +00:00
parent 1f842ffb93
commit 571040afd5
2 changed files with 62 additions and 28 deletions

View File

@ -165,6 +165,7 @@ struct PORT_DATA
portno dd ? ; port index, 0..31 portno dd ? ; port index, 0..31
drive_type db ? ; drive type drive_type db ? ; drive type
sector_count dq ? ; number of sectors sector_count dq ? ; number of sectors
ctr_ptr dd ? ; pointer to controller to which port belongs
ends ends
; Register FIS Host to Device ; Register FIS Host to Device
@ -558,6 +559,8 @@ ahci_init:
imul ecx, sizeof.PORT_DATA imul ecx, sizeof.PORT_DATA
add ecx, AHCI_CTR.port_data_arr add ecx, AHCI_CTR.port_data_arr
add ecx, [ctr_ptr] add ecx, [ctr_ptr]
mov eax, [ctr_ptr]
mov [ecx + PORT_DATA.ctr_ptr], eax ; to which controller the port belongs
stdcall ahci_port_rebase, edi, ebx, ecx stdcall ahci_port_rebase, edi, ebx, ecx
; DEBUGF 1, "K: AHCI: After REBASING, signature = 0x%x\n", [edi + HBA_PORT.signature] ; DEBUGF 1, "K: AHCI: After REBASING, signature = 0x%x\n", [edi + HBA_PORT.signature]
@ -662,10 +665,7 @@ proc ahci_port_identify stdcall, pdata: dword
pushad pushad
mov esi, [pdata] ; esi - address of PORT_DATA struct of port 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 stdcall ahci_find_cmdslot, esi
mov eax, edi
call ahci_find_cmdslot
cmp eax, -1 cmp eax, -1
jne .cmdslot_found jne .cmdslot_found
@ -724,6 +724,8 @@ proc ahci_port_identify stdcall, pdata: dword
@@: @@:
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 0 mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 0
mov edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
; Wait on previous command to complete, before issuing new command. ; Wait on previous command to complete, before issuing new command.
stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT
; DEBUGF 1, "eax = %x\n", eax ; DEBUGF 1, "eax = %x\n", eax
@ -808,9 +810,7 @@ proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, nums
DEBUGF AHCI_DBGLVL, " ahci_rw_sectors: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u, is_write = %u\n", [vbuf], [startsector], [startsector + 4], [numsectors], [is_write]:1 DEBUGF AHCI_DBGLVL, " ahci_rw_sectors: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u, is_write = %u\n", [vbuf], [startsector], [startsector + 4], [numsectors], [is_write]:1
mov esi, [pdata] ; esi - address of PORT_DATA struct of port 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 stdcall ahci_find_cmdslot, esi
mov eax, edi
call ahci_find_cmdslot
cmp eax, -1 cmp eax, -1
jne .cmdslot_found jne .cmdslot_found
@ -998,6 +998,8 @@ proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, nums
shr ebx, 8 shr ebx, 8
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.counth], bl mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.counth], bl
mov edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
; Wait on previous command to complete, before issuing new command. ; Wait on previous command to complete, before issuing new command.
stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT
@ -1050,7 +1052,9 @@ proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsecto
pushad pushad
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_lock call mutex_lock
mov eax, [numsectors_ptr] mov eax, [numsectors_ptr]
@ -1088,7 +1092,9 @@ proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsecto
jmp .read_loop jmp .read_loop
.read_loop_end: .read_loop_end:
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_unlock call mutex_unlock
popad popad
@ -1105,7 +1111,9 @@ proc ahci_write stdcall pdata: dword, buffer: dword, startsector: qword, numsect
pushad pushad
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_lock call mutex_lock
mov eax, [numsectors_ptr] mov eax, [numsectors_ptr]
@ -1134,7 +1142,9 @@ proc ahci_write stdcall pdata: dword, buffer: dword, startsector: qword, numsect
jmp .write_loop jmp .write_loop
.write_loop_end: .write_loop_end:
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_unlock call mutex_unlock
popad popad
@ -1251,6 +1261,8 @@ endp
; in: port - address of HBA_PORT structure ; in: port - address of HBA_PORT structure
; portno - port index (0..31) ; portno - port index (0..31)
; pdata - address of PORT_DATA structure ; pdata - address of PORT_DATA structure
; out:
; rebases port and fills pdata with mappings
proc ahci_port_rebase stdcall, port: dword, portno: dword, pdata: dword proc ahci_port_rebase stdcall, port: dword, portno: dword, pdata: dword
locals locals
phys_page1 dd ? phys_page1 dd ?
@ -1360,15 +1372,19 @@ endp
; ----------------------------------------------------------- ; TODO check ; ----------------------------------------------------------- ; TODO check
; Find a free command list slot ; Find a free command list slot
; in: eax - address of HBA_PORT structure ; in: pdata - address of HBA_PORT structure
; out: eax - if not found -1, else slot index ; out: eax - if not found -1, else slot index
ahci_find_cmdslot: proc ahci_find_cmdslot stdcall, pdata: dword
push ebx ecx edx esi push ebx ecx edx esi
mov esi, [pdata]
mov eax, [esi + PORT_DATA.port]
; If not set in SACT and CI, the slot is free ; If not set in SACT and CI, the slot is free
mov ebx, [eax + HBA_PORT.sata_active] mov ebx, [eax + HBA_PORT.sata_active]
or ebx, [eax + HBA_PORT.command_issue] ; ebx = slots or ebx, [eax + HBA_PORT.command_issue] ; ebx = slots
mov esi, [ctr1_data.abar] ; why ctr1 ? TODO: make for corresponding controller mov esi, [esi + PORT_DATA.ctr_ptr]
mov esi, [esi + AHCI_CTR.abar]
mov edx, [esi + HBA_MEM.cap] mov edx, [esi + HBA_MEM.cap]
shr edx, 8 shr edx, 8
and edx, 0xf and edx, 0xf
@ -1395,6 +1411,7 @@ ahci_find_cmdslot:
.ret: .ret:
pop esi edx ecx ebx pop esi edx ecx ebx
ret ret
endp
proc _memset stdcall, dest:dword, val:byte, cnt:dword ; doesnt clobber any registers proc _memset stdcall, dest:dword, val:byte, cnt:dword ; doesnt clobber any registers

View File

@ -165,6 +165,7 @@ struct PORT_DATA
portno dd ? ; port index, 0..31 portno dd ? ; port index, 0..31
drive_type db ? ; drive type drive_type db ? ; drive type
sector_count dq ? ; number of sectors sector_count dq ? ; number of sectors
ctr_ptr dd ? ; pointer to controller to which port belongs
ends ends
; Register FIS Host to Device ; Register FIS Host to Device
@ -558,6 +559,8 @@ ahci_init:
imul ecx, sizeof.PORT_DATA imul ecx, sizeof.PORT_DATA
add ecx, AHCI_CTR.port_data_arr add ecx, AHCI_CTR.port_data_arr
add ecx, [ctr_ptr] add ecx, [ctr_ptr]
mov eax, [ctr_ptr]
mov [ecx + PORT_DATA.ctr_ptr], eax ; to which controller the port belongs
stdcall ahci_port_rebase, edi, ebx, ecx stdcall ahci_port_rebase, edi, ebx, ecx
; DEBUGF 1, "K: AHCI: After REBASING, signature = 0x%x\n", [edi + HBA_PORT.signature] ; DEBUGF 1, "K: AHCI: After REBASING, signature = 0x%x\n", [edi + HBA_PORT.signature]
@ -662,10 +665,7 @@ proc ahci_port_identify stdcall, pdata: dword
pushad pushad
mov esi, [pdata] ; esi - address of PORT_DATA struct of port 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 stdcall ahci_find_cmdslot, esi
mov eax, edi
call ahci_find_cmdslot
cmp eax, -1 cmp eax, -1
jne .cmdslot_found jne .cmdslot_found
@ -724,6 +724,8 @@ proc ahci_port_identify stdcall, pdata: dword
@@: @@:
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 0 mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 0
mov edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
; Wait on previous command to complete, before issuing new command. ; Wait on previous command to complete, before issuing new command.
stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT
; DEBUGF 1, "eax = %x\n", eax ; DEBUGF 1, "eax = %x\n", eax
@ -808,9 +810,7 @@ proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, nums
DEBUGF AHCI_DBGLVL, " ahci_rw_sectors: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u, is_write = %u\n", [vbuf], [startsector], [startsector + 4], [numsectors], [is_write]:1 DEBUGF AHCI_DBGLVL, " ahci_rw_sectors: buffer = 0x%x, startsector = 0x%x:%x, numsectors = %u, is_write = %u\n", [vbuf], [startsector], [startsector + 4], [numsectors], [is_write]:1
mov esi, [pdata] ; esi - address of PORT_DATA struct of port 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 stdcall ahci_find_cmdslot, esi
mov eax, edi
call ahci_find_cmdslot
cmp eax, -1 cmp eax, -1
jne .cmdslot_found jne .cmdslot_found
@ -998,6 +998,8 @@ proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, nums
shr ebx, 8 shr ebx, 8
mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.counth], bl mov byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.counth], bl
mov edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
; Wait on previous command to complete, before issuing new command. ; Wait on previous command to complete, before issuing new command.
stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT stdcall ahci_port_wait, edi, AHCI_PORT_TIMEOUT
@ -1050,7 +1052,9 @@ proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsecto
pushad pushad
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_lock call mutex_lock
mov eax, [numsectors_ptr] mov eax, [numsectors_ptr]
@ -1088,7 +1092,9 @@ proc ahci_read stdcall pdata: dword, buffer: dword, startsector: qword, numsecto
jmp .read_loop jmp .read_loop
.read_loop_end: .read_loop_end:
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_unlock call mutex_unlock
popad popad
@ -1105,7 +1111,9 @@ proc ahci_write stdcall pdata: dword, buffer: dword, startsector: qword, numsect
pushad pushad
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_lock call mutex_lock
mov eax, [numsectors_ptr] mov eax, [numsectors_ptr]
@ -1134,7 +1142,9 @@ proc ahci_write stdcall pdata: dword, buffer: dword, startsector: qword, numsect
jmp .write_loop jmp .write_loop
.write_loop_end: .write_loop_end:
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller mov ecx, [pdata]
mov ecx, [ecx + PORT_DATA.ctr_ptr]
mov ecx, [ecx + AHCI_CTR.mutex]
call mutex_unlock call mutex_unlock
popad popad
@ -1251,6 +1261,8 @@ endp
; in: port - address of HBA_PORT structure ; in: port - address of HBA_PORT structure
; portno - port index (0..31) ; portno - port index (0..31)
; pdata - address of PORT_DATA structure ; pdata - address of PORT_DATA structure
; out:
; rebases port and fills pdata with mappings
proc ahci_port_rebase stdcall, port: dword, portno: dword, pdata: dword proc ahci_port_rebase stdcall, port: dword, portno: dword, pdata: dword
locals locals
phys_page1 dd ? phys_page1 dd ?
@ -1360,15 +1372,19 @@ endp
; ----------------------------------------------------------- ; TODO check ; ----------------------------------------------------------- ; TODO check
; Find a free command list slot ; Find a free command list slot
; in: eax - address of HBA_PORT structure ; in: pdata - address of HBA_PORT structure
; out: eax - if not found -1, else slot index ; out: eax - if not found -1, else slot index
ahci_find_cmdslot: proc ahci_find_cmdslot stdcall, pdata: dword
push ebx ecx edx esi push ebx ecx edx esi
mov esi, [pdata]
mov eax, [esi + PORT_DATA.port]
; If not set in SACT and CI, the slot is free ; If not set in SACT and CI, the slot is free
mov ebx, [eax + HBA_PORT.sata_active] mov ebx, [eax + HBA_PORT.sata_active]
or ebx, [eax + HBA_PORT.command_issue] ; ebx = slots or ebx, [eax + HBA_PORT.command_issue] ; ebx = slots
mov esi, [ctr1_data.abar] ; why ctr1 ? TODO: make for corresponding controller mov esi, [esi + PORT_DATA.ctr_ptr]
mov esi, [esi + AHCI_CTR.abar]
mov edx, [esi + HBA_MEM.cap] mov edx, [esi + HBA_MEM.cap]
shr edx, 8 shr edx, 8
and edx, 0xf and edx, 0xf
@ -1395,6 +1411,7 @@ ahci_find_cmdslot:
.ret: .ret:
pop esi edx ecx ebx pop esi edx ecx ebx
ret ret
endp
proc _memset stdcall, dest:dword, val:byte, cnt:dword ; doesnt clobber any registers proc _memset stdcall, dest:dword, val:byte, cnt:dword ; doesnt clobber any registers