Subversion Repositories Kolibri OS

Rev

Rev 1348 | Rev 1354 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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