powerpc/powernv: Report size of OPAL memcons log
[linux/fpc-iii.git] / arch / powerpc / platforms / pseries / hvCall.S
blob74b5b8e239c8235ac61b529b8085cc3ceff096ed
1 /*
2  * This file contains the generic code to perform a call to the
3  * pSeries LPAR hypervisor.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version
8  * 2 of the License, or (at your option) any later version.
9  */
10 #include <linux/jump_label.h>
11 #include <asm/hvcall.h>
12 #include <asm/processor.h>
13 #include <asm/ppc_asm.h>
14 #include <asm/asm-offsets.h>
15 #include <asm/ptrace.h>
17         .section        ".text"
18         
19 #ifdef CONFIG_TRACEPOINTS
21 #ifndef HAVE_JUMP_LABEL
22         .section        ".toc","aw"
24         .globl hcall_tracepoint_refcount
25 hcall_tracepoint_refcount:
26         .llong  0
28         .section        ".text"
29 #endif
32  * precall must preserve all registers.  use unused STK_PARAM()
33  * areas to save snapshots and opcode.
34  */
35 #define HCALL_INST_PRECALL(FIRST_REG)                           \
36         mflr    r0;                                             \
37         std     r3,STK_PARAM(R3)(r1);                           \
38         std     r4,STK_PARAM(R4)(r1);                           \
39         std     r5,STK_PARAM(R5)(r1);                           \
40         std     r6,STK_PARAM(R6)(r1);                           \
41         std     r7,STK_PARAM(R7)(r1);                           \
42         std     r8,STK_PARAM(R8)(r1);                           \
43         std     r9,STK_PARAM(R9)(r1);                           \
44         std     r10,STK_PARAM(R10)(r1);                         \
45         std     r0,16(r1);                                      \
46         addi    r4,r1,STK_PARAM(FIRST_REG);                     \
47         stdu    r1,-STACK_FRAME_OVERHEAD(r1);                   \
48         bl      __trace_hcall_entry;                            \
49         ld      r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1);      \
50         ld      r4,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1);      \
51         ld      r5,STACK_FRAME_OVERHEAD+STK_PARAM(R5)(r1);      \
52         ld      r6,STACK_FRAME_OVERHEAD+STK_PARAM(R6)(r1);      \
53         ld      r7,STACK_FRAME_OVERHEAD+STK_PARAM(R7)(r1);      \
54         ld      r8,STACK_FRAME_OVERHEAD+STK_PARAM(R8)(r1);      \
55         ld      r9,STACK_FRAME_OVERHEAD+STK_PARAM(R9)(r1);      \
56         ld      r10,STACK_FRAME_OVERHEAD+STK_PARAM(R10)(r1)
59  * postcall is performed immediately before function return which
60  * allows liberal use of volatile registers.
61  */
62 #define __HCALL_INST_POSTCALL                                   \
63         ld      r0,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1);      \
64         std     r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1);      \
65         mr      r4,r3;                                          \
66         mr      r3,r0;                                          \
67         bl      __trace_hcall_exit;                             \
68         ld      r0,STACK_FRAME_OVERHEAD+16(r1);                 \
69         addi    r1,r1,STACK_FRAME_OVERHEAD;                     \
70         ld      r3,STK_PARAM(R3)(r1);                           \
71         mtlr    r0
73 #define HCALL_INST_POSTCALL_NORETS                              \
74         li      r5,0;                                           \
75         __HCALL_INST_POSTCALL
77 #define HCALL_INST_POSTCALL(BUFREG)                             \
78         mr      r5,BUFREG;                                      \
79         __HCALL_INST_POSTCALL
81 #ifdef HAVE_JUMP_LABEL
82 #define HCALL_BRANCH(LABEL)                                     \
83         ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key)
84 #else
87  * We branch around this in early init (eg when populating the MMU
88  * hashtable) by using an unconditional cpu feature.
89  */
90 #define HCALL_BRANCH(LABEL)                                     \
91 BEGIN_FTR_SECTION;                                              \
92         b       1f;                                             \
93 END_FTR_SECTION(0, 1);                                          \
94         ld      r12,hcall_tracepoint_refcount@toc(r2);          \
95         std     r12,32(r1);                                     \
96         cmpdi   r12,0;                                          \
97         bne-    LABEL;                                          \
99 #endif
101 #else
102 #define HCALL_INST_PRECALL(FIRST_ARG)
103 #define HCALL_INST_POSTCALL_NORETS
104 #define HCALL_INST_POSTCALL(BUFREG)
105 #define HCALL_BRANCH(LABEL)
106 #endif
108 _GLOBAL_TOC(plpar_hcall_norets)
109         HMT_MEDIUM
111         mfcr    r0
112         stw     r0,8(r1)
113         HCALL_BRANCH(plpar_hcall_norets_trace)
114         HVSC                            /* invoke the hypervisor */
116         lwz     r0,8(r1)
117         mtcrf   0xff,r0
118         blr                             /* return r3 = status */
120 #ifdef CONFIG_TRACEPOINTS
121 plpar_hcall_norets_trace:
122         HCALL_INST_PRECALL(R4)
123         HVSC
124         HCALL_INST_POSTCALL_NORETS
125         lwz     r0,8(r1)
126         mtcrf   0xff,r0
127         blr
128 #endif
130 _GLOBAL_TOC(plpar_hcall)
131         HMT_MEDIUM
133         mfcr    r0
134         stw     r0,8(r1)
136         HCALL_BRANCH(plpar_hcall_trace)
138         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
140         mr      r4,r5
141         mr      r5,r6
142         mr      r6,r7
143         mr      r7,r8
144         mr      r8,r9
145         mr      r9,r10
147         HVSC                            /* invoke the hypervisor */
149         ld      r12,STK_PARAM(R4)(r1)
150         std     r4,  0(r12)
151         std     r5,  8(r12)
152         std     r6, 16(r12)
153         std     r7, 24(r12)
155         lwz     r0,8(r1)
156         mtcrf   0xff,r0
158         blr                             /* return r3 = status */
160 #ifdef CONFIG_TRACEPOINTS
161 plpar_hcall_trace:
162         HCALL_INST_PRECALL(R5)
164         std     r4,STK_PARAM(R4)(r1)
165         mr      r0,r4
167         mr      r4,r5
168         mr      r5,r6
169         mr      r6,r7
170         mr      r7,r8
171         mr      r8,r9
172         mr      r9,r10
174         HVSC
176         ld      r12,STK_PARAM(R4)(r1)
177         std     r4,0(r12)
178         std     r5,8(r12)
179         std     r6,16(r12)
180         std     r7,24(r12)
182         HCALL_INST_POSTCALL(r12)
184         lwz     r0,8(r1)
185         mtcrf   0xff,r0
187         blr
188 #endif
191  * plpar_hcall_raw can be called in real mode. kexec/kdump need some
192  * hypervisor calls to be executed in real mode. So plpar_hcall_raw
193  * does not access the per cpu hypervisor call statistics variables,
194  * since these variables may not be present in the RMO region.
195  */
196 _GLOBAL(plpar_hcall_raw)
197         HMT_MEDIUM
199         mfcr    r0
200         stw     r0,8(r1)
202         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
204         mr      r4,r5
205         mr      r5,r6
206         mr      r6,r7
207         mr      r7,r8
208         mr      r8,r9
209         mr      r9,r10
211         HVSC                            /* invoke the hypervisor */
213         ld      r12,STK_PARAM(R4)(r1)
214         std     r4,  0(r12)
215         std     r5,  8(r12)
216         std     r6, 16(r12)
217         std     r7, 24(r12)
219         lwz     r0,8(r1)
220         mtcrf   0xff,r0
222         blr                             /* return r3 = status */
224 _GLOBAL_TOC(plpar_hcall9)
225         HMT_MEDIUM
227         mfcr    r0
228         stw     r0,8(r1)
230         HCALL_BRANCH(plpar_hcall9_trace)
232         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
234         mr      r4,r5
235         mr      r5,r6
236         mr      r6,r7
237         mr      r7,r8
238         mr      r8,r9
239         mr      r9,r10
240         ld      r10,STK_PARAM(R11)(r1)   /* put arg7 in R10 */
241         ld      r11,STK_PARAM(R12)(r1)   /* put arg8 in R11 */
242         ld      r12,STK_PARAM(R13)(r1)    /* put arg9 in R12 */
244         HVSC                            /* invoke the hypervisor */
246         mr      r0,r12
247         ld      r12,STK_PARAM(R4)(r1)
248         std     r4,  0(r12)
249         std     r5,  8(r12)
250         std     r6, 16(r12)
251         std     r7, 24(r12)
252         std     r8, 32(r12)
253         std     r9, 40(r12)
254         std     r10,48(r12)
255         std     r11,56(r12)
256         std     r0, 64(r12)
258         lwz     r0,8(r1)
259         mtcrf   0xff,r0
261         blr                             /* return r3 = status */
263 #ifdef CONFIG_TRACEPOINTS
264 plpar_hcall9_trace:
265         HCALL_INST_PRECALL(R5)
267         std     r4,STK_PARAM(R4)(r1)
268         mr      r0,r4
270         mr      r4,r5
271         mr      r5,r6
272         mr      r6,r7
273         mr      r7,r8
274         mr      r8,r9
275         mr      r9,r10
276         ld      r10,STACK_FRAME_OVERHEAD+STK_PARAM(R11)(r1)
277         ld      r11,STACK_FRAME_OVERHEAD+STK_PARAM(R12)(r1)
278         ld      r12,STACK_FRAME_OVERHEAD+STK_PARAM(R13)(r1)
280         HVSC
282         mr      r0,r12
283         ld      r12,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1)
284         std     r4,0(r12)
285         std     r5,8(r12)
286         std     r6,16(r12)
287         std     r7,24(r12)
288         std     r8,32(r12)
289         std     r9,40(r12)
290         std     r10,48(r12)
291         std     r11,56(r12)
292         std     r0,64(r12)
294         HCALL_INST_POSTCALL(r12)
296         lwz     r0,8(r1)
297         mtcrf   0xff,r0
299         blr
300 #endif
302 /* See plpar_hcall_raw to see why this is needed */
303 _GLOBAL(plpar_hcall9_raw)
304         HMT_MEDIUM
306         mfcr    r0
307         stw     r0,8(r1)
309         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
311         mr      r4,r5
312         mr      r5,r6
313         mr      r6,r7
314         mr      r7,r8
315         mr      r8,r9
316         mr      r9,r10
317         ld      r10,STK_PARAM(R11)(r1)   /* put arg7 in R10 */
318         ld      r11,STK_PARAM(R12)(r1)   /* put arg8 in R11 */
319         ld      r12,STK_PARAM(R13)(r1)    /* put arg9 in R12 */
321         HVSC                            /* invoke the hypervisor */
323         mr      r0,r12
324         ld      r12,STK_PARAM(R4)(r1)
325         std     r4,  0(r12)
326         std     r5,  8(r12)
327         std     r6, 16(r12)
328         std     r7, 24(r12)
329         std     r8, 32(r12)
330         std     r9, 40(r12)
331         std     r10,48(r12)
332         std     r11,56(r12)
333         std     r0, 64(r12)
335         lwz     r0,8(r1)
336         mtcrf   0xff,r0
338         blr                             /* return r3 = status */