83,11 → 83,6 |
FIS_TYPE_PIO_SETUP = 0x5F ; PIO setup FIS - device to host |
FIS_TYPE_DEV_BITS = 0xA1 ; Set device bits FIS - device to host |
|
struct AHCI_DATA |
abar dd ? ; pointer to HBA Memory (BAR5) mapped to virtual kernelspace memory |
pcidev dd ? ; pointer to corresponding PCIDEV structure |
ends |
|
; Generic Host Control registers |
struct HBA_MEM |
cap dd ? ; 0x00, Host capabilities |
317,22 → 312,24 |
|
align 4 |
|
struct SD_DATA |
ahci_controller AHCI_DATA |
; AHCI controller structure |
struct AHCI_CTR |
abar dd ? ; pointer to HBA Memory (BAR5) mapped to virtual kernelspace memory |
pcidev dd ? ; pointer to corresponding PCIDEV structure |
port_data_arr rb (sizeof.PORT_DATA*AHCI_MAX_PORTS) |
ahci_mutex MUTEX |
mutex MUTEX |
ends |
|
sd1_data SD_DATA |
sd2_data SD_DATA |
sd3_data SD_DATA |
sd4_data SD_DATA |
sd5_data SD_DATA |
sd6_data SD_DATA |
sd7_data SD_DATA |
sd8_data SD_DATA |
ctr1_data AHCI_CTR |
ctr2_data AHCI_CTR |
ctr3_data AHCI_CTR |
ctr4_data AHCI_CTR |
ctr5_data AHCI_CTR |
ctr6_data AHCI_CTR |
ctr7_data AHCI_CTR |
ctr8_data AHCI_CTR |
|
sd_data dd ? |
ctr_ptr dd ? |
endg |
|
iglobal |
348,8 → 345,9 |
dd 0 ; use default cache size |
.end: |
hd_name db 'sd', 0, 0, 0 |
sd_counter dd 0 |
controllers_counter dd 0 |
sata_dev_counter dd 0 ; sata devices counter |
; TODO: satapi_dev_counter dd 0 ; satapi devices (optical drives) counter |
ctr_counter dd 0 ; controllers counter |
endg |
|
; ----------------------------------------------------------------------- |
356,11 → 354,9 |
; detect ahci controller and initialize |
align 4 |
ahci_init: |
|
mov ecx, sd1_data.ahci_controller |
mov esi, pcidev_list |
mov [sd_data], sd1_data |
mov [sd_counter], 0 |
mov [ctr_ptr], ctr1_data |
mov [sata_dev_counter], 0 |
.find_ahci_ctr: |
mov esi, [esi + PCIDEV.fd] |
cmp esi, pcidev_list |
379,13 → 375,12 |
.ahci_ctr_found: |
push esi |
|
mov ecx, [sd_data] |
add ecx, SD_DATA.ahci_mutex |
mov ecx, [ctr_ptr] |
add ecx, AHCI_CTR.mutex |
call mutex_init |
|
mov ecx, [sd_data] |
add ecx, SD_DATA.ahci_controller |
mov [ecx + AHCI_DATA.pcidev], esi |
mov ecx, [ctr_ptr] |
mov [ecx + AHCI_CTR.pcidev], esi |
|
mov eax, [esi+PCIDEV.class] |
movzx ebx, byte [esi+PCIDEV.bus] |
412,9 → 407,8 |
; Map MMIO region to virtual memory |
stdcall map_io_mem, edi, eax, PG_SWR + PG_NOCACHE |
push ecx |
mov ecx, [sd_data] |
add ecx, SD_DATA.ahci_controller |
mov [ecx + AHCI_DATA.abar], eax |
mov ecx, [ctr_ptr] |
mov [ecx + AHCI_CTR.abar], eax |
pop ecx |
DEBUGF 1, "K: AHCI controller BAR5 mapped to virtual addr %x\n", eax |
|
432,17 → 426,14 |
DEBUGF 1, "K: AHCI: pci_status_command = %x\n", eax |
stdcall pci_write32, ebx, ebp, PCI_REG_STATUS_COMMAND, eax |
|
mov esi, [ctr_ptr] |
mov esi, [esi + AHCI_CTR.abar] |
|
; ; Print some register values to debug board |
; mov esi, [[sd_data].ahci_controller + AHCI_DATA.abar] |
; DEBUGF 1, "K: AHCI: HBA.cap = %x, HBA.ghc = %x, HBA_MEM.version = %x\n", [esi + HBA_MEM.cap], [esi + HBA_MEM.ghc], [esi + HBA_MEM.version] |
|
;------------------------------------------------------- |
; Request BIOS/OS ownership handoff, if supported. (TODO check correctness) |
push ecx |
mov ecx, [sd_data] |
add ecx, SD_DATA.ahci_controller |
mov esi, [ecx + AHCI_DATA.abar] |
pop ecx |
;mov ebx, [esi + HBA_MEM.cap2] |
;DEBUGF 1, "K: AHCI: HBA_MEM.cap2 = %x\n", ebx |
bt [esi + HBA_MEM.cap2], bit_AHCI_HBA_CAP2_BOH |
565,8 → 556,8 |
|
mov ecx, ebx |
imul ecx, sizeof.PORT_DATA |
mov ecx, [sd_data] |
add ecx, SD_DATA.port_data_arr |
add ecx, AHCI_CTR.port_data_arr |
add ecx, [ctr_ptr] |
stdcall ahci_port_rebase, edi, ebx, ecx |
|
; DEBUGF 1, "K: AHCI: After REBASING, signature = 0x%x\n", [edi + HBA_PORT.signature] |
605,11 → 596,11 |
;stdcall ahci_read_first_sector, ecx |
|
push ecx |
mov eax, [sd_counter] |
inc [sd_counter] |
mov eax, [sata_dev_counter] |
inc [sata_dev_counter] |
xor edx, edx |
mov ecx, 10 |
div ecx ; eax = sd_counter / 10, edx = sd_counter % 10 |
div ecx ; eax = sata_dev_counter / 10, edx = sata_dev_counter % 10 |
test eax, eax |
jz .concat_one |
add al, '0' |
648,9 → 639,9 |
|
.end_detect_drives: |
pop esi |
add [sd_data], sizeof.SD_DATA |
inc [controllers_counter] |
cmp [controllers_counter], 8 |
add [ctr_ptr], sizeof.AHCI_CTR |
inc [ctr_counter] |
cmp [ctr_counter], 8 |
jnz .find_ahci_ctr |
DEBUGF 1, "AHCI: reached controllers number limit\n" |
ret |
792,7 → 783,7 |
ret |
endp |
|
; Read/write sectors |
; Read/write sectors, note: currently work for SATA, not SATAPI |
; return value: 0 = success, otherwise = error |
proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, numsectors: dword, is_write: dword |
locals |
1059,7 → 1050,7 |
|
pushad |
|
mov ecx, sd1_data.ahci_mutex |
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
call mutex_lock |
|
mov eax, [numsectors_ptr] |
1097,7 → 1088,7 |
jmp .read_loop |
.read_loop_end: |
|
mov ecx, sd1_data.ahci_mutex |
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
call mutex_unlock |
|
popad |
1114,7 → 1105,7 |
|
pushad |
|
mov ecx, sd1_data.ahci_mutex |
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
call mutex_lock |
|
mov eax, [numsectors_ptr] |
1143,7 → 1134,7 |
jmp .write_loop |
.write_loop_end: |
|
mov ecx, sd1_data.ahci_mutex |
mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
call mutex_unlock |
|
popad |
1377,7 → 1368,7 |
mov ebx, [eax + HBA_PORT.sata_active] |
or ebx, [eax + HBA_PORT.command_issue] ; ebx = slots |
|
mov esi, [sd1_data.ahci_controller + AHCI_DATA.abar] |
mov esi, [ctr1_data.abar] ; why ctr1 ? TODO: make for corresponding controller |
mov edx, [esi + HBA_MEM.cap] |
shr edx, 8 |
and edx, 0xf |