Cleanup: removed directory qnx/src/ipc3x_dev/perfutils
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / rpmsg-omx / hlos / knl / Qnx / mmap_peer.c
1 /*
2  * $QNXLicenseC$
3 */
4 /*
5  * Copyright (c) 2010, Texas Instruments Incorporated
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * *  Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * *  Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * *  Neither the name of Texas Instruments Incorporated nor the names of
20  *    its contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
30  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  * */
35 /*
36 * mmap_peer/munmap_peer implementation PR47400
37 */
39 #include <unistd.h>
40 #include <errno.h>
41 #include <inttypes.h>
42 #include <sys/mman.h>
43 #include <sys/memmsg.h>
45 #include "proto.h"
48 int memmgr_peer_sendnc( pid_t pid, int coid, void *smsg, size_t sbytes, void *rmsg, size_t rbytes )
49 {
50         mem_peer_t      peer;
51         iov_t           siov[2];
53         peer.i.type = _MEM_PEER;
54         peer.i.peer_msg_len = sizeof(peer);
55         peer.i.pid = pid;
57         SETIOV(siov + 0, &peer, sizeof peer);
58         SETIOV(siov + 1, smsg, sbytes);
59         return MsgSendvsnc( coid, siov, 2, rmsg, rbytes );
60 }
62 void *
63 _mmap2_peer(pid_t pid, void *addr, size_t len, int prot, int flags, int fd, off64_t off,
64                 unsigned align, unsigned pre_load, void **base, size_t *size) {
65         mem_map_t                                               msg;
67         msg.i.type = _MEM_MAP;
68         msg.i.zero = 0;
69         msg.i.addr = (uintptr_t)addr;
70         msg.i.len = len;
71         msg.i.prot = prot;
72         msg.i.flags = flags;
73         msg.i.fd = fd;
74         msg.i.offset = off;
75         msg.i.align = align;
76         msg.i.preload = pre_load;
77         msg.i.reserved1 = 0;
78         if(memmgr_peer_sendnc(pid, MEMMGR_COID, &msg.i, sizeof msg.i, &msg.o, sizeof msg.o) == -1) {
79                 return MAP_FAILED;
80         }
81         if(base) {
82                 *base = (void *)(uintptr_t)msg.o.real_addr;
83         }
84         if(size) {
85                 *size = msg.o.real_size;
86         }
87         return (void *)(uintptr_t)msg.o.addr;
88 }
91 void *
92 mmap64_peer(pid_t pid, void *addr, size_t len, int prot, int flags, int fd, off64_t off) {
93         return _mmap2_peer(pid, addr, len, prot, flags, fd, off, 0, 0, 0, 0);
94 }
97 // Make an unsigned version of the 'off_t' type so that we get a zero
98 // extension down below.
99 #if __OFF_BITS__ == 32
100         typedef _Uint32t uoff_t;
101 #elif __OFF_BITS__ == 64
102         typedef _Uint64t uoff_t;
103 #else
104         #error Do not know what size to make uoff_t
105 #endif
107 void *
108 mmap_peer(pid_t pid, void *addr, size_t len, int prot, int flags, int fd, off_t off) {
109         return _mmap2_peer(pid, addr, len, prot, flags, fd, (uoff_t)off, 0, 0, 0, 0);
112 int
113 munmap_flags_peer(pid_t pid, void *addr, size_t len, unsigned flags) {
114         mem_ctrl_t                                              msg;
116         msg.i.type = _MEM_CTRL;
117         msg.i.subtype = _MEM_CTRL_UNMAP;
118         msg.i.addr = (uintptr_t)addr;
119         msg.i.len = len;
120         msg.i.flags = flags;
121         return memmgr_peer_sendnc(pid, MEMMGR_COID, &msg.i, sizeof msg.i, 0, 0);
124 int
125 munmap_peer(pid_t pid, void *addr, size_t len) {
126         return munmap_flags_peer(pid, addr, len, 0);
129 int
130 mem_offset64_peer(pid_t pid, const uintptr_t addr, size_t len,
131                                 off64_t *offset, size_t *contig_len) {
132         struct _peer_mem_off {
133                 struct _mem_peer peer;
134                 struct _mem_offset msg;
135         };
136         typedef union {
137                 struct _peer_mem_off i;
138                 struct _mem_offset_reply o;
139         } memoffset_peer_t;
140         memoffset_peer_t msg;
142         msg.i.peer.type = _MEM_PEER;
143         msg.i.peer.peer_msg_len = sizeof(msg.i.peer);
144         msg.i.peer.pid = pid;
145         msg.i.peer.reserved1 = 0;
147         msg.i.msg.type = _MEM_OFFSET;
148         msg.i.msg.subtype = _MEM_OFFSET_PHYS;
149         msg.i.msg.addr = addr;
150         msg.i.msg.reserved = -1;
151         msg.i.msg.len = len;
152         if(MsgSendnc(MEMMGR_COID, &msg.i, sizeof msg.i, &msg.o, sizeof msg.o) == -1) {
153                 return -1;
154         }
155         *offset = msg.o.offset;
156         *contig_len = msg.o.size;
157         return(0);
161 #if defined(__X86__)
162 #define CPU_VADDR_SERVER_HINT 0x30000000u
163 #elif defined(__ARM__)
164 #define CPU_VADDR_SERVER_HINT 0x20000000u
165 #else
166 #error NO CPU SOUP FOR YOU!
167 #endif
169 /*
170  * map the object into both client and server at the same virtual address
171  */
172 void *
173 mmap64_join(pid_t pid, void *addr, size_t len, int prot, int flags, int fd, off64_t off) {
174         void *svaddr, *cvaddr = MAP_FAILED;
175         uintptr_t hint = (uintptr_t)addr;
176         uintptr_t start_hint = hint;
178         if ( hint == 0 ) hint = (uintptr_t)CPU_VADDR_SERVER_HINT;
180         do {
181                 svaddr = mmap64( (void *)hint, len, prot, flags, fd, off );
182                 if ( svaddr == MAP_FAILED ) {
183                         break;
184                 }
185                 if ( svaddr == cvaddr ) {
186                         return svaddr;
187                 }
189                 cvaddr = mmap64_peer( pid, svaddr, len, prot, flags, fd, off );
190                 if ( cvaddr == MAP_FAILED ) {
191                         break;
192                 }
193                 if ( svaddr == cvaddr ) {
194                         return svaddr;
195                 }
197                 if ( munmap( svaddr, len ) == -1 ) {
198                         svaddr = MAP_FAILED;
199                         break;
200                 }
202                 svaddr = mmap64( cvaddr, len, prot, flags, fd, off );
203                 if ( svaddr == MAP_FAILED ) {
204                         break;
205                 }
206                 if ( svaddr == cvaddr ) {
207                         return svaddr;
208                 }
210                 if ( munmap( svaddr, len ) == -1 ) {
211                         svaddr = MAP_FAILED;
212                         break;
213                 }
214                 if ( munmap_peer( pid, cvaddr, len ) == -1 ) {
215                         cvaddr = MAP_FAILED;
216                         break;
217                 }
219                 hint += __PAGESIZE;
221         } while(hint != start_hint); /* do we really want to wrap all the way */
223         if ( svaddr != MAP_FAILED ) {
224                 munmap( svaddr, len );
225         }
226         if ( cvaddr != MAP_FAILED ) {
227                 munmap_peer( pid, cvaddr, len );
228         }
229         return MAP_FAILED;