Rev 1560 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1551 | art_zh | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) 2010 KolibriOS team. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;; HT.inc ;; ;; |
||
7 | ;; ;; |
||
8 | ;; AMD HyperTransport bus control ;; |
||
9 | ;; ;; |
||
1599 | art_zh | 10 | ;; art_zh |
1551 | art_zh | 11 | ;; ;; |
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
13 | |||
1560 | art_zh | 14 | $Revision: 1554 $ |
1551 | art_zh | 15 | |
1599 | art_zh | 16 | NB_MISC_INDEX equ 0xF0000060 ; NB Misc indirect access |
17 | NB_MISC_DATA equ 0xF0000064 |
||
18 | PCIEIND_INDEX equ 0xF00000E0 ; PCIe Core indirect config space access |
||
19 | HTIU_NB_INDEX equ 0xF0000094 ; HyperTransport indirect config space access |
||
1551 | art_zh | 20 | |
21 | ;============================================================================= |
||
22 | ; |
||
23 | ; This code is a part of Kolibri-A and will only work with AMD RS760+ chipsets |
||
24 | ; |
||
25 | ;============================================================================= |
||
1560 | art_zh | 26 | align 4 |
1551 | art_zh | 27 | |
28 | ;------------------------------------------ |
||
29 | ; params: al = nbconfig register# |
||
30 | ; returns: eax = register content |
||
31 | ; |
||
32 | rs7xx_nbconfig_read_pci: |
||
33 | and eax, 0x0FC ; leave register# only |
||
34 | or eax, 0x80000000 ; bdf = 0:0.0 |
||
35 | mov dx, 0x0CF8 ; write to index reg |
||
36 | out dx, eax |
||
37 | add dl, 4 |
||
38 | in eax, dx |
||
39 | ret |
||
1560 | art_zh | 40 | align 4 |
1551 | art_zh | 41 | |
42 | rs7xx_nbconfig_flush_pci: |
||
43 | mov eax, 0x0B0 ; a scratch reg |
||
44 | mov dx, 0xCF8 |
||
45 | out dx, eax |
||
46 | ret |
||
47 | |||
1560 | art_zh | 48 | align 4 |
1551 | art_zh | 49 | |
1599 | art_zh | 50 | ;------------------------------------------ |
51 | ; params: al = nbconfig register# |
||
52 | ; ebx = register content |
||
53 | ; |
||
1551 | art_zh | 54 | rs7xx_nbconfig_write_pci: |
55 | and eax, 0x0FC ; leave register# only |
||
56 | or eax, 0x80000000 ; bdf = 0:0.0 |
||
57 | mov dx, 0x0CF8 ; write to index reg |
||
58 | out dx, eax |
||
59 | add dl, 4 |
||
60 | mov eax, ebx |
||
61 | out dx, eax |
||
62 | ret |
||
63 | |||
64 | ;*************************************************************************** |
||
65 | ; Function |
||
1599 | art_zh | 66 | ; rs7xx_unlock_bar3: unlocks the BAR3 register of nbconfig that |
67 | ; makes pcie config address space visible |
||
68 | ; ----------------------- |
||
69 | ; in: nothing out: nothing destroys: eax ebx edx |
||
70 | ; |
||
71 | ;*************************************************************************** |
||
72 | align 4 |
||
73 | rs7xx_unlock_bar3: |
||
74 | mov eax, NB_MISC_INDEX |
||
75 | mov ebx, 0x080 ; reg#0; write-enable |
||
76 | call rs7xx_nbconfig_write_pci ; set index |
||
77 | mov eax, NB_MISC_DATA |
||
78 | call rs7xx_nbconfig_read_pci ; read data |
||
79 | mov ebx, eax |
||
80 | and ebx, 0xFFFFFFF7 ; clear bit3 |
||
81 | mov eax, NB_MISC_DATA |
||
82 | call rs7xx_nbconfig_write_pci ; write it back |
||
83 | mov eax, NB_MISC_INDEX |
||
84 | xor ebx, ebx ; reg#0; write-locked |
||
85 | call rs7xx_nbconfig_write_pci ; set index |
||
86 | ret |
||
87 | |||
88 | ;-------------------------------------------------------------- |
||
89 | align 4 |
||
90 | rs780_read_misc: |
||
91 | ; in: eax(al) - reg# out: eax = NBMISCIND data |
||
92 | push edx |
||
93 | mov edx, NB_MISC_INDEX |
||
94 | and eax, 0x07F |
||
95 | mov [edx], eax |
||
96 | add dl, 4 |
||
97 | mov eax, [edx] |
||
98 | pop edx |
||
99 | ret |
||
100 | |||
101 | ;------------------------------------------- |
||
102 | align 4 |
||
103 | rs780_write_misc: |
||
104 | ; in: eax(al) - reg# ebx = NBMISCIND data |
||
105 | push edx |
||
106 | mov edx, NB_MISC_INDEX |
||
107 | and eax, 0x07F |
||
108 | or eax, 0x080 ; set WE |
||
109 | mov [edx], eax |
||
110 | add dl, 4 |
||
111 | mov [edx], ebx |
||
112 | sub dl, 4 |
||
113 | xor eax, eax |
||
114 | mov [edx], eax ; safety last |
||
115 | pop edx |
||
116 | ret |
||
117 | |||
118 | ;------------------------------------------------------------- |
||
119 | align 4 |
||
120 | rs780_read_pcieind: |
||
121 | ; in: ah = bridge#, al = reg# out: eax = PCIEIND data |
||
122 | push edx |
||
123 | xor edx, edx |
||
124 | mov ah, dl ; bridge# : 0 = Core+GFX; 0x10 = Core+SB |
||
125 | and dl, 15 ; 0x20 = Core+GPP; 2..12 = a PortBridge |
||
126 | shl edx, 15 ; device# |
||
127 | add edx, PCIEIND_INDEX ; full bdf-address |
||
128 | and eax, 0x30FF |
||
129 | or al, al |
||
130 | jnz @f |
||
131 | shl eax, 4 ; set bits 17..16 for a Core bridge |
||
132 | @@: |
||
133 | mov [edx], eax |
||
134 | add dl, 4 |
||
135 | mov eax, [edx] |
||
136 | pop edx |
||
137 | ret |
||
138 | |||
139 | ;------------------------------------------- |
||
140 | align 4 |
||
141 | rs780_write_pcieind: |
||
142 | ; in: ah = bridge#, al = reg#, ebx = PCIEIND data |
||
143 | push edx |
||
144 | xor edx, edx |
||
145 | mov ah, dl ; bridge# : 0 = Core+GFX; 0x10 = Core+SB |
||
146 | and dl, 15 ; 0x20 = Core+GPP; 2..12 = a PortBridge |
||
147 | shl edx, 15 ; device# |
||
148 | add edx, PCIEIND_INDEX ; full bdf-address |
||
149 | and eax, 0x30FF |
||
150 | or al, al |
||
151 | jnz @f |
||
152 | shl eax, 4 ; set bits 17..16 for a Core bridge |
||
153 | @@: |
||
154 | mov [edx], eax |
||
155 | add dl, 4 |
||
156 | mov [edx], ebx |
||
157 | sub dl, 4 |
||
158 | xor eax, eax |
||
159 | mov [edx], eax ; safety last |
||
160 | pop edx |
||
161 | ret |
||
162 | |||
163 | ;------------------------------------------------ |
||
164 | align 4 |
||
165 | rs780_read_htiu: |
||
166 | ; in: al = reg# | out: eax = HTIU data |
||
167 | ;------------------------------------------------ |
||
168 | push edx |
||
169 | mov edx, HTIU_NB_INDEX |
||
170 | and eax, 0x07F |
||
171 | mov [edx], eax |
||
172 | add dl, 4 |
||
173 | mov eax, [edx] |
||
174 | pop edx |
||
175 | ret |
||
176 | ;------------------------------------------------ |
||
177 | align 4 |
||
178 | rs780_write_htiu: |
||
179 | ; in: al = reg#; ebx = data |
||
180 | ;------------------------------------------------ |
||
181 | push edx |
||
182 | mov edx, HTIU_NB_INDEX |
||
183 | and eax, 0x07F |
||
184 | or eax, 0x100 |
||
185 | mov [edx], eax |
||
186 | add dl, 4 |
||
187 | mov [edx], ebx |
||
188 | sub dl, 4 |
||
189 | xor eax, eax |
||
190 | mov [edx], eax |
||
191 | pop edx |
||
192 | ret |
||
193 | |||
194 | |||
195 | |||
196 | ;*************************************************************************** |
||
197 | ; Function |
||
1551 | art_zh | 198 | ; rs7xx_pcie_init: |
199 | ; |
||
200 | ; Description |
||
201 | ; PCIe extended (memory-mapped) config space detection |
||
202 | ; |
||
203 | ;*************************************************************************** |
||
204 | |||
1560 | art_zh | 205 | align 4 |
206 | |||
1551 | art_zh | 207 | rs7xx_pcie_init: |
1599 | art_zh | 208 | call rs7xx_unlock_bar3 |
1551 | art_zh | 209 | mov al, 0x7C ; NB_IOC_CFG_CNTL |
210 | call rs7xx_nbconfig_read_pci |
||
211 | mov ebx, eax |
||
212 | call rs7xx_nbconfig_flush_pci |
||
213 | test ebx, 0x20000000 ; BAR3 locked? |
||
214 | jz .rs7xx_pcie_blocked |
||
215 | mov al, 0x84 ; NB_PCI_ARB |
||
216 | call rs7xx_nbconfig_read_pci |
||
217 | shr eax,16 |
||
218 | and ax, 7 ; the Bus range lays here: |
||
219 | jnz @f |
||
220 | mov ax, 8 ; 1=2Mb, 2=4MB, 3=8MB, 4=16MB |
||
221 | @@: |
||
222 | mov [PCIe_bus_range], ax ; 5=32Mb, 6=64MB, 7=128Mb, 8=256Mb |
||
223 | mov cl, al |
||
224 | call rs7xx_nbconfig_flush_pci |
||
225 | dec cl ; <4M ? |
||
226 | jnz @f |
||
227 | inc cl ; one PDE needed anyway |
||
228 | @@: |
||
229 | dec cl |
||
230 | mov ebx, 1 |
||
231 | shl ebx, cl |
||
232 | mov [mmio_pcie_cfg_pdes], bx ; 1..64 PDE(s) needed, |
||
233 | shl ebx, 22 |
||
234 | mov [mmio_pcie_cfg_lim], ebx ; or 4..256Mb space to map |
||
235 | dec [mmio_pcie_cfg_lim] |
||
236 | |||
237 | mov al, 0x1C ; NB_BAR3_PCIEXP_MMCFG |
||
238 | call rs7xx_nbconfig_read_pci |
||
239 | mov ebx, eax |
||
240 | call rs7xx_nbconfig_flush_pci |
||
241 | mov eax, ebx |
||
242 | and eax, 0xFFE00000 ; valid bits [31..21] |
||
1560 | art_zh | 243 | jz .rs7xx_pcie_blocked ; NB BAR3 may be invisible! |
244 | ; try to get pcie ecfg address indirectly |
||
245 | .addr_found: |
||
1551 | art_zh | 246 | mov [mmio_pcie_cfg_addr], eax ; physical address (lower 32 bits) |
247 | add [mmio_pcie_cfg_lim], eax |
||
248 | |||
249 | or eax, (PG_SHARED + PG_LARGE + PG_UW) ; by the way, UW is unsafe! |
||
250 | mov ecx, PCIe_CONFIG_SPACE ; linear address |
||
251 | mov ebx, ecx |
||
252 | shr ebx, 20 |
||
253 | add ebx, sys_pgdir ; PgDir entry @ |
||
1560 | art_zh | 254 | mov dl, byte[mmio_pcie_cfg_pdes] ; 1 page = 4M in address space |
255 | cmp dl, (USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4194304 |
||
256 | jb @f |
||
257 | mov dl, ((USER_DMA_BUFFER - PCIe_CONFIG_SPACE) / 4194304) - 1 |
||
258 | mov byte[mmio_pcie_cfg_pdes], dl |
||
1551 | art_zh | 259 | @@: |
1560 | art_zh | 260 | xor dx, dx ; PDEs counter |
261 | @@: |
||
262 | mov dword[ebx], eax ; map 4 buses |
||
1551 | art_zh | 263 | add bx, 4 ; new PDE |
264 | add eax, 0x400000 ; +4M phys. |
||
265 | add ecx, 0x400000 ; +4M lin. |
||
1560 | art_zh | 266 | cmp dl, byte[mmio_pcie_cfg_pdes] |
267 | jnc .pcie_cfg_mapped |
||
268 | inc dl |
||
269 | jmp @b |
||
1599 | art_zh | 270 | mov eax, cr3 |
271 | mov cr3, eax ; flush TLB |
||
1551 | art_zh | 272 | .pcie_cfg_mapped: |
273 | mov esi, boot_pcie_ok |
||
274 | call boot_log |
||
1560 | art_zh | 275 | ret ; <<< OK >>> |
1551 | art_zh | 276 | .rs7xx_pcie_fail: |
277 | mov esi, boot_rs7xx_fail |
||
278 | call boot_log |
||
1599 | art_zh | 279 | jmp $ |
1551 | art_zh | 280 | .rs7xx_pcie_blocked: |
281 | mov esi, boot_rs7xx_blkd |
||
282 | call boot_log |
||
1599 | art_zh | 283 | jmp $><><<>4M> |
1551 | art_zh | 284 |