Subversion Repositories Kolibri OS

Rev

Rev 4453 | Rev 5363 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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