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 */ 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 99*8e525d59SLiu 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 /** 112bd497fc9STimur Tabi * fh_partiton_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 */ 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 154*8e525d59SLiu 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 */ 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 208*8e525d59SLiu 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 */ 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 232*8e525d59SLiu 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 */ 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 265*8e525d59SLiu 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 */ 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 298*8e525d59SLiu 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 */ 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 320*8e525d59SLiu 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 */ 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 379*8e525d59SLiu 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 */ 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 402*8e525d59SLiu 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 */ 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 424*8e525d59SLiu 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 */ 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 450*8e525d59SLiu 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 */ 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 472*8e525d59SLiu 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 */ 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 509*8e525d59SLiu 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 */ 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 545*8e525d59SLiu 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 */ 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 575*8e525d59SLiu 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 */ 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 600*8e525d59SLiu 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 */ 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 621*8e525d59SLiu 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 */ 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 648*8e525d59SLiu 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