RTEMS  5.1
fsl_hcalls.h
1 /*
2  * Freescale hypervisor call interface
3  *
4  * Copyright 2008-2010 Freescale Semiconductor, Inc.
5  *
6  * Author: Timur Tabi <timur@freescale.com>
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 <stdint.h>
44 #include <asm/epapr_hcalls.h>
45 
46 #define FH_API_VERSION 1
47 
48 #define FH_ERR_GET_INFO 1
49 #define FH_PARTITION_GET_DTPROP 2
50 #define FH_PARTITION_SET_DTPROP 3
51 #define FH_PARTITION_RESTART 4
52 #define FH_PARTITION_GET_STATUS 5
53 #define FH_PARTITION_START 6
54 #define FH_PARTITION_STOP 7
55 #define FH_PARTITION_MEMCPY 8
56 #define FH_DMA_ENABLE 9
57 #define FH_DMA_DISABLE 10
58 #define FH_SEND_NMI 11
59 #define FH_VMPIC_GET_MSIR 12
60 #define FH_SYSTEM_RESET 13
61 #define FH_GET_CORE_STATE 14
62 #define FH_ENTER_NAP 15
63 #define FH_EXIT_NAP 16
64 #define FH_CLAIM_DEVICE 17
65 #define FH_PARTITION_STOP_DMA 18
66 
67 /* vendor ID: Freescale Semiconductor */
68 #define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num)
69 
70 /*
71  * We use "uintptr_t" to define a register because it's guaranteed to be a
72  * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
73  * platform.
74  *
75  * All registers are either input/output or output only. Registers that are
76  * initialized before making the hypercall are input/output. All
77  * input/output registers are represented with "+r". Output-only registers
78  * are represented with "=r". Do not specify any unused registers. The
79  * clobber list will tell the compiler that the hypercall modifies those
80  * registers, which is good enough.
81  */
82 
89 static inline unsigned int fh_send_nmi(unsigned int vcpu_mask)
90 {
91  register uintptr_t r11 __asm__("r11");
92  register uintptr_t r3 __asm__("r3");
93 
94  r11 = FH_HCALL_TOKEN(FH_SEND_NMI);
95  r3 = vcpu_mask;
96 
97  asm volatile("bl epapr_hypercall_start"
98  : "+r" (r11), "+r" (r3)
99  : : EV_HCALL_CLOBBERS1
100  );
101 
102  return r3;
103 }
104 
105 /* Arbitrary limits to avoid excessive memory allocation in hypervisor */
106 #define FH_DTPROP_MAX_PATHLEN 4096
107 #define FH_DTPROP_MAX_PROPLEN 32768
108 
119 static inline unsigned int fh_partition_get_dtprop(int handle,
120  uint64_t dtpath_addr,
121  uint64_t propname_addr,
122  uint64_t propvalue_addr,
123  uint32_t *propvalue_len)
124 {
125  register uintptr_t r11 __asm__("r11");
126  register uintptr_t r3 __asm__("r3");
127  register uintptr_t r4 __asm__("r4");
128  register uintptr_t r5 __asm__("r5");
129  register uintptr_t r6 __asm__("r6");
130  register uintptr_t r7 __asm__("r7");
131  register uintptr_t r8 __asm__("r8");
132  register uintptr_t r9 __asm__("r9");
133  register uintptr_t r10 __asm__("r10");
134 
135  r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_DTPROP);
136  r3 = handle;
137 
138 #ifdef CONFIG_PHYS_64BIT
139  r4 = dtpath_addr >> 32;
140  r6 = propname_addr >> 32;
141  r8 = propvalue_addr >> 32;
142 #else
143  r4 = 0;
144  r6 = 0;
145  r8 = 0;
146 #endif
147  r5 = (uint32_t)dtpath_addr;
148  r7 = (uint32_t)propname_addr;
149  r9 = (uint32_t)propvalue_addr;
150  r10 = *propvalue_len;
151 
152  asm volatile("bl epapr_hypercall_start"
153  : "+r" (r11),
154  "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
155  "+r" (r8), "+r" (r9), "+r" (r10)
156  : : EV_HCALL_CLOBBERS8
157  );
158 
159  *propvalue_len = r4;
160  return r3;
161 }
162 
173 static inline unsigned int fh_partition_set_dtprop(int handle,
174  uint64_t dtpath_addr,
175  uint64_t propname_addr,
176  uint64_t propvalue_addr,
177  uint32_t propvalue_len)
178 {
179  register uintptr_t r11 __asm__("r11");
180  register uintptr_t r3 __asm__("r3");
181  register uintptr_t r4 __asm__("r4");
182  register uintptr_t r6 __asm__("r6");
183  register uintptr_t r8 __asm__("r8");
184  register uintptr_t r5 __asm__("r5");
185  register uintptr_t r7 __asm__("r7");
186  register uintptr_t r9 __asm__("r9");
187  register uintptr_t r10 __asm__("r10");
188 
189  r11 = FH_HCALL_TOKEN(FH_PARTITION_SET_DTPROP);
190  r3 = handle;
191 
192 #ifdef CONFIG_PHYS_64BIT
193  r4 = dtpath_addr >> 32;
194  r6 = propname_addr >> 32;
195  r8 = propvalue_addr >> 32;
196 #else
197  r4 = 0;
198  r6 = 0;
199  r8 = 0;
200 #endif
201  r5 = (uint32_t)dtpath_addr;
202  r7 = (uint32_t)propname_addr;
203  r9 = (uint32_t)propvalue_addr;
204  r10 = propvalue_len;
205 
206  asm volatile("bl epapr_hypercall_start"
207  : "+r" (r11),
208  "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
209  "+r" (r8), "+r" (r9), "+r" (r10)
210  : : EV_HCALL_CLOBBERS8
211  );
212 
213  return r3;
214 }
215 
222 static inline unsigned int fh_partition_restart(unsigned int partition)
223 {
224  register uintptr_t r11 __asm__("r11");
225  register uintptr_t r3 __asm__("r3");
226 
227  r11 = FH_HCALL_TOKEN(FH_PARTITION_RESTART);
228  r3 = partition;
229 
230  asm volatile("bl epapr_hypercall_start"
231  : "+r" (r11), "+r" (r3)
232  : : EV_HCALL_CLOBBERS1
233  );
234 
235  return r3;
236 }
237 
238 #define FH_PARTITION_STOPPED 0
239 #define FH_PARTITION_RUNNING 1
240 #define FH_PARTITION_STARTING 2
241 #define FH_PARTITION_STOPPING 3
242 #define FH_PARTITION_PAUSING 4
243 #define FH_PARTITION_PAUSED 5
244 #define FH_PARTITION_RESUMING 6
245 
253 static inline unsigned int fh_partition_get_status(unsigned int partition,
254  unsigned int *status)
255 {
256  register uintptr_t r11 __asm__("r11");
257  register uintptr_t r3 __asm__("r3");
258  register uintptr_t r4 __asm__("r4");
259 
260  r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_STATUS);
261  r3 = partition;
262 
263  asm volatile("bl epapr_hypercall_start"
264  : "+r" (r11), "+r" (r3), "=r" (r4)
265  : : EV_HCALL_CLOBBERS2
266  );
267 
268  *status = r4;
269 
270  return r3;
271 }
272 
283 static inline unsigned int fh_partition_start(unsigned int partition,
284  uint32_t entry_point, int load)
285 {
286  register uintptr_t r11 __asm__("r11");
287  register uintptr_t r3 __asm__("r3");
288  register uintptr_t r4 __asm__("r4");
289  register uintptr_t r5 __asm__("r5");
290 
291  r11 = FH_HCALL_TOKEN(FH_PARTITION_START);
292  r3 = partition;
293  r4 = entry_point;
294  r5 = load;
295 
296  asm volatile("bl epapr_hypercall_start"
297  : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5)
298  : : EV_HCALL_CLOBBERS3
299  );
300 
301  return r3;
302 }
303 
310 static inline unsigned int fh_partition_stop(unsigned int partition)
311 {
312  register uintptr_t r11 __asm__("r11");
313  register uintptr_t r3 __asm__("r3");
314 
315  r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP);
316  r3 = partition;
317 
318  asm volatile("bl epapr_hypercall_start"
319  : "+r" (r11), "+r" (r3)
320  : : EV_HCALL_CLOBBERS1
321  );
322 
323  return r3;
324 }
325 
339 struct fh_sg_list {
340  uint64_t source;
341  uint64_t target;
342  uint64_t size;
343  uint64_t reserved;
344 } __attribute__ ((aligned(32)));
345 
355 static inline unsigned int fh_partition_memcpy(unsigned int source,
356  unsigned int target, uint64_t sg_list, unsigned int count)
357 {
358  register uintptr_t r11 __asm__("r11");
359  register uintptr_t r3 __asm__("r3");
360  register uintptr_t r4 __asm__("r4");
361  register uintptr_t r5 __asm__("r5");
362  register uintptr_t r6 __asm__("r6");
363  register uintptr_t r7 __asm__("r7");
364 
365  r11 = FH_HCALL_TOKEN(FH_PARTITION_MEMCPY);
366  r3 = source;
367  r4 = target;
368  r5 = (uint32_t) sg_list;
369 
370 #ifdef CONFIG_PHYS_64BIT
371  r6 = sg_list >> 32;
372 #else
373  r6 = 0;
374 #endif
375  r7 = count;
376 
377  asm volatile("bl epapr_hypercall_start"
378  : "+r" (r11),
379  "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7)
380  : : EV_HCALL_CLOBBERS5
381  );
382 
383  return r3;
384 }
385 
392 static inline unsigned int fh_dma_enable(unsigned int liodn)
393 {
394  register uintptr_t r11 __asm__("r11");
395  register uintptr_t r3 __asm__("r3");
396 
397  r11 = FH_HCALL_TOKEN(FH_DMA_ENABLE);
398  r3 = liodn;
399 
400  asm volatile("bl epapr_hypercall_start"
401  : "+r" (r11), "+r" (r3)
402  : : EV_HCALL_CLOBBERS1
403  );
404 
405  return r3;
406 }
407 
414 static inline unsigned int fh_dma_disable(unsigned int liodn)
415 {
416  register uintptr_t r11 __asm__("r11");
417  register uintptr_t r3 __asm__("r3");
418 
419  r11 = FH_HCALL_TOKEN(FH_DMA_DISABLE);
420  r3 = liodn;
421 
422  asm volatile("bl epapr_hypercall_start"
423  : "+r" (r11), "+r" (r3)
424  : : EV_HCALL_CLOBBERS1
425  );
426 
427  return r3;
428 }
429 
430 
438 static inline unsigned int fh_vmpic_get_msir(unsigned int interrupt,
439  unsigned int *msir_val)
440 {
441  register uintptr_t r11 __asm__("r11");
442  register uintptr_t r3 __asm__("r3");
443  register uintptr_t r4 __asm__("r4");
444 
445  r11 = FH_HCALL_TOKEN(FH_VMPIC_GET_MSIR);
446  r3 = interrupt;
447 
448  asm volatile("bl epapr_hypercall_start"
449  : "+r" (r11), "+r" (r3), "=r" (r4)
450  : : EV_HCALL_CLOBBERS2
451  );
452 
453  *msir_val = r4;
454 
455  return r3;
456 }
457 
463 static inline unsigned int fh_system_reset(void)
464 {
465  register uintptr_t r11 __asm__("r11");
466  register uintptr_t r3 __asm__("r3");
467 
468  r11 = FH_HCALL_TOKEN(FH_SYSTEM_RESET);
469 
470  asm volatile("bl epapr_hypercall_start"
471  : "+r" (r11), "=r" (r3)
472  : : EV_HCALL_CLOBBERS1
473  );
474 
475  return r3;
476 }
477 
478 
490 static inline unsigned int fh_err_get_info(int queue, uint32_t *bufsize,
491  uint32_t addr_hi, uint32_t addr_lo, int peek)
492 {
493  register uintptr_t r11 __asm__("r11");
494  register uintptr_t r3 __asm__("r3");
495  register uintptr_t r4 __asm__("r4");
496  register uintptr_t r5 __asm__("r5");
497  register uintptr_t r6 __asm__("r6");
498  register uintptr_t r7 __asm__("r7");
499 
500  r11 = FH_HCALL_TOKEN(FH_ERR_GET_INFO);
501  r3 = queue;
502  r4 = *bufsize;
503  r5 = addr_hi;
504  r6 = addr_lo;
505  r7 = peek;
506 
507  asm volatile("bl epapr_hypercall_start"
508  : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6),
509  "+r" (r7)
510  : : EV_HCALL_CLOBBERS5
511  );
512 
513  *bufsize = r4;
514 
515  return r3;
516 }
517 
518 
519 #define FH_VCPU_RUN 0
520 #define FH_VCPU_IDLE 1
521 #define FH_VCPU_NAP 2
522 
532 static inline unsigned int fh_get_core_state(unsigned int handle,
533  unsigned int vcpu, unsigned int *state)
534 {
535  register uintptr_t r11 __asm__("r11");
536  register uintptr_t r3 __asm__("r3");
537  register uintptr_t r4 __asm__("r4");
538 
539  r11 = FH_HCALL_TOKEN(FH_GET_CORE_STATE);
540  r3 = handle;
541  r4 = vcpu;
542 
543  asm volatile("bl epapr_hypercall_start"
544  : "+r" (r11), "+r" (r3), "+r" (r4)
545  : : EV_HCALL_CLOBBERS2
546  );
547 
548  *state = r4;
549  return r3;
550 }
551 
563 static inline unsigned int fh_enter_nap(unsigned int handle, unsigned int vcpu)
564 {
565  register uintptr_t r11 __asm__("r11");
566  register uintptr_t r3 __asm__("r3");
567  register uintptr_t r4 __asm__("r4");
568 
569  r11 = FH_HCALL_TOKEN(FH_ENTER_NAP);
570  r3 = handle;
571  r4 = vcpu;
572 
573  asm volatile("bl epapr_hypercall_start"
574  : "+r" (r11), "+r" (r3), "+r" (r4)
575  : : EV_HCALL_CLOBBERS2
576  );
577 
578  return r3;
579 }
580 
588 static inline unsigned int fh_exit_nap(unsigned int handle, unsigned int vcpu)
589 {
590  register uintptr_t r11 __asm__("r11");
591  register uintptr_t r3 __asm__("r3");
592  register uintptr_t r4 __asm__("r4");
593 
594  r11 = FH_HCALL_TOKEN(FH_EXIT_NAP);
595  r3 = handle;
596  r4 = vcpu;
597 
598  asm volatile("bl epapr_hypercall_start"
599  : "+r" (r11), "+r" (r3), "+r" (r4)
600  : : EV_HCALL_CLOBBERS2
601  );
602 
603  return r3;
604 }
611 static inline unsigned int fh_claim_device(unsigned int handle)
612 {
613  register uintptr_t r11 __asm__("r11");
614  register uintptr_t r3 __asm__("r3");
615 
616  r11 = FH_HCALL_TOKEN(FH_CLAIM_DEVICE);
617  r3 = handle;
618 
619  asm volatile("bl epapr_hypercall_start"
620  : "+r" (r11), "+r" (r3)
621  : : EV_HCALL_CLOBBERS1
622  );
623 
624  return r3;
625 }
626 
638 static inline unsigned int fh_partition_stop_dma(unsigned int handle)
639 {
640  register uintptr_t r11 __asm__("r11");
641  register uintptr_t r3 __asm__("r3");
642 
643  r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP_DMA);
644  r3 = handle;
645 
646  asm volatile("bl epapr_hypercall_start"
647  : "+r" (r11), "+r" (r3)
648  : : EV_HCALL_CLOBBERS1
649  );
650 
651  return r3;
652 }
653 #endif
Definition: media.c:43
uint64_t source
Definition: fsl_hcalls.h:340
uint64_t size
Definition: fsl_hcalls.h:342
typedef __attribute__
Disable IRQ Interrupts.
Definition: cmsis_gcc.h:69
uint64_t reserved
Definition: fsl_hcalls.h:343
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
Definition: fsl_hcalls.h:339
uint64_t target
Definition: fsl_hcalls.h:341