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

📄 amd64-agp.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
{	char *revstring;	u8 rev_id;	pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);	switch (rev_id) {	case 0x01: revstring="A0"; break;	case 0x02: revstring="A1"; break;	case 0x11: revstring="B0"; break;	case 0x12: revstring="B1"; break;	case 0x13: revstring="B2"; break;	case 0x14: revstring="B3"; break;	default:   revstring="??"; break;	}	printk (KERN_INFO PFX "Detected AMD 8151 AGP Bridge rev %s\n", revstring);	/*	 * Work around errata.	 * Chips before B2 stepping incorrectly reporting v3.5	 */	if (rev_id < 0x13) {		printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n");		bridge->major_version = 3;		bridge->minor_version = 0;	}}static struct aper_size_info_32 uli_sizes[7] ={	{256, 65536, 6, 10},	{128, 32768, 5, 9},	{64, 16384, 4, 8},	{32, 8192, 3, 7},	{16, 4096, 2, 6},	{8, 2048, 1, 4},	{4, 1024, 0, 3}};static int __devinit uli_agp_init(struct pci_dev *pdev){	u32 httfea,baseaddr,enuscr;	struct pci_dev *dev1;	int i;	unsigned size = amd64_fetch_size();	printk(KERN_INFO "Setting up ULi AGP.\n");	dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0));	if (dev1 == NULL) {		printk(KERN_INFO PFX "Detected a ULi chipset, "			"but could not fine the secondary device.\n");		return -ENODEV;	}	for (i = 0; i < ARRAY_SIZE(uli_sizes); i++)		if (uli_sizes[i].size == size)			break;	if (i == ARRAY_SIZE(uli_sizes)) {		printk(KERN_INFO PFX "No ULi size found for %d\n", size);		return -ENODEV;	}	/* shadow x86-64 registers into ULi registers */	pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &httfea);	/* if x86-64 aperture base is beyond 4G, exit here */	if ((httfea & 0x7fff) >> (32 - 25))		return -ENODEV;	httfea = (httfea& 0x7fff) << 25;	pci_read_config_dword(pdev, ULI_X86_64_BASE_ADDR, &baseaddr);	baseaddr&= ~PCI_BASE_ADDRESS_MEM_MASK;	baseaddr|= httfea;	pci_write_config_dword(pdev, ULI_X86_64_BASE_ADDR, baseaddr);	enuscr= httfea+ (size * 1024 * 1024) - 1;	pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea);	pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr);	return 0;}static struct aper_size_info_32 nforce3_sizes[5] ={	{512,  131072, 7, 0x00000000 },	{256,  65536,  6, 0x00000008 },	{128,  32768,  5, 0x0000000C },	{64,   16384,  4, 0x0000000E },	{32,   8192,   3, 0x0000000F }};/* Handle shadow device of the Nvidia NForce3 *//* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */static int __devinit nforce3_agp_init(struct pci_dev *pdev){	u32 tmp, apbase, apbar, aplimit;	struct pci_dev *dev1;	int i;	unsigned size = amd64_fetch_size();	printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n");	dev1 = pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0));	if (dev1 == NULL) {		printk(KERN_INFO PFX "agpgart: Detected an NVIDIA "			"nForce3 chipset, but could not find "			"the secondary device.\n");		return -ENODEV;	}	for (i = 0; i < ARRAY_SIZE(nforce3_sizes); i++)		if (nforce3_sizes[i].size == size)			break;	if (i == ARRAY_SIZE(nforce3_sizes)) {		printk(KERN_INFO PFX "No NForce3 size found for %d\n", size);		return -ENODEV;	}	pci_read_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, &tmp);	tmp &= ~(0xf);	tmp |= nforce3_sizes[i].size_value;	pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp);	/* shadow x86-64 registers into NVIDIA registers */	pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase);	/* if x86-64 aperture base is beyond 4G, exit here */	if ( (apbase & 0x7fff) >> (32 - 25) )		 return -ENODEV;	apbase = (apbase & 0x7fff) << 25;	pci_read_config_dword(pdev, NVIDIA_X86_64_0_APBASE, &apbar);	apbar &= ~PCI_BASE_ADDRESS_MEM_MASK;	apbar |= apbase;	pci_write_config_dword(pdev, NVIDIA_X86_64_0_APBASE, apbar);	aplimit = apbase + (size * 1024 * 1024) - 1;	pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE1, apbase);	pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT1, aplimit);	pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase);	pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit);	return 0;}static int __devinit agp_amd64_probe(struct pci_dev *pdev,				     const struct pci_device_id *ent){	struct agp_bridge_data *bridge;	u8 cap_ptr;	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);	if (!cap_ptr)		return -ENODEV;	/* Could check for AGPv3 here */	bridge = agp_alloc_bridge();	if (!bridge)		return -ENOMEM;	if (pdev->vendor == PCI_VENDOR_ID_AMD &&	    pdev->device == PCI_DEVICE_ID_AMD_8151_0) {		amd8151_init(pdev, bridge);	} else {		printk(KERN_INFO PFX "Detected AGP bridge %x\n", pdev->devfn);	}	bridge->driver = &amd_8151_driver;	bridge->dev = pdev;	bridge->capndx = cap_ptr;	/* Fill in the mode register */	pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);	if (cache_nbs(pdev, cap_ptr) == -1) {		agp_put_bridge(bridge);		return -ENODEV;	}	if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {		int ret = nforce3_agp_init(pdev);		if (ret) {			agp_put_bridge(bridge);			return ret;		}	}	if (pdev->vendor == PCI_VENDOR_ID_AL) {		int ret = uli_agp_init(pdev);		if (ret) {			agp_put_bridge(bridge);			return ret;		}	}	pci_set_drvdata(pdev, bridge);	return agp_add_bridge(bridge);}static void __devexit agp_amd64_remove(struct pci_dev *pdev){	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);	release_mem_region(virt_to_gart(bridge->gatt_table_real),			   amd64_aperture_sizes[bridge->aperture_size_idx].size);	agp_remove_bridge(bridge);	agp_put_bridge(bridge);}static struct pci_device_id agp_amd64_pci_table[] = {	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_AMD,	.device		= PCI_DEVICE_ID_AMD_8151_0,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* ULi M1689 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_AL,	.device		= PCI_DEVICE_ID_AL_M1689,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* VIA K8T800Pro */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_VIA,	.device		= PCI_DEVICE_ID_VIA_K8T800PRO_0,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* VIA K8T800 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_VIA,	.device		= PCI_DEVICE_ID_VIA_8385_0,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* VIA K8M800 / K8N800 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_VIA,	.device		= PCI_DEVICE_ID_VIA_8380_0,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* VIA K8T890 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_VIA,	.device		= PCI_DEVICE_ID_VIA_3238_0,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* VIA K8T800/K8M800/K8N800 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_VIA,	.device		= PCI_DEVICE_ID_VIA_838X_1,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* NForce3 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_NVIDIA,	.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_NVIDIA,	.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3S,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* SIS 755 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_SI,	.device		= PCI_DEVICE_ID_SI_755,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	/* SIS 760 */	{	.class		= (PCI_CLASS_BRIDGE_HOST << 8),	.class_mask	= ~0,	.vendor		= PCI_VENDOR_ID_SI,	.device		= PCI_DEVICE_ID_SI_760,	.subvendor	= PCI_ANY_ID,	.subdevice	= PCI_ANY_ID,	},	{ }};MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);static struct pci_driver agp_amd64_pci_driver = {	.name		= "agpgart-amd64",	.id_table	= agp_amd64_pci_table,	.probe		= agp_amd64_probe,	.remove		= agp_amd64_remove,};/* Not static due to IOMMU code calling it early. */int __init agp_amd64_init(void){	int err = 0;	static struct pci_device_id amd64nb[] = {		{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },		{ },	};	if (agp_off)		return -EINVAL;	if (pci_register_driver(&agp_amd64_pci_driver) > 0) {		struct pci_dev *dev;		if (!agp_try_unsupported && !agp_try_unsupported_boot) {			printk(KERN_INFO PFX "No supported AGP bridge found.\n");#ifdef MODULE			printk(KERN_INFO PFX "You can try agp_try_unsupported=1\n");#else			printk(KERN_INFO PFX "You can boot with agp=try_unsupported\n");#endif			return -ENODEV;		}		/* First check that we have at least one AMD64 NB */		if (!pci_dev_present(amd64nb))			return -ENODEV;		/* Look for any AGP bridge */		dev = NULL;		err = -ENODEV;		for_each_pci_dev(dev) {			if (!pci_find_capability(dev, PCI_CAP_ID_AGP))				continue;			/* Only one bridge supported right now */			if (agp_amd64_probe(dev, NULL) == 0) {				err = 0;				break;			}		}	}	return err;}static void __exit agp_amd64_cleanup(void){	if (aperture_resource)		release_resource(aperture_resource);	pci_unregister_driver(&agp_amd64_pci_driver);}/* On AMD64 the PCI driver needs to initialize this driver early   for the IOMMU, so it has to be called via a backdoor. */#ifndef CONFIG_GART_IOMMUmodule_init(agp_amd64_init);module_exit(agp_amd64_cleanup);#endifMODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen");module_param(agp_try_unsupported, bool, 0);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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