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

📄 esi.c

📁 linux 内核源代码
💻 C
字号:
/* * Extensible SAL Interface (ESI) support routines. * * Copyright (C) 2006 Hewlett-Packard Co * 	Alex Williamson <alex.williamson@hp.com> */#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/string.h>#include <asm/esi.h>#include <asm/sal.h>MODULE_AUTHOR("Alex Williamson <alex.williamson@hp.com>");MODULE_DESCRIPTION("Extensible SAL Interface (ESI) support");MODULE_LICENSE("GPL");#define MODULE_NAME	"esi"#define ESI_TABLE_GUID					\    EFI_GUID(0x43EA58DC, 0xCF28, 0x4b06, 0xB3,		\	     0x91, 0xB7, 0x50, 0x59, 0x34, 0x2B, 0xD4)enum esi_systab_entry_type {	ESI_DESC_ENTRY_POINT = 0};/* * Entry type:	Size: *	0	48 */#define ESI_DESC_SIZE(type)	"\060"[(unsigned) (type)]typedef struct ia64_esi_desc_entry_point {	u8 type;	u8 reserved1[15];	u64 esi_proc;	u64 gp;	efi_guid_t guid;} ia64_esi_desc_entry_point_t;struct pdesc {	void *addr;	void *gp;};static struct ia64_sal_systab *esi_systab;static int __init esi_init (void){	efi_config_table_t *config_tables;	struct ia64_sal_systab *systab;	unsigned long esi = 0;	char *p;	int i;	config_tables = __va(efi.systab->tables);	for (i = 0; i < (int) efi.systab->nr_tables; ++i) {		if (efi_guidcmp(config_tables[i].guid, ESI_TABLE_GUID) == 0) {			esi = config_tables[i].table;			break;		}	}	if (!esi)		return -ENODEV;;	systab = __va(esi);	if (strncmp(systab->signature, "ESIT", 4) != 0) {		printk(KERN_ERR "bad signature in ESI system table!");		return -ENODEV;	}	p = (char *) (systab + 1);	for (i = 0; i < systab->entry_count; i++) {		/*		 * The first byte of each entry type contains the type		 * descriptor.		 */		switch (*p) {		      case ESI_DESC_ENTRY_POINT:			break;		      default:			printk(KERN_WARNING "Unkown table type %d found in "			       "ESI table, ignoring rest of table\n", *p);			return -ENODEV;		}		p += ESI_DESC_SIZE(*p);	}	esi_systab = systab;	return 0;}int ia64_esi_call (efi_guid_t guid, struct ia64_sal_retval *isrvp,		   enum esi_proc_type proc_type, u64 func,		   u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,		   u64 arg7){	struct ia64_fpreg fr[6];	unsigned long flags = 0;	int i;	char *p;	if (!esi_systab)		return -1;	p = (char *) (esi_systab + 1);	for (i = 0; i < esi_systab->entry_count; i++) {		if (*p == ESI_DESC_ENTRY_POINT) {			ia64_esi_desc_entry_point_t *esi = (void *)p;			if (!efi_guidcmp(guid, esi->guid)) {				ia64_sal_handler esi_proc;				struct pdesc pdesc;				pdesc.addr = __va(esi->esi_proc);				pdesc.gp = __va(esi->gp);				esi_proc = (ia64_sal_handler) &pdesc;				ia64_save_scratch_fpregs(fr);				if (proc_type == ESI_PROC_SERIALIZED)					spin_lock_irqsave(&sal_lock, flags);				else if (proc_type == ESI_PROC_MP_SAFE)					local_irq_save(flags);				else					preempt_disable();				*isrvp = (*esi_proc)(func, arg1, arg2, arg3,						     arg4, arg5, arg6, arg7);				if (proc_type == ESI_PROC_SERIALIZED)					spin_unlock_irqrestore(&sal_lock,							       flags);				else if (proc_type == ESI_PROC_MP_SAFE)					local_irq_restore(flags);				else					preempt_enable();				ia64_load_scratch_fpregs(fr);				return 0;			}		}		p += ESI_DESC_SIZE(*p);	}	return -1;}EXPORT_SYMBOL_GPL(ia64_esi_call);int ia64_esi_call_phys (efi_guid_t guid, struct ia64_sal_retval *isrvp,			u64 func, u64 arg1, u64 arg2, u64 arg3, u64 arg4,			u64 arg5, u64 arg6, u64 arg7){	struct ia64_fpreg fr[6];	unsigned long flags;	u64 esi_params[8];	char *p;	int i;	if (!esi_systab)		return -1;	p = (char *) (esi_systab + 1);	for (i = 0; i < esi_systab->entry_count; i++) {		if (*p == ESI_DESC_ENTRY_POINT) {			ia64_esi_desc_entry_point_t *esi = (void *)p;			if (!efi_guidcmp(guid, esi->guid)) {				ia64_sal_handler esi_proc;				struct pdesc pdesc;				pdesc.addr = (void *)esi->esi_proc;				pdesc.gp = (void *)esi->gp;				esi_proc = (ia64_sal_handler) &pdesc;				esi_params[0] = func;				esi_params[1] = arg1;				esi_params[2] = arg2;				esi_params[3] = arg3;				esi_params[4] = arg4;				esi_params[5] = arg5;				esi_params[6] = arg6;				esi_params[7] = arg7;				ia64_save_scratch_fpregs(fr);				spin_lock_irqsave(&sal_lock, flags);				*isrvp = esi_call_phys(esi_proc, esi_params);				spin_unlock_irqrestore(&sal_lock, flags);				ia64_load_scratch_fpregs(fr);				return 0;			}		}		p += ESI_DESC_SIZE(*p);	}	return -1;}EXPORT_SYMBOL_GPL(ia64_esi_call_phys);static void __exit esi_exit (void){}module_init(esi_init);module_exit(esi_exit);	/* makes module removable... */

⌨️ 快捷键说明

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