~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/ia64/kernel/esi.c

Version: ~ [ linux-4.14 ] ~ [ linux-4.13.12 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.61 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.97 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.46 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.80 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.50 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.95 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.27.62 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Extensible SAL Interface (ESI) support routines.
  3  *
  4  * Copyright (C) 2006 Hewlett-Packard Co
  5  *      Alex Williamson <alex.williamson@hp.com>
  6  */
  7 #include <linux/kernel.h>
  8 #include <linux/init.h>
  9 #include <linux/module.h>
 10 #include <linux/string.h>
 11 
 12 #include <asm/esi.h>
 13 #include <asm/sal.h>
 14 
 15 MODULE_AUTHOR("Alex Williamson <alex.williamson@hp.com>");
 16 MODULE_DESCRIPTION("Extensible SAL Interface (ESI) support");
 17 MODULE_LICENSE("GPL");
 18 
 19 #define MODULE_NAME     "esi"
 20 
 21 #define ESI_TABLE_GUID                                  \
 22     EFI_GUID(0x43EA58DC, 0xCF28, 0x4b06, 0xB3,          \
 23              0x91, 0xB7, 0x50, 0x59, 0x34, 0x2B, 0xD4)
 24 
 25 enum esi_systab_entry_type {
 26         ESI_DESC_ENTRY_POINT = 0
 27 };
 28 
 29 /*
 30  * Entry type:  Size:
 31  *      0       48
 32  */
 33 #define ESI_DESC_SIZE(type)     "\060"[(unsigned) (type)]
 34 
 35 typedef struct ia64_esi_desc_entry_point {
 36         u8 type;
 37         u8 reserved1[15];
 38         u64 esi_proc;
 39         u64 gp;
 40         efi_guid_t guid;
 41 } ia64_esi_desc_entry_point_t;
 42 
 43 struct pdesc {
 44         void *addr;
 45         void *gp;
 46 };
 47 
 48 static struct ia64_sal_systab *esi_systab;
 49 
 50 static int __init esi_init (void)
 51 {
 52         efi_config_table_t *config_tables;
 53         struct ia64_sal_systab *systab;
 54         unsigned long esi = 0;
 55         char *p;
 56         int i;
 57 
 58         config_tables = __va(efi.systab->tables);
 59 
 60         for (i = 0; i < (int) efi.systab->nr_tables; ++i) {
 61                 if (efi_guidcmp(config_tables[i].guid, ESI_TABLE_GUID) == 0) {
 62                         esi = config_tables[i].table;
 63                         break;
 64                 }
 65         }
 66 
 67         if (!esi)
 68                 return -ENODEV;
 69 
 70         systab = __va(esi);
 71 
 72         if (strncmp(systab->signature, "ESIT", 4) != 0) {
 73                 printk(KERN_ERR "bad signature in ESI system table!");
 74                 return -ENODEV;
 75         }
 76 
 77         p = (char *) (systab + 1);
 78         for (i = 0; i < systab->entry_count; i++) {
 79                 /*
 80                  * The first byte of each entry type contains the type
 81                  * descriptor.
 82                  */
 83                 switch (*p) {
 84                       case ESI_DESC_ENTRY_POINT:
 85                         break;
 86                       default:
 87                         printk(KERN_WARNING "Unknown table type %d found in "
 88                                "ESI table, ignoring rest of table\n", *p);
 89                         return -ENODEV;
 90                 }
 91 
 92                 p += ESI_DESC_SIZE(*p);
 93         }
 94 
 95         esi_systab = systab;
 96         return 0;
 97 }
 98 
 99 
100 int ia64_esi_call (efi_guid_t guid, struct ia64_sal_retval *isrvp,
101                    enum esi_proc_type proc_type, u64 func,
102                    u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
103                    u64 arg7)
104 {
105         struct ia64_fpreg fr[6];
106         unsigned long flags = 0;
107         int i;
108         char *p;
109 
110         if (!esi_systab)
111                 return -1;
112 
113         p = (char *) (esi_systab + 1);
114         for (i = 0; i < esi_systab->entry_count; i++) {
115                 if (*p == ESI_DESC_ENTRY_POINT) {
116                         ia64_esi_desc_entry_point_t *esi = (void *)p;
117                         if (!efi_guidcmp(guid, esi->guid)) {
118                                 ia64_sal_handler esi_proc;
119                                 struct pdesc pdesc;
120 
121                                 pdesc.addr = __va(esi->esi_proc);
122                                 pdesc.gp = __va(esi->gp);
123 
124                                 esi_proc = (ia64_sal_handler) &pdesc;
125 
126                                 ia64_save_scratch_fpregs(fr);
127                                 if (proc_type == ESI_PROC_SERIALIZED)
128                                         spin_lock_irqsave(&sal_lock, flags);
129                                 else if (proc_type == ESI_PROC_MP_SAFE)
130                                         local_irq_save(flags);
131                                 else
132                                         preempt_disable();
133                                 *isrvp = (*esi_proc)(func, arg1, arg2, arg3,
134                                                      arg4, arg5, arg6, arg7);
135                                 if (proc_type == ESI_PROC_SERIALIZED)
136                                         spin_unlock_irqrestore(&sal_lock,
137                                                                flags);
138                                 else if (proc_type == ESI_PROC_MP_SAFE)
139                                         local_irq_restore(flags);
140                                 else
141                                         preempt_enable();
142                                 ia64_load_scratch_fpregs(fr);
143                                 return 0;
144                         }
145                 }
146                 p += ESI_DESC_SIZE(*p);
147         }
148         return -1;
149 }
150 EXPORT_SYMBOL_GPL(ia64_esi_call);
151 
152 int ia64_esi_call_phys (efi_guid_t guid, struct ia64_sal_retval *isrvp,
153                         u64 func, u64 arg1, u64 arg2, u64 arg3, u64 arg4,
154                         u64 arg5, u64 arg6, u64 arg7)
155 {
156         struct ia64_fpreg fr[6];
157         unsigned long flags;
158         u64 esi_params[8];
159         char *p;
160         int i;
161 
162         if (!esi_systab)
163                 return -1;
164 
165         p = (char *) (esi_systab + 1);
166         for (i = 0; i < esi_systab->entry_count; i++) {
167                 if (*p == ESI_DESC_ENTRY_POINT) {
168                         ia64_esi_desc_entry_point_t *esi = (void *)p;
169                         if (!efi_guidcmp(guid, esi->guid)) {
170                                 ia64_sal_handler esi_proc;
171                                 struct pdesc pdesc;
172 
173                                 pdesc.addr = (void *)esi->esi_proc;
174                                 pdesc.gp = (void *)esi->gp;
175 
176                                 esi_proc = (ia64_sal_handler) &pdesc;
177 
178                                 esi_params[0] = func;
179                                 esi_params[1] = arg1;
180                                 esi_params[2] = arg2;
181                                 esi_params[3] = arg3;
182                                 esi_params[4] = arg4;
183                                 esi_params[5] = arg5;
184                                 esi_params[6] = arg6;
185                                 esi_params[7] = arg7;
186                                 ia64_save_scratch_fpregs(fr);
187                                 spin_lock_irqsave(&sal_lock, flags);
188                                 *isrvp = esi_call_phys(esi_proc, esi_params);
189                                 spin_unlock_irqrestore(&sal_lock, flags);
190                                 ia64_load_scratch_fpregs(fr);
191                                 return 0;
192                         }
193                 }
194                 p += ESI_DESC_SIZE(*p);
195         }
196         return -1;
197 }
198 EXPORT_SYMBOL_GPL(ia64_esi_call_phys);
199 
200 static void __exit esi_exit (void)
201 {
202 }
203 
204 module_init(esi_init);
205 module_exit(esi_exit);  /* makes module removable... */
206 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp