Subversion Repositories Kolibri OS

Rev

Rev 1591 | Rev 1602 | 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
;;                                                              ;;
1591 lrz 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
431 serge 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: 1598 $
1 ha 25
 
26
;***************************************************************************
27
;   Function
28
;      pci_api:
29
;
30
;   Description
31
;       entry point for system PCI calls
32
;***************************************************************************
1370 art_zh 33
;mmio_pci_addr	equ  0x400		 ; set actual PCI address here to activate user-MMIO
1 ha 34
 
1591 lrz 35
iglobal
36
align 4
37
f62call:
38
	dd	pci_api.0
39
	dd	pci_api.1
40
	dd	pci_api.2
41
	dd	pci_api.not_support	;3
42
	dd	pci_read_reg		;4 byte
43
	dd	pci_read_reg            ;5 word
44
	dd	pci_read_reg            ;6 dword
45
	dd	pci_api.not_support     ;7
46
	dd	pci_write_reg           ;8 byte
47
	dd	pci_write_reg           ;9 word
48
	dd	pci_write_reg           ;10 dword
49
if defined mmio_pci_addr
50
	dd	pci_mmio_init		;11
51
	dd	pci_mmio_map		;12
52
	dd	pci_mmio_unmap		;13
53
end if
54
f62_rcall:
55
	dd	pci_read_reg.0		;4 byte
56
	dd	pci_read_reg.1		;5 word
57
	dd	pci_read_reg.2		;6 dword
58
f62_rcall2:
59
	dd	pci_read_reg_2.0	;4 byte
60
	dd	pci_read_reg_2.1	;5 word
61
	dd	pci_read_reg_2.2	;6 dword
62
f62_wcall:
63
	dd	pci_write_reg.0		;4 byte
64
	dd	pci_write_reg.1		;5 word
65
	dd	pci_write_reg.2		;6 dword
66
f62_wcall2:
67
	dd	pci_write_reg_2.0	;4 byte
68
	dd	pci_write_reg_2.1	;5 word
69
	dd	pci_write_reg_2.2	;6 dword
70
endg
1370 art_zh 71
 
1591 lrz 72
 
1 ha 73
align 4
74
pci_api:
1591 lrz 75
        movzx	eax,bl
1348 art_zh 76
	cmp  [pci_access_enabled],1
1591 lrz 77
	jne  .no_pci_access_for_applications
1 ha 78
 
1591 lrz 79
if defined mmio_pci_addr
80
        cmp eax, 13
81
        jb .not_support
82
else
83
        cmp eax, 10
84
        jb .not_support
85
end if
86
        call dword [f62call+eax*4]
87
        mov	dword [esp+32],eax
88
        ret
89
 
90
 
91
 
92
;	or al,al
93
;	jnz pci_fn_1
1348 art_zh 94
	; PCI function 0: get pci version (AH.AL)
1591 lrz 95
.0:
96
	movzx	eax, word [BOOT_VAR+0x9022]
1348 art_zh 97
	ret
1 ha 98
 
1591 lrz 99
;pci_fn_1:
100
;	cmp al,1
101
;	jnz pci_fn_2
1 ha 102
 
1348 art_zh 103
	; PCI function 1: get last bus in AL
1591 lrz 104
.1:
105
	movzx	eax, byte [BOOT_VAR+0x9021]
1348 art_zh 106
	ret
1 ha 107
 
1591 lrz 108
;pci_fn_2:
109
;	cmp al,2
110
;	jne pci_fn_3
1348 art_zh 111
	; PCI function 2: get pci access mechanism
1591 lrz 112
.2:
113
	movzx	eax, byte [BOOT_VAR+0x9020]
1348 art_zh 114
	ret
1591 lrz 115
;pci_fn_3:
1 ha 116
 
1591 lrz 117
;	cmp al,4
118
;	jz pci_read_reg   ;byte
119
;	cmp al,5
120
;	jz pci_read_reg   ;word
121
;	cmp al,6
122
;	jz pci_read_reg   ;dword
1 ha 123
 
1591 lrz 124
;	cmp al,8
125
;	jz pci_write_reg  ;byte
126
;	cmp al,9
127
;	jz pci_write_reg  ;word
128
;	cmp al,10
129
;	jz pci_write_reg  ;dword
1 ha 130
 
1591 lrz 131
;if defined mmio_pci_addr
132
;	cmp al,11	    ;  user-level MMIO functions
133
;	jz pci_mmio_init
134
;	cmp al,12
135
;	jz pci_mmio_map
136
;	cmp al,13
137
;	jz pci_mmio_unmap
138
;end if
1348 art_zh 139
 
1591 lrz 140
.not_support:
141
.no_pci_access_for_applications:
142
	or 	eax,-1
1348 art_zh 143
	ret
1 ha 144
 
145
;***************************************************************************
146
;   Function
147
;      pci_make_config_cmd
148
;
149
;   Description
150
;       creates a command dword  for use with the PCI bus
1591 lrz 151
;       bus # in bh;ah
152
;       device+func in ch;bh (dddddfff)
153
;       register in cl;bl
1 ha 154
;
1591 lrz 155
;      command dword returned in ebx;eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
1 ha 156
;***************************************************************************
157
 
158
align 4
159
 
160
pci_make_config_cmd:
1591 lrz 161
    shl     ebx,8;eax,8	   ; move bus to bits 16-23
162
    mov     bx,cx;ax,bx	   ; combine all
163
    and     ebx,0xffffff;eax,0xffffff
164
    or	    ebx,0x80000000;eax,0x80000000
1 ha 165
    ret
166
 
167
;***************************************************************************
168
;   Function
169
;      pci_read_reg:
170
;
171
;   Description
172
;       read a register from the PCI config space into EAX/AX/AL
1598 art_zh 173
;       IN: bh=bus,device+func=ch,register address=cl
174
;           number of bytes to read (1,2,4) coded into BL, bits 0-1
586 serge 175
;           (0 - byte, 1 - word, 2 - dword)
1 ha 176
;***************************************************************************
177
 
178
align 4
179
 
180
pci_read_reg:
1348 art_zh 181
	cmp	byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
182
	je	pci_read_reg_2
1 ha 183
 
1348 art_zh 184
		; mechanism 1
1591 lrz 185
;	push	esi   ; save register size into ESI
186
	mov	esi,ebx;eax
1348 art_zh 187
	and	esi,3
1 ha 188
 
1348 art_zh 189
	call	pci_make_config_cmd
1591 lrz 190
	mov	eax,ebx;ebx,eax
1348 art_zh 191
		; get current state
192
	mov	dx,0xcf8
193
	in	eax, dx
194
	push	eax
195
		; set up addressing to config data
196
	mov	eax,ebx
197
	and	al,0xfc ; make address dword-aligned
198
	out	dx,eax
199
		; get requested DWORD of config data
200
	mov	dl,0xfc
201
	and	bl,3
202
	or	dl,bl	 ; add to port address first 2 bits of register address
1 ha 203
 
1591 lrz 204
;	or	esi,esi
205
;	jz	pci_read_byte1
206
;	cmp	esi,1
207
;	jz	pci_read_word1
208
;	cmp	esi,2
209
;	jz	pci_read_dword1
210
;	jmp	pci_fin_read1
211
	jmp	dword [f62_rcall+esi*4]
1 ha 212
 
1591 lrz 213
.0:
1348 art_zh 214
	in	al,dx
1591 lrz 215
	jmp .pci_fin_read1
216
.1:
1348 art_zh 217
	in	ax,dx
1591 lrz 218
	jmp .pci_fin_read1
219
.2:
1348 art_zh 220
	in	eax,dx
1591 lrz 221
;	jmp	pci_fin_read1
222
.pci_fin_read1:
1348 art_zh 223
		; restore configuration control
224
	xchg	eax,[esp]
225
	mov	dx,0xcf8
226
	out	dx,eax
1 ha 227
 
1348 art_zh 228
	pop	eax
1591 lrz 229
	;pop	esi
1348 art_zh 230
	ret
1 ha 231
pci_read_reg_2:
232
 
1591 lrz 233
	test	ch,128;bh,128	;mech#2 only supports 16 devices per bus
234
	jnz	pci_api.not_support
1 ha 235
 
1591 lrz 236
;	push esi   ; save register size into ESI
237
	mov esi,ebx;eax
1348 art_zh 238
	and esi,3
1 ha 239
 
1591 lrz 240
	push	ebx;eax
241
	mov	eax,ebx
1348 art_zh 242
		;store current state of config space
243
	mov	dx,0xcf8
244
	in	al,dx
245
	mov	ah,al
246
	mov	dl,0xfa
247
	in	al,dx
1 ha 248
 
1348 art_zh 249
	xchg	eax,[esp]
250
		; out 0xcfa,bus
251
	mov	al,ah
252
	out	dx,al
253
		; out 0xcf8,0x80
254
	mov	dl,0xf8
255
	mov	al,0x80
256
	out	dx,al
257
		; compute addr
1591 lrz 258
	shr	ch,3;bh,3 ; func is ignored in mechanism 2
259
	or	ch,0xc0;bh,0xc0
260
	mov	dx,cx;bx
1 ha 261
 
1591 lrz 262
;	or	esi,esi
263
;	jz	pci_read_byte2
264
;	cmp	esi,1
265
;	jz	pci_read_word2
266
;	cmp	esi,2
267
;	jz	pci_read_dword2
268
;	jmp	pci_fin_read2
269
	jmp	dword [f62_rcall2+esi*4]
1 ha 270
 
1591 lrz 271
.0:
1348 art_zh 272
	in	al,dx
1591 lrz 273
	jmp .pci_fin_read2
274
.1:
1348 art_zh 275
	in	ax,dx
1591 lrz 276
	jmp .pci_fin_read2
277
.2:
1348 art_zh 278
	in	eax,dx
1 ha 279
;       jmp pci_fin_read2
280
 
1591 lrz 281
.pci_fin_read2:
282
 
1348 art_zh 283
		; restore configuration space
284
	xchg	eax,[esp]
285
	mov	dx,0xcfa
286
	out	dx,al
287
	mov	dl,0xf8
288
	mov	al,ah
289
	out	dx,al
1 ha 290
 
1348 art_zh 291
	pop	eax
1591 lrz 292
;	pop	esi
1348 art_zh 293
	ret
1 ha 294
 
1591 lrz 295
;pci_read_reg_err:
296
;	or 	dword [esp+32],-1
297
;	ret
1 ha 298
 
299
 
300
;***************************************************************************
301
;   Function
302
;      pci_write_reg:
303
;
304
;   Description
305
;       write a register from ECX/CX/CL into the PCI config space
1598 art_zh 306
;       IN: bh=bus,device+func=ch,register address (dword aligned)=cl,
307
;           value to write in edx
308
;           number of bytes to write (1,2,4) coded into BL, bits 0-1
586 serge 309
;           (0 - byte, 1 - word, 2 - dword)
1 ha 310
;***************************************************************************
311
 
312
align 4
313
 
314
pci_write_reg:
1348 art_zh 315
	cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
316
	je pci_write_reg_2
1 ha 317
 
1348 art_zh 318
		; mechanism 1
1591 lrz 319
;	push	esi   ; save register size into ESI
320
	mov	esi,ebx;eax
321
	and	esi,3	;not need
1 ha 322
 
1348 art_zh 323
	call	pci_make_config_cmd
1591 lrz 324
	mov	eax,ebx;ebx,eax
325
	mov	ecx,edx		;cross registers
1348 art_zh 326
		; get current state into ecx
327
	mov	dx,0xcf8
328
	in	eax, dx
329
	push	eax
330
		; set up addressing to config data
331
	mov	eax,ebx
332
	and	al,0xfc ; make address dword-aligned
333
	out	dx,eax
334
		; write DWORD of config data
335
	mov	dl,0xfc
336
	and	bl,3
337
	or	dl,bl
338
	mov	eax,ecx
1 ha 339
 
1591 lrz 340
;	or	esi,esi
341
;	jz	pci_write_byte1
342
;	cmp	esi,1
343
;	jz	pci_write_word1
344
;	cmp	esi,2
345
;	jz	pci_write_dword1
346
;	jmp	pci_fin_write1
347
	jmp	dword [f62_wcall+esi*4]
348
.0:
1348 art_zh 349
	out	dx,al
1591 lrz 350
	jmp .pci_fin_write1
351
.1:
1348 art_zh 352
	out	dx,ax
1591 lrz 353
	jmp .pci_fin_write1
354
.2:
1348 art_zh 355
	out	dx,eax
1591 lrz 356
.pci_fin_write1:
1 ha 357
 
1348 art_zh 358
		; restore configuration control
359
	pop	eax
360
	mov	dl,0xf8
361
	out	dx,eax
1 ha 362
 
1348 art_zh 363
	xor	eax,eax
1591 lrz 364
	;pop	esi
1348 art_zh 365
	ret
1 ha 366
pci_write_reg_2:
367
 
