Subversion Repositories Kolibri OS

Rev

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