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

📄 nrunpci.asm

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