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

📄 mppost.asm

📁 <BIOS研发技术剖析>书的源代码,包括完整的BIOS汇编语言源程序.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	shr	bl,1				; bl has device number shl 2
	or	bl,ch				; bl has source bus IRQ
	mov	ax,BUS_ACTIVE_LOW OR BUS_LEVEL_TRIGGER
	call	add_interrupt
	pop	bx
	mov	si,di				; si has table pointer
skip_function:
	dec	dl				; next function
	jns	count_function_numbers
skip_device:
	pop	bx
	dec	bl				; next device
	jns	count_device_numbers
	dec	bh				; next bus
	jns	count_bus_numbers
	pop	di					; restore registers
	pop	cx
	pop	bx
	cmp	si,di				; did we add a entry (si > di)?
	jne	PCI_interrupt_added		; table pointer did not change
	stc
	ret
PCI_interrupt_added:
	mov	di,si				; restore table pointer from si
	clc
	ret
add_pci_interrupt	endp
;-------------------------------;
; MAP_IRQ_TO_INTIN		;
;-------------------------------;
;	Description:		This routine takes the IRQ that is assigned to the
;				PCI device, and determines which PIRQ register value
;				matches.  The routing to the correct I/O APIC INTIN#
;				is done through the apic_intin_table.
;	Input:			CL - IRQ routed to PCI device
;				DH - INTIN#
;	Output:			CL - INTIN# to be added to MP Table
;				CY - SET, don't create MP entry
;				CY - CLR, ok to create MP entry
;	Stack:			Available
;	Registers destroyed:	CL, AL
;-------------------------------;
;
; I\O APIC PCI INTIN# Routing Table (this table must be modified to
; reflect the actual hardware design.
;
apic_intin_table:
	db	16	; INTIN# number for PIRQ0 (60H)
	db	17	; INTIN# number for PIRQ1 (61H)
	db	18	; INTIN# number for PIRQ2 (62H)
	db	19	; INTIN# number for PIRQ3 (63H)
map_irq_to_intin	proc	near
	push	bx
	push	cx
	push	dx
	push	si
	push	di
	mov	ch,cl			; save IRQ away for later
	mov	bx,PCI_ISA_DEV_FUNC
	mov	di,PIRQ0_REGISTER
	mov	si,offset apic_intin_table
miti_00:
	extrn	read_pci_cfg_byte:near	; get PIRQx value
	call	read_pci_cfg_byte	; get PIRQx value
	lodsb	cs:[si]			; get INTIN# corresponding to PIRQx
	cmp	ch,cl			; does the IRQ match this PIRQ?
	jne	short miti_next_pirq	; jump if not
	cmp	dh,al			; does the INTIN# match?
	je	short miti_intin_found	; jump if so
miti_next_pirq:
	inc	di			; point to next PIRQx
	cmp	di,PIRQ3_REGISTER	; checked all PIRQs yet?
	jbe	short miti_00		; jump if not
	stc				; indicate failure ..
	jmp	short @F		; .. and return
miti_intin_found:
	clc				; indicate success ..
@@:
	pop	di
	pop	si
	pop	dx
	pop	cx
	mov	cl,al			; get INTIN#
	pop	bx
	ret			; .. and return
map_irq_to_intin	endp
endif
;-------------------------------;
; ADD_INTERRUPT			;
;-------------------------------;
;	Description:		This routine creates the actual interrupt table entry.
;	Input:			AX =	Interrupt Properties
;				BL = 	Source bus IRQ
;				BH = 	Source bus number
;				CL =	Destination INTIN on I/O APIC
;				ES:DI =	Pointer in MP table where entry needs to be made
;	Output:			ES:DI = Pointer in MP table after entry completion
;	Stack:			Available
;	Registers destroyed:	EAX
;-------------------------------;
add_interrupt	proc	near
	push	ax				; save the interrupt properties
	mov	ax,INTERRUPT_ENTRY_TYPE		; interrupt entry type
	stosb
;
; First we need to decide which typr of interrupt it is.  If it is
; INTIN #0, it is an EXTINT_TYPE, if it is INTIN #23, it is an SMI_TYPE,
; otherwise it is an INTR_TYPE.
;
	mov	ax,INTR_TYPE			; default to INTR type
	or	cl,cl				; is it INTIN #0?
	jnz	check_smi_intr			; jump if not
	mov	ax,EXTINT_TYPE			; EXTINT type interrupt
	jmp	@F
