Subversion Repositories Kolibri OS

Rev

Rev 1687 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1687 Rev 1941
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.4A November 4th,  2010                            ;;
11
;;  Version 0.4A November 4th,  2010                            ;;
12
;;  Version 0.4  February 2nd,  2010                            ;;
12
;;  Version 0.4  February 2nd,  2010                            ;;
13
;;  Version 0.3  April 9, 2007                                  ;;
13
;;  Version 0.3  April 9, 2007                                  ;;
14
;;  Version 0.2  December 21st, 2002                            ;;
14
;;  Version 0.2  December 21st, 2002                            ;;
15
;;                                                              ;;
15
;;                                                              ;;
16
;;  Author: Victor Prodan, victorprodan@yahoo.com               ;;
16
;;  Author: Victor Prodan, victorprodan@yahoo.com               ;;
17
;;          Mihailov Ilia, ghost.nsk@gmail.com                  ;;
17
;;          Mihailov Ilia, ghost.nsk@gmail.com                  ;;
18
;;          Artem Jerdev,  kolibri@jerdev.co.uk                 ;;
18
;;          Artem Jerdev,  kolibri@jerdev.co.uk                 ;;
19
;;    Credits:                                                  ;;
19
;;    Credits:                                                  ;;
20
;;          Ralf Brown                                          ;;
20
;;          Ralf Brown                                          ;;
21
;;          Mike Hibbett, mikeh@oceanfree.net                   ;;
21
;;          Mike Hibbett, mikeh@oceanfree.net                   ;;
22
;;                                                              ;;
22
;;                                                              ;;
23
;;  See file COPYING for details                                ;;
23
;;  See file COPYING for details                                ;;
24
;;                                                              ;;
24
;;                                                              ;;
25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26
 
26
 
27
$Revision: 1687 $
27
$Revision: 1941 $
28
 
28
 
29
;***************************************************************************
29
;***************************************************************************
30
;   Function
30
;   Function
31
;      pci_api:
31
;      pci_api:
32
;
32
;
33
;   Description
33
;   Description
34
;       entry point for system PCI calls
34
;       entry point for system PCI calls
35
;***************************************************************************
35
;***************************************************************************
36
align 4
36
align 4
37
mmio_pci_addr	dw  0x100	; default PCI device bdf-address
37
mmio_pci_addr	dw  0x100	; default PCI device bdf-address
38
	dw 0
38
	dw 0
39
 
39
 
40
iglobal
40
iglobal
41
align 4
41
align 4
42
f62call:
42
f62call:
43
	dd	pci_fn_0
43
	dd	pci_fn_0
44
	dd	pci_fn_1
44
	dd	pci_fn_1
45
	dd	pci_fn_2
45
	dd	pci_fn_2
46
	dd	pci_service_not_supported	;3
46
	dd	pci_service_not_supported	;3
47
	dd	pci_read_reg		;4 byte
47
	dd	pci_read_reg		;4 byte
48
	dd	pci_read_reg		;5 word
48
	dd	pci_read_reg		;5 word
49
	dd	pci_read_reg		;6 dword
49
	dd	pci_read_reg		;6 dword
50
	dd	pci_service_not_supported   ;7
50
	dd	pci_service_not_supported   ;7
51
	dd	pci_write_reg		;8 byte
51
	dd	pci_write_reg		;8 byte
52
	dd	pci_write_reg		;9 word
52
	dd	pci_write_reg		;9 word
53
	dd	pci_write_reg		;10 dword
53
	dd	pci_write_reg		;10 dword
54
	dd	pci_mmio_init		;11
54
	dd	pci_mmio_init		;11
55
	dd	pci_mmio_map		;12
55
	dd	pci_mmio_map		;12
56
	dd	pci_mmio_unmap		;13
56
	dd	pci_mmio_unmap		;13
57
endg
57
endg
58
 
58
 
59
align 4
59
align 4
60
pci_api:
60
pci_api:
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
	cmp al, 13
70
	cmp al, 13
71
	ja pci_service_not_supported
71
	ja pci_service_not_supported
72
 
72
 
73
	call	dword [f62call+edx*4]
73
	call	dword [f62call+edx*4]
74
	mov	dword [esp+32],eax
74
	mov	dword [esp+32],eax
75
 
75
 
76
	ret
76
	ret
77
 
77
 
78
align 4
78
align 4
79
pci_api_drv:
79
pci_api_drv:
80
 
80
 
81
    cmp  [pci_access_enabled],1
81
    cmp  [pci_access_enabled],1
82
    jne  .fail
