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

📄 pcipnp.8

📁 tiny bios--了解BIOS非常好的资料
💻 8
📖 第 1 页 / 共 2 页
字号:
	call	pci_rnd
	
	mov	si,p_memp	;prefetch memory: 1MB boundaries
	;mov	dx,P_MEMINC1	;primary bus
	;mov	di,P_MEMINC2	;secondary bus
	;mov	cl,0fh
	call	pci_rnd
	
	mov	si,p_io	;I/O: 4K boundaries
	mov	cl,0ffh
	mov	dx,P_IOINC1	;primary bus
	mov	di,P_IOINC2	;secondary bus
	call	pci_rnd
	
	;set bridge base and limit registers
	
	mov	bl,pb_mem	;memory base / limit
	mov 	eax,[p_mem]	;+ p_memlim
	sub 	eax,10000h	;-> inclusive limit
	call	pci_setd
	mov	bl,pb_memp	;prefetchable base / limit
	mov 	eax,[p_memp]	;+ p_memplim
	sub 	eax,10000h	;-> inclusive limit
	call	pci_setd
	mov	bl,pb_io	;I/O base / limit
	mov	al,[p_io+1]
	mov	ah,[p_iolim+1]
	dec	ah	;-> inclusive limit
	call	pci_setw
	
	;clear high registers
	
	xor 	eax,eax	;clear high memory base
	mov	bl,pb_mem2
	call	pci_setd
	mov	bl,pb_memp2	;clear high prefetchable base
	call	pci_setd
	mov	bl,pb_io2	;clear high I/O base
	call	pci_setd
		
	; save variables for recursion
	
	push	word [p_capa]
	push 	dword [p_int]
	
	mov	word [p_capa],80h	;bus capabilities
	mov	bl,pb_stat	;read secondary status
	call	pci_getw
	and	byte [p_capa],al	;clear fast back to back if not supportd
	or	byte [p_capa+1],ah	;set devsel timing
	
	mov	bl,p_cmd	;command register: enable bus master
	call	pci_getw
	or	al,04
	mov	bl,p_cmd
	call	pci_setw

	push 	ebx	;save current EBX
	rol 	dword [p_int],8	;precompensate for interrupt rotation
	
	call	pci_bus	;enumerate this bus
	call	pci_capa	;set capability flags
	
	; limit -> new allocation pointer

	mov	ax,[p_memlim]	;memory
	mov	[p_mem],ax
	
	mov	ax,[p_memplim]	;prefetchable memory
	mov	[p_memp],ax
	
	mov	ax,[p_iolim]	;I/O
	mov	[p_io],ax
	
	; restore variables

	pop ebx	;restore after recursion
	pop 	dword [p_int]
	pop	word [p_capa]
	pop	word [p_iolim]
	pop	word [p_memplim]
	pop	word [p_memlim]
	pop	ax
	mov	[p_bus],ax
	
	mov	al,[p_lastbus]	;set correct subordinate bus number
	mov	bl,pb_bus3
	call	pci_setb

	mov	bl,pb_ctl	;set bridge control register
	mov	ax,P_BRIDGE
	and	byte [p_capa],80h	;isolate fast back to back bit
	or	al,byte [p_capa]	;copy to control register
	call	pci_setw
	ret
	;
	; get next interrupt assignment
	;
pci_nint:	test	bh,7	;function 0 ?
	jnz	pci_nint4	;no: same interrupts
	cmp	byte [p_bus],0	;primary bus ?
	jnz	pci_nint5	;:no
	cmp	word [p_irqpt],pci_tab9	;end of IRQ table ?
	jz	pci_nint4	;yes: don't change
	mov	si,[p_irqpt]	;get next table entry
	cs: 	lodsd
	mov	[p_irqpt],si
	mov 	[p_int],eax	;save interrupt setting
pci_nint4: ret
	
pci_nint5: ror 	dword [p_int],8	;rotate interrupts
	ret
	;
	; enumerate a bus - called recursively
	;
pci_bus:	mov	bh,80h	;enable config access
	mov	bl,[p_bus]	;bus number
	shl 	ebx,16	;device, function = 0

	; check vendor ID, 0 or FFFF = nothing there, skip device

pci_bus0:	call	pci_nint	;get next interrupt assignment
	mov	bl,p_id	;get vendor / device ID
	call	pci_getd
	inc	ax	;FFFF = not present
	jz	pci_bus4	;:skip device
	dec	ax	;0000 = no more functions
	jz	pci_bus4	;:skip device
	
	call	pci_airq	;assign interrupts

	call	pci_vga	;handle PCI VGA
	
	; check header type, different handling if bridge

	mov	bl,p_hedt	;get header type
	call	pci_getb
	
	and	al,7fh
	cmp	al,1	;bridge
	jz	pci_bus1
#if def	PCI_NORST
	cmp	bh,PCI_NORST	;don't touch base registers on this
	jz	pci_bus3	;device (pd 980728: was jz pci_bus2)
#endif
#if def	PCI_NORST2
	cmp	bh,PCI_NORST2
	jz	pci_bus3
#endif
	mov	cl,p_cis	;end index for normal device
	call	pci_dev	;allocate resources
	jmp	short pci_bus2

pci_bus1:	mov	cl,pb_bus	;end index for bridge
	call	pci_dev	;allocate resources
	call	pci_bri	;enumerate secondary buses

	; try next function

pci_bus2:	test	bh,7	;function 0 ?
	jnz	pci_bus4	;:no, try next subfunction
	
	; function 0 - is this a multifunction device
	
	mov	bl,p_hedt	;get header type
	call	pci_getb
	
	and	al,80h
	jnz	pci_bus4	;:yes, multifunction device
