]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/bus_space/Python/lang.c
MFV r308954:
[FreeBSD/FreeBSD.git] / tools / bus_space / Python / lang.c
1 /*-
2  * Copyright (c) 2014, 2015 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <Python.h>
31
32 #include "bus.h"
33 #include "busdma.h"
34
35 static PyObject *
36 bus_read_1(PyObject *self, PyObject *args)
37 {
38         long ofs;
39         int rid;
40         uint8_t val;
41
42         if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
43                 return (NULL);
44         if (!bs_read(rid, ofs, &val, sizeof(val))) {
45                 PyErr_SetString(PyExc_IOError, strerror(errno));
46                 return (NULL);
47         }
48         return (Py_BuildValue("B", val));
49 }
50
51 static PyObject *
52 bus_read_2(PyObject *self, PyObject *args)
53 {
54         long ofs;
55         int rid;
56         uint16_t val;
57
58         if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
59                 return (NULL);
60         if (!bs_read(rid, ofs, &val, sizeof(val))) {
61                 PyErr_SetString(PyExc_IOError, strerror(errno));
62                 return (NULL);
63         }
64         return (Py_BuildValue("H", val));
65 }
66
67 static PyObject *
68 bus_read_4(PyObject *self, PyObject *args)
69 {
70         long ofs;
71         int rid;
72         uint32_t val;
73
74         if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
75                 return (NULL);
76         if (!bs_read(rid, ofs, &val, sizeof(val))) {
77                 PyErr_SetString(PyExc_IOError, strerror(errno));
78                 return (NULL);
79         }
80         return (Py_BuildValue("I", val));
81 }
82
83 static PyObject *
84 bus_write_1(PyObject *self, PyObject *args)
85 {
86         long ofs;
87         int rid;
88         uint8_t val;
89
90         if (!PyArg_ParseTuple(args, "ilB", &rid, &ofs, &val))
91                 return (NULL);
92         if (!bs_write(rid, ofs, &val, sizeof(val))) {
93                 PyErr_SetString(PyExc_IOError, strerror(errno));
94                 return (NULL);
95         }
96         Py_RETURN_NONE;
97 }
98
99 static PyObject *
100 bus_write_2(PyObject *self, PyObject *args)
101 {
102         long ofs;
103         int rid;
104         uint16_t val;
105
106         if (!PyArg_ParseTuple(args, "ilH", &rid, &ofs, &val))
107                 return (NULL);
108         if (!bs_write(rid, ofs, &val, sizeof(val))) {
109                 PyErr_SetString(PyExc_IOError, strerror(errno));
110                 return (NULL);
111         }
112         Py_RETURN_NONE;
113 }
114
115 static PyObject *
116 bus_write_4(PyObject *self, PyObject *args)
117 {
118         long ofs;
119         int rid;
120         uint32_t val;
121
122         if (!PyArg_ParseTuple(args, "ilI", &rid, &ofs, &val))
123                 return (NULL);
124         if (!bs_write(rid, ofs, &val, sizeof(val))) {
125                 PyErr_SetString(PyExc_IOError, strerror(errno));
126                 return (NULL);
127         }
128         Py_RETURN_NONE;
129 }
130
131 static PyObject *
132 bus_map(PyObject *self, PyObject *args)
133 {
134         char *dev, *resource;
135         int rid;
136
137         if (!PyArg_ParseTuple(args, "ss", &dev, &resource))
138                 return (NULL);
139         rid = bs_map(dev, resource);
140         if (rid == -1) {
141                 PyErr_SetString(PyExc_IOError, strerror(errno));
142                 return (NULL);
143         }
144         return (Py_BuildValue("i", rid));
145 }
146
147 static PyObject *
148 bus_unmap(PyObject *self, PyObject *args)
149 {
150         int rid;
151
152         if (!PyArg_ParseTuple(args, "i", &rid))
153                 return (NULL);
154         if (!bs_unmap(rid)) {
155                 PyErr_SetString(PyExc_IOError, strerror(errno));
156                 return (NULL);
157         }
158         Py_RETURN_NONE;
159 }
160
161 static PyObject *
162 bus_subregion(PyObject *self, PyObject *args)
163 {
164         long ofs, sz;
165         int rid0, rid;
166
167         if (!PyArg_ParseTuple(args, "ill", &rid0, &ofs, &sz))
168                 return (NULL);
169         rid = bs_subregion(rid0, ofs, sz);
170         if (rid == -1) {
171                 PyErr_SetString(PyExc_IOError, strerror(errno));
172                 return (NULL);
173         }
174         return (Py_BuildValue("i", rid));
175 }
176
177 static PyObject *
178 busdma_tag_create(PyObject *self, PyObject *args)
179 {
180         char *dev;
181         u_long align, bndry, maxaddr, maxsz, maxsegsz;
182         u_int nsegs, datarate, flags;
183         int tid;
184
185         if (!PyArg_ParseTuple(args, "skkkkIkII", &dev, &align, &bndry,
186             &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
187                 return (NULL);
188         tid = bd_tag_create(dev, align, bndry, maxaddr, maxsz, nsegs,
189             maxsegsz, datarate, flags);
190         if (tid == -1) {
191                 PyErr_SetString(PyExc_IOError, strerror(errno));
192                 return (NULL);
193         }
194         return (Py_BuildValue("i", tid));
195 }
196
197 static PyObject *
198 busdma_tag_derive(PyObject *self, PyObject *args)
199 {
200         u_long align, bndry, maxaddr, maxsz, maxsegsz;
201         u_int nsegs, datarate, flags;
202         int ptid, tid;
203  
204         if (!PyArg_ParseTuple(args, "ikkkkIkII", &ptid, &align, &bndry,
205             &maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
206                 return (NULL);
207         tid = bd_tag_derive(ptid, align, bndry, maxaddr, maxsz, nsegs,
208             maxsegsz, datarate, flags);
209         if (tid == -1) {
210                 PyErr_SetString(PyExc_IOError, strerror(errno));
211                 return (NULL);
212         }
213         return (Py_BuildValue("i", tid));
214 }
215
216 static PyObject *
217 busdma_tag_destroy(PyObject *self, PyObject *args)
218 {
219         int error, tid;
220  
221         if (!PyArg_ParseTuple(args, "i", &tid))
222                 return (NULL);
223         error = bd_tag_destroy(tid);
224         if (error) {
225                 PyErr_SetString(PyExc_IOError, strerror(error));
226                 return (NULL);
227         }
228         Py_RETURN_NONE;
229 }
230
231 static PyObject *
232 busdma_md_create(PyObject *self, PyObject *args)
233 {
234         u_int flags;
235         int error, mdid, tid;
236  
237         if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
238                 return (NULL);
239         mdid = bd_md_create(tid, flags);
240         if (mdid == -1) {
241                 PyErr_SetString(PyExc_IOError, strerror(errno));
242                 return (NULL);
243         }
244         return (Py_BuildValue("i", mdid));
245 }
246
247 static PyObject *
248 busdma_md_destroy(PyObject *self, PyObject *args)
249 {
250         int error, mdid;
251
252         if (!PyArg_ParseTuple(args, "i", &mdid))
253                 return (NULL);
254         error = bd_md_destroy(mdid);
255         if (error) {
256                 PyErr_SetString(PyExc_IOError, strerror(error));
257                 return (NULL);
258         }
259         Py_RETURN_NONE;
260 }
261
262 static PyObject *
263 busdma_md_load(PyObject *self, PyObject *args)
264 {
265         void *buf;
266         u_long len;
267         u_int flags;
268         int error, mdid;
269
270         if (!PyArg_ParseTuple(args, "iwkI", &mdid, &buf, &len, &flags))
271                 return (NULL);
272         error = bd_md_load(mdid, buf, len, flags);
273         if (error) {
274                 PyErr_SetString(PyExc_IOError, strerror(error));
275                 return (NULL);
276         }
277         Py_RETURN_NONE;
278 }
279
280 static PyObject *
281 busdma_md_unload(PyObject *self, PyObject *args)
282 {
283         int error, mdid;
284
285         if (!PyArg_ParseTuple(args, "i", &mdid))
286                 return (NULL);
287         error = bd_md_unload(mdid);
288         if (error) {
289                 PyErr_SetString(PyExc_IOError, strerror(error));
290                 return (NULL);
291         }
292         Py_RETURN_NONE;
293 }
294
295 static PyObject *
296 busdma_mem_alloc(PyObject *self, PyObject *args)
297 {
298         u_int flags;
299         int mdid, tid;
300
301         if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
302                 return (NULL);
303         mdid = bd_mem_alloc(tid, flags);
304         if (mdid == -1) {
305                 PyErr_SetString(PyExc_IOError, strerror(errno));
306                 return (NULL);
307         }
308         return (Py_BuildValue("i", mdid));
309 }
310
311 static PyObject *
312 busdma_mem_free(PyObject *self, PyObject *args)
313 {
314         int error, mdid;
315
316         if (!PyArg_ParseTuple(args, "i", &mdid))
317                 return (NULL);
318         error = bd_mem_free(mdid);
319         if (error) {
320                 PyErr_SetString(PyExc_IOError, strerror(error));
321                 return (NULL);
322         }
323         Py_RETURN_NONE;
324 }
325
326 static PyObject *
327 busdma_md_first_seg(PyObject *self, PyObject *args)
328 {
329         int error, mdid, sid, what;
330
331         if (!PyArg_ParseTuple(args, "ii", &mdid, &what))
332                 return (NULL);
333         sid = bd_md_first_seg(mdid, what);
334         if (sid == -1)
335                 Py_RETURN_NONE;
336         return (Py_BuildValue("i", sid));
337 }
338
339 static PyObject *
340 busdma_md_next_seg(PyObject *self, PyObject *args)
341 {
342         int error, mdid, sid;
343
344         if (!PyArg_ParseTuple(args, "ii", &mdid, &sid))
345                 return (NULL);
346         sid = bd_md_next_seg(mdid, sid);
347         if (sid == -1)
348                 Py_RETURN_NONE;
349         return (Py_BuildValue("i", sid));
350 }
351
352 static PyObject *
353 busdma_seg_get_addr(PyObject *self, PyObject *args)
354 {
355         u_long addr;
356         int error, sid;
357
358         if (!PyArg_ParseTuple(args, "i", &sid))
359                 return (NULL);
360         error = bd_seg_get_addr(sid, &addr);
361         if (error) {
362                 PyErr_SetString(PyExc_IOError, strerror(error));
363                 return (NULL);
364         }
365         return (Py_BuildValue("k", addr));
366 }
367
368 static PyObject *
369 busdma_seg_get_size(PyObject *self, PyObject *args)
370 {
371         u_long size;
372         int error, sid;
373
374         if (!PyArg_ParseTuple(args, "i", &sid))
375                 return (NULL);
376         error = bd_seg_get_size(sid, &size);
377         if (error) {
378                 PyErr_SetString(PyExc_IOError, strerror(error));
379                 return (NULL);
380         }
381         return (Py_BuildValue("k", size));
382 }
383
384 static PyObject *
385 busdma_sync(PyObject *self, PyObject *args)
386 {
387         int error, mdid, op;
388
389         if (!PyArg_ParseTuple(args, "ii", &mdid, &op))
390                 return (NULL);
391         error = bd_sync(mdid, op, 0UL, ~0UL);
392         if (error) {
393                 PyErr_SetString(PyExc_IOError, strerror(error));
394                 return (NULL);
395         }
396         Py_RETURN_NONE;
397 }
398
399 static PyObject *
400 busdma_sync_range(PyObject *self, PyObject *args)
401 {
402         u_long ofs, len;
403         int error, mdid, op;
404
405         if (!PyArg_ParseTuple(args, "iikk", &mdid, &op, &ofs, &len))
406                 return (NULL);
407         error = bd_sync(mdid, op, ofs, len);
408         if (error) {
409                 PyErr_SetString(PyExc_IOError, strerror(error));
410                 return (NULL);
411         }
412         Py_RETURN_NONE;
413 }
414
415 static PyMethodDef bus_methods[] = {
416     { "read_1", bus_read_1, METH_VARARGS, "Read a 1-byte data item." },
417     { "read_2", bus_read_2, METH_VARARGS, "Read a 2-byte data item." },
418     { "read_4", bus_read_4, METH_VARARGS, "Read a 4-byte data item." },
419
420     { "write_1", bus_write_1, METH_VARARGS, "Write a 1-byte data item." },
421     { "write_2", bus_write_2, METH_VARARGS, "Write a 2-byte data item." },
422     { "write_4", bus_write_4, METH_VARARGS, "Write a 4-byte data item." },
423
424     { "map", bus_map, METH_VARARGS,
425         "Return a resource ID for a device file created by proto(4)" },
426     { "unmap", bus_unmap, METH_VARARGS,
427         "Free a resource ID" },
428     { "subregion", bus_subregion, METH_VARARGS,
429         "Return a resource ID for a subregion of another resource ID" },
430
431     { NULL, NULL, 0, NULL }
432 };
433
434 static PyMethodDef busdma_methods[] = {
435     { "tag_create", busdma_tag_create, METH_VARARGS,
436         "Create a root tag." },
437     { "tag_derive", busdma_tag_derive, METH_VARARGS,
438         "Derive a child tag." },
439     { "tag_destroy", busdma_tag_destroy, METH_VARARGS,
440         "Destroy a tag." },
441
442     { "md_create", busdma_md_create, METH_VARARGS,
443         "Create a new and empty memory descriptor." },
444     { "md_destroy", busdma_md_destroy, METH_VARARGS,
445         "Destroy a previously created memory descriptor." },
446     { "md_load", busdma_md_load, METH_VARARGS,
447         "Load a buffer into a memory descriptor." },
448     { "md_unload", busdma_md_unload, METH_VARARGS,
449         "Unload a memory descriptor." },
450
451     { "mem_alloc", busdma_mem_alloc, METH_VARARGS,
452         "Allocate memory according to the DMA constraints." },
453     { "mem_free", busdma_mem_free, METH_VARARGS,
454         "Free allocated memory." },
455
456     { "md_first_seg", busdma_md_first_seg, METH_VARARGS,
457         "Return first segment in one of the segment lists." },
458     { "md_next_seg", busdma_md_next_seg, METH_VARARGS,
459         "Return next segment in the segment list." },
460     { "seg_get_addr", busdma_seg_get_addr, METH_VARARGS,
461         "Return the address of the segment." },
462     { "seg_get_size", busdma_seg_get_size, METH_VARARGS,
463         "Return the size of the segment." },
464
465     { "sync", busdma_sync, METH_VARARGS,
466         "Make the entire memory descriptor coherent WRT to DMA." },
467     { "sync_range", busdma_sync_range, METH_VARARGS,
468         "Make part of the memory descriptor coherent WRT to DMA." },
469
470     { NULL, NULL, 0, NULL }
471 };
472
473 PyMODINIT_FUNC
474 initbus(void)
475 {
476         PyObject *bus, *busdma;
477
478         bus = Py_InitModule("bus", bus_methods);
479         if (bus == NULL)
480                 return;
481         busdma = Py_InitModule("busdma", busdma_methods);
482         if (busdma == NULL)
483                 return;
484         PyModule_AddObject(bus, "dma", busdma);
485
486         PyModule_AddObject(busdma, "MD_BUS_SPACE", Py_BuildValue("i", 0));
487         PyModule_AddObject(busdma, "MD_PHYS_SPACE", Py_BuildValue("i", 1));
488         PyModule_AddObject(busdma, "MD_VIRT_SPACE", Py_BuildValue("i", 2));
489
490         PyModule_AddObject(busdma, "SYNC_PREREAD", Py_BuildValue("i", 1));
491         PyModule_AddObject(busdma, "SYNC_POSTREAD", Py_BuildValue("i", 2));
492         PyModule_AddObject(busdma, "SYNC_PREWRITE", Py_BuildValue("i", 4));
493         PyModule_AddObject(busdma, "SYNC_POSTWRITE", Py_BuildValue("i", 8));
494 }