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 |