Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
ia64
kernel
esi.c
Go to the documentation of this file.
1
/*
2
* Extensible SAL Interface (ESI) support routines.
3
*
4
* Copyright (C) 2006 Hewlett-Packard Co
5
* Alex Williamson <
[email protected]
>
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 <
[email protected]
>"
);
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... */
Generated on Thu Jan 10 2013 13:06:39 for Linux Kernel by
1.8.2