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

📄 pci.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 3 页
字号:
#define USER_SPACE 1/*pci.cConfigure devices on the PCI busCreated:	Jan 2000 by Philip Homburg <philip@cs.vu.nl>*/#include "../drivers.h"#define	NDEBUG			/* disable assertions */#include <assert.h>#include <minix/com.h>#include <minix/syslib.h>#include "pci.h"#include "pci_amd.h"#include "pci_intel.h"#include "pci_sis.h"#include "pci_via.h"#if __minix_vmd#include "config.h"#endif#if !__minix_vmd#define irq_mode_pci(irq) ((void)0)#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#include <minix/sysutil.h>#define NR_PCIBUS	 4#define NR_PCIDEV	40#define PBT_INTEL	 1#define PBT_PCIBRIDGE	 2PRIVATE int debug= 0;PRIVATE struct pcibus{	int pb_type;	int pb_isabridge_dev;	int pb_isabridge_type;	int pb_devind;	int pb_bus;	u8_t (*pb_rreg8)(int busind, int devind, int port);	u16_t (*pb_rreg16)(int busind, int devind, int port);	u32_t (*pb_rreg32)(int busind, int devind, int port);	void (*pb_wreg16)(int busind, int devind, int port, U16_t value);	void (*pb_wreg32)(int busind, int devind, int port, u32_t value);	u16_t (*pb_rsts)(int busind);	void (*pb_wsts)(int busind, U16_t value);} pcibus[NR_PCIBUS];PRIVATE int nr_pcibus= 0;PRIVATE struct pcidev{	u8_t pd_busind;	u8_t pd_dev;	u8_t pd_func;	u8_t pd_baseclass;	u8_t pd_subclass;	u8_t pd_infclass;	u16_t pd_vid;	u16_t pd_did;	u8_t pd_inuse;} pcidev[NR_PCIDEV];PRIVATE int nr_pcidev= 0;/* Work around the limitation of the PCI emulation in QEMU 0.7.1 */PRIVATE int qemu_pci= 0;FORWARD _PROTOTYPE( void pci_intel_init, (void)				);FORWARD _PROTOTYPE( void probe_bus, (int busind)			);FORWARD _PROTOTYPE( int do_isabridge, (int busind)			);FORWARD _PROTOTYPE( void do_pcibridge, (int busind)			);FORWARD _PROTOTYPE( int do_piix, (int devind)				);FORWARD _PROTOTYPE( int do_amd_isabr, (int devind)			);FORWARD _PROTOTYPE( int do_sis_isabr, (int devind)			);FORWARD _PROTOTYPE( int do_via_isabr, (int devind)			);FORWARD _PROTOTYPE( char *pci_vid_name, (U16_t vid)			);FORWARD _PROTOTYPE( char *pci_baseclass_name, (U8_t baseclass)		);FORWARD _PROTOTYPE( char *pci_subclass_name, (U8_t baseclass,					U8_t subclass, U8_t infclass)	);FORWARD _PROTOTYPE( void ntostr, (unsigned n, char **str, char *end)	);FORWARD _PROTOTYPE( u16_t pci_attr_rsts, (int devind)			);FORWARD _PROTOTYPE( void pci_attr_wsts, (int devind, U16_t value)	);FORWARD _PROTOTYPE( u16_t pcibr_intel_rsts, (int busind)		);FORWARD _PROTOTYPE( void pcibr_intel_wsts, (int busind, U16_t value)	);FORWARD _PROTOTYPE( u16_t pcibr_via_rsts, (int busind)			);FORWARD _PROTOTYPE( void pcibr_via_wsts, (int busind, U16_t value)	);FORWARD _PROTOTYPE( u8_t pcii_rreg8, (int busind, int devind, int port)	);FORWARD _PROTOTYPE( u16_t pcii_rreg16, (int busind, int devind,							int port)	);FORWARD _PROTOTYPE( u32_t pcii_rreg32, (int busind, int devind,							int port)	);FORWARD _PROTOTYPE( void pcii_wreg16, (int busind, int devind, int port,							U16_t value)	);FORWARD _PROTOTYPE( void pcii_wreg32, (int busind, int devind, int port,							u32_t value)	);FORWARD _PROTOTYPE( u16_t pcii_rsts, (int busind)			);FORWARD _PROTOTYPE( void pcii_wsts, (int busind, U16_t value)		);/*===========================================================================* *			helper functions for I/O			     * *===========================================================================*/PUBLIC unsigned pci_inb(U16_t port) {	U8_t value;	int s;	if ((s=sys_inb(port, &value)) !=OK)		printf("PCI: warning, sys_inb failed: %d\n", s);	return value;}PUBLIC unsigned pci_inw(U16_t port) {	U16_t value;	int s;	if ((s=sys_inw(port, &value)) !=OK)		printf("PCI: warning, sys_inw failed: %d\n", s);	return value;}PUBLIC unsigned pci_inl(U16_t port) {	U32_t value;	int s;	if ((s=sys_inl(port, &value)) !=OK)		printf("PCI: warning, sys_inl failed: %d\n", s);	return value;}PUBLIC void pci_outb(U16_t port, U8_t value) {	int s;	if ((s=sys_outb(port, value)) !=OK)		printf("PCI: warning, sys_outb failed: %d\n", s);}PUBLIC void pci_outw(U16_t port, U16_t value) {	int s;	if ((s=sys_outw(port, value)) !=OK)		printf("PCI: warning, sys_outw failed: %d\n", s);}PUBLIC void pci_outl(U16_t port, U32_t value) {	int s;	if ((s=sys_outl(port, value)) !=OK)		printf("PCI: warning, sys_outl failed: %d\n", s);}/*===========================================================================* *				pci_init				     * *===========================================================================*/PUBLIC void pci_init(){	static int first_time= 1;	long v;	if (!first_time)		return;	v= 0;	env_parse("qemu_pci", "d", 0, &v, 0, 1);	qemu_pci= v;	v= 0;	env_parse("pci_debug", "d", 0, &v, 0, 1);	debug= v;	/* We don't expect to interrupted */	assert(first_time == 1);	first_time= -1;	/* Only Intel (compatible) PCI controllers are supported at the	 * moment.	 */	pci_intel_init();	first_time= 0;}/*===========================================================================* *				pci_find_dev				     * *===========================================================================*/PUBLIC int pci_find_dev(bus, dev, func, devindp)u8_t bus;u8_t dev;u8_t func;int *devindp;{	int devind;	for (devind= 0; devind < nr_pcidev; devind++)	{		if (pcidev[devind].pd_busind == bus &&			pcidev[devind].pd_dev == dev &&			pcidev[devind].pd_func == func)		{			break;		}	}	if (devind >= nr_pcidev)		return 0;	if (pcidev[devind].pd_inuse)		return 0;	*devindp= devind;	return 1;}/*===========================================================================* *				pci_first_dev				     * *===========================================================================*/PUBLIC int pci_first_dev(devindp, vidp, didp)int *devindp;u16_t *vidp;u16_t *didp;{	int devind;	for (devind= 0; devind < nr_pcidev; devind++)	{		if (!pcidev[devind].pd_inuse)			break;	}	if (devind >= nr_pcidev)		return 0;	*devindp= devind;	*vidp= pcidev[devind].pd_vid;	*didp= pcidev[devind].pd_did;	return 1;}/*===========================================================================* *				pci_next_dev				     * *===========================================================================*/PUBLIC int pci_next_dev(devindp, vidp, didp)int *devindp;u16_t *vidp;u16_t *didp;{	int devind;	for (devind= *devindp+1; devind < nr_pcidev; devind++)	{		if (!pcidev[devind].pd_inuse)			break;	}	if (devind >= nr_pcidev)		return 0;	*devindp= devind;	*vidp= pcidev[devind].pd_vid;	*didp= pcidev[devind].pd_did;	return 1;}/*===========================================================================* *				pci_reserve				     * *===========================================================================*/PUBLIC void pci_reserve(devind)int devind;{	assert(devind <= nr_pcidev);	assert(!pcidev[devind].pd_inuse);	pcidev[devind].pd_inuse= 1;}/*===========================================================================* *				pci_ids					     * *===========================================================================*/PUBLIC void pci_ids(devind, vidp, didp)int devind;u16_t *vidp;u16_t *didp;{	assert(devind <= nr_pcidev);	*vidp= pcidev[devind].pd_vid;	*didp= pcidev[devind].pd_did;}/*===========================================================================* *				pci_slot_name				     * *===========================================================================*/PUBLIC char *pci_slot_name(devind)int devind;{	static char label[]= "ddd.ddd.ddd";	char *end;	char *p;	p= label;	end= label+sizeof(label);	ntostr(pcidev[devind].pd_busind, &p, end);	*p++= '.';	ntostr(pcidev[devind].pd_dev, &p, end);	*p++= '.';	ntostr(pcidev[devind].pd_func, &p, end);	return label;}/*===========================================================================* *				pci_dev_name				     * *===========================================================================*/PUBLIC char *pci_dev_name(vid, did)u16_t vid;u16_t did;{	int i;	for (i= 0; pci_device_table[i].name; i++)	{		if (pci_device_table[i].vid == vid &&			pci_device_table[i].did == did)		{			return pci_device_table[i].name;		}	}	return NULL;}/*===========================================================================* *				pci_attr_r8				     * *===========================================================================*/PUBLIC u8_t pci_attr_r8(devind, port)int devind;int port;{	int busind;	busind= pcidev[devind].pd_busind;	return pcibus[busind].pb_rreg8(busind, devind, port);}/*===========================================================================* *				pci_attr_r16				     * *===========================================================================*/PUBLIC u16_t pci_attr_r16(devind, port)int devind;int port;{	int busind;	busind= pcidev[devind].pd_busind;	return pcibus[busind].pb_rreg16(busind, devind, port);}/*===========================================================================* *				pci_attr_r32				     * *===========================================================================*/PUBLIC u32_t pci_attr_r32(devind, port)int devind;int port;{	int busind;	busind= pcidev[devind].pd_busind;	return pcibus[busind].pb_rreg32(busind, devind, port);}/*===========================================================================* *				pci_attr_w16				     * *===========================================================================*/PUBLIC void pci_attr_w16(devind, port, value)int devind;int port;u16_t value;{	int busind;	busind= pcidev[devind].pd_busind;	pcibus[busind].pb_wreg16(busind, devind, port, value);}/*===========================================================================* *				pci_attr_w32				     * *===========================================================================*/PUBLIC void pci_attr_w32(devind, port, value)int devind;int port;u32_t value;{	int busind;	busind= pcidev[devind].pd_busind;	pcibus[busind].pb_wreg32(busind, devind, port, value);}/*===========================================================================* *				pci_intel_init				     * *===========================================================================*/PRIVATE void pci_intel_init(){	/* Try to detect a know PCI controller. Read the Vendor ID and	 * the Device ID for function 0 of device 0.	 * Two times the value 0xffff suggests a system without a (compatible)	 * PCI controller. Only controllers with values listed in the table	 * pci_intel_ctrl are actually used.	 */	u32_t bus, dev, func;	u16_t vid, did;	int s, i, r, busind;	char *dstr;	bus= 0;	dev= 0;	func= 0;	vid= PCII_RREG16_(bus, dev, func, PCI_VID);	did= PCII_RREG16_(bus, dev, func, PCI_DID);#if USER_SPACE	if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))		printf("PCI: warning, sys_outl failed: %d\n", s);#else	outl(PCII_CONFADD, PCII_UNSEL);#endif	if (vid == 0xffff && did == 0xffff)		return;	/* Nothing here */	for (i= 0; pci_intel_ctrl[i].vid; i++)	{		if (pci_intel_ctrl[i].vid == vid &&			pci_intel_ctrl[i].did == did)		{			break;		}	}	if (!pci_intel_ctrl[i].vid)	{		printf("pci_intel_init (warning): unknown PCI-controller:\n"			"\tvendor %04X (%s), device %04X\n",			vid, pci_vid_name(vid), did);	}	if (nr_pcibus >= NR_PCIBUS)		panic("PCI","too many PCI busses", nr_pcibus);	busind= nr_pcibus;	nr_pcibus++;	pcibus[busind].pb_type= PBT_INTEL;	pcibus[busind].pb_isabridge_dev= -1;	pcibus[busind].pb_isabridge_type= 0;	pcibus[busind].pb_devind= -1;	pcibus[busind].pb_bus= 0;	pcibus[busind].pb_rreg8= pcii_rreg8;

⌨️ 快捷键说明

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