staging: ti dspbridge: add platform manager code
Add TI's DSP Bridge platform manager driver sources Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com> Signed-off-by: Kanigeri, Hari <h-kanigeri2@ti.com> Signed-off-by: Ameya Palande <ameya.palande@nokia.com> Signed-off-by: Guzman Lugo, Fernando <fernando.lugo@ti.com> Signed-off-by: Hebbar, Shivananda <x0hebbar@ti.com> Signed-off-by: Ramos Falcon, Ernesto <ernesto@ti.com> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Anna, Suman <s-anna@ti.com> Signed-off-by: Gupta, Ramesh <grgupta@ti.com> Signed-off-by: Gomez Castellanos, Ivan <ivan.gomez@ti.com> Signed-off-by: Andy Shevchenko <ext-andriy.shevchenko@nokia.com> Signed-off-by: Armando Uribe De Leon <x0095078@ti.com> Signed-off-by: Deepak Chitriki <deepak.chitriki@ti.com> Signed-off-by: Menon, Nishanth <nm@ti.com> Signed-off-by: Phil Carmody <ext-phil.2.carmody@nokia.com> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
999e07d632
commit
c4ca3d5a4b
163
drivers/staging/tidspbridge/pmgr/chnl.c
Normal file
163
drivers/staging/tidspbridge/pmgr/chnl.c
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* chnl.c
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* DSP API channel interface: multiplexes data streams through the single
|
||||
* physical link managed by a Bridge Bridge driver.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* ----------------------------------- Host OS */
|
||||
#include <dspbridge/host_os.h>
|
||||
|
||||
/* ----------------------------------- DSP/BIOS Bridge */
|
||||
#include <dspbridge/std.h>
|
||||
#include <dspbridge/dbdefs.h>
|
||||
|
||||
/* ----------------------------------- Trace & Debug */
|
||||
#include <dspbridge/dbc.h>
|
||||
|
||||
/* ----------------------------------- OS Adaptation Layer */
|
||||
#include <dspbridge/cfg.h>
|
||||
#include <dspbridge/sync.h>
|
||||
|
||||
/* ----------------------------------- Platform Manager */
|
||||
#include <dspbridge/proc.h>
|
||||
#include <dspbridge/dev.h>
|
||||
|
||||
/* ----------------------------------- Others */
|
||||
#include <dspbridge/chnlpriv.h>
|
||||
#include <chnlobj.h>
|
||||
|
||||
/* ----------------------------------- This */
|
||||
#include <dspbridge/chnl.h>
|
||||
|
||||
/* ----------------------------------- Globals */
|
||||
static u32 refs;
|
||||
|
||||
/*
|
||||
* ======== chnl_create ========
|
||||
* Purpose:
|
||||
* Create a channel manager object, responsible for opening new channels
|
||||
* and closing old ones for a given 'Bridge board.
|
||||
*/
|
||||
int chnl_create(OUT struct chnl_mgr **phChnlMgr,
|
||||
struct dev_object *hdev_obj,
|
||||
IN CONST struct chnl_mgrattrs *pMgrAttrs)
|
||||
{
|
||||
int status;
|
||||
struct chnl_mgr *hchnl_mgr;
|
||||
struct chnl_mgr_ *chnl_mgr_obj = NULL;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(phChnlMgr != NULL);
|
||||
DBC_REQUIRE(pMgrAttrs != NULL);
|
||||
|
||||
*phChnlMgr = NULL;
|
||||
|
||||
/* Validate args: */
|
||||
if ((0 < pMgrAttrs->max_channels) &&
|
||||
(pMgrAttrs->max_channels <= CHNL_MAXCHANNELS))
|
||||
status = 0;
|
||||
else if (pMgrAttrs->max_channels == 0)
|
||||
status = -EINVAL;
|
||||
else
|
||||
status = -ECHRNG;
|
||||
|
||||
if (pMgrAttrs->word_size == 0)
|
||||
status = -EINVAL;
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
|
||||
if (DSP_SUCCEEDED(status) && hchnl_mgr != NULL)
|
||||
status = -EEXIST;
|
||||
|
||||
}
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
dev_get_intf_fxns(hdev_obj, &intf_fxns);
|
||||
/* Let Bridge channel module finish the create: */
|
||||
status = (*intf_fxns->pfn_chnl_create) (&hchnl_mgr, hdev_obj,
|
||||
pMgrAttrs);
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
/* Fill in DSP API channel module's fields of the
|
||||
* chnl_mgr structure */
|
||||
chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
|
||||
chnl_mgr_obj->intf_fxns = intf_fxns;
|
||||
/* Finally, return the new channel manager handle: */
|
||||
*phChnlMgr = hchnl_mgr;
|
||||
}
|
||||
}
|
||||
|
||||
DBC_ENSURE(DSP_FAILED(status) || chnl_mgr_obj);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== chnl_destroy ========
|
||||
* Purpose:
|
||||
* Close all open channels, and destroy the channel manager.
|
||||
*/
|
||||
int chnl_destroy(struct chnl_mgr *hchnl_mgr)
|
||||
{
|
||||
struct chnl_mgr_ *chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
int status;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
|
||||
if (chnl_mgr_obj) {
|
||||
intf_fxns = chnl_mgr_obj->intf_fxns;
|
||||
/* Let Bridge channel module destroy the chnl_mgr: */
|
||||
status = (*intf_fxns->pfn_chnl_destroy) (hchnl_mgr);
|
||||
} else {
|
||||
status = -EFAULT;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== chnl_exit ========
|
||||
* Purpose:
|
||||
* Discontinue usage of the CHNL module.
|
||||
*/
|
||||
void chnl_exit(void)
|
||||
{
|
||||
DBC_REQUIRE(refs > 0);
|
||||
|
||||
refs--;
|
||||
|
||||
DBC_ENSURE(refs >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== chnl_init ========
|
||||
* Purpose:
|
||||
* Initialize the CHNL module's private state.
|
||||
*/
|
||||
bool chnl_init(void)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
DBC_REQUIRE(refs >= 0);
|
||||
|
||||
if (ret)
|
||||
refs++;
|
||||
|
||||
DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
|
||||
|
||||
return ret;
|
||||
}
|
46
drivers/staging/tidspbridge/pmgr/chnlobj.h
Normal file
46
drivers/staging/tidspbridge/pmgr/chnlobj.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* chnlobj.h
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* Structure subcomponents of channel class library channel objects which
|
||||
* are exposed to DSP API from Bridge driver.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef CHNLOBJ_
|
||||
#define CHNLOBJ_
|
||||
|
||||
#include <dspbridge/chnldefs.h>
|
||||
#include <dspbridge/dspdefs.h>
|
||||
|
||||
/*
|
||||
* This struct is the first field in a chnl_mgr struct. Other. implementation
|
||||
* specific fields follow this structure in memory.
|
||||
*/
|
||||
struct chnl_mgr_ {
|
||||
/* These must be the first fields in a chnl_mgr struct: */
|
||||
|
||||
/* Function interface to Bridge driver. */
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct is the first field in a chnl_object struct. Other,
|
||||
* implementation specific fields follow this structure in memory.
|
||||
*/
|
||||
struct chnl_object_ {
|
||||
/* These must be the first fields in a chnl_object struct: */
|
||||
struct chnl_mgr_ *chnl_mgr_obj; /* Pointer back to channel manager. */
|
||||
};
|
||||
|
||||
#endif /* CHNLOBJ_ */
|
1172
drivers/staging/tidspbridge/pmgr/cmm.c
Normal file
1172
drivers/staging/tidspbridge/pmgr/cmm.c
Normal file
File diff suppressed because it is too large
Load Diff
658
drivers/staging/tidspbridge/pmgr/cod.c
Normal file
658
drivers/staging/tidspbridge/pmgr/cod.c
Normal file
@ -0,0 +1,658 @@
|
||||
/*
|
||||
* cod.c
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* This module implements DSP code management for the DSP/BIOS Bridge
|
||||
* environment. It is mostly a thin wrapper.
|
||||
*
|
||||
* This module provides an interface for loading both static and
|
||||
* dynamic code objects onto DSP systems.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* ----------------------------------- Host OS */
|
||||
#include <dspbridge/host_os.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/* ----------------------------------- DSP/BIOS Bridge */
|
||||
#include <dspbridge/std.h>
|
||||
#include <dspbridge/dbdefs.h>
|
||||
|
||||
/* ----------------------------------- Trace & Debug */
|
||||
#include <dspbridge/dbc.h>
|
||||
|
||||
/* ----------------------------------- OS Adaptation Layer */
|
||||
#include <dspbridge/ldr.h>
|
||||
|
||||
/* ----------------------------------- Platform Manager */
|
||||
/* Include appropriate loader header file */
|
||||
#include <dspbridge/dbll.h>
|
||||
|
||||
/* ----------------------------------- This */
|
||||
#include <dspbridge/cod.h>
|
||||
|
||||
/* magic number for handle validation */
|
||||
#define MAGIC 0xc001beef
|
||||
|
||||
/* macro to validate COD manager handles */
|
||||
#define IS_VALID(h) ((h) != NULL && (h)->ul_magic == MAGIC)
|
||||
|
||||
/*
|
||||
* ======== cod_manager ========
|
||||
*/
|
||||
struct cod_manager {
|
||||
struct dbll_tar_obj *target;
|
||||
struct dbll_library_obj *base_lib;
|
||||
bool loaded; /* Base library loaded? */
|
||||
u32 ul_entry;
|
||||
struct ldr_module *dll_obj;
|
||||
struct dbll_fxns fxns;
|
||||
struct dbll_attrs attrs;
|
||||
char sz_zl_file[COD_MAXPATHLENGTH];
|
||||
u32 ul_magic;
|
||||
};
|
||||
|
||||
/*
|
||||
* ======== cod_libraryobj ========
|
||||
*/
|
||||
struct cod_libraryobj {
|
||||
struct dbll_library_obj *dbll_lib;
|
||||
struct cod_manager *cod_mgr;
|
||||
};
|
||||
|
||||
static u32 refs = 0L;
|
||||
|
||||
static struct dbll_fxns ldr_fxns = {
|
||||
(dbll_close_fxn) dbll_close,
|
||||
(dbll_create_fxn) dbll_create,
|
||||
(dbll_delete_fxn) dbll_delete,
|
||||
(dbll_exit_fxn) dbll_exit,
|
||||
(dbll_get_attrs_fxn) dbll_get_attrs,
|
||||
(dbll_get_addr_fxn) dbll_get_addr,
|
||||
(dbll_get_c_addr_fxn) dbll_get_c_addr,
|
||||
(dbll_get_sect_fxn) dbll_get_sect,
|
||||
(dbll_init_fxn) dbll_init,
|
||||
(dbll_load_fxn) dbll_load,
|
||||
(dbll_load_sect_fxn) dbll_load_sect,
|
||||
(dbll_open_fxn) dbll_open,
|
||||
(dbll_read_sect_fxn) dbll_read_sect,
|
||||
(dbll_set_attrs_fxn) dbll_set_attrs,
|
||||
(dbll_unload_fxn) dbll_unload,
|
||||
(dbll_unload_sect_fxn) dbll_unload_sect,
|
||||
};
|
||||
|
||||
static bool no_op(void);
|
||||
|
||||
/*
|
||||
* File operations (originally were under kfile.c)
|
||||
*/
|
||||
static s32 cod_f_close(struct file *filp)
|
||||
{
|
||||
/* Check for valid handle */
|
||||
if (!filp)
|
||||
return -EFAULT;
|
||||
|
||||
filp_close(filp, NULL);
|
||||
|
||||
/* we can't use 0 here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file *cod_f_open(CONST char *psz_file_name, CONST char *pszMode)
|
||||
{
|
||||
mm_segment_t fs;
|
||||
struct file *filp;
|
||||
|
||||
fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
|
||||
/* ignore given mode and open file as read-only */
|
||||
filp = filp_open(psz_file_name, O_RDONLY, 0);
|
||||
|
||||
if (IS_ERR(filp))
|
||||
filp = NULL;
|
||||
|
||||
set_fs(fs);
|
||||
|
||||
return filp;
|
||||
}
|
||||
|
||||
static s32 cod_f_read(void __user *pbuffer, s32 size, s32 cCount,
|
||||
struct file *filp)
|
||||
{
|
||||
/* check for valid file handle */
|
||||
if (!filp)
|
||||
return -EFAULT;
|
||||
|
||||
if ((size > 0) && (cCount > 0) && pbuffer) {
|
||||
u32 dw_bytes_read;
|
||||
mm_segment_t fs;
|
||||
|
||||
/* read from file */
|
||||
fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
dw_bytes_read = filp->f_op->read(filp, pbuffer, size * cCount,
|
||||
&(filp->f_pos));
|
||||
set_fs(fs);
|
||||
|
||||
if (!dw_bytes_read)
|
||||
return -EBADF;
|
||||
|
||||
return dw_bytes_read / size;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static s32 cod_f_seek(struct file *filp, s32 lOffset, s32 cOrigin)
|
||||
{
|
||||
loff_t dw_cur_pos;
|
||||
|
||||
/* check for valid file handle */
|
||||
if (!filp)
|
||||
return -EFAULT;
|
||||
|
||||
/* based on the origin flag, move the internal pointer */
|
||||
dw_cur_pos = filp->f_op->llseek(filp, lOffset, cOrigin);
|
||||
|
||||
if ((s32) dw_cur_pos < 0)
|
||||
return -EPERM;
|
||||
|
||||
/* we can't use 0 here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 cod_f_tell(struct file *filp)
|
||||
{
|
||||
loff_t dw_cur_pos;
|
||||
|
||||
if (!filp)
|
||||
return -EFAULT;
|
||||
|
||||
/* Get current position */
|
||||
dw_cur_pos = filp->f_op->llseek(filp, 0, SEEK_CUR);
|
||||
|
||||
if ((s32) dw_cur_pos < 0)
|
||||
return -EPERM;
|
||||
|
||||
return dw_cur_pos;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_close ========
|
||||
*/
|
||||
void cod_close(struct cod_libraryobj *lib)
|
||||
{
|
||||
struct cod_manager *hmgr;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(lib != NULL);
|
||||
DBC_REQUIRE(IS_VALID(((struct cod_libraryobj *)lib)->cod_mgr));
|
||||
|
||||
hmgr = lib->cod_mgr;
|
||||
hmgr->fxns.close_fxn(lib->dbll_lib);
|
||||
|
||||
kfree(lib);
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_create ========
|
||||
* Purpose:
|
||||
* Create an object to manage code on a DSP system.
|
||||
* This object can be used to load an initial program image with
|
||||
* arguments that can later be expanded with
|
||||
* dynamically loaded object files.
|
||||
*
|
||||
*/
|
||||
int cod_create(OUT struct cod_manager **phMgr, char *pstrDummyFile,
|
||||
IN OPTIONAL CONST struct cod_attrs *attrs)
|
||||
{
|
||||
struct cod_manager *mgr_new;
|
||||
struct dbll_attrs zl_attrs;
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(phMgr != NULL);
|
||||
|
||||
/* assume failure */
|
||||
*phMgr = NULL;
|
||||
|
||||
/* we don't support non-default attrs yet */
|
||||
if (attrs != NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL);
|
||||
if (mgr_new == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
mgr_new->ul_magic = MAGIC;
|
||||
|
||||
/* Set up loader functions */
|
||||
mgr_new->fxns = ldr_fxns;
|
||||
|
||||
/* initialize the ZL module */
|
||||
mgr_new->fxns.init_fxn();
|
||||
|
||||
zl_attrs.alloc = (dbll_alloc_fxn) no_op;
|
||||
zl_attrs.free = (dbll_free_fxn) no_op;
|
||||
zl_attrs.fread = (dbll_read_fxn) cod_f_read;
|
||||
zl_attrs.fseek = (dbll_seek_fxn) cod_f_seek;
|
||||
zl_attrs.ftell = (dbll_tell_fxn) cod_f_tell;
|
||||
zl_attrs.fclose = (dbll_f_close_fxn) cod_f_close;
|
||||
zl_attrs.fopen = (dbll_f_open_fxn) cod_f_open;
|
||||
zl_attrs.sym_lookup = NULL;
|
||||
zl_attrs.base_image = true;
|
||||
zl_attrs.log_write = NULL;
|
||||
zl_attrs.log_write_handle = NULL;
|
||||
zl_attrs.write = NULL;
|
||||
zl_attrs.rmm_handle = NULL;
|
||||
zl_attrs.input_params = NULL;
|
||||
zl_attrs.sym_handle = NULL;
|
||||
zl_attrs.sym_arg = NULL;
|
||||
|
||||
mgr_new->attrs = zl_attrs;
|
||||
|
||||
status = mgr_new->fxns.create_fxn(&mgr_new->target, &zl_attrs);
|
||||
|
||||
if (DSP_FAILED(status)) {
|
||||
cod_delete(mgr_new);
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
/* return the new manager */
|
||||
*phMgr = mgr_new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_delete ========
|
||||
* Purpose:
|
||||
* Delete a code manager object.
|
||||
*/
|
||||
void cod_delete(struct cod_manager *hmgr)
|
||||
{
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(hmgr));
|
||||
|
||||
if (hmgr->base_lib) {
|
||||
if (hmgr->loaded)
|
||||
hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs);
|
||||
|
||||
hmgr->fxns.close_fxn(hmgr->base_lib);
|
||||
}
|
||||
if (hmgr->target) {
|
||||
hmgr->fxns.delete_fxn(hmgr->target);
|
||||
hmgr->fxns.exit_fxn();
|
||||
}
|
||||
hmgr->ul_magic = ~MAGIC;
|
||||
kfree(hmgr);
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_exit ========
|
||||
* Purpose:
|
||||
* Discontinue usage of the COD module.
|
||||
*
|
||||
*/
|
||||
void cod_exit(void)
|
||||
{
|
||||
DBC_REQUIRE(refs > 0);
|
||||
|
||||
refs--;
|
||||
|
||||
DBC_ENSURE(refs >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_get_base_lib ========
|
||||
* Purpose:
|
||||
* Get handle to the base image DBL library.
|
||||
*/
|
||||
int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
|
||||
struct dbll_library_obj **plib)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(cod_mgr_obj));
|
||||
DBC_REQUIRE(plib != NULL);
|
||||
|
||||
*plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_get_base_name ========
|
||||
*/
|
||||
int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *pszName,
|
||||
u32 usize)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(cod_mgr_obj));
|
||||
DBC_REQUIRE(pszName != NULL);
|
||||
|
||||
if (usize <= COD_MAXPATHLENGTH)
|
||||
strncpy(pszName, cod_mgr_obj->sz_zl_file, usize);
|
||||
else
|
||||
status = -EPERM;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_get_entry ========
|
||||
* Purpose:
|
||||
* Retrieve the entry point of a loaded DSP program image
|
||||
*
|
||||
*/
|
||||
int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *pulEntry)
|
||||
{
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(cod_mgr_obj));
|
||||
DBC_REQUIRE(pulEntry != NULL);
|
||||
|
||||
*pulEntry = cod_mgr_obj->ul_entry;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_get_loader ========
|
||||
* Purpose:
|
||||
* Get handle to the DBLL loader.
|
||||
*/
|
||||
int cod_get_loader(struct cod_manager *cod_mgr_obj,
|
||||
struct dbll_tar_obj **phLoader)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(cod_mgr_obj));
|
||||
DBC_REQUIRE(phLoader != NULL);
|
||||
|
||||
*phLoader = (struct dbll_tar_obj *)cod_mgr_obj->target;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_get_section ========
|
||||
* Purpose:
|
||||
* Retrieve the starting address and length of a section in the COFF file
|
||||
* given the section name.
|
||||
*/
|
||||
int cod_get_section(struct cod_libraryobj *lib, IN char *pstrSect,
|
||||
OUT u32 *puAddr, OUT u32 *puLen)
|
||||
{
|
||||
struct cod_manager *cod_mgr_obj;
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(lib != NULL);
|
||||
DBC_REQUIRE(IS_VALID(lib->cod_mgr));
|
||||
DBC_REQUIRE(pstrSect != NULL);
|
||||
DBC_REQUIRE(puAddr != NULL);
|
||||
DBC_REQUIRE(puLen != NULL);
|
||||
|
||||
*puAddr = 0;
|
||||
*puLen = 0;
|
||||
if (lib != NULL) {
|
||||
cod_mgr_obj = lib->cod_mgr;
|
||||
status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, pstrSect,
|
||||
puAddr, puLen);
|
||||
} else {
|
||||
status = -ESPIPE;
|
||||
}
|
||||
|
||||
DBC_ENSURE(DSP_SUCCEEDED(status) || ((*puAddr == 0) && (*puLen == 0)));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_get_sym_value ========
|
||||
* Purpose:
|
||||
* Retrieve the value for the specified symbol. The symbol is first
|
||||
* searched for literally and then, if not found, searched for as a
|
||||
* C symbol.
|
||||
*
|
||||
*/
|
||||
int cod_get_sym_value(struct cod_manager *hmgr, char *pstrSym,
|
||||
u32 *pul_value)
|
||||
{
|
||||
struct dbll_sym_val *dbll_sym;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(hmgr));
|
||||
DBC_REQUIRE(pstrSym != NULL);
|
||||
DBC_REQUIRE(pul_value != NULL);
|
||||
|
||||
dev_dbg(bridge, "%s: hmgr: %p pstrSym: %s pul_value: %p\n",
|
||||
__func__, hmgr, pstrSym, pul_value);
|
||||
if (hmgr->base_lib) {
|
||||
if (!hmgr->fxns.
|
||||
get_addr_fxn(hmgr->base_lib, pstrSym, &dbll_sym)) {
|
||||
if (!hmgr->fxns.
|
||||
get_c_addr_fxn(hmgr->base_lib, pstrSym, &dbll_sym))
|
||||
return -ESPIPE;
|
||||
}
|
||||
} else {
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
*pul_value = dbll_sym->value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_init ========
|
||||
* Purpose:
|
||||
* Initialize the COD module's private state.
|
||||
*
|
||||
*/
|
||||
bool cod_init(void)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
DBC_REQUIRE(refs >= 0);
|
||||
|
||||
if (ret)
|
||||
refs++;
|
||||
|
||||
DBC_ENSURE((ret && refs > 0) || (!ret && refs >= 0));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_load_base ========
|
||||
* Purpose:
|
||||
* Load the initial program image, optionally with command-line arguments,
|
||||
* on the DSP system managed by the supplied handle. The program to be
|
||||
* loaded must be the first element of the args array and must be a fully
|
||||
* qualified pathname.
|
||||
* Details:
|
||||
* if nArgc doesn't match the number of arguments in the aArgs array, the
|
||||
* aArgs array is searched for a NULL terminating entry, and argc is
|
||||
* recalculated to reflect this. In this way, we can support NULL
|
||||
* terminating aArgs arrays, if nArgc is very large.
|
||||
*/
|
||||
int cod_load_base(struct cod_manager *hmgr, u32 nArgc, char *aArgs[],
|
||||
cod_writefxn pfn_write, void *pArb, char *envp[])
|
||||
{
|
||||
dbll_flags flags;
|
||||
struct dbll_attrs save_attrs;
|
||||
struct dbll_attrs new_attrs;
|
||||
int status;
|
||||
u32 i;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(hmgr));
|
||||
DBC_REQUIRE(nArgc > 0);
|
||||
DBC_REQUIRE(aArgs != NULL);
|
||||
DBC_REQUIRE(aArgs[0] != NULL);
|
||||
DBC_REQUIRE(pfn_write != NULL);
|
||||
DBC_REQUIRE(hmgr->base_lib != NULL);
|
||||
|
||||
/*
|
||||
* Make sure every argv[] stated in argc has a value, or change argc to
|
||||
* reflect true number in NULL terminated argv array.
|
||||
*/
|
||||
for (i = 0; i < nArgc; i++) {
|
||||
if (aArgs[i] == NULL) {
|
||||
nArgc = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the write function for this operation */
|
||||
hmgr->fxns.get_attrs_fxn(hmgr->target, &save_attrs);
|
||||
|
||||
new_attrs = save_attrs;
|
||||
new_attrs.write = (dbll_write_fxn) pfn_write;
|
||||
new_attrs.input_params = pArb;
|
||||
new_attrs.alloc = (dbll_alloc_fxn) no_op;
|
||||
new_attrs.free = (dbll_free_fxn) no_op;
|
||||
new_attrs.log_write = NULL;
|
||||
new_attrs.log_write_handle = NULL;
|
||||
|
||||
/* Load the image */
|
||||
flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
|
||||
status = hmgr->fxns.load_fxn(hmgr->base_lib, flags, &new_attrs,
|
||||
&hmgr->ul_entry);
|
||||
if (DSP_FAILED(status))
|
||||
hmgr->fxns.close_fxn(hmgr->base_lib);
|
||||
|
||||
if (DSP_SUCCEEDED(status))
|
||||
hmgr->loaded = true;
|
||||
else
|
||||
hmgr->base_lib = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_open ========
|
||||
* Open library for reading sections.
|
||||
*/
|
||||
int cod_open(struct cod_manager *hmgr, IN char *pszCoffPath,
|
||||
u32 flags, struct cod_libraryobj **pLib)
|
||||
{
|
||||
int status = 0;
|
||||
struct cod_libraryobj *lib = NULL;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(hmgr));
|
||||
DBC_REQUIRE(pszCoffPath != NULL);
|
||||
DBC_REQUIRE(flags == COD_NOLOAD || flags == COD_SYMB);
|
||||
DBC_REQUIRE(pLib != NULL);
|
||||
|
||||
*pLib = NULL;
|
||||
|
||||
lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL);
|
||||
if (lib == NULL)
|
||||
status = -ENOMEM;
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
lib->cod_mgr = hmgr;
|
||||
status = hmgr->fxns.open_fxn(hmgr->target, pszCoffPath, flags,
|
||||
&lib->dbll_lib);
|
||||
if (DSP_SUCCEEDED(status))
|
||||
*pLib = lib;
|
||||
}
|
||||
|
||||
if (DSP_FAILED(status))
|
||||
pr_err("%s: error status 0x%x, pszCoffPath: %s flags: 0x%x\n",
|
||||
__func__, status, pszCoffPath, flags);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_open_base ========
|
||||
* Purpose:
|
||||
* Open base image for reading sections.
|
||||
*/
|
||||
int cod_open_base(struct cod_manager *hmgr, IN char *pszCoffPath,
|
||||
dbll_flags flags)
|
||||
{
|
||||
int status = 0;
|
||||
struct dbll_library_obj *lib;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(IS_VALID(hmgr));
|
||||
DBC_REQUIRE(pszCoffPath != NULL);
|
||||
|
||||
/* if we previously opened a base image, close it now */
|
||||
if (hmgr->base_lib) {
|
||||
if (hmgr->loaded) {
|
||||
hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs);
|
||||
hmgr->loaded = false;
|
||||
}
|
||||
hmgr->fxns.close_fxn(hmgr->base_lib);
|
||||
hmgr->base_lib = NULL;
|
||||
}
|
||||
status = hmgr->fxns.open_fxn(hmgr->target, pszCoffPath, flags, &lib);
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
/* hang onto the library for subsequent sym table usage */
|
||||
hmgr->base_lib = lib;
|
||||
strncpy(hmgr->sz_zl_file, pszCoffPath, COD_MAXPATHLENGTH - 1);
|
||||
hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0';
|
||||
}
|
||||
|
||||
if (DSP_FAILED(status))
|
||||
pr_err("%s: error status 0x%x pszCoffPath: %s\n", __func__,
|
||||
status, pszCoffPath);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== cod_read_section ========
|
||||
* Purpose:
|
||||
* Retrieve the content of a code section given the section name.
|
||||
*/
|
||||
int cod_read_section(struct cod_libraryobj *lib, IN char *pstrSect,
|
||||
OUT char *pstrContent, IN u32 cContentSize)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(lib != NULL);
|
||||
DBC_REQUIRE(IS_VALID(lib->cod_mgr));
|
||||
DBC_REQUIRE(pstrSect != NULL);
|
||||
DBC_REQUIRE(pstrContent != NULL);
|
||||
|
||||
if (lib != NULL)
|
||||
status =
|
||||
lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, pstrSect,
|
||||
pstrContent, cContentSize);
|
||||
else
|
||||
status = -ESPIPE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== no_op ========
|
||||
* Purpose:
|
||||
* No Operation.
|
||||
*
|
||||
*/
|
||||
static bool no_op(void)
|
||||
{
|
||||
return true;
|
||||
}
|
1585
drivers/staging/tidspbridge/pmgr/dbll.c
Normal file
1585
drivers/staging/tidspbridge/pmgr/dbll.c
Normal file
File diff suppressed because it is too large
Load Diff
1171
drivers/staging/tidspbridge/pmgr/dev.c
Normal file
1171
drivers/staging/tidspbridge/pmgr/dev.c
Normal file
File diff suppressed because it is too large
Load Diff
533
drivers/staging/tidspbridge/pmgr/dmm.c
Normal file
533
drivers/staging/tidspbridge/pmgr/dmm.c
Normal file
@ -0,0 +1,533 @@
|
||||
/*
|
||||
* dmm.c
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
|
||||
* space that can be directly mapped to any MPU buffer or memory region
|
||||
*
|
||||
* Notes:
|
||||
* Region: Generic memory entitiy having a start address and a size
|
||||
* Chunk: Reserved region
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* ----------------------------------- Host OS */
|
||||
#include <dspbridge/host_os.h>
|
||||
|
||||
/* ----------------------------------- DSP/BIOS Bridge */
|
||||
#include <dspbridge/std.h>
|
||||
#include <dspbridge/dbdefs.h>
|
||||
|
||||
/* ----------------------------------- Trace & Debug */
|
||||
#include <dspbridge/dbc.h>
|
||||
|
||||
/* ----------------------------------- OS Adaptation Layer */
|
||||
#include <dspbridge/sync.h>
|
||||
|
||||
/* ----------------------------------- Platform Manager */
|
||||
#include <dspbridge/dev.h>
|
||||
#include <dspbridge/proc.h>
|
||||
|
||||
/* ----------------------------------- This */
|
||||
#include <dspbridge/dmm.h>
|
||||
|
||||
/* ----------------------------------- Defines, Data Structures, Typedefs */
|
||||
#define DMM_ADDR_VIRTUAL(a) \
|
||||
(((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\
|
||||
dyn_mem_map_beg)
|
||||
#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K)
|
||||
|
||||
/* DMM Mgr */
|
||||
struct dmm_object {
|
||||
/* Dmm Lock is used to serialize access mem manager for
|
||||
* multi-threads. */
|
||||
spinlock_t dmm_lock; /* Lock to access dmm mgr */
|
||||
};
|
||||
|
||||
/* ----------------------------------- Globals */
|
||||
static u32 refs; /* module reference count */
|
||||
struct map_page {
|
||||
u32 region_size:15;
|
||||
u32 mapped_size:15;
|
||||
u32 reserved:1;
|
||||
u32 mapped:1;
|
||||
};
|
||||
|
||||
/* Create the free list */
|
||||
static struct map_page *virtual_mapping_table;
|
||||
static u32 free_region; /* The index of free region */
|
||||
static u32 free_size;
|
||||
static u32 dyn_mem_map_beg; /* The Beginning of dynamic memory mapping */
|
||||
static u32 table_size; /* The size of virt and phys pages tables */
|
||||
|
||||
/* ----------------------------------- Function Prototypes */
|
||||
static struct map_page *get_region(u32 addr);
|
||||
static struct map_page *get_free_region(u32 aSize);
|
||||
static struct map_page *get_mapped_region(u32 aAddr);
|
||||
|
||||
/* ======== dmm_create_tables ========
|
||||
* Purpose:
|
||||
* Create table to hold the information of physical address
|
||||
* the buffer pages that is passed by the user, and the table
|
||||
* to hold the information of the virtual memory that is reserved
|
||||
* for DSP.
|
||||
*/
|
||||
int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size)
|
||||
{
|
||||
struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
|
||||
int status = 0;
|
||||
|
||||
status = dmm_delete_tables(dmm_obj);
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
dyn_mem_map_beg = addr;
|
||||
table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K;
|
||||
/* Create the free list */
|
||||
virtual_mapping_table = __vmalloc(table_size *
|
||||
sizeof(struct map_page), GFP_KERNEL |
|
||||
__GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
|
||||
if (virtual_mapping_table == NULL)
|
||||
status = -ENOMEM;
|
||||
else {
|
||||
/* On successful allocation,
|
||||
* all entries are zero ('free') */
|
||||
free_region = 0;
|
||||
free_size = table_size * PG_SIZE4K;
|
||||
virtual_mapping_table[0].region_size = table_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (DSP_FAILED(status))
|
||||
pr_err("%s: failure, status 0x%x\n", __func__, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_create ========
|
||||
* Purpose:
|
||||
* Create a dynamic memory manager object.
|
||||
*/
|
||||
int dmm_create(OUT struct dmm_object **phDmmMgr,
|
||||
struct dev_object *hdev_obj,
|
||||
IN CONST struct dmm_mgrattrs *pMgrAttrs)
|
||||
{
|
||||
struct dmm_object *dmm_obj = NULL;
|
||||
int status = 0;
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(phDmmMgr != NULL);
|
||||
|
||||
*phDmmMgr = NULL;
|
||||
/* create, zero, and tag a cmm mgr object */
|
||||
dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL);
|
||||
if (dmm_obj != NULL) {
|
||||
spin_lock_init(&dmm_obj->dmm_lock);
|
||||
*phDmmMgr = dmm_obj;
|
||||
} else {
|
||||
status = -ENOMEM;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_destroy ========
|
||||
* Purpose:
|
||||
* Release the communication memory manager resources.
|
||||
*/
|
||||
int dmm_destroy(struct dmm_object *dmm_mgr)
|
||||
{
|
||||
struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
if (dmm_mgr) {
|
||||
status = dmm_delete_tables(dmm_obj);
|
||||
if (DSP_SUCCEEDED(status))
|
||||
kfree(dmm_obj);
|
||||
} else
|
||||
status = -EFAULT;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_delete_tables ========
|
||||
* Purpose:
|
||||
* Delete DMM Tables.
|
||||
*/
|
||||
int dmm_delete_tables(struct dmm_object *dmm_mgr)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
/* Delete all DMM tables */
|
||||
if (dmm_mgr)
|
||||
vfree(virtual_mapping_table);
|
||||
else
|
||||
status = -EFAULT;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_exit ========
|
||||
* Purpose:
|
||||
* Discontinue usage of module; free resources when reference count
|
||||
* reaches 0.
|
||||
*/
|
||||
void dmm_exit(void)
|
||||
{
|
||||
DBC_REQUIRE(refs > 0);
|
||||
|
||||
refs--;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_get_handle ========
|
||||
* Purpose:
|
||||
* Return the dynamic memory manager object for this device.
|
||||
* This is typically called from the client process.
|
||||
*/
|
||||
int dmm_get_handle(void *hprocessor, OUT struct dmm_object **phDmmMgr)
|
||||
{
|
||||
int status = 0;
|
||||
struct dev_object *hdev_obj;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(phDmmMgr != NULL);
|
||||
if (hprocessor != NULL)
|
||||
status = proc_get_dev_object(hprocessor, &hdev_obj);
|
||||
else
|
||||
hdev_obj = dev_get_first(); /* default */
|
||||
|
||||
if (DSP_SUCCEEDED(status))
|
||||
status = dev_get_dmm_mgr(hdev_obj, phDmmMgr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_init ========
|
||||
* Purpose:
|
||||
* Initializes private state of DMM module.
|
||||
*/
|
||||
bool dmm_init(void)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
DBC_REQUIRE(refs >= 0);
|
||||
|
||||
if (ret)
|
||||
refs++;
|
||||
|
||||
DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
|
||||
|
||||
virtual_mapping_table = NULL;
|
||||
table_size = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_map_memory ========
|
||||
* Purpose:
|
||||
* Add a mapping block to the reserved chunk. DMM assumes that this block
|
||||
* will be mapped in the DSP/IVA's address space. DMM returns an error if a
|
||||
* mapping overlaps another one. This function stores the info that will be
|
||||
* required later while unmapping the block.
|
||||
*/
|
||||
int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size)
|
||||
{
|
||||
struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
|
||||
struct map_page *chunk;
|
||||
int status = 0;
|
||||
|
||||
spin_lock(&dmm_obj->dmm_lock);
|
||||
/* Find the Reserved memory chunk containing the DSP block to
|
||||
* be mapped */
|
||||
chunk = (struct map_page *)get_region(addr);
|
||||
if (chunk != NULL) {
|
||||
/* Mark the region 'mapped', leave the 'reserved' info as-is */
|
||||
chunk->mapped = true;
|
||||
chunk->mapped_size = (size / PG_SIZE4K);
|
||||
} else
|
||||
status = -ENOENT;
|
||||
spin_unlock(&dmm_obj->dmm_lock);
|
||||
|
||||
dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, "
|
||||
"chunk %p", __func__, dmm_mgr, addr, size, status, chunk);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_reserve_memory ========
|
||||
* Purpose:
|
||||
* Reserve a chunk of virtually contiguous DSP/IVA address space.
|
||||
*/
|
||||
int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size,
|
||||
u32 *prsv_addr)
|
||||
{
|
||||
int status = 0;
|
||||
struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
|
||||
struct map_page *node;
|
||||
u32 rsv_addr = 0;
|
||||
u32 rsv_size = 0;
|
||||
|
||||
spin_lock(&dmm_obj->dmm_lock);
|
||||
|
||||
/* Try to get a DSP chunk from the free list */
|
||||
node = get_free_region(size);
|
||||
if (node != NULL) {
|
||||
/* DSP chunk of given size is available. */
|
||||
rsv_addr = DMM_ADDR_VIRTUAL(node);
|
||||
/* Calculate the number entries to use */
|
||||
rsv_size = size / PG_SIZE4K;
|
||||
if (rsv_size < node->region_size) {
|
||||
/* Mark remainder of free region */
|
||||
node[rsv_size].mapped = false;
|
||||
node[rsv_size].reserved = false;
|
||||
node[rsv_size].region_size =
|
||||
node->region_size - rsv_size;
|
||||
node[rsv_size].mapped_size = 0;
|
||||
}
|
||||
/* get_region will return first fit chunk. But we only use what
|
||||
is requested. */
|
||||
node->mapped = false;
|
||||
node->reserved = true;
|
||||
node->region_size = rsv_size;
|
||||
node->mapped_size = 0;
|
||||
/* Return the chunk's starting address */
|
||||
*prsv_addr = rsv_addr;
|
||||
} else
|
||||
/*dSP chunk of given size is not available */
|
||||
status = -ENOMEM;
|
||||
|
||||
spin_unlock(&dmm_obj->dmm_lock);
|
||||
|
||||
dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, "
|
||||
"rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size,
|
||||
prsv_addr, status, rsv_addr, rsv_size);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_un_map_memory ========
|
||||
* Purpose:
|
||||
* Remove the mapped block from the reserved chunk.
|
||||
*/
|
||||
int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize)
|
||||
{
|
||||
struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
|
||||
struct map_page *chunk;
|
||||
int status = 0;
|
||||
|
||||
spin_lock(&dmm_obj->dmm_lock);
|
||||
chunk = get_mapped_region(addr);
|
||||
if (chunk == NULL)
|
||||
status = -ENOENT;
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
/* Unmap the region */
|
||||
*psize = chunk->mapped_size * PG_SIZE4K;
|
||||
chunk->mapped = false;
|
||||
chunk->mapped_size = 0;
|
||||
}
|
||||
spin_unlock(&dmm_obj->dmm_lock);
|
||||
|
||||
dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, "
|
||||
"chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dmm_un_reserve_memory ========
|
||||
* Purpose:
|
||||
* Free a chunk of reserved DSP/IVA address space.
|
||||
*/
|
||||
int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr)
|
||||
{
|
||||
struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
|
||||
struct map_page *chunk;
|
||||
u32 i;
|
||||
int status = 0;
|
||||
u32 chunk_size;
|
||||
|
||||
spin_lock(&dmm_obj->dmm_lock);
|
||||
|
||||
/* Find the chunk containing the reserved address */
|
||||
chunk = get_mapped_region(rsv_addr);
|
||||
if (chunk == NULL)
|
||||
status = -ENOENT;
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
/* Free all the mapped pages for this reserved region */
|
||||
i = 0;
|
||||
while (i < chunk->region_size) {
|
||||
if (chunk[i].mapped) {
|
||||
/* Remove mapping from the page tables. */
|
||||
chunk_size = chunk[i].mapped_size;
|
||||
/* Clear the mapping flags */
|
||||
chunk[i].mapped = false;
|
||||
chunk[i].mapped_size = 0;
|
||||
i += chunk_size;
|
||||
} else
|
||||
i++;
|
||||
}
|
||||
/* Clear the flags (mark the region 'free') */
|
||||
chunk->reserved = false;
|
||||
/* NOTE: We do NOT coalesce free regions here.
|
||||
* Free regions are coalesced in get_region(), as it traverses
|
||||
*the whole mapping table
|
||||
*/
|
||||
}
|
||||
spin_unlock(&dmm_obj->dmm_lock);
|
||||
|
||||
dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p",
|
||||
__func__, dmm_mgr, rsv_addr, status, chunk);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== get_region ========
|
||||
* Purpose:
|
||||
* Returns a region containing the specified memory region
|
||||
*/
|
||||
static struct map_page *get_region(u32 aAddr)
|
||||
{
|
||||
struct map_page *curr_region = NULL;
|
||||
u32 i = 0;
|
||||
|
||||
if (virtual_mapping_table != NULL) {
|
||||
/* find page mapped by this address */
|
||||
i = DMM_ADDR_TO_INDEX(aAddr);
|
||||
if (i < table_size)
|
||||
curr_region = virtual_mapping_table + i;
|
||||
}
|
||||
|
||||
dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n",
|
||||
__func__, curr_region, free_region, free_size);
|
||||
return curr_region;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== get_free_region ========
|
||||
* Purpose:
|
||||
* Returns the requested free region
|
||||
*/
|
||||
static struct map_page *get_free_region(u32 aSize)
|
||||
{
|
||||
struct map_page *curr_region = NULL;
|
||||
u32 i = 0;
|
||||
u32 region_size = 0;
|
||||
u32 next_i = 0;
|
||||
|
||||
if (virtual_mapping_table == NULL)
|
||||
return curr_region;
|
||||
if (aSize > free_size) {
|
||||
/* Find the largest free region
|
||||
* (coalesce during the traversal) */
|
||||
while (i < table_size) {
|
||||
region_size = virtual_mapping_table[i].region_size;
|
||||
next_i = i + region_size;
|
||||
if (virtual_mapping_table[i].reserved == false) {
|
||||
/* Coalesce, if possible */
|
||||
if (next_i < table_size &&
|
||||
virtual_mapping_table[next_i].reserved
|
||||
== false) {
|
||||
virtual_mapping_table[i].region_size +=
|
||||
virtual_mapping_table
|
||||
[next_i].region_size;
|
||||
continue;
|
||||
}
|
||||
region_size *= PG_SIZE4K;
|
||||
if (region_size > free_size) {
|
||||
free_region = i;
|
||||
free_size = region_size;
|
||||
}
|
||||
}
|
||||
i = next_i;
|
||||
}
|
||||
}
|
||||
if (aSize <= free_size) {
|
||||
curr_region = virtual_mapping_table + free_region;
|
||||
free_region += (aSize / PG_SIZE4K);
|
||||
free_size -= aSize;
|
||||
}
|
||||
return curr_region;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== get_mapped_region ========
|
||||
* Purpose:
|
||||
* Returns the requestedmapped region
|
||||
*/
|
||||
static struct map_page *get_mapped_region(u32 aAddr)
|
||||
{
|
||||
u32 i = 0;
|
||||
struct map_page *curr_region = NULL;
|
||||
|
||||
if (virtual_mapping_table == NULL)
|
||||
return curr_region;
|
||||
|
||||
i = DMM_ADDR_TO_INDEX(aAddr);
|
||||
if (i < table_size && (virtual_mapping_table[i].mapped ||
|
||||
virtual_mapping_table[i].reserved))
|
||||
curr_region = virtual_mapping_table + i;
|
||||
return curr_region;
|
||||
}
|
||||
|
||||
#ifdef DSP_DMM_DEBUG
|
||||
u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr)
|
||||
{
|
||||
struct map_page *curr_node = NULL;
|
||||
u32 i;
|
||||
u32 freemem = 0;
|
||||
u32 bigsize = 0;
|
||||
|
||||
spin_lock(&dmm_mgr->dmm_lock);
|
||||
|
||||
if (virtual_mapping_table != NULL) {
|
||||
for (i = 0; i < table_size; i +=
|
||||
virtual_mapping_table[i].region_size) {
|
||||
curr_node = virtual_mapping_table + i;
|
||||
if (curr_node->reserved == TRUE) {
|
||||
/*printk("RESERVED size = 0x%x, "
|
||||
"Map size = 0x%x\n",
|
||||
(curr_node->region_size * PG_SIZE4K),
|
||||
(curr_node->mapped == false) ? 0 :
|
||||
(curr_node->mapped_size * PG_SIZE4K));
|
||||
*/
|
||||
} else {
|
||||
/* printk("UNRESERVED size = 0x%x\n",
|
||||
(curr_node->region_size * PG_SIZE4K));
|
||||
*/
|
||||
freemem += (curr_node->region_size * PG_SIZE4K);
|
||||
if (curr_node->region_size > bigsize)
|
||||
bigsize = curr_node->region_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&dmm_mgr->dmm_lock);
|
||||
printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n",
|
||||
freemem / (1024 * 1024));
|
||||
printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n",
|
||||
(((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024));
|
||||
printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n",
|
||||
(bigsize * PG_SIZE4K / (1024 * 1024)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
1685
drivers/staging/tidspbridge/pmgr/dspapi.c
Normal file
1685
drivers/staging/tidspbridge/pmgr/dspapi.c
Normal file
File diff suppressed because it is too large
Load Diff
142
drivers/staging/tidspbridge/pmgr/io.c
Normal file
142
drivers/staging/tidspbridge/pmgr/io.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* io.c
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* IO manager interface: Manages IO between CHNL and msg_ctrl.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* ----------------------------------- Host OS */
|
||||
#include <dspbridge/host_os.h>
|
||||
|
||||
/* ----------------------------------- DSP/BIOS Bridge */
|
||||
#include <dspbridge/std.h>
|
||||
#include <dspbridge/dbdefs.h>
|
||||
|
||||
/* ----------------------------------- Trace & Debug */
|
||||
#include <dspbridge/dbc.h>
|
||||
|
||||
/* ----------------------------------- OS Adaptation Layer */
|
||||
#include <dspbridge/cfg.h>
|
||||
|
||||
/* ----------------------------------- Platform Manager */
|
||||
#include <dspbridge/dev.h>
|
||||
|
||||
/* ----------------------------------- This */
|
||||
#include <ioobj.h>
|
||||
#include <dspbridge/iodefs.h>
|
||||
#include <dspbridge/io.h>
|
||||
|
||||
/* ----------------------------------- Globals */
|
||||
static u32 refs;
|
||||
|
||||
/*
|
||||
* ======== io_create ========
|
||||
* Purpose:
|
||||
* Create an IO manager object, responsible for managing IO between
|
||||
* CHNL and msg_ctrl
|
||||
*/
|
||||
int io_create(OUT struct io_mgr **phIOMgr, struct dev_object *hdev_obj,
|
||||
IN CONST struct io_attrs *pMgrAttrs)
|
||||
{
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
struct io_mgr *hio_mgr = NULL;
|
||||
struct io_mgr_ *pio_mgr = NULL;
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(phIOMgr != NULL);
|
||||
DBC_REQUIRE(pMgrAttrs != NULL);
|
||||
|
||||
*phIOMgr = NULL;
|
||||
|
||||
/* A memory base of 0 implies no memory base: */
|
||||
if ((pMgrAttrs->shm_base != 0) && (pMgrAttrs->usm_length == 0))
|
||||
status = -EINVAL;
|
||||
|
||||
if (pMgrAttrs->word_size == 0)
|
||||
status = -EINVAL;
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
dev_get_intf_fxns(hdev_obj, &intf_fxns);
|
||||
|
||||
/* Let Bridge channel module finish the create: */
|
||||
status = (*intf_fxns->pfn_io_create) (&hio_mgr, hdev_obj,
|
||||
pMgrAttrs);
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
pio_mgr = (struct io_mgr_ *)hio_mgr;
|
||||
pio_mgr->intf_fxns = intf_fxns;
|
||||
pio_mgr->hdev_obj = hdev_obj;
|
||||
|
||||
/* Return the new channel manager handle: */
|
||||
*phIOMgr = hio_mgr;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== io_destroy ========
|
||||
* Purpose:
|
||||
* Delete IO manager.
|
||||
*/
|
||||
int io_destroy(struct io_mgr *hio_mgr)
|
||||
{
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
struct io_mgr_ *pio_mgr = (struct io_mgr_ *)hio_mgr;
|
||||
int status;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
|
||||
intf_fxns = pio_mgr->intf_fxns;
|
||||
|
||||
/* Let Bridge channel module destroy the io_mgr: */
|
||||
status = (*intf_fxns->pfn_io_destroy) (hio_mgr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== io_exit ========
|
||||
* Purpose:
|
||||
* Discontinue usage of the IO module.
|
||||
*/
|
||||
void io_exit(void)
|
||||
{
|
||||
DBC_REQUIRE(refs > 0);
|
||||
|
||||
refs--;
|
||||
|
||||
DBC_ENSURE(refs >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== io_init ========
|
||||
* Purpose:
|
||||
* Initialize the IO module's private state.
|
||||
*/
|
||||
bool io_init(void)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
DBC_REQUIRE(refs >= 0);
|
||||
|
||||
if (ret)
|
||||
refs++;
|
||||
|
||||
DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
|
||||
|
||||
return ret;
|
||||
}
|
38
drivers/staging/tidspbridge/pmgr/ioobj.h
Normal file
38
drivers/staging/tidspbridge/pmgr/ioobj.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* ioobj.h
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* Structure subcomponents of channel class library IO objects which
|
||||
* are exposed to DSP API from Bridge driver.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef IOOBJ_
|
||||
#define IOOBJ_
|
||||
|
||||
#include <dspbridge/devdefs.h>
|
||||
#include <dspbridge/dspdefs.h>
|
||||
|
||||
/*
|
||||
* This struct is the first field in a io_mgr struct. Other, implementation
|
||||
* specific fields follow this structure in memory.
|
||||
*/
|
||||
struct io_mgr_ {
|
||||
/* These must be the first fields in a io_mgr struct: */
|
||||
struct bridge_dev_context *hbridge_context; /* Bridge context. */
|
||||
/* Function interface to Bridge driver. */
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
struct dev_object *hdev_obj; /* Device this board represents. */
|
||||
};
|
||||
|
||||
#endif /* IOOBJ_ */
|
129
drivers/staging/tidspbridge/pmgr/msg.c
Normal file
129
drivers/staging/tidspbridge/pmgr/msg.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* msg.c
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* DSP/BIOS Bridge msg_ctrl Module.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* ----------------------------------- Host OS */
|
||||
#include <dspbridge/host_os.h>
|
||||
|
||||
/* ----------------------------------- DSP/BIOS Bridge */
|
||||
#include <dspbridge/std.h>
|
||||
#include <dspbridge/dbdefs.h>
|
||||
|
||||
/* ----------------------------------- Trace & Debug */
|
||||
#include <dspbridge/dbc.h>
|
||||
|
||||
/* ----------------------------------- Bridge Driver */
|
||||
#include <dspbridge/dspdefs.h>
|
||||
|
||||
/* ----------------------------------- Platform Manager */
|
||||
#include <dspbridge/dev.h>
|
||||
|
||||
/* ----------------------------------- This */
|
||||
#include <msgobj.h>
|
||||
#include <dspbridge/msg.h>
|
||||
|
||||
/* ----------------------------------- Globals */
|
||||
static u32 refs; /* module reference count */
|
||||
|
||||
/*
|
||||
* ======== msg_create ========
|
||||
* Purpose:
|
||||
* Create an object to manage message queues. Only one of these objects
|
||||
* can exist per device object.
|
||||
*/
|
||||
int msg_create(OUT struct msg_mgr **phMsgMgr,
|
||||
struct dev_object *hdev_obj, msg_onexit msgCallback)
|
||||
{
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
struct msg_mgr_ *msg_mgr_obj;
|
||||
struct msg_mgr *hmsg_mgr;
|
||||
int status = 0;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
DBC_REQUIRE(phMsgMgr != NULL);
|
||||
DBC_REQUIRE(msgCallback != NULL);
|
||||
DBC_REQUIRE(hdev_obj != NULL);
|
||||
|
||||
*phMsgMgr = NULL;
|
||||
|
||||
dev_get_intf_fxns(hdev_obj, &intf_fxns);
|
||||
|
||||
/* Let Bridge message module finish the create: */
|
||||
status =
|
||||
(*intf_fxns->pfn_msg_create) (&hmsg_mgr, hdev_obj, msgCallback);
|
||||
|
||||
if (DSP_SUCCEEDED(status)) {
|
||||
/* Fill in DSP API message module's fields of the msg_mgr
|
||||
* structure */
|
||||
msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr;
|
||||
msg_mgr_obj->intf_fxns = intf_fxns;
|
||||
|
||||
/* Finally, return the new message manager handle: */
|
||||
*phMsgMgr = hmsg_mgr;
|
||||
} else {
|
||||
status = -EPERM;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== msg_delete ========
|
||||
* Purpose:
|
||||
* Delete a msg_ctrl manager allocated in msg_create().
|
||||
*/
|
||||
void msg_delete(struct msg_mgr *hmsg_mgr)
|
||||
{
|
||||
struct msg_mgr_ *msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr;
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
|
||||
DBC_REQUIRE(refs > 0);
|
||||
|
||||
if (msg_mgr_obj) {
|
||||
intf_fxns = msg_mgr_obj->intf_fxns;
|
||||
|
||||
/* Let Bridge message module destroy the msg_mgr: */
|
||||
(*intf_fxns->pfn_msg_delete) (hmsg_mgr);
|
||||
} else {
|
||||
dev_dbg(bridge, "%s: Error hmsg_mgr handle: %p\n",
|
||||
__func__, hmsg_mgr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== msg_exit ========
|
||||
*/
|
||||
void msg_exit(void)
|
||||
{
|
||||
DBC_REQUIRE(refs > 0);
|
||||
refs--;
|
||||
|
||||
DBC_ENSURE(refs >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== msg_mod_init ========
|
||||
*/
|
||||
bool msg_mod_init(void)
|
||||
{
|
||||
DBC_REQUIRE(refs >= 0);
|
||||
|
||||
refs++;
|
||||
|
||||
DBC_ENSURE(refs >= 0);
|
||||
|
||||
return true;
|
||||
}
|
38
drivers/staging/tidspbridge/pmgr/msgobj.h
Normal file
38
drivers/staging/tidspbridge/pmgr/msgobj.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* msgobj.h
|
||||
*
|
||||
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
|
||||
*
|
||||
* Structure subcomponents of channel class library msg_ctrl objects which
|
||||
* are exposed to DSP API from Bridge driver.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Texas Instruments, Inc.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef MSGOBJ_
|
||||
#define MSGOBJ_
|
||||
|
||||
#include <dspbridge/dspdefs.h>
|
||||
|
||||
#include <dspbridge/msgdefs.h>
|
||||
|
||||
/*
|
||||
* This struct is the first field in a msg_mgr struct. Other, implementation
|
||||
* specific fields follow this structure in memory.
|
||||
*/
|
||||
struct msg_mgr_ {
|
||||
/* The first field must match that in _msg_sm.h */
|
||||
|
||||
/* Function interface to Bridge driver. */
|
||||
struct bridge_drv_interface *intf_fxns;
|
||||
};
|
||||
|
||||
#endif /* MSGOBJ_ */
|
Loading…
Reference in New Issue
Block a user