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

📄 pciman.asm

📁 <BIOS研发技术剖析>书的源代码,包括完整的BIOS汇编语言源程序.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	page	,132
	title .			PCI Manual Override Device Initializer
;*****************************************************************;
;*****************************************************************;
;**                                                             **;
;**      (C)Copyright 1985-1996, American Megatrends, Inc.      **;
;**                                                             **;
;**                     All Rights Reserved.                    **;
;**                                                             **;
;**           6145-F Northbelt Pkwy, Norcross, GA 30071         **;
;**                                                             **;
;**                     Phone (770)-246-8600                    **;
;**                                                             **;
;*****************************************************************;
;*****************************************************************;

;---------------------------------------;
	include	dim.equ
	include devnode.equ
	include rt.equ
	include escd.equ
	include pci.equ
	include pnp.equ
;---------------------------------------;

	public pci_man_get_device_settings
	public pci_man_check_disabled
	public pci_man_prog_base_addr
	public pci_man_prog_rom_addr
	public pci_man_prog_irq
	public pci_man_get_latency

;---------------------------------------;

	extrn configure_pci_irq: near

	extrn OwnerWork: 	byte
	extrn PCIManOwner: 	byte
	extrn PciIOConflict: 	dword
	extrn PciIrqConflict: 	dword
	extrn PciMemConflict: 	dword
	extrn PciStatus: 	dword
	extrn EscdFuncNum:	byte 
	extrn EscdSlotNum:	byte

;---------------------------------------;

cgroup	group	_text
_text 	segment byte public 'CODE'
	assume	cs:cgroup
.386


;---------------------------------------;
; pci_man_get_device_settings           ;
;---------------------------------------;--------------------------------------;
; This routine reads manual settings for the given PCI device from CMOS and    ;
; returns the data in the form of the following structure:                     ;
;                                                                              ;
;   pci_man_settings	struc						       ;
;   pciman_flags	db ?		;Various flag bits		       ;
;                                       ; Bit 0: 0 = Disable the device        ;
;                                       ;        1 = Enable the device         ;
;                                       ; Bit 7-1: Reserved (set to 0)         ;
;   pciman_latency	db ?		;Value for latency timer reg	       ;
;   pciman_io_base	dw 4 dup (?)	;Values for 4 I/O base addr regs       ;
;   pciman_rom_base	dd ?		;Value for PCI Exp ROM base addr reg   ;
;   pciman_int_line     db ?            ;Int Line to use (Auto/A/B/C/D/Disable);
;   pciman_irq          db ?            ;IRQ to route to this Int Line         ;
;   pci_man_settings	ends						       ;
;                                                                              ;
; 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                               ;
;        DS:SI = Pointer to buffer containing a pci_man_settings structure     ;
;        DS = ES = _dimdata Segment                                            ;
;                                                                              ;
; Output: CF = Clear if device should be completely autoconfigured.            ;
;              Set if a device has one or more manually overridden config      ;
;              settings.                                                       ;
;        DS:SI = A pci_man_settings structure filled in with proper data if    ;
;                CF is set.                                                    ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
;  THE FOLLOWING ROUTINE IS NEEDED FOR GENERIC BIOS IMPLEMENTATION WHICH DOES
;  NOT IMPLEMENT SETUP QUESTION FOR EXPANSION ROM ADDRESS
FIRST_CMOS_REG		equ	51h	;Manual config CMOS data starts here
LAST_CMOS_REG		equ	68h	;Manual config CMOS data ends here
CMOS_BYTES_PER_SLOT	equ	06h	;#of CMOS registers used by a PCI SLOT
pci_man_get_device_settings	proc near
	pusha

	mov	di, si
	mov	cx, size pci_man_settings
	cld
	xor	al, al
	rep	stosb			;Initialize buffer to all auto config

	or	bh, bh
	jnz	get_dev_no_override	;Br if bus number <> 0
	test	bl, 07h
	jnz	get_dev_no_override	;Br if function number <> 0
	
	mov	al, 8Eh			;Read CMOS status reg
	call	read_cmos
	test	al, 0C1h
	jnz	get_dev_no_override	;Br if CMOS is bad or <INS> pressed

	shr	bl, 3			;BL = PCI Device #
	mov	ah, FIRST_CMOS_REG

get_dev_next_dev:
	push	ax
;Get byte 0 of cmos for IDSEL, latency timer
	mov	al, ah
	call	read_cmos		;AL bit 7:3 = IDSEL
					;   bit 2   = Not used
	xor	ecx, ecx		;   bit 1:0 = Latency timer
	mov	cl, al			;Save bits 1-0
	shr	al, 3
	and	al, 1Fh			;AL = IDSEL
	cmp	al, bl
	jne	get_dev_skip_dev	;Br if dev # does not match
	and	cl, 03h			;CL = Latency value 0/1/2/3
	inc	cl			;CL = 1/2/3/4
	shl	cl, 6			;CL = 40/80/C0/00
	jnz	get_dev_set_latency
	mov	cl, 0F8h
