Subversion Repositories Kolibri OS

Rev

Rev 9072 | Rev 9130 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9072 Rev 9074
Line 25... Line 25...
25
bit_AHCI_HBA_PxCMD_ST    = 0
25
bit_AHCI_HBA_PxCMD_ST    = 0
26
bit_AHCI_HBA_PxCMD_FRE   = 4
26
bit_AHCI_HBA_PxCMD_FRE   = 4
27
bit_AHCI_HBA_PxCMD_FR    = 14
27
bit_AHCI_HBA_PxCMD_FR    = 14
28
bit_AHCI_HBA_PxCMD_CR    = 15
28
bit_AHCI_HBA_PxCMD_CR    = 15
Line -... Line 29...
-
 
29
 
-
 
30
bit_AHCI_H2D_FLAG_CMD    = 7
29
 
31
 
30
AHCI_HBA_PxSSTS_DET         = 0xF
32
AHCI_HBA_PxSSTS_DET         = 0xF
31
AHCI_HBA_PORT_IPM_ACTIVE    = 1
33
AHCI_HBA_PORT_IPM_ACTIVE    = 1
Line 32... Line 34...
32
AHCI_HBA_PxSSTS_DET_PRESENT = 3
34
AHCI_HBA_PxSSTS_DET_PRESENT = 3
Line 88... Line 90...
88
        fis_based_switch_control dd ?                 ; 0x40
90
        fis_based_switch_control dd ?                 ; 0x40
89
        reserved1                rd 11                ; 0x44 - 0x6F
91
        reserved1                rd 11                ; 0x44 - 0x6F
90
        vendor                   rd 4                 ; 0x70 - 0x7F, vendor specific
92
        vendor                   rd 4                 ; 0x70 - 0x7F, vendor specific
91
ends
93
ends
Line 92... Line 94...
92
 
94
 
93
; Command header structure
95
; Command header structure, size = 32 bytes
94
struct HBA_CMD_HDR
96
struct HBA_CMD_HDR
95
    _flags1       db ? ; 0bPWACCCCC, P - Prefetchable, W - Write (1: H2D, 0: D2H)
97
    _flags1       db ? ; 0bPWACCCCC, P - Prefetchable, W - Write (1: H2D, 0: D2H)
Line 96... Line 98...
96
                       ; A - ATAPI, C - Command FIS length in DWORDS, 2 ~ 16
98
                       ; A - ATAPI, C - Command FIS length in DWORDS, 2 ~ 16
Line 103... Line 105...
103
    ctba          dd ? ; Command table descriptor base address
105
    ctba          dd ? ; Command table descriptor base address
104
    ctbau         dd ? ; Command table descriptor base address upper 32 bits
106
    ctbau         dd ? ; Command table descriptor base address upper 32 bits
105
                  rd 4 ; Reserved
107
                  rd 4 ; Reserved
106
ends
108
ends
Line -... Line 109...
-
 
109
 
107
 
110
; Physical region descriptor table entry, size = 16 bytes
108
struct HBA_PRDT_ENTRY
111
struct HBA_PRDT_ENTRY
109
    dba           dd ?  ; Data base address
112
    dba           dd ?  ; Data base address
110
    dbau          dd ?  ; Data base address upper 32 bits
113
    dbau          dd ?  ; Data base address upper 32 bits
111
                  dd ?  ; Reserved
114
                  dd ?  ; Reserved
Line 125... Line 128...
125
struct PORT_DATA
128
struct PORT_DATA
126
    clb           dd ? ; Command list base
129
    clb           dd ? ; Command list base
127
    fb            dd ? ; FIS base
130
    fb            dd ? ; FIS base
128
    ctba_arr      rd 32 ; ctba_arr[0] = clb[0].ctba, ... and so on.
131
    ctba_arr      rd 32 ; ctba_arr[0] = clb[0].ctba, ... and so on.
129
    port          dd ? ; address of correspoding HBA_PORT structure
132
    port          dd ? ; address of correspoding HBA_PORT structure
-
 
133
    portno        dd ? ; port index, 0..31
130
ends
134
ends
Line 131... Line 135...
131
 
135
 
132
; Register FIS – Host to Device
136
; Register FIS – Host to Device
133
struct FIS_REG_H2D
137
struct FIS_REG_H2D
Line 406... Line 410...
406
        mov     ecx, [esi + HBA_MEM.pi]
