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