Subversion Repositories Kolibri OS

Rev

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