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

📄 nettel.c

📁 基于linux-2.6.28的mtd驱动
💻 C
字号:
/****************************************************************************//* *      nettel.c -- mappings for NETtel/SecureEdge/SnapGear (x86) boards. * *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com) *//****************************************************************************/#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/mtd/mtd.h>#include <linux/mtd/map.h>#include <linux/mtd/partitions.h>#include <linux/mtd/cfi.h>#include <linux/reboot.h>#include <linux/err.h>#include <linux/kdev_t.h>#include <linux/root_dev.h>#include <asm/io.h>/****************************************************************************/#define INTEL_BUSWIDTH		1#define AMD_WINDOW_MAXSIZE	0x00200000#define AMD_BUSWIDTH	 	1/* *	PAR masks and shifts, assuming 64K pages. */#define SC520_PAR_ADDR_MASK	0x00003fff#define SC520_PAR_ADDR_SHIFT	16#define SC520_PAR_TO_ADDR(par) \	(((par)&SC520_PAR_ADDR_MASK) << SC520_PAR_ADDR_SHIFT)#define SC520_PAR_SIZE_MASK	0x01ffc000#define SC520_PAR_SIZE_SHIFT	2#define SC520_PAR_TO_SIZE(par) \	((((par)&SC520_PAR_SIZE_MASK) << SC520_PAR_SIZE_SHIFT) + (64*1024))#define SC520_PAR(cs, addr, size) \	((cs) | \	((((size)-(64*1024)) >> SC520_PAR_SIZE_SHIFT) & SC520_PAR_SIZE_MASK) | \	(((addr) >> SC520_PAR_ADDR_SHIFT) & SC520_PAR_ADDR_MASK))#define SC520_PAR_BOOTCS	0x8a000000#define	SC520_PAR_ROMCS1	0xaa000000#define SC520_PAR_ROMCS2	0xca000000	/* Cache disabled, 64K page */static void *nettel_mmcrp = NULL;#ifdef CONFIG_MTD_CFI_INTELEXTstatic struct mtd_info *intel_mtd;#endifstatic struct mtd_info *amd_mtd;/****************************************************************************//****************************************************************************/#ifdef CONFIG_MTD_CFI_INTELEXTstatic struct map_info nettel_intel_map = {	.name = "SnapGear Intel",	.size = 0,	.bankwidth = INTEL_BUSWIDTH,};static struct mtd_partition nettel_intel_partitions[] = {	{		.name = "SnapGear kernel",		.offset = 0,		.size = 0x000e0000	},	{		.name = "SnapGear filesystem",		.offset = 0x00100000,	},	{		.name = "SnapGear config",		.offset = 0x000e0000,		.size = 0x00020000	},	{		.name = "SnapGear Intel",		.offset = 0	},	{		.name = "SnapGear BIOS Config",		.offset = 0x007e0000,		.size = 0x00020000	},	{		.name = "SnapGear BIOS",		.offset = 0x007e0000,		.size = 0x00020000	},};#endifstatic struct map_info nettel_amd_map = {	.name = "SnapGear AMD",	.size = AMD_WINDOW_MAXSIZE,	.bankwidth = AMD_BUSWIDTH,};static struct mtd_partition nettel_amd_partitions[] = {	{		.name = "SnapGear BIOS config",		.offset = 0x000e0000,		.size = 0x00010000	},	{		.name = "SnapGear BIOS",		.offset = 0x000f0000,		.size = 0x00010000	},	{		.name = "SnapGear AMD",		.offset = 0	},	{		.name = "SnapGear high BIOS",		.offset = 0x001f0000,		.size = 0x00010000	}};#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)/****************************************************************************/#ifdef CONFIG_MTD_CFI_INTELEXT/* *	Set the Intel flash back to read mode since some old boot *	loaders don't. */static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v){	struct cfi_private *cfi = nettel_intel_map.fldrv_priv;	unsigned long b;	/* Make sure all FLASH chips are put back into read mode */	for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {		cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,			cfi->device_type, NULL);	}	return(NOTIFY_OK);}static struct notifier_block nettel_notifier_block = {	nettel_reboot_notifier, NULL, 0};#endif/****************************************************************************/static int __init nettel_init(void){	volatile unsigned long *amdpar;	unsigned long amdaddr, maxsize;	int num_amd_partitions=0;#ifdef CONFIG_MTD_CFI_INTELEXT	volatile unsigned long *intel0par, *intel1par;	unsigned long orig_bootcspar, orig_romcs1par;	unsigned long intel0addr, intel0size;	unsigned long intel1addr, intel1size;	int intelboot, intel0cs, intel1cs;	int num_intel_partitions;#endif	int rc = 0;	nettel_mmcrp = (void *) ioremap_nocache(0xfffef000, 4096);	if (nettel_mmcrp == NULL) {		printk("SNAPGEAR: failed to disable MMCR cache??\n");		return(-EIO);	}	/* Set CPU clock to be 33.000MHz */	*((unsigned char *) (nettel_mmcrp + 0xc64)) = 0x01;	amdpar = (volatile unsigned long *) (nettel_mmcrp + 0xc4);#ifdef CONFIG_MTD_CFI_INTELEXT	intelboot = 0;	intel0cs = SC520_PAR_ROMCS1;	intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc0);	intel1cs = SC520_PAR_ROMCS2;	intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xbc);	/*	 *	Save the CS settings then ensure ROMCS1 and ROMCS2 are off,	 *	otherwise they might clash with where we try to map BOOTCS.	 */	orig_bootcspar = *amdpar;	orig_romcs1par = *intel0par;	*intel0par = 0;	*intel1par = 0;#endif	/*	 *	The first thing to do is determine if we have a separate	 *	boot FLASH device. Typically this is a small (1 to 2MB)	 *	AMD FLASH part. It seems that device size is about the	 *	only way to tell if this is the case...	 */	amdaddr = 0x20000000;	maxsize = AMD_WINDOW_MAXSIZE;	*amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize);	__asm__ ("wbinvd");	nettel_amd_map.phys = amdaddr;	nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize);	if (!nettel_amd_map.virt) {		printk("SNAPGEAR: failed to ioremap() BOOTCS\n");		iounmap(nettel_mmcrp);		return(-EIO);	}	simple_map_init(&nettel_amd_map);	if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {		printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",			amd_mtd->size>>10);		amd_mtd->owner = THIS_MODULE;		/* The high BIOS partition is only present for 2MB units */		num_amd_partitions = NUM_AMD_PARTITIONS;		if (amd_mtd->size < AMD_WINDOW_MAXSIZE)			num_amd_partitions--;		/* Don't add the partition until after the primary INTEL's */#ifdef CONFIG_MTD_CFI_INTELEXT		/*		 *	Map the Intel flash into memory after the AMD		 *	It has to start on a multiple of maxsize.		 */		maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);		if (maxsize < (32 * 1024 * 1024))			maxsize = (32 * 1024 * 1024);		intel0addr = amdaddr + maxsize;#endif	} else {#ifdef CONFIG_MTD_CFI_INTELEXT		/* INTEL boot FLASH */		intelboot++;		if (!orig_romcs1par) {			intel0cs = SC520_PAR_BOOTCS;			intel0par = (volatile unsigned long *)				(nettel_mmcrp + 0xc4);			intel1cs = SC520_PAR_ROMCS1;			intel1par = (volatile unsigned long *)				(nettel_mmcrp + 0xc0);			intel0addr = SC520_PAR_TO_ADDR(orig_bootcspar);			maxsize = SC520_PAR_TO_SIZE(orig_bootcspar);		} else {			/* Kernel base is on ROMCS1, not BOOTCS */			intel0cs = SC520_PAR_ROMCS1;			intel0par = (volatile unsigned long *)				(nettel_mmcrp + 0xc0);			intel1cs = SC520_PAR_BOOTCS;			intel1par = (volatile unsigned long *)				(nettel_mmcrp + 0xc4);			intel0addr = SC520_PAR_TO_ADDR(orig_romcs1par);			maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);		}		/* Destroy useless AMD MTD mapping */		amd_mtd = NULL;		iounmap(nettel_amd_map.virt);		nettel_amd_map.virt = NULL;#else		/* Only AMD flash supported */		rc = -ENXIO;		goto out_unmap2;#endif	}#ifdef CONFIG_MTD_CFI_INTELEXT	/*	 *	We have determined the INTEL FLASH configuration, so lets	 *	go ahead and probe for them now.	 */	/* Set PAR to the maximum size */	if (maxsize < (32 * 1024 * 1024))		maxsize = (32 * 1024 * 1024);	*intel0par = SC520_PAR(intel0cs, intel0addr, maxsize);	/* Turn other PAR off so the first probe doesn't find it */	*intel1par = 0;	/* Probe for the size of the first Intel flash */	nettel_intel_map.size = maxsize;	nettel_intel_map.phys = intel0addr;	nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);	if (!nettel_intel_map.virt) {		printk("SNAPGEAR: failed to ioremap() ROMCS1\n");		rc = -EIO;		goto out_unmap2;	}	simple_map_init(&nettel_intel_map);	intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);	if (!intel_mtd) {		rc = -ENXIO;		goto out_unmap1;	}	/* Set PAR to the detected size */	intel0size = intel_mtd->size;	*intel0par = SC520_PAR(intel0cs, intel0addr, intel0size);	/*	 *	Map second Intel FLASH right after first. Set its size to the	 *	same maxsize used for the first Intel FLASH.	 */	intel1addr = intel0addr + intel0size;	*intel1par = SC520_PAR(intel1cs, intel1addr, maxsize);	__asm__ ("wbinvd");	maxsize += intel0size;	/* Delete the old map and probe again to do both chips */	map_destroy(intel_mtd);	intel_mtd = NULL;	iounmap(nettel_intel_map.virt);	nettel_intel_map.size = maxsize;	nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);	if (!nettel_intel_map.virt) {		printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");		rc = -EIO;		goto out_unmap2;	}	intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);	if (! intel_mtd) {		rc = -ENXIO;		goto out_unmap1;	}	intel1size = intel_mtd->size - intel0size;	if (intel1size > 0) {		*intel1par = SC520_PAR(intel1cs, intel1addr, intel1size);		__asm__ ("wbinvd");	} else {		*intel1par = 0;	}	printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n",		(intel_mtd->size >> 10));	intel_mtd->owner = THIS_MODULE;	num_intel_partitions = sizeof(nettel_intel_partitions) /		sizeof(nettel_intel_partitions[0]);	if (intelboot) {		/*		 *	Adjust offset and size of last boot partition.		 *	Must allow for BIOS region at end of FLASH.		 */		nettel_intel_partitions[1].size = (intel0size + intel1size) -			(1024*1024 + intel_mtd->erasesize);		nettel_intel_partitions[3].size = intel0size + intel1size;		nettel_intel_partitions[4].offset =			(intel0size + intel1size) - intel_mtd->erasesize;		nettel_intel_partitions[4].size = intel_mtd->erasesize;		nettel_intel_partitions[5].offset =			nettel_intel_partitions[4].offset;		nettel_intel_partitions[5].size =			nettel_intel_partitions[4].size;	} else {		/* No BIOS regions when AMD boot */		num_intel_partitions -= 2;	}	rc = add_mtd_partitions(intel_mtd, nettel_intel_partitions,		num_intel_partitions);#endif	if (amd_mtd) {		rc = add_mtd_partitions(amd_mtd, nettel_amd_partitions,			num_amd_partitions);	}#ifdef CONFIG_MTD_CFI_INTELEXT	register_reboot_notifier(&nettel_notifier_block);#endif	return(rc);#ifdef CONFIG_MTD_CFI_INTELEXTout_unmap1:	iounmap(nettel_intel_map.virt);#endifout_unmap2:	iounmap(nettel_mmcrp);	iounmap(nettel_amd_map.virt);	return(rc);}/****************************************************************************/static void __exit nettel_cleanup(void){#ifdef CONFIG_MTD_CFI_INTELEXT	unregister_reboot_notifier(&nettel_notifier_block);#endif	if (amd_mtd) {		del_mtd_partitions(amd_mtd);		map_destroy(amd_mtd);	}	if (nettel_mmcrp) {		iounmap(nettel_mmcrp);		nettel_mmcrp = NULL;	}	if (nettel_amd_map.virt) {		iounmap(nettel_amd_map.virt);		nettel_amd_map.virt = NULL;	}#ifdef CONFIG_MTD_CFI_INTELEXT	if (intel_mtd) {		del_mtd_partitions(intel_mtd);		map_destroy(intel_mtd);	}	if (nettel_intel_map.virt) {		iounmap(nettel_intel_map.virt);		nettel_intel_map.virt = NULL;	}#endif}/****************************************************************************/module_init(nettel_init);module_exit(nettel_cleanup);MODULE_LICENSE("GPL");MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support");/****************************************************************************/

⌨️ 快捷键说明

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