📄 nrunpci.asm
字号:
else
push ebx ;Save Bus/Dev/Func #
call dummy ;Push EIP on stack
dummy: pop ebx ;EBX = EIP = xxxx0000 + offset dummy
sub ebx, offset cs:dummy ;EBX = xxxx0000
movzx esi, word ptr [ebx+0E009h]
movzx esi, word ptr [esi+ebx+0E00Ch-0FFFFh] ;ESI points to rth_pci_device_limit
add esi, ebx
movzx ecx, byte ptr [esi+1] ;ECX = rth_pci_device_count
add esi, 4 ;ESI points to rth_pci_irq_routing_table
pop ebx ;Restore Bus/Dev/Func #
endif
and bl, 0F8h ;Zero out function number
xchg bh, bl ;Swap Bus # and Dev # to match table
get_irq_next_dev:
cmp word ptr ((pci_irq_entry ptr [esi]).pirq_bus_number), bx
je get_irq_found_dev ;Br if found proper bus#/dev#
add esi, size pci_irq_entry ;ESI points to next entry in table
loop get_irq_next_dev
stc ;Indicate error
jmp short get_irq_done
get_irq_found_dev:
lea esi, (pci_irq_entry ptr [esi]).pirq_inta_reg
dec dl ;DL = 0/1/2/3 for Int A/B/C/D
mov dh, dl
shl dl, 2 ;DL = 0/4/8/C for Int A/B/C/D
sub dl, dh ;DL = 0/3/6/9 for Int A/B/C/D
movzx ebx, dl ;EBX = 0/3/6/9 for Int A/B/C/D
add esi, ebx ;ESI points to chipset reg value
mov al, byte ptr [esi] ;AL = chipset reg value
mov dx, word ptr [esi+1] ;DX = bitmap of routable IRQs
clc
get_irq_done:
pop esi
pop ecx
pop ebx
ret
assume ds:nothing
endproc rth_pci_get_irq_reg
;---------------------------------------;
; rth_pci_search_xlat ; MOVED TO OEMRPCI.ASM
;---------------------------------------;
; rth_pci_get_last_bus ;
;---------------------------------------;--------------------------------------;
; This function returns the number of the last PCI bus in the system. If the ;
; system has one PCI bus this function should return 0. ;
; ;
; NOTE: This function does not need to be modified for most platforms. ;
; ;
; NOTE: This function is assembled twice, once for real mode code, and once ;
; for 32 bit protected mode code. All calls must be made using the ;
; callproc macro. Do not modify and segment registers. ;
; ;
; Input: None ;
; ;
; Output: CL = Bus number of last PCI bus ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
extproc rtpci_read_cfg_word
defproc rth_pci_get_last_bus
push ax
push bx
push dx
push di
push cx ;Keep this last on stack
xor dl, dl ;Default Max Bus is 0
mov bx, 0000h ;Bus 0 / Device 00 / Func 0
last_bus_next_dev:
mov di, PCI_REG_SUB_TYPE
callproc rtpci_read_cfg_word ;Returns Base class / Sub class in CX
jc last_bus_skip_dev ;Br if error reading CFG space
cmp cx, (BT_BRIDGE * 100h) + ST_PCI_BR
jne last_bus_skip_dev ;Br if not a PCI-PCI bridge
mov di, PPB_REG_SUB_BUS_NUM
callproc rtpci_read_cfg_byte ;Returns Subordinate bus # in CL
jc last_bus_skip_dev ;Br if error reading CFG space
cmp cl, dl
jbe last_bus_skip_dev ;Br if <= current Max Bus #
mov dl, cl ;Update Max Bus #
last_bus_skip_dev:
add bl, 8 ;Next PCI device
jnc last_bus_next_dev ;Try device 00 - 1F (BL = 00 - F8)
pop cx
mov cl, dl
pop di
pop dx
pop bx
pop ax
ret
endproc rth_pci_get_last_bus
;---------------------------------------;
; rth_pci_get_hw_mech ;
;---------------------------------------;--------------------------------------;
; This function returns the hardware mechanisms supported by this system. ;
; Any of the following constants can be used: ;
; PCI_SPEC_CYCLE_M1, PCI_CFG_SPACE_M1 ;
; PCI_SPEC_CYCLE_M2, PCI_CFG_SPACE_M2 ;
; ;
; NOTE: This function is assembled twice, once for real mode code, and once ;
; for 32 bit protected mode code. All calls must be made using the ;
; callproc macro. Do not modify and segment registers. ;
; ;
; Input: None ;
; ;
; Output: AL = Hardware mechanisms supported by this system: ;
; Bit 7-6: Reserved ;
; Bit 5: If 1, special cycle mechanism 2 is supported ;
; Bit 4: If 1, special cycle mechanism 1 is supported ;
; Bit 3-2: Reserved ;
; Bit 1: If 1, configuration space mechanism 2 is supported ;
; Bit 0: If 1, configuration space mechanism 1 is supported ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
defproc rth_pci_get_hw_mech
mov al, PCI_CFG_SPACE_M1 ;Config mechanism 1 is default
ret
endproc rth_pci_get_hw_mech
;---------------------------------------;
; rth_pci_special_cycle ;
;---------------------------------------;--------------------------------------;
; This function is used to generate a special cycle on the specified PCI bus. ;
; A special cycle "broadcasts" the data to all PCI devices on a bus. The bus ;
; number must be checked and carry should be set if the bus number is invalid. ;
; ;
; NOTE: Special cycle is not supported here. Modify this function only if ;
; special cycle support is needed. ;
; ;
; NOTE: This function is assembled twice, once for real mode code, and once ;
; for 32 bit protected mode code. All calls must be made using the ;
; callproc macro. Do not modify and segment registers. ;
; ;
; Input: BH = PCI bus number ;
; EDX = Special cycle data ;
; ;
; Output: CF = Set if error, cleared otherwise ;
; AH = Non zero return code if CF set (see RT.EQU) ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
defproc rth_pci_special_cycle
mov ah, RT_INVALID_FUNC
stc
ret
endproc rth_pci_special_cycle
;---------------------------------------;
; rth_pci_read_cfg ;
;---------------------------------------;--------------------------------------;
; This function reads a dword from the configuration space of given device / ;
; function. The bus number must be checked and carry should be set if the bus ;
; number is invalid. ;
; ;
; NOTE: This function should only be called from RT-PCI.ASM. All other ;
; callers must call the rt_entry (in RT.ASM) with AH containing the proper ;
; function number (see RT.EQU). ;
; ;
; Input: BH = PCI Bus number ;
; BL = Device / Function number ;
; Bits 7-3: PCI device number ;
; Bits 2-0: Function number within the device ;
; DI = Register number (must be dword aligned address, this value has ;
; already been checked for validity) ;
; SI = One of the following values: PCI_REG_ADDRESS_BYTE ;
; PCI_REG_ADDRESS_WORD, or PCI_REG_ADDRESS_DWORD ;
; ;
; Output: ECX, CX, CL = Data read from configuration space (width depends on ;
; value of SI on entry) ;
; CF = Set if error, cleared otherwise ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
defproc rth_pci_read_cfg
push eax
push dx
mov ah, 80h ;Set enable bit
mov al, bh
shl eax, 16
mov ax, di ;Add in register offset part
mov ah, bl ;Add in dev/func num part
and al, 0FCh ;Make address dword aligned
mov dx, CFG_SPACE_INDEX_REG
pushf ;Save current state of IF and CLI
cli
out dx, eax ;Set the index
mov dx, di ;Get original config register address
and dx, 03h ;Isolate lower 2 bits
add dx, CFG_SPACE_DATA_REG ;Add offset (0/1/2/3) to data addr
cmp si, PCI_REG_ADDRESS_BYTE
jne read_cfg_try_word
in al, dx ;Read the config register
mov cl, al
jmp short read_cfg_done
read_cfg_try_word:
cmp si, PCI_REG_ADDRESS_WORD
jne read_cfg_try_dword
in ax, dx ;Read the config register
mov cx, ax
jmp short read_cfg_done
read_cfg_try_dword:
in eax, dx ;Read the config register
mov ecx, eax
read_cfg_done:
popf ;Restore state of IF
pop dx
pop eax
clc
ret
endproc rth_pci_read_cfg
;---------------------------------------;
; rth_pci_write_cfg ;
;---------------------------------------;--------------------------------------;
; This function writes a dword to the configuration space of given device / ;
; function. The bus number must be checked and carry should be set if the bus ;
; number is invalid. ;
; ;
; NOTE: This function should only be called from RT-PCI.ASM. All other ;
; callers must call the rt_entry (in RT.ASM) with AH containing the proper ;
; function number (see RT.EQU). ;
; ;
; Input: BH = PCI Bus number ;
; BL = Device / Function number ;
; Bits 7-3: PCI device number ;
; Bits 2-0: Function number within the device ;
; DI = Register number (must be dword aligned address, this value has ;
; already been checked for validity) ;
; SI = One of the following values: PCI_REG_ADDRESS_BYTE ;
; PCI_REG_ADDRESS_WORD, or PCI_REG_ADDRESS_DWORD ;
; ECX, CX, CL = Data to write to configuration space (width depends on ;
; value of SI) ;
; ;
; Output: CF = Set if error, cleared otherwise ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
defproc rth_pci_write_cfg
push eax
push dx
mov ah, 80h ;Set enable bit
mov al, bh
shl eax, 16
mov ax, di ;Add in register offset part
mov ah, bl ;Add in dev/func num part
and al, 0FCh ;Make address dword aligned
mov dx, CFG_SPACE_INDEX_REG
pushf ;Save current state of IF and CLI
cli
out dx, eax ;Set the index
mov dx, di ;Get original config register address
and dx, 03h ;Isolate lower 2 bits
add dx, CFG_SPACE_DATA_REG ;Add offset (0/1/2/3) to data addr
cmp si, PCI_REG_ADDRESS_BYTE
jne write_cfg_try_word
mov al, cl
out dx, al ;Write the config register
jmp short write_cfg_done
write_cfg_try_word:
cmp si, PCI_REG_ADDRESS_WORD
jne write_cfg_try_dword
mov ax, cx
out dx, ax ;Write the config register
jmp short write_cfg_done
write_cfg_try_dword:
mov eax, ecx
out dx, eax ;Write the config register
write_cfg_done:
popf ;Restore state of IF
pop dx
pop eax
clc
ret
endproc rth_pci_write_cfg
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
include sb-link.inc ; (CORE0202+)
ifndef RT32
_text ends
else
_runtime32 ends
endif
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -