Rev 9264 | Rev 9272 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9264 | Rev 9271 | ||
---|---|---|---|
Line 81... | Line 81... | ||
81 | FIS_TYPE_DATA = 0x46 ; Data FIS - bidirectional |
81 | FIS_TYPE_DATA = 0x46 ; Data FIS - bidirectional |
82 | FIS_TYPE_BIST = 0x58 ; BIST activate FIS - bidirectional |
82 | FIS_TYPE_BIST = 0x58 ; BIST activate FIS - bidirectional |
83 | FIS_TYPE_PIO_SETUP = 0x5F ; PIO setup FIS - device to host |
83 | FIS_TYPE_PIO_SETUP = 0x5F ; PIO setup FIS - device to host |
84 | FIS_TYPE_DEV_BITS = 0xA1 ; Set device bits FIS - device to host |
84 | FIS_TYPE_DEV_BITS = 0xA1 ; Set device bits FIS - device to host |
Line 85... | Line -... | ||
85 | - | ||
86 | struct AHCI_DATA |
- | |
87 | abar dd ? ; pointer to HBA Memory (BAR5) mapped to virtual kernelspace memory |
- | |
88 | pcidev dd ? ; pointer to corresponding PCIDEV structure |
- | |
89 | ends |
- | |
90 | 85 | ||
91 | ; Generic Host Control registers |
86 | ; Generic Host Control registers |
92 | struct HBA_MEM |
87 | struct HBA_MEM |
93 | cap dd ? ; 0x00, Host capabilities |
88 | cap dd ? ; 0x00, Host capabilities |
94 | ghc dd ? ; 0x04, Global host control |
89 | ghc dd ? ; 0x04, Global host control |
Line 315... | Line 310... | ||
315 | ; -------------------------------------------------- |
310 | ; -------------------------------------------------- |
316 | uglobal |
311 | uglobal |
Line 317... | Line 312... | ||
317 | 312 | ||
Line -... | Line 313... | ||
- | 313 | align 4 |
|
318 | align 4 |
314 | |
- | 315 | ; AHCI controller structure |
|
319 | 316 | struct AHCI_CTR |
|
320 | struct SD_DATA |
317 | abar dd ? ; pointer to HBA Memory (BAR5) mapped to virtual kernelspace memory |
321 | ahci_controller AHCI_DATA |
318 | pcidev dd ? ; pointer to corresponding PCIDEV structure |
322 | port_data_arr rb (sizeof.PORT_DATA*AHCI_MAX_PORTS) |
319 | port_data_arr rb (sizeof.PORT_DATA*AHCI_MAX_PORTS) |
Line 323... | Line 320... | ||
323 | ahci_mutex MUTEX |
320 | mutex MUTEX |
324 | ends |
321 | ends |
325 | 322 | ||
326 | sd1_data SD_DATA |
323 | ctr1_data AHCI_CTR |
327 | sd2_data SD_DATA |
324 | ctr2_data AHCI_CTR |
328 | sd3_data SD_DATA |
325 | ctr3_data AHCI_CTR |
329 | sd4_data SD_DATA |
326 | ctr4_data AHCI_CTR |
330 | sd5_data SD_DATA |
327 | ctr5_data AHCI_CTR |
Line 331... | Line 328... | ||
331 | sd6_data SD_DATA |
328 | ctr6_data AHCI_CTR |
332 | sd7_data SD_DATA |
329 | ctr7_data AHCI_CTR |
Line 333... | Line 330... | ||
333 | sd8_data SD_DATA |
330 | ctr8_data AHCI_CTR |
334 | 331 | ||
335 | sd_data dd ? |
332 | ctr_ptr dd ? |
Line 346... | Line 343... | ||
346 | dd ahci_write |
343 | dd ahci_write |
347 | dd 0 ; no flush function |
344 | dd 0 ; no flush function |
348 | dd 0 ; use default cache size |
345 | dd 0 ; use default cache size |
349 | .end: |
346 | .end: |
350 | hd_name db 'sd', 0, 0, 0 |
347 | hd_name db 'sd', 0, 0, 0 |
351 | sd_counter dd 0 |
348 | sata_dev_counter dd 0 ; sata devices counter |
- | 349 | ; TODO: satapi_dev_counter dd 0 ; satapi devices (optical drives) counter |
|
352 | controllers_counter dd 0 |
350 | ctr_counter dd 0 ; controllers counter |
353 | endg |
351 | endg |
Line 354... | Line 352... | ||
354 | 352 | ||
355 | ; ----------------------------------------------------------------------- |
353 | ; ----------------------------------------------------------------------- |
356 | ; detect ahci controller and initialize |
354 | ; detect ahci controller and initialize |
357 | align 4 |
355 | align 4 |
358 | ahci_init: |
- | |
359 | - | ||
360 | mov ecx, sd1_data.ahci_controller |
356 | ahci_init: |
361 | mov esi, pcidev_list |
357 | mov esi, pcidev_list |
362 | mov [sd_data], sd1_data |
358 | mov [ctr_ptr], ctr1_data |
363 | mov [sd_counter], 0 |
359 | mov [sata_dev_counter], 0 |
364 | .find_ahci_ctr: |
360 | .find_ahci_ctr: |
365 | mov esi, [esi + PCIDEV.fd] |
361 | mov esi, [esi + PCIDEV.fd] |
366 | cmp esi, pcidev_list |
362 | cmp esi, pcidev_list |
367 | jz .ahci_ctr_not_found |
363 | jz .ahci_ctr_not_found |
Line 377... | Line 373... | ||
377 | ret |
373 | ret |
Line 378... | Line 374... | ||
378 | 374 | ||
379 | .ahci_ctr_found: |
375 | .ahci_ctr_found: |
Line 380... | Line 376... | ||
380 | push esi |
376 | push esi |
381 | 377 | ||
382 | mov ecx, [sd_data] |
378 | mov ecx, [ctr_ptr] |
Line 383... | Line 379... | ||
383 | add ecx, SD_DATA.ahci_mutex |
379 | add ecx, AHCI_CTR.mutex |
384 | call mutex_init |
- | |
385 | 380 | call mutex_init |
|
Line 386... | Line 381... | ||
386 | mov ecx, [sd_data] |
381 | |
387 | add ecx, SD_DATA.ahci_controller |
382 | mov ecx, [ctr_ptr] |
388 | mov [ecx + AHCI_DATA.pcidev], esi |
383 | mov [ecx + AHCI_CTR.pcidev], esi |
389 | 384 | ||
Line 410... | Line 405... | ||
410 | DEBUGF 1, "K: AHCI: MMIO region size = 0x%x bytes\n", eax |
405 | DEBUGF 1, "K: AHCI: MMIO region size = 0x%x bytes\n", eax |
Line 411... | Line 406... | ||
411 | 406 | ||
412 | ; Map MMIO region to virtual memory |
407 | ; Map MMIO region to virtual memory |
413 | stdcall map_io_mem, edi, eax, PG_SWR + PG_NOCACHE |
408 | stdcall map_io_mem, edi, eax, PG_SWR + PG_NOCACHE |
414 | push ecx |
409 | push ecx |
415 | mov ecx, [sd_data] |
- | |
416 | add ecx, SD_DATA.ahci_controller |
410 | mov ecx, [ctr_ptr] |
417 | mov [ecx + AHCI_DATA.abar], eax |
411 | mov [ecx + AHCI_CTR.abar], eax |
418 | pop ecx |
412 | pop ecx |
Line 419... | Line 413... | ||
419 | DEBUGF 1, "K: AHCI controller BAR5 mapped to virtual addr %x\n", eax |
413 | DEBUGF 1, "K: AHCI controller BAR5 mapped to virtual addr %x\n", eax |
420 | 414 | ||
Line 430... | Line 424... | ||
430 | or eax, 0x06 ; pci.command |= 0x06 (dma bus mastering + memory space access) |
424 | or eax, 0x06 ; pci.command |= 0x06 (dma bus mastering + memory space access) |
431 | btr eax, 10 ; clear the "disable interrupts" bit |
425 | btr eax, 10 ; clear the "disable interrupts" bit |
432 | DEBUGF 1, "K: AHCI: pci_status_command = %x\n", eax |
426 | DEBUGF 1, "K: AHCI: pci_status_command = %x\n", eax |
433 | stdcall pci_write32, ebx, ebp, PCI_REG_STATUS_COMMAND, eax |
427 | stdcall pci_write32, ebx, ebp, PCI_REG_STATUS_COMMAND, eax |
Line -... | Line 428... | ||
- | 428 | ||
- | 429 | mov esi, [ctr_ptr] |
|
- | 430 | mov esi, [esi + AHCI_CTR.abar] |
|
434 | 431 | ||
435 | ; ; Print some register values to debug board |
- | |
436 | ; mov esi, [[sd_data].ahci_controller + AHCI_DATA.abar] |
432 | ; ; Print some register values to debug board |
Line 437... | Line 433... | ||
437 | ; 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] |
433 | ; 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] |
438 | 434 | ||
439 | ;------------------------------------------------------- |
- | |
440 | ; Request BIOS/OS ownership handoff, if supported. (TODO check correctness) |
- | |
441 | push ecx |
- | |
442 | mov ecx, [sd_data] |
- | |
443 | add ecx, SD_DATA.ahci_controller |
- | |
444 | mov esi, [ecx + AHCI_DATA.abar] |
435 | ;------------------------------------------------------- |
445 | pop ecx |
436 | ; Request BIOS/OS ownership handoff, if supported. (TODO check correctness) |
446 | ;mov ebx, [esi + HBA_MEM.cap2] |
437 | ;mov ebx, [esi + HBA_MEM.cap2] |
447 | ;DEBUGF 1, "K: AHCI: HBA_MEM.cap2 = %x\n", ebx |
438 | ;DEBUGF 1, "K: AHCI: HBA_MEM.cap2 = %x\n", ebx |
448 | bt [esi + HBA_MEM.cap2], bit_AHCI_HBA_CAP2_BOH |
439 | bt [esi + HBA_MEM.cap2], bit_AHCI_HBA_CAP2_BOH |
Line 563... | Line 554... | ||
563 | 554 | ||
Line 564... | Line 555... | ||
564 | ; DEBUGF 1, "K: AHCI: found drive at port %d, cmd = 0x%x, ssts = 0x%x, signature = 0x%x\n", ebx, [edi + HBA_PORT.command], [edi + HBA_PORT.sata_status], [edi + HBA_PORT.signature] |
555 | ; DEBUGF 1, "K: AHCI: found drive at port %d, cmd = 0x%x, ssts = 0x%x, signature = 0x%x\n", ebx, [edi + HBA_PORT.command], [edi + HBA_PORT.sata_status], [edi + HBA_PORT.signature] |
565 | 556 | ||
566 | mov ecx, ebx |
557 | mov ecx, ebx |
567 | imul ecx, sizeof.PORT_DATA |
558 | imul ecx, sizeof.PORT_DATA |
568 | mov ecx, [sd_data] |
559 | add ecx, AHCI_CTR.port_data_arr |
Line 569... | Line 560... | ||
569 | add ecx, SD_DATA.port_data_arr |
560 | add ecx, [ctr_ptr] |
Line 570... | Line 561... | ||
570 | stdcall ahci_port_rebase, edi, ebx, ecx |
561 | stdcall ahci_port_rebase, edi, ebx, ecx |
Line 603... | Line 594... | ||
603 | ; register disk in system: |
594 | ; register disk in system: |
Line 604... | Line 595... | ||
604 | 595 | ||
Line 605... | Line 596... | ||
605 | ;stdcall ahci_read_first_sector, ecx |
596 | ;stdcall ahci_read_first_sector, ecx |
606 | 597 | ||
607 | push ecx |
598 | push ecx |
608 | mov eax, [sd_counter] |
599 | mov eax, [sata_dev_counter] |
609 | inc [sd_counter] |
600 | inc [sata_dev_counter] |
610 | xor edx, edx |
601 | xor edx, edx |
611 | mov ecx, 10 |
602 | mov ecx, 10 |
612 | div ecx ; eax = sd_counter / 10, edx = sd_counter % 10 |
603 | div ecx ; eax = sata_dev_counter / 10, edx = sata_dev_counter % 10 |
613 | test eax, eax |
604 | test eax, eax |
614 | jz .concat_one |
605 | jz .concat_one |
615 | add al, '0' |
606 | add al, '0' |
Line 646... | Line 637... | ||
646 | 637 | ||
647 | 638 | ||
648 | 639 | ||
649 | .end_detect_drives: |
640 | .end_detect_drives: |
650 | pop esi |
641 | pop esi |
651 | add [sd_data], sizeof.SD_DATA |
642 | add [ctr_ptr], sizeof.AHCI_CTR |
652 | inc [controllers_counter] |
643 | inc [ctr_counter] |
653 | cmp [controllers_counter], 8 |
644 | cmp [ctr_counter], 8 |
654 | jnz .find_ahci_ctr |
645 | jnz .find_ahci_ctr |
Line 790... | Line 781... | ||
790 | pop edx ecx |
781 | pop edx ecx |
791 | xor eax, eax |
782 | xor eax, eax |
792 | ret |
783 | ret |
793 | endp |
784 | endp |
Line 794... | Line 785... | ||
794 | 785 | ||
795 | ; Read/write sectors |
786 | ; Read/write sectors, note: currently work for SATA, not SATAPI |
796 | ; return value: 0 = success, otherwise = error |
787 | ; return value: 0 = success, otherwise = error |
797 | proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, numsectors: dword, is_write: dword |
788 | proc ahci_rw_sectors stdcall pdata: dword, vbuf: dword, startsector: qword, numsectors: dword, is_write: dword |
798 | locals |
789 | locals |
799 | cmdslot dd ? |
790 | cmdslot dd ? |
Line 1057... | Line 1048... | ||
1057 | numsectors dd ? |
1048 | numsectors dd ? |
1058 | endl |
1049 | endl |
Line 1059... | Line 1050... | ||
1059 | 1050 | ||
Line 1060... | Line 1051... | ||
1060 | pushad |
1051 | pushad |
1061 | 1052 | ||
Line 1062... | Line 1053... | ||
1062 | mov ecx, sd1_data.ahci_mutex |
1053 | mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
1063 | call mutex_lock |
1054 | call mutex_lock |
1064 | 1055 | ||
Line 1095... | Line 1086... | ||
1095 | adc dword [startsector + 4], 0 |
1086 | adc dword [startsector + 4], 0 |
Line 1096... | Line 1087... | ||
1096 | 1087 | ||
1097 | jmp .read_loop |
1088 | jmp .read_loop |
Line 1098... | Line 1089... | ||
1098 | .read_loop_end: |
1089 | .read_loop_end: |
1099 | 1090 | ||
Line 1100... | Line 1091... | ||
1100 | mov ecx, sd1_data.ahci_mutex |
1091 | mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
1101 | call mutex_unlock |
1092 | call mutex_unlock |
1102 | 1093 | ||
Line 1112... | Line 1103... | ||
1112 | numsectors dd ? |
1103 | numsectors dd ? |
1113 | endl |
1104 | endl |
Line 1114... | Line 1105... | ||
1114 | 1105 | ||
Line 1115... | Line 1106... | ||
1115 | pushad |
1106 | pushad |
1116 | 1107 | ||
Line 1117... | Line 1108... | ||
1117 | mov ecx, sd1_data.ahci_mutex |
1108 | mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
1118 | call mutex_lock |
1109 | call mutex_lock |
1119 | 1110 | ||
Line 1141... | Line 1132... | ||
1141 | adc dword [startsector + 4], 0 |
1132 | adc dword [startsector + 4], 0 |
Line 1142... | Line 1133... | ||
1142 | 1133 | ||
1143 | jmp .write_loop |
1134 | jmp .write_loop |
Line 1144... | Line 1135... | ||
1144 | .write_loop_end: |
1135 | .write_loop_end: |
1145 | 1136 | ||
Line 1146... | Line 1137... | ||
1146 | mov ecx, sd1_data.ahci_mutex |
1137 | mov ecx, ctr1_data.mutex ; why ctr1 ? TODO: make for corresponding controller |
1147 | call mutex_unlock |
1138 | call mutex_unlock |
1148 | 1139 | ||
Line 1375... | Line 1366... | ||
1375 | push ebx ecx edx esi |
1366 | push ebx ecx edx esi |
1376 | ; If not set in SACT and CI, the slot is free |
1367 | ; If not set in SACT and CI, the slot is free |
1377 | mov ebx, [eax + HBA_PORT.sata_active] |
1368 | mov ebx, [eax + HBA_PORT.sata_active] |
1378 | or ebx, [eax + HBA_PORT.command_issue] ; ebx = slots |
1369 | or ebx, [eax + HBA_PORT.command_issue] ; ebx = slots |
Line 1379... | Line 1370... | ||
1379 | 1370 | ||
1380 | mov esi, [sd1_data.ahci_controller + AHCI_DATA.abar] |
1371 | mov esi, [ctr1_data.abar] ; why ctr1 ? TODO: make for corresponding controller |
1381 | mov edx, [esi + HBA_MEM.cap] |
1372 | mov edx, [esi + HBA_MEM.cap] |
1382 | shr edx, 8 |
1373 | shr edx, 8 |
1383 | and edx, 0xf |
1374 | and edx, 0xf |
1384 | ; DEBUGF 1, "Number of Command Slots on each port = %u\n", edx |
1375 | ; DEBUGF 1, "Number of Command Slots on each port = %u\n", edx |