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

📄 mtrr.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 3 页
字号:
		base >>= PAGE_SHIFT;		size >>= PAGE_SHIFT;	}	reg = mtrr_add_page (base, size, type, 1);	if (reg >= 0)		++fcount[reg];	return reg;}static int mtrr_file_del (u64 base, u32 size,		struct file *file, int page){	int reg;	unsigned int *fcount = file->private_data;	if (!page) {		if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {			printk			    (KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");			printk (KERN_INFO "mtrr: size: 0x%x  base: 0x%Lx\n", size, base);			return -EINVAL;		}		base >>= PAGE_SHIFT;		size >>= PAGE_SHIFT;	}	reg = mtrr_del_page (-1, base, size);	if (reg < 0)		return reg;	if (fcount == NULL)		return reg;	if (fcount[reg] < 1)		return -EINVAL;	--fcount[reg];	return reg;}static ssize_t mtrr_read (struct file *file, char *buf, size_t len,		loff_t * ppos){	if (*ppos >= ascii_buf_bytes)		return 0;	if (*ppos + len > ascii_buf_bytes)		len = ascii_buf_bytes - *ppos;	if (copy_to_user (buf, ascii_buffer + *ppos, len))		return -EFAULT;	*ppos += len;	return len;}static ssize_t mtrr_write (struct file *file, const char *buf,		size_t len, loff_t * ppos)/*  Format of control line:    "base=%Lx size=%Lx type=%s"     OR:    "disable=%d"*/{	int i, err, reg;	u64 base;	u32 size;	char *ptr;	char line[LINE_SIZE];	if (!capable(CAP_SYS_ADMIN))		return -EPERM;	/*  Can't seek (pwrite) on this device  */	if (ppos != &file->f_pos)		return -ESPIPE;	memset (line, 0, LINE_SIZE);	if (len > LINE_SIZE)		len = LINE_SIZE;	if (copy_from_user (line, buf, len - 1))		return -EFAULT;	ptr = line + strlen (line) - 1;	if (*ptr == '\n')		*ptr = '\0';	if (!strncmp (line, "disable=", 8)) {		reg = simple_strtoul (line + 8, &ptr, 0);		err = mtrr_del_page (reg, 0, 0);		if (err < 0)			return err;		return len;	}	if (strncmp (line, "base=", 5)) {		printk (KERN_INFO "mtrr: no \"base=\" in line: \"%s\"\n", line);		return -EINVAL;	}	base = simple_strtoull (line + 5, &ptr, 0);	for (; isspace (*ptr); ++ptr) ;	if (strncmp (ptr, "size=", 5)) {		printk (KERN_INFO "mtrr: no \"size=\" in line: \"%s\"\n", line);		return -EINVAL;	}	size = simple_strtoull (ptr + 5, &ptr, 0);	if ((base & 0xfff) || (size & 0xfff)) {		printk (KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");		printk (KERN_INFO "mtrr: size: 0x%x  base: 0x%Lx\n", size, base);		return -EINVAL;	}	for (; isspace (*ptr); ++ptr) ;	if (strncmp (ptr, "type=", 5)) {		printk (KERN_INFO "mtrr: no \"type=\" in line: \"%s\"\n", line);		return -EINVAL;	}	ptr += 5;	for (; isspace (*ptr); ++ptr) ;	for (i = 0; i < MTRR_NUM_TYPES; ++i) {		if (strcmp (ptr, mtrr_strings[i]))			continue;		base >>= PAGE_SHIFT;		size >>= PAGE_SHIFT;		err = mtrr_add_page ((u64) base, size, i, 1);		if (err < 0)			return err;		return len;	}	printk (KERN_INFO "mtrr: illegal type: \"%s\"\n", ptr);	return -EINVAL;}static int mtrr_ioctl (struct inode *inode, struct file *file,		unsigned int cmd, unsigned long arg){	int err;	mtrr_type type;	struct mtrr_sentry sentry;	struct mtrr_gentry gentry;	switch (cmd) {	default:		return -ENOIOCTLCMD;	case MTRRIOC_ADD_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_file_add (sentry.base, sentry.size, sentry.type,				   file, 0);		if (err < 0)			return err;		break;	case MTRRIOC_SET_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_add (sentry.base, sentry.size, sentry.type, 0);		if (err < 0)			return err;		break;	case MTRRIOC_DEL_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_file_del (sentry.base, sentry.size, file, 0);		if (err < 0)			return err;		break;	case MTRRIOC_KILL_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_del (-1, sentry.base, sentry.size);		if (err < 0)			return err;		break;	case MTRRIOC_GET_ENTRY:		if (copy_from_user (&gentry, (void *) arg, sizeof gentry))			return -EFAULT;		if (gentry.regnum >= get_num_var_ranges ())			return -EINVAL;		get_mtrr (gentry.regnum, (u64*) &gentry.base, &gentry.size, &type);		/* Hide entries that go above 4GB */		if (gentry.base + gentry.size > 0x100000		    || gentry.size == 0x100000)			gentry.base = gentry.size = gentry.type = 0;		else {			gentry.base <<= PAGE_SHIFT;			gentry.size <<= PAGE_SHIFT;			gentry.type = type;		}		if (copy_to_user ((void *) arg, &gentry, sizeof gentry))			return -EFAULT;		break;	case MTRRIOC_ADD_PAGE_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_file_add (sentry.base, sentry.size, sentry.type, file, 1);		if (err < 0)			return err;		break;	case MTRRIOC_SET_PAGE_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_add_page (sentry.base, sentry.size, sentry.type, 0);		if (err < 0)			return err;		break;	case MTRRIOC_DEL_PAGE_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_file_del (sentry.base, sentry.size, file, 1);		if (err < 0)			return err;		break;	case MTRRIOC_KILL_PAGE_ENTRY:		if (!capable(CAP_SYS_ADMIN))			return -EPERM;		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))			return -EFAULT;		err = mtrr_del_page (-1, sentry.base, sentry.size);		if (err < 0)			return err;		break;	case MTRRIOC_GET_PAGE_ENTRY:		if (copy_from_user (&gentry, (void *) arg, sizeof gentry))			return -EFAULT;		if (gentry.regnum >= get_num_var_ranges ())			return -EINVAL;		get_mtrr (gentry.regnum, (u64*) &gentry.base, &gentry.size, &type);		gentry.type = type;		if (copy_to_user ((void *) arg, &gentry, sizeof gentry))			return -EFAULT;		break;	}	return 0;}static int mtrr_close (struct inode *ino, struct file *file){	int i, max;	unsigned int *fcount = file->private_data;	if (fcount == NULL)		return 0;	lock_kernel ();	max = get_num_var_ranges ();	for (i = 0; i < max; ++i) {		while (fcount[i] > 0) {			if (mtrr_del (i, 0, 0) < 0)				printk ("mtrr: reg %d not used\n", i);			--fcount[i];		}	}	unlock_kernel ();	kfree (fcount);	file->private_data = NULL;	return 0;}static struct file_operations mtrr_fops = {	owner:	THIS_MODULE,	read:	mtrr_read,	write:	mtrr_write,	ioctl:	mtrr_ioctl,	release:mtrr_close,};#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry *proc_root_mtrr;#endifstatic devfs_handle_t devfs_handle;static void compute_ascii (void){	char factor;	int i, max;	mtrr_type type;	u64 base;	u32 size;	ascii_buf_bytes = 0;	max = get_num_var_ranges ();	for (i = 0; i < max; i++) {		get_mtrr (i, &base, &size, &type);		if (size == 0)			usage_table[i] = 0;		else {			if (size < (0x100000 >> PAGE_SHIFT)) {				/* less than 1MB */				factor = 'K';				size <<= PAGE_SHIFT - 10;			} else {				factor = 'M';				size >>= 20 - PAGE_SHIFT;			}			sprintf (ascii_buffer + ascii_buf_bytes,				"reg%02i: base=0x%05Lx000 (%4iMB), size=%4i%cB: %s, count=%d\n",				i, base, (u32) base >> (20 - PAGE_SHIFT), size, factor,				attrib_to_str (type), usage_table[i]);			ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);		}	}	devfs_set_file_size (devfs_handle, ascii_buf_bytes);#ifdef CONFIG_PROC_FS	if (proc_root_mtrr)		proc_root_mtrr->size = ascii_buf_bytes;#endif}#endif	/*  USERSPACE_INTERFACE  */EXPORT_SYMBOL (mtrr_add);EXPORT_SYMBOL (mtrr_del);static void __init mtrr_setup (void){	printk ("mtrr: v%s)\n", MTRR_VERSION);	if (test_bit (X86_FEATURE_MTRR, boot_cpu_data.x86_capability)) {		/* Query the width (in bits) of the physical		   addressable memory on the Hammer family. */		if ((cpuid_eax (0x80000000) >= 0x80000008)) {			u32 phys_addr;			phys_addr = cpuid_eax (0x80000008) & 0xff;			size_or_mask = ~((1L << phys_addr) - 1);			/*			 * top bits MBZ as its beyond the addressable range.			 * bottom bits MBZ as we don't care about lower 12 bits of addr.			 */			size_and_mask = (~size_or_mask) & 0x000ffffffffff000L;		}	}}#ifdef CONFIG_SMPstatic volatile u32 smp_changes_mask __initdata = 0;static struct mtrr_state smp_mtrr_state __initdata = { 0, 0 };void __init mtrr_init_boot_cpu (void){	mtrr_setup();	get_mtrr_state (&smp_mtrr_state);}void __init mtrr_init_secondary_cpu (void){	u64 mask;	int count;	struct set_mtrr_context ctxt;	/* Note that this is not ideal, since the cache is only flushed/disabled	   for this CPU while the MTRRs are changed, but changing this requires	   more invasive changes to the way the kernel boots  */	set_mtrr_prepare (&ctxt);	mask = set_mtrr_state (&smp_mtrr_state, &ctxt);	set_mtrr_done (&ctxt);	/*  Use the atomic bitops to update the global mask  */	for (count = 0; count < sizeof mask * 8; ++count) {		if (mask & 0x01)			set_bit (count, &smp_changes_mask);		mask >>= 1;	}}#endif	/*  CONFIG_SMP  */int __init mtrr_init (void){#ifdef CONFIG_SMP	/* mtrr_setup() should already have been called from mtrr_init_boot_cpu() */	finalize_mtrr_state (&smp_mtrr_state);	mtrr_state_warn (smp_changes_mask);#else	mtrr_setup();#endif#ifdef CONFIG_PROC_FS	proc_root_mtrr = create_proc_entry ("mtrr", S_IWUSR | S_IRUGO, &proc_root);	if (proc_root_mtrr) {		proc_root_mtrr->owner = THIS_MODULE;		proc_root_mtrr->proc_fops = &mtrr_fops;	}#endif#ifdef CONFIG_DEVFS_FS	devfs_handle = devfs_register (NULL, "cpu/mtrr", DEVFS_FL_DEFAULT, 0, 0,				S_IFREG | S_IRUGO | S_IWUSR,				&mtrr_fops, NULL);#endif	init_table ();	return 0;}

⌨️ 快捷键说明

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