1bd497fc9STimur Tabi /*
2bd497fc9STimur Tabi * Freescale hypervisor call interface
3bd497fc9STimur Tabi *
4bd497fc9STimur Tabi * Copyright 2008-2010 Freescale Semiconductor, Inc.
5bd497fc9STimur Tabi *
6bd497fc9STimur Tabi * Author: Timur Tabi <timur@freescale.com>
7bd497fc9STimur Tabi *
8bd497fc9STimur Tabi * This file is provided under a dual BSD/GPL license. When using or
9bd497fc9STimur Tabi * redistributing this file, you may do so under either license.
10bd497fc9STimur Tabi *
11bd497fc9STimur Tabi * Redistribution and use in source and binary forms, with or without
12bd497fc9STimur Tabi * modification, are permitted provided that the following conditions are met:
13bd497fc9STimur Tabi * * Redistributions of source code must retain the above copyright
14bd497fc9STimur Tabi * notice, this list of conditions and the following disclaimer.
15bd497fc9STimur Tabi * * Redistributions in binary form must reproduce the above copyright
16bd497fc9STimur Tabi * notice, this list of conditions and the following disclaimer in the
17bd497fc9STimur Tabi * documentation and/or other materials provided with the distribution.
18bd497fc9STimur Tabi * * Neither the name of Freescale Semiconductor nor the
19bd497fc9STimur Tabi * names of its contributors may be used to endorse or promote products
20bd497fc9STimur Tabi * derived from this software without specific prior written permission.
21bd497fc9STimur Tabi *
22bd497fc9STimur Tabi *
23bd497fc9STimur Tabi * ALTERNATIVELY, this software may be distributed under the terms of the
24bd497fc9STimur Tabi * GNU General Public License ("GPL") as published by the Free Software
25bd497fc9STimur Tabi * Foundation, either version 2 of that License or (at your option) any
26bd497fc9STimur Tabi * later version.
27bd497fc9STimur Tabi *
28bd497fc9STimur Tabi * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
29bd497fc9STimur Tabi * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30bd497fc9STimur Tabi * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31bd497fc9STimur Tabi * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
32bd497fc9STimur Tabi * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33bd497fc9STimur Tabi * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34bd497fc9STimur Tabi * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35bd497fc9STimur Tabi * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36bd497fc9STimur Tabi * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37bd497fc9STimur Tabi * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38bd497fc9STimur Tabi */
39bd497fc9STimur Tabi
40bd497fc9STimur Tabi #ifndef _FSL_HCALLS_H
41bd497fc9STimur Tabi #define _FSL_HCALLS_H
42bd497fc9STimur Tabi
43bd497fc9STimur Tabi #include <linux/types.h>
44bd497fc9STimur Tabi #include <linux/errno.h>
45bd497fc9STimur Tabi #include <asm/byteorder.h>
46bd497fc9STimur Tabi #include <asm/epapr_hcalls.h>
47bd497fc9STimur Tabi
48bd497fc9STimur Tabi #define FH_API_VERSION 1
49bd497fc9STimur Tabi
50bd497fc9STimur Tabi #define FH_ERR_GET_INFO 1
51bd497fc9STimur Tabi #define FH_PARTITION_GET_DTPROP 2
52bd497fc9STimur Tabi #define FH_PARTITION_SET_DTPROP 3
53bd497fc9STimur Tabi #define FH_PARTITION_RESTART 4
54bd497fc9STimur Tabi #define FH_PARTITION_GET_STATUS 5
55bd497fc9STimur Tabi #define FH_PARTITION_START 6
56bd497fc9STimur Tabi #define FH_PARTITION_STOP 7
57bd497fc9STimur Tabi #define FH_PARTITION_MEMCPY 8
58bd497fc9STimur Tabi #define FH_DMA_ENABLE 9
59bd497fc9STimur Tabi #define FH_DMA_DISABLE 10
60bd497fc9STimur Tabi #define FH_SEND_NMI 11
61bd497fc9STimur Tabi #define FH_VMPIC_GET_MSIR 12
62bd497fc9STimur Tabi #define FH_SYSTEM_RESET 13
63bd497fc9STimur Tabi #define FH_GET_CORE_STATE 14
64bd497fc9STimur Tabi #define FH_ENTER_NAP 15
65bd497fc9STimur Tabi #define FH_EXIT_NAP 16
66bd497fc9STimur Tabi #define FH_CLAIM_DEVICE 17
67bd497fc9STimur Tabi #define FH_PARTITION_STOP_DMA 18
68bd497fc9STimur Tabi
69bd497fc9STimur Tabi /* vendor ID: Freescale Semiconductor */
70bd497fc9STimur Tabi #define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num)
71bd497fc9STimur Tabi
72bd497fc9STimur Tabi /*
73bd497fc9STimur Tabi * We use "uintptr_t" to define a register because it's guaranteed to be a
74bd497fc9STimur Tabi * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
75bd497fc9STimur Tabi * platform.
76bd497fc9STimur Tabi *
77bd497fc9STimur Tabi * All registers are either input/output or output only. Registers that are
78bd497fc9STimur Tabi * initialized before making the hypercall are input/output. All
79bd497fc9STimur Tabi * input/output registers are represented with "+r". Output-only registers
80bd497fc9STimur Tabi * are represented with "=r". Do not specify any unused registers. The
81bd497fc9STimur Tabi * clobber list will tell the compiler that the hypercall modifies those
82bd497fc9STimur Tabi * registers, which is good enough.
83bd497fc9STimur Tabi */
84bd497fc9STimur Tabi
85bd497fc9STimur Tabi /**
86bd497fc9STimur Tabi * fh_send_nmi - send NMI to virtual cpu(s).
87bd497fc9STimur Tabi * @vcpu_mask: send NMI to virtual cpu(s) specified by this mask.
88bd497fc9STimur Tabi *
89bd497fc9STimur Tabi * Returns 0 for success, or EINVAL for invalid vcpu_mask.
90bd497fc9STimur Tabi */
fh_send_nmi(unsigned int vcpu_mask)91bd497fc9STimur Tabi static inline unsigned int fh_send_nmi(unsigned int vcpu_mask)
92bd497fc9STimur Tabi {
93bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
94bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
95bd497fc9STimur Tabi
96bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_SEND_NMI);
97bd497fc9STimur Tabi r3 = vcpu_mask;
98bd497fc9STimur Tabi
998e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
100bd497fc9STimur Tabi : "+r" (r11), "+r" (r3)
101bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
102bd497fc9STimur Tabi );
103bd497fc9STimur Tabi
104bd497fc9STimur Tabi return r3;
105bd497fc9STimur Tabi }
106bd497fc9STimur Tabi
107bd497fc9STimur Tabi /* Arbitrary limits to avoid excessive memory allocation in hypervisor */
108bd497fc9STimur Tabi #define FH_DTPROP_MAX_PATHLEN 4096
109bd497fc9STimur Tabi #define FH_DTPROP_MAX_PROPLEN 32768
110bd497fc9STimur Tabi
111bd497fc9STimur Tabi /**
112*8ab102d6SMasahiro Yamada * fh_partition_get_dtprop - get a property from a guest device tree.
113bd497fc9STimur Tabi * @handle: handle of partition whose device tree is to be accessed
114bd497fc9STimur Tabi * @dtpath_addr: physical address of device tree path to access
115bd497fc9STimur Tabi * @propname_addr: physical address of name of property
116bd497fc9STimur Tabi * @propvalue_addr: physical address of property value buffer
117bd497fc9STimur Tabi * @propvalue_len: length of buffer on entry, length of property on return
118bd497fc9STimur Tabi *
119bd497fc9STimur Tabi * Returns zero on success, non-zero on error.
120bd497fc9STimur Tabi */
fh_partition_get_dtprop(int handle,uint64_t dtpath_addr,uint64_t propname_addr,uint64_t propvalue_addr,uint32_t * propvalue_len)121bd497fc9STimur Tabi static inline unsigned int fh_partition_get_dtprop(int handle,
122bd497fc9STimur Tabi uint64_t dtpath_addr,
123bd497fc9STimur Tabi uint64_t propname_addr,
124bd497fc9STimur Tabi uint64_t propvalue_addr,
125bd497fc9STimur Tabi uint32_t *propvalue_len)
126bd497fc9STimur Tabi {
127bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
128bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
129bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
130bd497fc9STimur Tabi register uintptr_t r5 __asm__("r5");
131bd497fc9STimur Tabi register uintptr_t r6 __asm__("r6");
132bd497fc9STimur Tabi register uintptr_t r7 __asm__("r7");
133bd497fc9STimur Tabi register uintptr_t r8 __asm__("r8");
134bd497fc9STimur Tabi register uintptr_t r9 __asm__("r9");
135bd497fc9STimur Tabi register uintptr_t r10 __asm__("r10");
136bd497fc9STimur Tabi
137bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_DTPROP);
138bd497fc9STimur Tabi r3 = handle;
139bd497fc9STimur Tabi
140bd497fc9STimur Tabi #ifdef CONFIG_PHYS_64BIT
141bd497fc9STimur Tabi r4 = dtpath_addr >> 32;
142bd497fc9STimur Tabi r6 = propname_addr >> 32;
143bd497fc9STimur Tabi r8 = propvalue_addr >> 32;
144bd497fc9STimur Tabi #else
145bd497fc9STimur Tabi r4 = 0;
146bd497fc9STimur Tabi r6 = 0;
147bd497fc9STimur Tabi r8 = 0;
148bd497fc9STimur Tabi #endif
149bd497fc9STimur Tabi r5 = (uint32_t)dtpath_addr;
150bd497fc9STimur Tabi r7 = (uint32_t)propname_addr;
151bd497fc9STimur Tabi r9 = (uint32_t)propvalue_addr;
152bd497fc9STimur Tabi r10 = *propvalue_len;
153bd497fc9STimur Tabi
1548e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
155bd497fc9STimur Tabi : "+r" (r11),
156bd497fc9STimur Tabi "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
157bd497fc9STimur Tabi "+r" (r8), "+r" (r9), "+r" (r10)
158bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS8
159bd497fc9STimur Tabi );
160bd497fc9STimur Tabi
161bd497fc9STimur Tabi *propvalue_len = r4;
162bd497fc9STimur Tabi return r3;
163bd497fc9STimur Tabi }
164bd497fc9STimur Tabi
165bd497fc9STimur Tabi /**
166bd497fc9STimur Tabi * Set a property in a guest device tree.
167bd497fc9STimur Tabi * @handle: handle of partition whose device tree is to be accessed
168bd497fc9STimur Tabi * @dtpath_addr: physical address of device tree path to access
169bd497fc9STimur Tabi * @propname_addr: physical address of name of property
170bd497fc9STimur Tabi * @propvalue_addr: physical address of property value
171bd497fc9STimur Tabi * @propvalue_len: length of property
172bd497fc9STimur Tabi *
173bd497fc9STimur Tabi * Returns zero on success, non-zero on error.
174bd497fc9STimur Tabi */
fh_partition_set_dtprop(int handle,uint64_t dtpath_addr,uint64_t propname_addr,uint64_t propvalue_addr,uint32_t propvalue_len)175bd497fc9STimur Tabi static inline unsigned int fh_partition_set_dtprop(int handle,
176bd497fc9STimur Tabi uint64_t dtpath_addr,
177bd497fc9STimur Tabi uint64_t propname_addr,
178bd497fc9STimur Tabi uint64_t propvalue_addr,
179bd497fc9STimur Tabi uint32_t propvalue_len)
180bd497fc9STimur Tabi {
181bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
182bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
183bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
184bd497fc9STimur Tabi register uintptr_t r6 __asm__("r6");
185bd497fc9STimur Tabi register uintptr_t r8 __asm__("r8");
186bd497fc9STimur Tabi register uintptr_t r5 __asm__("r5");
187bd497fc9STimur Tabi register uintptr_t r7 __asm__("r7");
188bd497fc9STimur Tabi register uintptr_t r9 __asm__("r9");
189bd497fc9STimur Tabi register uintptr_t r10 __asm__("r10");
190bd497fc9STimur Tabi
191bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_SET_DTPROP);
192bd497fc9STimur Tabi r3 = handle;
193bd497fc9STimur Tabi
194bd497fc9STimur Tabi #ifdef CONFIG_PHYS_64BIT
195bd497fc9STimur Tabi r4 = dtpath_addr >> 32;
196bd497fc9STimur Tabi r6 = propname_addr >> 32;
197bd497fc9STimur Tabi r8 = propvalue_addr >> 32;
198bd497fc9STimur Tabi #else
199bd497fc9STimur Tabi r4 = 0;
200bd497fc9STimur Tabi r6 = 0;
201bd497fc9STimur Tabi r8 = 0;
202bd497fc9STimur Tabi #endif
203bd497fc9STimur Tabi r5 = (uint32_t)dtpath_addr;
204bd497fc9STimur Tabi r7 = (uint32_t)propname_addr;
205bd497fc9STimur Tabi r9 = (uint32_t)propvalue_addr;
206bd497fc9STimur Tabi r10 = propvalue_len;
207bd497fc9STimur Tabi
2088e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
209bd497fc9STimur Tabi : "+r" (r11),
210bd497fc9STimur Tabi "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
211bd497fc9STimur Tabi "+r" (r8), "+r" (r9), "+r" (r10)
212bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS8
213bd497fc9STimur Tabi );
214bd497fc9STimur Tabi
215bd497fc9STimur Tabi return r3;
216bd497fc9STimur Tabi }
217bd497fc9STimur Tabi
218bd497fc9STimur Tabi /**
219bd497fc9STimur Tabi * fh_partition_restart - reboot the current partition
220bd497fc9STimur Tabi * @partition: partition ID
221bd497fc9STimur Tabi *
222bd497fc9STimur Tabi * Returns an error code if reboot failed. Does not return if it succeeds.
223bd497fc9STimur Tabi */
fh_partition_restart(unsigned int partition)224bd497fc9STimur Tabi static inline unsigned int fh_partition_restart(unsigned int partition)
225bd497fc9STimur Tabi {
226bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
227bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
228bd497fc9STimur Tabi
229bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_RESTART);
230bd497fc9STimur Tabi r3 = partition;
231bd497fc9STimur Tabi
2328e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
233bd497fc9STimur Tabi : "+r" (r11), "+r" (r3)
234bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
235bd497fc9STimur Tabi );
236bd497fc9STimur Tabi
237bd497fc9STimur Tabi return r3;
238bd497fc9STimur Tabi }
239bd497fc9STimur Tabi
240bd497fc9STimur Tabi #define FH_PARTITION_STOPPED 0
241bd497fc9STimur Tabi #define FH_PARTITION_RUNNING 1
242bd497fc9STimur Tabi #define FH_PARTITION_STARTING 2
243bd497fc9STimur Tabi #define FH_PARTITION_STOPPING 3
244bd497fc9STimur Tabi #define FH_PARTITION_PAUSING 4
245bd497fc9STimur Tabi #define FH_PARTITION_PAUSED 5
246bd497fc9STimur Tabi #define FH_PARTITION_RESUMING 6
247bd497fc9STimur Tabi
248bd497fc9STimur Tabi /**
249bd497fc9STimur Tabi * fh_partition_get_status - gets the status of a partition
250bd497fc9STimur Tabi * @partition: partition ID
251bd497fc9STimur Tabi * @status: returned status code
252bd497fc9STimur Tabi *
253bd497fc9STimur Tabi * Returns 0 for success, or an error code.
254bd497fc9STimur Tabi */
fh_partition_get_status(unsigned int partition,unsigned int * status)255bd497fc9STimur Tabi static inline unsigned int fh_partition_get_status(unsigned int partition,
256bd497fc9STimur Tabi unsigned int *status)
257bd497fc9STimur Tabi {
258bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
259bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
260bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
261bd497fc9STimur Tabi
262bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_STATUS);
263bd497fc9STimur Tabi r3 = partition;
264bd497fc9STimur Tabi
2658e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
266bd497fc9STimur Tabi : "+r" (r11), "+r" (r3), "=r" (r4)
267bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS2
268bd497fc9STimur Tabi );
269bd497fc9STimur Tabi
270bd497fc9STimur Tabi *status = r4;
271bd497fc9STimur Tabi
272bd497fc9STimur Tabi return r3;
273bd497fc9STimur Tabi }
274bd497fc9STimur Tabi
275bd497fc9STimur Tabi /**
276bd497fc9STimur Tabi * fh_partition_start - boots and starts execution of the specified partition
277bd497fc9STimur Tabi * @partition: partition ID
278bd497fc9STimur Tabi * @entry_point: guest physical address to start execution
279bd497fc9STimur Tabi *
280bd497fc9STimur Tabi * The hypervisor creates a 1-to-1 virtual/physical IMA mapping, so at boot
281bd497fc9STimur Tabi * time, guest physical address are the same as guest virtual addresses.
282bd497fc9STimur Tabi *
283bd497fc9STimur Tabi * Returns 0 for success, or an error code.
284bd497fc9STimur Tabi */
fh_partition_start(unsigned int partition,uint32_t entry_point,int load)285bd497fc9STimur Tabi static inline unsigned int fh_partition_start(unsigned int partition,
286bd497fc9STimur Tabi uint32_t entry_point, int load)
287bd497fc9STimur Tabi {
288bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
289bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
290bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
291bd497fc9STimur Tabi register uintptr_t r5 __asm__("r5");
292bd497fc9STimur Tabi
293bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_START);
294bd497fc9STimur Tabi r3 = partition;
295bd497fc9STimur Tabi r4 = entry_point;
296bd497fc9STimur Tabi r5 = load;
297bd497fc9STimur Tabi
2988e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
299bd497fc9STimur Tabi : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5)
300bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS3
301bd497fc9STimur Tabi );
302bd497fc9STimur Tabi
303bd497fc9STimur Tabi return r3;
304bd497fc9STimur Tabi }
305bd497fc9STimur Tabi
306bd497fc9STimur Tabi /**
307bd497fc9STimur Tabi * fh_partition_stop - stops another partition
308bd497fc9STimur Tabi * @partition: partition ID
309bd497fc9STimur Tabi *
310bd497fc9STimur Tabi * Returns 0 for success, or an error code.
311bd497fc9STimur Tabi */
fh_partition_stop(unsigned int partition)312bd497fc9STimur Tabi static inline unsigned int fh_partition_stop(unsigned int partition)
313bd497fc9STimur Tabi {
314bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
315bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
316bd497fc9STimur Tabi
317bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP);
318bd497fc9STimur Tabi r3 = partition;
319bd497fc9STimur Tabi
3208e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
321bd497fc9STimur Tabi : "+r" (r11), "+r" (r3)
322bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
323bd497fc9STimur Tabi );
324bd497fc9STimur Tabi
325bd497fc9STimur Tabi return r3;
326bd497fc9STimur Tabi }
327bd497fc9STimur Tabi
328bd497fc9STimur Tabi /**
329bd497fc9STimur Tabi * struct fh_sg_list: definition of the fh_partition_memcpy S/G list
330bd497fc9STimur Tabi * @source: guest physical address to copy from
331bd497fc9STimur Tabi * @target: guest physical address to copy to
332bd497fc9STimur Tabi * @size: number of bytes to copy
333bd497fc9STimur Tabi * @reserved: reserved, must be zero
334bd497fc9STimur Tabi *
335bd497fc9STimur Tabi * The scatter/gather list for fh_partition_memcpy() is an array of these
336bd497fc9STimur Tabi * structures. The array must be guest physically contiguous.
337bd497fc9STimur Tabi *
338bd497fc9STimur Tabi * This structure must be aligned on 32-byte boundary, so that no single
339bd497fc9STimur Tabi * strucuture can span two pages.
340bd497fc9STimur Tabi */
341bd497fc9STimur Tabi struct fh_sg_list {
342bd497fc9STimur Tabi uint64_t source; /**< guest physical address to copy from */
343bd497fc9STimur Tabi uint64_t target; /**< guest physical address to copy to */
344bd497fc9STimur Tabi uint64_t size; /**< number of bytes to copy */
345bd497fc9STimur Tabi uint64_t reserved; /**< reserved, must be zero */
346bd497fc9STimur Tabi } __attribute__ ((aligned(32)));
347bd497fc9STimur Tabi
348bd497fc9STimur Tabi /**
349bd497fc9STimur Tabi * fh_partition_memcpy - copies data from one guest to another
350bd497fc9STimur Tabi * @source: the ID of the partition to copy from
351bd497fc9STimur Tabi * @target: the ID of the partition to copy to
352bd497fc9STimur Tabi * @sg_list: guest physical address of an array of &fh_sg_list structures
353bd497fc9STimur Tabi * @count: the number of entries in @sg_list
354bd497fc9STimur Tabi *
355bd497fc9STimur Tabi * Returns 0 for success, or an error code.
356bd497fc9STimur Tabi */
fh_partition_memcpy(unsigned int source,unsigned int target,phys_addr_t sg_list,unsigned int count)357bd497fc9STimur Tabi static inline unsigned int fh_partition_memcpy(unsigned int source,
358bd497fc9STimur Tabi unsigned int target, phys_addr_t sg_list, unsigned int count)
359bd497fc9STimur Tabi {
360bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
361bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
362bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
363bd497fc9STimur Tabi register uintptr_t r5 __asm__("r5");
364bd497fc9STimur Tabi register uintptr_t r6 __asm__("r6");
365bd497fc9STimur Tabi register uintptr_t r7 __asm__("r7");
366bd497fc9STimur Tabi
367bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_MEMCPY);
368bd497fc9STimur Tabi r3 = source;
369bd497fc9STimur Tabi r4 = target;
370bd497fc9STimur Tabi r5 = (uint32_t) sg_list;
371bd497fc9STimur Tabi
372bd497fc9STimur Tabi #ifdef CONFIG_PHYS_64BIT
373bd497fc9STimur Tabi r6 = sg_list >> 32;
374bd497fc9STimur Tabi #else
375bd497fc9STimur Tabi r6 = 0;
376bd497fc9STimur Tabi #endif
377bd497fc9STimur Tabi r7 = count;
378bd497fc9STimur Tabi
3798e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
380bd497fc9STimur Tabi : "+r" (r11),
381bd497fc9STimur Tabi "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7)
382bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS5
383bd497fc9STimur Tabi );
384bd497fc9STimur Tabi
385bd497fc9STimur Tabi return r3;
386bd497fc9STimur Tabi }
387bd497fc9STimur Tabi
388bd497fc9STimur Tabi /**
389bd497fc9STimur Tabi * fh_dma_enable - enable DMA for the specified device
390bd497fc9STimur Tabi * @liodn: the LIODN of the I/O device for which to enable DMA
391bd497fc9STimur Tabi *
392bd497fc9STimur Tabi * Returns 0 for success, or an error code.
393bd497fc9STimur Tabi */
fh_dma_enable(unsigned int liodn)394bd497fc9STimur Tabi static inline unsigned int fh_dma_enable(unsigned int liodn)
395bd497fc9STimur Tabi {
396bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
397bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
398bd497fc9STimur Tabi
399bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_DMA_ENABLE);
400bd497fc9STimur Tabi r3 = liodn;
401bd497fc9STimur Tabi
4028e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
403bd497fc9STimur Tabi : "+r" (r11), "+r" (r3)
404bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
405bd497fc9STimur Tabi );
406bd497fc9STimur Tabi
407bd497fc9STimur Tabi return r3;
408bd497fc9STimur Tabi }
409bd497fc9STimur Tabi
410bd497fc9STimur Tabi /**
411bd497fc9STimur Tabi * fh_dma_disable - disable DMA for the specified device
412bd497fc9STimur Tabi * @liodn: the LIODN of the I/O device for which to disable DMA
413bd497fc9STimur Tabi *
414bd497fc9STimur Tabi * Returns 0 for success, or an error code.
415bd497fc9STimur Tabi */
fh_dma_disable(unsigned int liodn)416bd497fc9STimur Tabi static inline unsigned int fh_dma_disable(unsigned int liodn)
417bd497fc9STimur Tabi {
418bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
419bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
420bd497fc9STimur Tabi
421bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_DMA_DISABLE);
422bd497fc9STimur Tabi r3 = liodn;
423bd497fc9STimur Tabi
4248e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
425bd497fc9STimur Tabi : "+r" (r11), "+r" (r3)
426bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
427bd497fc9STimur Tabi );
428bd497fc9STimur Tabi
429bd497fc9STimur Tabi return r3;
430bd497fc9STimur Tabi }
431bd497fc9STimur Tabi
432bd497fc9STimur Tabi
433bd497fc9STimur Tabi /**
434bd497fc9STimur Tabi * fh_vmpic_get_msir - returns the MPIC-MSI register value
435bd497fc9STimur Tabi * @interrupt: the interrupt number
436bd497fc9STimur Tabi * @msir_val: returned MPIC-MSI register value
437bd497fc9STimur Tabi *
438bd497fc9STimur Tabi * Returns 0 for success, or an error code.
439bd497fc9STimur Tabi */
fh_vmpic_get_msir(unsigned int interrupt,unsigned int * msir_val)440bd497fc9STimur Tabi static inline unsigned int fh_vmpic_get_msir(unsigned int interrupt,
441bd497fc9STimur Tabi unsigned int *msir_val)
442bd497fc9STimur Tabi {
443bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
444bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
445bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
446bd497fc9STimur Tabi
447bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_VMPIC_GET_MSIR);
448bd497fc9STimur Tabi r3 = interrupt;
449bd497fc9STimur Tabi
4508e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
451bd497fc9STimur Tabi : "+r" (r11), "+r" (r3), "=r" (r4)
452bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS2
453bd497fc9STimur Tabi );
454bd497fc9STimur Tabi
455bd497fc9STimur Tabi *msir_val = r4;
456bd497fc9STimur Tabi
457bd497fc9STimur Tabi return r3;
458bd497fc9STimur Tabi }
459bd497fc9STimur Tabi
460bd497fc9STimur Tabi /**
461bd497fc9STimur Tabi * fh_system_reset - reset the system
462bd497fc9STimur Tabi *
463bd497fc9STimur Tabi * Returns 0 for success, or an error code.
464bd497fc9STimur Tabi */
fh_system_reset(void)465bd497fc9STimur Tabi static inline unsigned int fh_system_reset(void)
466bd497fc9STimur Tabi {
467bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
468bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
469bd497fc9STimur Tabi
470bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_SYSTEM_RESET);
471bd497fc9STimur Tabi
4728e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
473bd497fc9STimur Tabi : "+r" (r11), "=r" (r3)
474bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
475bd497fc9STimur Tabi );
476bd497fc9STimur Tabi
477bd497fc9STimur Tabi return r3;
478bd497fc9STimur Tabi }
479bd497fc9STimur Tabi
480bd497fc9STimur Tabi
481bd497fc9STimur Tabi /**
482bd497fc9STimur Tabi * fh_err_get_info - get platform error information
483bd497fc9STimur Tabi * @queue id:
484bd497fc9STimur Tabi * 0 for guest error event queue
485bd497fc9STimur Tabi * 1 for global error event queue
486bd497fc9STimur Tabi *
487bd497fc9STimur Tabi * @pointer to store the platform error data:
488bd497fc9STimur Tabi * platform error data is returned in registers r4 - r11
489bd497fc9STimur Tabi *
490bd497fc9STimur Tabi * Returns 0 for success, or an error code.
491bd497fc9STimur Tabi */
fh_err_get_info(int queue,uint32_t * bufsize,uint32_t addr_hi,uint32_t addr_lo,int peek)492bd497fc9STimur Tabi static inline unsigned int fh_err_get_info(int queue, uint32_t *bufsize,
493bd497fc9STimur Tabi uint32_t addr_hi, uint32_t addr_lo, int peek)
494bd497fc9STimur Tabi {
495bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
496bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
497bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
498bd497fc9STimur Tabi register uintptr_t r5 __asm__("r5");
499bd497fc9STimur Tabi register uintptr_t r6 __asm__("r6");
500bd497fc9STimur Tabi register uintptr_t r7 __asm__("r7");
501bd497fc9STimur Tabi
502bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_ERR_GET_INFO);
503bd497fc9STimur Tabi r3 = queue;
504bd497fc9STimur Tabi r4 = *bufsize;
505bd497fc9STimur Tabi r5 = addr_hi;
506bd497fc9STimur Tabi r6 = addr_lo;
507bd497fc9STimur Tabi r7 = peek;
508bd497fc9STimur Tabi
5098e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
510bd497fc9STimur Tabi : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6),
511bd497fc9STimur Tabi "+r" (r7)
512bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS5
513bd497fc9STimur Tabi );
514bd497fc9STimur Tabi
515bd497fc9STimur Tabi *bufsize = r4;
516bd497fc9STimur Tabi
517bd497fc9STimur Tabi return r3;
518bd497fc9STimur Tabi }
519bd497fc9STimur Tabi
520bd497fc9STimur Tabi
521bd497fc9STimur Tabi #define FH_VCPU_RUN 0
522bd497fc9STimur Tabi #define FH_VCPU_IDLE 1
523bd497fc9STimur Tabi #define FH_VCPU_NAP 2
524bd497fc9STimur Tabi
525bd497fc9STimur Tabi /**
526bd497fc9STimur Tabi * fh_get_core_state - get the state of a vcpu
527bd497fc9STimur Tabi *
528bd497fc9STimur Tabi * @handle: handle of partition containing the vcpu
529bd497fc9STimur Tabi * @vcpu: vcpu number within the partition
530bd497fc9STimur Tabi * @state:the current state of the vcpu, see FH_VCPU_*
531bd497fc9STimur Tabi *
532bd497fc9STimur Tabi * Returns 0 for success, or an error code.
533bd497fc9STimur Tabi */
fh_get_core_state(unsigned int handle,unsigned int vcpu,unsigned int * state)534bd497fc9STimur Tabi static inline unsigned int fh_get_core_state(unsigned int handle,
535bd497fc9STimur Tabi unsigned int vcpu, unsigned int *state)
536bd497fc9STimur Tabi {
537bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
538bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
539bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
540bd497fc9STimur Tabi
541bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_GET_CORE_STATE);
542bd497fc9STimur Tabi r3 = handle;
543bd497fc9STimur Tabi r4 = vcpu;
544bd497fc9STimur Tabi
5458e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
546bd497fc9STimur Tabi : "+r" (r11), "+r" (r3), "+r" (r4)
547bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS2
548bd497fc9STimur Tabi );
549bd497fc9STimur Tabi
550bd497fc9STimur Tabi *state = r4;
551bd497fc9STimur Tabi return r3;
552bd497fc9STimur Tabi }
553bd497fc9STimur Tabi
554bd497fc9STimur Tabi /**
555bd497fc9STimur Tabi * fh_enter_nap - enter nap on a vcpu
556bd497fc9STimur Tabi *
557bd497fc9STimur Tabi * Note that though the API supports entering nap on a vcpu other
558bd497fc9STimur Tabi * than the caller, this may not be implmented and may return EINVAL.
559bd497fc9STimur Tabi *
560bd497fc9STimur Tabi * @handle: handle of partition containing the vcpu
561bd497fc9STimur Tabi * @vcpu: vcpu number within the partition
562bd497fc9STimur Tabi *
563bd497fc9STimur Tabi * Returns 0 for success, or an error code.
564bd497fc9STimur Tabi */
fh_enter_nap(unsigned int handle,unsigned int vcpu)565bd497fc9STimur Tabi static inline unsigned int fh_enter_nap(unsigned int handle, unsigned int vcpu)
566bd497fc9STimur Tabi {
567bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
568bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
569bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
570bd497fc9STimur Tabi
571bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_ENTER_NAP);
572bd497fc9STimur Tabi r3 = handle;
573bd497fc9STimur Tabi r4 = vcpu;
574bd497fc9STimur Tabi
5758e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
576bd497fc9STimur Tabi : "+r" (r11), "+r" (r3), "+r" (r4)
577bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS2
578bd497fc9STimur Tabi );
579bd497fc9STimur Tabi
580bd497fc9STimur Tabi return r3;
581bd497fc9STimur Tabi }
582bd497fc9STimur Tabi
583bd497fc9STimur Tabi /**
584bd497fc9STimur Tabi * fh_exit_nap - exit nap on a vcpu
585bd497fc9STimur Tabi * @handle: handle of partition containing the vcpu
586bd497fc9STimur Tabi * @vcpu: vcpu number within the partition
587bd497fc9STimur Tabi *
588bd497fc9STimur Tabi * Returns 0 for success, or an error code.
589bd497fc9STimur Tabi */
fh_exit_nap(unsigned int handle,unsigned int vcpu)590bd497fc9STimur Tabi static inline unsigned int fh_exit_nap(unsigned int handle, unsigned int vcpu)
591bd497fc9STimur Tabi {
592bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
593bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
594bd497fc9STimur Tabi register uintptr_t r4 __asm__("r4");
595bd497fc9STimur Tabi
596bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_EXIT_NAP);
597bd497fc9STimur Tabi r3 = handle;
598bd497fc9STimur Tabi r4 = vcpu;
599bd497fc9STimur Tabi
6008e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
601bd497fc9STimur Tabi : "+r" (r11), "+r" (r3), "+r" (r4)
602bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS2
603bd497fc9STimur Tabi );
604bd497fc9STimur Tabi
605bd497fc9STimur Tabi return r3;
606bd497fc9STimur Tabi }
607bd497fc9STimur Tabi /**
608bd497fc9STimur Tabi * fh_claim_device - claim a "claimable" shared device
609bd497fc9STimur Tabi * @handle: fsl,hv-device-handle of node to claim
610bd497fc9STimur Tabi *
611bd497fc9STimur Tabi * Returns 0 for success, or an error code.
612bd497fc9STimur Tabi */
fh_claim_device(unsigned int handle)613bd497fc9STimur Tabi static inline unsigned int fh_claim_device(unsigned int handle)
614bd497fc9STimur Tabi {
615bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
616bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
617bd497fc9STimur Tabi
618bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_CLAIM_DEVICE);
619bd497fc9STimur Tabi r3 = handle;
620bd497fc9STimur Tabi
6218e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
622bd497fc9STimur Tabi : "+r" (r11), "+r" (r3)
623bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
624bd497fc9STimur Tabi );
625bd497fc9STimur Tabi
626bd497fc9STimur Tabi return r3;
627bd497fc9STimur Tabi }
628bd497fc9STimur Tabi
629bd497fc9STimur Tabi /**
630bd497fc9STimur Tabi * Run deferred DMA disabling on a partition's private devices
631bd497fc9STimur Tabi *
632bd497fc9STimur Tabi * This applies to devices which a partition owns either privately,
633bd497fc9STimur Tabi * or which are claimable and still actively owned by that partition,
634bd497fc9STimur Tabi * and which do not have the no-dma-disable property.
635bd497fc9STimur Tabi *
636bd497fc9STimur Tabi * @handle: partition (must be stopped) whose DMA is to be disabled
637bd497fc9STimur Tabi *
638bd497fc9STimur Tabi * Returns 0 for success, or an error code.
639bd497fc9STimur Tabi */
fh_partition_stop_dma(unsigned int handle)640bd497fc9STimur Tabi static inline unsigned int fh_partition_stop_dma(unsigned int handle)
641bd497fc9STimur Tabi {
642bd497fc9STimur Tabi register uintptr_t r11 __asm__("r11");
643bd497fc9STimur Tabi register uintptr_t r3 __asm__("r3");
644bd497fc9STimur Tabi
645bd497fc9STimur Tabi r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP_DMA);
646bd497fc9STimur Tabi r3 = handle;
647bd497fc9STimur Tabi
6488e525d59SLiu Yu-B13201 asm volatile("bl epapr_hypercall_start"
649bd497fc9STimur Tabi : "+r" (r11), "+r" (r3)
650bd497fc9STimur Tabi : : EV_HCALL_CLOBBERS1
651bd497fc9STimur Tabi );
652bd497fc9STimur Tabi
653bd497fc9STimur Tabi return r3;
654bd497fc9STimur Tabi }
655bd497fc9STimur Tabi #endif
656