Subversion Repositories Kolibri OS

Rev

Rev 586 | Rev 594 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
586 serge 2
;;                                                              ;;
431 serge 3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;                                                              ;;
586 serge 7
;;  PCI32.INC                                                   ;;
8
;;                                                              ;;
9
;;  32 bit PCI driver code                                      ;;
10
;;                                                              ;;
11
;;  Version 0.3  April 9, 2007                                  ;;
12
;;  Version 0.2  December 21st, 2002                            ;;
13
;;                                                              ;;
14
;;  Author: Victor Prodan, victorprodan@yahoo.com               ;;
15
;;          Mihailov Ilia, ghost.nsk@gmail.com                  ;;
16
;;    Credits:                                                  ;;
17
;;          Ralf Brown                                          ;;
18
;;          Mike Hibbett, mikeh@oceanfree.net                   ;;
19
;;                                                              ;;
20
;;  See file COPYING for details                                ;;
21
;;                                                              ;;
431 serge 22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 ha 23
 
593 mikedld 24
$Revision: 593 $
1 ha 25
 
593 mikedld 26
 
1 ha 27
;***************************************************************************
28
;   Function
29
;      pci_api:
30
;
31
;   Description
32
;       entry point for system PCI calls
33
;***************************************************************************
34
 
35
align 4
36
 
37
pci_api:
38
 
39
        cmp  [pci_access_enabled],1
40
        jne  no_pci_access_for_applications
41
 
42
        or al,al
43
        jnz pci_fn_1
44
        ; PCI function 0: get pci version (AH.AL)
465 serge 45
        movzx eax,word [BOOT_VAR+0x9022]
1 ha 46
        ret
47
 
48
pci_fn_1:
49
        cmp al,1
50
        jnz pci_fn_2
51
 
52
        ; PCI function 1: get last bus in AL
465 serge 53
        mov al,[BOOT_VAR+0x9021]
1 ha 54
        ret
55
 
56
pci_fn_2:
57
        cmp al,2
58
        jne pci_fn_3
59
        ; PCI function 2: get pci access mechanism
465 serge 60
        mov al,[BOOT_VAR+0x9020]
1 ha 61
        ret
62
pci_fn_3:
63
 
64
        cmp al,4
65
        jz pci_read_reg   ;byte
66
        cmp al,5
67
        jz pci_read_reg   ;word
68
        cmp al,6
69
        jz pci_read_reg   ;dword
70
 
71
        cmp al,8
72
        jz pci_write_reg  ;byte
73
        cmp al,9
74
        jz pci_write_reg  ;word
75
        cmp al,10
76
        jz pci_write_reg  ;dword
77
 
78
      no_pci_access_for_applications:
79
 
80
        mov eax,-1
81
 
82
        ret
83
 
84
;***************************************************************************
85
;   Function
86
;      pci_make_config_cmd
87
;
88
;   Description
89
;       creates a command dword  for use with the PCI bus
90
;       bus # in ah
91
;       device+func in bh (dddddfff)
92
;       register in bl
93
;
94
;      command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
95
;***************************************************************************
96
 
97
align 4
98
 
99
pci_make_config_cmd:
100
    shl     eax,8          ; move bus to bits 16-23
101
    mov     ax,bx          ; combine all
102
    and     eax,0xffffff
103
    or      eax,0x80000000
104
    ret
105
 
106
;***************************************************************************
107
;   Function
108
;      pci_read_reg:
109
;
110
;   Description
111
;       read a register from the PCI config space into EAX/AX/AL
112
;       IN: ah=bus,device+func=bh,register address=bl
113
;           number of bytes to read (1,2,4) coded into AL, bits 0-1
586 serge 114
;           (0 - byte, 1 - word, 2 - dword)
1 ha 115
;***************************************************************************
116
 
117
align 4
118
 
119
pci_read_reg:
465 serge 120
        cmp     byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
