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

📄 pci.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * pci.c :  this file contains basic PCI Io functions. * *  Copyright (C) 1999 valette@crf.canon.fr * *  This code is heavily inspired by the public specification of STREAM V2 *  that can be found at : * *      <http://www.chorus.com/Documentation/index.html> by following *  the STREAM API Specification Document link. * *  The license and distribution terms for this file may be *  found in found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: pci.c,v 1.2.4.4 2004/11/10 22:15:01 joel Exp $ * *  Till Straumann, <strauman@slac.stanford.edu>, 1/2002 *   - separated bridge detection code out of this file */#include <libcpu/io.h>#include <bsp/pci.h>#include <rtems/bspIo.h>/* allow for overriding these definitions */#ifndef PCI_CONFIG_ADDR#define PCI_CONFIG_ADDR			0xcf8#endif#ifndef PCI_CONFIG_DATA#define PCI_CONFIG_DATA			0xcfc#endif#define PCI_INVALID_VENDORDEVICEID	0xffffffff#define PCI_MULTI_FUNCTION		0x80/* define a shortcut */#define pci	BSP_pci_configuration/* * Bit encode for PCI_CONFIG_HEADER_TYPE register */unsigned char ucMaxPCIBus;static intindirect_pci_read_config_byte(unsigned char bus, unsigned char slot,			      unsigned char function, 			      unsigned char offset, unsigned char *val) {	out_be32((unsigned int*) pci.pci_config_addr, 		 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));	*val = in_8(pci.pci_config_data + (offset&3));	return PCIBIOS_SUCCESSFUL;}static intindirect_pci_read_config_word(unsigned char bus, unsigned char slot,			      unsigned char function, 			      unsigned char offset, unsigned short *val) {	*val = 0xffff; 	if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;	out_be32((unsigned int*) pci.pci_config_addr, 		 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));	*val = in_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)));	return PCIBIOS_SUCCESSFUL;}static intindirect_pci_read_config_dword(unsigned char bus, unsigned char slot,			      unsigned char function, 			      unsigned char offset, unsigned int *val) {	*val = 0xffffffff; 	if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;	out_be32((unsigned int*) pci.pci_config_addr, 		 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));	*val = in_le32((volatile unsigned int *)pci.pci_config_data);	return PCIBIOS_SUCCESSFUL;}static intindirect_pci_write_config_byte(unsigned char bus, unsigned char slot,			       unsigned char function, 			       unsigned char offset, unsigned char val) {	out_be32((unsigned int*) pci.pci_config_addr, 		 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));	out_8(pci.pci_config_data + (offset&3), val);	return PCIBIOS_SUCCESSFUL;}static intindirect_pci_write_config_word(unsigned char bus, unsigned char slot,			       unsigned char function, 			       unsigned char offset, unsigned short val) {	if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;	out_be32((unsigned int*) pci.pci_config_addr, 		 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));	out_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)), val);	return PCIBIOS_SUCCESSFUL;}static intindirect_pci_write_config_dword(unsigned char bus, unsigned char slot,				unsigned char function, 				unsigned char offset, unsigned int val) {	if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;	out_be32((unsigned int*) pci.pci_config_addr, 		 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));	out_le32((volatile unsigned int *)pci.pci_config_data, val);	return PCIBIOS_SUCCESSFUL;}const pci_config_access_functions pci_indirect_functions = {  	indirect_pci_read_config_byte,  	indirect_pci_read_config_word,  	indirect_pci_read_config_dword,  	indirect_pci_write_config_byte,  	indirect_pci_write_config_word,  	indirect_pci_write_config_dword};pci_config BSP_pci_configuration = {(volatile unsigned char*)PCI_CONFIG_ADDR,			 (volatile unsigned char*)PCI_CONFIG_DATA,			 &pci_indirect_functions};static intdirect_pci_read_config_byte(unsigned char bus, unsigned char slot,			    unsigned char function, 			    unsigned char offset, unsigned char *val) {	if (bus != 0 || (1<<slot & 0xff8007fe)) {		*val=0xff; 		return PCIBIOS_DEVICE_NOT_FOUND;	}	*val=in_8(pci.pci_config_data + ((1<<slot)&~1) 		  + (function<<8) + offset);	return PCIBIOS_SUCCESSFUL;}static intdirect_pci_read_config_word(unsigned char bus, unsigned char slot,			    unsigned char function, 			    unsigned char offset, unsigned short *val) {	*val = 0xffff; 	if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus != 0 || (1<<slot & 0xff8007fe)) { 		return PCIBIOS_DEVICE_NOT_FOUND;	}	*val=in_le16((volatile unsigned short *)		     (pci.pci_config_data + ((1<<slot)&~1)		      + (function<<8) + offset));	return PCIBIOS_SUCCESSFUL;}static intdirect_pci_read_config_dword(unsigned char bus, unsigned char slot,			     unsigned char function, 			     unsigned char offset, unsigned int *val) {	*val = 0xffffffff; 	if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus != 0 || (1<<slot & 0xff8007fe)) { 		return PCIBIOS_DEVICE_NOT_FOUND;	}	*val=in_le32((volatile unsigned int *)		     (pci.pci_config_data + ((1<<slot)&~1)		      + (function<<8) + offset));	return PCIBIOS_SUCCESSFUL;}static intdirect_pci_write_config_byte(unsigned char bus, unsigned char slot,			     unsigned char function, 			     unsigned char offset, unsigned char val) {	if (bus != 0 || (1<<slot & 0xff8007fe)) { 		return PCIBIOS_DEVICE_NOT_FOUND;	}	out_8(pci.pci_config_data + ((1<<slot)&~1) 	      + (function<<8) + offset, 	      val);	return PCIBIOS_SUCCESSFUL;}static intdirect_pci_write_config_word(unsigned char bus, unsigned char slot,			     unsigned char function, 			     unsigned char offset, unsigned short val) {	if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus != 0 || (1<<slot & 0xff8007fe)) { 		return PCIBIOS_DEVICE_NOT_FOUND;	}	out_le16((volatile unsigned short *)		 (pci.pci_config_data + ((1<<slot)&~1)		  + (function<<8) + offset),		 val);	return PCIBIOS_SUCCESSFUL;}static intdirect_pci_write_config_dword(unsigned char bus, unsigned char slot,			      unsigned char function, 			      unsigned char offset, unsigned int val) {	if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;	if (bus != 0 || (1<<slot & 0xff8007fe)) { 		return PCIBIOS_DEVICE_NOT_FOUND;	}	out_le32((volatile unsigned int *)		 (pci.pci_config_data + ((1<<slot)&~1)		  + (function<<8) + offset),		 val);	return PCIBIOS_SUCCESSFUL;}const pci_config_access_functions pci_direct_functions = {  	direct_pci_read_config_byte,  	direct_pci_read_config_word,  	direct_pci_read_config_dword,  	direct_pci_write_config_byte,  	direct_pci_write_config_word,  	direct_pci_write_config_dword};#define PRINT_MSG() \             printk("pci : Device %d:%02x routed to interrupt_line %d\n", pbus, pslot, int_name )/* ** Validate a test interrupt name and print a warning if its not one of** the names defined in the routing record.*/static int test_intname(  const struct _int_map *row,  int pbus,  int pslot,  int int_pin,  int int_name){   int j, k;   int _nopin= -1, _noname= -1;   for(j=0; row->pin_route[j].pin > -1; j++)   {      if( row->pin_route[j].pin == int_pin )       {         _nopin = 0;                  for(k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ )         {            if( row->pin_route[j].int_name[k] == int_name ){ _noname=0; break; }          }         break;      }   }   if( _nopin  )    {      printk("pci : Device %d:%02x supplied a bogus interrupt_pin %d\n", pbus, pslot, int_pin );      return -1;   }   else   {      if( _noname )         printk("pci : Device %d:%02x supplied a suspicious interrupt_line %d, using it anyway\n", pbus, pslot, int_name );   }   return 0;}struct pcibridge{      int bus,slot;};static int FindPCIbridge( int mybus, struct pcibridge *pb ){   int          pbus, pslot;   unsigned8    bussec, buspri;   unsigned16   devid, vendorid, dclass;   for(pbus=0; pbus< BusCountPCI(); pbus++)   {      for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++)      {          pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);         if( devid == 0xffff ) continue;         pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid);         if( vendorid == 0xffff ) continue;         pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass);         if( dclass == PCI_CLASS_BRIDGE_PCI )          {            pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS,    &buspri);            pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS,  &bussec);#if 0            printk("pci : Found bridge at %d:%d, mybus %d, pribus %d, secbus %d  ", pbus, pslot, mybus, buspri, bussec );#endif            if( bussec == mybus )            {#if 0               printk("match\n");#endif               /* found our nearest bridge going towards the root */

⌨️ 快捷键说明

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