82
    jne  .fail
83
 
83
 
84
    cmp eax, 2
84
    cmp eax, 2
85
    ja	 .fail
85
    ja	 .fail
86
 
86
 
87
    jmp dword [f62call+eax*4]
87
    jmp dword [f62call+eax*4]
88
 
88
 
89
.fail:
89
.fail:
90
    or eax,-1
90
    or eax,-1
91
    ret
91
    ret
92
 
92
 
93
;; ============================================
93
;; ============================================
94
 
94
 
95
pci_fn_0:	; PCI function 0: get pci version (AH.AL)
95
pci_fn_0:	; PCI function 0: get pci version (AH.AL)
96
	movzx eax,word [BOOT_VAR+0x9022]
96
	movzx eax,word [BOOT_VAR+0x9022]
97
	ret
97
	ret
98
 
98
 
99
pci_fn_1:	; PCI function 1: get last bus in AL
99
pci_fn_1:	; PCI function 1: get last bus in AL
100
	mov al,[BOOT_VAR+0x9021]
100
	mov al,[BOOT_VAR+0x9021]
101
	ret
101
	ret
102
 
102
 
103
pci_fn_2:	; PCI function 2: get pci access mechanism
103
pci_fn_2:	; PCI function 2: get pci access mechanism
104
	mov al,[BOOT_VAR+0x9020]
104
	mov al,[BOOT_VAR+0x9020]
105
	ret
105
	ret
106
 
106
 
107
pci_service_not_supported:
107
pci_service_not_supported:
108
	or eax,-1
108
	or eax,-1
109
	mov	dword [esp+32],eax
109
	mov	dword [esp+32],eax
110
	ret
110
	ret
111
 
111
 
112
;***************************************************************************
112
;***************************************************************************
113
;      (for backward compatibility only)
113
;      (for backward compatibility only)
114
;      command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
114
;      command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
115
;***************************************************************************
115
;***************************************************************************
116
align 4
116
align 4
117
pci_make_config_cmd:
117
pci_make_config_cmd:
118
    shl     eax,8	   ; move bus to bits 16-23
118
    shl     eax,8	   ; move bus to bits 16-23
119
    mov     ax,bx	   ; combine all
119
    mov     ax,bx	   ; combine all
120
    and     eax,0xffffff
120
    and     eax,0xffffff
121
    or	    eax,0x80000000
121
    or	    eax,0x80000000
122
    ret
122
    ret
123
 
123
 
124
 
124
 
125
;***************************************************************************
125
;***************************************************************************
126
;   Function
126
;   Function
127
;      pci_read_reg:
127
;      pci_read_reg:
128
;
128
;
129
;   Description
129
;   Description
130
;       read a register from the PCI config space into EAX/AX/AL
130
;       read a register from the PCI config space into EAX/AX/AL
131
;       IN: ah=bus,device+func=bh,register address=bl
131
;       IN: ah=bus,device+func=bh,register address=bl
132
;           number of bytes to read (1,2,4) coded into AL, bits 0-1
132
;           number of bytes to read (1,2,4) coded into AL, bits 0-1
133
;           (0 - byte, 1 - word, 2 - dword)
133
;           (0 - byte, 1 - word, 2 - dword)
134
;***************************************************************************
134
;***************************************************************************
135
 
135
 
136
align 4
136
align 4
137
pci_read_reg:
137
pci_read_reg:
138
;	push	edx
138
;       push    edx
139
;	xor	edx, edx
139
;       xor     edx, edx
140
;	mov	dh,  ah 	; bus
140
;       mov     dh,  ah         ; bus
141
;	mov	dl,  bh 	; dev+fn
141
;       mov     dl,  bh         ; dev+fn
142
;	shl	edx, 12
142
;       shl     edx, 12
143
;	mov	dl,  bl 	; reg
143
;       mov     dl,  bl         ; reg
144
;	add	edx, PCIe_CONFIG_SPACE
144
;       add     edx, PCIe_CONFIG_SPACE
145
;
145
;
146
;	and	al, 2
146
;       and     al, 2
147
;	jz	@f
147
;       jz      @f
148
;	mov	eax, dword[edx]
148
;       mov     eax, dword[edx]
149
;	pop	edx
149
;       pop     edx
150
;	ret
150
;       ret
151
;@@:
151
;@@:
152
;	and	al, 1
152
;       and     al, 1
153
;	jz	@f
153
;       jz      @f
154
;	mov	ax, word[edx]
154
;       mov     ax, word[edx]
155
;	pop	edx
155
;       pop     edx
156
;	ret
156
;       ret
157
;@@:
157
;@@:
158
;	mov	al, byte[edx]
158
;       mov     al, byte[edx]
159
;	pop	edx
159
;       pop     edx
160
;	ret
160
;       ret
161
	push	esi   ; save register size into ESI