1 ha 121
        je      pci_read_reg_2
122
 
123
                ; mechanism 1
124
        push    esi   ; save register size into ESI
125
        mov     esi,eax
126
        and     esi,3
127
 
128
        call    pci_make_config_cmd
129
        mov     ebx,eax
130
                ; get current state
131
        mov     dx,0xcf8
132
        in      eax, dx
133
        push    eax
134
                ; set up addressing to config data
135
        mov     eax,ebx
136
        and     al,0xfc ; make address dword-aligned
137
        out     dx,eax
138
                ; get requested DWORD of config data
139
        mov     dl,0xfc
140
        and     bl,3
141
        or      dl,bl    ; add to port address first 2 bits of register address
142
 
143
        or      esi,esi
144
        jz      pci_read_byte1
145
        cmp     esi,1
146
        jz      pci_read_word1
147
        cmp     esi,2
148
        jz      pci_read_dword1
149
        jmp     pci_fin_read1
150
 
151
pci_read_byte1:
152
        in      al,dx
153
        jmp pci_fin_read1
154
pci_read_word1:
155
        in      ax,dx
156
        jmp pci_fin_read1
157
pci_read_dword1:
158
        in      eax,dx
159
        jmp     pci_fin_read1
160
pci_fin_read1:
161
                ; restore configuration control
162
        xchg    eax,[esp]
163
        mov     dx,0xcf8
164
        out     dx,eax
165
 
166
        pop     eax
167
        pop     esi
168
        ret
169
pci_read_reg_2:
170
 
171
        test    bh,128  ;mech#2 only supports 16 devices per bus
172
        jnz     pci_read_reg_err
173
 
174
        push esi   ; save register size into ESI
175
        mov esi,eax
176
        and esi,3
177
 
178
        push    eax
179
                ;store current state of config space
180
        mov     dx,0xcf8
181
        in      al,dx
182
        mov     ah,al
183
        mov     dl,0xfa
184
        in      al,dx
185
 
186
        xchg    eax,[esp]
187
                ; out 0xcfa,bus
188
        mov     al,ah
189
        out     dx,al
190
                ; out 0xcf8,0x80
191
        mov     dl,0xf8
192
        mov     al,0x80
193
        out     dx,al
194
                ; compute addr
195
        shr     bh,3 ; func is ignored in mechanism 2
196
        or      bh,0xc0
197
        mov     dx,bx
198
 
199
        or      esi,esi
200
        jz      pci_read_byte2
201
        cmp     esi,1
202
        jz      pci_read_word2
203
        cmp     esi,2
204
        jz      pci_read_dword2
205
        jmp     pci_fin_read2
206
 
207
pci_read_byte2:
208
        in      al,dx
209
        jmp pci_fin_read2
210
pci_read_word2:
211
        in      ax,dx
212
        jmp pci_fin_read2
213
pci_read_dword2:
214
        in      eax,dx
215
;       jmp pci_fin_read2
216
pci_fin_read2:
217
 
218
                ; restore configuration space
219
        xchg    eax,[esp]
220
        mov     dx,0xcfa
221
        out     dx,al
222
        mov     dl,0xf8
223
        mov     al,ah
224
        out     dx,al
225
 
226
        pop     eax
227
        pop     esi
228
        ret
229
 
230
pci_read_reg_err:
231
        xor     eax,eax
232
        dec     eax
233
        ret
234
 
235
 
236
;***************************************************************************
237
;   Function
238
;      pci_write_reg:
239
;
240
;   Description
241
;       write a register from ECX/CX/CL into the PCI config space
242
;       IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
243
;           value to write in ecx
244
;           number of bytes to write (1,2,4) coded into AL, bits 0-1
586 serge 245
;           (0 - byte, 1 - word, 2 - dword)
1 ha 246
;***************************************************************************
247
 
248
align 4
249
 
250
pci_write_reg:
465 serge 251
        cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
