Subversion Repositories Kolibri OS

Rev

Rev 9023 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision$
  9.  
  10. PCI_REG_STATUS_COMMAND = 0x0004
  11. PCI_REG_BAR5 = 0x0024
  12.  
  13. AHCI_BOHCf_BOS  = 0        ; BIOS-Owned Semaphore (BIOS owns controller)
  14. AHCI_BOHCf_OOS  = 1        ; OS-Owned Semaphore (OS owns controller)
  15. AHCI_BOHCf_BB   = 4        ; BIOS Busy (polling bit while BIOS cleans up
  16.  
  17. AHCI_CAP2_BOH = 0          ; number of bit in BOH which shows Supports BIOS/OS Handoff
  18.  
  19. HBA_MEMORY_SIZE = 0x1100
  20.  
  21. struct AHCI_DATA
  22.         ;;
  23.         abar    dd ?       ; pointer to HBA Memory (BAR5) mapped to virtual kernelspace memory
  24.         pcidev  dd ?       ; pointer to corresponding PCIDEV structure
  25. ends
  26.  
  27. ; Generic Host Control registers
  28. struct HBA_MEM
  29.         capability            dd ?                    ; 0x00
  30.         global_host_control   dd ?                    ; 0x04
  31.         interrupt_status      dd ?                    ; 0x08
  32.         port_implemented      dd ?                    ; 0x0C
  33.         version               dd ?                    ; 0x10
  34.         ccc_ctl               dd ?                    ; 0x14, Command completion coalescing control
  35.         ccc_pts               dd ?                    ; 0x18, Command completion coalescing ports
  36.         em_loc                dd ?                    ; 0x1C, Enclosure management location
  37.         em_ctl                dd ?                    ; 0x20, Enclosure management control
  38.         capability2           dd ?                    ; 0x24, Host capabilities extended
  39.         bohc                  dd ?                    ; 0x28, BIOS/OS handoff control and status
  40.         reserved              rb (0xA0-0x2C)          ; 0x2C - 0x9F, Reserved
  41.         vendor                rb (0x100-0xA0)         ; 0xA0 - 0xFF, Vendor specific
  42.         ports                 rb (sizeof.HBA_PORT*32) ; 0x100 - 0x10FF, Port control registers, max 32
  43. ends
  44.  
  45. ; Port Control registers
  46. struct HBA_PORT
  47.         command_list_base_l      dd ?                 ; 0x00, command list base address, 1K-byte aligned
  48.         command_list_base_h      dd ?                 ; 0x04, command list base address upper 32 bits, used on 64 bit systems
  49.         fis_base_l               dd ?                 ; 0x08, FIS base address, 256-byte aligned
  50.         fis_base_h               dd ?                 ; 0x0C, FIS base address upper 32 bits, used on 64 bit systems
  51.         interrupt_status         dd ?                 ; 0x10
  52.         interrupt_enable         dd ?                 ; 0x14
  53.         command                  dd ?                 ; 0x18, command and status
  54.         reserved0                dd ?                 ; 0x1C
  55.         task_file_data           dd ?                 ; 0x20
  56.         signature                dd ?                 ; 0x24
  57.         sata_status              dd ?                 ; 0x28, SATA status (SCR0:SStatus)
  58.         sata_control             dd ?                 ; 0x2C, SATA control (SCR2:SControl)
  59.         sata_error               dd ?                 ; 0x30, SATA error (SCR1:SError)
  60.         sata_active              dd ?                 ; 0x34, SATA active (SCR3:SActive)
  61.         command_issue            dd ?                 ; 0x38
  62.         sata_notification        dd ?                 ; 0x3C, SATA notification (SCR4:SNotification)
  63.         fis_based_switch_control dd ?                 ; 0x40
  64.         reserved1                rd 11                ; 0x44 - 0x6F
  65.         vendor                   rd 4                 ; 0x70 - 0x7F, vendor specific
  66. ends
  67.  
  68. uglobal
  69. align 4
  70.         ahci_controller AHCI_DATA
  71. endg
  72.  
  73.  
  74. ; detect ahci controller and initialize
  75. align 4
  76. init_ahci:
  77.         mov     ecx, ahci_controller
  78.         mov     esi, pcidev_list
  79. .find_ahci_ctr:
  80.         mov     esi, [esi + PCIDEV.fd]
  81.         cmp     esi, pcidev_list
  82.         jz      .ahci_ctr_not_found
  83.         mov     eax, [esi + PCIDEV.class]
  84.         ;DEBUGF  1, "K: device class = %x\n", eax
  85.         shr     eax, 8 ; shift right because lowest 8 bits if ProgIf field
  86.         cmp     eax, 0x0106 ; 0x01 - Mass Storage Controller class,  0x06 - Serial ATA Controller subclass
  87.         jz      .ahci_ctr_found
  88.         jmp     .find_ahci_ctr
  89.  
  90. .ahci_ctr_not_found:
  91.         DEBUGF  1, "K: AHCI controller not found\n"
  92.         ret
  93.  
  94. .ahci_ctr_found:
  95.         mov     [ahci_controller + AHCI_DATA.pcidev], esi
  96.  
  97.         mov     eax, [esi+PCIDEV.class]
  98.         movzx   ebx, byte [esi+PCIDEV.bus]
  99.         movzx   ecx, byte [esi+PCIDEV.devfn]
  100.         shr     ecx, 3 ; get rid of 3 lowest bits (function code), the rest bits is device code
  101.         movzx   edx, byte [esi+PCIDEV.devfn]
  102.         and     edx, 00000111b ; get only 3 lowest bits (function code)
  103.         DEBUGF  1, "K: found AHCI controller, (class, subcl, progif) = %x, bus = %x, device = %x, function = %x\n", eax, ebx, ecx, edx
  104.        
  105.         mov     ah, [esi + PCIDEV.bus]
  106.         mov     al, 2 ; read dword
  107.         mov     bh, [esi + PCIDEV.devfn]
  108.         mov     bl, PCI_REG_BAR5
  109.         call    pci_read_reg
  110.         DEBUGF  1, "K: AHCI controller BAR5 = %x\n", eax
  111.  
  112.         stdcall map_io_mem, eax, HBA_MEMORY_SIZE, PG_SWR + PG_NOCACHE
  113.         mov     [ahci_controller + AHCI_DATA.abar], eax
  114.         DEBUGF  1, "K: AHCI controller BAR5 mapped to virtual addr %x\n", eax
  115.  
  116.         mov     ah, [esi + PCIDEV.bus]
  117.         mov     al, 2 ; read dword
  118.         mov     bh, [esi + PCIDEV.devfn]
  119.         mov     bl, PCI_REG_STATUS_COMMAND
  120.         call    pci_read_reg
  121.         DEBUGF  1, "K: AHCI: pci_status_command = %x\nEnabling interrupts, DMA bus mastering and memory space access\n", eax
  122.         or      eax, 0x06 ; pci.command |= 0x06 (dma bus mastering + memory space access)
  123.         btr     eax, 10 ; clear the "disable interrupts" bit
  124.         DEBUGF  1, "K: AHCI: pci_status_command = %x\n", eax
  125.         mov     ecx, eax
  126.         mov     ah, [esi + PCIDEV.bus]
  127.         mov     al, 2 ; write dword
  128.         mov     bh, [esi + PCIDEV.devfn]
  129.         mov     bl, PCI_REG_STATUS_COMMAND
  130.         call    pci_write_reg
  131.  
  132.         mov     eax, [ahci_controller + AHCI_DATA.abar]
  133.         mov     ebx, [eax + HBA_MEM.capability]
  134.         mov     ecx, [eax + HBA_MEM.global_host_control]
  135.         mov     edx, [eax + HBA_MEM.version]
  136.         DEBUGF  1, "K: AHCI: HBA.cap = %x, HBA.ghc = %x, HBA_MEM.version = %x\n", ebx, ecx, edx
  137.  
  138.         ; //Transferring ownership from BIOS if supported.
  139.         ; if (Bt(&hba->caps_ext, AHCI_CAPSEXTf_BOH))
  140.         ; {
  141.         ;       Bts(&hba->bohc, AHCI_BOHCf_OOS);
  142.         ;       "AHCI: Transferring ownership from BIOS\n";
  143.  
  144.         ;       while (Bt(&hba->bohc, AHCI_BOHCf_BOS));
  145.  
  146.         ;       Sleep(25);
  147.         ;       if (Bt(&hba->bohc, AHCI_BOHCf_BB)) //if Bios Busy is still set after 25 mS, wait 2 seconds.
  148.         ;               Sleep(2000);
  149.         ; }
  150.  
  151.         ; Transferring ownership from BIOS if supported. (TODO check)
  152.         mov     eax, [ahci_controller + AHCI_DATA.abar]
  153.         mov     ebx, [eax + HBA_MEM.capability2]
  154.         DEBUGF  1, "K: AHCI: HBA_MEM.cap2 = %x\n", ebx
  155.         bt      dword [eax + HBA_MEM.capability2], AHCI_CAP2_BOH
  156.         jnc     .end_handoff
  157.         DEBUGF  1, "K: AHCI: Transferring ownership from BIOS...\n"
  158.         bts     dword [eax + HBA_MEM.bohc], AHCI_BOHCf_OOS
  159.  
  160. .wait_not_bos:
  161.         bt      dword [eax + HBA_MEM.bohc], AHCI_BOHCf_BOS
  162.         jc      .wait_not_bos
  163.  
  164.         mov     ebx, 3
  165.         call    delay_hs
  166.  
  167.         ; if Bios Busy is still set after 25 mS, wait 2 seconds.
  168.         bt      dword [eax + HBA_MEM.bohc], AHCI_BOHCf_BB
  169.         jnc     @f
  170.  
  171.         mov     ebx, 200
  172.         call    delay_hs
  173. @@:
  174.         DEBUGF  1, "K: AHCI: Done.\n"
  175.  
  176. .end_handoff:
  177.  
  178.         ;; TODO: Reset controller ?
  179.  
  180.         ;; TODO enble AHCI ? (see https://github.com/ZenithOS/ZenithOS/blob/4ea8b133613ab95a8b53ed543d8e63525a21954e/src/Kernel/BlkDev/DiskAHCI.CC#L719)
  181.  
  182.         ;; TODO: find drives (see https://github.com/ZenithOS/ZenithOS/blob/4ea8b133613ab95a8b53ed543d8e63525a21954e/src/Kernel/BlkDev/DiskAHCI.CC#L742)
  183.  
  184.         ret
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.