Subversion Repositories Kolibri OS

Rev

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