Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fsl_hcalls.h
Go to the documentation of this file.
1 /*
2  * Freescale hypervisor call interface
3  *
4  * Copyright 2008-2010 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 #ifndef _FSL_HCALLS_H
41 #define _FSL_HCALLS_H
42 
43 #include <linux/types.h>
44 #include <linux/errno.h>
45 #include <asm/byteorder.h>
46 #include <asm/epapr_hcalls.h>
47 
48 #define FH_API_VERSION 1
49 
50 #define FH_ERR_GET_INFO 1
51 #define FH_PARTITION_GET_DTPROP 2
52 #define FH_PARTITION_SET_DTPROP 3
53 #define FH_PARTITION_RESTART 4
54 #define FH_PARTITION_GET_STATUS 5
55 #define FH_PARTITION_START 6
56 #define FH_PARTITION_STOP 7
57 #define FH_PARTITION_MEMCPY 8
58 #define FH_DMA_ENABLE 9
59 #define FH_DMA_DISABLE 10
60 #define FH_SEND_NMI 11
61 #define FH_VMPIC_GET_MSIR 12
62 #define FH_SYSTEM_RESET 13
63 #define FH_GET_CORE_STATE 14
64 #define FH_ENTER_NAP 15
65 #define FH_EXIT_NAP 16
66 #define FH_CLAIM_DEVICE 17
67 #define FH_PARTITION_STOP_DMA 18
68 
69 /* vendor ID: Freescale Semiconductor */
70 #define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num)
71 
72 /*
73  * We use "uintptr_t" to define a register because it's guaranteed to be a
74  * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
75  * platform.
76  *
77  * All registers are either input/output or output only. Registers that are
78  * initialized before making the hypercall are input/output. All
79  * input/output registers are represented with "+r". Output-only registers
80  * are represented with "=r". Do not specify any unused registers. The
81  * clobber list will tell the compiler that the hypercall modifies those
82  * registers, which is good enough.
83  */
84 
91 static inline unsigned int fh_send_nmi(unsigned int vcpu_mask)
92 {
93  register uintptr_t r11 __asm__("r11");
94  register uintptr_t r3 __asm__("r3");
95 
97  r3 = vcpu_mask;
98 
99  __asm__ __volatile__ ("sc 1"
100  : "+r" (r11), "+r" (r3)
102  );
103 
104  return r3;
105 }
106 
107 /* Arbitrary limits to avoid excessive memory allocation in hypervisor */
108 #define FH_DTPROP_MAX_PATHLEN 4096
109 #define FH_DTPROP_MAX_PROPLEN 32768
110 
121 static inline unsigned int fh_partition_get_dtprop(int handle,
122  uint64_t dtpath_addr,
123  uint64_t propname_addr,
124  uint64_t propvalue_addr,
125  uint32_t *propvalue_len)
126 {
127  register uintptr_t r11 __asm__("r11");
128  register uintptr_t r3 __asm__("r3");
129  register uintptr_t r4 __asm__("r4");
130  register uintptr_t r5 __asm__("r5");
131  register uintptr_t r6 __asm__("r6");
132  register uintptr_t r7 __asm__("r7");
133  register uintptr_t r8 __asm__("r8");
134  register uintptr_t r9 __asm__("r9");
135  register uintptr_t r10 __asm__("r10");
136 
138  r3 = handle;
139 
140 #ifdef CONFIG_PHYS_64BIT
141  r4 = dtpath_addr >> 32;
142  r6 = propname_addr >> 32;
143  r8 = propvalue_addr >> 32;
144 #else
145  r4 = 0;
146  r6 = 0;
147  r8 = 0;
148 #endif
149  r5 = (uint32_t)dtpath_addr;
150  r7 = (uint32_t)propname_addr;
151  r9 = (uint32_t)propvalue_addr;
152  r10 = *propvalue_len;
153 
154  __asm__ __volatile__ ("sc 1"
155  : "+r" (r11),
156  "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
157  "+r" (r8), "+r" (r9), "+r" (r10)
159  );
160 
161  *propvalue_len = r4;
162  return r3;
163 }
164 
175 static inline unsigned int fh_partition_set_dtprop(int handle,
176  uint64_t dtpath_addr,
177  uint64_t propname_addr,
178  uint64_t propvalue_addr,
179  uint32_t propvalue_len)
180 {
181  register uintptr_t r11 __asm__("r11");
182  register uintptr_t r3 __asm__("r3");
183  register uintptr_t r4 __asm__("r4");
184  register uintptr_t r6 __asm__("r6");
185  register uintptr_t r8 __asm__("r8");
186  register uintptr_t r5 __asm__("r5");
187  register uintptr_t r7 __asm__("r7");
188  register uintptr_t r9 __asm__("r9");
189  register uintptr_t r10 __asm__("r10");
190 
192  r3 = handle;
193 
194 #ifdef CONFIG_PHYS_64BIT
195  r4 = dtpath_addr >> 32;
196  r6 = propname_addr >> 32;
197  r8 = propvalue_addr >> 32;
198 #else
199  r4 = 0;
200  r6 = 0;
201  r8 = 0;
202 #endif
203  r5 = (uint32_t)dtpath_addr;
204  r7 = (uint32_t)propname_addr;
205  r9 = (uint32_t)propvalue_addr;
206  r10 = propvalue_len;
207 
208  __asm__ __volatile__ ("sc 1"
209  : "+r" (r11),
210  "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
211  "+r" (r8), "+r" (r9), "+r" (r10)
213  );
214 
215  return r3;
216 }
217 
224 static inline unsigned int fh_partition_restart(unsigned int partition)
225 {
226  register uintptr_t r11 __asm__("r11");
227  register uintptr_t r3 __asm__("r3");
228 
230  r3 = partition;
231 
232  __asm__ __volatile__ ("sc 1"
233  : "+r" (r11), "+r" (r3)
235  );
236 
237  return r3;
238 }
239 
240 #define FH_PARTITION_STOPPED 0
241 #define FH_PARTITION_RUNNING 1
242 #define FH_PARTITION_STARTING 2
243 #define FH_PARTITION_STOPPING 3
244 #define FH_PARTITION_PAUSING 4
245 #define FH_PARTITION_PAUSED 5
246 #define FH_PARTITION_RESUMING 6
247 
255 static inline unsigned int fh_partition_get_status(unsigned int partition,
256  unsigned int *status)
257 {
258  register uintptr_t r11 __asm__("r11");
259  register uintptr_t r3 __asm__("r3");
260  register uintptr_t r4 __asm__("r4");
261 
263  r3 = partition;
264 
265  __asm__ __volatile__ ("sc 1"
266  : "+r" (r11), "+r" (r3), "=r" (r4)
268  );
269 
270  *status = r4;
271 
272  return r3;
273 }
274 
285 static inline unsigned int fh_partition_start(unsigned int partition,
286  uint32_t entry_point, int load)
287 {
288  register uintptr_t r11 __asm__("r11");
289  register uintptr_t r3 __asm__("r3");
290  register uintptr_t r4 __asm__("r4");
291  register uintptr_t r5 __asm__("r5");
292 
294  r3 = partition;
295  r4 = entry_point;
296  r5 = load;
297 
298  __asm__ __volatile__ ("sc 1"
299  : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5)
301  );
302 
303  return r3;
304 }
305 
312 static inline unsigned int fh_partition_stop(unsigned int partition)
313 {
314  register uintptr_t r11 __asm__("r11");
315  register uintptr_t r3 __asm__("r3");
316 
318  r3 = partition;
319 
320  __asm__ __volatile__ ("sc 1"
321  : "+r" (r11), "+r" (r3)
323  );
324 
325  return r3;
326 }
327 
341 struct fh_sg_list {
346 } __attribute__ ((aligned(32)));
357 static inline unsigned int fh_partition_memcpy(unsigned int source,
358  unsigned int target, phys_addr_t sg_list, unsigned int count)
359 {
360  register uintptr_t r11 __asm__("r11");
361  register uintptr_t r3 __asm__("r3");
362  register uintptr_t r4 __asm__("r4");
363  register uintptr_t r5 __asm__("r5");
364  register uintptr_t r6 __asm__("r6");
365  register uintptr_t r7 __asm__("r7");
366 
368  r3 = source;
369  r4 = target;
370  r5 = (uint32_t) sg_list;
371 
372 #ifdef CONFIG_PHYS_64BIT
373  r6 = sg_list >> 32;
374 #else
375  r6 = 0;
376 #endif
377  r7 = count;
378 
379  __asm__ __volatile__ ("sc 1"
380  : "+r" (r11),
381  "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7)
383  );
384 
385  return r3;
386 }
387 
394 static inline unsigned int fh_dma_enable(unsigned int liodn)
395 {
396  register uintptr_t r11 __asm__("r11");
397  register uintptr_t r3 __asm__("r3");
398 
400  r3 = liodn;
401 
402  __asm__ __volatile__ ("sc 1"
403  : "+r" (r11), "+r" (r3)
405  );
406 
407  return r3;
408 }
409 
416 static inline unsigned int fh_dma_disable(unsigned int liodn)
417 {
418  register uintptr_t r11 __asm__("r11");
419  register uintptr_t r3 __asm__("r3");
420 
422  r3 = liodn;
423 
424  __asm__ __volatile__ ("sc 1"
425  : "+r" (r11), "+r" (r3)
427  );
428 
429  return r3;
430 }
431 
432 
440 static inline unsigned int fh_vmpic_get_msir(unsigned int interrupt,
441  unsigned int *msir_val)
442 {
443  register uintptr_t r11 __asm__("r11");
444  register uintptr_t r3 __asm__("r3");
445  register uintptr_t r4 __asm__("r4");
446 
448  r3 = interrupt;
449 
450  __asm__ __volatile__ ("sc 1"
451  : "+r" (r11), "+r" (r3), "=r" (r4)
453  );
454 
455  *msir_val = r4;
456 
457  return r3;
458 }
459 
465 static inline unsigned int fh_system_reset(void)
466 {
467  register uintptr_t r11 __asm__("r11");
468  register uintptr_t r3 __asm__("r3");
469 
471 
472  __asm__ __volatile__ ("sc 1"
473  : "+r" (r11), "=r" (r3)
475  );
476 
477  return r3;
478 }
479 
480 
492 static inline unsigned int fh_err_get_info(int queue, uint32_t *bufsize,
493  uint32_t addr_hi, uint32_t addr_lo, int peek)
494 {
495  register uintptr_t r11 __asm__("r11");
496  register uintptr_t r3 __asm__("r3");
497  register uintptr_t r4 __asm__("r4");
498  register uintptr_t r5 __asm__("r5");
499  register uintptr_t r6 __asm__("r6");
500  register uintptr_t r7 __asm__("r7");
501 
503  r3 = queue;
504  r4 = *bufsize;
505  r5 = addr_hi;
506  r6 = addr_lo;
507  r7 = peek;
508 
509  __asm__ __volatile__ ("sc 1"
510  : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6),
511  "+r" (r7)
513  );
514 
515  *bufsize = r4;
516 
517  return r3;
518 }
519 
520 
521 #define FH_VCPU_RUN 0
522 #define FH_VCPU_IDLE 1
523 #define FH_VCPU_NAP 2
524 
534 static inline unsigned int fh_get_core_state(unsigned int handle,
535  unsigned int vcpu, unsigned int *state)
536 {
537  register uintptr_t r11 __asm__("r11");
538  register uintptr_t r3 __asm__("r3");
539  register uintptr_t r4 __asm__("r4");
540 
542  r3 = handle;
543  r4 = vcpu;
544 
545  __asm__ __volatile__ ("sc 1"
546  : "+r" (r11), "+r" (r3), "+r" (r4)
548  );
549 
550  *state = r4;
551  return r3;
552 }
553 
565 static inline unsigned int fh_enter_nap(unsigned int handle, unsigned int vcpu)
566 {
567  register uintptr_t r11 __asm__("r11");
568  register uintptr_t r3 __asm__("r3");
569  register uintptr_t r4 __asm__("r4");
570 
572  r3 = handle;
573  r4 = vcpu;
574 
575  __asm__ __volatile__ ("sc 1"
576  : "+r" (r11), "+r" (r3), "+r" (r4)
578  );
579 
580  return r3;
581 }
582 
590 static inline unsigned int fh_exit_nap(unsigned int handle, unsigned int vcpu)
591 {
592  register uintptr_t r11 __asm__("r11");
593  register uintptr_t r3 __asm__("r3");
594  register uintptr_t r4 __asm__("r4");
595 
597  r3 = handle;
598  r4 = vcpu;
599 
600  __asm__ __volatile__ ("sc 1"
601  : "+r" (r11), "+r" (r3), "+r" (r4)
603  );
604 
605  return r3;
606 }
613 static inline unsigned int fh_claim_device(unsigned int handle)
614 {
615  register uintptr_t r11 __asm__("r11");
616  register uintptr_t r3 __asm__("r3");
617 
619  r3 = handle;
620 
621  __asm__ __volatile__ ("sc 1"
622  : "+r" (r11), "+r" (r3)
624  );
625 
626  return r3;
627 }
628 
640 static inline unsigned int fh_partition_stop_dma(unsigned int handle)
641 {
642  register uintptr_t r11 __asm__("r11");
643  register uintptr_t r3 __asm__("r3");
644 
646  r3 = handle;
647 
648  __asm__ __volatile__ ("sc 1"
649  : "+r" (r11), "+r" (r3)
651  );
652 
653  return r3;
654 }
655 #endif