summaryrefslogtreecommitdiff
path: root/src/apps_mem_imp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/apps_mem_imp.c')
-rw-r--r--src/apps_mem_imp.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/apps_mem_imp.c b/src/apps_mem_imp.c
new file mode 100644
index 0000000..d6f2ccb
--- /dev/null
+++ b/src/apps_mem_imp.c
@@ -0,0 +1,244 @@
+/*
+ * 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 VERIFY_PRINT_ERROR
+#define VERIFY_PRINT_ERROR
+#endif /* VERIFY_PRINT_ERROR */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/mman.h>
+#include "apps_mem.h"
+#include "remote64.h"
+#include "rpcmem.h"
+#include "verify.h"
+#include "rpcmem.h"
+#include "AEEQList.h"
+#include "AEEstd.h"
+#include "AEEStdErr.h"
+#include "fastrpc_apps_user.h"
+#include "platform_libs.h"
+
+#define ADSP_MMAP_HEAP_ADDR 4
+#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
+#define ADSP_MMAP_ADD_PAGES 0x1000
+
+static QList memlst;
+static pthread_mutex_t memmt;
+
+struct mem_info {
+ QNode qn;
+ uint64 vapps;
+ uint64 vadsp;
+ int32 size;
+ int32 mapped;
+};
+
+/*
+These should be called in some static constructor of the .so that
+uses rpcmem.
+
+I moved them into fastrpc_apps_user.c because there is no gurantee in
+the order of when constructors are called.
+*/
+
+static int apps_mem_init(void) {
+ QList_Ctor(&memlst);
+ pthread_mutex_init(&memmt, 0);
+ return AEE_SUCCESS;
+}
+
+void apps_mem_deinit(void) {
+ QNode *pn;
+ while ((pn = QList_PopZ(&memlst)) != NULL) {
+ struct mem_info *mfree = STD_RECOVER_REC(struct mem_info, qn, pn);
+
+ if (mfree->vapps) {
+ if(mfree->mapped) {
+ munmap((void*)(uintptr_t)mfree->vapps, mfree->size);
+ } else {
+ rpcmem_free_internal((void *)(uintptr_t)mfree->vapps);
+ }
+ }
+ free(mfree);
+ mfree = NULL;
+ }
+ pthread_mutex_destroy(&memmt);
+}
+PL_DEFINE(apps_mem, apps_mem_init, apps_mem_deinit);
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_map64)(int heapid, uint32 lflags, uint32 rflags, uint64 vin, int64 len, uint64* vapps, uint64* vadsp) __QAIC_IMPL_ATTRIBUTE {
+ struct mem_info *minfo = 0;
+ int nErr = 0;
+ void* buf = 0;
+ uint64_t pbuf;
+ int fd = -1;
+
+ (void)vin;
+ VERIFYC(NULL != (minfo = malloc(sizeof(*minfo))), AEE_ENOMEMORY);
+ QNode_CtorZ(&minfo->qn);
+ *vadsp = 0;
+ if (rflags == ADSP_MMAP_HEAP_ADDR || rflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+ VERIFY(AEE_SUCCESS == (nErr = remote_mmap64(-1, rflags, 0, len, (uint64_t*)vadsp)));
+ *vapps = 0;
+ minfo->vapps = 0;
+ } else {
+ if ((rflags != ADSP_MMAP_ADD_PAGES) ||
+ ((rflags == ADSP_MMAP_ADD_PAGES) && !is_kernel_alloc_supported(-1, -1))) {
+ VERIFYC(NULL != (buf = rpcmem_alloc_internal(heapid, lflags, len)), AEE_ENORPCMEMORY);
+ fd = rpcmem_to_fd_internal(buf);
+ VERIFYC(fd > 0, AEE_EINVALIDFD);
+ }
+ VERIFY(AEE_SUCCESS == (nErr = remote_mmap64(fd, rflags, (uint64_t)buf, len, (uint64_t*)vadsp)));
+ pbuf = (uint64_t)buf;
+ *vapps = pbuf;
+ minfo->vapps = *vapps;
+ }
+ minfo->vadsp = *vadsp;
+ minfo->size = len;
+ minfo->mapped = 0;
+ pthread_mutex_lock(&memmt);
+ QList_AppendNode(&memlst, &minfo->qn);
+ pthread_mutex_unlock(&memmt);
+bail:
+ if(nErr) {
+ if(buf) {
+ rpcmem_free_internal(buf);
+ buf = NULL;
+ }
+ if(minfo) {
+ free(minfo);
+ minfo = NULL;
+ }
+ VERIFY_EPRINTF("Error %x: apps_mem_request_mmap64 failed\n", nErr);
+ }
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_map)(int heapid, uint32 lflags, uint32 rflags, uint32 vin, int32 len, uint32* vapps, uint32* vadsp) __QAIC_IMPL_ATTRIBUTE {
+ uint64 vin1, vapps1, vadsp1;
+ int64 len1;
+ int nErr = AEE_SUCCESS;
+ vin1 = (uint64)vin;
+ len1 = (int64)len;
+ nErr = apps_mem_request_map64(heapid, lflags, rflags, vin1, len1, &vapps1, &vadsp1);
+ *vapps = (uint32)vapps1;
+ *vadsp = (uint32)vadsp1;
+ if(nErr != AEE_SUCCESS) {
+ VERIFY_EPRINTF("Error %x: apps_mem_request_map failed\n", nErr);
+ }
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_unmap64)(uint64 vadsp, int64 len) __QAIC_IMPL_ATTRIBUTE {
+ int nErr = AEE_SUCCESS;
+ struct mem_info *minfo, *mfree = 0;
+ QNode *pn, *pnn;
+ VERIFY(0 == (nErr = remote_munmap64((uint64_t)vadsp, len)));
+ pthread_mutex_lock(&memmt);
+ QLIST_NEXTSAFE_FOR_ALL(&memlst, pn, pnn) {
+ minfo = STD_RECOVER_REC(struct mem_info, qn, pn);
+ if(minfo->vadsp == vadsp) {
+ mfree = minfo;
+ QNode_Dequeue(&minfo->qn);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&memmt);
+ VERIFYC(mfree, AEE_ENOSUCHMAP);
+ if(mfree->mapped) {
+ munmap((void*)(uintptr_t)mfree->vapps, mfree->size);
+ } else {
+ if (mfree->vapps)
+ rpcmem_free_internal((void *)(uintptr_t)mfree->vapps);
+ }
+ free(mfree);
+ mfree = NULL;
+bail:
+ if(nErr != AEE_SUCCESS) {
+ VERIFY_EPRINTF("Error %x: apps_mem_request_unmap64 failed\n", nErr);
+ }
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_unmap)(uint32 vadsp, int32 len) __QAIC_IMPL_ATTRIBUTE {
+ uint64 vadsp1 = (uint64)vadsp;
+ int64 len1 = (int64)len;
+ int nErr = apps_mem_request_unmap64(vadsp1, len1);
+ if(nErr != AEE_SUCCESS) {
+ VERIFY_EPRINTF("Error %x: apps_mem_request_unmap failed\n", nErr);
+ }
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_share_map)(int fd, int size, uint64* vapps, uint64* vadsp) __QAIC_IMPL_ATTRIBUTE {
+ struct mem_info *minfo = 0;
+ int nErr = AEE_SUCCESS;
+ void* buf = 0;
+ uint64_t pbuf;
+ VERIFYC(0 != (minfo = malloc(sizeof(*minfo))), AEE_ENOMEMORY);
+ QNode_CtorZ(&minfo->qn);
+ VERIFYC(fd > 0, AEE_EINVALIDFD);
+ *vadsp = 0;
+ VERIFYC(MAP_FAILED != (buf = (void *)mmap(NULL, size,
+ PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)), AEE_EMMAP);
+ VERIFY(AEE_SUCCESS == (nErr = remote_mmap64(fd, 0, (uint64_t)buf, size, (uint64_t*)vadsp)));
+ pbuf = (uint64_t)buf;
+ *vapps = pbuf;
+ minfo->vapps = *vapps;
+ minfo->vadsp = *vadsp;
+ minfo->size = size;
+ minfo->mapped = 1;
+ pthread_mutex_lock(&memmt);
+ QList_AppendNode(&memlst, &minfo->qn);
+ pthread_mutex_unlock(&memmt);
+bail:
+ if(nErr) {
+ if(buf) {
+ munmap(buf, size);
+ }
+ if(minfo) {
+ free(minfo);
+ minfo = NULL;
+ }
+ VERIFY_EPRINTF("Error %x: apps_mem_share_map failed\n", nErr);
+ }
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_share_unmap)(uint64 vadsp, int size) __QAIC_IMPL_ATTRIBUTE {
+ int64 len1 = (int64)size;
+ int nErr = AEE_SUCCESS;
+ nErr = apps_mem_request_unmap64(vadsp, len1);
+ if(nErr != AEE_SUCCESS) {
+ VERIFY_EPRINTF("Error %x: apps_mem_share_unmap failed\n", nErr);
+ }
+ return nErr;
+}