pci_bus3:	or	bh,7	;step to next device
pci_bus4:	inc	bh
	jnz	pci_bus0
	mov	ax,[p_mem]	;check allocation limits
	cmp	ax,[p_memlim]
	ja	pci_bus9	;:error
	mov	ax,[p_memp]
	cmp	ax,[p_memplim]
	ja	pci_bus9	;:error
	mov	ax,[p_io]
	cmp	ax,[p_iolim]
	ja	pci_bus9
	ret
	
pci_bus9:	mov	al,0e5h	;error !
pci_err9:	call	postcode 	;pd 980728: don't do direct I/O
pci_err99: jmp	pci_err99
	;
	; handle PCI VGA
	;
pci_vga:	mov	bl,p_class	;read class ID
	call	pci_getd
	shr	eax,16	;check high 16 bits
	cmp	ax,0300h	;VGA ?
	jnz	pci_vga9	;:no
	
	mov	bl,p_cmd	;enable memory access
	call	pci_getw
	push	ax
	or	al,2
	call	pci_setw
	
	mov	bl,p_rom	;enable ROM - at P_ROM0
	mov	esi,P_ROM0 shl 16
	mov 	eax,esi
	inc	ax	;low bit = 1 -> enable
	call	pci_setd
	push 	ebx	;save ebx context
	
	call	getunreal	;enter unreal mode
	
	mov	ax,[esi]
	cmp	ax,0aa55h	;ROM header ?
	jnz	pci_vga2	;:no
	call	cs_vshad2	;copy video BIOS to shadow RAM
			;(chipset specific)
	
pci_vga2:	pop 	ebx	;restore ebx
	xor 	eax,eax	;disable ROM
	call	pci_setd

	pop	ax	;restore command register
	mov	bl,p_cmd
	call	pci_setw

	xor	ax,ax	;restore segment (from unreal mode)
	mov	ds,ax
	mov	es,ax
pci_vga9:	ret
	;
	; set capability bits & enable devices
	;
pci_capa:	xor	bx,bx	;start with device / function 0
	mov	cx,P_COMMAND	;standard command value
	cmp	byte [p_capa],80h	;all devices back-to-back capable ?
	jnz	pci_capa1	;:no
	or	ch,02	;enable fast back-to-back mode
pci_capa1: mov	bl,p_id	;get vendor / device ID
	call	pci_getw
	inc	ax	;FFFF = not present
	jz	pci_capa4	;:skip device
	dec	ax	;0000 = no more functions
	jz	pci_capa4	;:skip device

	mov	bl,p_cmd	;read command register
	call	pci_getw
	and	ax,0ff5fh	;clear stepping, palette snoop bits
	or	ax,cx	;enable according to P_COMMAND
	call	pci_setw	;set command register

#if def	P_LINSIZE
	mov	bl,p_linesz
	mov	al,P_LINSIZE
	call	pci_setb
#endif

	; try next function

	test	bh,7	;function 0 ?
	jnz	pci_capa4	;:no, try next subfunction
	
	; function 0 - is this a multifunction device
	
	mov	bl,p_hedt	;get header type
	call	pci_getb
	
;	mov 	eax,ebx	;device address
;	mov	al,p_hedt and 0fch	;header type
;	mov	dx,pci_ad
;	out 	dx,eax
;	mov	dl,low(pci_dat) + 2
;	in 	al,dx
	and	al,80h
	jnz	pci_capa4	;:yes, multifunction device
	or	bh,7	;step to next device
pci_capa4: inc	bh
	jnz	pci_capa1
	ret
	;
	; PCI plug & play configuration
	;
	; EAX = scratch
	; EBX = 80 / bus / device / function / index
	; CX  = scratch
	; DX  = port address
	; SI  = scratch
	; DI  = scratch
	; BP  = scratch
	;
pci_pnp:	mov	word [p_mem],P_MEM0	;set starting addresses
	mov	word [p_memp],P_MEMP0
	mov	word [p_memr],P_MEMR0
	mov	word [p_io],P_IO0
	mov	word [p_memlim],P_MEM9	;set allocation limits
	mov	word [p_memplim],P_MEMP9
	mov	word [p_memrlim],P_MEMR9
	mov	word [p_iolim],P_IO9
	;mov	byte [p_bus],0
	;mov	byte [p_lastbus],0
	mov	word [p_irqpt],offset pci_tab
	
	call	pci_bus	;enumerate bus
	call	pci_capa	;set capability flags

	mov	al,[p_lastbus]	;set number of last PCI bus
	mov 	byte [cs:d_lastbus],al
	ret
	;
	; Disable all devices on primary bus
	;
	; NOTE: Called without stack ! On a chipset with PCI reset
	; function, PCI reset is the easier way...
	;
pci_rst:

#if def	PCI_NOCLR
	ret
#else

#if def	PCI_NORST
	mov 	eax,p_cmd+80000800h	;start with device 1 (don't cut off
			;chipset)
#else
	mov 	eax,p_cmd+80000000h	;access bus 0, device 0, function 0
#endif

pci_rst1:

#if def	PCI_NORST
	cmp	ah,PCI_NORST	;don't reset this device
	jnz	pci_rst2
	add	ah,8
pci_rst2:
#endif
	mov	dx,pci_ad
	out 	dx,eax	;write index
	xchg	ax,bx
	mov	dl,low(pci_dat)
	in	ax,dx	;read command register
	and	ax,0fff8h	;disable bus master, I/O, memory access
	xchg	ax,bx
	mov	dl,low(pci_ad)
	out 	dx,eax	;write index
	xchg	ax,bx
	mov	dl,low(pci_dat)
	out	dx,ax	;write command register
	xchg	ax,bx
	inc	ah	;next device / function
	jnz	pci_rst1
	ret
#endif

⌨️ 快捷键说明

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