Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/bus_space/Python/lang.c
39485 views
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
#include <Python.h>
29
30
#include "bus.h"
31
#include "busdma.h"
32
33
static PyObject *
34
bus_read_1(PyObject *self, PyObject *args)
35
{
36
long ofs;
37
int rid;
38
uint8_t val;
39
40
if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
41
return (NULL);
42
if (!bs_read(rid, ofs, &val, sizeof(val))) {
43
PyErr_SetString(PyExc_IOError, strerror(errno));
44
return (NULL);
45
}
46
return (Py_BuildValue("B", val));
47
}
48
49
static PyObject *
50
bus_read_2(PyObject *self, PyObject *args)
51
{
52
long ofs;
53
int rid;
54
uint16_t val;
55
56
if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
57
return (NULL);
58
if (!bs_read(rid, ofs, &val, sizeof(val))) {
59
PyErr_SetString(PyExc_IOError, strerror(errno));
60
return (NULL);
61
}
62
return (Py_BuildValue("H", val));
63
}
64
65
static PyObject *
66
bus_read_4(PyObject *self, PyObject *args)
67
{
68
long ofs;
69
int rid;
70
uint32_t val;
71
72
if (!PyArg_ParseTuple(args, "il", &rid, &ofs))
73
return (NULL);
74
if (!bs_read(rid, ofs, &val, sizeof(val))) {
75
PyErr_SetString(PyExc_IOError, strerror(errno));
76
return (NULL);
77
}
78
return (Py_BuildValue("I", val));
79
}
80
81
static PyObject *
82
bus_write_1(PyObject *self, PyObject *args)
83
{
84
long ofs;
85
int rid;
86
uint8_t val;
87
88
if (!PyArg_ParseTuple(args, "ilB", &rid, &ofs, &val))
89
return (NULL);
90
if (!bs_write(rid, ofs, &val, sizeof(val))) {
91
PyErr_SetString(PyExc_IOError, strerror(errno));
92
return (NULL);
93
}
94
Py_RETURN_NONE;
95
}
96
97
static PyObject *
98
bus_write_2(PyObject *self, PyObject *args)
99
{
100
long ofs;
101
int rid;
102
uint16_t val;
103
104
if (!PyArg_ParseTuple(args, "ilH", &rid, &ofs, &val))
105
return (NULL);
106
if (!bs_write(rid, ofs, &val, sizeof(val))) {
107
PyErr_SetString(PyExc_IOError, strerror(errno));
108
return (NULL);
109
}
110
Py_RETURN_NONE;
111
}
112
113
static PyObject *
114
bus_write_4(PyObject *self, PyObject *args)
115
{
116
long ofs;
117
int rid;
118
uint32_t val;
119
120
if (!PyArg_ParseTuple(args, "ilI", &rid, &ofs, &val))
121
return (NULL);
122
if (!bs_write(rid, ofs, &val, sizeof(val))) {
123
PyErr_SetString(PyExc_IOError, strerror(errno));
124
return (NULL);
125
}
126
Py_RETURN_NONE;
127
}
128
129
static PyObject *
130
bus_map(PyObject *self, PyObject *args)
131
{
132
char *dev, *resource;
133
int rid;
134
135
if (!PyArg_ParseTuple(args, "ss", &dev, &resource))
136
return (NULL);
137
rid = bs_map(dev, resource);
138
if (rid == -1) {
139
PyErr_SetString(PyExc_IOError, strerror(errno));
140
return (NULL);
141
}
142
return (Py_BuildValue("i", rid));
143
}
144
145
static PyObject *
146
bus_unmap(PyObject *self, PyObject *args)
147
{
148
int rid;
149
150
if (!PyArg_ParseTuple(args, "i", &rid))
151
return (NULL);
152
if (!bs_unmap(rid)) {
153
PyErr_SetString(PyExc_IOError, strerror(errno));
154
return (NULL);
155
}
156
Py_RETURN_NONE;
157
}
158
159
static PyObject *
160
bus_subregion(PyObject *self, PyObject *args)
161
{
162
long ofs, sz;
163
int rid0, rid;
164
165
if (!PyArg_ParseTuple(args, "ill", &rid0, &ofs, &sz))
166
return (NULL);
167
rid = bs_subregion(rid0, ofs, sz);
168
if (rid == -1) {
169
PyErr_SetString(PyExc_IOError, strerror(errno));
170
return (NULL);
171
}
172
return (Py_BuildValue("i", rid));
173
}
174
175
static PyObject *
176
busdma_tag_create(PyObject *self, PyObject *args)
177
{
178
char *dev;
179
u_long align, bndry, maxaddr, maxsz, maxsegsz;
180
u_int nsegs, datarate, flags;
181
int tid;
182
183
if (!PyArg_ParseTuple(args, "skkkkIkII", &dev, &align, &bndry,
184
&maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
185
return (NULL);
186
tid = bd_tag_create(dev, align, bndry, maxaddr, maxsz, nsegs,
187
maxsegsz, datarate, flags);
188
if (tid == -1) {
189
PyErr_SetString(PyExc_IOError, strerror(errno));
190
return (NULL);
191
}
192
return (Py_BuildValue("i", tid));
193
}
194
195
static PyObject *
196
busdma_tag_derive(PyObject *self, PyObject *args)
197
{
198
u_long align, bndry, maxaddr, maxsz, maxsegsz;
199
u_int nsegs, datarate, flags;
200
int ptid, tid;
201
202
if (!PyArg_ParseTuple(args, "ikkkkIkII", &ptid, &align, &bndry,
203
&maxaddr, &maxsz, &nsegs, &maxsegsz, &datarate, &flags))
204
return (NULL);
205
tid = bd_tag_derive(ptid, align, bndry, maxaddr, maxsz, nsegs,
206
maxsegsz, datarate, flags);
207
if (tid == -1) {
208
PyErr_SetString(PyExc_IOError, strerror(errno));
209
return (NULL);
210
}
211
return (Py_BuildValue("i", tid));
212
}
213
214
static PyObject *
215
busdma_tag_destroy(PyObject *self, PyObject *args)
216
{
217
int error, tid;
218
219
if (!PyArg_ParseTuple(args, "i", &tid))
220
return (NULL);
221
error = bd_tag_destroy(tid);
222
if (error) {
223
PyErr_SetString(PyExc_IOError, strerror(error));
224
return (NULL);
225
}
226
Py_RETURN_NONE;
227
}
228
229
static PyObject *
230
busdma_md_create(PyObject *self, PyObject *args)
231
{
232
u_int flags;
233
int error, mdid, tid;
234
235
if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
236
return (NULL);
237
mdid = bd_md_create(tid, flags);
238
if (mdid == -1) {
239
PyErr_SetString(PyExc_IOError, strerror(errno));
240
return (NULL);
241
}
242
return (Py_BuildValue("i", mdid));
243
}
244
245
static PyObject *
246
busdma_md_destroy(PyObject *self, PyObject *args)
247
{
248
int error, mdid;
249
250
if (!PyArg_ParseTuple(args, "i", &mdid))
251
return (NULL);
252
error = bd_md_destroy(mdid);
253
if (error) {
254
PyErr_SetString(PyExc_IOError, strerror(error));
255
return (NULL);
256
}
257
Py_RETURN_NONE;
258
}
259
260
static PyObject *
261
busdma_md_load(PyObject *self, PyObject *args)
262
{
263
void *buf;
264
u_long len;
265
u_int flags;
266
int error, mdid;
267
268
if (!PyArg_ParseTuple(args, "iwkI", &mdid, &buf, &len, &flags))
269
return (NULL);
270
error = bd_md_load(mdid, buf, len, flags);
271
if (error) {
272
PyErr_SetString(PyExc_IOError, strerror(error));
273
return (NULL);
274
}
275
Py_RETURN_NONE;
276
}
277
278
static PyObject *
279
busdma_md_unload(PyObject *self, PyObject *args)
280
{
281
int error, mdid;
282
283
if (!PyArg_ParseTuple(args, "i", &mdid))
284
return (NULL);
285
error = bd_md_unload(mdid);
286
if (error) {
287
PyErr_SetString(PyExc_IOError, strerror(error));
288
return (NULL);
289
}
290
Py_RETURN_NONE;
291
}
292
293
static PyObject *
294
busdma_mem_alloc(PyObject *self, PyObject *args)
295
{
296
u_int flags;
297
int mdid, tid;
298
299
if (!PyArg_ParseTuple(args, "iI", &tid, &flags))
300
return (NULL);
301
mdid = bd_mem_alloc(tid, flags);
302
if (mdid == -1) {
303
PyErr_SetString(PyExc_IOError, strerror(errno));
304
return (NULL);
305
}
306
return (Py_BuildValue("i", mdid));
307
}
308
309
static PyObject *
310
busdma_mem_free(PyObject *self, PyObject *args)
311
{
312
int error, mdid;
313
314
if (!PyArg_ParseTuple(args, "i", &mdid))
315
return (NULL);
316
error = bd_mem_free(mdid);
317
if (error) {
318
PyErr_SetString(PyExc_IOError, strerror(error));
319
return (NULL);
320
}
321
Py_RETURN_NONE;
322
}
323
324
static PyObject *
325
busdma_md_first_seg(PyObject *self, PyObject *args)
326
{
327
int error, mdid, sid, what;
328
329
if (!PyArg_ParseTuple(args, "ii", &mdid, &what))
330
return (NULL);
331
sid = bd_md_first_seg(mdid, what);
332
if (sid == -1)
333
Py_RETURN_NONE;
334
return (Py_BuildValue("i", sid));
335
}
336
337
static PyObject *
338
busdma_md_next_seg(PyObject *self, PyObject *args)
339
{
340
int error, mdid, sid;
341
342
if (!PyArg_ParseTuple(args, "ii", &mdid, &sid))
343
return (NULL);
344
sid = bd_md_next_seg(mdid, sid);
345
if (sid == -1)
346
Py_RETURN_NONE;
347
return (Py_BuildValue("i", sid));
348
}
349
350
static PyObject *
351
busdma_seg_get_addr(PyObject *self, PyObject *args)
352
{
353
u_long addr;
354
int error, sid;
355
356
if (!PyArg_ParseTuple(args, "i", &sid))
357
return (NULL);
358
error = bd_seg_get_addr(sid, &addr);
359
if (error) {
360
PyErr_SetString(PyExc_IOError, strerror(error));
361
return (NULL);
362
}
363
return (Py_BuildValue("k", addr));
364
}
365
366
static PyObject *
367
busdma_seg_get_size(PyObject *self, PyObject *args)
368
{
369
u_long size;
370
int error, sid;
371
372
if (!PyArg_ParseTuple(args, "i", &sid))
373
return (NULL);
374
error = bd_seg_get_size(sid, &size);
375
if (error) {
376
PyErr_SetString(PyExc_IOError, strerror(error));
377
return (NULL);
378
}
379
return (Py_BuildValue("k", size));
380
}
381
382
static PyObject *
383
busdma_sync(PyObject *self, PyObject *args)
384
{
385
int error, mdid, op;
386
387
if (!PyArg_ParseTuple(args, "ii", &mdid, &op))
388
return (NULL);
389
error = bd_sync(mdid, op, 0UL, ~0UL);
390
if (error) {
391
PyErr_SetString(PyExc_IOError, strerror(error));
392
return (NULL);
393
}
394
Py_RETURN_NONE;
395
}
396
397
static PyObject *
398
busdma_sync_range(PyObject *self, PyObject *args)
399
{
400
u_long ofs, len;
401
int error, mdid, op;
402
403
if (!PyArg_ParseTuple(args, "iikk", &mdid, &op, &ofs, &len))
404
return (NULL);
405
error = bd_sync(mdid, op, ofs, len);
406
if (error) {
407
PyErr_SetString(PyExc_IOError, strerror(error));
408
return (NULL);
409
}
410
Py_RETURN_NONE;
411
}
412
413
/*
414
* Module methods and initialization.
415
*/
416
417
static char bus_docstr[] = "Access to H/W bus memory and register areas.";
418
419
static PyMethodDef bus_methods[] = {
420
{ "read_1", bus_read_1, METH_VARARGS, "Read a 1-byte data item." },
421
{ "read_2", bus_read_2, METH_VARARGS, "Read a 2-byte data item." },
422
{ "read_4", bus_read_4, METH_VARARGS, "Read a 4-byte data item." },
423
424
{ "write_1", bus_write_1, METH_VARARGS, "Write a 1-byte data item." },
425
{ "write_2", bus_write_2, METH_VARARGS, "Write a 2-byte data item." },
426
{ "write_4", bus_write_4, METH_VARARGS, "Write a 4-byte data item." },
427
428
{ "map", bus_map, METH_VARARGS,
429
"Return a resource ID for a device file created by proto(4)" },
430
{ "unmap", bus_unmap, METH_VARARGS,
431
"Free a resource ID" },
432
{ "subregion", bus_subregion, METH_VARARGS,
433
"Return a resource ID for a subregion of another resource ID" },
434
435
{ NULL, NULL, 0, NULL }
436
};
437
438
static char busdma_docstr[] = "A bus- and device-independent interface"
439
" to Direct Memory Access (DMA) mechanisms.";
440
441
static PyMethodDef busdma_methods[] = {
442
{ "tag_create", busdma_tag_create, METH_VARARGS,
443
"Create a root tag." },
444
{ "tag_derive", busdma_tag_derive, METH_VARARGS,
445
"Derive a child tag." },
446
{ "tag_destroy", busdma_tag_destroy, METH_VARARGS,
447
"Destroy a tag." },
448
449
{ "md_create", busdma_md_create, METH_VARARGS,
450
"Create a new and empty memory descriptor." },
451
{ "md_destroy", busdma_md_destroy, METH_VARARGS,
452
"Destroy a previously created memory descriptor." },
453
{ "md_load", busdma_md_load, METH_VARARGS,
454
"Load a buffer into a memory descriptor." },
455
{ "md_unload", busdma_md_unload, METH_VARARGS,
456
"Unload a memory descriptor." },
457
458
{ "mem_alloc", busdma_mem_alloc, METH_VARARGS,
459
"Allocate memory according to the DMA constraints." },
460
{ "mem_free", busdma_mem_free, METH_VARARGS,
461
"Free allocated memory." },
462
463
{ "md_first_seg", busdma_md_first_seg, METH_VARARGS,
464
"Return first segment in one of the segment lists." },
465
{ "md_next_seg", busdma_md_next_seg, METH_VARARGS,
466
"Return next segment in the segment list." },
467
{ "seg_get_addr", busdma_seg_get_addr, METH_VARARGS,
468
"Return the address of the segment." },
469
{ "seg_get_size", busdma_seg_get_size, METH_VARARGS,
470
"Return the size of the segment." },
471
472
{ "sync", busdma_sync, METH_VARARGS,
473
"Make the entire memory descriptor coherent WRT to DMA." },
474
{ "sync_range", busdma_sync_range, METH_VARARGS,
475
"Make part of the memory descriptor coherent WRT to DMA." },
476
477
{ NULL, NULL, 0, NULL }
478
};
479
480
static PyObject *
481
module_initialize(PyObject *bus, PyObject *busdma)
482
{
483
484
if (bus == NULL || busdma == NULL)
485
return (NULL);
486
487
PyModule_AddObject(busdma, "MD_BUS_SPACE", Py_BuildValue("i", 0));
488
PyModule_AddObject(busdma, "MD_PHYS_SPACE", Py_BuildValue("i", 1));
489
PyModule_AddObject(busdma, "MD_VIRT_SPACE", Py_BuildValue("i", 2));
490
491
PyModule_AddObject(busdma, "SYNC_PREREAD", Py_BuildValue("i", 1));
492
PyModule_AddObject(busdma, "SYNC_POSTREAD", Py_BuildValue("i", 2));
493
PyModule_AddObject(busdma, "SYNC_PREWRITE", Py_BuildValue("i", 4));
494
PyModule_AddObject(busdma, "SYNC_POSTWRITE", Py_BuildValue("i", 8));
495
496
PyModule_AddObject(bus, "dma", busdma);
497
return (bus);
498
}
499
500
#if PY_MAJOR_VERSION >= 3
501
502
static struct PyModuleDef bus_module = {
503
PyModuleDef_HEAD_INIT,
504
"bus",
505
bus_docstr,
506
-1,
507
bus_methods,
508
};
509
510
static struct PyModuleDef busdma_module = {
511
PyModuleDef_HEAD_INIT,
512
"busdma",
513
busdma_docstr,
514
-1,
515
busdma_methods,
516
};
517
518
PyMODINIT_FUNC
519
PyInit_bus(void)
520
{
521
PyObject *bus, *busdma;
522
523
bus = PyModule_Create(&bus_module);
524
busdma = PyModule_Create(&busdma_module);
525
return (module_initialize(bus, busdma));
526
}
527
528
#else /* PY_MAJOR_VERSION >= 3 */
529
530
PyMODINIT_FUNC
531
initbus(void)
532
{
533
PyObject *bus, *busdma;
534
535
bus = Py_InitModule3("bus", bus_methods, bus_docstr);
536
busdma = Py_InitModule3("busdma", busdma_methods, busdma_docstr);
537
(void)module_initialize(bus, busdma);
538
}
539
540
#endif /* PY_MAJOR_VERSION >= 3 */
541
542