1591 lrz 368
	test	ch,128;bh,128	;mech#2 only supports 16 devices per bus
369
	jnz	pci_api.not_support
1 ha 370
 
371
 
1591 lrz 372
;	push esi   ; save register size into ESI
1348 art_zh 373
	mov esi,eax
1591 lrz 374
	and esi,3	;not need
1 ha 375
 
1348 art_zh 376
	push	eax
1591 lrz 377
	mov	ecx,edx		;cross registers
1348 art_zh 378
		;store current state of config space
379
	mov	dx,0xcf8
380
	in	al,dx
381
	mov	ah,al
382
	mov	dl,0xfa
383
	in	al,dx
384
	xchg	eax,[esp]
385
		; out 0xcfa,bus
386
	mov	al,ah
387
	out	dx,al
388
		; out 0xcf8,0x80
389
	mov	dl,0xf8
390
	mov	al,0x80
391
	out	dx,al
392
		; compute addr
393
	shr	bh,3 ; func is ignored in mechanism 2
394
	or	bh,0xc0
395
	mov	dx,bx
396
		; write register
397
	mov	eax,ecx
1 ha 398
 
1591 lrz 399
;	or	esi,esi
400
;	jz	pci_write_byte2
401
;	cmp	esi,1
402
;	jz	pci_write_word2
403
;	cmp	esi,2
404
;	jz	pci_write_dword2
405
;	jmp	pci_fin_write2
406
	jmp	dword [f62_wcall2+esi*4]
407
.0:
1348 art_zh 408
	out	dx,al
1591 lrz 409
	jmp .pci_fin_write2
410
.1:
1348 art_zh 411
	out	dx,ax
1591 lrz 412
	jmp .pci_fin_write2
413
.2:
1348 art_zh 414
	out	dx,eax
1591 lrz 415
.pci_fin_write2:
1348 art_zh 416
		; restore configuration space
417
	pop	eax
418
	mov	dx,0xcfa
419
	out	dx,al
420
	mov	dl,0xf8
421
	mov	al,ah
422
	out	dx,al
1 ha 423
 
1348 art_zh 424
	xor	eax,eax
1591 lrz 425
	;pop	esi
1348 art_zh 426
	ret
1 ha 427
 
1591 lrz 428
;pci_write_reg_err:
429
;	xor	eax,eax
430
;	dec	eax
431
;	ret
586 serge 432
 
1370 art_zh 433
if defined mmio_pci_addr	; must be set above
1348 art_zh 434
;***************************************************************************
435
;   Function
1370 art_zh 436
;      pci_mmio_init
1348 art_zh 437
;
438
;   Description
1591 lrz 439
;       IN:  cx = device's PCI bus address (bbbbbbbbdddddfff)
1358 art_zh 440
;   Returns  eax = user heap space available (bytes)
1348 art_zh 441
;   Error codes
442
;       eax = -1 : PCI user access blocked,
443
;       eax = -2 : device not registered for uMMIO service
444
;       eax = -3 : user heap initialization failure
445
;***************************************************************************
446
pci_mmio_init:
1591 lrz 447
    cmp     cx, mmio_pci_addr
1348 art_zh 448
    jz	    @f
449
    mov     eax,-2
450
    ret
451
@@:
452
    call    init_heap	   ; (if not initialized yet)
453
    or	    eax,eax
454
    jz	    @f
455
    ret
456
@@:
457
    mov     eax,-3
458
    ret
459
 
460
 
461
;***************************************************************************
462
;   Function
1370 art_zh 463
;      pci_mmio_map
1348 art_zh 464
;
465
;   Description
466
;       maps a block of PCI memory to user-accessible linear address
467
;
468
;       WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only!
469
;       The target device address should be set in kernel var mmio_pci_addr
470
;
1598 art_zh 471
;       IN:  bh = BAR#;
472
;       IN: ecx = block size (bytes);
473
;       IN: edx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
1348 art_zh 474
;
475
;   Returns eax = MMIO block's linear address in the userspace (if no error)
476
;
477
;
478
;   Error codes
479
;       eax = -1 : user access to PCI blocked,
480
;       eax = -2 : an invalid BAR register referred
481
;       eax = -3 : no i/o space on that BAR
482
;       eax = -4 : a port i/o BAR register referred
483
;       eax = -5 : dynamic userspace allocation problem
484
;***************************************************************************
485
 
486
pci_mmio_map:
487
    and     edx,0x0ffff
1598 art_zh 488
    cmp     bh, 6