1 ha 252
        je pci_write_reg_2
253
 
254
                ; mechanism 1
255
        push    esi   ; save register size into ESI
256
        mov     esi,eax
257
        and     esi,3
258
 
259
        call    pci_make_config_cmd
260
        mov     ebx,eax
261
                ; get current state into ecx
262
        mov     dx,0xcf8
263
        in      eax, dx
264
        push    eax
265
                ; set up addressing to config data
266
        mov     eax,ebx
267
        and     al,0xfc ; make address dword-aligned
268
        out     dx,eax
269
                ; write DWORD of config data
270
        mov     dl,0xfc
271
        and     bl,3
272
        or      dl,bl
273
        mov     eax,ecx
274
 
275
        or      esi,esi
276
        jz      pci_write_byte1
277
        cmp     esi,1
278
        jz      pci_write_word1
279
        cmp     esi,2
280
        jz      pci_write_dword1
281
        jmp     pci_fin_write1
282
 
283
pci_write_byte1:
284
        out     dx,al
285
        jmp pci_fin_write1
286
pci_write_word1:
287
        out     dx,ax
288
        jmp pci_fin_write1
289
pci_write_dword1:
290
        out     dx,eax
291
        jmp     pci_fin_write1
292
pci_fin_write1:
293
 
294
                ; restore configuration control
295
        pop     eax
296
        mov     dl,0xf8
297
        out     dx,eax
298
 
299
        xor     eax,eax
300
        pop     esi
301
 
302
        ret
303
pci_write_reg_2:
304
 
305
        test    bh,128  ;mech#2 only supports 16 devices per bus
306
        jnz     pci_write_reg_err
307
 
308
 
309
        push esi   ; save register size into ESI
310
        mov esi,eax
311
        and esi,3
312
 
313
        push    eax
314
                ;store current state of config space
315
        mov     dx,0xcf8
316
        in      al,dx
317
        mov     ah,al
318
        mov     dl,0xfa
319
        in      al,dx
320
        xchg    eax,[esp]
321
                ; out 0xcfa,bus
322
        mov     al,ah
323
        out     dx,al
324
                ; out 0xcf8,0x80
325
        mov     dl,0xf8
326
        mov     al,0x80
327
        out     dx,al
328
                ; compute addr
329
        shr     bh,3 ; func is ignored in mechanism 2
330
        or      bh,0xc0
331
        mov     dx,bx
332
                ; write register
333
        mov     eax,ecx
334
 
335
        or      esi,esi
336
        jz      pci_write_byte2
337
        cmp     esi,1
338
        jz      pci_write_word2
339
        cmp     esi,2
340
        jz      pci_write_dword2
341
        jmp     pci_fin_write2
342
 
343
pci_write_byte2:
344
        out     dx,al
345
        jmp pci_fin_write2
346
pci_write_word2:
347
        out     dx,ax
348
        jmp pci_fin_write2
349
pci_write_dword2:
350
        out     dx,eax
351
        jmp     pci_fin_write2
352
pci_fin_write2:
353
                ; restore configuration space
354
        pop     eax
355
        mov     dx,0xcfa
356
        out     dx,al
357
        mov     dl,0xf8
358
        mov     al,ah
359
        out     dx,al
360
 
361
        xor     eax,eax
362
        pop     esi
363
        ret
364
 
365
pci_write_reg_err:
366
        xor     eax,eax
367
        dec     eax
368
        ret
586 serge 369
 
370
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
371
 
372
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
373
pci_emu_dat:	times	30*10 db 0
374
 
375
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
376
align 4
377
sys_pcibios:
378
	cmp	[pci_access_enabled], 1
379
        jne	.unsupported_func
380
	mov	edi, [pci_bios_entry]
381
	test	edi, edi
382
	jz	.emulate_bios
383
	xchg	ebx, eax
384
	xchg	ecx, eax
385
	xchg	edx, eax