get_dev_set_latency:			;CL = 40/80/C0/F8
	mov	(pci_man_settings ptr [si]).pciman_latency, cl

;Get bytes 1/2/3/4 from CMOS and program I/O base address

	xor	bx, bx
get_dev_next_io:
	inc	ah
	mov	al, ah
	call	read_cmos		;AL = 00/40/41/42/.../FF
	movzx	cx, al
	jcxz	get_dev_set_iobase	;Br if base addr is auto
	shl	cx, 2			;CX = 100/104/108/.../3FC
	cmp	cx, 100h
	jae	get_dev_set_iobase	;Br if base addr is not disabled
	mov	cx, 0FFFFh
get_dev_set_iobase:			;CX = 100/104/108/.../3FC/FFFF
	mov	(pci_man_settings ptr [si+bx]).pciman_io_base, cx
	inc	bx
	inc	bx
	cmp	bl, 8
	jb	get_dev_next_io		;Br if not done with all 4 I/Os

; Get byte 5 from CMOS and program Int Line, IRQ and device enable/disable

	inc	ah
	mov	al, ah
	call	read_cmos		;AL bit 2-0: 0->5 = Auto/A/B/C/D/Disable
					;   bit 3  : 0/1 = enabled/disabled
	mov	cl, al			;   bit 7-4: IRQ to route (if bit 2-0 valid)
	test	al, 08h
	jnz	get_dev_buffer_done	;Br if device is disabled
	or	(pci_man_settings ptr [si]).pciman_flags, 01h
get_dev_dis_done:
	and	cl, 07h
	cmp	cl, 4
	jbe	get_dev_set_int_line	;Br if Int Line not disabled
	mov	cl, 0FFh
get_dev_set_int_line:
	mov	(pci_man_settings ptr [si]).pciman_int_line, cl
	shr	al, 4			;AL = IRQ to route
	mov	(pci_man_settings ptr [si]).pciman_irq, al

	lea	di, (pci_man_settings ptr [si]).pciman_io_base
	mov	cx, 13			;4 I/O (8 bytes) + 1 Exp ROM (4 bytes)
	xor	al, al			;  + Int Line (1 byte)
	repz	scasb
	jnz	get_dev_buffer_done	;Br if one or more manual settings
	pop	ax
	jmp	short get_dev_no_override

get_dev_buffer_done:
	pop	ax
	stc
	jmp	short get_dev_done

get_dev_skip_dev:
	pop	ax
	add	ah, CMOS_BYTES_PER_SLOT	;CMOS reg for next device
	cmp	ah, LAST_CMOS_REG
	jb	get_dev_next_dev	;Br if more devs in CMOS

get_dev_no_override:
	clc

get_dev_done:
	popa
	ret
pci_man_get_device_settings	endp

;---------------------------------------;
;  THE FOLLOWING ROUTINE IS NEEDED FOR THE BIOS IMPLEMENTATION WHICH DOES
;  IMPLEMENT SETUP QUESTION FOR EXPANSION ROM ADDRESS

;---------------------------------------;
; pci_man_check_disabled                ;
;---------------------------------------;--------------------------------------;
; This function will be called only if one or more settings for a device are   ;
; set to manual override.  This function should check the enable/disable bit   ;
; in the pci_man_settings structure passed in and return CF set properly.      ;
;                                                                              ;
; 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                               ;
;        DS:SI = Pointer to buffer containing a pci_man_settings structure     ;
;        DS = ES = _dimdata Segment                                            ;
;                                                                              ;
; Output: CF = Set if device should be disabled                                ;
;              Clear if device should be configured using the manual setting(s);
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
pci_man_check_disabled	proc near
	test	(pci_man_settings ptr [si]).pciman_flags, 01h
	jnz	check_dis_done		;Br if enabled (CF is already clear)
	stc
check_dis_done:
	ret
pci_man_check_disabled	endp


;---------------------------------------;
; pci_man_prog_base_addr                ;
;---------------------------------------;--------------------------------------;
; This function forces a PCI 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 base address register              ;
;        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_base_addr	proc near
	pushad

	cmp	di, 1Ch
	ja	prog_base_auto		;Br if not one of 1st four base addr regs

	push	bx
	mov	bx, di
	sub	bx, 10h			;BX = 0/4/8/C
	shr	bx, 1			;BX = 0/2/4/6
	movzx	ecx, (pci_man_settings ptr [si+bx]).pciman_io_base

⌨️ 快捷键说明

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