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

📄 prep_pci.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	unsigned char intpin;	static unsigned char bridge_intrs[4] = { 3, 4, 5, 8 };	if (dev == NULL)		return;	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &intpin);	if (intpin < 1 || intpin > 4)		return;	intpin = (PCI_SLOT(dev->devfn) + intpin - 1) & 3;	dev->irq = openpic_to_irq(bridge_intrs[intpin]);	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);}void __initprep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi){	if (have_residual_data) {		Motherboard_map_name = res->VitalProductData.PrintableModel;		Motherboard_map = NULL;		Motherboard_routes = NULL;		residual_irq_mask(irq_edge_mask_lo, irq_edge_mask_hi);	}}void __initprep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi){	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 */}void __initprep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi){	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 */}void __initprep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi){	Motherboard_map_name = "IBM 7248, PowerSeries 830/850 (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 */}void __initprep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi){	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 */}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 irq_edge_mask_lo, irq_edge_mask_hi;		unsigned short irq_edge_mask;		int i;		setup_ibm_pci(&irq_edge_mask_lo, &irq_edge_mask_hi);		outb(inb(0x04d0)|irq_edge_mask_lo, 0x4d0); /* primary 8259 */		outb(inb(0x04d1)|irq_edge_mask_hi, 0x4d1); /* cascaded 8259 */		irq_edge_mask = (irq_edge_mask_hi << 8) | irq_edge_mask_lo;		for (i = 0; i < 16; ++i, irq_edge_mask >>= 1)			if (irq_edge_mask & 1)				irq_desc[i].status |= IRQ_LEVEL;	} else {		printk("No known machine pci routing!\n");		return;	}	/* Set up mapping from slots */	if (Motherboard_routes) {		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_get_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_get_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_get_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);			}		}		pci_dev_put(dev);	}	if ((dev = pci_get_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);		}	}	pci_dev_put(dev);}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 */	pci_read_config_byte(dev, 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 = NULL;	int irq;	int have_openpic = (OpenPIC_Addr != NULL);	prep_route_pci_interrupts();	printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);	/* Iterate through all the PCI devices, setting the IRQ */	for_each_pci_dev(dev) {		/*		 * If we have residual data, then this is easy: query the		 * residual data for the IRQ line allocated to the device.		 * This works the same whether we have an OpenPic or not.		 */		if (have_residual_data) {			irq = residual_pcidev_irq(dev);			dev->irq = have_openpic ? openpic_to_irq(irq) : irq;		}		/*		 * If we don't have residual data, then we need to use		 * tables to determine the IRQ.  The table organisation		 * is different depending on whether there is an OpenPIC		 * or not.  The tables are only used for bus 0, so check		 * this first.		 */		else if (dev->bus->number == 0) {			irq = Motherboard_map[PCI_SLOT(dev->devfn)];			dev->irq = have_openpic ? openpic_to_irq(irq)						: Motherboard_routes[irq];		}		/*		 * Finally, if we don't have residual data and the bus is		 * non-zero, use the callback (if provided)		 */		else {			if (Motherboard_non0 != NULL)				Motherboard_non0(dev);			continue;		}		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);	}	/* Setup the Winbond or Via PIB - prep_pib_init() is coded for	 * the non-openpic case, but it breaks (at least) the Utah	 * (Powerstack II Pro4000), so only call it if we have an	 * openpic.	 */	if (have_openpic)		prep_pib_init();}static void __initprep_pcibios_after_init(void){#if 0	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_get_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);		pci_dev_put(dev);	}#endif}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 = ioremap(PREP_ISA_IO_BASE, 0x800000);	prep_init_resource(&hose->io_resource, 0, 0x007fffff, IORESOURCE_IO);	prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff,			   IORESOURCE_MEM);	setup_indirect_pci(hose, PREP_ISA_IO_BASE + 0xcf8,			   PREP_ISA_IO_BASE + 0xcfc);	printk("PReP architecture\n");	if (have_residual_data) {		PPC_DEVICE *hostbridge;		hostbridge = residual_find_device(PROCESSORDEVICE, NULL,			BridgeController, PCIBridge, -1, 0);		if (hostbridge &&			((hostbridge->DeviceId.Interface == PCIBridgeIndirect) ||			 (hostbridge->DeviceId.Interface == PCIBridgeRS6K))) {			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)));#undef p			} else				setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc);		}	}	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 + -