⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcinc.asm

📁 <BIOS研发技术剖析>书的源代码,包括完整的BIOS汇编语言源程序.
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        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 + -