📄 pcinc.asm
字号:
page ,132
title . PCI Non Compliant Device Initializer
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
;---------------------------------------;
BAD_VGA_ATTRIBUTE EQU 00000001b; bit-0 = 1 for bad VGA device
IGNORE_BIT3_0_DEV_ID EQU 00010000b; bit-4 = 1 ignore bit3-0 of Device ID
IGNORE_BIT7_4_DEV_ID EQU 00100000b; bit-5 = 1 ignore bit7-4 of Device ID
;---------------------------------------;
include dim.equ
include devnode.equ
include rt.equ
include escd.equ
include pci.equ
include pnp.equ
;---------------------------------------;
public configure_bad_pci_devs
public check_bad_pci_device
;---------------------------------------;
extrn EscdFuncNum: byte
extrn EscdSlotNum: byte
extrn OwnerWork: byte
extrn bad_pci_device_flag:byte
extrn configure_pci_irq: near
extrn dih_pci_get_info: near
extrn dih_pci_check_disabled:near
extrn check_isa_vga:near
;---------------------------------------;
cgroup group _text
_text segment byte public 'CODE'
assume cs:cgroup
.386
;---------------------------------------;
; check_bad_pci_no_disable ;
;---------------------------------------;--------------------------------------;
; This function is called from DI-PCI func_0 just before each device is ;
; disabled. If the device is a non-compliant PCI device that should not be ;
; disabled, then return with CF set. ;
; ;
; Input: ECX = Vendor/Device ID (Vendor ID in lower word, device ID in upper) ;
; ;
; Output: CF = Clear if OK to disable this device ;
; Set if device should not be disabled ;
; ;
; Destroys: Nothing ;
; ;
; NOTE: The difference between this function and dih_pci_prot_dev is: ;
; this routine will protect devices that will not function properly if ;
; they are disabled. But this device will get configured by the PCI code ;
; in the normal initialisation process. For example, Tseng Lab VGA, etc. ;
; ;
; The function dih_pci_prot_dev is to be used to protect a device which ;
; should not be disabled, configured, or touched at all by the PCI code. ;
; For example, on-board PCI chipsets Neptune, Mercury, SIS, etc. ;
;------------------------------------------------------------------------------;
check_bad_pci_no_disable proc near
push eax
push si
mov si, offset cgroup:bad_pci_no_disable_table
check_nodis_next:
db 2eh ;CS:
lodsd ;Get Vendor/Device ID from table
inc eax ;Check for FFFFFFFF
clc
jz check_nodis_done ;Br if at end of table
dec eax
cmp eax, ecx
jne check_nodis_next ;Br if no match
stc ;Do not disable device
check_nodis_done:
pop si
pop eax
ret
check_bad_pci_no_disable endp
;---------------------------------------;
; bad_pci_no_disable_table ;
;---------------------------------------;--------------------------------------;
; This table contains an entry for each PCI device that should not be disabled.;
; It is used by the routine check_bad_pci_no_disable. Each entry in the table ;
; is a dword, with the upper word containing the PCI device's ID and the lower ;
; word containing the PCI device's Vendor ID. The table must end with a dword ;
; set to 0FFFFFFFFh. ;
;------------------------------------------------------------------------------;
bad_pci_no_disable_table:
dd 3202100ch ;TSENG LAB ET4000 VGA card
dd 3207100ch ;TSENG LAB ET4000 VGA card
dd 05301039h ;Host Bridge for SiS 530
dd 0FFFFFFFFh ;End of table marker
;---------------------------------------;
; configure_bad_pci_devs ;
;---------------------------------------;--------------------------------------;
; This function steps through the bad_pci_device_table for any devices that ;
; may be present in the system. If a device is found that has an entry in the ;
; table, then it is configured and the resources that the device uses are ;
; allocated. ;
; ;
; Input: DS = ES = _dimdata Segment ;
; SI = Offset of the NVRam workspace (in _dimdata seg) ;
; ;
; Output: Nothing ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
configure_bad_pci_devs proc near
pushad
mov bp, si
mov EscdFuncNum, 0 ;Make sure we don't use ESCD data
mov EscdSlotNum, INVALID_SLOT_NUM
; search for the device presence in all dev# (0-1F) in func#0, Bus# 0 only
xor bx, bx ;BH = Bus#, BL bit7-3 = Dev#
; bit2-0 = Func#
bad_pci_continue:
mov ecx, 0ffffffffh ;Init Device ID, Vendor ID
mov di, PCI_REG_VENDID
mov ah, RT_PCI_READ_CFG_DWORD
CALL_RT_FUNCTION ;ECX = Device ID, Vendor ID from PCI Bus
mov dx, cx ;DX = Vendor ID from PCI Bus
shr ecx, 16 ;CX = Device ID from PCI Bus
mov di, offset cgroup:bad_pci_device_table
bad_pci_next_entry:
; DX, CX = Vendor ID, Device ID
; CS:DI = Offset of the entry in bad_pci_device_table
cmp byte ptr cs:[di], 0 ;Look at size of this entry
jz bad_pci_not_found ;Br if no more device entry in table
call check_vendor_device_id ;Vendor ID and Device ID match ?
jnz bad_pci_not_this_entry ;Br if does not match
; Vendor ID, Device ID matches with an entry in the table
; BH, (BL) = Bus#, (device#, func#)
; DX, CX = Vendor ID, Device ID
; CS:DI = Offset of the entry in bad_pci_device_table
; BP = Offset of the NVRam workspace (in _dimdata seg)
; DS = ES = _dimdata Segment
; extrn dih_check_offboard_vga:near
; call dih_check_offboard_vga ;12/18/96
; jc bad_pci_not_this_entry ;Br if to keep it disabled..12/18/96
call dih_pci_check_disabled
jc bad_pci_not_this_entry ;Br if device is not present
call init_bad_pci_device ;Try to initialize the device
bad_pci_not_this_entry:
movzx ax, byte ptr cs:[di] ;AX = length of this entry in the table
add di, ax ;ptr to next entry
jmp short bad_pci_next_entry
bad_pci_not_found:
add bl, 08h
jnz bad_pci_continue ;try the next device#
popad
ret
;---------------------------------------; 02/14/96
configure_bad_pci_devs endp
;---------------------------------------;
; check_vendor_device_id ;
;---------------------------------------;--------------------------------------;
; This function finds whther the given Vendor ID and Device ID is present in ;
; the bad_pci_device_table. ;
; ;
; Input: DX = Vendor ID of device ;
; CX = Device ID of device ;
; DI = Offset of the entry in bad_pci_device_table (in CS) ;
; Output: Zero Flag Set (ZR) means match found ;
; Zero Flag ReSet (NZ) means match not found ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
check_vendor_device_id proc near
pusha
cmp dx, cs:[di+1] ;Vendor ID matches ?
jnz check_vendor_device_done;Br if Vendor ID does not match
; 05/15/96 Meaning of upper four bits in attribute field is different
; than how it is treated in the previous code.
; mov al, cs:[di+5] ;Previous code 05/15/96 ;AL = attribute from table
; and ax, 00f0h ;Previous code 05/15/96 ;Save Device ID bit info to ignore
; shr al, 04h ;Previous code 05/15/96 ;AX = bit mask to ignore in Device ID
; not ax ;Previous code 05/15/96 ;AX = AND mask for Device ID
mov ax,0ffffh ;AX = AND mask for Device ID
test byte ptr cs:[di+5],IGNORE_BIT3_0_DEV_ID ;Ignore bits 3-0 of Device ID?
jz short @f ;Br if checking bits 3-0
and al,0f0h ;Mask off bits 3-0
@@:
test byte ptr cs:[di+5],IGNORE_BIT7_4_DEV_ID ;Ignore bits 7-4 of Device ID?
jz short @f ;Br if checking bits 7-4
and al,00fh ;Mask off bits 7-4
@@:
mov bx, cs:[di+3] ;Get Device ID from table
and bx, ax ;Mask off Device ID from table
and ax, cx ;Mask off Device ID from PCI Bus
; Should compare AX with BX here.
; cmp ax, cx ;Previous code 05/15/96 ;Device ID matches ?
cmp ax, bx ;Device ID matches ?
check_vendor_device_done:
popa
ret
check_vendor_device_id endp
;---------------------------------------;
; init_bad_pci_device ;
;---------------------------------------;--------------------------------------;
; This function configures one non-compliant PCI device using resource data ;
; from the bad_pci_device_table. All resources used by the device are ;
; allocated. ;
; ;
; Input: BL = Device/Function number to initialize ;
; Bits 7-3: PCI device number ;
; Bits 2-0: Function number within the device ;
; BH = Bus number of device to initialize ;
; DX = Vendor ID of device ;
; CX = Device ID of device ;
; DI = Offset of the entry in bad_pci_device_table (in CS) ;
; BP = Offset of the NVRam workspace (in _dimdata seg) ;
; DS = ES = _dimdata Segment ;
; ;
; Output: Nothing ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
init_bad_pci_device proc near
pushad
mov si, di
push si ;Save start of table entry
mov di, offset OwnerWork ;Use this global as workspace
mov (owner_pci ptr [di]).own_pci_sig, OWNTYPE_PCI
mov (owner_pci ptr [di]).own_pci_bus, bh
mov (owner_pci ptr [di]).own_pci_devfunc, bl
shl ecx, 16 ;Combine Vendor/Dev ID
mov cx, dx ;Also fills in own_pci_devid
mov dword ptr (owner_pci ptr [di]).own_pci_vendid, ecx
cmp ecx, 0140104bh ; Buslogic SCSI Vendor/Device ID.
jnz @f
mov (owner_pci ptr [di]).own_pci_sig, OWNTYPE_ISA
@@:
mov (owner_pci ptr [di]).own_pci_rsvd, 0
; Allocate I/O port entries
add si, 7 ;SI = ptr to # of I/O port entries
movzx cx, byte ptr cs:[si] ;CX = number of I/O port entries
inc si ;SI = ptr to cfg space reg
jcxz bad_dev_no_ports
bad_dev_next_port:
push cx ;Save number of I/O port entries
push si ;Save ptr to cfg space reg
inc si ;SI = ptr length of I/O port block
mov dx, cs:[si] ;DX = length of I/O port block
inc si
inc si ;SI = ptr to number of options
movzx cx, byte ptr cs:[si] ;CX = number of options
inc si ;SI = ptr to 1st base addr option
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -