Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5363 yogev_ezra 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;                                                              ;;
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
;;                                                              ;;
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23
 
24
$Revision: 9910 $
25
 
26
;***************************************************************************
27
;   Function
28
;      pci_api:
29
;
30
;   Description
31
;       entry point for system PCI calls
32
;***************************************************************************
7136 dunkaist 33
;mmio_pci_addr  =  0x400               ; set actual PCI address here to activate user-MMIO
2288 clevermous 34
 
35
iglobal
36
align 4
37
f62call:
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
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
 
55
endg
56
 
57
align 4
58
 
59
pci_api:
60
;cross
61
        mov     eax, ebx
62
        mov     ebx, ecx
63
        mov     ecx, edx
64
 
65
        cmp     [pci_access_enabled], 1
66
        jne     pci_service_not_supported
67
 
68
        movzx   edx, al
69
 
70
if defined mmio_pci_addr
71
        cmp     al, 13
72
        ja      pci_service_not_supported
73
else
74
        cmp     al, 10
75
        ja      pci_service_not_supported
76
end if
77
 
9910 Doczom 78
        call    dword [f62call + edx*4]
79
        mov     dword [esp + SYSCALL_STACK.eax], eax
2288 clevermous 80
        ret
81
 
82
 
83
align 4
84
pci_api_drv:
85
 
86
        cmp     [pci_access_enabled], 1
87
        jne     .fail
88
 
89
        cmp     eax, 2
90
        ja      .fail
91
 
9910 Doczom 92
        jmp     dword [f62call + eax*4]
2288 clevermous 93
 
94
.fail:
95
        or      eax, -1
96
        ret
97
 
98
 
99
;; ============================================
100
 
101
pci_fn_0:
102
; PCI function 0: get pci version (AH.AL)
9227 dunkaist 103
        movzx   eax, [BOOT.pci_data.version]
2288 clevermous 104
        ret
105
 
106
pci_fn_1:
107
; PCI function 1: get last bus in AL
9227 dunkaist 108
        mov     al, [BOOT.pci_data.last_bus]
2288 clevermous 109
        ret
110
 
111
pci_fn_2:
112
; PCI function 2: get pci access mechanism
9227 dunkaist 113
        mov     al, [BOOT.pci_data.access_mechanism]
2288 clevermous 114
        ret
115
 
116
pci_service_not_supported:
117
        or      eax, -1
9910 Doczom 118
        mov     dword [esp + SYSCALL_STACK.eax], eax
2288 clevermous 119
        ret
120
 
121
;***************************************************************************
122
;   Function
123
;      pci_make_config_cmd
124
;
125
;   Description
126
;       creates a command dword  for use with the PCI bus
127
;       bus # in ah
128
;       device+func in bh (dddddfff)
129
;       register in bl
130
;
131
;      command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
132
;***************************************************************************
133
 
134
align 4
135
 
136
pci_make_config_cmd:
137
        shl     eax, 8     ; move bus to bits 16-23
138
        mov     ax, bx     ; combine all
139
        and     eax, 0xffffff
140
        or      eax, 0x80000000
141
        ret
142
 
143
;***************************************************************************
144
;   Function
145
;      pci_read_reg:
146
;
147
;   Description
148
;       read a register from the PCI config space into EAX/AX/AL
149
;       IN: ah=bus,device+func=bh,register address=bl
150
;           number of bytes to read (1,2,4) coded into AL, bits 0-1
151
;           (0 - byte, 1 - word, 2 - dword)
152
;***************************************************************************
153
 
154
align 4
155
 
156
pci_read_reg:
3393 clevermous 157
        push    ebx esi
9227 dunkaist 158
        cmp     [BOOT.pci_data.access_mechanism], 2; what mechanism will we use?
9910 Doczom 159
        je      .pci_read_reg_2
2288 clevermous 160
 
161
                ; mechanism 1
3393 clevermous 162
        mov     esi, eax ; save register size into ESI
2288 clevermous 163
        and     esi, 3
164
 
165
        call    pci_make_config_cmd
166
        mov     ebx, eax
167
        mov     dx, 0xcf8
168
                ; set up addressing to config data
169
        mov     eax, ebx
170
        and     al, 0xfc; make address dword-aligned
171
        out     dx, eax
172
                ; get requested DWORD of config data
173
        mov     dl, 0xfc
174
        and     bl, 3
175
        or      dl, bl   ; add to port address first 2 bits of register address
176
 
177
        or      esi, esi
9910 Doczom 178
        jz      .byte1
2288 clevermous 179
        cmp     esi, 1
9910 Doczom 180
        jz      .word1
2288 clevermous 181
        cmp     esi, 2
9910 Doczom 182
        jz      .dword1
183
        jmp     .fin_read1
2288 clevermous 184
 
9910 Doczom 185
.byte1:
2288 clevermous 186
        in      al, dx
9910 Doczom 187
        jmp     .fin_read1
188
.word1:
2288 clevermous 189
        in      ax, dx
9910 Doczom 190
        jmp     .fin_read1
191
.dword1:
2288 clevermous 192
        in      eax, dx
9910 Doczom 193
.fin_read1:
3393 clevermous 194
        pop     esi ebx
2288 clevermous 195
        ret
196
 
9910 Doczom 197
.pci_read_reg_2:
198
 
2288 clevermous 199
        test    bh, 128 ;mech#2 only supports 16 devices per bus
9910 Doczom 200
        jnz     .pci_read_reg_err
2288 clevermous 201
 
3393 clevermous 202
        mov     esi, eax ; save register size into ESI
2288 clevermous 203
        and     esi, 3
204
 
4599 clevermous 205
        mov     dx, 0xcfa
2288 clevermous 206
 
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
218
 
219
        or      esi, esi
9910 Doczom 220
        jz      .byte2
2288 clevermous 221
        cmp     esi, 1
9910 Doczom 222
        jz      .word2
2288 clevermous 223
        cmp     esi, 2
9910 Doczom 224
        jz      .dword2
225
        jmp     .fin_read2
2288 clevermous 226
 
9910 Doczom 227
.byte2:
2288 clevermous 228
        in      al, dx
9910 Doczom 229
        jmp     .fin_read2
230
.word2:
2288 clevermous 231
        in      ax, dx
9910 Doczom 232
        jmp     .fin_read2
233
.dword2:
2288 clevermous 234
        in      eax, dx
9910 Doczom 235
.fin_read2:
2288 clevermous 236
 
3393 clevermous 237
        pop     esi ebx
2288 clevermous 238
        ret
239
 
9910 Doczom 240
.pci_read_reg_err:
2288 clevermous 241
        xor     eax, eax
242
        dec     eax
3393 clevermous 243
        pop     esi ebx
2288 clevermous 244
        ret
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
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
256
;           (0 - byte, 1 - word, 2 - dword)
257
;***************************************************************************
258
 
259
align 4
260
 
261
pci_write_reg:
3393 clevermous 262
        push    esi ebx
9227 dunkaist 263
        cmp     [BOOT.pci_data.access_mechanism], 2; what mechanism will we use?
2288 clevermous 264
        je      pci_write_reg_2
265
 
266
                ; mechanism 1
3393 clevermous 267
        mov     esi, eax ; save register size into ESI
2288 clevermous 268
        and     esi, 3
269
 
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
282
 
283
        or      esi, esi
9910 Doczom 284
        jz      .byte1
2288 clevermous 285
        cmp     esi, 1
9910 Doczom 286
        jz      .word1
2288 clevermous 287
        cmp     esi, 2
9910 Doczom 288
        jz      .dword1
289
        jmp     .fin_write1
2288 clevermous 290
 
9910 Doczom 291
.byte1:
2288 clevermous 292
        out     dx, al
9910 Doczom 293
        jmp     .fin_write1
294
.word1:
2288 clevermous 295
        out     dx, ax
9910 Doczom 296
        jmp     .fin_write1
297
.dword1:
2288 clevermous 298
        out     dx, eax
9910 Doczom 299
.fin_write1:
2288 clevermous 300
 
301
        xor     eax, eax
3393 clevermous 302
        pop     ebx esi
2288 clevermous 303
 
304
        ret
305
pci_write_reg_2:
306
 
307
        test    bh, 128 ;mech#2 only supports 16 devices per bus
9910 Doczom 308
        jnz     .pci_write_reg_err
2288 clevermous 309
 
310
 
3393 clevermous 311
        mov     esi, eax ; save register size into ESI
2288 clevermous 312
        and     esi, 3
313
 
4599 clevermous 314
        mov     dx, 0xcfa
2288 clevermous 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
328
 
329
        or      esi, esi