1353 art_zh 489
    jc     .bar_0_5
490
    jz     .bar_rom
1348 art_zh 491
    mov     eax,-2
492
    ret
1353 art_zh 493
.bar_rom:
494
    mov    ah, 8	; bar6 = Expansion ROM base address
495
.bar_0_5:
1598 art_zh 496
    push    edx
497
    add     ecx, 4095
498
    and     ecx, 0xFFFFF000	; 4k-alignment
1348 art_zh 499
    push    ecx
1598 art_zh 500
    mov     cl, bh	; cl = BAR# (0..5), however cl=8 for BAR6
501
    shl     cl, 1
502
    shl     cl, 1
503
    add     cl, 0x10	; now cl = BAR offset in PCI config. space
1354 diamond 504
    mov     ax, mmio_pci_addr
1598 art_zh 505
    mov     ch, al	; ch = dddddfff
506
    mov     bl, 2		; bl : DW to read
507
    call    pci_read_reg	; new call
1348 art_zh 508
    or	    eax, eax
509
    jnz     @f
510
    mov     eax,-3	; empty I/O space
511
    jmp     mmio_ret_fail
512
@@:
513
    test    eax, 1
514
    jz	    @f
515
    mov     eax,-4	; damned ports (not MMIO space)
516
    jmp     mmio_ret_fail
517
@@:
1598 art_zh 518
    pop     ecx 		; ecx = block size, bytes (expanded to whole page)
1348 art_zh 519
    mov     ebx, ecx	; user_alloc destroys eax, ecx, edx, but saves ebx
1598 art_zh 520
    and     al, 0xF0	; clear flags
1462 art_zh 521
    push    eax 	      ; store MMIO physical address + keep 2DWords in the stack
1348 art_zh 522
    stdcall user_alloc, ecx
1598 art_zh 523
    or	eax, eax
1348 art_zh 524
    jnz     mmio_map_over
525
    mov     eax,-5	; problem with page allocation
526
 
527
mmio_ret_fail:
528
    pop     ecx
529
    pop     edx
530
    ret
531
 
532
mmio_map_over:
533
    mov     ecx, ebx	; ecx = size (bytes, expanded to whole page)
534
    shr     ecx, 12	; ecx = number of pages
535
    mov     ebx, eax	; ebx = linear address
1598 art_zh 536
    pop     eax 		; eax = MMIO start
537
    pop     edx 		; edx = MMIO shift (pages)
1348 art_zh 538
    shl     edx, 12	; edx = MMIO shift (bytes)
539
    add     eax, edx	; eax = uMMIO physical address
1598 art_zh 540
    or	eax, PG_SHARED+PG_UW+PG_NOCACHE
1348 art_zh 541
    mov     edi, ebx
542
    call    commit_pages
543
    mov     eax, edi
544
    ret
545
 
546
;***************************************************************************
547
;   Function
1370 art_zh 548
;      pci_mmio_unmap_page
1348 art_zh 549
;
550
;   Description
551
;       unmaps the linear space previously tied to a PCI memory block
552
;
553
;       IN: ebx = linear address of space previously allocated by pci_mmio_map
554
;       returns eax = 1 if successfully unmapped
555
;
556
;   Error codes
557
;       eax = -1 if no user PCI access allowed,
558
;       eax =  0 if unmapping failed
559
;***************************************************************************
560
 
561
pci_mmio_unmap:
1591 lrz 562
    stdcall user_free, ecx;ebx
1348 art_zh 563
    ret
564
 
1354 diamond 565
end if
1348 art_zh 566
 
586 serge 567
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1375 Lrz 568
uglobal
569
align 4
586 serge 570
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
571
pci_emu_dat:	times	30*10 db 0
1375 Lrz 572
endg
586 serge 573
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
574
align 4
575
sys_pcibios:
594 diamond 576
	cmp	[pci_access_enabled], 1
1348 art_zh 577
	jne	.unsupported_func
578
	cmp	[pci_bios_entry], 0
594 diamond 579
	jz	.emulate_bios
586 serge 580
 
1348 art_zh 581
	push	ds
582
	mov	ax, pci_data_sel
583
	mov	ds, ax
584
	mov	eax, ebp
585
	mov	ah, 0B1h
586
	call	pword [cs:pci_bios_entry]
587
	pop	ds
586 serge 588
 
589
	jmp	.return
590
	;-=-=-=-=-=-=-=-=
