📄 pcinc.asm
字号:
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 + -