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

📄 prep_pci.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		return PCIBIOS_DEVICE_NOT_FOUND;    	} else                                                                	{		ptr = (unsigned long *)CFGPTR(dev);		_val = le32_to_cpu(*ptr);	}	*val = _val;	return PCIBIOS_SUCCESSFUL;}__prepintprep_pcibios_read_config_word (unsigned char bus,			  unsigned char dev, unsigned char offset, unsigned short *val){	unsigned short _val;                                          	unsigned short *ptr;	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))	{                   		*val = 0xFFFF;		return PCIBIOS_DEVICE_NOT_FOUND;    	} else                                                                	{		ptr = (unsigned short *)CFGPTR(dev);		_val = le16_to_cpu(*ptr);	}	*val = _val;	return PCIBIOS_SUCCESSFUL;}__prepintprep_pcibios_read_config_byte (unsigned char bus,			  unsigned char dev, unsigned char offset, unsigned char *val){	unsigned char _val;                                          	unsigned char *ptr;	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))	{                   		*val = 0xFF;		return PCIBIOS_DEVICE_NOT_FOUND;    	} else                                                                	{		ptr = (unsigned char *)CFGPTR(dev);		_val = *ptr;	}	*val = _val;	return PCIBIOS_SUCCESSFUL;}__prepintprep_pcibios_write_config_dword (unsigned char bus,			    unsigned char dev, unsigned char offset, unsigned int val){	unsigned long _val;	unsigned long *ptr;	_val = le32_to_cpu(val);	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))	{		return PCIBIOS_DEVICE_NOT_FOUND;	} else	{		ptr = (unsigned long *)CFGPTR(dev);		*ptr = _val;	}	return PCIBIOS_SUCCESSFUL;}__prepintprep_pcibios_write_config_word (unsigned char bus,			   unsigned char dev, unsigned char offset, unsigned short val){	unsigned short _val;	unsigned short *ptr;	_val = le16_to_cpu(val);	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))	{		return PCIBIOS_DEVICE_NOT_FOUND;	} else	{		ptr = (unsigned short *)CFGPTR(dev);		*ptr = _val;	}	return PCIBIOS_SUCCESSFUL;}__prepintprep_pcibios_write_config_byte (unsigned char bus,			   unsigned char dev, unsigned char offset, unsigned char val){	unsigned char _val;	unsigned char *ptr;	_val = val;	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))	{		return PCIBIOS_DEVICE_NOT_FOUND;	} else	{		ptr = (unsigned char *)CFGPTR(dev);		*ptr = _val;	}	return PCIBIOS_SUCCESSFUL;}#define MOTOROLA_CPUTYPE_REG	0x800#define MOTOROLA_BASETYPE_REG	0x803#define MPIC_RAVEN_ID		0x48010000#define	MPIC_HAWK_ID		0x48030000#define	MOT_PROC2_BIT		0x800static u_char mvme2600_openpic_initsenses[] __initdata = {    1,	/* MVME2600_INT_SIO */    0,	/* MVME2600_INT_FALCN_ECC_ERR */    1,	/* MVME2600_INT_PCI_ETHERNET */    1,	/* MVME2600_INT_PCI_SCSI */    1,	/* MVME2600_INT_PCI_GRAPHICS */    1,	/* MVME2600_INT_PCI_VME0 */    1,	/* MVME2600_INT_PCI_VME1 */    1,	/* MVME2600_INT_PCI_VME2 */    1,	/* MVME2600_INT_PCI_VME3 */    1,	/* MVME2600_INT_PCI_INTA */    1,	/* MVME2600_INT_PCI_INTB */    1,	/* MVME2600_INT_PCI_INTC */    1,	/* MVME2600_INT_PCI_INTD */    1,	/* MVME2600_INT_LM_SIG0 */    1,	/* MVME2600_INT_LM_SIG1 */};#define MOT_RAVEN_PRESENT	0x1#define MOT_HAWK_PRESENT	0x2int prep_keybd_present = 1;int MotMPIC = 0;int __init raven_init(void){	unsigned int	devid;	unsigned int	pci_membase;	unsigned char	base_mod;	/* Check to see if the Raven chip exists. */	if ( _prep_type != _PREP_Motorola) {		OpenPIC = NULL;		return 0;	}	/* Check to see if this board is a type that might have a Raven. */	if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) {		OpenPIC = NULL;		return 0;	}	/* Check the first PCI device to see if it is a Raven. */	pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devid);	switch (devid & 0xffff0000) {	case MPIC_RAVEN_ID:		MotMPIC = MOT_RAVEN_PRESENT;		break;	case MPIC_HAWK_ID:		MotMPIC = MOT_HAWK_PRESENT;		break;	default:		OpenPIC = NULL;		return 0;	}	/* Read the memory base register. */	pcibios_read_config_dword(0, 0, PCI_BASE_ADDRESS_1, &pci_membase);	if (pci_membase == 0) {		OpenPIC = NULL;		return 0;	}	/* Map the Raven MPIC registers to virtual memory. */	OpenPIC = (struct OpenPIC *)ioremap(pci_membase+0xC0000000, 0x22000);	OpenPIC_InitSenses = mvme2600_openpic_initsenses;	OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses);	ppc_md.get_irq = chrp_get_irq;	ppc_md.post_irq = chrp_post_irq;		/* If raven is present on Motorola store the system config register	 * for later use.	 */	ProcInfo = (unsigned long *)ioremap(0xfef80400, 4);	/* This is a hack.  If this is a 2300 or 2400 mot board then there is	 * no keyboard controller and we have to indicate that.	 */	base_mod = inb(MOTOROLA_BASETYPE_REG);	if ((MotMPIC == MOT_HAWK_PRESENT) || (base_mod == 0xF9) ||	    (base_mod == 0xFA) || (base_mod == 0xE1))		prep_keybd_present = 0;	return 1;}struct mot_info {	int		cpu_type;	/* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */					/* 0x200 if this board has a Hawk chip. */	int		base_type;	int		max_cpu;	/* ored with 0x80 if this board should be checked for multi CPU */	const char	*name;	unsigned char	*map;	unsigned char	*routes;} mot_info[] = {	{0x300, 0x00, 0x00, "MVME 2400",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x010, 0x00, 0x00, "Genesis",				Genesis_pci_IRQ_map,	Genesis_pci_IRQ_routes},	{0x020, 0x00, 0x00, "Powerstack (Series E)",		Comet_pci_IRQ_map,	Comet_pci_IRQ_routes},	{0x040, 0x00, 0x00, "Blackhawk (Powerstack)",		Blackhawk_pci_IRQ_map,	Blackhawk_pci_IRQ_routes},	{0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)",	Omaha_pci_IRQ_map,	Omaha_pci_IRQ_routes},	{0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)",	Utah_pci_IRQ_map,	Utah_pci_IRQ_routes},	{0x0A0, 0x00, 0x00, "Powerstack (Series EX)",		Comet2_pci_IRQ_map,	Comet2_pci_IRQ_routes},	{0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)",		Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)",		Sitka_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC",	Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xF6, 0x80, "MTX Plus",				MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xF6, 0x81, "Dual MTX Plus",			MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xF9, 0x00, "MVME 2300",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFA, 0x00, "MVME 2300SC/2600",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},	{0x000, 0x00, 0x00, "",					NULL,			NULL}};unsigned long __init prep_route_pci_interrupts(void){	unsigned char *ibc_pirq = (unsigned char *)0x80800860;	unsigned char *ibc_pcicon = (unsigned char *)0x80800840;	int i;		if ( _prep_type == _PREP_Motorola)	{		unsigned short irq_mode;		unsigned char  cpu_type;		unsigned char  base_mod;		int	       entry;		int	       mot_entry = -1;		cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;		base_mod = inb(MOTOROLA_BASETYPE_REG);		for (entry = 0; mot_info[entry].cpu_type != 0; entry++) {			if (mot_info[entry].cpu_type & 0x200) {		 	/* Check for Hawk chip */				if (!(MotMPIC & MOT_HAWK_PRESENT))					continue;			} else {						/* Check non hawk boards */				if ((mot_info[entry].cpu_type & 0xff) != cpu_type)					continue;				if (mot_info[entry].base_type == 0) {					mot_entry = entry;					break;				}				if (mot_info[entry].base_type != base_mod)					continue;			}			if (!(mot_info[entry].max_cpu & 0x80)) {				mot_entry = entry;				break;			}			/* processor 1 not present and max processor zero indicated */			if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) {				mot_entry = entry;				break;			}			/* processor 1 present and max processor zero indicated */			if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) {				mot_entry = entry;				break;			}		}		if (mot_entry == -1) 	/* No particular cpu type found - assume Blackhawk */			mot_entry = 3;		Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;		Motherboard_map = mot_info[mot_entry].map;		Motherboard_routes = mot_info[mot_entry].routes;		if (!(mot_info[entry].cpu_type & 0x100)) {			/* AJF adjust level/edge control according to routes */			irq_mode = 0;			for (i = 1;  i <= 4;  i++)			{				irq_mode |= ( 1 << Motherboard_routes[i] );			}			outb( irq_mode & 0xff, 0x4d0 );			outb( (irq_mode >> 8) & 0xff, 0x4d1 );		}	} else if ( _prep_type == _PREP_IBM )	{		unsigned char pl_id;		/*		 * my carolina is 0xf0		 * 6015 has 0xfc		 * -- Cort		 */		printk("IBM ID: %08x\n", inb(0x0852));		switch(inb(0x0852))		{		case 0xff:			Motherboard_map_name = "IBM 850/860 Portable\n";			Motherboard_map = Nobis_pci_IRQ_map;			Motherboard_routes = Nobis_pci_IRQ_routes;			break;		case 0xfc:			Motherboard_map_name = "IBM 6015";			Motherboard_map = ibm6015_pci_IRQ_map;			Motherboard_routes = ibm6015_pci_IRQ_routes;			break;					default:			Motherboard_map_name = "IBM 8xx (Carolina)";			Motherboard_map = ibm8xx_pci_IRQ_map;			Motherboard_routes = ibm8xx_pci_IRQ_routes;			break;		}		/*printk("Changing IRQ mode\n");*/		pl_id=inb(0x04d0);		/*printk("Low mask is %#0x\n", pl_id);*/		outb(pl_id|CAROLINA_IRQ_EDGE_MASK_LO, 0x04d0);				pl_id=inb(0x04d1);		/*printk("Hi mask is  %#0x\n", pl_id);*/		outb(pl_id|CAROLINA_IRQ_EDGE_MASK_HI, 0x04d1);		pl_id=inb(0x04d1);		/*printk("Hi mask now %#0x\n", pl_id);*/	} else if ( _prep_type == _PREP_Radstone )	{		unsigned char ucElcrM, ucElcrS;		/*		 * Set up edge/level		 */		switch(ucSystemType)		{			case RS_SYS_TYPE_PPC1:			{				if(ucBoardRevMaj<5)				{					ucElcrS=ELCRS_INT15_LVL;				}				else				{					ucElcrS=ELCRS_INT9_LVL |					        ELCRS_INT11_LVL |					        ELCRS_INT14_LVL |					        ELCRS_INT15_LVL;				}				ucElcrM=ELCRM_INT5_LVL | ELCRM_INT7_LVL;				break;			}			case RS_SYS_TYPE_PPC1a:			{				ucElcrS=ELCRS_INT9_LVL |				        ELCRS_INT11_LVL |				        ELCRS_INT14_LVL |				        ELCRS_INT15_LVL;				ucElcrM=ELCRM_INT5_LVL;				break;			}			case RS_SYS_TYPE_PPC2:			case RS_SYS_TYPE_PPC2a:			case RS_SYS_TYPE_PPC2ep:			case RS_SYS_TYPE_PPC4:			case RS_SYS_TYPE_PPC4a:			default:			{				ucElcrS=ELCRS_INT9_LVL |				        ELCRS_INT10_LVL |				        ELCRS_INT11_LVL |				        ELCRS_INT14_LVL |				        ELCRS_INT15_LVL;				ucElcrM=ELCRM_INT5_LVL |				        ELCRM_INT7_LVL;				break;			}		}		/*		 * Write edge/level selection		 */		outb(ucElcrS, ISA8259_S_ELCR);		outb(ucElcrM, ISA8259_M_ELCR);		/*		 * Radstone boards have PCI interrupts all set up		 * so leave well alone		 */		return 0;	} else	{		printk("No known machine pci routing!\n");		return -1;	}		/* Set up mapping from slots */	for (i = 1;  i <= 4;  i++)	{		ibc_pirq[i-1] = Motherboard_routes[i];	}	/* Enable PCI interrupts */	*ibc_pcicon |= 0x20;	return 0;}void __initprep_pcibios_fixup(void){        struct pci_dev *dev;        extern unsigned char *Motherboard_map;        extern unsigned char *Motherboard_routes;        unsigned char i;        if ( _prep_type == _PREP_Radstone )        {                printk("Radstone boards require no PCI fixups\n");		return;        }	prep_route_pci_interrupts();	printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);	if (OpenPIC) {		/* PCI interrupts are controlled by the OpenPIC */		pci_for_each_dev(dev) {			if (dev->bus->number == 0) {                       		dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);				pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_PIN, dev->irq);			}		}		return;	}	pci_for_each_dev(dev) {		/*		 * Use our old hard-coded kludge to figure out what		 * irq this device uses.  This is necessary on things		 * without residual data. -- Cort		 */		unsigned char d = PCI_SLOT(dev->devfn);		dev->irq = Motherboard_routes[Motherboard_map[d]];		for ( i = 0 ; i <= 5 ; i++ )		{		        if ( dev->resource[i].start > 0x10000000 )		        {		                printk("Relocating PCI address %lx -> %lx\n",		                       dev->resource[i].start,		                       (dev->resource[i].start & 0x00FFFFFF)		                       | 0x01000000);		                dev->resource[i].start =		                  (dev->resource[i].start & 0x00FFFFFF) | 0x01000000;		                pci_write_config_dword(dev,		                        PCI_BASE_ADDRESS_0+(i*0x4),		                       dev->resource[i].start );		        }		}#if 0		/*		 * If we have residual data and if it knows about this		 * device ask it what the irq is.		 *  -- Cort		 */		ppcd = residual_find_device_id( ~0L, dev->device,		                                -1,-1,-1, 0);#endif	}}decl_config_access_method(indirect);void __initprep_setup_pci_ptrs(void){	PPC_DEVICE *hostbridge;        printk("PReP architecture\n");        if ( _prep_type == _PREP_Radstone )        {		pci_config_address = (unsigned *)0x80000cf8;		pci_config_data = (char *)0x80000cfc;		set_config_access_method(indirect);		        }        else        {                hostbridge = residual_find_device(PROCESSORDEVICE, NULL,		       BridgeController, PCIBridge, -1, 0);                if (hostbridge &&                    hostbridge->DeviceId.Interface == PCIBridgeIndirect) {                        PnP_TAG_PACKET * pkt;                        set_config_access_method(indirect);                        pkt = PnP_find_large_vendor_packet(				res->DevicePnPHeap+hostbridge->AllocatedOffset,				3, 0);                        if(pkt)			{#define p pkt->L4_Pack.L4_Data.L4_PPCPack                                pci_config_address= (unsigned *)ld_le32((unsigned *) p.PPCData);				pci_config_data= (unsigned char *)ld_le32((unsigned *) (p.PPCData+8));                        }			else			{                                pci_config_address= (unsigned *) 0x80000cf8;                                pci_config_data= (unsigned char *) 0x80000cfc;                        }                }		else		{                        set_config_access_method(prep);                }        }	ppc_md.pcibios_fixup = prep_pcibios_fixup;}

⌨️ 快捷键说明

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