fsl_hcalls.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  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. #ifndef _FSL_HCALLS_H
  40. #define _FSL_HCALLS_H
  41. #include <linux/types.h>
  42. #include <linux/errno.h>
  43. #include <asm/byteorder.h>
  44. #include <asm/epapr_hcalls.h>
  45. #define FH_API_VERSION 1
  46. #define FH_ERR_GET_INFO 1
  47. #define FH_PARTITION_GET_DTPROP 2
  48. #define FH_PARTITION_SET_DTPROP 3
  49. #define FH_PARTITION_RESTART 4
  50. #define FH_PARTITION_GET_STATUS 5
  51. #define FH_PARTITION_START 6
  52. #define FH_PARTITION_STOP 7
  53. #define FH_PARTITION_MEMCPY 8
  54. #define FH_DMA_ENABLE 9
  55. #define FH_DMA_DISABLE 10
  56. #define FH_SEND_NMI 11
  57. #define FH_VMPIC_GET_MSIR 12
  58. #define FH_SYSTEM_RESET 13
  59. #define FH_GET_CORE_STATE 14
  60. #define FH_ENTER_NAP 15
  61. #define FH_EXIT_NAP 16
  62. #define FH_CLAIM_DEVICE 17
  63. #define FH_PARTITION_STOP_DMA 18
  64. /* vendor ID: Freescale Semiconductor */
  65. #define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num)
  66. /*
  67. * We use "uintptr_t" to define a register because it's guaranteed to be a
  68. * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit
  69. * platform.
  70. *
  71. * All registers are either input/output or output only. Registers that are
  72. * initialized before making the hypercall are input/output. All
  73. * input/output registers are represented with "+r". Output-only registers
  74. * are represented with "=r". Do not specify any unused registers. The
  75. * clobber list will tell the compiler that the hypercall modifies those
  76. * registers, which is good enough.
  77. */
  78. /**
  79. * fh_send_nmi - send NMI to virtual cpu(s).
  80. * @vcpu_mask: send NMI to virtual cpu(s) specified by this mask.
  81. *
  82. * Returns 0 for success, or EINVAL for invalid vcpu_mask.
  83. */
  84. static inline unsigned int fh_send_nmi(unsigned int vcpu_mask)
  85. {
  86. register uintptr_t r11 __asm__("r11");
  87. register uintptr_t r3 __asm__("r3");
  88. r11 = FH_HCALL_TOKEN(FH_SEND_NMI);
  89. r3 = vcpu_mask;
  90. __asm__ __volatile__ ("sc 1"
  91. : "+r" (r11), "+r" (r3)
  92. : : EV_HCALL_CLOBBERS1
  93. );
  94. return r3;
  95. }
  96. /* Arbitrary limits to avoid excessive memory allocation in hypervisor */
  97. #define FH_DTPROP_MAX_PATHLEN 4096
  98. #define FH_DTPROP_MAX_PROPLEN 32768
  99. /**
  100. * fh_partiton_get_dtprop - get a property from a guest device tree.
  101. * @handle: handle of partition whose device tree is to be accessed
  102. * @dtpath_addr: physical address of device tree path to access
  103. * @propname_addr: physical address of name of property
  104. * @propvalue_addr: physical address of property value buffer
  105. * @propvalue_len: length of buffer on entry, length of property on return
  106. *
  107. * Returns zero on success, non-zero on error.
  108. */
  109. static inline unsigned int fh_partition_get_dtprop(int handle,
  110. uint64_t dtpath_addr,
  111. uint64_t propname_addr,
  112. uint64_t propvalue_addr,
  113. uint32_t *propvalue_len)
  114. {
  115. register uintptr_t r11 __asm__("r11");
  116. register uintptr_t r3 __asm__("r3");
  117. register uintptr_t r4 __asm__("r4");
  118. register uintptr_t r5 __asm__("r5");
  119. register uintptr_t r6 __asm__("r6");
  120. register uintptr_t r7 __asm__("r7");
  121. register uintptr_t r8 __asm__("r8");
  122. register uintptr_t r9 __asm__("r9");
  123. register uintptr_t r10 __asm__("r10");
  124. r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_DTPROP);
  125. r3 = handle;
  126. #ifdef CONFIG_PHYS_64BIT
  127. r4 = dtpath_addr >> 32;
  128. r6 = propname_addr >> 32;
  129. r8 = propvalue_addr >> 32;
  130. #else
  131. r4 = 0;
  132. r6 = 0;
  133. r8 = 0;
  134. #endif
  135. r5 = (uint32_t)dtpath_addr;
  136. r7 = (uint32_t)propname_addr;
  137. r9 = (uint32_t)propvalue_addr;
  138. r10 = *propvalue_len;
  139. __asm__ __volatile__ ("sc 1"
  140. : "+r" (r11),
  141. "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
  142. "+r" (r8), "+r" (r9), "+r" (r10)
  143. : : EV_HCALL_CLOBBERS8
  144. );
  145. *propvalue_len = r4;
  146. return r3;
  147. }
  148. /**
  149. * Set a property in a guest device tree.
  150. * @handle: handle of partition whose device tree is to be accessed
  151. * @dtpath_addr: physical address of device tree path to access
  152. * @propname_addr: physical address of name of property
  153. * @propvalue_addr: physical address of property value
  154. * @propvalue_len: length of property
  155. *
  156. * Returns zero on success, non-zero on error.
  157. */
  158. static inline unsigned int fh_partition_set_dtprop(int handle,
  159. uint64_t dtpath_addr,
  160. uint64_t propname_addr,
  161. uint64_t propvalue_addr,
  162. uint32_t propvalue_len)
  163. {
  164. register uintptr_t r11 __asm__("r11");
  165. register uintptr_t r3 __asm__("r3");
  166. register uintptr_t r4 __asm__("r4");
  167. register uintptr_t r6 __asm__("r6");
  168. register uintptr_t r8 __asm__("r8");
  169. register uintptr_t r5 __asm__("r5");
  170. register uintptr_t r7 __asm__("r7");
  171. register uintptr_t r9 __asm__("r9");
  172. register uintptr_t r10 __asm__("r10");
  173. r11 = FH_HCALL_TOKEN(FH_PARTITION_SET_DTPROP);
  174. r3 = handle;
  175. #ifdef CONFIG_PHYS_64BIT
  176. r4 = dtpath_addr >> 32;
  177. r6 = propname_addr >> 32;
  178. r8 = propvalue_addr >> 32;
  179. #else
  180. r4 = 0;
  181. r6 = 0;
  182. r8 = 0;
  183. #endif
  184. r5 = (uint32_t)dtpath_addr;
  185. r7 = (uint32_t)propname_addr;
  186. r9 = (uint32_t)propvalue_addr;
  187. r10 = propvalue_len;
  188. __asm__ __volatile__ ("sc 1"
  189. : "+r" (r11),
  190. "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7),
  191. "+r" (r8), "+r" (r9), "+r" (r10)
  192. : : EV_HCALL_CLOBBERS8
  193. );
  194. return r3;
  195. }
  196. /**
  197. * fh_partition_restart - reboot the current partition
  198. * @partition: partition ID
  199. *
  200. * Returns an error code if reboot failed. Does not return if it succeeds.
  201. */
  202. static inline unsigned int fh_partition_restart(unsigned int partition)
  203. {
  204. register uintptr_t r11 __asm__("r11");
  205. register uintptr_t r3 __asm__("r3");
  206. r11 = FH_HCALL_TOKEN(FH_PARTITION_RESTART);
  207. r3 = partition;
  208. __asm__ __volatile__ ("sc 1"
  209. : "+r" (r11), "+r" (r3)
  210. : : EV_HCALL_CLOBBERS1
  211. );
  212. return r3;
  213. }
  214. #define FH_PARTITION_STOPPED 0
  215. #define FH_PARTITION_RUNNING 1
  216. #define FH_PARTITION_STARTING 2
  217. #define FH_PARTITION_STOPPING 3
  218. #define FH_PARTITION_PAUSING 4
  219. #define FH_PARTITION_PAUSED 5
  220. #define FH_PARTITION_RESUMING 6
  221. /**
  222. * fh_partition_get_status - gets the status of a partition
  223. * @partition: partition ID
  224. * @status: returned status code
  225. *
  226. * Returns 0 for success, or an error code.
  227. */
  228. static inline unsigned int fh_partition_get_status(unsigned int partition,
  229. unsigned int *status)
  230. {
  231. register uintptr_t r11 __asm__("r11");
  232. register uintptr_t r3 __asm__("r3");
  233. register uintptr_t r4 __asm__("r4");
  234. r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_STATUS);
  235. r3 = partition;
  236. __asm__ __volatile__ ("sc 1"
  237. : "+r" (r11), "+r" (r3), "=r" (r4)
  238. : : EV_HCALL_CLOBBERS2
  239. );
  240. *status = r4;
  241. return r3;
  242. }
  243. /**
  244. * fh_partition_start - boots and starts execution of the specified partition
  245. * @partition: partition ID
  246. * @entry_point: guest physical address to start execution
  247. *
  248. * The hypervisor creates a 1-to-1 virtual/physical IMA mapping, so at boot
  249. * time, guest physical address are the same as guest virtual addresses.
  250. *
  251. * Returns 0 for success, or an error code.
  252. */
  253. static inline unsigned int fh_partition_start(unsigned int partition,
  254. uint32_t entry_point, int load)
  255. {
  256. register uintptr_t r11 __asm__("r11");
  257. register uintptr_t r3 __asm__("r3");
  258. register uintptr_t r4 __asm__("r4");
  259. register uintptr_t r5 __asm__("r5");
  260. r11 = FH_HCALL_TOKEN(FH_PARTITION_START);
  261. r3 = partition;
  262. r4 = entry_point;
  263. r5 = load;
  264. __asm__ __volatile__ ("sc 1"
  265. : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5)
  266. : : EV_HCALL_CLOBBERS3
  267. );
  268. return r3;
  269. }
  270. /**
  271. * fh_partition_stop - stops another partition
  272. * @partition: partition ID
  273. *
  274. * Returns 0 for success, or an error code.
  275. */
  276. static inline unsigned int fh_partition_stop(unsigned int partition)
  277. {
  278. register uintptr_t r11 __asm__("r11");
  279. register uintptr_t r3 __asm__("r3");
  280. r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP);
  281. r3 = partition;
  282. __asm__ __volatile__ ("sc 1"
  283. : "+r" (r11), "+r" (r3)
  284. : : EV_HCALL_CLOBBERS1
  285. );
  286. return r3;
  287. }
  288. /**
  289. * struct fh_sg_list: definition of the fh_partition_memcpy S/G list
  290. * @source: guest physical address to copy from
  291. * @target: guest physical address to copy to
  292. * @size: number of bytes to copy
  293. * @reserved: reserved, must be zero
  294. *
  295. * The scatter/gather list for fh_partition_memcpy() is an array of these
  296. * structures. The array must be guest physically contiguous.
  297. *
  298. * This structure must be aligned on 32-byte boundary, so that no single
  299. * strucuture can span two pages.
  300. */
  301. struct fh_sg_list {
  302. uint64_t source; /**< guest physical address to copy from */
  303. uint64_t target; /**< guest physical address to copy to */
  304. uint64_t size; /**< number of bytes to copy */
  305. uint64_t reserved; /**< reserved, must be zero */
  306. } __attribute__ ((aligned(32)));
  307. /**
  308. * fh_partition_memcpy - copies data from one guest to another
  309. * @source: the ID of the partition to copy from
  310. * @target: the ID of the partition to copy to
  311. * @sg_list: guest physical address of an array of &fh_sg_list structures
  312. * @count: the number of entries in @sg_list
  313. *
  314. * Returns 0 for success, or an error code.
  315. */
  316. static inline unsigned int fh_partition_memcpy(unsigned int source,
  317. unsigned int target, phys_addr_t sg_list, unsigned int count)
  318. {
  319. register uintptr_t r11 __asm__("r11");
  320. register uintptr_t r3 __asm__("r3");
  321. register uintptr_t r4 __asm__("r4");
  322. register uintptr_t r5 __asm__("r5");
  323. register uintptr_t r6 __asm__("r6");
  324. register uintptr_t r7 __asm__("r7");
  325. r11 = FH_HCALL_TOKEN(FH_PARTITION_MEMCPY);
  326. r3 = source;
  327. r4 = target;
  328. r5 = (uint32_t) sg_list;
  329. #ifdef CONFIG_PHYS_64BIT
  330. r6 = sg_list >> 32;
  331. #else
  332. r6 = 0;
  333. #endif
  334. r7 = count;
  335. __asm__ __volatile__ ("sc 1"
  336. : "+r" (r11),
  337. "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7)
  338. : : EV_HCALL_CLOBBERS5
  339. );
  340. return r3;
  341. }
  342. /**
  343. * fh_dma_enable - enable DMA for the specified device
  344. * @liodn: the LIODN of the I/O device for which to enable DMA
  345. *
  346. * Returns 0 for success, or an error code.
  347. */
  348. static inline unsigned int fh_dma_enable(unsigned int liodn)
  349. {
  350. register uintptr_t r11 __asm__("r11");
  351. register uintptr_t r3 __asm__("r3");
  352. r11 = FH_HCALL_TOKEN(FH_DMA_ENABLE);
  353. r3 = liodn;
  354. __asm__ __volatile__ ("sc 1"
  355. : "+r" (r11), "+r" (r3)
  356. : : EV_HCALL_CLOBBERS1
  357. );
  358. return r3;
  359. }
  360. /**
  361. * fh_dma_disable - disable DMA for the specified device
  362. * @liodn: the LIODN of the I/O device for which to disable DMA
  363. *
  364. * Returns 0 for success, or an error code.
  365. */
  366. static inline unsigned int fh_dma_disable(unsigned int liodn)
  367. {
  368. register uintptr_t r11 __asm__("r11");
  369. register uintptr_t r3 __asm__("r3");
  370. r11 = FH_HCALL_TOKEN(FH_DMA_DISABLE);
  371. r3 = liodn;
  372. __asm__ __volatile__ ("sc 1"
  373. : "+r" (r11), "+r" (r3)
  374. : : EV_HCALL_CLOBBERS1
  375. );
  376. return r3;
  377. }
  378. /**
  379. * fh_vmpic_get_msir - returns the MPIC-MSI register value
  380. * @interrupt: the interrupt number
  381. * @msir_val: returned MPIC-MSI register value
  382. *
  383. * Returns 0 for success, or an error code.
  384. */
  385. static inline unsigned int fh_vmpic_get_msir(unsigned int interrupt,
  386. unsigned int *msir_val)
  387. {
  388. register uintptr_t r11 __asm__("r11");
  389. register uintptr_t r3 __asm__("r3");
  390. register uintptr_t r4 __asm__("r4");
  391. r11 = FH_HCALL_TOKEN(FH_VMPIC_GET_MSIR);
  392. r3 = interrupt;
  393. __asm__ __volatile__ ("sc 1"
  394. : "+r" (r11), "+r" (r3), "=r" (r4)
  395. : : EV_HCALL_CLOBBERS2
  396. );
  397. *msir_val = r4;
  398. return r3;
  399. }
  400. /**
  401. * fh_system_reset - reset the system
  402. *
  403. * Returns 0 for success, or an error code.
  404. */
  405. static inline unsigned int fh_system_reset(void)
  406. {
  407. register uintptr_t r11 __asm__("r11");
  408. register uintptr_t r3 __asm__("r3");
  409. r11 = FH_HCALL_TOKEN(FH_SYSTEM_RESET);
  410. __asm__ __volatile__ ("sc 1"
  411. : "+r" (r11), "=r" (r3)
  412. : : EV_HCALL_CLOBBERS1
  413. );
  414. return r3;
  415. }
  416. /**
  417. * fh_err_get_info - get platform error information
  418. * @queue id:
  419. * 0 for guest error event queue
  420. * 1 for global error event queue
  421. *
  422. * @pointer to store the platform error data:
  423. * platform error data is returned in registers r4 - r11
  424. *
  425. * Returns 0 for success, or an error code.
  426. */
  427. static inline unsigned int fh_err_get_info(int queue, uint32_t *bufsize,
  428. uint32_t addr_hi, uint32_t addr_lo, int peek)
  429. {
  430. register uintptr_t r11 __asm__("r11");
  431. register uintptr_t r3 __asm__("r3");
  432. register uintptr_t r4 __asm__("r4");
  433. register uintptr_t r5 __asm__("r5");
  434. register uintptr_t r6 __asm__("r6");
  435. register uintptr_t r7 __asm__("r7");
  436. r11 = FH_HCALL_TOKEN(FH_ERR_GET_INFO);
  437. r3 = queue;
  438. r4 = *bufsize;
  439. r5 = addr_hi;
  440. r6 = addr_lo;
  441. r7 = peek;
  442. __asm__ __volatile__ ("sc 1"
  443. : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6),
  444. "+r" (r7)
  445. : : EV_HCALL_CLOBBERS5
  446. );
  447. *bufsize = r4;
  448. return r3;
  449. }
  450. #define FH_VCPU_RUN 0
  451. #define FH_VCPU_IDLE 1
  452. #define FH_VCPU_NAP 2
  453. /**
  454. * fh_get_core_state - get the state of a vcpu
  455. *
  456. * @handle: handle of partition containing the vcpu
  457. * @vcpu: vcpu number within the partition
  458. * @state:the current state of the vcpu, see FH_VCPU_*
  459. *
  460. * Returns 0 for success, or an error code.
  461. */
  462. static inline unsigned int fh_get_core_state(unsigned int handle,
  463. unsigned int vcpu, unsigned int *state)
  464. {
  465. register uintptr_t r11 __asm__("r11");
  466. register uintptr_t r3 __asm__("r3");
  467. register uintptr_t r4 __asm__("r4");
  468. r11 = FH_HCALL_TOKEN(FH_GET_CORE_STATE);
  469. r3 = handle;
  470. r4 = vcpu;
  471. __asm__ __volatile__ ("sc 1"
  472. : "+r" (r11), "+r" (r3), "+r" (r4)
  473. : : EV_HCALL_CLOBBERS2
  474. );
  475. *state = r4;
  476. return r3;
  477. }
  478. /**
  479. * fh_enter_nap - enter nap on a vcpu
  480. *
  481. * Note that though the API supports entering nap on a vcpu other
  482. * than the caller, this may not be implmented and may return EINVAL.
  483. *
  484. * @handle: handle of partition containing the vcpu
  485. * @vcpu: vcpu number within the partition
  486. *
  487. * Returns 0 for success, or an error code.
  488. */
  489. static inline unsigned int fh_enter_nap(unsigned int handle, unsigned int vcpu)
  490. {
  491. register uintptr_t r11 __asm__("r11");
  492. register uintptr_t r3 __asm__("r3");
  493. register uintptr_t r4 __asm__("r4");
  494. r11 = FH_HCALL_TOKEN(FH_ENTER_NAP);
  495. r3 = handle;
  496. r4 = vcpu;
  497. __asm__ __volatile__ ("sc 1"
  498. : "+r" (r11), "+r" (r3), "+r" (r4)
  499. : : EV_HCALL_CLOBBERS2
  500. );
  501. return r3;
  502. }
  503. /**
  504. * fh_exit_nap - exit nap on a vcpu
  505. * @handle: handle of partition containing the vcpu
  506. * @vcpu: vcpu number within the partition
  507. *
  508. * Returns 0 for success, or an error code.
  509. */
  510. static inline unsigned int fh_exit_nap(unsigned int handle, unsigned int vcpu)
  511. {
  512. register uintptr_t r11 __asm__("r11");
  513. register uintptr_t r3 __asm__("r3");
  514. register uintptr_t r4 __asm__("r4");
  515. r11 = FH_HCALL_TOKEN(FH_EXIT_NAP);
  516. r3 = handle;
  517. r4 = vcpu;
  518. __asm__ __volatile__ ("sc 1"
  519. : "+r" (r11), "+r" (r3), "+r" (r4)
  520. : : EV_HCALL_CLOBBERS2
  521. );
  522. return r3;
  523. }
  524. /**
  525. * fh_claim_device - claim a "claimable" shared device
  526. * @handle: fsl,hv-device-handle of node to claim
  527. *
  528. * Returns 0 for success, or an error code.
  529. */
  530. static inline unsigned int fh_claim_device(unsigned int handle)
  531. {
  532. register uintptr_t r11 __asm__("r11");
  533. register uintptr_t r3 __asm__("r3");
  534. r11 = FH_HCALL_TOKEN(FH_CLAIM_DEVICE);
  535. r3 = handle;
  536. __asm__ __volatile__ ("sc 1"
  537. : "+r" (r11), "+r" (r3)
  538. : : EV_HCALL_CLOBBERS1
  539. );
  540. return r3;
  541. }
  542. /**
  543. * Run deferred DMA disabling on a partition's private devices
  544. *
  545. * This applies to devices which a partition owns either privately,
  546. * or which are claimable and still actively owned by that partition,
  547. * and which do not have the no-dma-disable property.
  548. *
  549. * @handle: partition (must be stopped) whose DMA is to be disabled
  550. *
  551. * Returns 0 for success, or an error code.
  552. */
  553. static inline unsigned int fh_partition_stop_dma(unsigned int handle)
  554. {
  555. register uintptr_t r11 __asm__("r11");
  556. register uintptr_t r3 __asm__("r3");
  557. r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP_DMA);
  558. r3 = handle;
  559. __asm__ __volatile__ ("sc 1"
  560. : "+r" (r11), "+r" (r3)
  561. : : EV_HCALL_CLOBBERS1
  562. );
  563. return r3;
  564. }
  565. #endif