| /** | |
| * Copyright (c) 2019, The Linux Foundation. All rights reserved. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: | |
| * * Redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer. | |
| * * Redistributions in binary form must reproduce the above | |
| * copyright notice, this list of conditions and the following | |
| * disclaimer in the documentation and/or other materials provided | |
| * with the distribution. | |
| * * Neither the name of The Linux Foundation nor the names of its | |
| * contributors may be used to endorse or promote products derived | |
| * from this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| */ | |
| #ifndef FASTRPC_INTERNAL_H | |
| #define FASTRPC_INTERNAL_H | |
| #include <linux/types.h> | |
| #include "remote64.h" | |
| #include "verify.h" | |
| #include "AEEstd.h" | |
| #define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_alloc_dma_buf) | |
| #define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, uint32_t) | |
| #define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke) | |
| #define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4) | |
| #define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create) | |
| #define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_ioctl_mmap) | |
| #define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_ioctl_munmap) | |
| #define DEVICE_NAME "adsprpc-smd" | |
| #if !(defined __qdsp6__) && !(defined __hexagon__) | |
| static __inline uint32 Q6_R_cl0_R(uint32 num) { | |
| int ii; | |
| for(ii = 31; ii >= 0; --ii) { | |
| if(num & (1 << ii)) { | |
| return 31 - ii; | |
| } | |
| } | |
| return 0; | |
| } | |
| #else | |
| #include "hexagon_protos.h" | |
| #include <types.h> | |
| #endif | |
| #define FASTRPC_INFO_SMMU (1 << 0) | |
| /* struct fastrpc_invoke_args { | |
| __u64 ptr; | |
| __u64 length; | |
| __s32 fd; | |
| __u32 attrs; | |
| __u32 crc; | |
| }; */ | |
| struct fastrpc_invoke_args { | |
| __u64 ptr; | |
| __u64 length; | |
| __s32 fd; | |
| __u32 reserved; | |
| }; | |
| struct fastrpc_invoke { | |
| __u32 handle; | |
| __u32 sc; | |
| __u64 args; | |
| }; | |
| #define FASTRPC_ATTR_NOVA (1) | |
| #define FASTRPC_ATTR_NOMAP (16) | |
| #define GUEST_OS 0 | |
| #define USER_PD -1 | |
| #define STATIC_USER_PD 1 | |
| #define ATTACH_SENSORS_PD 2 | |
| #define GUEST_OS_SHARED 3 | |
| struct fastrpc_init_create { | |
| __u32 filelen; /* elf file length */ | |
| __s32 filefd; /* fd for the file */ | |
| __u32 attrs; | |
| __u32 siglen; | |
| __u64 file; /* pointer to elf file */ | |
| }; | |
| #define FASTRPC_ATTR_DEBUG_PROCESS (1) | |
| struct fastrpc_alloc_dma_buf { | |
| __s32 fd; /* fd */ | |
| __u32 flags; /* flags to map with */ | |
| __u64 size; /* size */ | |
| }; | |
| struct fastrpc_ioctl_mmap { | |
| __s32 fd; /* fd */ | |
| __u32 flags; /* flags for dsp to map with */ | |
| __u64 vaddrin; /* optional virtual address */ | |
| __u64 size; /* size */ | |
| __u64 vaddrout; /* dsps virtual address */ | |
| }; | |
| struct fastrpc_ioctl_munmap { | |
| __u64 vaddrout; /* address to unmap */ | |
| __u64 size; /* size */ | |
| }; | |
| #define FASTRPC_CONTROL_LATENCY (1) | |
| struct fastrpc_ctrl_latency { | |
| uint32_t enable; //!latency control enable | |
| uint32_t level; //!level of control | |
| }; | |
| #define FASTRPC_CONTROL_SMMU (2) | |
| struct fastrpc_ctrl_smmu { | |
| uint32_t sharedcb; | |
| }; | |
| #define FASTRPC_CONTROL_KALLOC (3) | |
| struct fastrpc_ctrl_kalloc { | |
| uint32_t kalloc_support; | |
| }; | |
| struct fastrpc_ioctl_control { | |
| uint32_t req; | |
| union { | |
| struct fastrpc_ctrl_latency lp; | |
| struct fastrpc_ctrl_smmu smmu; | |
| struct fastrpc_ctrl_kalloc kalloc; | |
| }; | |
| }; | |
| #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" | |
| struct smq_null_invoke32 { | |
| uint32_t ctx; //! invoke caller context | |
| remote_handle handle; //! handle to invoke | |
| uint32_t sc; //! scalars structure describing the rest of the data | |
| }; | |
| struct smq_null_invoke { | |
| uint64_t ctx; //! invoke caller context | |
| remote_handle handle; //! handle to invoke | |
| uint32_t sc; //! scalars structure describing the rest of the data | |
| }; | |
| typedef uint32_t smq_invoke_buf_phy_addr; | |
| struct smq_phy_page { | |
| uint64_t addr; //! physical address | |
| int64_t size; //! size | |
| }; | |
| struct smq_phy_page32 { | |
| uint32_t addr; //! physical address | |
| uint32_t size; //! size | |
| }; | |
| struct smq_invoke_buf { | |
| int num; | |
| int pgidx; | |
| }; | |
| struct smq_invoke32 { | |
| struct smq_null_invoke32 header; | |
| struct smq_phy_page32 page; //! remote arg and list of pages address | |
| }; | |
| struct smq_invoke { | |
| struct smq_null_invoke header; | |
| struct smq_phy_page page; //! remote arg and list of pages address | |
| }; | |
| struct smq_msg32 { | |
| uint32_t pid; | |
| uint32_t tid; | |
| struct smq_invoke32 invoke; | |
| }; | |
| struct smq_msg { | |
| uint32_t pid; | |
| uint32_t tid; | |
| struct smq_invoke invoke; | |
| }; | |
| struct smq_msg_u { | |
| union { | |
| struct smq_msg32 msg32; | |
| struct smq_msg msg64; | |
| } msg; | |
| int size; | |
| }; | |
| struct smq_invoke_rsp32 { | |
| uint32_t ctx; //! invoke caller context | |
| int nRetVal; //! invoke return value | |
| }; | |
| struct smq_invoke_rsp { | |
| uint64_t ctx; //! invoke caller context | |
| int nRetVal; //! invoke return value | |
| }; | |
| struct smq_invoke_rsp_u { | |
| union { | |
| struct smq_invoke_rsp32 rsp32; | |
| struct smq_invoke_rsp rsp64; | |
| } rsp; | |
| int size; | |
| }; | |
| static __inline void to_smq_msg(uint32 mode, struct smq_msg_u* msg, struct smq_msg* msg64) { | |
| if(0 == mode) { | |
| msg64->pid = msg->msg.msg32.pid; | |
| msg64->tid = msg->msg.msg32.tid; | |
| msg64->invoke.header.ctx = msg->msg.msg32.invoke.header.ctx; | |
| msg64->invoke.header.handle = msg->msg.msg32.invoke.header.handle; | |
| msg64->invoke.header.sc = msg->msg.msg32.invoke.header.sc; | |
| msg64->invoke.page.addr = msg->msg.msg32.invoke.page.addr; | |
| msg64->invoke.page.size = msg->msg.msg32.invoke.page.size; | |
| } else { | |
| std_memmove(msg64, &msg->msg.msg64, sizeof(*msg64)); | |
| } | |
| } | |
| static __inline void to_smq_invoke_rsp(uint32 mode, uint64 ctx, int nRetVal, struct smq_invoke_rsp_u* rsp) { | |
| if (0 == mode) { | |
| rsp->rsp.rsp32.ctx = (uint32)ctx; | |
| rsp->rsp.rsp32.nRetVal = nRetVal; | |
| rsp->size = sizeof(rsp->rsp.rsp32); | |
| } else { | |
| rsp->rsp.rsp64.ctx = ctx; | |
| rsp->rsp.rsp64.nRetVal = nRetVal; | |
| rsp->size = sizeof(rsp->rsp.rsp64); | |
| } | |
| } | |
| static __inline struct smq_invoke_buf* to_smq_invoke_buf_start(uint32 mode, void* virt, uint32 sc) { | |
| struct smq_invoke_buf* buf; | |
| int len = REMOTE_SCALARS_LENGTH(sc); | |
| if(0 == mode) { | |
| remote_arg* pra = (remote_arg*)virt; | |
| buf = (struct smq_invoke_buf*)(&pra[len]); | |
| } else { | |
| remote_arg64* pra = (remote_arg64*)virt; | |
| buf = (struct smq_invoke_buf*)(&pra[len]); | |
| } | |
| return buf; | |
| } | |
| static __inline struct smq_invoke_buf* smq_invoke_buf_start(remote_arg64 *pra, uint32 sc) { | |
| int len = REMOTE_SCALARS_LENGTH(sc); | |
| return (struct smq_invoke_buf*)(&pra[len]); | |
| } | |
| static __inline struct smq_phy_page* smq_phy_page_start(uint32 sc, struct smq_invoke_buf* buf) { | |
| int nTotal = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); | |
| return (struct smq_phy_page*)(&buf[nTotal]); | |
| } | |
| //! size of the out of band data | |
| static __inline int smq_data_size(uint32 sc, int nPages) { | |
| struct smq_invoke_buf* buf = smq_invoke_buf_start(0, sc); | |
| struct smq_phy_page* page = smq_phy_page_start(sc, buf); | |
| return (int)(uintptr_t)(&(page[nPages])); | |
| } | |
| static __inline void to_smq_data(uint32 mode, uint32 sc, int nPages, void* pv, remote_arg64* rpra) { | |
| if(0 == mode) { | |
| struct smq_phy_page* page; | |
| struct smq_phy_page32* page32; | |
| remote_arg *pra = (remote_arg*)pv; | |
| int ii, len; | |
| len = REMOTE_SCALARS_LENGTH(sc); | |
| for(ii = 0; ii < len; ++ii) { | |
| rpra[ii].buf.pv = (uint64)(uintptr_t)pra[ii].buf.pv; | |
| rpra[ii].buf.nLen = pra[ii].buf.nLen; | |
| } | |
| len = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); | |
| std_memmove(&rpra[ii], &pra[ii], len * sizeof(struct smq_invoke_buf)); | |
| page = (struct smq_phy_page*)((struct smq_invoke_buf*)&rpra[ii] + len); | |
| page32 = (struct smq_phy_page32*)((struct smq_invoke_buf*)&pra[ii] + len); | |
| for(ii = 0; ii < nPages; ++ii) { | |
| page[ii].addr = page32[ii].addr; | |
| page[ii].size = page32[ii].size; | |
| } | |
| } else { | |
| std_memmove(rpra, pv, smq_data_size(sc, nPages)); | |
| } | |
| } | |
| #endif // FASTRPC_INTERNAL_H |