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
powerpc
include
asm
epapr_hcalls.h
Go to the documentation of this file.
1
/*
2
* ePAPR hcall interface
3
*
4
* Copyright 2008-2011 Freescale Semiconductor, Inc.
5
*
6
* Author: Timur Tabi <
[email protected]
>
7
*
8
* This file is provided under a dual BSD/GPL license. When using or
9
* redistributing this file, you may do so under either license.
10
*
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions are met:
13
* * Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* * Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* * Neither the name of Freescale Semiconductor nor the
19
* names of its contributors may be used to endorse or promote products
20
* derived from this software without specific prior written permission.
21
*
22
*
23
* ALTERNATIVELY, this software may be distributed under the terms of the
24
* GNU General Public License ("GPL") as published by the Free Software
25
* Foundation, either version 2 of that License or (at your option) any
26
* later version.
27
*
28
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
29
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
32
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
*/
39
40
/* A "hypercall" is an "sc 1" instruction. This header file file provides C
41
* wrapper functions for the ePAPR hypervisor interface. It is inteded
42
* for use by Linux device drivers and other operating systems.
43
*
44
* The hypercalls are implemented as inline assembly, rather than assembly
45
* language functions in a .S file, for optimization. It allows
46
* the caller to issue the hypercall instruction directly, improving both
47
* performance and memory footprint.
48
*/
49
50
#ifndef _EPAPR_HCALLS_H
51
#define _EPAPR_HCALLS_H
52
53
#include <linux/types.h>
54
#include <linux/errno.h>
55
#include <asm/byteorder.h>
56
57
#define EV_BYTE_CHANNEL_SEND 1
58
#define EV_BYTE_CHANNEL_RECEIVE 2
59
#define EV_BYTE_CHANNEL_POLL 3
60
#define EV_INT_SET_CONFIG 4
61
#define EV_INT_GET_CONFIG 5
62
#define EV_INT_SET_MASK 6
63
#define EV_INT_GET_MASK 7
64
#define EV_INT_IACK 9
65
#define EV_INT_EOI 10
66
#define EV_INT_SEND_IPI 11
67
#define EV_INT_SET_TASK_PRIORITY 12
68
#define EV_INT_GET_TASK_PRIORITY 13
69
#define EV_DOORBELL_SEND 14
70
#define EV_MSGSND 15
71
#define EV_IDLE 16
72
73
/* vendor ID: epapr */
74
#define EV_LOCAL_VENDOR_ID 0
/* for private use */
75
#define EV_EPAPR_VENDOR_ID 1
76
#define EV_FSL_VENDOR_ID 2
/* Freescale Semiconductor */
77
#define EV_IBM_VENDOR_ID 3
/* IBM */
78
#define EV_GHS_VENDOR_ID 4
/* Green Hills Software */
79
#define EV_ENEA_VENDOR_ID 5
/* Enea */
80
#define EV_WR_VENDOR_ID 6
/* Wind River Systems */
81
#define EV_AMCC_VENDOR_ID 7
/* Applied Micro Circuits */
82
#define EV_KVM_VENDOR_ID 42
/* KVM */
83
84
/* The max number of bytes that a byte channel can send or receive per call */
85
#define EV_BYTE_CHANNEL_MAX_BYTES 16
86
87
88
#define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))
89
#define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num)
90
91
/* epapr error codes */
92
#define EV_EPERM 1
/* Operation not permitted */
93
#define EV_ENOENT 2
/* Entry Not Found */
94
#define EV_EIO 3
/* I/O error occured */
95
#define EV_EAGAIN 4
/* The operation had insufficient
96
* resources to complete and should be
97
* retried
98
*/
99
#define EV_ENOMEM 5
/* There was insufficient memory to
100
* complete the operation */
101
#define EV_EFAULT 6
/* Bad guest address */
102
#define EV_ENODEV 7
/* No such device */
103
#define EV_EINVAL 8
/* An argument supplied to the hcall
104
was out of range or invalid */
105
#define EV_INTERNAL 9
/* An internal error occured */
106
#define EV_CONFIG 10
/* A configuration error was detected */
107
#define EV_INVALID_STATE 11
/* The object is in an invalid state */
108
#define EV_UNIMPLEMENTED 12
/* Unimplemented hypercall */
109
#define EV_BUFFER_OVERFLOW 13
/* Caller-supplied buffer too small */
110
111
/*
112
* Hypercall register clobber list
113
*
114
* These macros are used to define the list of clobbered registers during a
115
* hypercall. Technically, registers r0 and r3-r12 are always clobbered,
116
* but the gcc inline assembly syntax does not allow us to specify registers
117
* on the clobber list that are also on the input/output list. Therefore,
118
* the lists of clobbered registers depends on the number of register
119
* parmeters ("+r" and "=r") passed to the hypercall.
120
*
121
* Each assembly block should use one of the HCALL_CLOBBERSx macros. As a
122
* general rule, 'x' is the number of parameters passed to the assembly
123
* block *except* for r11.
124
*
125
* If you're not sure, just use the smallest value of 'x' that does not
126
* generate a compilation error. Because these are static inline functions,
127
* the compiler will only check the clobber list for a function if you
128
* compile code that calls that function.
129
*
130
* r3 and r11 are not included in any clobbers list because they are always
131
* listed as output registers.
132
*
133
* XER, CTR, and LR are currently listed as clobbers because it's uncertain
134
* whether they will be clobbered.
135
*
136
* Note that r11 can be used as an output parameter.
137
*
138
* The "memory" clobber is only necessary for hcalls where the Hypervisor
139
* will read or write guest memory. However, we add it to all hcalls because
140
* the impact is minimal, and we want to ensure that it's present for the
141
* hcalls that need it.
142
*/
143
144
/* List of common clobbered registers. Do not use this macro. */
145
#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory"
146
147
#define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS
148
#define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10"
149
#define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9"
150
#define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8"
151
#define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7"
152
#define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6"
153
#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
154
#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
155
156
extern
bool
epapr_paravirt_enabled
;
157
extern
u32
epapr_hypercall_start
[];
158
159
/*
160
* We use "uintptr_t" to define a register because it's guaranteed to be a
161
* 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
162
* platform.
163
*
164
* All registers are either input/output or output only. Registers that are
165
* initialized before making the hypercall are input/output. All
166
* input/output registers are represented with "+r". Output-only registers
167
* are represented with "=r". Do not specify any unused registers. The
168
* clobber list will tell the compiler that the hypercall modifies those
169
* registers, which is good enough.
170
*/
171
181
static
inline
unsigned
int
ev_int_set_config(
unsigned
int
interrupt
,
182
uint32_t
config
,
unsigned
int
priority
,
uint32_t
destination)
183
{
184
register
uintptr_t
r11
__asm__
(
"r11"
);
185
register
uintptr_t
r3
__asm__
(
"r3"
);
186
register
uintptr_t
r4
__asm__
(
"r4"
);
187
register
uintptr_t
r5
__asm__
(
"r5"
);
188
register
uintptr_t
r6
__asm__
(
"r6"
);
189
190
r11
=
EV_HCALL_TOKEN
(
EV_INT_SET_CONFIG
);
191
r3
=
interrupt
;
192
r4
=
config
;
193
r5
=
priority
;
194
r6
= destination;
195
196
__asm__ __volatile__ (
"sc 1"
197
:
"+r"
(
r11
),
"+r"
(
r3
),
"+r"
(
r4
),
"+r"
(
r5
),
"+r"
(
r6
)
198
: :
EV_HCALL_CLOBBERS4
199
);
200
201
return
r3
;
202
}
203
213
static
inline
unsigned
int
ev_int_get_config(
unsigned
int
interrupt
,
214
uint32_t
*
config
,
unsigned
int
*
priority
,
uint32_t
*destination)
215
{
216
register
uintptr_t
r11
__asm__
(
"r11"
);
217
register
uintptr_t
r3
__asm__
(
"r3"
);
218
register
uintptr_t
r4
__asm__
(
"r4"
);
219
register
uintptr_t
r5
__asm__
(
"r5"
);
220
register
uintptr_t
r6
__asm__
(
"r6"
);
221
222
r11
=
EV_HCALL_TOKEN
(
EV_INT_GET_CONFIG
);
223
r3
=
interrupt
;
224
225
__asm__
__volatile__ (
"sc 1"
226
:
"+r"
(
r11
),
"+r"
(
r3
),
"=r"
(
r4
),
"=r"
(
r5
),
"=r"
(
r6
)
227
: :
EV_HCALL_CLOBBERS4
228
);
229
230
*config =
r4
;
231
*priority =
r5
;
232
*destination =
r6
;
233
234
return
r3
;
235
}
236
244
static
inline
unsigned
int
ev_int_set_mask(
unsigned
int
interrupt,
245
unsigned
int
mask
)
246
{
247
register
uintptr_t
r11
__asm__
(
"r11"
);
248
register
uintptr_t
r3
__asm__
(
"r3"
);
249
register
uintptr_t
r4
__asm__
(
"r4"
);
250
251
r11
=
EV_HCALL_TOKEN
(
EV_INT_SET_MASK
);
252
r3
=
interrupt
;
253
r4
=
mask
;
254
255
__asm__
__volatile__ (
"sc 1"
256
:
"+r"
(
r11
),
"+r"
(
r3
),
"+r"
(
r4
)
257
: :
EV_HCALL_CLOBBERS2
258
);
259
260
return
r3
;
261
}
262
270
static
inline
unsigned
int
ev_int_get_mask(
unsigned
int
interrupt,
271
unsigned
int
*mask)
272
{
273
register
uintptr_t
r11
__asm__
(
"r11"
);
274
register
uintptr_t
r3
__asm__
(
"r3"
);
275
register
uintptr_t
r4
__asm__
(
"r4"
);
276
277
r11
=
EV_HCALL_TOKEN
(
EV_INT_GET_MASK
);
278
r3
=
interrupt
;
279
280
__asm__
__volatile__ (
"sc 1"
281
:
"+r"
(
r11
),
"+r"
(
r3
),
"=r"
(
r4
)
282
: :
EV_HCALL_CLOBBERS2
283
);
284
285
*mask =
r4
;
286
287
return
r3
;
288
}
289
300
static
inline
unsigned
int
ev_int_eoi(
unsigned
int
interrupt)
301
{
302
register
uintptr_t
r11
__asm__
(
"r11"
);
303
register
uintptr_t
r3
__asm__
(
"r3"
);
304
305
r11
=
EV_HCALL_TOKEN
(
EV_INT_EOI
);
306
r3
=
interrupt
;
307
308
__asm__
__volatile__ (
"sc 1"
309
:
"+r"
(
r11
),
"+r"
(
r3
)
310
: :
EV_HCALL_CLOBBERS1
311
);
312
313
return
r3
;
314
}
315
327
static
inline
unsigned
int
ev_byte_channel_send(
unsigned
int
handle
,
328
unsigned
int
*
count
,
const
char
buffer
[
EV_BYTE_CHANNEL_MAX_BYTES
])
329
{
330
register
uintptr_t
r11
__asm__
(
"r11"
);
331
register
uintptr_t
r3
__asm__
(
"r3"
);
332
register
uintptr_t
r4
__asm__
(
"r4"
);
333
register
uintptr_t
r5
__asm__
(
"r5"
);
334
register
uintptr_t
r6
__asm__
(
"r6"
);
335
register
uintptr_t
r7
__asm__
(
"r7"
);
336
register
uintptr_t
r8
__asm__
(
"r8"
);
337
const
uint32_t
*
p
= (
const
uint32_t
*)
buffer
;
338
339
r11
=
EV_HCALL_TOKEN
(
EV_BYTE_CHANNEL_SEND
);
340
r3
=
handle
;
341
r4
= *
count
;
342
r5
=
be32_to_cpu
(p[0]);
343
r6
=
be32_to_cpu
(p[1]);
344
r7
=
be32_to_cpu
(p[2]);
345
r8
=
be32_to_cpu
(p[3]);
346
347
__asm__
__volatile__ (
"sc 1"
348
:
"+r"
(
r11
),
"+r"
(
r3
),
349
"+r"
(
r4
),
"+r"
(
r5
),
"+r"
(
r6
),
"+r"
(
r7
),
"+r"
(
r8
)
350
: :
EV_HCALL_CLOBBERS6
351
);
352
353
*count =
r4
;
354
355
return
r3
;
356
}
357
370
static
inline
unsigned
int
ev_byte_channel_receive(
unsigned
int
handle,
371
unsigned
int
*count,
char
buffer
[EV_BYTE_CHANNEL_MAX_BYTES])
372
{
373
register
uintptr_t
r11
__asm__
(
"r11"
);
374
register
uintptr_t
r3
__asm__
(
"r3"
);
375
register
uintptr_t
r4
__asm__
(
"r4"
);
376
register
uintptr_t
r5
__asm__
(
"r5"
);
377
register
uintptr_t
r6
__asm__
(
"r6"
);
378
register
uintptr_t
r7
__asm__
(
"r7"
);
379
register
uintptr_t
r8
__asm__
(
"r8"
);
380
uint32_t
*p = (
uint32_t
*)
buffer
;
381
382
r11
=
EV_HCALL_TOKEN
(
EV_BYTE_CHANNEL_RECEIVE
);
383
r3
=
handle
;
384
r4
= *
count
;
385
386
__asm__
__volatile__ (
"sc 1"
387
:
"+r"
(
r11
),
"+r"
(
r3
),
"+r"
(
r4
),
388
"=r"
(
r5
),
"=r"
(
r6
),
"=r"
(
r7
),
"=r"
(
r8
)
389
: :
EV_HCALL_CLOBBERS6
390
);
391
392
*count =
r4
;
393
p[0] =
cpu_to_be32
(
r5
);
394
p[1] =
cpu_to_be32
(
r6
);
395
p[2] =
cpu_to_be32
(
r7
);
396
p[3] =
cpu_to_be32
(
r8
);
397
398
return
r3
;
399
}
400
413
static
inline
unsigned
int
ev_byte_channel_poll(
unsigned
int
handle,
414
unsigned
int
*rx_count,
unsigned
int
*tx_count)
415
{
416
register
uintptr_t
r11
__asm__
(
"r11"
);
417
register
uintptr_t
r3
__asm__
(
"r3"
);
418
register
uintptr_t
r4
__asm__
(
"r4"
);
419
register
uintptr_t
r5
__asm__
(
"r5"
);
420
421
r11
=
EV_HCALL_TOKEN
(
EV_BYTE_CHANNEL_POLL
);
422
r3
=
handle
;
423
424
__asm__
__volatile__ (
"sc 1"
425
:
"+r"
(
r11
),
"+r"
(
r3
),
"=r"
(
r4
),
"=r"
(
r5
)
426
: :
EV_HCALL_CLOBBERS3
427
);
428
429
*rx_count =
r4
;
430
*tx_count =
r5
;
431
432
return
r3
;
433
}
434
447
static
inline
unsigned
int
ev_int_iack(
unsigned
int
handle,
448
unsigned
int
*
vector
)
449
{
450
register
uintptr_t
r11
__asm__
(
"r11"
);
451
register
uintptr_t
r3
__asm__
(
"r3"
);
452
register
uintptr_t
r4
__asm__
(
"r4"
);
453
454
r11
=
EV_HCALL_TOKEN
(
EV_INT_IACK
);
455
r3
=
handle
;
456
457
__asm__
__volatile__ (
"sc 1"
458
:
"+r"
(
r11
),
"+r"
(
r3
),
"=r"
(
r4
)
459
: :
EV_HCALL_CLOBBERS2
460
);
461
462
*vector =
r4
;
463
464
return
r3
;
465
}
466
473
static
inline
unsigned
int
ev_doorbell_send(
unsigned
int
handle)
474
{
475
register
uintptr_t
r11
__asm__
(
"r11"
);
476
register
uintptr_t
r3
__asm__
(
"r3"
);
477
478
r11
=
EV_HCALL_TOKEN
(
EV_DOORBELL_SEND
);
479
r3
=
handle
;
480
481
__asm__
__volatile__ (
"sc 1"
482
:
"+r"
(
r11
),
"+r"
(
r3
)
483
: :
EV_HCALL_CLOBBERS1
484
);
485
486
return
r3
;
487
}
488
494
static
inline
unsigned
int
ev_idle(
void
)
495
{
496
register
uintptr_t
r11
__asm__
(
"r11"
);
497
register
uintptr_t
r3
__asm__
(
"r3"
);
498
499
r11
=
EV_HCALL_TOKEN
(
EV_IDLE
);
500
501
__asm__
__volatile__ (
"sc 1"
502
:
"+r"
(
r11
),
"=r"
(
r3
)
503
: :
EV_HCALL_CLOBBERS1
504
);
505
506
return
r3
;
507
}
508
509
#endif
Generated on Thu Jan 10 2013 13:13:17 for Linux Kernel by
1.8.2