Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1206 → Rev 1376

/kernel/branches/net/bus/pci/pci16.inc
Property changes:
Modified: svn:keywords
-Revision
\ No newline at end of property
+Rev
\ No newline at end of property
Added: svn:mergeinfo
/kernel/branches/net/bus/pci/pci32.inc
30,55 → 30,66
; Description
; entry point for system PCI calls
;***************************************************************************
;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO
 
 
align 4
 
pci_api:
 
cmp [pci_access_enabled],1
jne no_pci_access_for_applications
cmp [pci_access_enabled],1
jne no_pci_access_for_applications
 
or al,al
jnz pci_fn_1
; PCI function 0: get pci version (AH.AL)
movzx eax,word [BOOT_VAR+0x9022]
ret
or al,al
jnz pci_fn_1
; PCI function 0: get pci version (AH.AL)
movzx eax,word [BOOT_VAR+0x9022]
ret
 
pci_fn_1:
cmp al,1
jnz pci_fn_2
cmp al,1
jnz pci_fn_2
 
; PCI function 1: get last bus in AL
mov al,[BOOT_VAR+0x9021]
ret
; PCI function 1: get last bus in AL
mov al,[BOOT_VAR+0x9021]
ret
 
pci_fn_2:
cmp al,2
jne pci_fn_3
; PCI function 2: get pci access mechanism
mov al,[BOOT_VAR+0x9020]
ret
cmp al,2
jne pci_fn_3
; PCI function 2: get pci access mechanism
mov al,[BOOT_VAR+0x9020]
ret
pci_fn_3:
 
cmp al,4
jz pci_read_reg ;byte
cmp al,5
jz pci_read_reg ;word
cmp al,6
jz pci_read_reg ;dword
cmp al,4
jz pci_read_reg ;byte
cmp al,5
jz pci_read_reg ;word
cmp al,6
jz pci_read_reg ;dword
 
cmp al,8
jz pci_write_reg ;byte
cmp al,9
jz pci_write_reg ;word
cmp al,10
jz pci_write_reg ;dword
cmp al,8
jz pci_write_reg ;byte
cmp al,9
jz pci_write_reg ;word
cmp al,10
jz pci_write_reg ;dword
 
if defined mmio_pci_addr
cmp al,11 ; user-level MMIO functions
jz pci_mmio_init
cmp al,12
jz pci_mmio_map
cmp al,13
jz pci_mmio_unmap
end if
 
no_pci_access_for_applications:
 
mov eax,-1
or eax,-1
 
ret
ret
 
;***************************************************************************
; Function
96,10 → 107,10
align 4
 
pci_make_config_cmd:
shl eax,8 ; move bus to bits 16-23
mov ax,bx ; combine all
shl eax,8 ; move bus to bits 16-23
mov ax,bx ; combine all
and eax,0xffffff
or eax,0x80000000
or eax,0x80000000
ret
 
;***************************************************************************
116,120 → 127,120
align 4
 
pci_read_reg:
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_read_reg_2
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_read_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
call pci_make_config_cmd
mov ebx,eax
; get current state
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; get requested DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl ; add to port address first 2 bits of register address
call pci_make_config_cmd
mov ebx,eax
; get current state
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; get requested DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl ; add to port address first 2 bits of register address
 
or esi,esi
jz pci_read_byte1
cmp esi,1
jz pci_read_word1
cmp esi,2
jz pci_read_dword1
jmp pci_fin_read1
or esi,esi
jz pci_read_byte1
cmp esi,1
jz pci_read_word1
cmp esi,2
jz pci_read_dword1
jmp pci_fin_read1
 
pci_read_byte1:
in al,dx
jmp pci_fin_read1
in al,dx
jmp pci_fin_read1
pci_read_word1:
in ax,dx
jmp pci_fin_read1
in ax,dx
jmp pci_fin_read1
pci_read_dword1:
in eax,dx
jmp pci_fin_read1
in eax,dx
jmp pci_fin_read1
pci_fin_read1:
; restore configuration control
xchg eax,[esp]
mov dx,0xcf8
out dx,eax
; restore configuration control
xchg eax,[esp]
mov dx,0xcf8
out dx,eax
 
pop eax
pop esi
ret
pop eax
pop esi
ret
pci_read_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_read_reg_err
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_read_reg_err
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
 
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
 
or esi,esi
jz pci_read_byte2
cmp esi,1
jz pci_read_word2
cmp esi,2
jz pci_read_dword2
jmp pci_fin_read2
or esi,esi
jz pci_read_byte2
cmp esi,1
jz pci_read_word2
cmp esi,2
jz pci_read_dword2
jmp pci_fin_read2
 
pci_read_byte2:
in al,dx
jmp pci_fin_read2
in al,dx
jmp pci_fin_read2
pci_read_word2:
in ax,dx
jmp pci_fin_read2
in ax,dx
jmp pci_fin_read2
pci_read_dword2:
in eax,dx
in eax,dx
; jmp pci_fin_read2
pci_fin_read2:
 