161
	push	esi   ; save register size into ESI
162
	mov	esi,eax
162
	mov	esi,eax
163
	and	esi,3
163
	and	esi,3
164
 
164
 
165
	call	pci_make_config_cmd
165
	call	pci_make_config_cmd
166
	mov	ebx,eax
166
	mov	ebx,eax
167
		; get current state
167
		; get current state
168
	mov	dx,0xcf8
168
	mov	dx,0xcf8
169
	in	eax, dx
169
	in	eax, dx
170
	push	eax
170
	push	eax
171
		; set up addressing to config data
171
		; set up addressing to config data
172
	mov	eax,ebx
172
	mov	eax,ebx
173
	and	al,0xfc ; make address dword-aligned
173
	and	al,0xfc ; make address dword-aligned
174
	out	dx,eax
174
	out	dx,eax
175
		; get requested DWORD of config data
175
		; get requested DWORD of config data
176
	mov	dl,0xfc
176
	mov	dl,0xfc
177
	and	bl,3
177
	and	bl,3
178
	or	dl,bl	 ; add to port address first 2 bits of register address
178
	or	dl,bl	 ; add to port address first 2 bits of register address
179
 
179
 
180
	or	esi,esi
180
	or	esi,esi
181
	jz	pci_read_byte1
181
	jz	pci_read_byte1
182
	cmp	esi,1
182
	cmp	esi,1
183
	jz	pci_read_word1
183
	jz	pci_read_word1
184
	cmp	esi,2
184
	cmp	esi,2
185
	jz	pci_read_dword1
185
	jz	pci_read_dword1
186
	jmp	pci_fin_read1
186
	jmp	pci_fin_read1
187
 
187
 
188
pci_read_byte1:
188
pci_read_byte1:
189
	in	al,dx
189
	in	al,dx
190
	jmp pci_fin_read1
190
	jmp pci_fin_read1
191
pci_read_word1:
191
pci_read_word1:
192
	in	ax,dx
192
	in	ax,dx
193
	jmp pci_fin_read1
193
	jmp pci_fin_read1
194
pci_read_dword1:
194
pci_read_dword1:
195
	in	eax,dx
195
	in	eax,dx
196
	jmp	pci_fin_read1
196
	jmp	pci_fin_read1
197
pci_fin_read1:
197
pci_fin_read1:
198
		; restore configuration control
198
		; restore configuration control
199
	xchg	eax,[esp]
199
	xchg	eax,[esp]
200
	mov	dx,0xcf8
200
	mov	dx,0xcf8
201
	out	dx,eax
201
	out	dx,eax
202
 
202
 
203
	pop	eax
203
	pop	eax
204
	pop	esi
204
	pop	esi
205
	ret
205
	ret
206
 
206
 
207
 
207
 
208
 
208
 
209
;***************************************************************************
209
;***************************************************************************
210
;   Function
210
;   Function
211
;      pci_write_reg:
211
;      pci_write_reg:
212
;
212
;
213
;   Description
213
;   Description
214
;       write a register from ECX/CX/CL into the PCI config space
214
;       write a register from ECX/CX/CL into the PCI config space
215
;       IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
215
;       IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
216
;           value to write in ecx
216
;           value to write in ecx
217
;           number of bytes to write (1,2,4) coded into AL, bits 0-1
217
;           number of bytes to write (1,2,4) coded into AL, bits 0-1
218
;           (0 - byte, 1 - word, 2 - dword)
218
;           (0 - byte, 1 - word, 2 - dword)
219
;***************************************************************************
219
;***************************************************************************
220
 
220
 