9910 Doczom 330
        jz      .byte2
2288 clevermous 331
        cmp     esi, 1
9910 Doczom 332
        jz      .word2
2288 clevermous 333
        cmp     esi, 2
9910 Doczom 334
        jz      .dword2
335
        jmp     .fin_write2
2288 clevermous 336
 
9910 Doczom 337
.byte2:
2288 clevermous 338
        out     dx, al
9910 Doczom 339
        jmp     .fin_write2
340
.word2:
2288 clevermous 341
        out     dx, ax
9910 Doczom 342
        jmp     .fin_write2
343
.dword2:
2288 clevermous 344
        out     dx, eax
9910 Doczom 345
.fin_write2:
2288 clevermous 346
 
347
        xor     eax, eax
3393 clevermous 348
        pop     ebx esi
2288 clevermous 349
        ret
350
 
9910 Doczom 351
.pci_write_reg_err:
2288 clevermous 352
        xor     eax, eax
353
        dec     eax
3393 clevermous 354
        pop     ebx esi
2288 clevermous 355
        ret
356
 
357
if defined mmio_pci_addr        ; must be set above
358
;***************************************************************************
359
;   Function
360
;      pci_mmio_init
361
;
362
;   Description
363
;       IN:  bx = device's PCI bus address (bbbbbbbbdddddfff)
364
;   Returns  eax = user heap space available (bytes)
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:
371
        cmp     bx, mmio_pci_addr
372
        jz      @f
373
        mov     eax, -2
374
        ret
375
@@:
376
        call    init_heap  ; (if not initialized yet)
377
        or      eax, eax
378
        jz      @f
379
        ret
380
@@:
381
        mov     eax, -3
382
        ret
383
 
384
 
385
;***************************************************************************
386
;   Function
387
;      pci_mmio_map
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
;
395
;       IN:  ah = BAR#;
396
;       IN: ebx = block size (bytes);
397
;       IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
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:
411
        and     edx, 0x0ffff
412
        cmp     ah, 6
413
        jc      .bar_0_5
414
        jz      .bar_rom
415
        mov     eax, -2
416
        ret
417
.bar_rom:
418
        mov     ah, 8   ; bar6 = Expansion ROM base address
419
.bar_0_5:
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
9910 Doczom 435
        jmp     .mmio_ret_fail
2288 clevermous 436
@@:
437
        test    eax, 1
438
        jz      @f
439
        mov     eax, -4 ; damned ports (not MMIO space)
9910 Doczom 440
        jmp     .mmio_ret_fail
2288 clevermous 441
@@:
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
9910 Doczom 448
        jnz     .mmio_map_over
2288 clevermous 449
        mov     eax, -5 ; problem with page allocation
450
 
9910 Doczom 451
.mmio_ret_fail:
2288 clevermous 452
        pop     ecx
453
        pop     edx
454
        ret
455
 
9910 Doczom 456
.mmio_map_over:
2288 clevermous 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
471
 
472
;***************************************************************************
473
;   Function
474
;      pci_mmio_unmap_page
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:
488
        stdcall user_free, ebx
489
        ret
490
 
491
end if
492
 
493
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
494
uglobal
495
align 4
496
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
497
pci_emu_dat:
498
                times   30*10 db 0
499
endg
500
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
501
align 4
502
sys_pcibios:
503
        cmp     [pci_access_enabled], 1
504
        jne     .unsupported_func
505
        cmp     [pci_bios_entry], 0
506
        jz      .emulate_bios
507
 
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
515
 
516
        jmp     .return
517
        ;-=-=-=-=-=-=-=-=
518
.emulate_bios:
519
        cmp     ebp, 1                  ; PCI_FUNCTION_ID
520
        jnz     .not_PCI_BIOS_PRESENT
521
        mov     edx, 'PCI '
9227 dunkaist 522
        mov     al, [BOOT.pci_data.access_mechanism]
523
        mov     bx, word[BOOT.pci_data.version]
524
        mov     cl, [BOOT.pci_data.last_bus]
2288 clevermous 525
        xor     ah, ah
526
        jmp     .return_abcd
527
 
528
.not_PCI_BIOS_PRESENT:
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
547
..dev_not_found:
548
        mov     ah, 0x86                ; DEVICE_NOT_FOUND
549
        jmp     .return_a
550
 
551
.not_FIND_PCI_DEVICE:
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
567
 