check_smi_intr:
	cmp	cl,23				; is it INTIN #23?
	jnz	@F				; jump if not
	mov	ax,SMI_TYPE			; default to SMI type
@@:	stosb
;
; If the interrupt is the RTC (IRQ8) the modes are EDGE and HIGH.
;
	pop	ax				; restore interrupt properties
	cmp	cl,8				; is it IRQ8?
	jnz	short @F			; jump if not
	mov	ax,BUS_EDGE_TRIGGER OR BUS_ACTIVE_HIGH
@@:	stosw
	mov	al,bh				; bus number
	stosb
	mov	al,bl				; source bus IRQ
	stosb
	mov	al,DEFAULT_IO_APIC_ID		; destination IO APIC
	stosb
	mov	al,cl				; destination INTIN
	stosb
	inc	word ptr es:[MP_Header.Entry_Count]	; increment number of entries
	ret
add_interrupt	endp
;-------------------------------;
; PROCESS_OEM_ID_ENTRY		;
;-------------------------------;
;	Description:		This routine makes the OEM entry in MP table header.
;	Input:			ES:DI = Pointer in MP table where entry needs to be made
;	Output:			ES:DI = Pointer in MP table after entry completion
;	Stack:			Available
;	Registers destroyed:    EAX
;-------------------------------;
process_OEM_ID_entry	proc	near
;
; To create an OEM ID, use the following syntax:
;
;      	Set_OEM_ID	<string>	where string is upto 8 characters
;
;	For example,
;			Set_OEM_ID <AMI>
;
; To use OEM ID from makefile use the following syntax:
;
;	Set_OEM_ID	%OEM
;
; To create a blank OEM ID, either use makefile and leave OEM ID blank
; in makefile or use the following:
;
;	Set_OEM_ID
;
;-------------------------------;
	Set_OEM_ID	%OEM		; pick OEM ID from makefile
	ret
process_OEM_ID_entry	endp
;-------------------------------;
; PROCESS_PRODUCT_ID_ENTRY	;
;-------------------------------;
;	Description:		This routine makes the product entry in MP table header.
;	Input:			ES:DI = Pointer in MP table where entry needs to be made
;	Output:			ES:DI = Pointer in MP table after entry completion
;	Stack:			Available
;	Registers destroyed:    EAX
;-------------------------------;
process_product_ID_entry	proc	near
;
; To create a product ID, use the following syntax:
;
;      	Set_Product_ID	<string>	where string is upto 8 characters
;
;	For example,
;			Set_Product_ID <VOYAGER>
;
; To use product ID from makefile use the following syntax:
;
;	Set_Product_ID	%PROD
;
; To create a blank product ID, either use makefile and leave product ID blank
; in makefile or use the following:
;
;	Set_Product_ID
;
;-------------------------------;
	Set_Product_ID	%PROD		; pick Product ID from makefile
	ret
process_product_ID_entry	endp

;-------------------------------;
; PROCESS_OEM_TABLE_ENTRY	;
;-------------------------------;
;	Description:		This routine makes the entry for a OEM table (if present)
;				in the MP header.
;	Input:			ES:DI = Pointer in MP table where entry needs to be made
;	Output:			ES:DI = Pointer in MP table after entry completion
;	Stack:			Available
;	Registers destroyed:	EAX
;-------------------------------;
process_OEM_table_entry	proc	near
;
; To declare an OEM Table, use the following syntax:
;
;	Declare_OEM_Table 	Pointer_in_flat_mode, Table_size_in_bytes
;
;	For example, for a 100h byte table at F000:4000, use:
;
;		Declare_OEM_Table 	0F4000h, 100h
;
; If no table is present, just use:
;
;	Declare_OEM_Table
;
;-------------------------------;
	Declare_OEM_Table
	ret
process_OEM_table_entry	endp

;-------------------------------;
; GET_LOCAL_APIC_ADDRESS	;
;-------------------------------;
;	Description:		This routine will return the CPU's local apic address
;	Input:			None
;	Output:			EAX = 	Local APIC Address
;	Stack:			Available
;	Registers destroyed:	EAX
;-------------------------------;
get_local_apic_address	proc	near
	mov	eax,DEFAULT_LOCAL_APIC_ADDRESS		; Default LOCAL APIC Address
	ret
get_local_apic_address	endp

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

⌨️ 快捷键说明

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