162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Freescale hypervisor call interface 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright 2008-2010 Freescale Semiconductor, Inc. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Author: Timur Tabi <timur@freescale.com> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This file is provided under a dual BSD/GPL license. When using or 962306a36Sopenharmony_ci * redistributing this file, you may do so under either license. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 1262306a36Sopenharmony_ci * modification, are permitted provided that the following conditions are met: 1362306a36Sopenharmony_ci * * Redistributions of source code must retain the above copyright 1462306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 1562306a36Sopenharmony_ci * * Redistributions in binary form must reproduce the above copyright 1662306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 1762306a36Sopenharmony_ci * documentation and/or other materials provided with the distribution. 1862306a36Sopenharmony_ci * * Neither the name of Freescale Semiconductor nor the 1962306a36Sopenharmony_ci * names of its contributors may be used to endorse or promote products 2062306a36Sopenharmony_ci * derived from this software without specific prior written permission. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * ALTERNATIVELY, this software may be distributed under the terms of the 2462306a36Sopenharmony_ci * GNU General Public License ("GPL") as published by the Free Software 2562306a36Sopenharmony_ci * Foundation, either version 2 of that License or (at your option) any 2662306a36Sopenharmony_ci * later version. 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 2962306a36Sopenharmony_ci * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 3062306a36Sopenharmony_ci * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 3162306a36Sopenharmony_ci * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 3262306a36Sopenharmony_ci * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 3362306a36Sopenharmony_ci * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 3462306a36Sopenharmony_ci * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 3562306a36Sopenharmony_ci * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3662306a36Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3762306a36Sopenharmony_ci * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#ifndef _FSL_HCALLS_H 4162306a36Sopenharmony_ci#define _FSL_HCALLS_H 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#include <linux/types.h> 4462306a36Sopenharmony_ci#include <linux/errno.h> 4562306a36Sopenharmony_ci#include <asm/byteorder.h> 4662306a36Sopenharmony_ci#include <asm/epapr_hcalls.h> 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define FH_API_VERSION 1 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define FH_ERR_GET_INFO 1 5162306a36Sopenharmony_ci#define FH_PARTITION_GET_DTPROP 2 5262306a36Sopenharmony_ci#define FH_PARTITION_SET_DTPROP 3 5362306a36Sopenharmony_ci#define FH_PARTITION_RESTART 4 5462306a36Sopenharmony_ci#define FH_PARTITION_GET_STATUS 5 5562306a36Sopenharmony_ci#define FH_PARTITION_START 6 5662306a36Sopenharmony_ci#define FH_PARTITION_STOP 7 5762306a36Sopenharmony_ci#define FH_PARTITION_MEMCPY 8 5862306a36Sopenharmony_ci#define FH_DMA_ENABLE 9 5962306a36Sopenharmony_ci#define FH_DMA_DISABLE 10 6062306a36Sopenharmony_ci#define FH_SEND_NMI 11 6162306a36Sopenharmony_ci#define FH_VMPIC_GET_MSIR 12 6262306a36Sopenharmony_ci#define FH_SYSTEM_RESET 13 6362306a36Sopenharmony_ci#define FH_GET_CORE_STATE 14 6462306a36Sopenharmony_ci#define FH_ENTER_NAP 15 6562306a36Sopenharmony_ci#define FH_EXIT_NAP 16 6662306a36Sopenharmony_ci#define FH_CLAIM_DEVICE 17 6762306a36Sopenharmony_ci#define FH_PARTITION_STOP_DMA 18 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* vendor ID: Freescale Semiconductor */ 7062306a36Sopenharmony_ci#define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/* 7362306a36Sopenharmony_ci * We use "uintptr_t" to define a register because it's guaranteed to be a 7462306a36Sopenharmony_ci * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit 7562306a36Sopenharmony_ci * platform. 7662306a36Sopenharmony_ci * 7762306a36Sopenharmony_ci * All registers are either input/output or output only. Registers that are 7862306a36Sopenharmony_ci * initialized before making the hypercall are input/output. All 7962306a36Sopenharmony_ci * input/output registers are represented with "+r". Output-only registers 8062306a36Sopenharmony_ci * are represented with "=r". Do not specify any unused registers. The 8162306a36Sopenharmony_ci * clobber list will tell the compiler that the hypercall modifies those 8262306a36Sopenharmony_ci * registers, which is good enough. 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/** 8662306a36Sopenharmony_ci * fh_send_nmi - send NMI to virtual cpu(s). 8762306a36Sopenharmony_ci * @vcpu_mask: send NMI to virtual cpu(s) specified by this mask. 8862306a36Sopenharmony_ci * 8962306a36Sopenharmony_ci * Returns 0 for success, or EINVAL for invalid vcpu_mask. 9062306a36Sopenharmony_ci */ 9162306a36Sopenharmony_cistatic inline unsigned int fh_send_nmi(unsigned int vcpu_mask) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 9462306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_SEND_NMI); 9762306a36Sopenharmony_ci r3 = vcpu_mask; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 10062306a36Sopenharmony_ci : "+r" (r11), "+r" (r3) 10162306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 10262306a36Sopenharmony_ci ); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci return r3; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* Arbitrary limits to avoid excessive memory allocation in hypervisor */ 10862306a36Sopenharmony_ci#define FH_DTPROP_MAX_PATHLEN 4096 10962306a36Sopenharmony_ci#define FH_DTPROP_MAX_PROPLEN 32768 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/** 11262306a36Sopenharmony_ci * fh_partition_get_dtprop - get a property from a guest device tree. 11362306a36Sopenharmony_ci * @handle: handle of partition whose device tree is to be accessed 11462306a36Sopenharmony_ci * @dtpath_addr: physical address of device tree path to access 11562306a36Sopenharmony_ci * @propname_addr: physical address of name of property 11662306a36Sopenharmony_ci * @propvalue_addr: physical address of property value buffer 11762306a36Sopenharmony_ci * @propvalue_len: length of buffer on entry, length of property on return 11862306a36Sopenharmony_ci * 11962306a36Sopenharmony_ci * Returns zero on success, non-zero on error. 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_cistatic inline unsigned int fh_partition_get_dtprop(int handle, 12262306a36Sopenharmony_ci uint64_t dtpath_addr, 12362306a36Sopenharmony_ci uint64_t propname_addr, 12462306a36Sopenharmony_ci uint64_t propvalue_addr, 12562306a36Sopenharmony_ci uint32_t *propvalue_len) 12662306a36Sopenharmony_ci{ 12762306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 12862306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 12962306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 13062306a36Sopenharmony_ci register uintptr_t r5 __asm__("r5"); 13162306a36Sopenharmony_ci register uintptr_t r6 __asm__("r6"); 13262306a36Sopenharmony_ci register uintptr_t r7 __asm__("r7"); 13362306a36Sopenharmony_ci register uintptr_t r8 __asm__("r8"); 13462306a36Sopenharmony_ci register uintptr_t r9 __asm__("r9"); 13562306a36Sopenharmony_ci register uintptr_t r10 __asm__("r10"); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_DTPROP); 13862306a36Sopenharmony_ci r3 = handle; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci#ifdef CONFIG_PHYS_64BIT 14162306a36Sopenharmony_ci r4 = dtpath_addr >> 32; 14262306a36Sopenharmony_ci r6 = propname_addr >> 32; 14362306a36Sopenharmony_ci r8 = propvalue_addr >> 32; 14462306a36Sopenharmony_ci#else 14562306a36Sopenharmony_ci r4 = 0; 14662306a36Sopenharmony_ci r6 = 0; 14762306a36Sopenharmony_ci r8 = 0; 14862306a36Sopenharmony_ci#endif 14962306a36Sopenharmony_ci r5 = (uint32_t)dtpath_addr; 15062306a36Sopenharmony_ci r7 = (uint32_t)propname_addr; 15162306a36Sopenharmony_ci r9 = (uint32_t)propvalue_addr; 15262306a36Sopenharmony_ci r10 = *propvalue_len; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 15562306a36Sopenharmony_ci : "+r" (r11), 15662306a36Sopenharmony_ci "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), 15762306a36Sopenharmony_ci "+r" (r8), "+r" (r9), "+r" (r10) 15862306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS8 15962306a36Sopenharmony_ci ); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci *propvalue_len = r4; 16262306a36Sopenharmony_ci return r3; 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci/** 16662306a36Sopenharmony_ci * Set a property in a guest device tree. 16762306a36Sopenharmony_ci * @handle: handle of partition whose device tree is to be accessed 16862306a36Sopenharmony_ci * @dtpath_addr: physical address of device tree path to access 16962306a36Sopenharmony_ci * @propname_addr: physical address of name of property 17062306a36Sopenharmony_ci * @propvalue_addr: physical address of property value 17162306a36Sopenharmony_ci * @propvalue_len: length of property 17262306a36Sopenharmony_ci * 17362306a36Sopenharmony_ci * Returns zero on success, non-zero on error. 17462306a36Sopenharmony_ci */ 17562306a36Sopenharmony_cistatic inline unsigned int fh_partition_set_dtprop(int handle, 17662306a36Sopenharmony_ci uint64_t dtpath_addr, 17762306a36Sopenharmony_ci uint64_t propname_addr, 17862306a36Sopenharmony_ci uint64_t propvalue_addr, 17962306a36Sopenharmony_ci uint32_t propvalue_len) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 18262306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 18362306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 18462306a36Sopenharmony_ci register uintptr_t r6 __asm__("r6"); 18562306a36Sopenharmony_ci register uintptr_t r8 __asm__("r8"); 18662306a36Sopenharmony_ci register uintptr_t r5 __asm__("r5"); 18762306a36Sopenharmony_ci register uintptr_t r7 __asm__("r7"); 18862306a36Sopenharmony_ci register uintptr_t r9 __asm__("r9"); 18962306a36Sopenharmony_ci register uintptr_t r10 __asm__("r10"); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_SET_DTPROP); 19262306a36Sopenharmony_ci r3 = handle; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#ifdef CONFIG_PHYS_64BIT 19562306a36Sopenharmony_ci r4 = dtpath_addr >> 32; 19662306a36Sopenharmony_ci r6 = propname_addr >> 32; 19762306a36Sopenharmony_ci r8 = propvalue_addr >> 32; 19862306a36Sopenharmony_ci#else 19962306a36Sopenharmony_ci r4 = 0; 20062306a36Sopenharmony_ci r6 = 0; 20162306a36Sopenharmony_ci r8 = 0; 20262306a36Sopenharmony_ci#endif 20362306a36Sopenharmony_ci r5 = (uint32_t)dtpath_addr; 20462306a36Sopenharmony_ci r7 = (uint32_t)propname_addr; 20562306a36Sopenharmony_ci r9 = (uint32_t)propvalue_addr; 20662306a36Sopenharmony_ci r10 = propvalue_len; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 20962306a36Sopenharmony_ci : "+r" (r11), 21062306a36Sopenharmony_ci "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), 21162306a36Sopenharmony_ci "+r" (r8), "+r" (r9), "+r" (r10) 21262306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS8 21362306a36Sopenharmony_ci ); 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci return r3; 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci/** 21962306a36Sopenharmony_ci * fh_partition_restart - reboot the current partition 22062306a36Sopenharmony_ci * @partition: partition ID 22162306a36Sopenharmony_ci * 22262306a36Sopenharmony_ci * Returns an error code if reboot failed. Does not return if it succeeds. 22362306a36Sopenharmony_ci */ 22462306a36Sopenharmony_cistatic inline unsigned int fh_partition_restart(unsigned int partition) 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 22762306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_RESTART); 23062306a36Sopenharmony_ci r3 = partition; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 23362306a36Sopenharmony_ci : "+r" (r11), "+r" (r3) 23462306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 23562306a36Sopenharmony_ci ); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci return r3; 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci#define FH_PARTITION_STOPPED 0 24162306a36Sopenharmony_ci#define FH_PARTITION_RUNNING 1 24262306a36Sopenharmony_ci#define FH_PARTITION_STARTING 2 24362306a36Sopenharmony_ci#define FH_PARTITION_STOPPING 3 24462306a36Sopenharmony_ci#define FH_PARTITION_PAUSING 4 24562306a36Sopenharmony_ci#define FH_PARTITION_PAUSED 5 24662306a36Sopenharmony_ci#define FH_PARTITION_RESUMING 6 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci/** 24962306a36Sopenharmony_ci * fh_partition_get_status - gets the status of a partition 25062306a36Sopenharmony_ci * @partition: partition ID 25162306a36Sopenharmony_ci * @status: returned status code 25262306a36Sopenharmony_ci * 25362306a36Sopenharmony_ci * Returns 0 for success, or an error code. 25462306a36Sopenharmony_ci */ 25562306a36Sopenharmony_cistatic inline unsigned int fh_partition_get_status(unsigned int partition, 25662306a36Sopenharmony_ci unsigned int *status) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 25962306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 26062306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_STATUS); 26362306a36Sopenharmony_ci r3 = partition; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 26662306a36Sopenharmony_ci : "+r" (r11), "+r" (r3), "=r" (r4) 26762306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS2 26862306a36Sopenharmony_ci ); 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci *status = r4; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci return r3; 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci/** 27662306a36Sopenharmony_ci * fh_partition_start - boots and starts execution of the specified partition 27762306a36Sopenharmony_ci * @partition: partition ID 27862306a36Sopenharmony_ci * @entry_point: guest physical address to start execution 27962306a36Sopenharmony_ci * 28062306a36Sopenharmony_ci * The hypervisor creates a 1-to-1 virtual/physical IMA mapping, so at boot 28162306a36Sopenharmony_ci * time, guest physical address are the same as guest virtual addresses. 28262306a36Sopenharmony_ci * 28362306a36Sopenharmony_ci * Returns 0 for success, or an error code. 28462306a36Sopenharmony_ci */ 28562306a36Sopenharmony_cistatic inline unsigned int fh_partition_start(unsigned int partition, 28662306a36Sopenharmony_ci uint32_t entry_point, int load) 28762306a36Sopenharmony_ci{ 28862306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 28962306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 29062306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 29162306a36Sopenharmony_ci register uintptr_t r5 __asm__("r5"); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_START); 29462306a36Sopenharmony_ci r3 = partition; 29562306a36Sopenharmony_ci r4 = entry_point; 29662306a36Sopenharmony_ci r5 = load; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 29962306a36Sopenharmony_ci : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5) 30062306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS3 30162306a36Sopenharmony_ci ); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci return r3; 30462306a36Sopenharmony_ci} 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci/** 30762306a36Sopenharmony_ci * fh_partition_stop - stops another partition 30862306a36Sopenharmony_ci * @partition: partition ID 30962306a36Sopenharmony_ci * 31062306a36Sopenharmony_ci * Returns 0 for success, or an error code. 31162306a36Sopenharmony_ci */ 31262306a36Sopenharmony_cistatic inline unsigned int fh_partition_stop(unsigned int partition) 31362306a36Sopenharmony_ci{ 31462306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 31562306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP); 31862306a36Sopenharmony_ci r3 = partition; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 32162306a36Sopenharmony_ci : "+r" (r11), "+r" (r3) 32262306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 32362306a36Sopenharmony_ci ); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci return r3; 32662306a36Sopenharmony_ci} 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci/** 32962306a36Sopenharmony_ci * struct fh_sg_list: definition of the fh_partition_memcpy S/G list 33062306a36Sopenharmony_ci * @source: guest physical address to copy from 33162306a36Sopenharmony_ci * @target: guest physical address to copy to 33262306a36Sopenharmony_ci * @size: number of bytes to copy 33362306a36Sopenharmony_ci * @reserved: reserved, must be zero 33462306a36Sopenharmony_ci * 33562306a36Sopenharmony_ci * The scatter/gather list for fh_partition_memcpy() is an array of these 33662306a36Sopenharmony_ci * structures. The array must be guest physically contiguous. 33762306a36Sopenharmony_ci * 33862306a36Sopenharmony_ci * This structure must be aligned on 32-byte boundary, so that no single 33962306a36Sopenharmony_ci * strucuture can span two pages. 34062306a36Sopenharmony_ci */ 34162306a36Sopenharmony_cistruct fh_sg_list { 34262306a36Sopenharmony_ci uint64_t source; /**< guest physical address to copy from */ 34362306a36Sopenharmony_ci uint64_t target; /**< guest physical address to copy to */ 34462306a36Sopenharmony_ci uint64_t size; /**< number of bytes to copy */ 34562306a36Sopenharmony_ci uint64_t reserved; /**< reserved, must be zero */ 34662306a36Sopenharmony_ci} __attribute__ ((aligned(32))); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci/** 34962306a36Sopenharmony_ci * fh_partition_memcpy - copies data from one guest to another 35062306a36Sopenharmony_ci * @source: the ID of the partition to copy from 35162306a36Sopenharmony_ci * @target: the ID of the partition to copy to 35262306a36Sopenharmony_ci * @sg_list: guest physical address of an array of &fh_sg_list structures 35362306a36Sopenharmony_ci * @count: the number of entries in @sg_list 35462306a36Sopenharmony_ci * 35562306a36Sopenharmony_ci * Returns 0 for success, or an error code. 35662306a36Sopenharmony_ci */ 35762306a36Sopenharmony_cistatic inline unsigned int fh_partition_memcpy(unsigned int source, 35862306a36Sopenharmony_ci unsigned int target, phys_addr_t sg_list, unsigned int count) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 36162306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 36262306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 36362306a36Sopenharmony_ci register uintptr_t r5 __asm__("r5"); 36462306a36Sopenharmony_ci register uintptr_t r6 __asm__("r6"); 36562306a36Sopenharmony_ci register uintptr_t r7 __asm__("r7"); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_MEMCPY); 36862306a36Sopenharmony_ci r3 = source; 36962306a36Sopenharmony_ci r4 = target; 37062306a36Sopenharmony_ci r5 = (uint32_t) sg_list; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci#ifdef CONFIG_PHYS_64BIT 37362306a36Sopenharmony_ci r6 = sg_list >> 32; 37462306a36Sopenharmony_ci#else 37562306a36Sopenharmony_ci r6 = 0; 37662306a36Sopenharmony_ci#endif 37762306a36Sopenharmony_ci r7 = count; 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 38062306a36Sopenharmony_ci : "+r" (r11), 38162306a36Sopenharmony_ci "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7) 38262306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS5 38362306a36Sopenharmony_ci ); 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci return r3; 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci/** 38962306a36Sopenharmony_ci * fh_dma_enable - enable DMA for the specified device 39062306a36Sopenharmony_ci * @liodn: the LIODN of the I/O device for which to enable DMA 39162306a36Sopenharmony_ci * 39262306a36Sopenharmony_ci * Returns 0 for success, or an error code. 39362306a36Sopenharmony_ci */ 39462306a36Sopenharmony_cistatic inline unsigned int fh_dma_enable(unsigned int liodn) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 39762306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_DMA_ENABLE); 40062306a36Sopenharmony_ci r3 = liodn; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 40362306a36Sopenharmony_ci : "+r" (r11), "+r" (r3) 40462306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 40562306a36Sopenharmony_ci ); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci return r3; 40862306a36Sopenharmony_ci} 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci/** 41162306a36Sopenharmony_ci * fh_dma_disable - disable DMA for the specified device 41262306a36Sopenharmony_ci * @liodn: the LIODN of the I/O device for which to disable DMA 41362306a36Sopenharmony_ci * 41462306a36Sopenharmony_ci * Returns 0 for success, or an error code. 41562306a36Sopenharmony_ci */ 41662306a36Sopenharmony_cistatic inline unsigned int fh_dma_disable(unsigned int liodn) 41762306a36Sopenharmony_ci{ 41862306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 41962306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_DMA_DISABLE); 42262306a36Sopenharmony_ci r3 = liodn; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 42562306a36Sopenharmony_ci : "+r" (r11), "+r" (r3) 42662306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 42762306a36Sopenharmony_ci ); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci return r3; 43062306a36Sopenharmony_ci} 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci/** 43462306a36Sopenharmony_ci * fh_vmpic_get_msir - returns the MPIC-MSI register value 43562306a36Sopenharmony_ci * @interrupt: the interrupt number 43662306a36Sopenharmony_ci * @msir_val: returned MPIC-MSI register value 43762306a36Sopenharmony_ci * 43862306a36Sopenharmony_ci * Returns 0 for success, or an error code. 43962306a36Sopenharmony_ci */ 44062306a36Sopenharmony_cistatic inline unsigned int fh_vmpic_get_msir(unsigned int interrupt, 44162306a36Sopenharmony_ci unsigned int *msir_val) 44262306a36Sopenharmony_ci{ 44362306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 44462306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 44562306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_VMPIC_GET_MSIR); 44862306a36Sopenharmony_ci r3 = interrupt; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 45162306a36Sopenharmony_ci : "+r" (r11), "+r" (r3), "=r" (r4) 45262306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS2 45362306a36Sopenharmony_ci ); 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci *msir_val = r4; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci return r3; 45862306a36Sopenharmony_ci} 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci/** 46162306a36Sopenharmony_ci * fh_system_reset - reset the system 46262306a36Sopenharmony_ci * 46362306a36Sopenharmony_ci * Returns 0 for success, or an error code. 46462306a36Sopenharmony_ci */ 46562306a36Sopenharmony_cistatic inline unsigned int fh_system_reset(void) 46662306a36Sopenharmony_ci{ 46762306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 46862306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_SYSTEM_RESET); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 47362306a36Sopenharmony_ci : "+r" (r11), "=r" (r3) 47462306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 47562306a36Sopenharmony_ci ); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci return r3; 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci/** 48262306a36Sopenharmony_ci * fh_err_get_info - get platform error information 48362306a36Sopenharmony_ci * @queue id: 48462306a36Sopenharmony_ci * 0 for guest error event queue 48562306a36Sopenharmony_ci * 1 for global error event queue 48662306a36Sopenharmony_ci * 48762306a36Sopenharmony_ci * @pointer to store the platform error data: 48862306a36Sopenharmony_ci * platform error data is returned in registers r4 - r11 48962306a36Sopenharmony_ci * 49062306a36Sopenharmony_ci * Returns 0 for success, or an error code. 49162306a36Sopenharmony_ci */ 49262306a36Sopenharmony_cistatic inline unsigned int fh_err_get_info(int queue, uint32_t *bufsize, 49362306a36Sopenharmony_ci uint32_t addr_hi, uint32_t addr_lo, int peek) 49462306a36Sopenharmony_ci{ 49562306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 49662306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 49762306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 49862306a36Sopenharmony_ci register uintptr_t r5 __asm__("r5"); 49962306a36Sopenharmony_ci register uintptr_t r6 __asm__("r6"); 50062306a36Sopenharmony_ci register uintptr_t r7 __asm__("r7"); 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_ERR_GET_INFO); 50362306a36Sopenharmony_ci r3 = queue; 50462306a36Sopenharmony_ci r4 = *bufsize; 50562306a36Sopenharmony_ci r5 = addr_hi; 50662306a36Sopenharmony_ci r6 = addr_lo; 50762306a36Sopenharmony_ci r7 = peek; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 51062306a36Sopenharmony_ci : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), 51162306a36Sopenharmony_ci "+r" (r7) 51262306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS5 51362306a36Sopenharmony_ci ); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci *bufsize = r4; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci return r3; 51862306a36Sopenharmony_ci} 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci#define FH_VCPU_RUN 0 52262306a36Sopenharmony_ci#define FH_VCPU_IDLE 1 52362306a36Sopenharmony_ci#define FH_VCPU_NAP 2 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci/** 52662306a36Sopenharmony_ci * fh_get_core_state - get the state of a vcpu 52762306a36Sopenharmony_ci * 52862306a36Sopenharmony_ci * @handle: handle of partition containing the vcpu 52962306a36Sopenharmony_ci * @vcpu: vcpu number within the partition 53062306a36Sopenharmony_ci * @state:the current state of the vcpu, see FH_VCPU_* 53162306a36Sopenharmony_ci * 53262306a36Sopenharmony_ci * Returns 0 for success, or an error code. 53362306a36Sopenharmony_ci */ 53462306a36Sopenharmony_cistatic inline unsigned int fh_get_core_state(unsigned int handle, 53562306a36Sopenharmony_ci unsigned int vcpu, unsigned int *state) 53662306a36Sopenharmony_ci{ 53762306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 53862306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 53962306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_GET_CORE_STATE); 54262306a36Sopenharmony_ci r3 = handle; 54362306a36Sopenharmony_ci r4 = vcpu; 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 54662306a36Sopenharmony_ci : "+r" (r11), "+r" (r3), "+r" (r4) 54762306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS2 54862306a36Sopenharmony_ci ); 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci *state = r4; 55162306a36Sopenharmony_ci return r3; 55262306a36Sopenharmony_ci} 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci/** 55562306a36Sopenharmony_ci * fh_enter_nap - enter nap on a vcpu 55662306a36Sopenharmony_ci * 55762306a36Sopenharmony_ci * Note that though the API supports entering nap on a vcpu other 55862306a36Sopenharmony_ci * than the caller, this may not be implmented and may return EINVAL. 55962306a36Sopenharmony_ci * 56062306a36Sopenharmony_ci * @handle: handle of partition containing the vcpu 56162306a36Sopenharmony_ci * @vcpu: vcpu number within the partition 56262306a36Sopenharmony_ci * 56362306a36Sopenharmony_ci * Returns 0 for success, or an error code. 56462306a36Sopenharmony_ci */ 56562306a36Sopenharmony_cistatic inline unsigned int fh_enter_nap(unsigned int handle, unsigned int vcpu) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 56862306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 56962306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_ENTER_NAP); 57262306a36Sopenharmony_ci r3 = handle; 57362306a36Sopenharmony_ci r4 = vcpu; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 57662306a36Sopenharmony_ci : "+r" (r11), "+r" (r3), "+r" (r4) 57762306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS2 57862306a36Sopenharmony_ci ); 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci return r3; 58162306a36Sopenharmony_ci} 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci/** 58462306a36Sopenharmony_ci * fh_exit_nap - exit nap on a vcpu 58562306a36Sopenharmony_ci * @handle: handle of partition containing the vcpu 58662306a36Sopenharmony_ci * @vcpu: vcpu number within the partition 58762306a36Sopenharmony_ci * 58862306a36Sopenharmony_ci * Returns 0 for success, or an error code. 58962306a36Sopenharmony_ci */ 59062306a36Sopenharmony_cistatic inline unsigned int fh_exit_nap(unsigned int handle, unsigned int vcpu) 59162306a36Sopenharmony_ci{ 59262306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 59362306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 59462306a36Sopenharmony_ci register uintptr_t r4 __asm__("r4"); 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_EXIT_NAP); 59762306a36Sopenharmony_ci r3 = handle; 59862306a36Sopenharmony_ci r4 = vcpu; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 60162306a36Sopenharmony_ci : "+r" (r11), "+r" (r3), "+r" (r4) 60262306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS2 60362306a36Sopenharmony_ci ); 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci return r3; 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci/** 60862306a36Sopenharmony_ci * fh_claim_device - claim a "claimable" shared device 60962306a36Sopenharmony_ci * @handle: fsl,hv-device-handle of node to claim 61062306a36Sopenharmony_ci * 61162306a36Sopenharmony_ci * Returns 0 for success, or an error code. 61262306a36Sopenharmony_ci */ 61362306a36Sopenharmony_cistatic inline unsigned int fh_claim_device(unsigned int handle) 61462306a36Sopenharmony_ci{ 61562306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 61662306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_CLAIM_DEVICE); 61962306a36Sopenharmony_ci r3 = handle; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 62262306a36Sopenharmony_ci : "+r" (r11), "+r" (r3) 62362306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 62462306a36Sopenharmony_ci ); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci return r3; 62762306a36Sopenharmony_ci} 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci/** 63062306a36Sopenharmony_ci * Run deferred DMA disabling on a partition's private devices 63162306a36Sopenharmony_ci * 63262306a36Sopenharmony_ci * This applies to devices which a partition owns either privately, 63362306a36Sopenharmony_ci * or which are claimable and still actively owned by that partition, 63462306a36Sopenharmony_ci * and which do not have the no-dma-disable property. 63562306a36Sopenharmony_ci * 63662306a36Sopenharmony_ci * @handle: partition (must be stopped) whose DMA is to be disabled 63762306a36Sopenharmony_ci * 63862306a36Sopenharmony_ci * Returns 0 for success, or an error code. 63962306a36Sopenharmony_ci */ 64062306a36Sopenharmony_cistatic inline unsigned int fh_partition_stop_dma(unsigned int handle) 64162306a36Sopenharmony_ci{ 64262306a36Sopenharmony_ci register uintptr_t r11 __asm__("r11"); 64362306a36Sopenharmony_ci register uintptr_t r3 __asm__("r3"); 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP_DMA); 64662306a36Sopenharmony_ci r3 = handle; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci asm volatile("bl epapr_hypercall_start" 64962306a36Sopenharmony_ci : "+r" (r11), "+r" (r3) 65062306a36Sopenharmony_ci : : EV_HCALL_CLOBBERS1 65162306a36Sopenharmony_ci ); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci return r3; 65462306a36Sopenharmony_ci} 65562306a36Sopenharmony_ci#endif 656