; restore configuration space
xchg eax,[esp]
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
; restore configuration space
xchg eax,[esp]
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
 
pop eax
pop esi
ret
pop eax
pop esi
ret
 
pci_read_reg_err:
xor eax,eax
dec eax
ret
xor eax,eax
dec eax
ret
 
 
;***************************************************************************
247,150 → 258,281
align 4
 
pci_write_reg:
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_write_reg_2
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_write_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
call pci_make_config_cmd
mov ebx,eax
; get current state into ecx
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; write DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl
mov eax,ecx
call pci_make_config_cmd
mov ebx,eax
; get current state into ecx
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; write DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl
mov eax,ecx
 
or esi,esi
jz pci_write_byte1
cmp esi,1
jz pci_write_word1
cmp esi,2
jz pci_write_dword1
jmp pci_fin_write1
or esi,esi
jz pci_write_byte1
cmp esi,1
jz pci_write_word1
cmp esi,2
jz pci_write_dword1
jmp pci_fin_write1
 
pci_write_byte1:
out dx,al
jmp pci_fin_write1
out dx,al
jmp pci_fin_write1
pci_write_word1:
out dx,ax
jmp pci_fin_write1
out dx,ax
jmp pci_fin_write1
pci_write_dword1:
out dx,eax
jmp pci_fin_write1
out dx,eax
jmp pci_fin_write1
pci_fin_write1:
 
; restore configuration control
pop eax
mov dl,0xf8
out dx,eax
; restore configuration control
pop eax
mov dl,0xf8
out dx,eax
 
xor eax,eax
pop esi
xor eax,eax
pop esi
 
ret
ret
pci_write_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_write_reg_err
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_write_reg_err
 
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
; write register
mov eax,ecx
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
; write register
mov eax,ecx
 
or esi,esi
jz pci_write_byte2
cmp esi,1
jz pci_write_word2
cmp esi,2
jz pci_write_dword2
jmp pci_fin_write2
or esi,esi
jz pci_write_byte2
cmp esi,1
jz pci_write_word2
cmp esi,2
jz pci_write_dword2
jmp pci_fin_write2
 
pci_write_byte2:
out dx,al
jmp pci_fin_write2
out dx,al
jmp pci_fin_write2
pci_write_word2:
out dx,ax
jmp pci_fin_write2
out dx,ax
jmp pci_fin_write2
pci_write_dword2:
out dx,eax
jmp pci_fin_write2
out dx,eax
jmp pci_fin_write2
pci_fin_write2:
; restore configuration space
pop eax
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
; restore configuration space
pop eax
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
 
xor eax,eax
pop esi
ret
xor eax,eax
pop esi
ret
 
pci_write_reg_err:
xor eax,eax
dec eax
ret
xor eax,eax
dec eax
ret
 
if defined mmio_pci_addr ; must be set above
;***************************************************************************
; Function
; pci_mmio_init
;
; Description
; IN: bx = device's PCI bus address (bbbbbbbbdddddfff)
; Returns eax = user heap space available (bytes)
; Error codes
; eax = -1 : PCI user access blocked,
; eax = -2 : device not registered for uMMIO service
; eax = -3 : user heap initialization failure
;***************************************************************************
pci_mmio_init:
cmp bx, mmio_pci_addr
jz @f
mov eax,-2
ret
@@:
call init_heap ; (if not initialized yet)
or eax,eax
jz @f
ret
@@:
mov eax,-3
ret
 
 
;***************************************************************************
; Function
; pci_mmio_map
;
; Description
; maps a block of PCI memory to user-accessible linear address
;
; WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only!
; The target device address should be set in kernel var mmio_pci_addr
;
; IN: ah = BAR#;
; IN: ebx = block size (bytes);
; IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
;
; Returns eax = MMIO block's linear address in the userspace (if no error)
;
;
; Error codes
; eax = -1 : user access to PCI blocked,
; eax = -2 : an invalid BAR register referred
; eax = -3 : no i/o space on that BAR
; eax = -4 : a port i/o BAR register referred
; eax = -5 : dynamic userspace allocation problem
;***************************************************************************
 
pci_mmio_map:
and edx,0x0ffff
cmp ah,6
jc .bar_0_5
jz .bar_rom
mov eax,-2
ret
.bar_rom:
mov ah, 8 ; bar6 = Expansion ROM base address
.bar_0_5:
push ecx
add ebx, 4095
and ebx,-4096
push ebx
mov bl, ah ; bl = BAR# (0..5), however bl=8 for BAR6
shl bl, 1
shl bl, 1
add bl, 0x10 ; now bl = BAR offset in PCI config. space
mov ax, mmio_pci_addr
mov bh, al ; bh = dddddfff
mov al, 2 ; al : DW to read
call pci_read_reg
or eax, eax
jnz @f
mov eax,-3 ; empty I/O space
jmp mmio_ret_fail
@@:
test eax, 1
jz @f
mov eax,-4 ; damned ports (not MMIO space)
jmp mmio_ret_fail
@@:
pop ecx ; ecx = block size, bytes (expanded to whole page)
mov ebx, ecx ; user_alloc destroys eax, ecx, edx, but saves ebx
push eax ; store MMIO physical address + keep 2DWords in the stack
stdcall user_alloc, ecx
or eax, eax
jnz mmio_map_over
mov eax,-5 ; problem with page allocation
 
mmio_ret_fail:
pop ecx
pop edx
ret
 
mmio_map_over:
mov ecx, ebx ; ecx = size (bytes, expanded to whole page)
shr ecx, 12 ; ecx = number of pages
mov ebx, eax ; ebx = linear address
pop eax ; eax = MMIO start
pop edx ; edx = MMIO shift (pages)
shl edx, 12 ; edx = MMIO shift (bytes)
add eax, edx ; eax = uMMIO physical address
or eax, PG_SHARED
or eax, PG_UW
or eax, PG_NOCACHE
mov edi, ebx
call commit_pages
mov eax, edi
ret
 
;***************************************************************************
; Function
; pci_mmio_unmap_page
;
; Description
; unmaps the linear space previously tied to a PCI memory block
;
; IN: ebx = linear address of space previously allocated by pci_mmio_map
; returns eax = 1 if successfully unmapped
;
; Error codes
; eax = -1 if no user PCI access allowed,
; eax = 0 if unmapping failed
;***************************************************************************
 
pci_mmio_unmap:
stdcall user_free, ebx
ret
 
end if
 
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
uglobal
align 4
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
pci_emu_dat: times 30*10 db 0
 
endg
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
align 4
sys_pcibios:
xchg ebx, eax
xchg ecx, eax
xchg edx, eax
xchg esi, eax
xchg edi, eax
cmp [pci_access_enabled], 1
jne .unsupported_func
cmp [pci_bios_entry], 0
jne .unsupported_func
cmp [pci_bios_entry], 0
jz .emulate_bios
 
push ds
mov ax, pci_data_sel
mov ds, ax
mov eax, ebp
mov ah, 0B1h
call pword [cs:pci_bios_entry]
pop ds
push ds
mov ax, pci_data_sel
mov ds, ax
mov eax, ebp
mov ah, 0B1h
call pword [cs:pci_bios_entry]
pop ds
 
jmp .return
;-=-=-=-=-=-=-=-=
398,10 → 540,10
cmp ebp, 1 ; PCI_FUNCTION_ID
jnz .not_PCI_BIOS_PRESENT
mov edx, 'PCI '
mov al, [OS_BASE+0x2F0000 + 0x9020]
mov bx, [OS_BASE+0x2F0000 + 0x9022]
mov cl, [OS_BASE+0x2F0000 + 0x9021]
xor ah, ah
mov al, [OS_BASE+0x2F0000 + 0x9020]
mov bx, [OS_BASE+0x2F0000 + 0x9022]
mov cl, [OS_BASE+0x2F0000 + 0x9021]
xor ah, ah
jmp .return_abcd
 
.not_PCI_BIOS_PRESENT:
415,7 → 557,7
dec si
jns ..no
mov bx, [ebx + 4]
xor ah, ah
xor ah, ah
jmp .return_ab
..no: cmp word[ebx], 0
je ..dev_not_found
430,10 → 572,10
jne .not_FIND_PCI_CLASS_CODE
mov esi, pci_emu_dat
shl ecx, 8
..nxt2: cmp [esi], ecx
..nxt2: cmp [esi], ecx
jne ..no2
mov bx, [esi]
xor ah, ah
xor ah, ah
jmp .return_ab
..no2: cmp dword[esi], 0
je ..dev_not_found
445,11 → 587,11
jb .not_READ_CONFIG
cmp ebp, 0x0A
ja .not_READ_CONFIG
mov eax, ebp
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
mov eax, ebp
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_read_reg
mov ecx, eax
xor ah, ah ; SUCCESSFUL
459,11 → 601,11
jb .not_WRITE_CONFIG
cmp ebp, 0x0D
ja .not_WRITE_CONFIG
lea eax, [ebp+1]
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
lea eax, [ebp+1]
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_write_reg
xor ah, ah ; SUCCESSFUL
jmp .return_abc
470,14 → 612,14
.not_WRITE_CONFIG:
.unsupported_func:
mov ah, 0x81 ; FUNC_NOT_SUPPORTED
.return:mov dword[esp + 8 ], edi
mov dword[esp + 12], esi
.return:mov dword[esp + 4 ], edi
mov dword[esp + 8], esi
.return_abcd:
mov dword[esp + 28], edx
mov dword[esp + 24], edx
.return_abc:
mov dword[esp + 32], ecx
mov dword[esp + 28], ecx
.return_ab:
mov dword[esp + 24], ebx
mov dword[esp + 20], ebx
.return_a:
mov dword[esp + 36], eax
mov dword[esp + 32], eax
ret
Property changes:
Modified: svn:keywords
-Revision
\ No newline at end of property
+Rev
\ No newline at end of property
Added: svn:mergeinfo