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

📄 pcinc.asm

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

; For doing PCI compliant I/O parsing.
; The resource manager returns the allocated resource in AX, so save all
; registers besides AX on the stack.
        push    bx                      ;
        push    cx                      ;
        push    dx                      ;
        push    di                      ;
        push    si                      ;
        push    bp                      ;

        mov     cx, cs:[si]             ;CX = base addr of I/O port block
        mov     bx, cx                  ;BX also = base addr
        mov     si, 1                   ;Alignment = byte

; For doing PCI compliant I/O parsing
; If requested I/O range (CX) = 0ffffh, then treat this resource for the
; noncompliant card as a PCI compliant resource.
        cmp     cx, 0ffffh              ;PCI compliant?
        jne     short non_pci_compliant_io
        xor     bx, bx                  ;BX=Min base addr = 00000h
        mov     cx, dx                  ;CX=Size of I/O range
        dec     cx                      ;CX=Size of I/O range - 1
        not     cx                      ;CX=properly aligned max I/O address.
        mov     si, dx                  ;SI=Size of I/O range
non_pci_compliant_io:

        mov     ax, (RM_ALLOC_PORT * 100h) + RESFLAG_PORT_DECODE16
        CALL_RESMGR                     ;Call Resource Manager to allocate port

; For doing PCI compliant I/O parsing.
; The resource manager returns the allocated resource in AX, so restore all
; registers besides AX from the stack.
        pop     bp                      ;
        pop     si                      ;
        pop     di                      ;
        pop     dx                      ;
        pop     cx                      ;
        pop     bx                      ;

        jnc     bad_dev_prog_port       ;Br if alloc succeeded
        inc     si
        inc     si                      ;SI = ptr to next base addr option
        loop    bad_dev_next_p_option   ;Try all options
        pop     si                      ;Balance stack
        pop     cx
        jmp     bad_dev_conflict        ;Br if unresolvable conflict

bad_dev_prog_port:
        pop     si                      ;Restore ptr to cfg space reg
        push    di                      ;Save ptr to owner_pci struc
        movzx   di, byte ptr cs:[si]    ;DI = offset within cfg space
        movzx   ecx, ax                 ;ECX = base addr of I/O port block
        mov     ah, RT_PCI_WRITE_CFG_DWORD
        CALL_RT_FUNCTION                ;Write ECX to cfg register
        pop     di                      ;Restore ptr to owner_pci struc
        pop     cx                      ;Restore number of I/O port entries

        movzx   ax, byte ptr cs:[si+3]  ;Get option count (number of words)
        shl     ax, 1                   ;AX = number of bytes of options
        add     si, 4                   ;Add 4 bytes for fixed info
        add     si, ax                  ;Add [ax] bytes for options
                                        ;SI now ptr to next cfg space register
        loop    bad_dev_next_port
bad_dev_no_ports:

; Allocate memory entries

        movzx   cx, byte ptr cs:[si]    ;CX = number of memory entries
        inc     si                      ;SI = ptr to cfg space reg

        or      cx,cx                   ;CX = 0?
        jz      bad_dev_no_memory       ;Br if there are no memory entries

bad_dev_next_memory:
        push    cx                      ;Save number of memory entries
        push    si                      ;Save ptr to cfg space reg

        inc     si                      ;SI = ptr length of memory block
        mov     edx, cs:[si]            ;EDX = length of memory block
        add     si, 4
        movzx   cx, byte ptr cs:[si]    ;CX = number of options

        inc     si                      ;SI = ptr to 1st base addr option
bad_dev_next_m_option:
        pop     ax                      ;Get copy of ptr to base add reg
        push    ax

; For doing PCI compliant memory parsing
; The resource manager returns the allocated resource in EAX, so save all
; registers besides EAX on the stack.
        push    ebx                     ;
        push    ecx                     ;
        push    edx                     ;
        push    edi                     ;
        push    esi                     ;
        push    ebp                     ;

        mov     bx, ax                  ;BX = ptr to base add reg
        mov     ax, (RM_ALLOC_MEM * 100h) + 0   ;Assume memory is not a ROM
        mov     ecx, cs:[si]            ;ECX = base addr of memory block
        cmp     byte ptr cs:[bx], 30h
        jne     @f                      ;Br if not programming exp rom reg
        cmp     ecx, 100000h
        jb      @f                      ;Br if address is below 1MB
        or      al, RESFLAG_MEM_EXP_ROM ;Allocate memory as exp ROM to copy down
