Subversion Repositories Kolibri OS

Rev

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

Rev 1949 Rev 2288
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: 1949 $
24
$Revision: 2288 $
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:	times	30*10 db 0
549
                times   30*10 db 0
549
endg
550
endg
550
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
551
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
551
align 4
552
align 4
552
sys_pcibios:
553
sys_pcibios:
553
	cmp	[pci_access_enabled], 1
554
        cmp     [pci_access_enabled], 1
554
	jne	.unsupported_func
555
        jne     .unsupported_func
555
	cmp	[pci_bios_entry], 0
556
        cmp     [pci_bios_entry], 0
556
	jz	.emulate_bios
557
        jz      .emulate_bios
557
 
558
 
558
	push	ds
559
        push    ds
559
	mov	ax, pci_data_sel
560
        mov     ax, pci_data_sel
560
	mov	ds, ax
561
        mov     ds, ax
561
	mov	eax, ebp
562
        mov     eax, ebp
562
	mov	ah, 0B1h
563
        mov     ah, 0B1h
563
	call	pword [cs:pci_bios_entry]
564
        call    pword [cs:pci_bios_entry]
564
	pop	ds
565
        pop     ds
565
 
566
 
566
	jmp	.return
567
        jmp     .return
567
	;-=-=-=-=-=-=-=-=
568
        ;-=-=-=-=-=-=-=-=
568
.emulate_bios:
569
.emulate_bios:
569
	cmp	ebp, 1			; PCI_FUNCTION_ID
570
        cmp     ebp, 1                  ; PCI_FUNCTION_ID
570
	jnz	.not_PCI_BIOS_PRESENT
571
        jnz     .not_PCI_BIOS_PRESENT
571
	mov	edx, 'PCI '
572
        mov     edx, 'PCI '
572
	mov	al, [BOOT_VAR + 0x9020]
573
        mov     al, [BOOT_VAR + 0x9020]
573
	mov	bx, [BOOT_VAR + 0x9022]
574
        mov     bx, [BOOT_VAR + 0x9022]
574
	mov	cl, [BOOT_VAR + 0x9021]
575
        mov     cl, [BOOT_VAR + 0x9021]
575
	xor	ah, ah
576
        xor     ah, ah
576
	jmp	.return_abcd
577
        jmp     .return_abcd
577
 
578
 
578
.not_PCI_BIOS_PRESENT:
579
.not_PCI_BIOS_PRESENT:
579
	cmp	ebp, 2			; FIND_PCI_DEVICE
580
        cmp     ebp, 2                  ; FIND_PCI_DEVICE
580
	jne	.not_FIND_PCI_DEVICE
581
        jne     .not_FIND_PCI_DEVICE
581
	mov	ebx, pci_emu_dat
582
        mov     ebx, pci_emu_dat
-
 
583
..nxt:
582
..nxt:	cmp	[ebx], dx
584
        cmp     [ebx], dx
583
	jne	..no
585
        jne     ..no
584
	cmp	[ebx + 2], cx
586
        cmp     [ebx + 2], cx
585
	jne	..no
587
        jne     ..no
586
	dec	si
588
        dec     si
587
	jns	..no
589
        jns     ..no
588
	mov	bx, [ebx + 4]
590
        mov     bx, [ebx + 4]
589
	xor	ah, ah
591
        xor     ah, ah
590
	jmp	.return_ab
592
        jmp     .return_ab
-
 
593
..no:
591
..no:	cmp	word[ebx], 0
594
        cmp     word[ebx], 0
592
	je	..dev_not_found
595
        je      ..dev_not_found
593
	add	ebx, 10
596
        add     ebx, 10
594
	jmp	..nxt
597
        jmp     ..nxt
595
..dev_not_found:
598
..dev_not_found:
596
	mov	ah, 0x86		; DEVICE_NOT_FOUND
599
        mov     ah, 0x86                ; DEVICE_NOT_FOUND
597
	jmp	.return_a
600
        jmp     .return_a
598
 
601
 
599
.not_FIND_PCI_DEVICE:
602
.not_FIND_PCI_DEVICE:
600
	cmp	ebp, 3			; FIND_PCI_CLASS_CODE
603
        cmp     ebp, 3                  ; FIND_PCI_CLASS_CODE
601
	jne	.not_FIND_PCI_CLASS_CODE
