Subversion Repositories Kolibri OS

Rev

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

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