📄 mppost.asm
字号:
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 + -