410
        mov     ecx, [esi + HBA_MEM.pi]
407
        bt      ecx, ebx
411
        bt      ecx, ebx
408
        jnc     .continue_detect_drives
412
        jnc     .continue_detect_drives
Line 409... Line 413...
409
 
413
 
410
        mov     edi, ebx
414
        mov     edi, ebx
411
        shl     edi, BSF sizeof.HBA_PORT
415
        imul    edi, sizeof.HBA_PORT
412
        add     edi, HBA_MEM.ports
416
        add     edi, HBA_MEM.ports
413
        add     edi, esi
417
        add     edi, esi
Line 414... Line 418...
414
        ; now edi - base of HBA_MEM.ports[ebx]
418
        ; now edi - base of HBA_MEM.ports[ebx]
Line 427... Line 431...
427
        jne     .continue_detect_drives
431
        jne     .continue_detect_drives
Line 428... Line 432...
428
 
432
 
Line 429... Line 433...
429
        DEBUGF  1, "K: AHCI: found drive at port %d, signature = %x\n", ebx, [edi + HBA_PORT.signature]  
433
        DEBUGF  1, "K: AHCI: found drive at port %d, signature = %x\n", ebx, [edi + HBA_PORT.signature]  
430
 
434
 
431
        mov     ecx, ebx
435
        mov     ecx, ebx
432
        shl     ecx, BSF sizeof.PORT_DATA
436
        imul    ecx, sizeof.PORT_DATA
Line -... Line 437...
-
 
437
        add     ecx, port_data_arr
-
 
438
        stdcall ahci_port_rebase, edi, ebx, ecx
433
        add     ecx, port_data_arr
439
 
434
        stdcall ahci_port_rebase, edi, ebx, ecx
440
        stdcall ahci_port_identify, ecx
435
 
441
 
Line 443... Line 449...
443
        
449
        
444
 
450
 
Line -... Line 451...
-
 
451
        ret
-
 
452
; -------------------------------------------------
-
 
453
 
-
 
454
modelstr  rb 42
-
 
455
; Identify drive on port ; TODO check
-
 
456
; in: pdata - address of PORT_DATA structure
-
 
457
proc ahci_port_identify stdcall, pdata: dword
-
 
458
        locals
-
 
459
            cmdslot dd ?
-
 
460
            cmdheader dd ?
-
 
461
            cmdtable  dd ?
-
 
462
            buf_phys  dd ?
-
 
463
            buf_virt  dd ?
-
 
464
        endl
-
 
465
 
-
 
466
        pushad
-
 
467
        
-
 
468
        mov     esi, [pdata] ; esi - address of PORT_DATA struct of port
-
 
469
        mov     edi, [esi + PORT_DATA.port] ; edi - address of HBA_PORT struct of port
-
 
470
 
-
 
471
        mov     eax, edi
-
 
472
        call    ahci_find_cmdslot
-
 
473
 
-
 
474
        cmp     eax, -1
-
 
475
        jne      .cmdslot_found
-
 
476
 
-
 
477
        DEBUGF  1, "No free cmdslot on port %u\n", [esi + PORT_DATA.portno]
-
 
478
 
-
 
479
.cmdslot_found:
-
 
480
        mov     [cmdslot], eax
-
 
481
        DEBUGF  1, "Found free cmdslot %u on port %u\n", [cmdslot], [esi + PORT_DATA.portno]
-
 
482
 
-
 
483
        shl     eax, BSF sizeof.HBA_CMD_HDR
-
 
484
        add     eax, [esi + PORT_DATA.clb]
-
 
485
        mov     [cmdheader], eax ; address of virtual mapping of command header
-
 
486
        mov     eax, [cmdslot]
-
 
487
        mov     eax, [esi + eax*4 + PORT_DATA.ctba_arr]
-
 
488
        mov     [cmdtable], eax ; address of virtual mapping of command table of command header
-
 
489
 
-
 
490
        stdcall _memset, eax, 0, sizeof.HBA_CMD_TBL
-
 
491
 
-
 
492
        call    alloc_page
-
 
493
        mov     [buf_phys], eax
-
 
494
 
-
 
495
        stdcall map_io_mem, eax, 4096, PG_NOCACHE + PG_SWR  ; map to virt memory so we can work with it
-
 
496
        mov     [buf_virt], eax
-
 
497
 
-
 
498
        mov     eax, [cmdtable]
-
 
499
        mov     ebx, [buf_phys]
-
 
500
        mov     dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.dba], ebx
-
 
501
        mov     dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY.dbau], 0
-
 
502
        mov     dword [eax + HBA_CMD_TBL.prdt_entry + HBA_PRDT_ENTRY._flags], 512 - 1 ; why -1 ?
-
 
503
        mov     eax, [cmdheader]
-
 
504
        mov     [eax + HBA_CMD_HDR.prdtl], 1
-
 
505
 
-
 
506
        mov     eax, [cmdtable]
-
 
507
        mov     byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.fis_type], FIS_TYPE_REG_H2D
-
 
508
        movzx   ebx, byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D._flags]
-
 
509
        bts     ebx, bit_AHCI_H2D_FLAG_CMD ; Set Command bit in H2D FIS.
-
 
510
        mov     byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D._flags], bl
-
 
511
        ; if (port->signature == AHCI_PxSIG_ATAPI) cmd_fis->command = ATA_IDENTIFY_PACKET;
-
 
512
        ; else cmd_fis->command = ATA_IDENTIFY;
-
 
513
        mov     byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.command], 0xEC ;ATA_IDENTIFY ; 
-
 
514
        mov     byte [eax + HBA_CMD_TBL.cfis + FIS_REG_H2D.device], 0
-
 
515
 
-
 
516
        ; TODO Wait on previous command to complete. AHCIPortWait(bd->port_num, tS + 2);
-
 
517
        mov     ebx, 20 ;;;
-
 
518
        call    delay_hs ;;;
-
 
519
 
-
 
520
        mov     eax, [cmdslot]
-
 
521
        bts     [edi + HBA_PORT.command_issue], eax ; Issue the command
-
 
522
 
-
 
523
        ; TODO AHCIPortCmdWait(bd->port_num, cmd_slot);
-
 
524
        mov     ebx, 20 ;;;
-
 
525
        call    delay_hs ;;;
-
 
526
 
-
 
527
        mov     esi, [buf_virt]
-
 
528
        add     esi, 27*2
-
 
529
        mov     edi, modelstr
-
 
530
        mov     ecx, ((46-27)+1)*2
-
 
531
        cld
-
 
532
        rep movsb
-
 
533
        mov     byte [edi], 0
-
 
534
        
-
 
535
        xor     ecx, ecx
-
 
536
.reverse1:
-
 
537
        cmp     ecx, ((46-27)+1)*2
-
 
538
        jae     .reverse1_end
-
 
539
        mov     bl, byte [modelstr + ecx]
-
 
540
        mov     dl, byte [modelstr + ecx + 1]
-
 
541
        mov     byte [modelstr + ecx], dl
-
 
542
        mov     byte [modelstr + ecx + 1], bl
-
 
543
        add     ecx, 2
-
 
544
        jmp     .reverse1
-
 
545
.reverse1_end:
-
 
546
        DEBUGF  1, "Ident data of port: model = %s\n", modelstr
-
 
547
 
-
 
548
.ret:
-
 
549
        popad
445
        ret
550
        ret
446
; -------------------------------------------------
551
endp
447
 
552
 
448
; Start command engine
553
; Start command engine
449
; in: eax - address of HBA_PORT structure
554
; in: eax - address of HBA_PORT structure
Line 533... Line 638...
533
        mov     ebx, [virt_page1]
638
        mov     ebx, [virt_page1]
534
        mov     [edi + PORT_DATA.clb], ebx ; set pdata->clb
639
        mov     [edi + PORT_DATA.clb], ebx ; set pdata->clb
Line 535... Line 640...
535
 
640
 
536
        mov     eax, [port]
641
        mov     eax, [port]
-
 
642
        mov     [edi + PORT_DATA.port], eax ; set pdata->port
-
 
643
        mov     eax, [portno]               ; set pdata->portno
Line 537... Line 644...
537
        mov     [edi + PORT_DATA.port], eax ; set pdata->port
644
        mov     [edi + PORT_DATA.portno], eax
Line 538... Line 645...
538
 
645
 
539
        stdcall _memset, ebx, 0, 1024 ; zero out the command list
646
        stdcall _memset, ebx, 0, 1024 ; zero out the command list