Rev 9020 | Rev 9024 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9020 | Rev 9023 | ||
---|---|---|---|
Line 8... | Line 8... | ||
8 | $Revision$ |
8 | $Revision$ |
Line 9... | Line 9... | ||
9 | 9 | ||
10 | PCI_REG_STATUS_COMMAND = 0x0004 |
10 | PCI_REG_STATUS_COMMAND = 0x0004 |
Line -... | Line 11... | ||
- | 11 | PCI_REG_BAR5 = 0x0024 |
|
- | 12 | ||
- | 13 | ; bit_ prefix means that its index of bit |
|
- | 14 | ; format: bit_AHCI_STR_REG_BIT |
|
11 | PCI_REG_BAR5 = 0x0024 |
15 | bit_AHCI_HBA_CAP2_BOH = 0 ; Supports BIOS/OS Handoff |
12 | 16 | ||
13 | AHCI_BOHCf_BOS = 0 ; BIOS-Owned Semaphore (BIOS owns controller) |
17 | bit_AHCI_HBA_BOHC_BOS = 0 ; BIOS-Owned Semaphore (BIOS owns controller) |
14 | AHCI_BOHCf_OOS = 1 ; OS-Owned Semaphore (OS owns controller) |
18 | bit_AHCI_HBA_BOHC_OOS = 1 ; OS-Owned Semaphore (OS owns controller) |
- | 19 | bit_AHCI_HBA_BOHC_BB = 4 ; BIOS Busy (polling bit while BIOS cleans up |
|
- | 20 | ||
15 | AHCI_BOHCf_BB = 4 ; BIOS Busy (polling bit while BIOS cleans up |
21 | bit_AHCI_HBA_GHC_AHCI_ENABLE = 31 ; Enable AHCI mode |
Line -... | Line 22... | ||
- | 22 | bit_AHCI_HBA_GHC_RESET = 0 ; Reset HBA |
|
16 | 23 | bit_AHCI_HBA_GHC_INTERRUPT_ENABLE = 1 ; Enable interrupts from the HBA |
|
Line 17... | Line 24... | ||
17 | AHCI_CAP2_BOH = 0 ; number of bit in BOH which shows Supports BIOS/OS Handoff |
24 | |
18 | 25 | AHCI_MAX_PORTS = 32 ; |
|
19 | HBA_MEMORY_SIZE = 0x1100 |
26 | HBA_MEMORY_SIZE = 0x1100 |
Line 37... | Line 44... | ||
37 | em_ctl dd ? ; 0x20, Enclosure management control |
44 | em_ctl dd ? ; 0x20, Enclosure management control |
38 | capability2 dd ? ; 0x24, Host capabilities extended |
45 | capability2 dd ? ; 0x24, Host capabilities extended |
39 | bohc dd ? ; 0x28, BIOS/OS handoff control and status |
46 | bohc dd ? ; 0x28, BIOS/OS handoff control and status |
40 | reserved rb (0xA0-0x2C) ; 0x2C - 0x9F, Reserved |
47 | reserved rb (0xA0-0x2C) ; 0x2C - 0x9F, Reserved |
41 | vendor rb (0x100-0xA0) ; 0xA0 - 0xFF, Vendor specific |
48 | vendor rb (0x100-0xA0) ; 0xA0 - 0xFF, Vendor specific |
42 | ports rb (sizeof.HBA_PORT*32) ; 0x100 - 0x10FF, Port control registers, max 32 |
49 | ports rb (sizeof.HBA_PORT*AHCI_MAX_PORTS) ; 0x100 - 0x10FF, Port control registers, max AHCI_MAX_PORTS |
43 | ends |
50 | ends |
Line 44... | Line 51... | ||
44 | 51 | ||
45 | ; Port Control registers |
52 | ; Port Control registers |
46 | struct HBA_PORT |
53 | struct HBA_PORT |
Line 100... | Line 107... | ||
100 | shr ecx, 3 ; get rid of 3 lowest bits (function code), the rest bits is device code |
107 | shr ecx, 3 ; get rid of 3 lowest bits (function code), the rest bits is device code |
101 | movzx edx, byte [esi+PCIDEV.devfn] |
108 | movzx edx, byte [esi+PCIDEV.devfn] |
102 | and edx, 00000111b ; get only 3 lowest bits (function code) |
109 | 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 |
110 | DEBUGF 1, "K: found AHCI controller, (class, subcl, progif) = %x, bus = %x, device = %x, function = %x\n", eax, ebx, ecx, edx |
Line -... | Line 111... | ||
- | 111 | ||
104 | 112 | ; get BAR5 value, it is physical address |
|
105 | mov ah, [esi + PCIDEV.bus] |
113 | mov ah, [esi + PCIDEV.bus] |
106 | mov al, 2 ; read dword |
114 | mov al, 2 ; read dword |
107 | mov bh, [esi + PCIDEV.devfn] |
115 | mov bh, [esi + PCIDEV.devfn] |
108 | mov bl, PCI_REG_BAR5 |
116 | mov bl, PCI_REG_BAR5 |
109 | call pci_read_reg |
117 | call pci_read_reg |
Line -... | Line 118... | ||
- | 118 | DEBUGF 1, "K: AHCI controller BAR5 = %x\n", eax |
|
110 | DEBUGF 1, "K: AHCI controller BAR5 = %x\n", eax |
119 | |
111 | 120 | ; Map BAR5 to virtual memory |
|
112 | stdcall map_io_mem, eax, HBA_MEMORY_SIZE, PG_SWR + PG_NOCACHE |
121 | stdcall map_io_mem, eax, HBA_MEMORY_SIZE, PG_SWR + PG_NOCACHE |
Line -... | Line 122... | ||
- | 122 | mov [ahci_controller + AHCI_DATA.abar], eax |
|
- | 123 | DEBUGF 1, "K: AHCI controller BAR5 mapped to virtual addr %x\n", eax |
|
113 | mov [ahci_controller + AHCI_DATA.abar], eax |
124 | |
114 | DEBUGF 1, "K: AHCI controller BAR5 mapped to virtual addr %x\n", eax |
125 | ; Enable dma bus mastering, memory space access, clear the "disable interrupts" bit |
115 | 126 | ; Usually, it is already done before us |
|
116 | mov ah, [esi + PCIDEV.bus] |
127 | mov ah, [esi + PCIDEV.bus] |
117 | mov al, 2 ; read dword |
128 | mov al, 2 ; read dword |
Line 127... | Line 138... | ||
127 | mov al, 2 ; write dword |
138 | mov al, 2 ; write dword |
128 | mov bh, [esi + PCIDEV.devfn] |
139 | mov bh, [esi + PCIDEV.devfn] |
129 | mov bl, PCI_REG_STATUS_COMMAND |
140 | mov bl, PCI_REG_STATUS_COMMAND |
130 | call pci_write_reg |
141 | call pci_write_reg |
Line -... | Line 142... | ||
- | 142 | ||
131 | 143 | ; ; Print some register values to debug board |
|
132 | mov eax, [ahci_controller + AHCI_DATA.abar] |
144 | ; mov esi, [ahci_controller + AHCI_DATA.abar] |
133 | mov ebx, [eax + HBA_MEM.capability] |
145 | ; mov ebx, [esi + HBA_MEM.capability] |
134 | mov ecx, [eax + HBA_MEM.global_host_control] |
146 | ; mov ecx, [esi + HBA_MEM.global_host_control] |
135 | mov edx, [eax + HBA_MEM.version] |
147 | ; mov edx, [esi + HBA_MEM.version] |
136 | DEBUGF 1, "K: AHCI: HBA.cap = %x, HBA.ghc = %x, HBA_MEM.version = %x\n", ebx, ecx, edx |
148 | ; DEBUGF 1, "K: AHCI: HBA.cap = %x, HBA.ghc = %x, HBA_MEM.version = %x\n", ebx, ecx, edx |
137 | 149 | ||
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 | 150 | ;------------------------------------------------------- |
|
151 | ; Transferring ownership from BIOS if supported. (TODO check) |
151 | ; Request BIOS/OS ownership handoff, if supported. (TODO check correctness) |
152 | mov eax, [ahci_controller + AHCI_DATA.abar] |
152 | mov esi, [ahci_controller + AHCI_DATA.abar] |
153 | mov ebx, [eax + HBA_MEM.capability2] |
153 | ;mov ebx, [esi + HBA_MEM.capability2] |
154 | DEBUGF 1, "K: AHCI: HBA_MEM.cap2 = %x\n", ebx |
154 | ;DEBUGF 1, "K: AHCI: HBA_MEM.cap2 = %x\n", ebx |
155 | bt dword [eax + HBA_MEM.capability2], AHCI_CAP2_BOH |
155 | bt dword [esi + HBA_MEM.capability2], bit_AHCI_HBA_CAP2_BOH |
156 | jnc .end_handoff |
156 | jnc .end_handoff |
157 | DEBUGF 1, "K: AHCI: Transferring ownership from BIOS...\n" |
157 | DEBUGF 1, "K: AHCI: requesting AHCI ownership change...\n" |
Line 158... | Line 158... | ||
158 | bts dword [eax + HBA_MEM.bohc], AHCI_BOHCf_OOS |
158 | bts dword [esi + HBA_MEM.bohc], bit_AHCI_HBA_BOHC_OOS |
159 | 159 | ||
160 | .wait_not_bos: |
160 | .wait_not_bos: |
Line 161... | Line 161... | ||
161 | bt dword [eax + HBA_MEM.bohc], AHCI_BOHCf_BOS |
161 | bt dword [esi + HBA_MEM.bohc], bit_AHCI_HBA_BOHC_BOS |
162 | jc .wait_not_bos |
162 | jc .wait_not_bos |
Line 163... | Line 163... | ||
163 | 163 | ||
164 | mov ebx, 3 |
164 | mov ebx, 3 |
165 | call delay_hs |
165 | call delay_hs |
Line 166... | Line 166... | ||
166 | 166 | ||
167 | ; if Bios Busy is still set after 25 mS, wait 2 seconds. |
167 | ; if Bios Busy is still set after 30 mS, wait 2 seconds. |
168 | bt dword [eax + HBA_MEM.bohc], AHCI_BOHCf_BB |
168 | bt dword [esi + HBA_MEM.bohc], bit_AHCI_HBA_BOHC_BB |
169 | jnc @f |
169 | jnc @f |
Line 170... | Line 170... | ||
170 | 170 | ||
- | 171 | mov ebx, 200 |
|
Line -... | Line 172... | ||
- | 172 | call delay_hs |
|
- | 173 | @@: |
|
- | 174 | DEBUGF 1, "K: AHCI: ownership change completed.\n" |
|
- | 175 | ||
171 | mov ebx, 200 |
176 | .end_handoff: |
- | 177 | ;------------------------------------------------------- |
|
- | 178 | ||
- | 179 | ; enable the AHCI and reset it |
|
172 | call delay_hs |
180 | bts dword [esi + HBA_MEM.global_host_control], bit_AHCI_HBA_GHC_AHCI_ENABLE |
- | 181 | bts dword [esi + HBA_MEM.global_host_control], bit_AHCI_HBA_GHC_RESET |
|
173 | @@: |
182 | |
- | 183 | ; wait for reset to complete |
|
- | 184 | .wait_reset: |
|
- | 185 | bt dword [esi + HBA_MEM.global_host_control], bit_AHCI_HBA_GHC_RESET |
|
- | 186 | jc .wait_reset |
|
- | 187 | ||
- | 188 | ; enable the AHCI and interrupts |
|
- | 189 | bts dword [esi + HBA_MEM.global_host_control], bit_AHCI_HBA_GHC_AHCI_ENABLE |
|
Line 174... | Line 190... | ||
174 | DEBUGF 1, "K: AHCI: Done.\n" |
190 | bts dword [esi + HBA_MEM.global_host_control], bit_AHCI_HBA_GHC_INTERRUPT_ENABLE |
Line 175... | Line 191... | ||
175 | 191 | mov ebx, 2 |