123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281 |
- /*
- * Copyright (C) 2009-2010 Felipe Contreras
- * Copyright (C) 2009-2010 Nokia Corporation
- * Copyright (C) 2007 Texas Instruments, Incorporated
- *
- * Author: Felipe Contreras <felipe.contreras@gmail.com>
- *
- * This file may be used under the terms of the GNU Lesser General Public
- * License version 2.1, a copy of which is found in LICENSE included in the
- * packaging of this file.
- */
- #include "dsp_bridge.h"
- /* for open */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h> /* for close */
- #include <sys/ioctl.h> /* for ioctl */
- #include <stdlib.h> /* for free */
- #include <malloc.h> /* for memalign */
- #include <string.h> /* for memset */
- #define ALLOCATE_SM
- #ifdef ALLOCATE_SM
- #include <malloc.h> /* for memalign */
- #include <sys/mman.h> /* for mmap */
- #endif
- #if DSP_API < 2
- #include <errno.h>
- #endif
- #define VALGRIND
- /*
- * Dspbridge ioctl numbering scheme
- *
- * 7 0
- * ---------------------------------
- * | Module | ioctl Number |
- * ---------------------------------
- * | x | x | x | 0 | 0 | 0 | 0 | 0 |
- * ---------------------------------
- */
- /* ioctl driver identifier */
- #define DB 0xDB
- /*
- * Following are used to distinguish between module ioctls, this is needed
- * in case new ioctls are introduced.
- */
- #define DB_MODULE_MASK 0xE0
- #define DB_IOC_MASK 0x1F
- #if DSP_API >= 1
- #include <linux/ioctl.h>
- /* ioctl module masks */
- #define DB_MGR 0x0
- #define DB_PROC 0x20
- #define DB_NODE 0x40
- #define DB_STRM 0x60
- #define DB_CMM 0x80
- /* Used to calculate the ioctl per dspbridge module */
- #define DB_IOC(module, num) \
- (((module) & DB_MODULE_MASK) | ((num) & DB_IOC_MASK))
- #else
- #define DB_MGR 1
- #define DB_PROC 7
- #define DB_NODE 24
- #define DB_STRM 39
- #define DB_CMM 50
- #define DB_IOC(module, num) ((module) + (num))
- #undef _IOR
- #undef _IOW
- #undef _IOWR
- #define _IOR(type, nr, size) (nr)
- #define _IOW(type, nr, size) (nr)
- #define _IOWR(type, nr, size) (nr)
- #endif /* DSP_API */
- /* MGR Module */
- #define MGR_WAIT _IOWR(DB, DB_IOC(DB_MGR, 4), unsigned long)
- #define MGR_ENUMNODE_INFO _IOWR(DB, DB_IOC(DB_MGR, 0), unsigned long)
- #define MGR_REGISTEROBJECT _IOWR(DB, DB_IOC(DB_MGR, 2), unsigned long)
- #define MGR_UNREGISTEROBJECT _IOWR(DB, DB_IOC(DB_MGR, 3), unsigned long)
- /* PROC Module */
- #define PROC_ATTACH _IOWR(DB, DB_IOC(DB_PROC, 0), unsigned long)
- /* PROC_DETACH Deprecated */
- #define PROC_DETACH _IOR(DB, DB_IOC(DB_PROC, 2), unsigned long)
- #define PROC_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_PROC, 8), unsigned long)
- #define PROC_RSVMEM _IOWR(DB, DB_IOC(DB_PROC, 10), unsigned long)
- #define PROC_UNRSVMEM _IOW(DB, DB_IOC(DB_PROC, 11), unsigned long)
- #define PROC_MAPMEM _IOWR(DB, DB_IOC(DB_PROC, 12), unsigned long)
- #define PROC_UNMAPMEM _IOR(DB, DB_IOC(DB_PROC, 13), unsigned long)
- #define PROC_FLUSHMEMORY _IOW(DB, DB_IOC(DB_PROC, 14), unsigned long)
- #define PROC_INVALIDATEMEMORY _IOW(DB, DB_IOC(DB_PROC, 16), unsigned long)
- #define PROC_GET_STATE _IOWR(DB, DB_IOC(DB_PROC, 5), unsigned long)
- #define PROC_ENUMRESOURCES _IOWR(DB, DB_IOC(DB_PROC, 4), unsigned long)
- #define PROC_ENUMNODE _IOWR(DB, DB_IOC(DB_PROC, 3), unsigned long)
- #define PROC_STOP _IOWR(DB, DB_IOC(DB_PROC, 15), unsigned long)
- #define PROC_LOAD _IOW(DB, DB_IOC(DB_PROC, 7), unsigned long)
- #define PROC_START _IOW(DB, DB_IOC(DB_PROC, 9), unsigned long)
- #define PROC_BEGINDMA _IOW(DB, DB_IOC(DB_PROC, 17), unsigned long)
- #define PROC_ENDDMA _IOW(DB, DB_IOC(DB_PROC, 18), unsigned long)
- /* NODE Module */
- #define NODE_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_NODE, 11), unsigned long)
- #define NODE_CREATE _IOW(DB, DB_IOC(DB_NODE, 4), unsigned long)
- #define NODE_RUN _IOW(DB, DB_IOC(DB_NODE, 12), unsigned long)
- #define NODE_TERMINATE _IOWR(DB, DB_IOC(DB_NODE, 13), unsigned long)
- #define NODE_PUTMESSAGE _IOW(DB, DB_IOC(DB_NODE, 10), unsigned long)
- #define NODE_GETMESSAGE _IOWR(DB, DB_IOC(DB_NODE, 8), unsigned long)
- #define NODE_DELETE _IOW(DB, DB_IOC(DB_NODE, 5), unsigned long)
- #define NODE_GETATTR _IOWR(DB, DB_IOC(DB_NODE, 7), unsigned long)
- #define NODE_ALLOCMSGBUF _IOWR(DB, DB_IOC(DB_NODE, 1), unsigned long)
- #define NODE_GETUUIDPROPS _IOWR(DB, DB_IOC(DB_NODE, 14), unsigned long)
- #define NODE_ALLOCATE _IOWR(DB, DB_IOC(DB_NODE, 0), unsigned long)
- #define NODE_CONNECT _IOW(DB, DB_IOC(DB_NODE, 3), unsigned long)
- /* CMM Module */
- #define CMM_GETHANDLE _IOR(DB, DB_IOC(DB_CMM, 2), unsigned long)
- #define CMM_GETINFO _IOR(DB, DB_IOC(DB_CMM, 3), unsigned long)
- /* STRM Module */
- #define STRM_OPEN _IOWR(DB, DB_IOC(DB_STRM, 7), unsigned long)
- #define STRM_CLOSE _IOW(DB, DB_IOC(DB_STRM, 1), unsigned long)
- #define STRM_GETINFO _IOWR(DB, DB_IOC(DB_STRM, 4), unsigned long)
- #define STRM_ALLOCATEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 0), unsigned long)
- #define STRM_IDLE _IOW(DB, DB_IOC(DB_STRM, 5), unsigned long)
- #define STRM_RECLAIM _IOWR(DB, DB_IOC(DB_STRM, 8), unsigned long)
- #define STRM_FREEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 2), unsigned long)
- #define STRM_ISSUE _IOW(DB, DB_IOC(DB_STRM, 6), unsigned long)
- #if DSP_API < 2
- static inline int real_ioctl(int fd, int r, void *arg)
- {
- return ioctl(fd, r, arg);
- }
- #endif
- /* will not be needed when tidspbridge uses proper error codes */
- #define ioctl(...) (ioctl(__VA_ARGS__) < 0)
- int dsp_open(void)
- {
- return open("/dev/DspBridge", O_RDWR);
- }
- int dsp_close(int handle)
- {
- return close(handle);
- }
- struct proc_attach {
- unsigned int num;
- const void *info; /* not used */
- void **ret_handle;
- };
- bool dsp_attach(int handle,
- unsigned int num,
- const void *info,
- void **ret_handle)
- {
- struct proc_attach arg = {
- .num = num,
- .info = info,
- .ret_handle = ret_handle,
- };
- return !ioctl(handle, PROC_ATTACH, &arg);
- }
- struct proc_detach {
- void *proc_handle;
- };
- bool dsp_detach(int handle,
- void *proc_handle)
- {
- struct proc_detach arg = {
- .proc_handle = proc_handle,
- };
- return !ioctl(handle, PROC_DETACH, &arg);
- }
- struct register_notify {
- void *proc_handle;
- unsigned int event_mask;
- unsigned int notify_type;
- struct dsp_notification *info;
- };
- bool dsp_register_notify(int handle,
- void *proc_handle,
- unsigned int event_mask,
- unsigned int notify_type,
- struct dsp_notification *info)
- {
- struct register_notify arg = {
- .proc_handle = proc_handle,
- .event_mask = event_mask,
- .notify_type = notify_type,
- .info = info,
- };
- return !ioctl(handle, PROC_REGISTERNOTIFY, &arg);
- }
- struct proc_start {
- void *proc_handle;
- };
- bool dsp_start(int handle,
- void *proc_handle)
- {
- struct proc_start arg = {
- .proc_handle = proc_handle,
- };
- return !ioctl(handle, PROC_START, &arg);
- }
- bool dsp_stop(int handle,
- void *proc_handle)
- {
- struct proc_start arg = {
- .proc_handle = proc_handle,
- };
- return !ioctl(handle, PROC_STOP, &arg);
- }
- struct proc_load {
- void *proc_handle;
- int argc;
- char **argv;
- char **env;
- };
- bool dsp_load(int handle,
- void *proc_handle,
- int argc, char **argv,
- char **env)
- {
- struct proc_load arg = {
- .proc_handle = proc_handle,
- .argc = argc,
- .argv = argv,
- .env = env,
- };
- return !ioctl(handle, PROC_LOAD, &arg);
- }
- struct node_register_notify {
- void *node_handle;
- unsigned int event_mask;
- unsigned int notify_type;
- struct dsp_notification *info;
- };
- bool dsp_node_register_notify(int handle,
- struct dsp_node *node,
- unsigned int event_mask,
- unsigned int notify_type,
- struct dsp_notification *info)
- {
- struct node_register_notify arg = {
- .node_handle = node->handle,
- .event_mask = event_mask,
- .notify_type = notify_type,
- .info = info,
- };
- return !ioctl(handle, NODE_REGISTERNOTIFY, &arg);
- }
- struct wait_for_events {
- struct dsp_notification **notifications;
- unsigned int count;
- unsigned int *ret_index;
- unsigned int timeout;
- };
- bool dsp_wait_for_events(int handle,
- struct dsp_notification **notifications,
- unsigned int count,
- unsigned int *ret_index,
- unsigned int timeout)
- {
- struct wait_for_events arg = {
- .notifications = notifications,
- .count = count,
- .ret_index = ret_index,
- .timeout = timeout,
- };
- #if DSP_API >= 2
- return !ioctl(handle, MGR_WAIT, &arg);
- #else
- /*
- * Temporary hack since libc only saves errors -1 to -4095; 0x80008017
- * is not stored.
- */
- int r;
- r = real_ioctl(handle, MGR_WAIT, &arg);
- if (r == (int)0x80008017)
- errno = ETIME;
- return r >= 0;
- #endif
- }
- struct enum_node {
- unsigned int num;
- struct dsp_ndb_props *info;
- unsigned int info_size;
- unsigned int *ret_num;
- };
- bool dsp_enum(int handle,
- unsigned int num,
- struct dsp_ndb_props *info,
- size_t info_size,
- unsigned int *ret_num)
- {
- struct enum_node arg = {
- .num = num,
- .info = info,
- .info_size = info_size,
- .ret_num = ret_num,
- };
- return !ioctl(handle, MGR_ENUMNODE_INFO, &arg);
- }
- struct register_object {
- const struct dsp_uuid *uuid;
- enum dsp_dcd_object_type type;
- const char *path;
- };
- bool dsp_register(int handle,
- const struct dsp_uuid *uuid,
- enum dsp_dcd_object_type type,
- const char *path)
- {
- struct register_object arg = {
- .uuid = uuid,
- .type = type,
- .path = path,
- };
- return !ioctl(handle, MGR_REGISTEROBJECT, &arg);
- }
- struct unregister_object {
- const struct dsp_uuid *uuid;
- enum dsp_dcd_object_type type;
- };
- bool dsp_unregister(int handle,
- const struct dsp_uuid *uuid,
- enum dsp_dcd_object_type type)
- {
- struct unregister_object arg = {
- .uuid = uuid,
- .type = type,
- };
- return !ioctl(handle, MGR_UNREGISTEROBJECT, &arg);
- }
- struct node_create {
- void *node_handle;
- };
- bool dsp_node_create(int handle,
- struct dsp_node *node)
- {
- struct node_create arg = {
- .node_handle = node->handle,
- };
- return !ioctl(handle, NODE_CREATE, &arg);
- }
- struct node_run {
- void *node_handle;
- };
- bool dsp_node_run(int handle,
- struct dsp_node *node)
- {
- struct node_run arg = {
- .node_handle = node->handle,
- };
- return !ioctl(handle, NODE_RUN, &arg);
- }
- struct node_terminate {
- void *node_handle;
- unsigned long *status;
- };
- bool dsp_node_terminate(int handle,
- struct dsp_node *node,
- unsigned long *status)
- {
- struct node_terminate arg = {
- .node_handle = node->handle,
- .status = status,
- };
- return !ioctl(handle, NODE_TERMINATE, &arg);
- }
- struct node_put_message {
- void *node_handle;
- const struct dsp_msg *message;
- unsigned int timeout;
- };
- bool dsp_node_put_message(int handle,
- struct dsp_node *node,
- const struct dsp_msg *message,
- unsigned int timeout)
- {
- struct node_put_message arg = {
- .node_handle = node->handle,
- .message = message,
- .timeout = timeout,
- };
- return !ioctl(handle, NODE_PUTMESSAGE, &arg);
- }
- struct node_get_message {
- void *node_handle;
- struct dsp_msg *message;
- unsigned int timeout;
- };
- bool dsp_node_get_message(int handle,
- struct dsp_node *node,
- struct dsp_msg *message,
- unsigned int timeout)
- {
- struct node_get_message arg = {
- .node_handle = node->handle,
- .message = message,
- .timeout = timeout,
- };
- #ifdef VALGRIND
- memset(message, 0, sizeof(*message));
- #endif
- return !ioctl(handle, NODE_GETMESSAGE, &arg);
- }
- struct node_delete {
- void *node_handle;
- };
- static inline bool dsp_node_delete(int handle,
- struct dsp_node *node)
- {
- struct node_delete arg = {
- .node_handle = node->handle,
- };
- return !ioctl(handle, NODE_DELETE, &arg);
- }
- #ifdef ALLOCATE_SM
- struct node_get_attr {
- void *node_handle;
- struct dsp_node_attr *attr;
- unsigned int attr_size;
- };
- bool dsp_node_get_attr(int handle,
- struct dsp_node *node,
- struct dsp_node_attr *attr,
- size_t attr_size)
- {
- struct node_get_attr arg = {
- .node_handle = node->handle,
- .attr = attr,
- .attr_size = attr_size,
- };
- return !ioctl(handle, NODE_GETATTR, &arg);
- }
- struct dsp_buffer_attr {
- unsigned long cb;
- unsigned int segment;
- unsigned int alignment;
- };
- struct node_alloc_buf {
- void *node_handle;
- unsigned int size;
- struct dsp_buffer_attr *attr;
- void **buffer;
- };
- static inline bool dsp_node_alloc_buf(int handle,
- struct dsp_node *node,
- size_t size,
- struct dsp_buffer_attr *attr,
- void **buffer)
- {
- struct node_alloc_buf arg = {
- .node_handle = node->handle,
- .size = size,
- .attr = attr,
- .buffer = buffer,
- };
- if (ioctl(handle, NODE_ALLOCMSGBUF, &arg)) {
- *buffer = NULL;
- return false;
- }
- return true;
- }
- struct dsp_cmm_seg_info {
- unsigned long base_pa;
- unsigned long size;
- unsigned long gpp_base_pa;
- unsigned long gpp_size;
- unsigned long dsp_base_va;
- unsigned long dsp_size;
- unsigned long use_count;
- unsigned long base_va;
- };
- struct dsp_cmm_info {
- unsigned long segments;
- unsigned long use_count;
- unsigned long min_block_size;
- struct dsp_cmm_seg_info info[1];
- };
- struct cmm_get_handle {
- void *proc_handle;
- struct cmm_object **cmm;
- };
- struct cmm_get_info {
- struct cmm_object *cmm;
- struct dsp_cmm_info *info;
- };
- static inline bool get_cmm_info(int handle,
- void *proc_handle,
- struct dsp_cmm_info *cmm_info)
- {
- struct cmm_object *cmm;
- struct cmm_get_handle cmm_arg = {
- .proc_handle = proc_handle,
- .cmm = &cmm,
- };
- struct cmm_get_info cmm_info_arg = {
- .info = cmm_info,
- };
- if (ioctl(handle, CMM_GETHANDLE, &cmm_arg))
- return false;
- cmm_info_arg.cmm = cmm;
- if (ioctl(handle, CMM_GETINFO, &cmm_info_arg))
- return false;
- return true;
- }
- static inline bool allocate_segments(int handle,
- void *proc_handle,
- struct dsp_node *node)
- {
- struct dsp_cmm_info cmm_info;
- struct dsp_node_attr attr;
- enum dsp_node_type node_type;
- #ifdef VALGRIND
- memset(&cmm_info, 0, sizeof(cmm_info));
- memset(&attr, 0, sizeof(attr));
- #endif
- if (!get_cmm_info(handle, proc_handle, &cmm_info))
- return false;
- if (!dsp_node_get_attr(handle, node, &attr, sizeof(attr)))
- return false;
- node_type = attr.info.props.ntype;
- if ((node_type != DSP_NODE_DEVICE) && (cmm_info.segments > 0)) {
- struct dsp_cmm_seg_info *seg;
- seg = &cmm_info.info[0];
- if (seg->base_pa != 0 && seg->size > 0) {
- void *base;
- struct dsp_buffer_attr buffer_attr;
- base = mmap(NULL, seg->size,
- PROT_READ | PROT_WRITE, MAP_SHARED | 0x2000 /* MAP_LOCKED */,
- handle, seg->base_pa);
- if (!base)
- return false;
- buffer_attr.alignment = 0;
- buffer_attr.segment = 1 | 0x10000000;
- buffer_attr.cb = 0;
- if (!dsp_node_alloc_buf(handle, node, seg->size,
- &buffer_attr, &base))
- {
- munmap(base, seg->size);
- return false;
- }
- node->msgbuf_addr = base;
- node->msgbuf_size = seg->size;
- }
- }
- return true;
- }
- #endif
- #ifdef ALLOCATE_HEAP
- struct get_uuid_props {
- void *proc_handle;
- const struct dsp_uuid *node_uuid;
- struct dsp_ndb_props *props;
- };
- static inline bool get_uuid_props(int handle,
- void *proc_handle,
- const struct dsp_uuid *node_uuid,
- struct dsp_ndb_props *props)
- {
- struct get_uuid_props arg = {
- .proc_handle = proc_handle,
- .node_uuid = node_uuid,
- .props = props,
- };
- return !ioctl(handle, NODE_GETUUIDPROPS, &arg);
- }
- #define PG_SIZE_4K 4096
- #define PG_MASK(pg_size) (~((pg_size)-1))
- #define PG_ALIGN_LOW(addr, pg_size) ((addr) & PG_MASK(pg_size))
- #define PG_ALIGN_HIGH(addr, pg_size) (((addr)+(pg_size)-1) & PG_MASK(pg_size))
- #endif
- struct node_allocate {
- void *proc_handle;
- const struct dsp_uuid *node_id;
- const void *cb_data;
- struct dsp_node_attr_in *attrs;
- void **ret_node;
- };
- bool dsp_node_allocate(int handle,
- void *proc_handle,
- const struct dsp_uuid *node_uuid,
- const void *cb_data,
- struct dsp_node_attr_in *attrs,
- struct dsp_node **ret_node)
- {
- struct dsp_node *node;
- void *node_handle = NULL;
- struct node_allocate arg = {
- .proc_handle = proc_handle,
- .node_id = node_uuid,
- .cb_data = cb_data,
- .attrs = attrs,
- .ret_node = &node_handle,
- };
- #ifdef ALLOCATE_HEAP
- if (attrs) {
- struct dsp_ndb_props props;
- #ifdef VALGRIND
- memset(&props, 0, sizeof(props));
- #endif
- if (!get_uuid_props(handle, proc_handle, node_uuid, &props)) {
- attrs->gpp_va = NULL;
- return false;
- }
- if (attrs->profile_id < props.count_profiles) {
- unsigned int heap_size = 0;
- heap_size = props.node_profiles[attrs->profile_id].heap_size;
- if (heap_size) {
- void *virtual = NULL;
- heap_size = PG_ALIGN_HIGH(heap_size, PG_SIZE_4K);
- virtual = memalign(128, heap_size);
- if (!virtual)
- return false;
- attrs->heap_size = heap_size;
- attrs->gpp_va = virtual;
- }
- }
- }
- #endif
- if (ioctl(handle, NODE_ALLOCATE, &arg)) {
- if (attrs) {
- free(attrs->gpp_va);
- attrs->gpp_va = NULL;
- }
- return false;
- }
- node = calloc(1, sizeof(*node));
- node->handle = node_handle;
- if (attrs)
- node->heap = attrs->gpp_va;
- #ifdef ALLOCATE_SM
- if (!allocate_segments(handle, proc_handle, node)) {
- dsp_node_delete(handle, node);
- free(node->heap);
- free(node);
- return false;
- }
- #endif
- *ret_node = node;
- return true;
- }
- struct node_connect {
- void *node_handle;
- unsigned int stream;
- void *other_node_handle;
- unsigned int other_stream;
- struct dsp_stream_attr *attrs;
- void *params;
- };
- bool dsp_node_connect(int handle,
- struct dsp_node *node,
- unsigned int stream,
- struct dsp_node *other_node,
- unsigned int other_stream,
- struct dsp_stream_attr *attrs,
- void *params)
- {
- struct node_connect arg = {
- .node_handle = node->handle,
- .stream = stream,
- .other_node_handle = other_node->handle,
- .other_stream = other_stream,
- .attrs = attrs,
- .params = params,
- };
- return !ioctl(handle, NODE_CONNECT, &arg);
- }
- bool dsp_node_free(int handle,
- struct dsp_node *node)
- {
- #ifdef ALLOCATE_SM
- munmap(node->msgbuf_addr, node->msgbuf_size);
- #endif
- dsp_node_delete(handle, node);
- free(node->heap);
- free(node);
- return true;
- }
- struct reserve_mem {
- void *proc_handle;
- unsigned long size;
- void **addr;
- };
- bool dsp_reserve(int handle,
- void *proc_handle,
- unsigned long size,
- void **addr)
- {
- struct reserve_mem arg = {
- .proc_handle = proc_handle,
- .size = size,
- .addr = addr,
- };
- return !ioctl(handle, PROC_RSVMEM, &arg);
- }
- struct unreserve_mem {
- void *proc_handle;
- unsigned long size;
- void *addr;
- };
- bool dsp_unreserve(int handle,
- void *proc_handle,
- void *addr)
- {
- struct unreserve_mem arg = {
- .proc_handle = proc_handle,
- .addr = addr,
- };
- return !ioctl(handle, PROC_UNRSVMEM, &arg);
- }
- struct map_mem {
- void *proc_handle;
- void *mpu_addr;
- unsigned long size;
- void *req_addr;
- void **ret_map_addr;
- unsigned long attr;
- };
- bool dsp_map(int handle,
- void *proc_handle,
- void *mpu_addr,
- unsigned long size,
- void *req_addr,
- void *ret_map_addr,
- unsigned long attr)
- {
- struct map_mem arg = {
- .proc_handle = proc_handle,
- .mpu_addr = mpu_addr,
- .size = size,
- .req_addr = req_addr,
- .ret_map_addr = ret_map_addr,
- .attr = attr,
- };
- return !ioctl(handle, PROC_MAPMEM, &arg);
- }
- struct unmap_mem {
- void *proc_handle;
- unsigned long size;
- void *map_addr;
- };
- bool dsp_unmap(int handle,
- void *proc_handle,
- void *map_addr)
- {
- struct unmap_mem arg = {
- .proc_handle = proc_handle,
- .map_addr = map_addr,
- };
- return !ioctl(handle, PROC_UNMAPMEM, &arg);
- }
- struct flush_mem {
- void *proc_handle;
- void *mpu_addr;
- unsigned long size;
- unsigned long flags;
- };
- bool dsp_flush(int handle,
- void *proc_handle,
- void *mpu_addr,
- unsigned long size,
- unsigned long flags)
- {
- struct flush_mem arg = {
- .proc_handle = proc_handle,
- .mpu_addr = mpu_addr,
- .size = size,
- .flags = flags,
- };
- return !ioctl(handle, PROC_FLUSHMEMORY, &arg);
- }
- struct invalidate_mem {
- void *proc_handle;
- void *mpu_addr;
- unsigned long size;
- };
- bool dsp_invalidate(int handle,
- void *proc_handle,
- void *mpu_addr,
- unsigned long size)
- {
- struct invalidate_mem arg = {
- .proc_handle = proc_handle,
- .mpu_addr = mpu_addr,
- .size = size,
- };
- return !ioctl(handle, PROC_INVALIDATEMEMORY, &arg);
- }
- struct dma_op {
- void *proc_handle;
- void *mpu_addr;
- unsigned long size;
- unsigned long dir;
- };
- bool dsp_begin_dma(int handle,
- void *proc_handle,
- void *mpu_addr,
- unsigned long size,
- unsigned long dir)
- {
- struct dma_op arg = {
- .proc_handle = proc_handle,
- .mpu_addr = mpu_addr,
- .size = size,
- .dir = dir,
- };
- return !ioctl(handle, PROC_BEGINDMA, &arg);
- }
- bool dsp_end_dma(int handle,
- void *proc_handle,
- void *mpu_addr,
- unsigned long size,
- unsigned long dir)
- {
- struct dma_op arg = {
- .proc_handle = proc_handle,
- .mpu_addr = mpu_addr,
- .size = size,
- .dir = dir,
- };
- return !ioctl(handle, PROC_ENDDMA, &arg);
- }
- struct proc_get_info {
- void *proc_handle;
- unsigned type;
- struct dsp_info *info;
- unsigned size;
- };
- bool dsp_proc_get_info(int handle,
- void *proc_handle,
- unsigned type,
- struct dsp_info *info,
- unsigned size)
- {
- struct proc_get_info arg = {
- .proc_handle = proc_handle,
- .type = type,
- .info = info,
- .size = size,
- };
- return !ioctl(handle, PROC_ENUMRESOURCES, &arg);
- }
- struct enum_nodes {
- void *proc_handle;
- void **node_table;
- unsigned node_table_size;
- unsigned *num_nodes;
- unsigned *allocated;
- };
- bool dsp_enum_nodes(int handle,
- void *proc_handle,
- void **node_table,
- unsigned node_table_size,
- unsigned *num_nodes,
- unsigned *allocated)
- {
- struct enum_nodes arg = {
- .proc_handle = proc_handle,
- .node_table = node_table,
- .node_table_size = node_table_size,
- .num_nodes = num_nodes,
- .allocated = allocated,
- };
- return !ioctl(handle, PROC_ENUMNODE, &arg);
- }
- struct stream_attr {
- void *event;
- char *name;
- void *base;
- unsigned long size;
- struct dsp_stream_attr_in *attrin;
- };
- struct stream_open {
- void *node_handle;
- unsigned int direction;
- unsigned int index;
- struct stream_attr *attr;
- void *stream;
- };
- bool dsp_stream_open(int handle,
- struct dsp_node *node,
- unsigned int direction,
- unsigned int index,
- struct dsp_stream_attr_in *attrin,
- void *stream)
- {
- struct stream_attr strm_attr = {
- .attrin = attrin,
- };
- struct stream_open stream_arg = {
- .node_handle = node->handle,
- .direction = direction,
- .index = index,
- .attr = &strm_attr,
- .stream = stream,
- };
- if (attrin && (attrin->mode == STRMMODE_ZEROCOPY ||
- attrin->mode == STRMMODE_RDMA)) {
- struct dsp_cmm_info cmm_info;
- if (!get_cmm_info(handle, NULL, &cmm_info))
- return false;
- if (cmm_info.segments > 0) {
- void *base;
- struct dsp_cmm_seg_info *seg;
- seg = &cmm_info.info[0];
- base = mmap(NULL, seg->size,
- PROT_READ | PROT_WRITE,
- MAP_SHARED | 0x2000 /* MAP_LOCKED */,
- handle, seg->base_pa);
- if (!base)
- return false;
- strm_attr.base = base;
- strm_attr.size = seg->size;
- }
- }
- return !ioctl(handle, STRM_OPEN, &stream_arg);
- }
- struct stream_info {
- enum dsp_stream_mode mode;
- unsigned int segment;
- void *base;
- struct dsp_stream_info *info;
- };
- struct stream_get_info {
- void *stream;
- struct stream_info *info;
- unsigned int size;
- };
- static inline bool get_stream_info(int handle,
- void *stream,
- struct stream_info *info,
- unsigned int size)
- {
- struct stream_get_info arg = {
- .stream = stream,
- .info = info,
- .size = size,
- };
- return !ioctl(handle, STRM_GETINFO, &arg);
- }
- bool dsp_stream_close(int handle,
- void *stream)
- {
- struct stream_info info;
- if (!get_stream_info(handle, stream, &info, sizeof(struct stream_info)))
- return false;
- if (info.base) {
- struct dsp_cmm_info cmm_info;
- if (!get_cmm_info(handle, NULL, &cmm_info))
- return false;
- if (cmm_info.segments > 0) {
- struct dsp_cmm_seg_info *seg;
- seg = &cmm_info.info[0];
- if (munmap(info.base, seg->size))
- return false;
- }
- }
- return !ioctl(handle, STRM_CLOSE, &stream);
- }
- struct stream_idle {
- void *stream;
- bool flush;
- };
- bool dsp_stream_idle(int handle,
- void *stream,
- bool flush)
- {
- struct stream_idle arg = {
- .stream = stream,
- .flush = flush,
- };
- return !ioctl(handle, STRM_IDLE, &arg);
- }
- struct stream_reclaim {
- void *stream;
- unsigned char **buff;
- unsigned long *data_size;
- unsigned long *buff_size;
- unsigned long *flag;
- };
- bool dsp_stream_reclaim(int handle,
- void *stream,
- unsigned char **buff,
- unsigned long *data_size,
- unsigned long *buff_size,
- unsigned long *flag)
- {
- struct stream_reclaim arg = {
- .stream = stream,
- .buff = buff,
- .data_size = data_size,
- .buff_size = buff_size,
- .flag = flag,
- };
- return !ioctl(handle, STRM_RECLAIM, &arg);
- }
- struct stream_issue {
- void *stream;
- unsigned char *buff;
- unsigned long data_size;
- unsigned long buff_size;
- unsigned long flag;
- };
- bool dsp_stream_issue(int handle,
- void *stream,
- unsigned char *buff,
- unsigned long data_size,
- unsigned long buff_size,
- unsigned long flag)
- {
- struct stream_issue arg = {
- .stream = stream,
- .buff = buff,
- .data_size = data_size,
- .buff_size = buff_size,
- .flag = flag,
- };
- return !ioctl(handle, STRM_ISSUE, &arg);
- }
- bool dsp_stream_get_info(int handle,
- void *stream,
- struct dsp_stream_info *info,
- unsigned int size)
- {
- struct stream_info stream_info = {
- .info = info
- };
- return get_stream_info(handle, stream, &stream_info, size);
- }
- struct stream_allocate_buffer {
- void *stream;
- unsigned int size;
- unsigned char **buff;
- unsigned int num_buf;
- };
- bool dsp_stream_allocate_buffers(int handle,
- void *stream,
- unsigned int size,
- unsigned char **buff,
- unsigned int num_buf)
- {
- unsigned int i;
- struct stream_info info;
- if (!get_stream_info(handle, stream, &info, sizeof(struct stream_info)))
- return false;
- if (info.segment > 0) {
- struct stream_allocate_buffer arg = {
- .stream = stream,
- .size = size,
- .buff = buff,
- .num_buf = num_buf,
- };
- return !ioctl(handle, STRM_ALLOCATEBUFFER, &arg);
- }
- for (i = 0; i < num_buf; i++)
- buff[i] = (unsigned char *) malloc(size);
- return true;
- }
- struct stream_free_buffers {
- void *stream;
- unsigned char **buff;
- unsigned int num_buf;
- };
- bool dsp_stream_free_buffers(int handle,
- void *stream,
- unsigned char **buff,
- unsigned int num_buf)
- {
- unsigned int i;
- struct stream_info info;
- if (!get_stream_info(handle, stream, &info, sizeof(struct stream_info)))
- return false;
- if (info.segment) {
- struct stream_free_buffers arg = {
- .stream = stream,
- .buff = buff,
- .num_buf = num_buf,
- };
- return !ioctl(handle, STRM_FREEBUFFER, &arg);
- }
- for (i = 0; i < num_buf; i++) {
- free(buff[i]);
- buff[i] = NULL;
- }
- return true;
- }
|