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

📄 pciman.asm

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

	jcxz	prog_base_auto		;Br if addr is 0 (auto config)
	inc	cx
	clc				;Clear CF in case this jz jumps
	jz	prog_base_exit		;Br if addr was FFFF (disabled)
	dec	cx

	mov	ah, RT_PCI_WRITE_CFG_DWORD
	CALL_RT_FUNCTION		;Write reg DI with ECX

	mov	dx, 8			;Assume 8 bytes of I/O if IDE
	cmp	cx, 1F0h
	je	prog_base_alloc		;Br if primary IDE
	cmp	cx, 170h
	je	prog_base_alloc		;Br if secondary IDE
	mov	dx, 4			;Assume 4 byte default
	cmp	ch, 03h			;3xx ?
	jnz	prog_base_alloc
	cmp	cl, 0F4h
	je	prog_base_ide		;Br if primary IDE
	cmp	cl, 74h
	je	prog_base_ide		;Br if secondary IDE
	cmp	cl, 0F0h
	je	prog_base_ide		;Br if primary IDE
	cmp	cl, 070h
	jnz	prog_base_alloc		;Br if not secondary IDE
prog_base_ide:
	mov	dx, 1			;1 byte for IDE control port
	and	cl, 0f0h
	or	cl, 06h			;CX = 3F6/376 for primary/secondary IDE

prog_base_alloc:
	push	bx
	mov	di, offset OwnerWork	;Point ES:DI to owner_pci structure
	mov	bx, cx			;Min base addr = Max base addr
	mov	si, 1			;Alignment = byte
	mov	ax, (RM_ALLOC_PORT * 100h) + RESFLAG_PORT_DECODE16
	CALL_RESMGR			;Call Resource Manager to allocate port
	pop	bx
	mov	al, 0FFh
	jnc	prog_base_done		;Br if alloc successful

	or	PciStatus, STAT_PCI_IO_CONFLICT
	shr	bl, 3			;BL = dev # (0/1/2/3/.../1F)
	xor	bh, bh
	bts	word ptr PciIOConflict, bx
	inc	al			;Make AL = 0
	clc

prog_base_done:
	inc	al			;AL will be 0 if successful, non-zero
prog_base_exit:				;  if a conflict
	popad
	ret

prog_base_auto:
	stc				;Indicate port should be autoconfigured
	jmp	short prog_base_exit

pci_man_prog_base_addr	endp


;---------------------------------------;
; pci_man_prog_rom_addr                 ;
;---------------------------------------;--------------------------------------;
; This function forces a the expansion ROM base address register to a manual   ;
; override value.                                                              ;
;                                                                              ;
; 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                               ;
;        DI = Offset in PCI config space of expansion ROM base address reg     ;
;        DS:SI = Pointer to buffer containing a pci_man_settings structure     ;
;        DS = ES = _dimdata Segment                                            ;
;                                                                              ;
; Output: CF = Set if base address register was not programmed and should be   ;
;              autoconfigured.                                                 ;
;              Clear if the base address register has been manually overridden.;
;         ZF = Valid only if CF is clear                                       ;
;              Set if manual override was successful                           ;
;              Clear if manual override would cause conflict                   ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
pci_man_prog_rom_addr	proc near
	pushad

	mov	cx, (pci_man_settings ptr [si]).pciman_io_base
	jcxz	prog_rom_auto		;Br if 1st base addr is auto (0000)
	inc	cx
	jcxz	prog_rom_auto		;Br if 1st base addr is disabled (FFFF)

	mov	di, PCI_REG_VENDID
	mov	ah, RT_PCI_READ_CFG_DWORD
	CALL_RT_FUNCTION		;ECX = Vendor / Device ID
	cmp	cx, 104Bh		;Buslogic Vendor ID
	jne	prog_rom_auto		;Br if no match
	shr	ecx, 24			;CL = High byte of device ID
	cmp	cl, 10h
	jae	prog_rom_auto		;Br if Device ID >= 10xxh

	mov	di, offset PCIManOwner	;Point ES:DI to owner structure
	mov	(owner_isa ptr [di]).own_isa_sig, OWNTYPE_ISA
	mov	(owner_isa ptr [di]).own_isa_slot, 0
	mov	(owner_isa ptr [di]).own_isa_func, 0
	mov	dword ptr ((owner_isa ptr [di]).own_isa_vendid), 0
	mov	(owner_isa ptr [di]).own_isa_rsvd2, 0

	push	bx
	mov	edx, 4000h		;Size = 16k
	mov	ebx, 0C8000h		;Min base addr = C800:0
	mov	ecx, 0DC000h		;Max base addr = DC00:0
	mov	esi, 4000h		;Alignment = 16k
	mov	ax, (RM_ALLOC_MEM * 100h) + RESFLAG_MEM_SHADOW + RESFLAG_LO_TO_HI
	CALL_RESMGR			;Call Resource Manager to allocate mem
	pop	bx
	jc	prog_rom_auto		;Br if error in alloc

	mov	ecx, eax
	or	cl, 1
	mov	di, PCI_REG_ROM_BASE_ADD
	mov	ah, RT_PCI_WRITE_CFG_DWORD
	CALL_RT_FUNCTION		;Program Exp ROM reg
	xor	al, al			;Clear CF and set ZF
	jmp	short prog_rom_done

