Subversion Repositories Kolibri OS

Rev

Rev 5577 | Details | Compare with Previous | Last modification | View Log | RSS feed

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