diff --git a/pci16.inc b/pci16.inc new file mode 100644 index 0000000000..bb04d80d58 --- /dev/null +++ b/pci16.inc @@ -0,0 +1,51 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; PCI16.INC ;; +;; ;; +;; 16 bit PCI driver code ;; +;; ;; +;; Version 0.2 December 21st, 2002 ;; +;; ;; +;; Author: Victor Prodan, victorprodan@yahoo.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision: 593 $ + + +init_pci_16: + + pushad + + xor ax,ax + mov es,ax + mov byte [es:0x9020],1 ;default mechanism:1 + mov ax,0xb101 + int 0x1a + or ah,ah + jnz pci16skip + + mov [es:0x9021],cl ;last PCI bus in system + mov [es:0x9022],bx + mov [es:0x9024],edi + +; we have a PCI BIOS, so check which configuration mechanism(s) +; it supports +; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2) + test al,1 + jnz pci16skip + test al,2 + jz pci16skip + mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2 + +pci16skip: + + mov ax,0x1000 + mov es,ax + + popad diff --git a/pci32.inc b/pci32.inc new file mode 100644 index 0000000000..64a77ae762 --- /dev/null +++ b/pci32.inc @@ -0,0 +1,203 @@ +; 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 +;*************************************************************************** + +align 4 +pci_mmio_map: + and edx,0x0ffff + cmp ah,6 + jc @f + mov eax,-2 + ret +@@: + push ecx + add ebx, 4095 + and ebx,-4096 + push ebx + mov bl, ah ; bl = BAR# (0..5) + shl bl, 1 + shl bl, 1 + add bl, 0x10 ; bl = BARs offset in PCI config. space + mov ax,word [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 ; NEW! +; +; 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 +;*************************************************************************** + +align 4 +pci_mmio_unmap: + stdcall user_free, ebx + ret + + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1) +pci_emu_dat: times 30*10 db 0 + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +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 + 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 + + jmp .return + ;-=-=-=-=-=-=-=-= +.emulate_bios: + 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 + jmp .return_abcd + +.not_PCI_BIOS_PRESENT: + cmp ebp, 2 ; FIND_PCI_DEVICE + jne .not_FIND_PCI_DEVICE + mov ebx, pci_emu_dat +..nxt: cmp [ebx], dx + jne ..no + cmp [ebx + 2], cx + jne ..no + dec si + jns ..no + mov bx, [ebx + 4] + xor ah, ah + jmp .return_ab +..no: cmp word[ebx], 0 + je ..dev_not_found + add ebx, 10 + jmp ..nxt +..dev_not_found: + mov ah, 0x86 ; DEVICE_NOT_FOUND + jmp .return_a + +.not_FIND_PCI_DEVICE: + cmp ebp, 3 ; FIND_PCI_CLASS_CODE + jne .not_FIND_PCI_CLASS_CODE + mov esi, pci_emu_dat + shl ecx, 8 +..nxt2: cmp [esi], ecx + jne ..no2 + mov bx, [esi] + xor ah, ah + jmp .return_ab +..no2: cmp dword[esi], 0 + je ..dev_not_found + add esi, 10 + jmp ..nxt2 + +.not_FIND_PCI_CLASS_CODE: + cmp ebp, 8 ; READ_CONFIG_* + 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 + call pci_read_reg + mov ecx, eax + xor ah, ah ; SUCCESSFUL + jmp .return_abc +.not_READ_CONFIG: + cmp ebp, 0x0B ; WRITE_CONFIG_* + 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 + call pci_write_reg + xor ah, ah ; SUCCESSFUL + jmp .return_abc +.not_WRITE_CONFIG: +.unsupported_func: + mov ah, 0x81 ; FUNC_NOT_SUPPORTED +.return:mov dword[esp + 8 ], edi + mov dword[esp + 12], esi +.return_abcd: + mov dword[esp + 28], edx +.return_abc: + mov dword[esp + 32], ecx +.return_ab: + mov dword[esp + 24], ebx +.return_a: + mov dword[esp + 36], eax + ret