568
.not_FIND_PCI_CLASS_CODE:
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
582
.not_READ_CONFIG:
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
595
.not_WRITE_CONFIG:
596
.unsupported_func:
597
        mov     ah, 0x81                ; FUNC_NOT_SUPPORTED
598
.return:
9910 Doczom 599
        mov     dword[esp + SYSCALL_STACK.edi], edi
600
        mov     dword[esp + SYSCALL_STACK.esi], esi
2288 clevermous 601
.return_abcd:
9910 Doczom 602
        mov     dword[esp + SYSCALL_STACK.edx], edx
2288 clevermous 603
.return_abc:
9910 Doczom 604
        mov     dword[esp + SYSCALL_STACK.ecx], ecx
2288 clevermous 605
.return_ab:
9910 Doczom 606
        mov     dword[esp + SYSCALL_STACK.ebx], ebx
2288 clevermous 607
.return_a:
9910 Doczom 608
        mov     dword[esp + SYSCALL_STACK.eax], eax
2288 clevermous 609
        ret
3393 clevermous 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]
623
        mov     bl, 0
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
3598 clevermous 632
        movi    eax, sizeof.PCIDEV
3393 clevermous 633
        call    malloc
634
        pop     ecx
635
        test    eax, eax
636
        jz      .nomemory
637
        mov     edi, eax
638
        mov     [edi+PCIDEV.vendor_device_id], ecx
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
645
        mov     eax, dword [.devfn]
4418 clevermous 646
        mov     dword [edi+PCIDEV.devfn], eax
647
        mov     dword [edi+PCIDEV.owner], 0
3393 clevermous 648
        mov     bh, al
649
        mov     al, 2
650
        mov     bl, 8
651
        call    pci_read_reg
652
        shr     eax, 8
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]
659
        mov     bl, 0Eh
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]
9227 dunkaist 668
        cmp     ah, [BOOT.pci_data.last_bus]
3393 clevermous 669
        jbe     .loop
670
.nomemory:
671
        leave
672
        ret
673
endp
4453 clevermous 674
 
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
9567 Doczom 680
 
681
 
682
align 4
683
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
684
        push    ebx
685
        xor     eax, eax
686
        xor     ebx, ebx
687
        mov     ah, byte [bus]
688
        mov     al, 6
689
        mov     bh, byte [devfn]
690
        mov     bl, byte [reg]
691
        call    pci_read_reg
692
        pop     ebx
693
        ret
694
endp
695
 
696
align 4
697
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
698
        push    ebx
699
        xor     eax, eax
700
        xor     ebx, ebx
701
        mov     ah, byte [bus]
702
        mov     al, 5
703
        mov     bh, byte [devfn]
704
        mov     bl, byte [reg]
705
        call    pci_read_reg
706
        pop     ebx
707
        ret
708
endp
709
 
710
align 4
711
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
712
        push    ebx
713
        xor     eax, eax
714
        xor     ebx, ebx
715
        mov     ah, byte [bus]
716
        mov     al, 4
717
        mov     bh, byte [devfn]
718
        mov     bl, byte [reg]
719
        call    pci_read_reg
720
        pop     ebx
721
        ret
722
endp
723
 
724
align 4
725
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
726
        push    ebx
727
        xor     eax, eax
728
        xor     ebx, ebx
729
        mov     ah, byte [bus]
730
        mov     al, 8
731
        mov     bh, byte [devfn]
732
        mov     bl, byte [reg]
733
        mov     ecx, [val]
734
        call    pci_write_reg
735
        pop     ebx
736
        ret
737
endp
738
 
739
align 4
740
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
741
        push    ebx
742
        xor     eax, eax
743
        xor     ebx, ebx
744
        mov     ah, byte [bus]
745
        mov     al, 9
746
        mov     bh, byte [devfn]
747
        mov     bl, byte [reg]
748
        mov     ecx, [val]
749
        call    pci_write_reg
750
        pop     ebx
751
        ret
752
endp
753
 
754
align 4
755
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
756
        push    ebx
757
        xor     eax, eax
758
        xor     ebx, ebx
759
        mov     ah, byte [bus]
760
        mov     al, 10
761
        mov     bh, byte [devfn]
762
        mov     bl, byte [reg]
763
        mov     ecx, [val]
764
        call    pci_write_reg
765
        pop     ebx
766
        ret
767
endp