mailbox.c
Go to the documentation of this file.
1 /*
2 Copyright (c) 2012, Broadcom Europe Ltd.
3 Copyright (c) 2016, Jeremy Garff
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the copyright holder nor the
14  names of its contributors may be used to endorse or promote products
15  derived from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <assert.h>
35 #include <stdint.h>
36 #include <errno.h>
37 #include <unistd.h>
38 #include <sys/mman.h>
39 #include <sys/ioctl.h>
40 #include <sys/sysmacros.h>
41 #include <sys/stat.h>
42 
43 #include "mailbox.h"
44 
45 
46 void *mapmem(uint32_t base, uint32_t size, const char *mem_dev) {
47  uint32_t pagemask = ~0UL ^ (getpagesize() - 1);
48  uint32_t offsetmask = getpagesize() - 1;
49  int mem_fd;
50  void *mem;
51 
52  mem_fd = open(mem_dev, O_RDWR | O_SYNC);
53  if (mem_fd < 0) {
54  perror("Can't open /dev/mem");
55  return NULL;
56  }
57 
58  mem = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, base & pagemask);
59  if (mem == MAP_FAILED) {
60  perror("mmap error\n");
61  return NULL;
62  }
63 
64  close(mem_fd);
65 
66  return (char *)mem + (base & offsetmask);
67 }
68 
69 void *unmapmem(void *addr, uint32_t size) {
70  uint32_t pagemask = ~0UL ^ (getpagesize() - 1);
71  uintptr_t baseaddr = (uintptr_t)addr & pagemask;
72  int s;
73 
74  s = munmap((void *)baseaddr, size);
75  if (s != 0) {
76  perror("munmap error\n");
77  }
78 
79  return NULL;
80 }
81 
82 /*
83  * use ioctl to send mbox property message
84  */
85 
86 static int mbox_property(int file_desc, void *buf) {
87  int fd = file_desc;
88  int ret_val = -1;
89 
90  if (fd < 0) {
91  fd = mbox_open();
92  }
93 
94  if (fd >= 0) {
95  ret_val = ioctl(fd, IOCTL_MBOX_PROPERTY, buf);
96 
97  if (ret_val < 0) {
98  perror("ioctl_set_msg failed\n");
99  }
100  }
101 
102  if (file_desc < 0) {
103  mbox_close(fd);
104  }
105 
106  return ret_val;
107 }
108 
109 uint32_t mem_alloc(int file_desc, uint32_t size, uint32_t align, uint32_t flags) {
110  int i=0;
111  uint32_t p[32];
112 
113  p[i++] = 0; // size
114  p[i++] = 0x00000000; // process request
115 
116  p[i++] = 0x3000c; // (the tag id)
117  p[i++] = 12; // (size of the buffer)
118  p[i++] = 12; // (size of the data)
119  p[i++] = size; // (num bytes? or pages?)
120  p[i++] = align; // (alignment)
121  p[i++] = flags; // (MEM_FLAG_L1_NONALLOCATING)
122 
123  p[i++] = 0x00000000; // end tag
124  p[0] = i*sizeof *p; // actual size
125 
126  if (mbox_property(file_desc, p) < 0)
127  return 0;
128  else
129  return p[5];
130 }
131 
132 uint32_t mem_free(int file_desc, uint32_t handle) {
133  int i=0;
134  uint32_t p[32];
135 
136  p[i++] = 0; // size
137  p[i++] = 0x00000000; // process request
138 
139  p[i++] = 0x3000f; // (the tag id)
140  p[i++] = 4; // (size of the buffer)
141  p[i++] = 4; // (size of the data)
142  p[i++] = handle;
143 
144  p[i++] = 0x00000000; // end tag
145  p[0] = i*sizeof *p; // actual size
146 
147  mbox_property(file_desc, p);
148 
149  return p[5];
150 }
151 
152 uint32_t mem_lock(int file_desc, uint32_t handle) {
153  int i=0;
154  uint32_t p[32];
155 
156  p[i++] = 0; // size
157  p[i++] = 0x00000000; // process request
158 
159  p[i++] = 0x3000d; // (the tag id)
160  p[i++] = 4; // (size of the buffer)
161  p[i++] = 4; // (size of the data)
162  p[i++] = handle;
163 
164  p[i++] = 0x00000000; // end tag
165  p[0] = i*sizeof *p; // actual size
166 
167  if (mbox_property(file_desc, p) < 0)
168  return ~0;
169  else
170  return p[5];
171 }
172 
173 uint32_t mem_unlock(int file_desc, uint32_t handle) {
174  int i=0;
175  uint32_t p[32];
176 
177  p[i++] = 0; // size
178  p[i++] = 0x00000000; // process request
179 
180  p[i++] = 0x3000e; // (the tag id)
181  p[i++] = 4; // (size of the buffer)
182  p[i++] = 4; // (size of the data)
183  p[i++] = handle;
184 
185  p[i++] = 0x00000000; // end tag
186  p[0] = i * sizeof(*p); // actual size
187 
188  mbox_property(file_desc, p);
189 
190  return p[5];
191 }
192 
193 uint32_t execute_code(int file_desc, uint32_t code, uint32_t r0, uint32_t r1,
194  uint32_t r2, uint32_t r3, uint32_t r4, uint32_t r5) {
195  int i=0;
196  uint32_t p[32];
197 
198  p[i++] = 0; // size
199  p[i++] = 0x00000000; // process request
200 
201  p[i++] = 0x30010; // (the tag id)
202  p[i++] = 28; // (size of the buffer)
203  p[i++] = 28; // (size of the data)
204  p[i++] = code;
205  p[i++] = r0;
206  p[i++] = r1;
207  p[i++] = r2;
208  p[i++] = r3;
209  p[i++] = r4;
210  p[i++] = r5;
211 
212  p[i++] = 0x00000000; // end tag
213  p[0] = i * sizeof(*p); // actual size
214 
215  mbox_property(file_desc, p);
216 
217  return p[5];
218 }
219 
220 uint32_t qpu_enable(int file_desc, uint32_t enable) {
221  int i=0;
222  uint32_t p[32];
223 
224  p[i++] = 0; // size
225  p[i++] = 0x00000000; // process request
226 
227  p[i++] = 0x30012; // (the tag id)
228  p[i++] = 4; // (size of the buffer)
229  p[i++] = 4; // (size of the data)
230  p[i++] = enable;
231 
232  p[i++] = 0x00000000; // end tag
233  p[0] = i * sizeof(*p); // actual size
234 
235  mbox_property(file_desc, p);
236 
237  return p[5];
238 }
239 
240 uint32_t execute_qpu(int file_desc, uint32_t num_qpus, uint32_t control,
241  uint32_t noflush, uint32_t timeout) {
242  int i = 0;
243  uint32_t p[32];
244 
245  p[i++] = 0; // size
246  p[i++] = 0x00000000; // process request
247  p[i++] = 0x30011; // (the tag id)
248  p[i++] = 16; // (size of the buffer)
249  p[i++] = 16; // (size of the data)
250  p[i++] = num_qpus;
251  p[i++] = control;
252  p[i++] = noflush;
253  p[i++] = timeout; // ms
254 
255  p[i++] = 0x00000000; // end tag
256  p[0] = i * sizeof(*p); // actual size
257 
258  mbox_property(file_desc, p);
259 
260  return p[5];
261 }
262 
263 int mbox_open(void) {
264  int file_desc;
265  char filename[64];
266 
267  file_desc = open("/dev/vcio", 0);
268  if (file_desc >= 0) {
269  return file_desc;
270  }
271 
272  // open a char device file used for communicating with kernel mbox driver
273  sprintf(filename, "/tmp/mailbox-%d", getpid());
274  unlink(filename);
275  if (mknod(filename, S_IFCHR|0600, makedev(100, 0)) < 0) {
276  perror("Failed to create mailbox device\n");
277  return -1;
278  }
279  file_desc = open(filename, 0);
280  if (file_desc < 0) {
281  perror("Can't open device file\n");
282  unlink(filename);
283  return -1;
284  }
285  unlink(filename);
286 
287  return file_desc;
288 }
289 
290 void mbox_close(int file_desc) {
291  close(file_desc);
292 }
int mbox_open(void)
Definition: mailbox.c:263
void mbox_close(int file_desc)
Definition: mailbox.c:290
uint32_t mem_lock(int file_desc, uint32_t handle)
Definition: mailbox.c:152
static int mbox_property(int file_desc, void *buf)
Definition: mailbox.c:86
XmlRpcServer s
#define IOCTL_MBOX_PROPERTY
Definition: mailbox.h:31
void * mapmem(uint32_t base, uint32_t size, const char *mem_dev)
Definition: mailbox.c:46
void * unmapmem(void *addr, uint32_t size)
Definition: mailbox.c:69
uint32_t mem_alloc(int file_desc, uint32_t size, uint32_t align, uint32_t flags)
Definition: mailbox.c:109
uint32_t execute_code(int file_desc, uint32_t code, uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3, uint32_t r4, uint32_t r5)
Definition: mailbox.c:193
uint32_t mem_unlock(int file_desc, uint32_t handle)
Definition: mailbox.c:173
uint32_t execute_qpu(int file_desc, uint32_t num_qpus, uint32_t control, uint32_t noflush, uint32_t timeout)
Definition: mailbox.c:240
uint32_t qpu_enable(int file_desc, uint32_t enable)
Definition: mailbox.c:220
uint32_t mem_free(int file_desc, uint32_t handle)
Definition: mailbox.c:132


ws281x
Author(s): Alexey Rogachevskiy , Oleg Kalachev
autogenerated on Wed Jun 15 2022 02:46:00