221
align 4
221
align 4
222
pci_write_reg:
222
pci_write_reg:
223
;	push	edx
223
;       push    edx
224
;	xor	edx, edx
224
;       xor     edx, edx
225
;	mov	dh,  ah 	; bus
225
;       mov     dh,  ah         ; bus
226
;	mov	dl,  bh 	; dev+fn
226
;       mov     dl,  bh         ; dev+fn
227
;	shl	edx, 12
227
;       shl     edx, 12
228
;	mov	dl,  bl 	; reg
228
;       mov     dl,  bl         ; reg
229
;	add	edx, PCIe_CONFIG_SPACE
229
;       add     edx, PCIe_CONFIG_SPACE
230
;
230
;
231
;	test	al, 2
231
;       test    al, 2
232
;	jz	@f
232
;       jz      @f
233
;	mov	dword[edx], ecx
233
;       mov     dword[edx], ecx
234
;	ret
234
;       ret
235
;@@:
235
;@@:
236
;	test	al, 1
236
;       test    al, 1
237
;	jz	@f
237
;       jz      @f
238
;	mov	word[edx], cx
238
;       mov     word[edx], cx
239
;	pop	edx
239
;       pop     edx
240
;	ret
240
;       ret
241
;@@:
241
;@@:
242
;	mov	byte[edx], cl
242
;       mov     byte[edx], cl
243
;	pop	edx
243
;       pop     edx
244
;	ret
244
;       ret
245
	push	esi   ; save register size into ESI
245
	push	esi   ; save register size into ESI
246
	mov	esi,eax
246
	mov	esi,eax
247
	and	esi,3
247
	and	esi,3
248
 
248
 
249
	call	pci_make_config_cmd
249
	call	pci_make_config_cmd
250
	mov	ebx,eax
250
	mov	ebx,eax
251
		; get current state into ecx
251
		; get current state into ecx
252
	mov	dx,0xcf8
252
	mov	dx,0xcf8
253
	in	eax, dx
253
	in	eax, dx
254
	push	eax
254
	push	eax
255
		; set up addressing to config data
255
		; set up addressing to config data
256
	mov	eax,ebx
256
	mov	eax,ebx
257
	and	al,0xfc ; make address dword-aligned
257
	and	al,0xfc ; make address dword-aligned
258
	out	dx,eax
258
	out	dx,eax
259
		; write DWORD of config data
259
		; write DWORD of config data
260
	mov	dl,0xfc
260
	mov	dl,0xfc
261
	and	bl,3
261
	and	bl,3
262
	or	dl,bl
262
	or	dl,bl
263
	mov	eax,ecx
263
	mov	eax,ecx
264
 
264
 
265
	or	esi,esi
265
	or	esi,esi
266
	jz	pci_write_byte1
266
	jz	pci_write_byte1
267
	cmp	esi,1
267
	cmp	esi,1
268
	jz	pci_write_word1
268
	jz	pci_write_word1
269
	cmp	esi,2
269
	cmp	esi,2
270
	jz	pci_write_dword1
270
	jz	pci_write_dword1
271
	jmp	pci_fin_write1
271
	jmp	pci_fin_write1
272
 
272
 
273
pci_write_byte1:
273
pci_write_byte1:
274
	out	dx,al
274
	out	dx,al
275
	jmp pci_fin_write1
275
	jmp pci_fin_write1
276
pci_write_word1:
276
pci_write_word1:
277
	out	dx,ax
277
	out	dx,ax
278
	jmp pci_fin_write1
278
	jmp pci_fin_write1
279
pci_write_dword1:
279
pci_write_dword1:
280
	out	dx,eax
280
	out	dx,eax
281
	jmp	pci_fin_write1
281
	jmp	pci_fin_write1
282
pci_fin_write1:
282
pci_fin_write1:
283
 
283
 
284
		; restore configuration control
284
		; restore configuration control
285
	pop	eax
285
	pop	eax
286
	mov	dl,0xf8
286
	mov	dl,0xf8
287
	out	dx,eax
287
	out	dx,eax
288
	xor	eax,eax
288
	xor	eax,eax
289
	pop	esi
289
	pop	esi
290
	ret
290
	ret
291
 
291
 
292
;***************************************************************************
292
;***************************************************************************
293
;   Function
293
;   Function
294
;      pci_mmio_init
294
;      pci_mmio_init
295
;
295
;
296
;   Description
296
;   Description
297
;       IN:  bx = device's PCI bus address (bbbbbbbbdddddfff)
297
;       IN:  bx = device's PCI bus address (bbbbbbbbdddddfff)
298
;   Returns  eax = phys. address of user-accessible DMA block
298
;   Returns  eax = phys. address of user-accessible DMA block
299
;   Error codes
299
;   Error codes
300
;       eax = -1 : PCI user access blocked,
300
;       eax = -1 : PCI user access blocked,
301
;       eax = -3 : user heap initialization failure
301
;       eax = -3 : user heap initialization failure
302
;***************************************************************************
302
;***************************************************************************
303
pci_mmio_init:
303
pci_mmio_init:
304
    mov     [mmio_pci_addr],bx
304
    mov     [mmio_pci_addr],bx
305
 
305
 
306
    call    init_heap	   ; (if not initialized yet)
306
    call    init_heap	   ; (if not initialized yet)
307
    or	    eax,eax
307
    or	    eax,eax
308
    jz	    @f
308
    jz	    @f
309
    mov     eax, [UserDMAaddr]
309
    mov     eax, [UserDMAaddr]
310
    ret
310
    ret
311
@@:
311
@@:
312
    mov     eax,-3
312
    mov     eax,-3
313
    ret
313
    ret
314
 
314
 
315
 
315
 
316
;***************************************************************************
316
;***************************************************************************
317
;   Function
317
;   Function
318
;      pci_mmio_map
318
;      pci_mmio_map
319
;
319
;
320
;   Description
320
;   Description
321
;       maps a block of PCI memory to user-accessible linear address
321
;       maps a block of PCI memory to user-accessible linear address
322
;
322
;
323
;
323
;
324
;       IN:  ah = BAR#; or
324
;       IN:  ah = BAR#; or
325
;       IN:  ah = 0xDA for DMA-mapping requests;
325
;       IN:  ah = 0xDA for DMA-mapping requests;
326
;       IN: ebx = block size (bytes);
326
;       IN: ebx = block size (bytes);
327
;       IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
327
;       IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
328
;
328
;
329
;   Returns eax = MMIO block's linear address in the userspace (if no error)
329
;   Returns eax = MMIO block's linear address in the userspace (if no error)
330
;
330
;
331
;
331
;
332
;   Error codes
332
;   Error codes
333
;       eax = -1 : user access to PCI blocked,
333
;       eax = -1 : user access to PCI blocked,
334
;       eax = -2 : an invalid BAR register referred
334
;       eax = -2 : an invalid BAR register referred
335
;       eax = -3 : no i/o space on that BAR
335
;       eax = -3 : no i/o space on that BAR
336
;       eax = -4 : a port i/o BAR register referred
336
;       eax = -4 : a port i/o BAR register referred
337
;       eax = -5 : dynamic userspace allocation problem
337
;       eax = -5 : dynamic userspace allocation problem
338
;***************************************************************************
338
;***************************************************************************
339
 
339
 
340
pci_mmio_map:
340
pci_mmio_map:
341
    and     edx,0x0ffff
341
    and     edx,0x0ffff
342
    cmp     ah, 0xDA
342
    cmp     ah, 0xDA
343
    jz	   .dma_map
343
    jz	   .dma_map
344
    cmp     ah,6
344
    cmp     ah,6
345
    jb	   .bar_0_5
345
    jb	   .bar_0_5
346
    jz	   .bar_rom
346
    jz	   .bar_rom
347
    mov     eax,-2
347
    mov     eax,-2
348
    ret
348
    ret
349
 
349
 
350
.dma_map:
350
.dma_map:
351
    push    ecx
351
    push    ecx
352
    mov     ecx,ebx
352
    mov     ecx,ebx
353
    mov     eax,[UserDMAaddr]
353
    mov     eax,[UserDMAaddr]
354
    jmp    .allocate_block
354
    jmp    .allocate_block
355
 
355
 
356
.bar_rom:
356
.bar_rom:
357
    mov    ah, 8	; bar6 = Expansion ROM base address
357
    mov    ah, 8	; bar6 = Expansion ROM base address
358
.bar_0_5:
358
.bar_0_5:
359
    push    ecx
359
    push    ecx
360
    add     ebx, 4095
360
    add     ebx, 4095
361
    and     ebx,-4096
361
    and     ebx,-4096
362
    push    ebx
362
    push    ebx
363
    mov     bl, ah	; bl = BAR# (0..5), however bl=8 for BAR6
363
    mov     bl, ah	; bl = BAR# (0..5), however bl=8 for BAR6
364
    shl     bl, 1
364
    shl     bl, 1
365
    shl     bl, 1
365
    shl     bl, 1
366
    add     bl, 0x10	; now bl = BAR offset in PCI config. space
366
    add     bl, 0x10	; now bl = BAR offset in PCI config. space
367
    mov     eax, dword[mmio_pci_addr]
367
    mov     eax, dword[mmio_pci_addr]
368
    shl     eax, 12
368
    shl     eax, 12
369
    mov     al, bl	; BAR offset
369
    mov     al, bl	; BAR offset
370
    add     eax, PCIe_CONFIG_SPACE
370
    add     eax, PCIe_CONFIG_SPACE
371
    mov     eax, [eax]	; read the BAR
371
    mov     eax, [eax]	; read the BAR
372
    or	    eax, eax
372
    or	    eax, eax
373
    jnz     @f
373
    jnz     @f
374
    mov     eax,-3	; empty I/O space
374
    mov     eax,-3	; empty I/O space
375
    jmp     mmio_ret_fail
375
    jmp     mmio_ret_fail
376
@@:
376
@@:
377
    test    eax, 1
377
    test    eax, 1
378
    jz	    @f
378
    jz	    @f
379
    mov     eax,-4	; damned ports (not MMIO space)
379
    mov     eax,-4	; damned ports (not MMIO space)
380
    jmp     mmio_ret_fail
380
    jmp     mmio_ret_fail
381
@@:
381
@@:
382
    pop     ecx 	; ecx = block size, bytes (expanded to whole page)
382
    pop     ecx 	; ecx = block size, bytes (expanded to whole page)
383
    mov     ebx, ecx	; user_alloc destroys eax, ecx, edx, but saves ebx
383
    mov     ebx, ecx	; user_alloc destroys eax, ecx, edx, but saves ebx
384
    and     eax, 0xFFFFFFF0
384
    and     eax, 0xFFFFFFF0
385
 
385
 
386
.allocate_block:
386
.allocate_block:
387
    push    eax 	; store MMIO physical address + keep the stack 2x4b deep
387
    push    eax 	; store MMIO physical address + keep the stack 2x4b deep
388
    stdcall user_alloc, ecx
388
    stdcall user_alloc, ecx
389
    or	    eax, eax
389
    or	    eax, eax
390
    jnz     mmio_map_over
390
    jnz     mmio_map_over
391
    mov     eax,-5	; problem with page allocation
391
    mov     eax,-5	; problem with page allocation
392
 
392
 
393
mmio_ret_fail:
393
mmio_ret_fail:
394
    pop     ecx
394
    pop     ecx
395
    pop     edx
395
    pop     edx
396
    ret
396
    ret
397
 
397
 
398
mmio_map_over:
398
mmio_map_over:
399
    mov     ecx, ebx	; ecx = size (bytes, expanded to whole page)
399
    mov     ecx, ebx	; ecx = size (bytes, expanded to whole page)
400
    shr     ecx, 12	; ecx = number of pages
400
    shr     ecx, 12	; ecx = number of pages
401
    mov     ebx, eax	; ebx = linear address
401
    mov     ebx, eax	; ebx = linear address
402
    pop     eax 	; eax = MMIO start
402
    pop     eax 	; eax = MMIO start
403
    pop     edx 	; edx = MMIO shift (pages)
403
    pop     edx 	; edx = MMIO shift (pages)
404
    shl     edx, 12	; edx = MMIO shift (bytes)
404
    shl     edx, 12	; edx = MMIO shift (bytes)
405
    add     eax, edx	; eax = uMMIO physical address
405
    add     eax, edx	; eax = uMMIO physical address
406
    or	    eax, (PG_SHARED+PG_UW+PG_NOCACHE)
406
    or	    eax, (PG_SHARED+PG_UW+PG_NOCACHE)
407
    mov     edi, ebx
407
    mov     edi, ebx
408
    call    commit_pages
408
    call    commit_pages
409
    mov     eax, edi
409
    mov     eax, edi
410
    ret
410
    ret
411
 
411
 
412
;***************************************************************************
412
;***************************************************************************
413
;   Function
413
;   Function
414
;      pci_mmio_unmap_page
414
;      pci_mmio_unmap_page
415
;
415
;
416
;   Description
416
;   Description
417
;       unmaps the linear space previously tied to a PCI memory block
417
;       unmaps the linear space previously tied to a PCI memory block
418
;
418
;
419
;       IN: ebx = linear address of space previously allocated by pci_mmio_map
419
;       IN: ebx = linear address of space previously allocated by pci_mmio_map
420
;       returns eax = 1 if successfully unmapped
420
;       returns eax = 1 if successfully unmapped
421
;
421
;
422
;   Error codes
422
;   Error codes
423
;       eax = -1 if no user PCI access allowed,
423
;       eax = -1 if no user PCI access allowed,
424
;       eax =  0 if unmapping failed
424
;       eax =  0 if unmapping failed
425
;***************************************************************************
425
;***************************************************************************
426
 
426
 
427
pci_mmio_unmap:
427
pci_mmio_unmap:
428
    stdcall user_free, ebx
428
    stdcall user_free, ebx
429
    ret
429
    ret
-
 
430
 
-
 
431
 
-
 
432
;------------------------------------------------
-
 
433
align 4
-
 
434
sys_map1:
-
 
435
;       copies a block from kernel to user space
-
 
436
;  in: esi = address in kernel space
-
 
437
;      edi = eddress in user space
-
 
438
;      ebx = count (dwords)
-
 
439
; out: nothing
-
 
440
;------------------------------------------------
-
 
441
	mov     ecx, ebx
-
 
442
        pushfd
-
 
443
	cld
-
 
444
	rep	movsd
-
 
445
	popfd
-
 
446
	ret
-
 
447
 
430
 
448
 
431
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
449
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
432
uglobal
450
uglobal
433
align 4
451
align 4
434
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
452
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
435
pci_emu_dat:	times	30*10 db 0
453
pci_emu_dat:	times	30*10 db 0
436
endg
454
endg
437
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
455
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
438
align 4
456
align 4
439
sys_pcibios:
457
sys_pcibios:
440
	cmp	[pci_access_enabled], 1
458
	cmp	[pci_access_enabled], 1
441
	jne	.unsupported_func
459
	jne	.unsupported_func
442
	cmp	[pci_bios_entry], 0
460
	cmp	[pci_bios_entry], 0
443
	jz	.emulate_bios
461
	jz	.emulate_bios
444
 
462
 
445
	push	ds
463
	push	ds
446
	mov	ax, pci_data_sel
464
	mov	ax, pci_data_sel
447
	mov	ds, ax
465
	mov	ds, ax
448
	mov	eax, ebp
466
	mov	eax, ebp
449
	mov	ah, 0B1h
467
	mov	ah, 0B1h
450
	call	pword [cs:pci_bios_entry]
468
	call	pword [cs:pci_bios_entry]
451
	pop	ds
469
	pop	ds
452
 
470
 
453
	jmp	.return
471
	jmp	.return
454
	;-=-=-=-=-=-=-=-=
472
	;-=-=-=-=-=-=-=-=
455
.emulate_bios:
473
.emulate_bios:
456
	cmp	ebp, 1			; PCI_FUNCTION_ID
474
	cmp	ebp, 1			; PCI_FUNCTION_ID
457
	jnz	.not_PCI_BIOS_PRESENT
475
	jnz	.not_PCI_BIOS_PRESENT
458
	mov	edx, 'PCI '
476
	mov	edx, 'PCI '
459
	mov	al, [OS_BASE+0x2F0000 + 0x9020]
477
	mov	al, [OS_BASE+0x2F0000 + 0x9020]
460
	mov	bx, [OS_BASE+0x2F0000 + 0x9022]
478
	mov	bx, [OS_BASE+0x2F0000 + 0x9022]
461
	mov	cl, [OS_BASE+0x2F0000 + 0x9021]
479
	mov	cl, [OS_BASE+0x2F0000 + 0x9021]
462
	xor	ah, ah
480
	xor	ah, ah
463
	jmp	.return_abcd
481
	jmp	.return_abcd
464
 
482
 
465
.not_PCI_BIOS_PRESENT:
483
.not_PCI_BIOS_PRESENT:
466
	cmp	ebp, 2			; FIND_PCI_DEVICE
484
	cmp	ebp, 2			; FIND_PCI_DEVICE
467
	jne	.not_FIND_PCI_DEVICE
485
	jne	.not_FIND_PCI_DEVICE
468
	mov	ebx, pci_emu_dat
486
	mov	ebx, pci_emu_dat
469
..nxt:	cmp	[ebx], dx
487
..nxt:	cmp	[ebx], dx
470
	jne	..no
488
	jne	..no
471
	cmp	[ebx + 2], cx
489
	cmp	[ebx + 2], cx
472
	jne	..no
490
	jne	..no
473
	dec	si
491
	dec	si
474
	jns	..no
492
	jns	..no
475
	mov	bx, [ebx + 4]
493
	mov	bx, [ebx + 4]
476
	xor	ah, ah
494
	xor	ah, ah
477
	jmp	.return_ab
495
	jmp	.return_ab
478
..no:	cmp	word[ebx], 0
496
..no:	cmp	word[ebx], 0
479
	je	..dev_not_found
497
	je	..dev_not_found
480
	add	ebx, 10
498
	add	ebx, 10
481
	jmp	..nxt
499
	jmp	..nxt
482
..dev_not_found:
500
..dev_not_found:
483
	mov	ah, 0x86		; DEVICE_NOT_FOUND
501
	mov	ah, 0x86		; DEVICE_NOT_FOUND
484
	jmp	.return_a
502
	jmp	.return_a