386
	xchg	esi, eax
387
        mov     edi, eax
388
 
389
        push ds
390
        mov ax, pci_data_sel
391
        mov ds, ax
392
        mov eax, ebp
393
        call pword [cs:pci_bios_entry]
394
        pop ds
395
 
396
	jmp	.return
397
	;-=-=-=-=-=-=-=-=
398
.emulate_bios:
399
	cmp	ebp, 1			; PCI_FUNCTION_ID
400
	jnz	.not_PCI_BIOS_PRESENT
401
	mov	edx, 'PCI '
402
	xor	ah, ah
403
        mov     al, [OS_BASE+0x2F0000 + 0x9020]
404
        mov     bx, [OS_BASE+0x2F0000 + 0x9022]
405
        mov     cl, [OS_BASE+0x2F0000 + 0x9021]
406
	jmp	.return
407
 
408
.not_PCI_BIOS_PRESENT:
409
	cmp	ebp, 2			; FIND_PCI_DEVICE
410
	jne	.not_FIND_PCI_DEVICE
411
	mov	esi, pci_emu_dat
412
..nxt:	cmp	[esi], cx
413
	jne	..no
414
	cmp	[esi + 2], bx
415
	jne	..no
416
	dec	dx
417
	jns	..no
418
	mov	bx, [esi + 4]
419
	xor	ah, ah
420
	jmp	.return
421
..no:	cmp	word[esi], 0
422
	je	..dev_not_found
423
	add	esi, 10
424
	jmp	..nxt
425
..dev_not_found:
426
	mov	ah, 0x86		; DEVICE_NOT_FOUND
427
	jmp	.return
428
 
429
.not_FIND_PCI_DEVICE:
430
	cmp	ebp, 3			; FIND_PCI_CLASS_CODE
431
	jne	.not_FIND_PCI_CLASS_CODE
432
	mov	esi, pci_emu_dat
433
	shl	ebx, 8
434
..nxt2:	cmp	[esi], ebx
435
	jne	..no2
436
	mov	bx, [esi]
437
	xor	ah, ah
438
	jmp	.return
439
..no2:	cmp	dword[esi], 0
440
	je	..dev_not_found2
441
	add	esi, 10
442
	jmp	..nxt2
443
..dev_not_found2:
444
	mov	ah, 0x86		; DEVICE_NOT_FOUND
445
	jmp	.return
446
 
447
.not_FIND_PCI_CLASS_CODE:
448
	cmp	ebp, 8			; READ_CONFIG_*
449
	jb	.not_READ_CONFIG
450
	cmp	ebp, 0x0A
451
	ja	.not_READ_CONFIG
452
	mov	ebx, esi
453
	mov	bh, al
454
	mov	edx, ebp
455
	mov	al, dl
456
	call	pci_read_reg
457
	mov	ecx, eax
458
	xor	ah, ah			; SUCCESSFUL
459
	jmp	.return
460
.not_READ_CONFIG:
461
	cmp	ebp, 0x0B		; WRITE_CONFIG_*
462
	jb	.not_WRITE_CONFIG
463
	cmp	ebp, 0x0D
464
	ja	.not_WRITE_CONFIG
465
	mov	ecx, ebx
466
	mov	ebx, esi
467
	mov	bh, al
468
	mov	edx, ebp
469
	inc	edx
470
	mov	al, dl
471
	call	pci_write_reg
472
	xor	ah, ah			; SUCCESSFUL
473
	jmp	.return
474
.not_WRITE_CONFIG:
475
.unsupported_func:
476
	mov	ah, 0x81		; FUNC_NOT_SUPPORTED
477
.return:mov	dword[esp + 8 ], edi
478
	mov	dword[esp + 12], esi
479
	mov	dword[esp + 24], ebx
480
	mov	dword[esp + 28], edx
481
	mov	dword[esp + 32], ecx
482
	mov	dword[esp + 36], eax
483
	ret