@@:
        mov     ebx, ecx                ;EBX also = base addr
        mov     esi, 1                  ;Alignment = byte

; For doing PCI compliant memory parsing
; If requested memory range (ECX) = 0ffffffffh, then treat this resource
; for the noncompliant card as a PCI compliant resource.
        cmp     ecx, 0ffffffffh         ;PCI compliant?
        jne     short non_pci_compliant_mem
        xor     ebx, ebx                ;EBX=Min base addr = 00000000h
        mov     ecx, edx                ;ECX=Size of memory range
        dec     ecx                     ;ECX=Size of memory range - 1
        not     ecx                     ;ECX=properly aligned max memory address.
        mov     esi, edx                ;ESI=Size of memory range
non_pci_compliant_mem:

        CALL_RESMGR                     ;Call Resource Manager to allocate port

; For doing PCI compliant memory parsing
; The resource manager returns the allocated resource in EAX, so restore all
; registers besides EAX from the stack.
        pop     ebp                     ;
        pop     esi                     ;
        pop     edi                     ;
        pop     edx                     ;
        pop     ecx                     ;
        pop     ebx                     ;

        jnc     bad_dev_prog_memory     ;Br if alloc succeeded
        add     si, 4                   ;SI = ptr to next base addr option
        loop    bad_dev_next_m_option   ;Try all options
        pop     si                      ;Balance stack
        pop     cx
        jmp     bad_dev_conflict        ;Br if unresolvable conflict

bad_dev_prog_memory:
        pop     si                      ;Restore ptr to cfg space reg
        push    di                      ;Save ptr to owner_pci struc
        movzx   di, byte ptr cs:[si]    ;DI = offset within cfg space
        mov     ecx, eax                ;ECX = base addr of memory block
        cmp     di, 30h
        jne     bad_dev_not_exp_rom     ;Br if not programming exp rom reg
        or      cl, 1                   ;Turn on exp rom enable bit
bad_dev_not_exp_rom:
        mov     ah, RT_PCI_WRITE_CFG_DWORD
        CALL_RT_FUNCTION                ;Write ECX to cfg register
        pop     di                      ;Restore ptr to owner_pci struc
        pop     cx                      ;Restore number of memory entries

        movzx   ax, byte ptr cs:[si+5]  ;Get option count (number of dwords)
        shl     ax, 2                   ;AX = number of bytes of options
        add     si, 6                   ;Add 6 bytes for fixed info for memory info
        add     si, ax                  ;Add [ax] bytes for options
                                        ;SI now ptr to next cfg space register

        dec     cx                      ;
        jnz     bad_dev_next_memory     ;

bad_dev_no_memory:

; Allocate IRQ entry

        pop     si
        push    si
        add     si, 6                   ;Point DI to IRQ entry
        db      2Eh                     ;CS:
        lodsb                           ;Get IRQ byte
        or      al, al

        jnz     bad_dev_irq             ;Br if device needs IRQ
        mov     di, PCI_REG_INT_LINE    ;DI=IRQ reg. (03ch)
        mov     cl, 0ffh                ;CL=Unknown/Unrouted IRQ.
        mov     ah, RT_PCI_WRITE_CFG_BYTE
        CALL_RT_FUNCTION                ;Write CL to cfg register
        jmp     short bad_dev_no_irq    ;
bad_dev_irq:

        mov     dh, al                  ;DH = IRQ needed / FF for any IRQ
        mov     dl, 1                   ;Int Pin reg value (assume INTA)
        push    si                      ;Save SI
        mov     si, bp                  ;SI = ptr to NVRam workspace
        call    configure_pci_irq       ;Returns alloc'd IRQ in CL
        pop     si                      ;Restore SI
        jnc     bad_dev_no_irq          ;Br if alloc'd IRQ ok
        jmp     bad_dev_conflict        ;Br if unresolvable conflict
