| /** |
| * 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 |