prog_rom_auto:
	stc
prog_rom_done:
	popad
	ret
pci_man_prog_rom_addr	endp
;---------------------------------------;
; pci_man_prog_irq                      ;
;---------------------------------------;--------------------------------------;
; This function forces an Interrupt Line register to a manual override         ;
; value and routes an IRQ to the given Int pin.                                ;
;                                                                              ;
; 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                               ;
;        DI = Offset in PCI config space of Int Line register                  ;
;        DS:SI = Pointer to buffer containing a pci_man_settings structure     ;
;        BP = Offset of the NVRam workspace (in _dimdata seg)                  ;
;        DS = ES = _dimdata Segment                                            ;
;                                                                              ;
; Output: CF = Set if base address register was not programmed and should be   ;
;              autoconfigured.                                                 ;
;              Clear if the base address register has been manually overridden.;
;         ZF = Valid only if CF is clear                                       ;
;              Set if manual override was successful                           ;
;              Clear if manual override would cause conflict                   ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
pci_man_prog_irq	proc near
	pusha

	mov	al, EscdFuncNum		;Save ESCD slot/func
	mov	ah, EscdSlotNum
	push	ax
	mov	EscdFuncNum, 0		;Make sure we don't use ESCD data
	mov	EscdSlotNum, INVALID_SLOT_NUM

	mov	dx, word ptr (pci_man_settings ptr [si]).pciman_int_line
	or	dl, dl			;DL = 0-5 : Auto/A/B/C/D/Disable, DH=IRQ
	stc
	jz	prog_irq_auto		;Br if Int Line is 0 (auto config)
	cmp	dl, 0FFh
	jne	prog_irq_manual		;Br if Int Line is not FF
	xor	cl, cl			;Force Int Line reg to 00 (disabled)
	mov	ah, RT_PCI_WRITE_CFG_BYTE
	CALL_RT_FUNCTION		;Write Int Line reg with CL
	xor	al, al			;CF clear, ZF set for successful
	jmp	short prog_irq_auto

prog_irq_manual:			;DH = IRQ needed / FF for any IRQ
	push	si			;DL = Int Pin reg value (assume INTA)
	mov	si, bp			;SI = ptr to NVRam workspace
	mov	di, offset OwnerWork	;Point ES:DI to owner_pci structure
	call	configure_pci_irq	;Returns alloc'd IRQ in CL
	pop	si			;Restore SI
	mov	al,0ffh			;set AL = FF so that INC AL makes ZF set
	jnc	prog_irq_done		;Br if alloc'd IRQ ok

	or	PciStatus, STAT_PCI_IRQ_CONFLICT
	shr	bl, 3			;BL = dev # (0/1/2/3/.../1F)
	xor	bh, bh
	bts	word ptr PciIrqConflict, bx
	xor	al, al			;Make AL = 0, and CF clear

prog_irq_done:
	inc	al			;ZF set for successful
					;   not set for conflict
prog_irq_auto:
	pop	ax
	mov	EscdFuncNum, al		;Restore ESCD slot/func
	mov	EscdSlotNum, ah

	popa
	ret
pci_man_prog_irq	endp


;---------------------------------------;
; pci_man_get_latency                   ;
;---------------------------------------;--------------------------------------;
; This function returns the manual override value to be used for the Max.      ;
; Latency register.                                                            ;
;                                                                              ;
; Input: BL = Device/Function number to initialize                             ;
;                Bits 7-3: PCI device number                                   ;
;                Bits 2-0: Function number within the device                   ;
;        AL = Default value for the Max Latency register                       ;
;        BH = Bus number of device to initialize                               ;
;        DS:SI = Pointer to buffer containing a pci_man_settings structure     ;
;        DS = ES = _dimdata Segment                                            ;
;                                                                              ;
; Output: AL = Value to use when programming the device's Max Latency reg.     ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
pci_man_get_latency	proc near
	cmp	(pci_man_settings ptr [si]).pciman_latency, 0
	jz	get_lat_auto
	mov	al, (pci_man_settings ptr [si]).pciman_latency
get_lat_auto:
	ret
pci_man_get_latency	endp



read_cmos	proc near
	or	al, 80h
	out	70h, al
	jcxz	$+2
	jcxz	$+2
	in	al, 71h
	ret
read_cmos	endp



_text	ends
	end

;*****************************************************************;
;*****************************************************************;
;**                                                             **;
;**      (C)Copyright 1985-1996, American Megatrends, Inc.      **;
;**                                                             **;
;**                     All Rights Reserved.                    **;
;**                                                             **;
;**           6145-F Northbelt Pkwy, Norcross, GA 30071         **;
;**                                                             **;
;**                     Phone (770)-246-8600                    **;
;**                                                             **;
;*****************************************************************;
;*****************************************************************;

⌨️ 快捷键说明

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