;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RDOS operating system ; Copyright (C) 1988-2000, Leif Ekblad ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. The only exception to this rule ; is for commercial usage in embedded systems. For information on ; usage in commercial embedded systems, contact embedded@rdos.net ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; The author of this program may be contacted at leif@rdos.net ; ; PCI.ASM ; PCI support ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NAME pci GateSize = 16 INCLUDE system.def INCLUDE protseg.def INCLUDE driver.def INCLUDE user.def INCLUDE virt.def INCLUDE os.def INCLUDE system.inc INCLUDE user.inc INCLUDE virt.inc INCLUDE os.inc .386p code SEGMENT byte public use16 'CODE' assume cs:code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GetPciBusCount ; ; DESCRIPTION: Determine number of PCI buses ; ; RETURNS: AL Number of buses ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetPciBusCount Proc near push ebx push ecx push dx ; mov ebx,80000000h mov ecx,80000000h get_pci_bus_count_loop: mov eax,ecx mov dx,0CF8h and al,0FCh cli out dx,eax mov dx,0CFCh in eax,dx sti cmp ax,-1 je get_pci_bus_count_next shr eax,16 cmp ax,-1 je get_pci_bus_count_next ; mov ebx,ecx get_pci_bus_count_next: add ecx,800h cmp ecx,81000000h jne get_pci_bus_count_loop ; shr ebx,16 mov al,bl ; pop dx pop ecx pop ebx ret GetPciBusCount Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ReadPciByte ; ; DESCRIPTION: Read a 8-bit register ; ; PARAMETERS: BH Bus ; BL Device ; CH Function ; CL Register ; ; RETURNS: AL Data ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read_pci_byte_name DB 'Read PCI byte',0 read_pci_byte Proc far push bx push ecx push dx ; mov al,bh mov ah,80h shl eax,16 mov ah,bl shl ah,3 or ah,ch mov al,cl ; and al,0FCh mov dx,0CF8h cli out dx,eax mov dx,0CFCh and cl,3 or dl,cl in al,dx sti ; pop dx pop ecx pop bx ret read_pci_byte Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: write_pci_byte ; ; DESCRIPTION: Write a 8-bit register ; ; PARAMETERS: AL Data ; BH Bus ; BL Device ; CH Function ; CL Register ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; write_pci_byte_name DB 'Write PCI byte',0 write_pci_byte Proc far push eax push bx push ecx push dx ; push ax mov al,bh mov ah,80h shl eax,16 mov ah,bl shl ah,3 or ah,ch mov al,cl ; and al,0FCh mov dx,0CF8h cli out dx,eax mov dx,0CFCh and cl,3 or dl,cl pop ax out dx,al sti ; pop dx pop ecx pop bx pop eax ret write_pci_byte Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ReadPciWord ; ; DESCRIPTION: Read a 16-bit register ; ; PARAMETERS: BH Bus ; BL Device ; CH Function ; CL Register ; ; RETURNS: AX Data ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read_pci_word_name DB 'Read PCI word',0 read_pci_word Proc far push bx push ecx push dx ; mov al,bh mov ah,80h shl eax,16 mov ah,bl shl ah,3 or ah,ch mov al,cl ; and al,0FCh mov dx,0CF8h cli out dx,eax mov dx,0CFCh and cl,2 or dl,cl in ax,dx sti ; pop dx pop ecx pop bx ret read_pci_word Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: WritePciWord ; ; DESCRIPTION: Write a 16-bit register ; ; PARAMETERS: AX Data ; BH Bus ; BL Device ; CH Function ; CL Register ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; write_pci_word_name DB 'Write PCI word',0 write_pci_word Proc far push eax push bx push ecx push dx ; push ax mov al,bh mov ah,80h shl eax,16 mov ah,bl shl ah,3 or ah,ch mov al,cl ; mov dx,0CF8h and al,0FCh cli out dx,eax mov dx,0CFCh and cl,2 or dl,cl pop ax out dx,ax sti ; pop dx pop ecx pop bx pop eax ret write_pci_word Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ReadPciDword ; ; DESCRIPTION: Read a 32-bit register ; ; PARAMETERS: BH Bus ; BL Device ; CH Function ; CL Register ; ; RETURNS: EAX Data ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read_pci_dword_name DB 'Read PCI dword',0 read_pci_dword Proc far push bx push ecx push dx ; mov al,bh mov ah,80h shl eax,16 mov ah,bl shl ah,3 or ah,ch mov al,cl ; mov dx,0CF8h cli out dx,eax mov dx,0CFCh in eax,dx sti ; pop dx pop ecx pop bx ret read_pci_dword Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: WritePciDword ; ; DESCRIPTION: Write a 32-bit register ; ; PARAMETERS: EAX Data ; BH Bus ; BL Device ; CH Function ; CL Register ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; write_pci_dword_name DB 'Write PCI dword',0 write_pci_dword Proc far push eax push bx push ecx push dx ; push eax mov al,bh mov ah,80h shl eax,16 mov ah,bl shl ah,3 or ah,ch mov al,cl ; mov dx,0CF8h cli out dx,eax mov dx,0CFCh pop eax out dx,eax sti ; pop dx pop ecx pop bx pop eax ret write_pci_dword Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FindPciDevice ; ; DESCRIPTION: Find a PCI device ; ; PARAMETERS: CX Device ID ; DX Vendor ID ; AX Device number ; ; RETURNS: NC Success ; BH Bus ; BL Device ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; find_pci_device_name DB 'Find PCI Device',0 find_pci_device Proc far push eax push ecx push dx push si ; mov si,ax mov bx,cx shl ebx,16 mov bx,dx mov ecx,80000000h find_pci_device_loop: mov eax,ecx mov dx,0CF8h and al,0FCh cli out dx,eax mov dx,0CFCh in eax,dx sti cmp eax,ebx jne find_pci_device_next ; or si,si jz find_pci_device_ok ; sub si,1 find_pci_device_next: add ecx,800h cmp ecx,81000000h jne find_pci_device_loop stc jmp find_pci_device_done find_pci_device_ok: mov ebx,ecx shr ebx,8 shr bl,3 clc find_pci_device_done: pop si pop dx pop ecx pop eax ret find_pci_device Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FindPciClass ; ; DESCRIPTION: Write a 32-bit register ; ; PARAMETERS: BH Class ; BL Sub class ; CH Interface ; AX Device number ; ; RETURNS: NC Success ; BH Bus ; BL Device ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; find_pci_class_name DB 'Find PCI Class',0 find_pci_class Proc far push eax push ecx push dx push si ; mov si,ax movzx eax,bx shl eax,16 mov ah,ch mov ebx,eax mov ecx,80000008h find_pci_class_loop: mov eax,ecx mov dx,0CF8h and al,0FCh cli out dx,eax mov dx,0CFCh in eax,dx sti xor al,al cmp eax,ebx jne find_pci_class_next ; or si,si jz find_pci_class_ok ; sub si,1 find_pci_class_next: add ecx,800h cmp ecx,81000000h jne find_pci_class_loop stc jmp find_pci_class_done find_pci_class_ok: mov ebx,ecx shr ebx,8 shr bl,3 clc find_pci_class_done: pop si pop dx pop ecx pop eax ret find_pci_class Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: bios_pci_int ; ; DESCRIPTION: Handling BIOS PCI int (0B1h, int 1Ah) ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bios_pci_int_name DB 'BIOS PCI int',0 pci_error Proc near int 3 or byte ptr [bp].vm_eflags,1 ret pci_error Endp pci_inst_check Proc near mov edx,20494350h xor edi,edi call GetPciBusCount mov cl,al mov eax,[bp].vm_eax xor ax,ax mov word ptr [bp].vm_ebx,210h and byte ptr [bp].vm_eflags,NOT 1 ret pci_inst_check Endp pci_find_device Proc near mov ax,si FindPciDevice jc pci_find_device_fail ; shl bl,3 xor ax,ax mov [bp].vm_ebx,bx and byte ptr [bp].vm_eflags,NOT 1 ret pci_find_device_fail: or byte ptr [bp].vm_eflags,1 mov ax,8600h ret pci_find_device Endp pci_find_class Proc near mov eax,ecx mov cx,si mov ch,al mov bl,ah shr eax,16 mov bh,al FindPciClass jc pci_find_fail ; shl bl,3 xor ax,ax mov [bp].vm_ebx,bx and byte ptr [bp].vm_eflags,NOT 1 ret pci_find_fail: or byte ptr [bp].vm_eflags,1 mov ax,8600h ret pci_find_class Endp pci_read_byte Proc near mov cx,di mov bx,[bp].vm_ebx mov ch,bl and ch,7 shr bl,3 ReadPciByte mov cl,al xor ax,ax and byte ptr [bp].vm_eflags,NOT 1 ret pci_read_byte Endp pci_write_byte Proc near mov al,cl mov cx,di mov bx,[bp].vm_ebx mov ch,bl and ch,7 shr bl,3 WritePciByte xor ax,ax and byte ptr [bp].vm_eflags,NOT 1 ret pci_write_byte Endp pci_read_word Proc near mov cx,di mov bx,[bp].vm_ebx mov ch,bl and ch,7 shr bl,3 ReadPciWord mov cx,ax xor ax,ax and byte ptr [bp].vm_eflags,NOT 1 ret pci_read_word Endp pci_write_word Proc near mov ax,cx mov cx,di mov bx,[bp].vm_ebx mov ch,bl and ch,7 shr bl,3 WritePciWord xor ax,ax and byte ptr [bp].vm_eflags,NOT 1 ret pci_write_word Endp pci_read_dword Proc near mov cx,di mov bx,[bp].vm_ebx mov ch,bl and ch,7 shr bl,3 ReadPciDword mov ecx,eax xor ax,ax and byte ptr [bp].vm_eflags,NOT 1 ret pci_read_dword Endp pci_write_dword Proc near mov eax,ecx mov cx,di mov bx,[bp].vm_ebx mov ch,bl and ch,7 shr bl,3 WritePciDword xor ax,ax and byte ptr [bp].vm_eflags,NOT 1 ret pci_write_dword Endp pci_int_tab: pci00 DW OFFSET pci_error pci01 DW OFFSET pci_inst_check pci02 DW OFFSET pci_find_device pci03 DW OFFSET pci_find_class pci04 DW OFFSET pci_error pci05 DW OFFSET pci_error pci06 DW OFFSET pci_error pci07 DW OFFSET pci_error pci08 DW OFFSET pci_read_byte pci09 DW OFFSET pci_read_word pci0A DW OFFSET pci_read_dword pci0B DW OFFSET pci_write_byte pci0C DW OFFSET pci_write_word pci0D DW OFFSET pci_write_dword pci0E DW OFFSET pci_error pci0F DW OFFSET pci_error bios_pci_int Proc far movzx bx,al cmp bx,10h jnc bios_pci_failed ; add bx,bx call word ptr cs:[bx].pci_int_tab ret bios_pci_failed: or byte ptr [bp].vm_eflags,1 ret bios_pci_int Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: init ; ; DESCRIPTION: INIT PCI DEVICE ; ; PARAMETERS: ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; init Proc far push ds push es pusha mov bx,pci_code_sel InitDevice ; mov ax,cs mov ds,ax mov es,ax ; mov si,OFFSET bios_pci_int mov di,OFFSET bios_pci_int_name xor cl,cl mov ax,bios_pci_int_nr RegisterOsGate ; mov si,OFFSET read_pci_byte mov di,OFFSET read_pci_byte_name xor cl,cl mov ax,read_pci_byte_nr RegisterOsGate ; mov si,OFFSET read_pci_word mov di,OFFSET read_pci_word_name xor cl,cl mov ax,read_pci_word_nr RegisterOsGate ; mov si,OFFSET read_pci_dword mov di,OFFSET read_pci_dword_name xor cl,cl mov ax,read_pci_dword_nr RegisterOsGate ; mov si,OFFSET write_pci_byte mov di,OFFSET write_pci_byte_name xor cl,cl mov ax,write_pci_byte_nr RegisterOsGate ; mov si,OFFSET write_pci_word mov di,OFFSET write_pci_word_name xor cl,cl mov ax,write_pci_word_nr RegisterOsGate ; mov si,OFFSET write_pci_dword mov di,OFFSET write_pci_dword_name xor cl,cl mov ax,write_pci_dword_nr RegisterOsGate ; mov si,OFFSET find_pci_class mov di,OFFSET find_pci_class_name xor cl,cl mov ax,find_pci_class_nr RegisterOsGate ; mov si,OFFSET find_pci_device mov di,OFFSET find_pci_device_name xor cl,cl mov ax,find_pci_device_nr RegisterOsGate ; popa pop es pop ds ret init Endp code ENDS END init