bad_dev_no_irq:

        ;Finally, initialize the Max Latency and Cache Line Size registers, and
        ;then enable the device by writing to its command register.

        call    dih_pci_get_info        ;Returns AL=Latency val, AH=Cache Line

        mov     cx, ax                  ;CL = value to write to Latency reg
        mov     di, PCI_REG_LATENCY
        mov     ah, RT_PCI_WRITE_CFG_BYTE
        CALL_RT_FUNCTION                ;Write CL to Max Lat register

        xchg    cl, ch                  ;CL = value to write to Cache Ln Sz reg
        mov     di, PCI_REG_LINE_SIZE
        mov     ah, RT_PCI_WRITE_CFG_BYTE
        CALL_RT_FUNCTION                ;Write CL to Cache Line Size register

        mov     cx, STAT_RESET_ALL      ;Reset all status bits
        mov     di, PCI_REG_STATUS
        mov     ah, RT_PCI_WRITE_CFG_WORD
        CALL_RT_FUNCTION                ;Write CX to status register

        pop     si                      ;ptr to start of bad device table
        push    si
        test    cs:byte ptr [si+5], BAD_VGA_ATTRIBUTE;VGA ?
        jz      bad_not_vga             ;Br if not

        mov     di, offset OwnerWork
        mov     ah, RM_ALLOC_STD_VGA
        CALL_RESMGR                     ;Allocate standard VGA resources

        xor     cx, cx                  ;Command register value
        test    ds:byte ptr bad_pci_device_flag, BAD_VGA_ATTRIBUTE;Any VGA already enabled ?
        jnz     bad_vga_done            ;Br if done already
        mov     ds:byte ptr bad_pci_device_flag, BAD_VGA_ATTRIBUTE
	call	check_isa_vga
        jz      short bad_vga_done
	extrn	q_pri_display_card:abs
	mov	al,q_pri_display_card
;	call	check_cmos_data_far
        db      9ah                     ; CALL FAR F000:EED5
        dw      0eed5h
        dw      0f000h
	jz	short bad_not_vga
	push	cx
	push	si
	mov	ecx, BT_DISPLAY * 100h * 100h
	sub	si,si
	mov	ah,RT_PCI_FIND_CLASS
        CALL_RT_FUNCTION
	pop	si
	pop	cx
	jc	short bad_not_vga
	or	bh,bh
	jnz	short bad_vga_done
bad_not_vga:
        mov     cx, CMD_IO_SPACE + CMD_MEM_SPACE + CMD_BUS_MASTER + CMD_SPECIAL_CYCLE + CMD_MEM_INVALIDATE + CMD_SERR
bad_vga_done:
        mov     di, PCI_REG_COMMAND
        mov     ah, RT_PCI_WRITE_CFG_WORD
        CALL_RT_FUNCTION                ;Write CX to command register

        clc                             ;Indicate success
        jmp     short bad_dev_done

bad_dev_conflict:
        ;An unresolvable conflict has occurred, so zero out all base address
        ;registers, the exp ROM register, the Int Line register and the
        ;command register.

        mov     di, PCI_REG_FIRST_BASE_ADD
        xor     ecx, ecx                ;Write 0 to the upper half of 64 bit reg
                                        ;BH/BL has bus/device/function number
config_dev_base_clear:
        mov     ah, RT_PCI_WRITE_CFG_DWORD
        CALL_RT_FUNCTION                ;Clear base add reg
        add     di, 4                   ;Point to next base address register
        cmp     di, PCI_REG_LAST_BASE_ADD
        jbe     config_dev_base_clear   ;Br if more base address registers

        mov     di, PCI_REG_ROM_BASE_ADD
        mov     ah, RT_PCI_WRITE_CFG_DWORD
        CALL_RT_FUNCTION                ;Clear Exp ROM reg

        mov     di, PCI_REG_INT_LINE
        mov     ah, RT_PCI_WRITE_CFG_BYTE
        CALL_RT_FUNCTION                ;Clear Int Line reg

        mov     di, PCI_REG_COMMAND
        mov     ah, RT_PCI_WRITE_CFG_WORD
        CALL_RT_FUNCTION                ;Clear command register

        mov     di, offset OwnerWork    ;Point ES:DI to owner_pci structure
        mov     ah, RM_FREE_DEVICE
        CALL_RESMGR                     ;Call ResMgr free device's resources

        stc                             ;Indicate failure

bad_dev_done:
        pop     si                      ;Get rid of ptr to table entry on stack
        popad
        ret
init_bad_pci_device     endp


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -