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

📄 prep_pci.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
	dev->irq = openpic_to_irq(bridge_intrs[intpin]);	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);}void __initprep_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;		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;		Motherboard_non0 = mot_info[mot_entry].map_non0_bus;		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 planar_id = inb(0x0852);		unsigned char irq_edge_mask_lo, irq_edge_mask_hi;		printk("IBM ID: %08x\n", planar_id);		switch(planar_id) {		case 0xff:			Motherboard_map_name = "IBM Thinkpad 850/860";			Motherboard_map = Nobis_pci_IRQ_map;			Motherboard_routes = Nobis_pci_IRQ_routes;			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */			irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */			break;		case 0xfc:			Motherboard_map_name = "IBM 6015/7020 (Sandalfoot/Sandalbow)";			Motherboard_map = ibm6015_pci_IRQ_map;			Motherboard_routes = ibm6015_pci_IRQ_routes;			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */			irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */			break;		case 0xd5:			Motherboard_map_name = "IBM 43P-140 (Tiger1)";			Motherboard_map = ibm43p_pci_IRQ_map;			Motherboard_routes = ibm43p_pci_IRQ_routes;			Motherboard_non0 = ibm43p_pci_map_non0;			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */			irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */			break;		default:			printk(KERN_ERR "Unknown IBM motherboard! Defaulting to Carolina.\n");		case 0xf0: /* PowerSeries 830/850 */		case 0xf1: /* PowerSeries 830/850 */		case 0xf2: /* PowerSeries 830/850 */		case 0xf4: /* 7248-43P */		case 0xf5: /* 7248-43P */		case 0xf6: /* 7248-43P */		case 0xf7: /* 7248-43P (missing from Carolina Tech Spec) */			Motherboard_map_name = "IBM PS830/PS850/7248 (Carolina)";			Motherboard_map = ibm8xx_pci_IRQ_map;			Motherboard_routes = ibm8xx_pci_IRQ_routes;			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */			irq_edge_mask_hi = 0xA4; /* irq's 10, 13, 15 level-triggered */			break;		}		outb(inb(0x04d0)|irq_edge_mask_lo, 0x04d0); /* primary 8259 */		outb(inb(0x04d1)|irq_edge_mask_hi, 0x04d1); /* cascaded 8259 */	} else {		printk("No known machine pci routing!\n");		return;	}		/* Set up mapping from slots */	for (i = 1;  i <= 4;  i++)		ibc_pirq[i-1] = Motherboard_routes[i];	/* Enable PCI interrupts */	*ibc_pcicon |= 0x20;}void __initprep_pib_init(void){	unsigned char   reg;	unsigned short  short_reg;	struct pci_dev *dev = NULL;	if (( _prep_type == _PREP_Motorola) && (OpenPIC_Addr)) {		/*		 * Perform specific configuration for the Via Tech or		 * or Winbond PCI-ISA-Bridge part.		 */		if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, 					PCI_DEVICE_ID_VIA_82C586_1, dev))) {			/*			 * PPCBUG does not set the enable bits			 * for the IDE device. Force them on here.			 */			pci_read_config_byte(dev, 0x40, &reg);			reg |= 0x03; /* IDE: Chip Enable Bits */			pci_write_config_byte(dev, 0x40, reg);		}		if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,						PCI_DEVICE_ID_VIA_82C586_2,						dev)) && (dev->devfn = 0x5a)) {			/* Force correct USB interrupt */			dev->irq = 11;			pci_write_config_byte(dev,					PCI_INTERRUPT_LINE,					dev->irq);		}		if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,					PCI_DEVICE_ID_WINBOND_83C553, dev))) {			 /* Clear PCI Interrupt Routing Control Register. */			short_reg = 0x0000;			pci_write_config_word(dev, 0x44, short_reg);			if (OpenPIC_Addr){				/* Route IDE interrupts to IRQ 14 */				reg = 0xEE;				pci_write_config_byte(dev, 0x43, reg);			}		}	}	if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,				   PCI_DEVICE_ID_WINBOND_82C105, dev))){		if (OpenPIC_Addr){			/*			 * Disable LEGIRQ mode so PCI INTS are routed			 * directly to the 8259 and enable both channels			 */			pci_write_config_dword(dev, 0x40, 0x10ff0033);			/* Force correct IDE interrupt */			dev->irq = 14;			pci_write_config_byte(dev,					PCI_INTERRUPT_LINE,					dev->irq);		} else {			/* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */			pci_write_config_dword(dev, 0x40, 0x10ff08a1);		}	}}static void __initPowerplus_Map_Non0(struct pci_dev *dev){	struct pci_bus  *pbus;          /* Parent bus structure pointer */	struct pci_dev  *tdev = dev;    /* Temporary device structure */	unsigned int    devnum;         /* Accumulated device number */	unsigned char   intline;        /* Linux interrupt value */	unsigned char   intpin;         /* PCI interrupt pin */	/* Check for valid PCI dev pointer */	if (dev == NULL) return;	/* Initialize bridge IDSEL variable */	devnum = PCI_SLOT(tdev->devfn);	/* Read the interrupt pin of the device and adjust for indexing */	pcibios_read_config_byte(dev->bus->number, dev->devfn,			PCI_INTERRUPT_PIN, &intpin);	/* If device doesn't request an interrupt, return */	if ( (intpin < 1) || (intpin > 4) )		return;	intpin--;	/*	 * Walk up to bus 0, adjusting the interrupt pin for the standard	 * PCI bus swizzle.	 */	do {		intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;		pbus = tdev->bus;        /* up one level */		tdev = pbus->self;		devnum = PCI_SLOT(tdev->devfn);	} while(tdev->bus->number);	/* Use the primary interrupt inputs by default */	intline = mot_info[mot_entry].pci_irq_list->primary[intpin];	/*	 * If the board has secondary interrupt inputs, walk the bus and	 * note the devfn of the bridge from bus 0.  If it is the same as	 * the devfn of the bus bridge with secondary inputs, use those.	 * Otherwise, assume it's a PMC site and get the interrupt line	 * value from the interrupt routing table.	 */ 	if (mot_info[mot_entry].secondary_bridge_devfn) {		pbus = dev->bus;		while (pbus->primary != 0)			pbus = pbus->parent;		if ((pbus->self)->devfn != 0xA0) {			if ((pbus->self)->devfn == mot_info[mot_entry].secondary_bridge_devfn)				intline = mot_info[mot_entry].pci_irq_list->secondary[intpin];			else {				if ((char *)(mot_info[mot_entry].map) == (char *)Mesquite_pci_IRQ_map)					intline = mot_info[mot_entry].map[((pbus->self)->devfn)/8] + 16;				else {					int i;					for (i=0;i<3;i++)						intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;					intline = mot_info[mot_entry].pci_irq_list->primary[intpin];				}			}		}	}	/* Write calculated interrupt value to header and device list */	dev->irq = intline;	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, (u8)dev->irq);}void __initprep_pcibios_fixup(void){        struct pci_dev *dev;        extern unsigned char *Motherboard_map;        extern unsigned char *Motherboard_routes;        unsigned char i;	prep_route_pci_interrupts();	printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);	if (OpenPIC_Addr) {		/* 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_LINE, dev->irq);			} else {				if (Motherboard_non0 != NULL)					Motherboard_non0(dev);			}		}		/* Setup the Winbond or Via PIB */		prep_pib_init();		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++ ) {			/*			 * Relocate PCI I/O resources if necessary so the			 * standard 256MB BAT covers them.			 */			if ( (pci_resource_flags(dev, i) & IORESOURCE_IO) &&				      (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);				dev->resource[i].end = 					(dev->resource[i].end & 0x00FFFFFF)					| 0x01000000;		        }		}#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	}}static void __initprep_pcibios_after_init(void){	struct pci_dev *dev;		/* If there is a WD 90C, reset the IO BAR to 0x0 (it started that 	 * way, but the PCI layer relocated it because it thought 0x0 was	 * invalid for a BAR).	 * If you don't do this, the card's VGA base will be <IO BAR>+0xc0000	 * instead of 0xc0000. vgacon.c (for example) is completely unaware of	 * this little quirk.	 */	dev = pci_find_device(PCI_VENDOR_ID_WD, PCI_DEVICE_ID_WD_90C, NULL);	if (dev) {		dev->resource[1].end -= dev->resource[1].start;		dev->resource[1].start = 0;		/* tell the hardware */		pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x0);	}}static void __initprep_init_resource(struct resource *res, unsigned long start,		   unsigned long end, int flags){	res->flags = flags;	res->start = start;	res->end = end;	res->name = "PCI host bridge";	res->parent = NULL;	res->sibling = NULL;	res->child = NULL;}void __initprep_find_bridges(void){	struct pci_controller* hose;	hose = pcibios_alloc_controller();	if (!hose)		return;	hose->first_busno = 0;	hose->last_busno = 0xff;	hose->pci_mem_offset = PREP_ISA_MEM_BASE;	hose->io_base_phys = PREP_ISA_IO_BASE;	hose->io_base_virt = (void *)0x80000000; /* see prep_map_io() */	prep_init_resource(&hose->io_resource, 0, 0x0fffffff, IORESOURCE_IO);	prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff,			   IORESOURCE_MEM);		printk("PReP architecture\n");	{#ifdef CONFIG_PREP_RESIDUAL	  		PPC_DEVICE *hostbridge;		hostbridge = residual_find_device(PROCESSORDEVICE, NULL,			BridgeController, PCIBridge, -1, 0);		if (hostbridge &&			hostbridge->DeviceId.Interface == PCIBridgeIndirect) {			PnP_TAG_PACKET * pkt;			pkt = PnP_find_large_vendor_packet(				res->DevicePnPHeap+hostbridge->AllocatedOffset,				3, 0);			if(pkt) {#define p pkt->L4_Pack.L4_Data.L4_PPCPack				setup_indirect_pci(hose, 					ld_le32((unsigned *) (p.PPCData)),					ld_le32((unsigned *) (p.PPCData+8)));			} else				setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc);		} else#endif /* CONFIG_PREP_RESIDUAL */			hose->ops = &prep_pci_ops;	}	ppc_md.pcibios_fixup = prep_pcibios_fixup;	ppc_md.pcibios_after_init = prep_pcibios_after_init;}

⌨️ 快捷键说明

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