591
.emulate_bios:
592
	cmp	ebp, 1			; PCI_FUNCTION_ID
593
	jnz	.not_PCI_BIOS_PRESENT
594
	mov	edx, 'PCI '
1348 art_zh 595
	mov	al, [OS_BASE+0x2F0000 + 0x9020]
596
	mov	bx, [OS_BASE+0x2F0000 + 0x9022]
597
	mov	cl, [OS_BASE+0x2F0000 + 0x9021]
598
	xor	ah, ah
594 diamond 599
	jmp	.return_abcd
586 serge 600
 
601
.not_PCI_BIOS_PRESENT:
602
	cmp	ebp, 2			; FIND_PCI_DEVICE
603
	jne	.not_FIND_PCI_DEVICE
594 diamond 604
	mov	ebx, pci_emu_dat
605
..nxt:	cmp	[ebx], dx
586 serge 606
	jne	..no
594 diamond 607
	cmp	[ebx + 2], cx
586 serge 608
	jne	..no
594 diamond 609
	dec	si
586 serge 610
	jns	..no
594 diamond 611
	mov	bx, [ebx + 4]
1348 art_zh 612
	xor	ah, ah
594 diamond 613
	jmp	.return_ab
614
..no:	cmp	word[ebx], 0
586 serge 615
	je	..dev_not_found
594 diamond 616
	add	ebx, 10
586 serge 617
	jmp	..nxt
618
..dev_not_found:
619
	mov	ah, 0x86		; DEVICE_NOT_FOUND
594 diamond 620
	jmp	.return_a
586 serge 621
 
622
.not_FIND_PCI_DEVICE:
623
	cmp	ebp, 3			; FIND_PCI_CLASS_CODE
624
	jne	.not_FIND_PCI_CLASS_CODE
625
	mov	esi, pci_emu_dat
594 diamond 626
	shl	ecx, 8
1348 art_zh 627
..nxt2: cmp	[esi], ecx
586 serge 628
	jne	..no2
629
	mov	bx, [esi]
1348 art_zh 630
	xor	ah, ah
594 diamond 631
	jmp	.return_ab
586 serge 632
..no2:	cmp	dword[esi], 0
594 diamond 633
	je	..dev_not_found
586 serge 634
	add	esi, 10
635
	jmp	..nxt2
636
 
637
.not_FIND_PCI_CLASS_CODE:
1598 art_zh 638
	mov	edx, ecx
586 serge 639
	cmp	ebp, 8			; READ_CONFIG_*
640
	jb	.not_READ_CONFIG
641
	cmp	ebp, 0x0A
642
	ja	.not_READ_CONFIG
1598 art_zh 643
	mov	eax, ebp	; -- ??
644
;	mov	ah, bh	; bus
645
	mov	ecx, edi
646
	mov	ch, bl	; dev+fn
647
;	mov	cl, dl	; reg#
648
	call	pci_read_reg
649
	mov	edx, eax
586 serge 650
	xor	ah, ah			; SUCCESSFUL
594 diamond 651
	jmp	.return_abc
586 serge 652
.not_READ_CONFIG:
653
	cmp	ebp, 0x0B		; WRITE_CONFIG_*
654
	jb	.not_WRITE_CONFIG
655
	cmp	ebp, 0x0D
656
	ja	.not_WRITE_CONFIG
1348 art_zh 657
	lea	eax, [ebp+1]
1598 art_zh 658
;	mov	ah, bh	; bus
659
	mov	ecx, edi
660
	mov	ch, bl
661
;	mov	cl, dl
586 serge 662
	call	pci_write_reg
663
	xor	ah, ah			; SUCCESSFUL
594 diamond 664
	jmp	.return_abc
586 serge 665
.not_WRITE_CONFIG:
666
.unsupported_func:
667
	mov	ah, 0x81		; FUNC_NOT_SUPPORTED
1375 Lrz 668
.return:mov	dword[esp + 4 ], edi
669
	mov	dword[esp + 8], esi
594 diamond 670
.return_abcd:
1375 Lrz 671
	mov	dword[esp + 24], edx
594 diamond 672
.return_abc:
1375 Lrz 673
	mov	dword[esp + 28], ecx
594 diamond 674
.return_ab:
1375 Lrz 675
	mov	dword[esp + 20], ebx
594 diamond 676
.return_a:
1375 Lrz 677
	mov	dword[esp + 32], eax
586 serge 678
	ret