Subversion Repositories Kolibri OS

Rev

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

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