485
 
503
 
486
.not_FIND_PCI_DEVICE:
504
.not_FIND_PCI_DEVICE:
487
	cmp	ebp, 3			; FIND_PCI_CLASS_CODE
505
	cmp	ebp, 3			; FIND_PCI_CLASS_CODE
488
	jne	.not_FIND_PCI_CLASS_CODE
506
	jne	.not_FIND_PCI_CLASS_CODE
489
	mov	esi, pci_emu_dat
507
	mov	esi, pci_emu_dat
490
	shl	ecx, 8
508
	shl	ecx, 8
491
..nxt2: cmp	[esi], ecx
509
..nxt2: cmp	[esi], ecx
492
	jne	..no2
510
	jne	..no2
493
	mov	bx, [esi]
511
	mov	bx, [esi]
494
	xor	ah, ah
512
	xor	ah, ah
495
	jmp	.return_ab
513
	jmp	.return_ab
496
..no2:	cmp	dword[esi], 0
514
..no2:	cmp	dword[esi], 0
497
	je	..dev_not_found
515
	je	..dev_not_found
498
	add	esi, 10
516
	add	esi, 10
499
	jmp	..nxt2
517
	jmp	..nxt2
500
 
518
 
501
.not_FIND_PCI_CLASS_CODE:
519
.not_FIND_PCI_CLASS_CODE:
502
	cmp	ebp, 8			; READ_CONFIG_*
520
	cmp	ebp, 8			; READ_CONFIG_*
503
	jb	.not_READ_CONFIG
521
	jb	.not_READ_CONFIG
504
	cmp	ebp, 0x0A
522
	cmp	ebp, 0x0A
505
	ja	.not_READ_CONFIG
523
	ja	.not_READ_CONFIG
506
	mov	eax, ebp
524
	mov	eax, ebp
507
	mov	ah, bh
525
	mov	ah, bh
508
	mov	edx, edi
526
	mov	edx, edi
509
	mov	bh, bl
527
	mov	bh, bl
510
	mov	bl, dl
528
	mov	bl, dl
511
	call	pci_read_reg
529
	call	pci_read_reg
512
	mov	ecx, eax
530
	mov	ecx, eax
513
	xor	ah, ah			; SUCCESSFUL
531
	xor	ah, ah			; SUCCESSFUL
514
	jmp	.return_abc
532
	jmp	.return_abc
515
.not_READ_CONFIG:
533
.not_READ_CONFIG:
516
	cmp	ebp, 0x0B		; WRITE_CONFIG_*
534
	cmp	ebp, 0x0B		; WRITE_CONFIG_*
517
	jb	.not_WRITE_CONFIG
535
	jb	.not_WRITE_CONFIG
518
	cmp	ebp, 0x0D
536
	cmp	ebp, 0x0D
519
	ja	.not_WRITE_CONFIG
537
	ja	.not_WRITE_CONFIG
520
	lea	eax, [ebp+1]
538
	lea	eax, [ebp+1]
521
	mov	ah, bh
539
	mov	ah, bh
522
	mov	edx, edi
540
	mov	edx, edi
523
	mov	bh, bl
541
	mov	bh, bl
524
	mov	bl, dl
542
	mov	bl, dl
525
	call	pci_write_reg
543
	call	pci_write_reg
526
	xor	ah, ah			; SUCCESSFUL
544
	xor	ah, ah			; SUCCESSFUL
527
	jmp	.return_abc
545
	jmp	.return_abc
528
.not_WRITE_CONFIG:
546
.not_WRITE_CONFIG:
529
.unsupported_func:
547
.unsupported_func:
530
	mov	ah, 0x81		; FUNC_NOT_SUPPORTED
548
	mov	ah, 0x81		; FUNC_NOT_SUPPORTED
531
.return:mov	dword[esp + 4 ], edi
549
.return:mov	dword[esp + 4 ], edi
532
	mov	dword[esp + 8], esi
550
	mov	dword[esp + 8], esi
533
.return_abcd:
551
.return_abcd:
534
	mov	dword[esp + 24], edx
552
	mov	dword[esp + 24], edx
535
.return_abc:
553
.return_abc:
536
	mov	dword[esp + 28], ecx
554
	mov	dword[esp + 28], ecx
537
.return_ab:
555
.return_ab:
538
	mov	dword[esp + 20], ebx
556
	mov	dword[esp + 20], ebx
539
.return_a:
557
.return_a:
540
	mov	dword[esp + 32], eax
558
	mov	dword[esp + 32], eax
541
	ret
559
	ret