Subversion Repositories Kolibri OS

Rev

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