604
        jne     .not_FIND_PCI_CLASS_CODE
602
	mov	esi, pci_emu_dat
605
        mov     esi, pci_emu_dat
603
	shl	ecx, 8
606
        shl     ecx, 8
-
 
607
..nxt2:
604
..nxt2: cmp	[esi], ecx
608
        cmp     [esi], ecx
605
	jne	..no2
609
        jne     ..no2
606
	mov	bx, [esi]
610
        mov     bx, [esi]
607
	xor	ah, ah
611
        xor     ah, ah
608
	jmp	.return_ab
612
        jmp     .return_ab
-
 
613
..no2:
609
..no2:	cmp	dword[esi], 0
614
        cmp     dword[esi], 0
610
	je	..dev_not_found
615
        je      ..dev_not_found
611
	add	esi, 10
616
        add     esi, 10
612
	jmp	..nxt2
617
        jmp     ..nxt2
613
 
618
 
614
.not_FIND_PCI_CLASS_CODE:
619
.not_FIND_PCI_CLASS_CODE:
615
	cmp	ebp, 8			; READ_CONFIG_*
620
        cmp     ebp, 8                  ; READ_CONFIG_*
616
	jb	.not_READ_CONFIG
621
        jb      .not_READ_CONFIG
617
	cmp	ebp, 0x0A
622
        cmp     ebp, 0x0A
618
	ja	.not_READ_CONFIG
623
        ja      .not_READ_CONFIG
619
	mov	eax, ebp
624
        mov     eax, ebp
620
	mov	ah, bh
625
        mov     ah, bh
621
	mov	edx, edi
626
        mov     edx, edi
622
	mov	bh, bl
627
        mov     bh, bl
623
	mov	bl, dl
628
        mov     bl, dl
624
	call	pci_read_reg
629
        call    pci_read_reg
625
	mov	ecx, eax
630
        mov     ecx, eax
626
	xor	ah, ah			; SUCCESSFUL
631
        xor     ah, ah                  ; SUCCESSFUL
627
	jmp	.return_abc
632
        jmp     .return_abc
628
.not_READ_CONFIG:
633
.not_READ_CONFIG:
629
	cmp	ebp, 0x0B		; WRITE_CONFIG_*
634
        cmp     ebp, 0x0B               ; WRITE_CONFIG_*
630
	jb	.not_WRITE_CONFIG
635
        jb      .not_WRITE_CONFIG
631
	cmp	ebp, 0x0D
636
        cmp     ebp, 0x0D
632
	ja	.not_WRITE_CONFIG
637
        ja      .not_WRITE_CONFIG
633
	lea	eax, [ebp+1]
638
        lea     eax, [ebp+1]
634
	mov	ah, bh
639
        mov     ah, bh
635
	mov	edx, edi
640
        mov     edx, edi
636
	mov	bh, bl
641
        mov     bh, bl
637
	mov	bl, dl
642
        mov     bl, dl
638
	call	pci_write_reg
643
        call    pci_write_reg
639
	xor	ah, ah			; SUCCESSFUL
644
        xor     ah, ah                  ; SUCCESSFUL
640
	jmp	.return_abc
645
        jmp     .return_abc
641
.not_WRITE_CONFIG:
646
.not_WRITE_CONFIG:
642
.unsupported_func:
647
.unsupported_func:
643
	mov	ah, 0x81		; FUNC_NOT_SUPPORTED
648
        mov     ah, 0x81                ; FUNC_NOT_SUPPORTED
-
 
649
.return:
644
.return:mov	dword[esp + 4 ], edi
650
        mov     dword[esp + 4 ], edi
645
	mov	dword[esp + 8], esi
651
        mov     dword[esp + 8], esi
646
.return_abcd:
652
.return_abcd:
647
	mov	dword[esp + 24], edx
653
        mov     dword[esp + 24], edx
648
.return_abc:
654
.return_abc:
649
	mov	dword[esp + 28], ecx
655
        mov     dword[esp + 28], ecx
650
.return_ab:
656
.return_ab:
651
	mov	dword[esp + 20], ebx
657
        mov     dword[esp + 20], ebx
652
.return_a:
658
.return_a:
653
	mov	dword[esp + 32], eax
659
        mov     dword[esp + 32], eax
654
	ret
660
        ret