diff options
Diffstat (limited to 'drivers/staging/tidspbridge')
124 files changed, 0 insertions, 44725 deletions
diff --git a/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS b/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS deleted file mode 100644 index 86f578727f9..00000000000 --- a/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS +++ /dev/null @@ -1,45 +0,0 @@ -TI DSP/Bridge Driver - Contributors File - -The DSP/Bridge project wish to thank all of its contributors, current bridge -driver is the result of the work of all of them. If any name is accidentally -omitted, let us know by sending a mail to omar.ramirez@ti.com or -x095840@ti.com. - -Please keep the following list in alphabetical order. - - Suman Anna - Sripal Bagadia - Felipe Balbi - Ohad Ben-Cohen - Phil Carmody - Deepak Chitriki - Felipe Contreras - Hiroshi Doyu - Seth Forshee - Ivan Gomez Castellanos - Mark Grosen - Ramesh Gupta G - Fernando Guzman Lugo - Axel Haslam - Janet Head - Shivananda Hebbar - Hari Kanigeri - Tony Lindgren - Antonio Luna - Hari Nagalla - Nishanth Menon - Ameya Palande - Vijay Pasam - Gilbert Pitney - Omar Ramirez Luna - Ernesto Ramos - Chris Ring - Larry Schiefer - Rebecca Schultz Zavin - Bhavin Shah - Andy Shevchenko - Jeff Taylor - Roman Tereshonkov - Armando Uribe de Leon - Nischal Varide - Wenbiao Wang diff --git a/drivers/staging/tidspbridge/Documentation/README b/drivers/staging/tidspbridge/Documentation/README deleted file mode 100644 index df6d371161e..00000000000 --- a/drivers/staging/tidspbridge/Documentation/README +++ /dev/null @@ -1,70 +0,0 @@ - Linux DSP/BIOS Bridge release - -DSP/BIOS Bridge overview -======================== - -DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more -attached DSPs. The GPP is considered the master or "host" processor, and the -attached DSPs are processing resources that can be utilized by applications -and drivers running on the GPP. - -The abstraction that DSP/BIOS Bridge supplies, is a direct link between a GPP -program and a DSP task. This communication link is partitioned into two -types of sub-links: messaging (short, fixed-length packets) and data -streaming (multiple, large buffers). Each sub-link operates independently, -and features in-order delivery of data, meaning that messages are delivered -in the order they were submitted to the message link, and stream buffers are -delivered in the order they were submitted to the stream link. - -In addition, a GPP client can specify what inputs and outputs a DSP task -uses. DSP tasks typically use message objects for passing control and status -information and stream objects for efficient streaming of real-time data. - -GPP Software Architecture -========================= - -A GPP application communicates with its associated DSP task running on the -DSP subsystem using the DSP/BIOS Bridge API. For example, a GPP audio -application can use the API to pass messages to a DSP task that is managing -data flowing from analog-to-digital converters (ADCs) to digital-to-analog -converters (DACs). - -From the perspective of the GPP OS, the DSP is treated as just another -peripheral device. Most high level GPP OS typically support a device driver -model, whereby applications can safely access and share a hardware peripheral -through standard driver interfaces. Therefore, to allow multiple GPP -applications to share access to the DSP, the GPP side of DSP/BIOS Bridge -implements a device driver for the DSP. - -Since driver interfaces are not always standard across GPP OS, and to provide -some level of interoperability of application code using DSP/BIOS Bridge -between GPP OS, DSP/BIOS Bridge provides a standard library of APIs which -wrap calls into the device driver. So, rather than calling GPP OS specific -driver interfaces, applications (and even other device drivers) can use the -standard API library directly. - -DSP Software Architecture -========================= - -For DSP/BIOS, DSP/BIOS Bridge adds a device-independent streaming I/O (STRM) -interface, a messaging interface (NODE), and a Resource Manager (RM) Server. -The RM Server runs as a task of DSP/BIOS and is subservient to commands -and queries from the GPP. It executes commands to start and stop DSP signal -processing nodes in response to GPP programs making requests through the -(GPP-side) API. - -DSP tasks started by the RM Server are similar to any other DSP task with two -important differences: they must follow a specific task model consisting of -three C-callable functions (node create, execute, and delete), with specific -sets of arguments, and they have a pre-defined task environment established -by the RM Server. - -Tasks started by the RM Server communicate using the STRM and NODE interfaces -and act as servers for their corresponding GPP clients, performing signal -processing functions as requested by messages sent by their GPP client. -Typically, a DSP task moves data from source devices to sink devices using -device independent I/O streams, performing application-specific processing -and transformations on the data while it is moved. For example, an audio -task might perform audio decompression (ADPCM, MPEG, CELP) on data received -from a GPP audio driver and then send the decompressed linear samples to a -digital-to-analog converter. diff --git a/drivers/staging/tidspbridge/Documentation/error-codes b/drivers/staging/tidspbridge/Documentation/error-codes deleted file mode 100644 index ad73cba058e..00000000000 --- a/drivers/staging/tidspbridge/Documentation/error-codes +++ /dev/null @@ -1,157 +0,0 @@ - DSP/Bridge Error Code Guide - - -Success code is always taken as 0, except for one case where a success status -different than 0 can be possible, this is when enumerating a series of dsp -objects, if the enumeration doesn't have any more objects it is considered as a -successful case. In this case a positive ENODATA is returned (TODO: Change to -avoid this case). - -Error codes are returned as a negative 1, if an specific code is expected, it -can be propagated to user space by reading errno symbol defined in errno.h, for -specific details on the implementation a copy of the standard used should be -read first. - -The error codes used by this driver are: - -[EPERM] - General driver failure. - - According to the use case the following might apply: - - Device is in 'sleep/suspend' mode due to DPM. - - User cannot mark end of stream on an input channel. - - Requested operation is invalid for the node type. - - Invalid alignment for the node messaging buffer. - - The specified direction is invalid for the stream. - - Invalid stream mode. - -[ENOENT] - The specified object or file was not found. - -[ESRCH] - A shared memory buffer contained in a message or stream could not be mapped - to the GPP client process's virtual space. - -[EIO] - Driver interface I/O error. - - or: - - Unable to plug channel ISR for configured IRQ. - - No free I/O request packets are available. - -[ENXIO] - Unable to find a named section in DSP executable or a non-existent memory - segment identifier was specified. - -[EBADF] - General error for file handling: - - - Unable to open file. - - Unable to read file. - - An error occurred while parsing the DSP executable file. - -[ENOMEM] - A memory allocation failure occurred. - -[EACCES] - - Unable to read content of DCD data section; this is typically caused by - improperly configured nodes. - - Unable to decode DCD data section content; this is typically caused by - changes to DSP/BIOS Bridge data structures. - - Unable to get pointer to DCD data section; this is typically caused by - improperly configured UUIDs. - - Unable to load file containing DCD data section; this is typically - caused by a missing COFF file. - - The specified COFF file does not contain a valid node registration - section. - -[EFAULT] - Invalid pointer or handler. - -[EEXIST] - Attempted to create a channel manager when one already exists. - -[EINVAL] - Invalid argument. - -[ESPIPE] - Symbol not found in the COFF file. DSPNode_Create will return this if - the iAlg function table for an xDAIS socket is not found in the COFF file. - In this case, force the symbol to be linked into the COFF file. - DSPNode_Create, DSPNode_Execute, and DSPNode_Delete will return this if - the create, execute, or delete phase function, respectively, could not be - found in the COFF file. - - - No symbol table is loaded/found for this board. - - Unable to initialize the ZL COFF parsing module. - -[EPIPE] - I/O is currently pending. - - - End of stream was already requested on this output channel. - -[EDOM] - A parameter is specified outside its valid range. - -[ENOSYS] - The indicated operation is not supported. - -[EIDRM] - During enumeration a change in the number or properties of the objects - has occurred. - -[ECHRNG] - Attempt to created channel manager with too many channels or channel ID out - of range. - -[EBADR] - The state of the specified object is incorrect for the requested operation. - - - Invalid segment ID. - -[ENODATA] - Unable to retrieve resource information from the registry. - - - No more registry values. - -[ETIME] - A timeout occurred before the requested operation could complete. - -[ENOSR] - A stream has been issued the maximum number of buffers allowed in the - stream at once; buffers must be reclaimed from the stream before any more - can be issued. - - - No free channels are available. - -[EILSEQ] - Error occurred in a dynamic loader library function. - -[EISCONN] - The Specified Connection already exists. - -[ENOTCONN] - Nodes not connected. - -[ETIMEDOUT] - Timeout occurred waiting for a response from the hardware. - - - Wait for flush operation on an output channel timed out. - -[ECONNREFUSED] - No more connections can be made for this node. - -[EALREADY] - Channel is already in use. - -[EREMOTEIO] - dwTimeOut parameter was CHNL_IOCNOWAIT, yet no I/O completions were - queued. - -[ECANCELED] - I/O has been cancelled on this channel. - -[ENOKEY] - Invalid subkey parameter. - - - UUID not found in registry. diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig deleted file mode 100644 index b5e74e9de6b..00000000000 --- a/drivers/staging/tidspbridge/Kconfig +++ /dev/null @@ -1,69 +0,0 @@ -# -# DSP Bridge Driver Support -# - -menuconfig TIDSPBRIDGE - tristate "DSP Bridge driver" - depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM && BROKEN - select MAILBOX - select OMAP2PLUS_MBOX - help - DSP/BIOS Bridge is designed for platforms that contain a GPP and - one or more attached DSPs. The GPP is considered the master or - "host" processor, and the attached DSPs are processing resources - that can be utilized by applications and drivers running on the GPP. - - This driver depends on OMAP Mailbox (OMAP_MBOX_FWK). - -config TIDSPBRIDGE_DVFS - bool "Enable Bridge Dynamic Voltage and Frequency Scaling (DVFS)" - depends on TIDSPBRIDGE && CPU_FREQ - help - DVFS allows DSP Bridge to initiate the operating point change to - scale the chip voltage and frequency in order to match the - performance and power consumption to the current processing - requirements. - -config TIDSPBRIDGE_MEMPOOL_SIZE - hex "Physical memory pool size (Byte)" - depends on TIDSPBRIDGE - default 0x600000 - help - Allocate specified size of memory at booting time to avoid allocation - failure under heavy memory fragmentation after some use time. - -config TIDSPBRIDGE_RECOVERY - bool "Recovery Support" - depends on TIDSPBRIDGE - default y - help - In case of DSP fatal error, BRIDGE driver will try to - recover itself. - -config TIDSPBRIDGE_CACHE_LINE_CHECK - bool "Check buffers to be 128 byte aligned" - depends on TIDSPBRIDGE - help - When the DSP processes data, the DSP cache controller loads 128-Byte - chunks (lines) from SDRAM and writes the data back in 128-Byte chunks. - If a DMM buffer does not start and end on a 128-Byte boundary, the data - preceding the start address (SA) from the 128-Byte boundary to the SA - and the data at addresses trailing the end address (EA) from the EA to - the next 128-Byte boundary will be loaded and written back as well. - This can lead to heap corruption. Say Y, to enforce the check for 128 - byte alignment, buffers failing this check will be rejected. - -config TIDSPBRIDGE_NTFY_PWRERR - bool "Notify power errors" - depends on TIDSPBRIDGE - help - Enable notifications to registered clients on the event of power error - trying to suspend bridge driver. Say Y, to signal this event as a fatal - error, this will require a bridge restart to recover. - -config TIDSPBRIDGE_BACKTRACE - bool "Dump backtraces on fatal errors" - depends on TIDSPBRIDGE - help - Enable useful information to backtrace fatal errors. Say Y if you - want to dump information for testing purposes. diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile deleted file mode 100644 index adb21c53f74..00000000000 --- a/drivers/staging/tidspbridge/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge.o - -libgen = gen/gh.o -libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ - core/tiomap3430_pwr.o core/tiomap_io.o \ - core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o -libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \ - pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o -librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ - rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \ - rmgr/nldr.o rmgr/drv_interface.o -libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \ - dynload/tramp.o -libhw = hw/hw_mmu.o - -tidspbridge-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \ - $(libdload) $(libhw) - -#Machine dependent -ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ - -DTICFG_PROC_VER -DTICFG_EVM_TYPE -DCHNL_SMCLASS \ - -DCHNL_MESSAGES -DUSE_LEVEL_1_MACROS - -ccflags-y += -Idrivers/staging/tidspbridge/include -ccflags-y += -Idrivers/staging/tidspbridge/services -ccflags-y += -Idrivers/staging/tidspbridge/core -ccflags-y += -Idrivers/staging/tidspbridge/pmgr -ccflags-y += -Idrivers/staging/tidspbridge/rmgr -ccflags-y += -Idrivers/staging/tidspbridge/dynload -ccflags-y += -Idrivers/staging/tidspbridge/hw -ccflags-y += -Iarch/arm - diff --git a/drivers/staging/tidspbridge/TODO b/drivers/staging/tidspbridge/TODO deleted file mode 100644 index 1c51e2dc7b5..00000000000 --- a/drivers/staging/tidspbridge/TODO +++ /dev/null @@ -1,18 +0,0 @@ -* Migrate to (and if necessary, extend) existing upstream code such as - iommu, wdt, mcbsp, gptimers -* Decouple hardware-specific code (e.g. bridge_brd_start/stop/delete/monitor) -* DOFF binary loader: consider pushing to user space. at the very least - eliminate the direct filesystem access -* Eliminate general services and libraries - use or extend existing kernel - libraries instead (e.g. gcf/lcm in nldr.c, global helpers in gen/) -* Eliminate direct manipulation of OMAP_SYSC_BASE -* Eliminate DSP_SUCCEEDED macros and their imposed redundant indentations - (adopt the kernel way of checking for return values) -* Audit interfaces exposed to user space -* Audit and clean up header files folder -* Use kernel coding style -* checkpatch.pl fixes -* allocate ext_mem_pool from consistent memory instead of using ioremap - -Please send any patches to Greg Kroah-Hartman <greg@kroah.com> -and Omar Ramirez Luna <omar.ramirez@ti.com>. diff --git a/drivers/staging/tidspbridge/core/_cmm.h b/drivers/staging/tidspbridge/core/_cmm.h deleted file mode 100644 index 7660bef6ebb..00000000000 --- a/drivers/staging/tidspbridge/core/_cmm.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * _cmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Private header file defining CMM manager objects and defines needed - * by IO manager to register shared memory regions when DSP base image - * is loaded(bridge_io_on_loaded). - * - * 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 _CMM_ -#define _CMM_ - -/* - * These target side symbols define the beginning and ending addresses - * of the section of shared memory used for shared memory manager CMM. - * They are defined in the *cfg.cmd file by cdb code. - */ -#define SHM0_SHARED_BASE_SYM "_SHM0_BEG" -#define SHM0_SHARED_END_SYM "_SHM0_END" -#define SHM0_SHARED_RESERVED_BASE_SYM "_SHM0_RSVDSTRT" - -/* - * Shared Memory Region #0(SHMSEG0) is used in the following way: - * - * |(_SHM0_BEG) | (_SHM0_RSVDSTRT) | (_SHM0_END) - * V V V - * ------------------------------------------------------------ - * | DSP-side allocations | GPP-side allocations | - * ------------------------------------------------------------ - * - * - */ - -#endif /* _CMM_ */ diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h deleted file mode 100644 index 025d34320e7..00000000000 --- a/drivers/staging/tidspbridge/core/_deh.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * _deh.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Private header for DEH module. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * Copyright (C) 2010 Felipe Contreras - * - * 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 _DEH_ -#define _DEH_ - -#include <dspbridge/ntfy.h> -#include <dspbridge/dspdefs.h> - -/* DEH Manager: only one created per board: */ -struct deh_mgr { - struct bridge_dev_context *bridge_context; /* Bridge context. */ - struct ntfy_object *ntfy_obj; /* NTFY object */ - - /* MMU Fault DPC */ - struct tasklet_struct dpc_tasklet; -}; - -#endif /* _DEH_ */ diff --git a/drivers/staging/tidspbridge/core/_msg_sm.h b/drivers/staging/tidspbridge/core/_msg_sm.h deleted file mode 100644 index f6e58e3f3b4..00000000000 --- a/drivers/staging/tidspbridge/core/_msg_sm.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * _msg_sm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Private header file defining msg_ctrl manager objects and defines needed - * by IO manager. - * - * 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 _MSG_SM_ -#define _MSG_SM_ - -#include <linux/list.h> -#include <dspbridge/msgdefs.h> - -/* - * These target side symbols define the beginning and ending addresses - * of the section of shared memory used for messages. They are - * defined in the *cfg.cmd file by cdb code. - */ -#define MSG_SHARED_BUFFER_BASE_SYM "_MSG_BEG" -#define MSG_SHARED_BUFFER_LIMIT_SYM "_MSG_END" - -#ifndef _CHNL_WORDSIZE -#define _CHNL_WORDSIZE 4 /* default _CHNL_WORDSIZE is 2 bytes/word */ -#endif - -/* - * ======== msg_ctrl ======== - * There is a control structure for messages to the DSP, and a control - * structure for messages from the DSP. The shared memory region for - * transferring messages is partitioned as follows: - * - * ---------------------------------------------------------- - * |Control | Messages from DSP | Control | Messages to DSP | - * ---------------------------------------------------------- - * - * msg_ctrl control structure for messages to the DSP is used in the following - * way: - * - * buf_empty - This flag is set to FALSE by the GPP after it has output - * messages for the DSP. The DSP host driver sets it to - * TRUE after it has copied the messages. - * post_swi - Set to 1 by the GPP after it has written the messages, - * set the size, and set buf_empty to FALSE. - * The DSP Host driver uses SWI_andn of the post_swi field - * when a host interrupt occurs. The host driver clears - * this after posting the SWI. - * size - Number of messages to be read by the DSP. - * - * For messages from the DSP: - * buf_empty - This flag is set to FALSE by the DSP after it has output - * messages for the GPP. The DPC on the GPP sets it to - * TRUE after it has copied the messages. - * post_swi - Set to 1 the DPC on the GPP after copying the messages. - * size - Number of messages to be read by the GPP. - */ -struct msg_ctrl { - u32 buf_empty; /* to/from DSP buffer is empty */ - u32 post_swi; /* Set to "1" to post msg_ctrl SWI */ - u32 size; /* Number of messages to/from the DSP */ - u32 resvd; -}; - -/* - * ======== msg_mgr ======== - * The msg_mgr maintains a list of all MSG_QUEUEs. Each NODE object can - * have msg_queue to hold all messages that come up from the corresponding - * node on the DSP. The msg_mgr also has a shared queue of messages - * ready to go to the DSP. - */ -struct msg_mgr { - /* The first field must match that in msgobj.h */ - - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; - - struct io_mgr *iomgr; /* IO manager */ - struct list_head queue_list; /* List of MSG_QUEUEs */ - spinlock_t msg_mgr_lock; /* For critical sections */ - /* Signalled when MsgFrame is available */ - struct sync_object *sync_event; - struct list_head msg_free_list; /* Free MsgFrames ready to be filled */ - struct list_head msg_used_list; /* MsgFrames ready to go to DSP */ - u32 msgs_pending; /* # of queued messages to go to DSP */ - u32 max_msgs; /* Max # of msgs that fit in buffer */ - msg_onexit on_exit; /* called when RMS_EXIT is received */ -}; - -/* - * ======== msg_queue ======== - * Each NODE has a msg_queue for receiving messages from the - * corresponding node on the DSP. The msg_queue object maintains a list - * of messages that have been sent to the host, but not yet read (MSG_Get), - * and a list of free frames that can be filled when new messages arrive - * from the DSP. - * The msg_queue's hSynEvent gets posted when a message is ready. - */ -struct msg_queue { - struct list_head list_elem; - struct msg_mgr *msg_mgr; - u32 max_msgs; /* Node message depth */ - u32 msgq_id; /* Node environment pointer */ - struct list_head msg_free_list; /* Free MsgFrames ready to be filled */ - /* Filled MsgFramess waiting to be read */ - struct list_head msg_used_list; - void *arg; /* Handle passed to mgr on_exit callback */ - struct sync_object *sync_event; /* Signalled when message is ready */ - struct sync_object *sync_done; /* For synchronizing cleanup */ - struct sync_object *sync_done_ack; /* For synchronizing cleanup */ - struct ntfy_object *ntfy_obj; /* For notification of message ready */ - bool done; /* TRUE <==> deleting the object */ - u32 io_msg_pend; /* Number of pending MSG_get/put calls */ -}; - -/* - * ======== msg_dspmsg ======== - */ -struct msg_dspmsg { - struct dsp_msg msg; - u32 msgq_id; /* Identifies the node the message goes to */ -}; - -/* - * ======== msg_frame ======== - */ -struct msg_frame { - struct list_head list_elem; - struct msg_dspmsg msg_data; -}; - -#endif /* _MSG_SM_ */ diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h deleted file mode 100644 index 65971b784b7..00000000000 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * _tiomap.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Definitions and types private to this 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 _TIOMAP_ -#define _TIOMAP_ - -/* - * XXX These powerdomain.h/clockdomain.h includes are wrong and should - * be removed. No driver should call pwrdm_* or clkdm_* functions - * directly; they should rely on OMAP core code to do this. - */ -#include <mach-omap2/powerdomain.h> -#include <mach-omap2/clockdomain.h> -/* - * XXX These mach-omap2/ includes are wrong and should be removed. No - * driver should read or write to PRM/CM registers directly; they - * should rely on OMAP core code to do this. - */ -#include <mach-omap2/cm3xxx.h> -#include <mach-omap2/prm-regbits-34xx.h> -#include <mach-omap2/cm-regbits-34xx.h> -#include <dspbridge/devdefs.h> -#include <hw_defs.h> -#include <dspbridge/dspioctl.h> /* for bridge_ioctl_extproc defn */ -#include <dspbridge/sync.h> -#include <dspbridge/clk.h> - -struct map_l4_peripheral { - u32 phys_addr; - u32 dsp_virt_addr; -}; - -#define ARM_MAILBOX_START 0xfffcf000 -#define ARM_MAILBOX_LENGTH 0x800 - -/* New Registers in OMAP3.1 */ - -#define TESTBLOCK_ID_START 0xfffed400 -#define TESTBLOCK_ID_LENGTH 0xff - -/* ID Returned by OMAP1510 */ -#define TBC_ID_VALUE 0xB47002F - -#define SPACE_LENGTH 0x2000 -#define API_CLKM_DPLL_DMA 0xfffec000 -#define ARM_INTERRUPT_OFFSET 0xb00 - -#define BIOS24XX - -#define L4_PERIPHERAL_NULL 0x0 -#define DSPVA_PERIPHERAL_NULL 0x0 - -#define MAX_LOCK_TLB_ENTRIES 15 - -#define L4_PERIPHERAL_PRM 0x48306000 /*PRM L4 Peripheral */ -#define DSPVA_PERIPHERAL_PRM 0x1181e000 -#define L4_PERIPHERAL_SCM 0x48002000 /*SCM L4 Peripheral */ -#define DSPVA_PERIPHERAL_SCM 0x1181f000 -#define L4_PERIPHERAL_MMU 0x5D000000 /*MMU L4 Peripheral */ -#define DSPVA_PERIPHERAL_MMU 0x11820000 -#define L4_PERIPHERAL_CM 0x48004000 /* Core L4, Clock Management */ -#define DSPVA_PERIPHERAL_CM 0x1181c000 -#define L4_PERIPHERAL_PER 0x48005000 /* PER */ -#define DSPVA_PERIPHERAL_PER 0x1181d000 - -#define L4_PERIPHERAL_GPIO1 0x48310000 -#define DSPVA_PERIPHERAL_GPIO1 0x11809000 -#define L4_PERIPHERAL_GPIO2 0x49050000 -#define DSPVA_PERIPHERAL_GPIO2 0x1180a000 -#define L4_PERIPHERAL_GPIO3 0x49052000 -#define DSPVA_PERIPHERAL_GPIO3 0x1180b000 -#define L4_PERIPHERAL_GPIO4 0x49054000 -#define DSPVA_PERIPHERAL_GPIO4 0x1180c000 -#define L4_PERIPHERAL_GPIO5 0x49056000 -#define DSPVA_PERIPHERAL_GPIO5 0x1180d000 - -#define L4_PERIPHERAL_IVA2WDT 0x49030000 -#define DSPVA_PERIPHERAL_IVA2WDT 0x1180e000 - -#define L4_PERIPHERAL_DISPLAY 0x48050000 -#define DSPVA_PERIPHERAL_DISPLAY 0x1180f000 - -#define L4_PERIPHERAL_SSI 0x48058000 -#define DSPVA_PERIPHERAL_SSI 0x11804000 -#define L4_PERIPHERAL_GDD 0x48059000 -#define DSPVA_PERIPHERAL_GDD 0x11805000 -#define L4_PERIPHERAL_SS1 0x4805a000 -#define DSPVA_PERIPHERAL_SS1 0x11806000 -#define L4_PERIPHERAL_SS2 0x4805b000 -#define DSPVA_PERIPHERAL_SS2 0x11807000 - -#define L4_PERIPHERAL_CAMERA 0x480BC000 -#define DSPVA_PERIPHERAL_CAMERA 0x11819000 - -#define L4_PERIPHERAL_SDMA 0x48056000 -#define DSPVA_PERIPHERAL_SDMA 0x11810000 /* 0x1181d000 conflict w/ PER */ - -#define L4_PERIPHERAL_UART1 0x4806a000 -#define DSPVA_PERIPHERAL_UART1 0x11811000 -#define L4_PERIPHERAL_UART2 0x4806c000 -#define DSPVA_PERIPHERAL_UART2 0x11812000 -#define L4_PERIPHERAL_UART3 0x49020000 -#define DSPVA_PERIPHERAL_UART3 0x11813000 - -#define L4_PERIPHERAL_MCBSP1 0x48074000 -#define DSPVA_PERIPHERAL_MCBSP1 0x11814000 -#define L4_PERIPHERAL_MCBSP2 0x49022000 -#define DSPVA_PERIPHERAL_MCBSP2 0x11815000 -#define L4_PERIPHERAL_MCBSP3 0x49024000 -#define DSPVA_PERIPHERAL_MCBSP3 0x11816000 -#define L4_PERIPHERAL_MCBSP4 0x49026000 -#define DSPVA_PERIPHERAL_MCBSP4 0x11817000 -#define L4_PERIPHERAL_MCBSP5 0x48096000 -#define DSPVA_PERIPHERAL_MCBSP5 0x11818000 - -#define L4_PERIPHERAL_GPTIMER5 0x49038000 -#define DSPVA_PERIPHERAL_GPTIMER5 0x11800000 -#define L4_PERIPHERAL_GPTIMER6 0x4903a000 -#define DSPVA_PERIPHERAL_GPTIMER6 0x11801000 -#define L4_PERIPHERAL_GPTIMER7 0x4903c000 -#define DSPVA_PERIPHERAL_GPTIMER7 0x11802000 -#define L4_PERIPHERAL_GPTIMER8 0x4903e000 -#define DSPVA_PERIPHERAL_GPTIMER8 0x11803000 - -#define L4_PERIPHERAL_SPI1 0x48098000 -#define DSPVA_PERIPHERAL_SPI1 0x1181a000 -#define L4_PERIPHERAL_SPI2 0x4809a000 -#define DSPVA_PERIPHERAL_SPI2 0x1181b000 - -#define L4_PERIPHERAL_MBOX 0x48094000 -#define DSPVA_PERIPHERAL_MBOX 0x11808000 - -#define PM_GRPSEL_BASE 0x48307000 -#define DSPVA_GRPSEL_BASE 0x11821000 - -#define L4_PERIPHERAL_SIDETONE_MCBSP2 0x49028000 -#define DSPVA_PERIPHERAL_SIDETONE_MCBSP2 0x11824000 -#define L4_PERIPHERAL_SIDETONE_MCBSP3 0x4902a000 -#define DSPVA_PERIPHERAL_SIDETONE_MCBSP3 0x11825000 - -/* define a static array with L4 mappings */ -static const struct map_l4_peripheral l4_peripheral_table[] = { - {L4_PERIPHERAL_MBOX, DSPVA_PERIPHERAL_MBOX}, - {L4_PERIPHERAL_SCM, DSPVA_PERIPHERAL_SCM}, - {L4_PERIPHERAL_MMU, DSPVA_PERIPHERAL_MMU}, - {L4_PERIPHERAL_GPTIMER5, DSPVA_PERIPHERAL_GPTIMER5}, - {L4_PERIPHERAL_GPTIMER6, DSPVA_PERIPHERAL_GPTIMER6}, - {L4_PERIPHERAL_GPTIMER7, DSPVA_PERIPHERAL_GPTIMER7}, - {L4_PERIPHERAL_GPTIMER8, DSPVA_PERIPHERAL_GPTIMER8}, - {L4_PERIPHERAL_GPIO1, DSPVA_PERIPHERAL_GPIO1}, - {L4_PERIPHERAL_GPIO2, DSPVA_PERIPHERAL_GPIO2}, - {L4_PERIPHERAL_GPIO3, DSPVA_PERIPHERAL_GPIO3}, - {L4_PERIPHERAL_GPIO4, DSPVA_PERIPHERAL_GPIO4}, - {L4_PERIPHERAL_GPIO5, DSPVA_PERIPHERAL_GPIO5}, - {L4_PERIPHERAL_IVA2WDT, DSPVA_PERIPHERAL_IVA2WDT}, - {L4_PERIPHERAL_DISPLAY, DSPVA_PERIPHERAL_DISPLAY}, - {L4_PERIPHERAL_SSI, DSPVA_PERIPHERAL_SSI}, - {L4_PERIPHERAL_GDD, DSPVA_PERIPHERAL_GDD}, - {L4_PERIPHERAL_SS1, DSPVA_PERIPHERAL_SS1}, - {L4_PERIPHERAL_SS2, DSPVA_PERIPHERAL_SS2}, - {L4_PERIPHERAL_UART1, DSPVA_PERIPHERAL_UART1}, - {L4_PERIPHERAL_UART2, DSPVA_PERIPHERAL_UART2}, - {L4_PERIPHERAL_UART3, DSPVA_PERIPHERAL_UART3}, - {L4_PERIPHERAL_MCBSP1, DSPVA_PERIPHERAL_MCBSP1}, - {L4_PERIPHERAL_MCBSP2, DSPVA_PERIPHERAL_MCBSP2}, - {L4_PERIPHERAL_MCBSP3, DSPVA_PERIPHERAL_MCBSP3}, - {L4_PERIPHERAL_MCBSP4, DSPVA_PERIPHERAL_MCBSP4}, - {L4_PERIPHERAL_MCBSP5, DSPVA_PERIPHERAL_MCBSP5}, - {L4_PERIPHERAL_CAMERA, DSPVA_PERIPHERAL_CAMERA}, - {L4_PERIPHERAL_SPI1, DSPVA_PERIPHERAL_SPI1}, - {L4_PERIPHERAL_SPI2, DSPVA_PERIPHERAL_SPI2}, - {L4_PERIPHERAL_PRM, DSPVA_PERIPHERAL_PRM}, - {L4_PERIPHERAL_CM, DSPVA_PERIPHERAL_CM}, - {L4_PERIPHERAL_PER, DSPVA_PERIPHERAL_PER}, - {PM_GRPSEL_BASE, DSPVA_GRPSEL_BASE}, - {L4_PERIPHERAL_SIDETONE_MCBSP2, DSPVA_PERIPHERAL_SIDETONE_MCBSP2}, - {L4_PERIPHERAL_SIDETONE_MCBSP3, DSPVA_PERIPHERAL_SIDETONE_MCBSP3}, - {L4_PERIPHERAL_NULL, DSPVA_PERIPHERAL_NULL} -}; - -/* - * 15 10 0 - * --------------------------------- - * |0|0|1|0|0|0|c|c|c|i|i|i|i|i|i|i| - * --------------------------------- - * | (class) | (module specific) | - * - * where c -> Externel Clock Command: Clk & Autoidle Disable/Enable - * i -> External Clock ID Timers 5,6,7,8, McBSP1,2 and WDT3 - */ - -/* MBX_PM_CLK_IDMASK: DSP External clock id mask. */ -#define MBX_PM_CLK_IDMASK 0x7F - -/* MBX_PM_CLK_CMDSHIFT: DSP External clock command shift. */ -#define MBX_PM_CLK_CMDSHIFT 7 - -/* MBX_PM_CLK_CMDMASK: DSP External clock command mask. */ -#define MBX_PM_CLK_CMDMASK 7 - -/* MBX_PM_MAX_RESOURCES: CORE 1 Clock resources. */ -#define MBX_CORE1_RESOURCES 7 - -/* MBX_PM_MAX_RESOURCES: CORE 2 Clock Resources. */ -#define MBX_CORE2_RESOURCES 1 - -/* MBX_PM_MAX_RESOURCES: TOTAL Clock Resources. */ -#define MBX_PM_MAX_RESOURCES 11 - -/* Power Management Commands */ -#define BPWR_DISABLE_CLOCK 0 -#define BPWR_ENABLE_CLOCK 1 - -/* OMAP242x specific resources */ -enum bpwr_ext_clock_id { - BPWR_GP_TIMER5 = 0x10, - BPWR_GP_TIMER6, - BPWR_GP_TIMER7, - BPWR_GP_TIMER8, - BPWR_WD_TIMER3, - BPWR_MCBSP1, - BPWR_MCBSP2, - BPWR_MCBSP3, - BPWR_MCBSP4, - BPWR_MCBSP5, - BPWR_SSI = 0x20 -}; - -static const u32 bpwr_clkid[] = { - (u32) BPWR_GP_TIMER5, - (u32) BPWR_GP_TIMER6, - (u32) BPWR_GP_TIMER7, - (u32) BPWR_GP_TIMER8, - (u32) BPWR_WD_TIMER3, - (u32) BPWR_MCBSP1, - (u32) BPWR_MCBSP2, - (u32) BPWR_MCBSP3, - (u32) BPWR_MCBSP4, - (u32) BPWR_MCBSP5, - (u32) BPWR_SSI -}; - -struct bpwr_clk_t { - u32 clk_id; - enum dsp_clk_id clk; -}; - -static const struct bpwr_clk_t bpwr_clks[] = { - {(u32) BPWR_GP_TIMER5, DSP_CLK_GPT5}, - {(u32) BPWR_GP_TIMER6, DSP_CLK_GPT6}, - {(u32) BPWR_GP_TIMER7, DSP_CLK_GPT7}, - {(u32) BPWR_GP_TIMER8, DSP_CLK_GPT8}, - {(u32) BPWR_WD_TIMER3, DSP_CLK_WDT3}, - {(u32) BPWR_MCBSP1, DSP_CLK_MCBSP1}, - {(u32) BPWR_MCBSP2, DSP_CLK_MCBSP2}, - {(u32) BPWR_MCBSP3, DSP_CLK_MCBSP3}, - {(u32) BPWR_MCBSP4, DSP_CLK_MCBSP4}, - {(u32) BPWR_MCBSP5, DSP_CLK_MCBSP5}, - {(u32) BPWR_SSI, DSP_CLK_SSI} -}; - -/* Interrupt Register Offsets */ -#define INTH_IT_REG_OFFSET 0x00 /* Interrupt register offset */ -#define INTH_MASK_IT_REG_OFFSET 0x04 /* Mask Interrupt reg offset */ - -#define DSP_MAILBOX1_INT 10 -/* - * Bit definition of Interrupt Level Registers - */ - -/* Mail Box defines */ -#define MB_ARM2DSP1_REG_OFFSET 0x00 - -#define MB_ARM2DSP1B_REG_OFFSET 0x04 - -#define MB_DSP2ARM1B_REG_OFFSET 0x0C - -#define MB_ARM2DSP1_FLAG_REG_OFFSET 0x18 - -#define MB_ARM2DSP_FLAG 0x0001 - -#define MBOX_ARM2DSP HW_MBOX_ID0 -#define MBOX_DSP2ARM HW_MBOX_ID1 -#define MBOX_ARM HW_MBOX_U0_ARM -#define MBOX_DSP HW_MBOX_U1_DSP1 - -#define ENABLE true -#define DISABLE false - -#define HIGH_LEVEL true -#define LOW_LEVEL false - -/* Macro's */ -#define CLEAR_BIT(reg, mask) (reg &= ~mask) -#define SET_BIT(reg, mask) (reg |= mask) - -#define SET_GROUP_BITS16(reg, position, width, value) \ - do {\ - reg &= ~((0xFFFF >> (16 - (width))) << (position)); \ - reg |= ((value & (0xFFFF >> (16 - (width)))) << (position)); \ - } while (0); - -#define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index))) - -/* This Bridge driver's device context: */ -struct bridge_dev_context { - struct dev_object *dev_obj; /* Handle to Bridge device object. */ - u32 dsp_base_addr; /* Arm's API to DSP virt base addr */ - /* - * DSP External memory prog address as seen virtually by the OS on - * the host side. - */ - u32 dsp_ext_base_addr; /* See the comment above */ - u32 api_reg_base; /* API mem map'd registers */ - void __iomem *dsp_mmu_base; /* DSP MMU Mapped registers */ - u32 api_clk_base; /* CLK Registers */ - u32 dsp_clk_m2_base; /* DSP Clock Module m2 */ - u32 public_rhea; /* Pub Rhea */ - u32 int_addr; /* MB INTR reg */ - u32 tc_endianism; /* TC Endianism register */ - u32 test_base; /* DSP MMU Mapped registers */ - u32 self_loop; /* Pointer to the selfloop */ - u32 dsp_start_add; /* API Boot vector */ - u32 internal_size; /* Internal memory size */ - - struct omap_mbox *mbox; /* Mail box handle */ - - struct cfg_hostres *resources; /* Host Resources */ - - /* - * Processor specific info is set when prog loaded and read from DCD. - * [See bridge_dev_ctrl()] PROC info contains DSP-MMU TLB entries. - */ - /* DMMU TLB entries */ - struct bridge_ioctl_extproc atlb_entry[BRDIOCTL_NUMOFMMUTLB]; - u32 brd_state; /* Last known board state. */ - - /* TC Settings */ - bool tc_word_swap_on; /* Traffic Controller Word Swap */ - struct pg_table_attrs *pt_attrs; - u32 dsp_per_clks; -}; - -/* - * If dsp_debug is true, do not branch to the DSP entry - * point and wait for DSP to boot. - */ -extern s32 dsp_debug; - -/* - * ======== sm_interrupt_dsp ======== - * Purpose: - * Set interrupt value & send an interrupt to the DSP processor(s). - * This is typically used when mailbox interrupt mechanisms allow data - * to be associated with interrupt such as for OMAP's CMD/DATA regs. - * Parameters: - * dev_context: Handle to Bridge driver defined device info. - * mb_val: Value associated with interrupt(e.g. mailbox value). - * Returns: - * 0: Interrupt sent; - * else: Unable to send interrupt. - * Requires: - * Ensures: - */ -int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); - -#endif /* _TIOMAP_ */ diff --git a/drivers/staging/tidspbridge/core/_tiomap_pwr.h b/drivers/staging/tidspbridge/core/_tiomap_pwr.h deleted file mode 100644 index 7bbd3802c15..00000000000 --- a/drivers/staging/tidspbridge/core/_tiomap_pwr.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * _tiomap_pwr.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Definitions and types for the DSP wake/sleep routines. - * - * 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 _TIOMAP_PWR_ -#define _TIOMAP_PWR_ - -#ifdef CONFIG_PM -extern s32 dsp_test_sleepstate; -#endif - -extern struct mailbox_context mboxsetting; - -/* - * ======== wake_dsp ========= - * Wakes up the DSP from DeepSleep - */ -extern int wake_dsp(struct bridge_dev_context *dev_context, - void *pargs); - -/* - * ======== sleep_dsp ========= - * Places the DSP in DeepSleep. - */ -extern int sleep_dsp(struct bridge_dev_context *dev_context, - u32 dw_cmd, void *pargs); -/* - * ========interrupt_dsp======== - * Sends an interrupt to DSP unconditionally. - */ -extern void interrupt_dsp(struct bridge_dev_context *dev_context, - u16 mb_val); - -/* - * ======== wake_dsp ========= - * Wakes up the DSP from DeepSleep - */ -extern int dsp_peripheral_clk_ctrl(struct bridge_dev_context - *dev_context, void *pargs); -/* - * ======== handle_hibernation_from_dsp ======== - * Handle Hibernation requested from DSP - */ -int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context); -/* - * ======== post_scale_dsp ======== - * Handle Post Scale notification to DSP - */ -int post_scale_dsp(struct bridge_dev_context *dev_context, - void *pargs); -/* - * ======== pre_scale_dsp ======== - * Handle Pre Scale notification to DSP - */ -int pre_scale_dsp(struct bridge_dev_context *dev_context, - void *pargs); -/* - * ======== handle_constraints_set ======== - * Handle constraints request from DSP - */ -int handle_constraints_set(struct bridge_dev_context *dev_context, - void *pargs); - -/* - * ======== dsp_clk_wakeup_event_ctrl ======== - * This function sets the group selction bits for while - * enabling/disabling. - */ -void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable); - -#endif /* _TIOMAP_PWR_ */ diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c deleted file mode 100644 index 16fa3462fbb..00000000000 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ /dev/null @@ -1,907 +0,0 @@ -/* - * chnl_sm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implements upper edge functions for Bridge driver channel 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. - */ - -/* - * The lower edge functions must be implemented by the Bridge driver - * writer, and are declared in chnl_sm.h. - * - * Care is taken in this code to prevent simultaneous access to channel - * queues from - * 1. Threads. - * 2. io_dpc(), scheduled from the io_isr() as an event. - * - * This is done primarily by: - * - Semaphores. - * - state flags in the channel object; and - * - ensuring the IO_Dispatch() routine, which is called from both - * CHNL_AddIOReq() and the DPC(if implemented), is not re-entered. - * - * Channel Invariant: - * There is an important invariant condition which must be maintained per - * channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of - * which may cause timeouts and/or failure of function sync_wait_on_event. - * This invariant condition is: - * - * list_empty(&pchnl->io_completions) ==> pchnl->sync_event is reset - * and - * !list_empty(&pchnl->io_completions) ==> pchnl->sync_event is set. - */ - -#include <linux/types.h> - -/* ----------------------------------- OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Bridge Driver */ -#include <dspbridge/dspdefs.h> -#include <dspbridge/dspchnl.h> -#include "_tiomap.h" - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> - -/* ----------------------------------- Others */ -#include <dspbridge/io_sm.h> - -/* ----------------------------------- Define for This */ -#define USERMODE_ADDR PAGE_OFFSET - -#define MAILBOX_IRQ INT_MAIL_MPU_IRQ - -/* ----------------------------------- Function Prototypes */ -static int create_chirp_list(struct list_head *list, u32 chirps); - -static void free_chirp_list(struct list_head *list); - -static int search_free_channel(struct chnl_mgr *chnl_mgr_obj, - u32 *chnl); - -/* - * ======== bridge_chnl_add_io_req ======== - * Enqueue an I/O request for data transfer on a channel to the DSP. - * The direction (mode) is specified in the channel object. Note the DSP - * address is specified for channels opened in direct I/O mode. - */ -int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf, - u32 byte_size, u32 buf_size, - u32 dw_dsp_addr, u32 dw_arg) -{ - int status = 0; - struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; - struct chnl_irp *chnl_packet_obj = NULL; - struct bridge_dev_context *dev_ctxt; - struct dev_object *dev_obj; - u8 dw_state; - bool is_eos; - struct chnl_mgr *chnl_mgr_obj; - u8 *host_sys_buf = NULL; - bool sched_dpc = false; - u16 mb_val = 0; - - is_eos = (byte_size == 0); - - /* Validate args */ - if (!host_buf || !pchnl) - return -EFAULT; - - if (is_eos && CHNL_IS_INPUT(pchnl->chnl_mode)) - return -EPERM; - - /* - * Check the channel state: only queue chirp if channel state - * allows it. - */ - dw_state = pchnl->state; - if (dw_state != CHNL_STATEREADY) { - if (dw_state & CHNL_STATECANCEL) - return -ECANCELED; - if ((dw_state & CHNL_STATEEOS) && - CHNL_IS_OUTPUT(pchnl->chnl_mode)) - return -EPIPE; - /* No other possible states left */ - } - - dev_obj = dev_get_first(); - dev_get_bridge_context(dev_obj, &dev_ctxt); - if (!dev_ctxt) - return -EFAULT; - - if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1 && host_buf) { - if (!(host_buf < (void *)USERMODE_ADDR)) { - host_sys_buf = host_buf; - goto func_cont; - } - /* if addr in user mode, then copy to kernel space */ - host_sys_buf = kmalloc(buf_size, GFP_KERNEL); - if (host_sys_buf == NULL) - return -ENOMEM; - - if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) { - status = copy_from_user(host_sys_buf, host_buf, - buf_size); - if (status) { - kfree(host_sys_buf); - host_sys_buf = NULL; - return -EFAULT; - } - } - } -func_cont: - /* Mailbox IRQ is disabled to avoid race condition with DMA/ZCPY - * channels. DPCCS is held to avoid race conditions with PCPY channels. - * If DPC is scheduled in process context (iosm_schedule) and any - * non-mailbox interrupt occurs, that DPC will run and break CS. Hence - * we disable ALL DPCs. We will try to disable ONLY IO DPC later. */ - chnl_mgr_obj = pchnl->chnl_mgr_obj; - spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); - omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); - if (pchnl->chnl_type == CHNL_PCPY) { - /* This is a processor-copy channel. */ - if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) { - /* Check buffer size on output channels for fit. */ - if (byte_size > io_buf_size( - pchnl->chnl_mgr_obj->iomgr)) { - status = -EINVAL; - goto out; - } - } - } - - /* Get a free chirp: */ - if (list_empty(&pchnl->free_packets_list)) { - status = -EIO; - goto out; - } - chnl_packet_obj = list_first_entry(&pchnl->free_packets_list, - struct chnl_irp, link); - list_del(&chnl_packet_obj->link); - - /* Enqueue the chirp on the chnl's IORequest queue: */ - chnl_packet_obj->host_user_buf = chnl_packet_obj->host_sys_buf = - host_buf; - if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1) - chnl_packet_obj->host_sys_buf = host_sys_buf; - - /* - * Note: for dma chans dw_dsp_addr contains dsp address - * of SM buffer. - */ - /* DSP address */ - chnl_packet_obj->dsp_tx_addr = dw_dsp_addr / chnl_mgr_obj->word_size; - chnl_packet_obj->byte_size = byte_size; - chnl_packet_obj->buf_size = buf_size; - /* Only valid for output channel */ - chnl_packet_obj->arg = dw_arg; - chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS : - CHNL_IOCSTATCOMPLETE); - list_add_tail(&chnl_packet_obj->link, &pchnl->io_requests); - pchnl->cio_reqs++; - /* - * If end of stream, update the channel state to prevent - * more IOR's. - */ - if (is_eos) - pchnl->state |= CHNL_STATEEOS; - - /* Request IO from the DSP */ - io_request_chnl(chnl_mgr_obj->iomgr, pchnl, - (CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT : - IO_OUTPUT), &mb_val); - sched_dpc = true; -out: - omap_mbox_enable_irq(dev_ctxt->mbox, IRQ_RX); - spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); - if (mb_val != 0) - sm_interrupt_dsp(dev_ctxt, mb_val); - - /* Schedule a DPC, to do the actual data transfer */ - if (sched_dpc) - iosm_schedule(chnl_mgr_obj->iomgr); - - return status; -} - -/* - * ======== bridge_chnl_cancel_io ======== - * Return all I/O requests to the client which have not yet been - * transferred. The channel's I/O completion object is - * signalled, and all the I/O requests are queued as IOC's, with the - * status field set to CHNL_IOCSTATCANCEL. - * This call is typically used in abort situations, and is a prelude to - * chnl_close(); - */ -int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) -{ - struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; - u32 chnl_id = -1; - s8 chnl_mode; - struct chnl_irp *chirp, *tmp; - struct chnl_mgr *chnl_mgr_obj = NULL; - - /* Check args: */ - if (!pchnl || !pchnl->chnl_mgr_obj) - return -EFAULT; - - chnl_id = pchnl->chnl_id; - chnl_mode = pchnl->chnl_mode; - chnl_mgr_obj = pchnl->chnl_mgr_obj; - - /* Mark this channel as cancelled, to prevent further IORequests or - * IORequests or dispatching. */ - spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); - - pchnl->state |= CHNL_STATECANCEL; - - if (list_empty(&pchnl->io_requests)) { - spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); - return 0; - } - - if (pchnl->chnl_type == CHNL_PCPY) { - /* Indicate we have no more buffers available for transfer: */ - if (CHNL_IS_INPUT(pchnl->chnl_mode)) { - io_cancel_chnl(chnl_mgr_obj->iomgr, chnl_id); - } else { - /* Record that we no longer have output buffers - * available: */ - chnl_mgr_obj->output_mask &= ~(1 << chnl_id); - } - } - /* Move all IOR's to IOC queue: */ - list_for_each_entry_safe(chirp, tmp, &pchnl->io_requests, link) { - list_del(&chirp->link); - chirp->byte_size = 0; - chirp->status |= CHNL_IOCSTATCANCEL; - list_add_tail(&chirp->link, &pchnl->io_completions); - pchnl->cio_cs++; - pchnl->cio_reqs--; - } - - spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); - - return 0; -} - -/* - * ======== bridge_chnl_close ======== - * Purpose: - * Ensures all pending I/O on this channel is cancelled, discards all - * queued I/O completion notifications, then frees the resources allocated - * for this channel, and makes the corresponding logical channel id - * available for subsequent use. - */ -int bridge_chnl_close(struct chnl_object *chnl_obj) -{ - int status; - struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; - - /* Check args: */ - if (!pchnl) - return -EFAULT; - /* Cancel IO: this ensures no further IO requests or notifications */ - status = bridge_chnl_cancel_io(chnl_obj); - if (status) - return status; - /* Invalidate channel object: Protects from CHNL_GetIOCompletion() */ - /* Free the slot in the channel manager: */ - pchnl->chnl_mgr_obj->channels[pchnl->chnl_id] = NULL; - spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); - pchnl->chnl_mgr_obj->open_channels -= 1; - spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); - if (pchnl->ntfy_obj) { - ntfy_delete(pchnl->ntfy_obj); - kfree(pchnl->ntfy_obj); - pchnl->ntfy_obj = NULL; - } - /* Reset channel event: (NOTE: user_event freed in user context) */ - if (pchnl->sync_event) { - sync_reset_event(pchnl->sync_event); - kfree(pchnl->sync_event); - pchnl->sync_event = NULL; - } - /* Free I/O request and I/O completion queues: */ - free_chirp_list(&pchnl->io_completions); - pchnl->cio_cs = 0; - - free_chirp_list(&pchnl->io_requests); - pchnl->cio_reqs = 0; - - free_chirp_list(&pchnl->free_packets_list); - - /* Release channel object. */ - kfree(pchnl); - - return status; -} - -/* - * ======== bridge_chnl_create ======== - * Create a channel manager object, responsible for opening new channels - * and closing old ones for a given board. - */ -int bridge_chnl_create(struct chnl_mgr **channel_mgr, - struct dev_object *hdev_obj, - const struct chnl_mgrattrs *mgr_attrts) -{ - int status = 0; - struct chnl_mgr *chnl_mgr_obj = NULL; - u8 max_channels; - - /* Allocate channel manager object */ - chnl_mgr_obj = kzalloc(sizeof(struct chnl_mgr), GFP_KERNEL); - if (chnl_mgr_obj) { - /* - * The max_channels attr must equal the # of supported chnls for - * each transport(# chnls for PCPY = DDMA = ZCPY): i.e. - * mgr_attrts->max_channels = CHNL_MAXCHANNELS = - * DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS. - */ - max_channels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY; - /* Create array of channels */ - chnl_mgr_obj->channels = kzalloc(sizeof(struct chnl_object *) - * max_channels, GFP_KERNEL); - if (chnl_mgr_obj->channels) { - /* Initialize chnl_mgr object */ - chnl_mgr_obj->type = CHNL_TYPESM; - chnl_mgr_obj->word_size = mgr_attrts->word_size; - /* Total # chnls supported */ - chnl_mgr_obj->max_channels = max_channels; - chnl_mgr_obj->open_channels = 0; - chnl_mgr_obj->output_mask = 0; - chnl_mgr_obj->last_output = 0; - chnl_mgr_obj->dev_obj = hdev_obj; - spin_lock_init(&chnl_mgr_obj->chnl_mgr_lock); - } else { - status = -ENOMEM; - } - } else { - status = -ENOMEM; - } - - if (status) { - bridge_chnl_destroy(chnl_mgr_obj); - *channel_mgr = NULL; - } else { - /* Return channel manager object to caller... */ - *channel_mgr = chnl_mgr_obj; - } - return status; -} - -/* - * ======== bridge_chnl_destroy ======== - * Purpose: - * Close all open channels, and destroy the channel manager. - */ -int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr) -{ - int status = 0; - struct chnl_mgr *chnl_mgr_obj = hchnl_mgr; - u32 chnl_id; - - if (hchnl_mgr) { - /* Close all open channels: */ - for (chnl_id = 0; chnl_id < chnl_mgr_obj->max_channels; - chnl_id++) { - status = - bridge_chnl_close(chnl_mgr_obj->channels - [chnl_id]); - if (status) - dev_dbg(bridge, "%s: Error status 0x%x\n", - __func__, status); - } - - /* Free channel manager object: */ - kfree(chnl_mgr_obj->channels); - - /* Set hchnl_mgr to NULL in device object. */ - dev_set_chnl_mgr(chnl_mgr_obj->dev_obj, NULL); - /* Free this Chnl Mgr object: */ - kfree(hchnl_mgr); - } else { - status = -EFAULT; - } - return status; -} - -/* - * ======== bridge_chnl_flush_io ======== - * purpose: - * Flushes all the outstanding data requests on a channel. - */ -int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout) -{ - int status = 0; - struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; - s8 chnl_mode = -1; - struct chnl_mgr *chnl_mgr_obj; - struct chnl_ioc chnl_ioc_obj; - /* Check args: */ - if (pchnl) { - if ((timeout == CHNL_IOCNOWAIT) - && CHNL_IS_OUTPUT(pchnl->chnl_mode)) { - status = -EINVAL; - } else { - chnl_mode = pchnl->chnl_mode; - chnl_mgr_obj = pchnl->chnl_mgr_obj; - } - } else { - status = -EFAULT; - } - if (!status) { - /* Note: Currently, if another thread continues to add IO - * requests to this channel, this function will continue to - * flush all such queued IO requests. */ - if (CHNL_IS_OUTPUT(chnl_mode) - && (pchnl->chnl_type == CHNL_PCPY)) { - /* Wait for IO completions, up to the specified - * timeout: */ - while (!list_empty(&pchnl->io_requests) && !status) { - status = bridge_chnl_get_ioc(chnl_obj, - timeout, &chnl_ioc_obj); - if (status) - continue; - - if (chnl_ioc_obj.status & CHNL_IOCSTATTIMEOUT) - status = -ETIMEDOUT; - - } - } else { - status = bridge_chnl_cancel_io(chnl_obj); - /* Now, leave the channel in the ready state: */ - pchnl->state &= ~CHNL_STATECANCEL; - } - } - return status; -} - -/* - * ======== bridge_chnl_get_info ======== - * Purpose: - * Retrieve information related to a channel. - */ -int bridge_chnl_get_info(struct chnl_object *chnl_obj, - struct chnl_info *channel_info) -{ - int status = 0; - struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; - if (channel_info != NULL) { - if (pchnl) { - /* Return the requested information: */ - channel_info->chnl_mgr = pchnl->chnl_mgr_obj; - channel_info->event_obj = pchnl->user_event; - channel_info->cnhl_id = pchnl->chnl_id; - channel_info->mode = pchnl->chnl_mode; - channel_info->bytes_tx = pchnl->bytes_moved; - channel_info->process = pchnl->process; - channel_info->sync_event = pchnl->sync_event; - channel_info->cio_cs = pchnl->cio_cs; - channel_info->cio_reqs = pchnl->cio_reqs; - channel_info->state = pchnl->state; - } else { - status = -EFAULT; - } - } else { - status = -EFAULT; - } - return status; -} - -/* - * ======== bridge_chnl_get_ioc ======== - * Optionally wait for I/O completion on a channel. Dequeue an I/O - * completion record, which contains information about the completed - * I/O request. - * Note: Ensures Channel Invariant (see notes above). - */ -int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, - struct chnl_ioc *chan_ioc) -{ - int status = 0; - struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; - struct chnl_irp *chnl_packet_obj; - int stat_sync; - bool dequeue_ioc = true; - struct chnl_ioc ioc = { NULL, 0, 0, 0, 0 }; - u8 *host_sys_buf = NULL; - struct bridge_dev_context *dev_ctxt; - struct dev_object *dev_obj; - - /* Check args: */ - if (!chan_ioc || !pchnl) { - status = -EFAULT; - } else if (timeout == CHNL_IOCNOWAIT) { - if (list_empty(&pchnl->io_completions)) - status = -EREMOTEIO; - - } - - dev_obj = dev_get_first(); - dev_get_bridge_context(dev_obj, &dev_ctxt); - if (!dev_ctxt) - status = -EFAULT; - - if (status) - goto func_end; - - ioc.status = CHNL_IOCSTATCOMPLETE; - if (timeout != - CHNL_IOCNOWAIT && list_empty(&pchnl->io_completions)) { - if (timeout == CHNL_IOCINFINITE) - timeout = SYNC_INFINITE; - - stat_sync = sync_wait_on_event(pchnl->sync_event, timeout); - if (stat_sync == -ETIME) { - /* No response from DSP */ - ioc.status |= CHNL_IOCSTATTIMEOUT; - dequeue_ioc = false; - } else if (stat_sync == -EPERM) { - /* This can occur when the user mode thread is - * aborted (^C), or when _VWIN32_WaitSingleObject() - * fails due to unknown causes. */ - /* Even though Wait failed, there may be something in - * the Q: */ - if (list_empty(&pchnl->io_completions)) { - ioc.status |= CHNL_IOCSTATCANCEL; - dequeue_ioc = false; - } - } - } - /* See comment in AddIOReq */ - spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); - omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); - if (dequeue_ioc) { - /* Dequeue IOC and set chan_ioc; */ - chnl_packet_obj = list_first_entry(&pchnl->io_completions, - struct chnl_irp, link); - list_del(&chnl_packet_obj->link); - /* Update chan_ioc from channel state and chirp: */ - pchnl->cio_cs--; - /* - * If this is a zero-copy channel, then set IOC's pbuf - * to the DSP's address. This DSP address will get - * translated to user's virtual addr later. - */ - host_sys_buf = chnl_packet_obj->host_sys_buf; - ioc.buf = chnl_packet_obj->host_user_buf; - ioc.byte_size = chnl_packet_obj->byte_size; - ioc.buf_size = chnl_packet_obj->buf_size; - ioc.arg = chnl_packet_obj->arg; - ioc.status |= chnl_packet_obj->status; - /* Place the used chirp on the free list: */ - list_add_tail(&chnl_packet_obj->link, - &pchnl->free_packets_list); - } else { - ioc.buf = NULL; - ioc.byte_size = 0; - ioc.arg = 0; - ioc.buf_size = 0; - } - /* Ensure invariant: If any IOC's are queued for this channel... */ - if (!list_empty(&pchnl->io_completions)) { - /* Since DSPStream_Reclaim() does not take a timeout - * parameter, we pass the stream's timeout value to - * bridge_chnl_get_ioc. We cannot determine whether or not - * we have waited in user mode. Since the stream's timeout - * value may be non-zero, we still have to set the event. - * Therefore, this optimization is taken out. - * - * if (timeout == CHNL_IOCNOWAIT) { - * ... ensure event is set.. - * sync_set_event(pchnl->sync_event); - * } */ - sync_set_event(pchnl->sync_event); - } else { - /* else, if list is empty, ensure event is reset. */ - sync_reset_event(pchnl->sync_event); - } - omap_mbox_enable_irq(dev_ctxt->mbox, IRQ_RX); - spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); - if (dequeue_ioc - && (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1)) { - if (!(ioc.buf < (void *)USERMODE_ADDR)) - goto func_cont; - - /* If the addr is in user mode, then copy it */ - if (!host_sys_buf || !ioc.buf) { - status = -EFAULT; - goto func_cont; - } - if (!CHNL_IS_INPUT(pchnl->chnl_mode)) - goto func_cont1; - - /*host_user_buf */ - status = copy_to_user(ioc.buf, host_sys_buf, ioc.byte_size); - if (status) { - if (current->flags & PF_EXITING) - status = 0; - } - if (status) - status = -EFAULT; -func_cont1: - kfree(host_sys_buf); - } -func_cont: - /* Update User's IOC block: */ - *chan_ioc = ioc; -func_end: - return status; -} - -/* - * ======== bridge_chnl_get_mgr_info ======== - * Retrieve information related to the channel manager. - */ -int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr, u32 ch_id, - struct chnl_mgrinfo *mgr_info) -{ - struct chnl_mgr *chnl_mgr_obj = (struct chnl_mgr *)hchnl_mgr; - - if (!mgr_info || !hchnl_mgr) - return -EFAULT; - - if (ch_id > CHNL_MAXCHANNELS) - return -ECHRNG; - - /* Return the requested information: */ - mgr_info->chnl_obj = chnl_mgr_obj->channels[ch_id]; - mgr_info->open_channels = chnl_mgr_obj->open_channels; - mgr_info->type = chnl_mgr_obj->type; - /* total # of chnls */ - mgr_info->max_channels = chnl_mgr_obj->max_channels; - - return 0; -} - -/* - * ======== bridge_chnl_idle ======== - * Idles a particular channel. - */ -int bridge_chnl_idle(struct chnl_object *chnl_obj, u32 timeout, - bool flush_data) -{ - s8 chnl_mode; - struct chnl_mgr *chnl_mgr_obj; - int status = 0; - - chnl_mode = chnl_obj->chnl_mode; - chnl_mgr_obj = chnl_obj->chnl_mgr_obj; - - if (CHNL_IS_OUTPUT(chnl_mode) && !flush_data) { - /* Wait for IO completions, up to the specified timeout: */ - status = bridge_chnl_flush_io(chnl_obj, timeout); - } else { - status = bridge_chnl_cancel_io(chnl_obj); - - /* Reset the byte count and put channel back in ready state. */ - chnl_obj->bytes_moved = 0; - chnl_obj->state &= ~CHNL_STATECANCEL; - } - - return status; -} - -/* - * ======== bridge_chnl_open ======== - * Open a new half-duplex channel to the DSP board. - */ -int bridge_chnl_open(struct chnl_object **chnl, - struct chnl_mgr *hchnl_mgr, s8 chnl_mode, - u32 ch_id, const struct chnl_attr *pattrs) -{ - int status = 0; - struct chnl_mgr *chnl_mgr_obj = hchnl_mgr; - struct chnl_object *pchnl = NULL; - struct sync_object *sync_event = NULL; - - *chnl = NULL; - - /* Validate Args: */ - if (!pattrs->uio_reqs) - return -EINVAL; - - if (!hchnl_mgr) - return -EFAULT; - - if (ch_id != CHNL_PICKFREE) { - if (ch_id >= chnl_mgr_obj->max_channels) - return -ECHRNG; - if (chnl_mgr_obj->channels[ch_id] != NULL) - return -EALREADY; - } else { - /* Check for free channel */ - status = search_free_channel(chnl_mgr_obj, &ch_id); - if (status) - return status; - } - - - /* Create channel object: */ - pchnl = kzalloc(sizeof(struct chnl_object), GFP_KERNEL); - if (!pchnl) - return -ENOMEM; - - /* Protect queues from io_dpc: */ - pchnl->state = CHNL_STATECANCEL; - - /* Allocate initial IOR and IOC queues: */ - status = create_chirp_list(&pchnl->free_packets_list, - pattrs->uio_reqs); - if (status) - goto out_err; - - INIT_LIST_HEAD(&pchnl->io_requests); - INIT_LIST_HEAD(&pchnl->io_completions); - - pchnl->chnl_packets = pattrs->uio_reqs; - pchnl->cio_cs = 0; - pchnl->cio_reqs = 0; - - sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL); - if (!sync_event) { - status = -ENOMEM; - goto out_err; - } - sync_init_event(sync_event); - - pchnl->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL); - if (!pchnl->ntfy_obj) { - status = -ENOMEM; - goto out_err; - } - ntfy_init(pchnl->ntfy_obj); - - /* Initialize CHNL object fields: */ - pchnl->chnl_mgr_obj = chnl_mgr_obj; - pchnl->chnl_id = ch_id; - pchnl->chnl_mode = chnl_mode; - pchnl->user_event = sync_event; - pchnl->sync_event = sync_event; - /* Get the process handle */ - pchnl->process = current->tgid; - pchnl->cb_arg = 0; - pchnl->bytes_moved = 0; - /* Default to proc-copy */ - pchnl->chnl_type = CHNL_PCPY; - - /* Insert channel object in channel manager: */ - chnl_mgr_obj->channels[pchnl->chnl_id] = pchnl; - spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); - chnl_mgr_obj->open_channels++; - spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); - /* Return result... */ - pchnl->state = CHNL_STATEREADY; - *chnl = pchnl; - - return status; - -out_err: - /* Free memory */ - free_chirp_list(&pchnl->io_completions); - free_chirp_list(&pchnl->io_requests); - free_chirp_list(&pchnl->free_packets_list); - - kfree(sync_event); - - if (pchnl->ntfy_obj) { - ntfy_delete(pchnl->ntfy_obj); - kfree(pchnl->ntfy_obj); - pchnl->ntfy_obj = NULL; - } - kfree(pchnl); - - return status; -} - -/* - * ======== bridge_chnl_register_notify ======== - * Registers for events on a particular channel. - */ -int bridge_chnl_register_notify(struct chnl_object *chnl_obj, - u32 event_mask, u32 notify_type, - struct dsp_notification *hnotification) -{ - int status = 0; - - - if (event_mask) - status = ntfy_register(chnl_obj->ntfy_obj, hnotification, - event_mask, notify_type); - else - status = ntfy_unregister(chnl_obj->ntfy_obj, hnotification); - - return status; -} - -/* - * ======== create_chirp_list ======== - * Purpose: - * Initialize a queue of channel I/O Request/Completion packets. - * Parameters: - * list: Pointer to a list_head - * chirps: Number of Chirps to allocate. - * Returns: - * 0 if successful, error code otherwise. - * Requires: - * Ensures: - */ -static int create_chirp_list(struct list_head *list, u32 chirps) -{ - struct chnl_irp *chirp; - u32 i; - - INIT_LIST_HEAD(list); - - /* Make N chirps and place on queue. */ - for (i = 0; i < chirps; i++) { - chirp = kzalloc(sizeof(struct chnl_irp), GFP_KERNEL); - if (!chirp) - break; - list_add_tail(&chirp->link, list); - } - - /* If we couldn't allocate all chirps, free those allocated: */ - if (i != chirps) { - free_chirp_list(list); - return -ENOMEM; - } - - return 0; -} - -/* - * ======== free_chirp_list ======== - * Purpose: - * Free the queue of Chirps. - */ -static void free_chirp_list(struct list_head *chirp_list) -{ - struct chnl_irp *chirp, *tmp; - - list_for_each_entry_safe(chirp, tmp, chirp_list, link) { - list_del(&chirp->link); - kfree(chirp); - } -} - -/* - * ======== search_free_channel ======== - * Search for a free channel slot in the array of channel pointers. - */ -static int search_free_channel(struct chnl_mgr *chnl_mgr_obj, - u32 *chnl) -{ - int status = -ENOSR; - u32 i; - - for (i = 0; i < chnl_mgr_obj->max_channels; i++) { - if (chnl_mgr_obj->channels[i] == NULL) { - status = 0; - *chnl = i; - break; - } - } - - return status; -} diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c deleted file mode 100644 index a1aca4416ca..00000000000 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * clk.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Clock and Timer services. - * - * 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. - */ - -#define L4_34XX_BASE 0x48000000 - -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> -#include <plat/dmtimer.h> -#include <linux/platform_data/asoc-ti-mcbsp.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> -#include <dspbridge/drv.h> -#include <dspbridge/dev.h> -#include "_tiomap.h" - -/* ----------------------------------- This */ -#include <dspbridge/clk.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ - -#define OMAP_SSI_OFFSET 0x58000 -#define OMAP_SSI_SIZE 0x1000 -#define OMAP_SSI_SYSCONFIG_OFFSET 0x10 - -#define SSI_AUTOIDLE (1 << 0) -#define SSI_SIDLE_SMARTIDLE (2 << 3) -#define SSI_MIDLE_NOIDLE (1 << 12) - -/* Clk types requested by the dsp */ -#define IVA2_CLK 0 -#define GPT_CLK 1 -#define WDT_CLK 2 -#define MCBSP_CLK 3 -#define SSI_CLK 4 - -/* Bridge GPT id (1 - 4), DM Timer id (5 - 8) */ -#define DMT_ID(id) ((id) + 4) -#define DM_TIMER_CLOCKS 4 - -/* Bridge MCBSP id (6 - 10), OMAP Mcbsp id (0 - 4) */ -#define MCBSP_ID(id) ((id) - 6) - -static struct omap_dm_timer *timer[4]; - -struct clk *iva2_clk; - -struct dsp_ssi { - struct clk *sst_fck; - struct clk *ssr_fck; - struct clk *ick; -}; - -static struct dsp_ssi ssi; - -static u32 dsp_clocks; - -static inline u32 is_dsp_clk_active(u32 clk, u8 id) -{ - return clk & (1 << id); -} - -static inline void set_dsp_clk_active(u32 *clk, u8 id) -{ - *clk |= (1 << id); -} - -static inline void set_dsp_clk_inactive(u32 *clk, u8 id) -{ - *clk &= ~(1 << id); -} - -static s8 get_clk_type(u8 id) -{ - s8 type; - - if (id == DSP_CLK_IVA2) - type = IVA2_CLK; - else if (id <= DSP_CLK_GPT8) - type = GPT_CLK; - else if (id == DSP_CLK_WDT3) - type = WDT_CLK; - else if (id <= DSP_CLK_MCBSP5) - type = MCBSP_CLK; - else if (id == DSP_CLK_SSI) - type = SSI_CLK; - else - type = -1; - - return type; -} - -/* - * ======== dsp_clk_exit ======== - * Purpose: - * Cleanup CLK module. - */ -void dsp_clk_exit(void) -{ - int i; - - dsp_clock_disable_all(dsp_clocks); - - for (i = 0; i < DM_TIMER_CLOCKS; i++) - omap_dm_timer_free(timer[i]); - - clk_unprepare(iva2_clk); - clk_put(iva2_clk); - clk_unprepare(ssi.sst_fck); - clk_put(ssi.sst_fck); - clk_unprepare(ssi.ssr_fck); - clk_put(ssi.ssr_fck); - clk_unprepare(ssi.ick); - clk_put(ssi.ick); -} - -/* - * ======== dsp_clk_init ======== - * Purpose: - * Initialize CLK module. - */ -void dsp_clk_init(void) -{ - static struct platform_device dspbridge_device; - int i, id; - - dspbridge_device.dev.bus = &platform_bus_type; - - for (i = 0, id = 5; i < DM_TIMER_CLOCKS; i++, id++) - timer[i] = omap_dm_timer_request_specific(id); - - iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck"); - if (IS_ERR(iva2_clk)) - dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk); - else - clk_prepare(iva2_clk); - - ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck"); - ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck"); - ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick"); - - if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) { - dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n", - ssi.sst_fck, ssi.ssr_fck, ssi.ick); - } else { - clk_prepare(ssi.sst_fck); - clk_prepare(ssi.ssr_fck); - clk_prepare(ssi.ick); - } -} - -/** - * dsp_gpt_wait_overflow - set gpt overflow and wait for fixed timeout - * @clk_id: GP Timer clock id. - * @load: Overflow value. - * - * Sets an overflow interrupt for the desired GPT waiting for a timeout - * of 5 msecs for the interrupt to occur. - */ -void dsp_gpt_wait_overflow(short int clk_id, unsigned int load) -{ - struct omap_dm_timer *gpt = timer[clk_id - 1]; - unsigned long timeout; - - if (!gpt) - return; - - /* Enable overflow interrupt */ - omap_dm_timer_set_int_enable(gpt, OMAP_TIMER_INT_OVERFLOW); - - /* - * Set counter value to overflow counter after - * one tick and start timer. - */ - omap_dm_timer_set_load_start(gpt, 0, load); - - /* Wait 80us for timer to overflow */ - udelay(80); - - timeout = msecs_to_jiffies(5); - /* Check interrupt status and wait for interrupt */ - while (!(omap_dm_timer_read_status(gpt) & OMAP_TIMER_INT_OVERFLOW)) { - if (time_is_after_jiffies(timeout)) { - pr_err("%s: GPTimer interrupt failed\n", __func__); - break; - } - } -} - -/* - * ======== dsp_clk_enable ======== - * Purpose: - * Enable Clock . - * - */ -int dsp_clk_enable(enum dsp_clk_id clk_id) -{ - int status = 0; - - if (is_dsp_clk_active(dsp_clocks, clk_id)) { - dev_err(bridge, "WARN: clock id %d already enabled\n", clk_id); - goto out; - } - - switch (get_clk_type(clk_id)) { - case IVA2_CLK: - clk_enable(iva2_clk); - break; - case GPT_CLK: - status = omap_dm_timer_start(timer[clk_id - 1]); - break; -#ifdef CONFIG_SND_OMAP_SOC_MCBSP - case MCBSP_CLK: - omap_mcbsp_request(MCBSP_ID(clk_id)); - omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PAD_SRC); - break; -#endif - case WDT_CLK: - dev_err(bridge, "ERROR: DSP requested to enable WDT3 clk\n"); - break; - case SSI_CLK: - clk_enable(ssi.sst_fck); - clk_enable(ssi.ssr_fck); - clk_enable(ssi.ick); - - /* - * The SSI module need to configured not to have the Forced - * idle for master interface. If it is set to forced idle, - * the SSI module is transitioning to standby thereby causing - * the client in the DSP hang waiting for the SSI module to - * be active after enabling the clocks - */ - ssi_clk_prepare(true); - break; - default: - dev_err(bridge, "Invalid clock id for enable\n"); - status = -EPERM; - } - - if (!status) - set_dsp_clk_active(&dsp_clocks, clk_id); - -out: - return status; -} - -/** - * dsp_clock_enable_all - Enable clocks used by the DSP - * @dev_context Driver's device context strucure - * - * This function enables all the peripheral clocks that were requested by DSP. - */ -u32 dsp_clock_enable_all(u32 dsp_per_clocks) -{ - u32 clk_id; - u32 status = -EPERM; - - for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) { - if (is_dsp_clk_active(dsp_per_clocks, clk_id)) - status = dsp_clk_enable(clk_id); - } - - return status; -} - -/* - * ======== dsp_clk_disable ======== - * Purpose: - * Disable the clock. - * - */ -int dsp_clk_disable(enum dsp_clk_id clk_id) -{ - int status = 0; - - if (!is_dsp_clk_active(dsp_clocks, clk_id)) { - dev_err(bridge, "ERR: clock id %d already disabled\n", clk_id); - goto out; - } - - switch (get_clk_type(clk_id)) { - case IVA2_CLK: - clk_disable(iva2_clk); - break; - case GPT_CLK: - status = omap_dm_timer_stop(timer[clk_id - 1]); - break; -#ifdef CONFIG_SND_OMAP_SOC_MCBSP - case MCBSP_CLK: - omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PRCM_SRC); - omap_mcbsp_free(MCBSP_ID(clk_id)); - break; -#endif - case WDT_CLK: - dev_err(bridge, "ERROR: DSP requested to disable WDT3 clk\n"); - break; - case SSI_CLK: - ssi_clk_prepare(false); - ssi_clk_prepare(false); - clk_disable(ssi.sst_fck); - clk_disable(ssi.ssr_fck); - clk_disable(ssi.ick); - break; - default: - dev_err(bridge, "Invalid clock id for disable\n"); - status = -EPERM; - } - - if (!status) - set_dsp_clk_inactive(&dsp_clocks, clk_id); - -out: - return status; -} - -/** - * dsp_clock_disable_all - Disable all active clocks - * @dev_context Driver's device context structure - * - * This function disables all the peripheral clocks that were enabled by DSP. - * It is meant to be called only when DSP is entering hibernation or when DSP - * is in error state. - */ -u32 dsp_clock_disable_all(u32 dsp_per_clocks) -{ - u32 clk_id; - u32 status = -EPERM; - - for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) { - if (is_dsp_clk_active(dsp_per_clocks, clk_id)) - status = dsp_clk_disable(clk_id); - } - - return status; -} - -u32 dsp_clk_get_iva2_rate(void) -{ - u32 clk_speed_khz; - - clk_speed_khz = clk_get_rate(iva2_clk); - clk_speed_khz /= 1000; - dev_dbg(bridge, "%s: clk speed Khz = %d\n", __func__, clk_speed_khz); - - return clk_speed_khz; -} - -void ssi_clk_prepare(bool FLAG) -{ - void __iomem *ssi_base; - unsigned int value; - - ssi_base = ioremap(L4_34XX_BASE + OMAP_SSI_OFFSET, OMAP_SSI_SIZE); - if (!ssi_base) { - pr_err("%s: error, SSI not configured\n", __func__); - return; - } - - if (FLAG) { - /* Set Autoidle, SIDLEMode to smart idle, and MIDLEmode to - * no idle - */ - value = SSI_AUTOIDLE | SSI_SIDLE_SMARTIDLE | SSI_MIDLE_NOIDLE; - } else { - /* Set Autoidle, SIDLEMode to forced idle, and MIDLEmode to - * forced idle - */ - value = SSI_AUTOIDLE; - } - - __raw_writel(value, ssi_base + OMAP_SSI_SYSCONFIG_OFFSET); - iounmap(ssi_base); -} - diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c deleted file mode 100644 index c2829aa7780..00000000000 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ /dev/null @@ -1,2245 +0,0 @@ -/* - * io_sm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * IO dispatcher for a shared memory channel 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. - */ - -/* - * Channel Invariant: - * There is an important invariant condition which must be maintained per - * channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of - * which may cause timeouts and/or failure of the sync_wait_on_event - * function. - */ -#include <linux/types.h> -#include <linux/list.h> - -/* Host OS */ -#include <dspbridge/host_os.h> -#include <linux/workqueue.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* Services Layer */ -#include <dspbridge/ntfy.h> -#include <dspbridge/sync.h> - -/* Hardware Abstraction Layer */ -#include <hw_defs.h> -#include <hw_mmu.h> - -/* Bridge Driver */ -#include <dspbridge/dspdeh.h> -#include <dspbridge/dspio.h> -#include <dspbridge/dspioctl.h> -#include <dspbridge/wdt.h> -#include <_tiomap.h> -#include <tiomap_io.h> -#include <_tiomap_pwr.h> - -/* Platform Manager */ -#include <dspbridge/cod.h> -#include <dspbridge/node.h> -#include <dspbridge/dev.h> - -/* Others */ -#include <dspbridge/rms_sh.h> -#include <dspbridge/mgr.h> -#include <dspbridge/drv.h> -#include "_cmm.h" -#include "module_list.h" - -/* This */ -#include <dspbridge/io_sm.h> -#include "_msg_sm.h" - -/* Defines, Data Structures, Typedefs */ -#define OUTPUTNOTREADY 0xffff -#define NOTENABLED 0xffff /* Channel(s) not enabled */ - -#define EXTEND "_EXT_END" - -#define SWAP_WORD(x) (x) -#define UL_PAGE_ALIGN_SIZE 0x10000 /* Page Align Size */ - -#define MAX_PM_REQS 32 - -#define MMU_FAULT_HEAD1 0xa5a5a5a5 -#define MMU_FAULT_HEAD2 0x96969696 -#define POLL_MAX 1000 -#define MAX_MMU_DBGBUFF 10240 - -/* IO Manager: only one created per board */ -struct io_mgr { - /* These four fields must be the first fields in a io_mgr_ struct */ - /* Bridge device context */ - struct bridge_dev_context *bridge_context; - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; - struct dev_object *dev_obj; /* Device this board represents */ - - /* These fields initialized in bridge_io_create() */ - struct chnl_mgr *chnl_mgr; - struct shm *shared_mem; /* Shared Memory control */ - u8 *input; /* Address of input channel */ - u8 *output; /* Address of output channel */ - struct msg_mgr *msg_mgr; /* Message manager */ - /* Msg control for from DSP messages */ - struct msg_ctrl *msg_input_ctrl; - /* Msg control for to DSP messages */ - struct msg_ctrl *msg_output_ctrl; - u8 *msg_input; /* Address of input messages */ - u8 *msg_output; /* Address of output messages */ - u32 sm_buf_size; /* Size of a shared memory I/O channel */ - bool shared_irq; /* Is this IRQ shared? */ - u32 word_size; /* Size in bytes of DSP word */ - u16 intr_val; /* Interrupt value */ - /* Private extnd proc info; mmu setup */ - struct mgr_processorextinfo ext_proc_info; - struct cmm_object *cmm_mgr; /* Shared Mem Mngr */ - struct work_struct io_workq; /* workqueue */ -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) - u32 trace_buffer_begin; /* Trace message start address */ - u32 trace_buffer_end; /* Trace message end address */ - u32 trace_buffer_current; /* Trace message current address */ - u32 gpp_read_pointer; /* GPP Read pointer to Trace buffer */ - u8 *msg; - u32 gpp_va; - u32 dsp_va; -#endif - /* IO Dpc */ - u32 dpc_req; /* Number of requested DPC's. */ - u32 dpc_sched; /* Number of executed DPC's. */ - struct tasklet_struct dpc_tasklet; - spinlock_t dpc_lock; - -}; - -struct shm_symbol_val { - u32 shm_base; - u32 shm_lim; - u32 msg_base; - u32 msg_lim; - u32 shm0_end; - u32 dyn_ext; - u32 ext_end; -}; - -/* Function Prototypes */ -static void io_dispatch_pm(struct io_mgr *pio_mgr); -static void notify_chnl_complete(struct chnl_object *pchnl, - struct chnl_irp *chnl_packet_obj); -static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, - u8 io_mode); -static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, - u8 io_mode); -static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr); -static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr); -static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj, - struct chnl_object *pchnl, u32 mask); - -/* Bus Addr (cached kernel) */ -static int register_shm_segs(struct io_mgr *hio_mgr, - struct cod_manager *cod_man, - u32 dw_gpp_base_pa); - -static inline void set_chnl_free(struct shm *sm, u32 chnl) -{ - sm->host_free_mask &= ~(1 << chnl); -} - -static inline void set_chnl_busy(struct shm *sm, u32 chnl) -{ - sm->host_free_mask |= 1 << chnl; -} - - -/* - * ======== bridge_io_create ======== - * Create an IO manager object. - */ -int bridge_io_create(struct io_mgr **io_man, - struct dev_object *hdev_obj, - const struct io_attrs *mgr_attrts) -{ - struct io_mgr *pio_mgr = NULL; - struct bridge_dev_context *hbridge_context = NULL; - struct cfg_devnode *dev_node_obj; - struct chnl_mgr *hchnl_mgr; - u8 dev_type; - - /* Check requirements */ - if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0) - return -EFAULT; - - *io_man = NULL; - - dev_get_chnl_mgr(hdev_obj, &hchnl_mgr); - if (!hchnl_mgr || hchnl_mgr->iomgr) - return -EFAULT; - - /* - * Message manager will be created when a file is loaded, since - * size of message buffer in shared memory is configurable in - * the base image. - */ - dev_get_bridge_context(hdev_obj, &hbridge_context); - if (!hbridge_context) - return -EFAULT; - - dev_get_dev_type(hdev_obj, &dev_type); - - /* Allocate IO manager object */ - pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL); - if (!pio_mgr) - return -ENOMEM; - - /* Initialize chnl_mgr object */ - pio_mgr->chnl_mgr = hchnl_mgr; - pio_mgr->word_size = mgr_attrts->word_size; - - if (dev_type == DSP_UNIT) { - /* Create an IO DPC */ - tasklet_init(&pio_mgr->dpc_tasklet, io_dpc, (u32) pio_mgr); - - /* Initialize DPC counters */ - pio_mgr->dpc_req = 0; - pio_mgr->dpc_sched = 0; - - spin_lock_init(&pio_mgr->dpc_lock); - - if (dev_get_dev_node(hdev_obj, &dev_node_obj)) { - bridge_io_destroy(pio_mgr); - return -EIO; - } - } - - pio_mgr->bridge_context = hbridge_context; - pio_mgr->shared_irq = mgr_attrts->irq_shared; - if (dsp_wdt_init()) { - bridge_io_destroy(pio_mgr); - return -EPERM; - } - - /* Return IO manager object to caller... */ - hchnl_mgr->iomgr = pio_mgr; - *io_man = pio_mgr; - - return 0; -} - -/* - * ======== bridge_io_destroy ======== - * Purpose: - * Disable interrupts, destroy the IO manager. - */ -int bridge_io_destroy(struct io_mgr *hio_mgr) -{ - int status = 0; - if (hio_mgr) { - /* Free IO DPC object */ - tasklet_kill(&hio_mgr->dpc_tasklet); - -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) - kfree(hio_mgr->msg); -#endif - dsp_wdt_exit(); - /* Free this IO manager object */ - kfree(hio_mgr); - } else { - status = -EFAULT; - } - - return status; -} - -struct shm_symbol_val *_get_shm_symbol_values(struct io_mgr *hio_mgr) -{ - struct shm_symbol_val *s; - struct cod_manager *cod_man; - int status; - - s = kzalloc(sizeof(*s), GFP_KERNEL); - if (!s) - return ERR_PTR(-ENOMEM); - - status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man); - if (status) - goto free_symbol; - - /* Get start and length of channel part of shared memory */ - status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_BASE_SYM, - &s->shm_base); - if (status) - goto free_symbol; - - status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_LIMIT_SYM, - &s->shm_lim); - if (status) - goto free_symbol; - - if (s->shm_lim <= s->shm_base) { - status = -EINVAL; - goto free_symbol; - } - - /* Get start and length of message part of shared memory */ - status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_BASE_SYM, - &s->msg_base); - if (status) - goto free_symbol; - - status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_LIMIT_SYM, - &s->msg_lim); - if (status) - goto free_symbol; - - if (s->msg_lim <= s->msg_base) { - status = -EINVAL; - goto free_symbol; - } - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE - status = cod_get_sym_value(cod_man, DSP_TRACESEC_END, &s->shm0_end); -#else - status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM, &s->shm0_end); -#endif - if (status) - goto free_symbol; - - status = cod_get_sym_value(cod_man, DYNEXTBASE, &s->dyn_ext); - if (status) - goto free_symbol; - - status = cod_get_sym_value(cod_man, EXTEND, &s->ext_end); - if (status) - goto free_symbol; - - return s; - -free_symbol: - kfree(s); - return ERR_PTR(status); -} - -/* - * ======== bridge_io_on_loaded ======== - * Purpose: - * Called when a new program is loaded to get shared memory buffer - * parameters from COFF file. ulSharedBufferBase and ulSharedBufferLimit - * are in DSP address units. - */ -int bridge_io_on_loaded(struct io_mgr *hio_mgr) -{ - struct bridge_dev_context *dc = hio_mgr->bridge_context; - struct cfg_hostres *cfg_res = dc->resources; - struct bridge_ioctl_extproc *eproc; - struct cod_manager *cod_man; - struct chnl_mgr *hchnl_mgr; - struct msg_mgr *hmsg_mgr; - struct shm_symbol_val *s; - int status; - u8 num_procs; - s32 ndx; - u32 i; - u32 mem_sz, msg_sz, pad_sz, shm_sz, shm_base_offs; - u32 seg0_sz, seg1_sz; - u32 pa, va, da; - u32 pa_curr, va_curr, da_curr; - u32 bytes; - u32 all_bits = 0; - u32 page_size[] = { - HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; - u32 map_attrs = DSP_MAPLITTLEENDIAN | DSP_MAPPHYSICALADDR | - DSP_MAPELEMSIZE32 | DSP_MAPDONOTLOCK; - - status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man); - if (status) - return status; - - hchnl_mgr = hio_mgr->chnl_mgr; - - /* The message manager is destroyed when the board is stopped */ - dev_get_msg_mgr(hio_mgr->dev_obj, &hio_mgr->msg_mgr); - hmsg_mgr = hio_mgr->msg_mgr; - if (!hchnl_mgr || !hmsg_mgr) - return -EFAULT; - - if (hio_mgr->shared_mem) - hio_mgr->shared_mem = NULL; - - s = _get_shm_symbol_values(hio_mgr); - if (IS_ERR(s)) - return PTR_ERR(s); - - /* Get total length in bytes */ - shm_sz = (s->shm_lim - s->shm_base + 1) * hio_mgr->word_size; - - /* Calculate size of a PROCCOPY shared memory region */ - dev_dbg(bridge, "%s: (proc)proccopy shmmem size: 0x%x bytes\n", - __func__, shm_sz - sizeof(struct shm)); - - /* Length (bytes) of messaging part of shared memory */ - msg_sz = (s->msg_lim - s->msg_base + 1) * hio_mgr->word_size; - - /* Total length (bytes) of shared memory: chnl + msg */ - mem_sz = shm_sz + msg_sz; - - /* Get memory reserved in host resources */ - (void)mgr_enum_processor_info(0, - (struct dsp_processorinfo *) - &hio_mgr->ext_proc_info, - sizeof(struct mgr_processorextinfo), - &num_procs); - - /* IO supports only one DSP for now */ - if (num_procs != 1) { - status = -EINVAL; - goto free_symbol; - } - - /* The first MMU TLB entry(TLB_0) in DCD is ShmBase */ - pa = cfg_res->mem_phys[1]; - va = cfg_res->mem_base[1]; - - /* This is the virtual uncached ioremapped address!!! */ - /* Why can't we directly take the DSPVA from the symbols? */ - da = hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt; - seg0_sz = (s->shm0_end - da) * hio_mgr->word_size; - seg1_sz = (s->ext_end - s->dyn_ext) * hio_mgr->word_size; - - /* 4K align */ - seg1_sz = (seg1_sz + 0xFFF) & (~0xFFFUL); - - /* 64K align */ - seg0_sz = (seg0_sz + 0xFFFF) & (~0xFFFFUL); - - pad_sz = UL_PAGE_ALIGN_SIZE - ((pa + seg1_sz) % UL_PAGE_ALIGN_SIZE); - if (pad_sz == UL_PAGE_ALIGN_SIZE) - pad_sz = 0x0; - - dev_dbg(bridge, "%s: pa %x, va %x, da %x\n", __func__, pa, va, da); - dev_dbg(bridge, - "shm0_end %x, dyn_ext %x, ext_end %x, seg0_sz %x seg1_sz %x\n", - s->shm0_end, s->dyn_ext, s->ext_end, seg0_sz, seg1_sz); - - if ((seg0_sz + seg1_sz + pad_sz) > cfg_res->mem_length[1]) { - pr_err("%s: shm Error, reserved 0x%x required 0x%x\n", - __func__, cfg_res->mem_length[1], - seg0_sz + seg1_sz + pad_sz); - status = -ENOMEM; - goto free_symbol; - } - - pa_curr = pa; - va_curr = s->dyn_ext * hio_mgr->word_size; - da_curr = va; - bytes = seg1_sz; - - /* - * Try to fit into TLB entries. If not possible, push them to page - * tables. It is quite possible that if sections are not on - * bigger page boundary, we may end up making several small pages. - * So, push them onto page tables, if that is the case. - */ - while (bytes) { - /* - * To find the max. page size with which both PA & VA are - * aligned. - */ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, - "seg all_bits %x, pa_curr %x, va_curr %x, bytes %x\n", - all_bits, pa_curr, va_curr, bytes); - - for (i = 0; i < 4; i++) { - if ((bytes >= page_size[i]) && - ((all_bits & (page_size[i] - 1)) == 0)) { - status = hio_mgr->intf_fxns->brd_mem_map(dc, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - if (status) - goto free_symbol; - - pa_curr += page_size[i]; - va_curr += page_size[i]; - da_curr += page_size[i]; - bytes -= page_size[i]; - /* - * Don't try smaller sizes. Hopefully we have - * reached an address aligned to a bigger page - * size. - */ - break; - } - } - } - - pa_curr += pad_sz; - va_curr += pad_sz; - da_curr += pad_sz; - bytes = seg0_sz; - va_curr = da * hio_mgr->word_size; - - eproc = kzalloc(sizeof(*eproc) * BRDIOCTL_NUMOFMMUTLB, GFP_KERNEL); - if (!eproc) { - status = -ENOMEM; - goto free_symbol; - } - - ndx = 0; - /* Configure the TLB entries for the next cacheable segment */ - while (bytes) { - /* - * To find the max. page size with which both PA & VA are - * aligned. - */ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, - "seg1 all_bits %x, pa_curr %x, va_curr %x, bytes %x\n", - all_bits, pa_curr, va_curr, bytes); - - for (i = 0; i < 4; i++) { - if (!(bytes >= page_size[i]) || - !((all_bits & (page_size[i] - 1)) == 0)) - continue; - - if (ndx >= MAX_LOCK_TLB_ENTRIES) { - status = hio_mgr->intf_fxns->brd_mem_map(dc, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - dev_dbg(bridge, - "PTE pa %x va %x dsp_va %x sz %x\n", - eproc[ndx].gpp_pa, - eproc[ndx].gpp_va, - eproc[ndx].dsp_va * - hio_mgr->word_size, page_size[i]); - if (status) - goto free_eproc; - } - - /* This is the physical address written to DSP MMU */ - eproc[ndx].gpp_pa = pa_curr; - - /* - * This is the virtual uncached ioremapped - * address!!! - */ - eproc[ndx].gpp_va = da_curr; - eproc[ndx].dsp_va = va_curr / hio_mgr->word_size; - eproc[ndx].size = page_size[i]; - eproc[ndx].endianism = HW_LITTLE_ENDIAN; - eproc[ndx].elem_size = HW_ELEM_SIZE16BIT; - eproc[ndx].mixed_mode = HW_MMU_CPUES; - dev_dbg(bridge, "%s: tlb pa %x va %x dsp_va %x sz %x\n", - __func__, eproc[ndx].gpp_pa, - eproc[ndx].gpp_va, - eproc[ndx].dsp_va * hio_mgr->word_size, - page_size[i]); - ndx++; - - pa_curr += page_size[i]; - va_curr += page_size[i]; - da_curr += page_size[i]; - bytes -= page_size[i]; - /* - * Don't try smaller sizes. Hopefully we have reached - * an address aligned to a bigger page size. - */ - break; - } - } - - /* - * Copy remaining entries from CDB. All entries are 1 MB and - * should not conflict with shm entries on MPU or DSP side. - */ - for (i = 3; i < 7 && ndx < BRDIOCTL_NUMOFMMUTLB; i++) { - struct mgr_processorextinfo *ep = &hio_mgr->ext_proc_info; - u32 word_sz = hio_mgr->word_size; - - if (ep->ty_tlb[i].gpp_phys == 0) - continue; - - if ((ep->ty_tlb[i].gpp_phys > pa - 0x100000 && - ep->ty_tlb[i].gpp_phys <= pa + seg0_sz) || - (ep->ty_tlb[i].dsp_virt > da - 0x100000 / word_sz && - ep->ty_tlb[i].dsp_virt <= da + seg0_sz / word_sz)) { - dev_dbg(bridge, - "err cdb%d pa %x da %x shm pa %x da %x sz %x\n", - i, ep->ty_tlb[i].gpp_phys, - ep->ty_tlb[i].dsp_virt, pa, da, seg0_sz); - status = -EPERM; - goto free_eproc; - } - - if (ndx >= MAX_LOCK_TLB_ENTRIES) { - status = hio_mgr->intf_fxns->brd_mem_map(dc, - ep->ty_tlb[i].gpp_phys, - ep->ty_tlb[i].dsp_virt, - 0x100000, map_attrs, NULL); - if (status) - goto free_eproc; - } - - eproc[ndx].dsp_va = ep->ty_tlb[i].dsp_virt; - eproc[ndx].gpp_pa = ep->ty_tlb[i].gpp_phys; - eproc[ndx].gpp_va = 0; - - /* 1 MB */ - eproc[ndx].size = 0x100000; - dev_dbg(bridge, "shm MMU entry pa %x da 0x%x\n", - eproc[ndx].gpp_pa, eproc[ndx].dsp_va); - ndx++; - } - - /* Map the L4 peripherals */ - i = 0; - while (l4_peripheral_table[i].phys_addr) { - status = hio_mgr->intf_fxns->brd_mem_map(dc, - l4_peripheral_table[i].phys_addr, - l4_peripheral_table[i].dsp_virt_addr, - HW_PAGE_SIZE4KB, map_attrs, NULL); - if (status) - goto free_eproc; - i++; - } - - for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) { - eproc[i].dsp_va = 0; - eproc[i].gpp_pa = 0; - eproc[i].gpp_va = 0; - eproc[i].size = 0; - } - - /* - * Set the shm physical address entry (grayed out in CDB file) - * to the virtual uncached ioremapped address of shm reserved - * on MPU. - */ - hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys = - (va + seg1_sz + pad_sz); - - /* - * Need shm Phys addr. IO supports only one DSP for now: - * num_procs = 1. - */ - if (!hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys) - return -EFAULT; - - if (eproc[0].dsp_va > s->shm_base) - return -EPERM; - - /* shm_base may not be at ul_dsp_va address */ - shm_base_offs = (s->shm_base - eproc[0].dsp_va) * - hio_mgr->word_size; - /* - * bridge_dev_ctrl() will set dev context dsp-mmu info. In - * bridge_brd_start() the MMU will be re-programed with MMU - * DSPVa-GPPPa pair info while DSP is in a known - * (reset) state. - */ - status = hio_mgr->intf_fxns->dev_cntrl(hio_mgr->bridge_context, - BRDIOCTL_SETMMUCONFIG, eproc); - if (status) - goto free_eproc; - - s->shm_base = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys; - s->shm_base += shm_base_offs; - s->shm_base = (u32) MEM_LINEAR_ADDRESS((void *)s->shm_base, - mem_sz); - if (!s->shm_base) { - status = -EFAULT; - goto free_eproc; - } - - /* Register SM */ - status = register_shm_segs(hio_mgr, cod_man, eproc[0].gpp_pa); - - hio_mgr->shared_mem = (struct shm *)s->shm_base; - hio_mgr->input = (u8 *) hio_mgr->shared_mem + sizeof(struct shm); - hio_mgr->output = hio_mgr->input + (shm_sz - - sizeof(struct shm)) / 2; - hio_mgr->sm_buf_size = hio_mgr->output - hio_mgr->input; - - /* Set up Shared memory addresses for messaging */ - hio_mgr->msg_input_ctrl = - (struct msg_ctrl *)((u8 *) hio_mgr->shared_mem + shm_sz); - hio_mgr->msg_input = - (u8 *) hio_mgr->msg_input_ctrl + sizeof(struct msg_ctrl); - hio_mgr->msg_output_ctrl = - (struct msg_ctrl *)((u8 *) hio_mgr->msg_input_ctrl + - msg_sz / 2); - hio_mgr->msg_output = - (u8 *) hio_mgr->msg_output_ctrl + sizeof(struct msg_ctrl); - hmsg_mgr->max_msgs = - ((u8 *) hio_mgr->msg_output_ctrl - hio_mgr->msg_input) / - sizeof(struct msg_dspmsg); - - dev_dbg(bridge, "IO MGR shm details: shared_mem %p, input %p, " - "output %p, msg_input_ctrl %p, msg_input %p, " - "msg_output_ctrl %p, msg_output %p\n", - (u8 *) hio_mgr->shared_mem, hio_mgr->input, - hio_mgr->output, (u8 *) hio_mgr->msg_input_ctrl, - hio_mgr->msg_input, (u8 *) hio_mgr->msg_output_ctrl, - hio_mgr->msg_output); - dev_dbg(bridge, "(proc) Mas msgs in shared memory: 0x%x\n", - hmsg_mgr->max_msgs); - memset((void *)hio_mgr->shared_mem, 0, sizeof(struct shm)); - -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) - /* Get the start address of trace buffer */ - status = cod_get_sym_value(cod_man, SYS_PUTCBEG, - &hio_mgr->trace_buffer_begin); - if (status) - goto free_eproc; - - hio_mgr->gpp_read_pointer = - hio_mgr->trace_buffer_begin = - (va + seg1_sz + pad_sz) + - (hio_mgr->trace_buffer_begin - da); - - /* Get the end address of trace buffer */ - status = cod_get_sym_value(cod_man, SYS_PUTCEND, - &hio_mgr->trace_buffer_end); - if (status) - goto free_eproc; - - hio_mgr->trace_buffer_end = - (va + seg1_sz + pad_sz) + - (hio_mgr->trace_buffer_end - da); - - /* Get the current address of DSP write pointer */ - status = cod_get_sym_value(cod_man, BRIDGE_SYS_PUTC_CURRENT, - &hio_mgr->trace_buffer_current); - if (status) - goto free_eproc; - - hio_mgr->trace_buffer_current = - (va + seg1_sz + pad_sz) + - (hio_mgr->trace_buffer_current - da); - - /* Calculate the size of trace buffer */ - kfree(hio_mgr->msg); - hio_mgr->msg = kmalloc(((hio_mgr->trace_buffer_end - - hio_mgr->trace_buffer_begin) * - hio_mgr->word_size) + 2, GFP_KERNEL); - if (!hio_mgr->msg) { - status = -ENOMEM; - goto free_eproc; - } - - hio_mgr->dsp_va = da; - hio_mgr->gpp_va = (va + seg1_sz + pad_sz); -#endif - -free_eproc: - kfree(eproc); -free_symbol: - kfree(s); - - return status; -} - -/* - * ======== io_buf_size ======== - * Size of shared memory I/O channel. - */ -u32 io_buf_size(struct io_mgr *hio_mgr) -{ - if (hio_mgr) - return hio_mgr->sm_buf_size; - else - return 0; -} - -/* - * ======== io_cancel_chnl ======== - * Cancel IO on a given PCPY channel. - */ -void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl) -{ - struct io_mgr *pio_mgr = (struct io_mgr *)hio_mgr; - struct shm *sm; - - if (!hio_mgr) - goto func_end; - sm = hio_mgr->shared_mem; - - /* Inform DSP that we have no more buffers on this channel */ - set_chnl_free(sm, chnl); - - sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); -func_end: - return; -} - - -/* - * ======== io_dispatch_pm ======== - * Performs I/O dispatch on PM related messages from DSP - */ -static void io_dispatch_pm(struct io_mgr *pio_mgr) -{ - int status; - u32 parg[2]; - - /* Perform Power message processing here */ - parg[0] = pio_mgr->intr_val; - - /* Send the command to the Bridge clk/pwr manager to handle */ - if (parg[0] == MBX_PM_HIBERNATE_EN) { - dev_dbg(bridge, "PM: Hibernate command\n"); - status = pio_mgr->intf_fxns-> - dev_cntrl(pio_mgr->bridge_context, - BRDIOCTL_PWR_HIBERNATE, parg); - if (status) - pr_err("%s: hibernate cmd failed 0x%x\n", - __func__, status); - } else if (parg[0] == MBX_PM_OPP_REQ) { - parg[1] = pio_mgr->shared_mem->opp_request.rqst_opp_pt; - dev_dbg(bridge, "PM: Requested OPP = 0x%x\n", parg[1]); - status = pio_mgr->intf_fxns-> - dev_cntrl(pio_mgr->bridge_context, - BRDIOCTL_CONSTRAINT_REQUEST, parg); - if (status) - dev_dbg(bridge, "PM: Failed to set constraint " - "= 0x%x\n", parg[1]); - } else { - dev_dbg(bridge, "PM: clk control value of msg = 0x%x\n", - parg[0]); - status = pio_mgr->intf_fxns-> - dev_cntrl(pio_mgr->bridge_context, - BRDIOCTL_CLK_CTRL, parg); - if (status) - dev_dbg(bridge, "PM: Failed to ctrl the DSP clk" - "= 0x%x\n", *parg); - } -} - -/* - * ======== io_dpc ======== - * Deferred procedure call for shared memory channel driver ISR. Carries - * out the dispatch of I/O as a non-preemptible event. It can only be - * pre-empted by an ISR. - */ -void io_dpc(unsigned long ref_data) -{ - struct io_mgr *pio_mgr = (struct io_mgr *)ref_data; - struct chnl_mgr *chnl_mgr_obj; - struct msg_mgr *msg_mgr_obj; - struct deh_mgr *hdeh_mgr; - u32 requested; - u32 serviced; - - if (!pio_mgr) - goto func_end; - chnl_mgr_obj = pio_mgr->chnl_mgr; - dev_get_msg_mgr(pio_mgr->dev_obj, &msg_mgr_obj); - dev_get_deh_mgr(pio_mgr->dev_obj, &hdeh_mgr); - if (!chnl_mgr_obj) - goto func_end; - - requested = pio_mgr->dpc_req; - serviced = pio_mgr->dpc_sched; - - if (serviced == requested) - goto func_end; - - /* Process pending DPC's */ - do { - /* Check value of interrupt reg to ensure it's a valid error */ - if ((pio_mgr->intr_val > DEH_BASE) && - (pio_mgr->intr_val < DEH_LIMIT)) { - /* Notify DSP/BIOS exception */ - if (hdeh_mgr) { -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE - print_dsp_debug_trace(pio_mgr); -#endif - bridge_deh_notify(hdeh_mgr, DSP_SYSERROR, - pio_mgr->intr_val); - } - } - /* Proc-copy channel dispatch */ - input_chnl(pio_mgr, NULL, IO_SERVICE); - output_chnl(pio_mgr, NULL, IO_SERVICE); - -#ifdef CHNL_MESSAGES - if (msg_mgr_obj) { - /* Perform I/O dispatch on message queues */ - input_msg(pio_mgr, msg_mgr_obj); - output_msg(pio_mgr, msg_mgr_obj); - } - -#endif -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE - if (pio_mgr->intr_val & MBX_DBG_SYSPRINTF) { - /* Notify DSP Trace message */ - print_dsp_debug_trace(pio_mgr); - } -#endif - serviced++; - } while (serviced != requested); - pio_mgr->dpc_sched = requested; -func_end: - return; -} - -/* - * ======== io_mbox_msg ======== - * Main interrupt handler for the shared memory IO manager. - * Calls the Bridge's CHNL_ISR to determine if this interrupt is ours, then - * schedules a DPC to dispatch I/O. - */ -int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg) -{ - struct io_mgr *pio_mgr; - struct dev_object *dev_obj; - unsigned long flags; - - dev_obj = dev_get_first(); - dev_get_io_mgr(dev_obj, &pio_mgr); - - if (!pio_mgr) - return NOTIFY_BAD; - - pio_mgr->intr_val = (u16)((u32)msg); - if (pio_mgr->intr_val & MBX_PM_CLASS) - io_dispatch_pm(pio_mgr); - - if (pio_mgr->intr_val == MBX_DEH_RESET) { - pio_mgr->intr_val = 0; - } else { - spin_lock_irqsave(&pio_mgr->dpc_lock, flags); - pio_mgr->dpc_req++; - spin_unlock_irqrestore(&pio_mgr->dpc_lock, flags); - tasklet_schedule(&pio_mgr->dpc_tasklet); - } - return NOTIFY_OK; -} - -/* - * ======== io_request_chnl ======== - * Purpose: - * Request channel I/O from the DSP. Sets flags in shared memory, then - * interrupts the DSP. - */ -void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl, - u8 io_mode, u16 *mbx_val) -{ - struct chnl_mgr *chnl_mgr_obj; - struct shm *sm; - - if (!pchnl || !mbx_val) - goto func_end; - chnl_mgr_obj = io_manager->chnl_mgr; - sm = io_manager->shared_mem; - if (io_mode == IO_INPUT) { - /* Indicate to the DSP we have a buffer available for input */ - set_chnl_busy(sm, pchnl->chnl_id); - *mbx_val = MBX_PCPY_CLASS; - } else if (io_mode == IO_OUTPUT) { - /* - * Record the fact that we have a buffer available for - * output. - */ - chnl_mgr_obj->output_mask |= (1 << pchnl->chnl_id); - } else { - } -func_end: - return; -} - -/* - * ======== iosm_schedule ======== - * Schedule DPC for IO. - */ -void iosm_schedule(struct io_mgr *io_manager) -{ - unsigned long flags; - - if (!io_manager) - return; - - /* Increment count of DPC's pending. */ - spin_lock_irqsave(&io_manager->dpc_lock, flags); - io_manager->dpc_req++; - spin_unlock_irqrestore(&io_manager->dpc_lock, flags); - - /* Schedule DPC */ - tasklet_schedule(&io_manager->dpc_tasklet); -} - -/* - * ======== find_ready_output ======== - * Search for a host output channel which is ready to send. If this is - * called as a result of servicing the DPC, then implement a round - * robin search; otherwise, this was called by a client thread (via - * IO_Dispatch()), so just start searching from the current channel id. - */ -static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj, - struct chnl_object *pchnl, u32 mask) -{ - u32 ret = OUTPUTNOTREADY; - u32 id, start_id; - u32 shift; - - id = (pchnl != - NULL ? pchnl->chnl_id : (chnl_mgr_obj->last_output + 1)); - id = ((id == CHNL_MAXCHANNELS) ? 0 : id); - if (id >= CHNL_MAXCHANNELS) - goto func_end; - if (mask) { - shift = (1 << id); - start_id = id; - do { - if (mask & shift) { - ret = id; - if (pchnl == NULL) - chnl_mgr_obj->last_output = id; - break; - } - id = id + 1; - id = ((id == CHNL_MAXCHANNELS) ? 0 : id); - shift = (1 << id); - } while (id != start_id); - } -func_end: - return ret; -} - -/* - * ======== input_chnl ======== - * Dispatch a buffer on an input channel. - */ -static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, - u8 io_mode) -{ - struct chnl_mgr *chnl_mgr_obj; - struct shm *sm; - u32 chnl_id; - u32 bytes; - struct chnl_irp *chnl_packet_obj = NULL; - u32 dw_arg; - bool clear_chnl = false; - bool notify_client = false; - - sm = pio_mgr->shared_mem; - chnl_mgr_obj = pio_mgr->chnl_mgr; - - /* Attempt to perform input */ - if (!sm->input_full) - goto func_end; - - bytes = sm->input_size * chnl_mgr_obj->word_size; - chnl_id = sm->input_id; - dw_arg = sm->arg; - if (chnl_id >= CHNL_MAXCHANNELS) { - /* Shouldn't be here: would indicate corrupted shm. */ - goto func_end; - } - pchnl = chnl_mgr_obj->channels[chnl_id]; - if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) { - if ((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY) { - /* Get the I/O request, and attempt a transfer */ - if (!list_empty(&pchnl->io_requests)) { - if (!pchnl->cio_reqs) - goto func_end; - - chnl_packet_obj = list_first_entry( - &pchnl->io_requests, - struct chnl_irp, link); - list_del(&chnl_packet_obj->link); - pchnl->cio_reqs--; - - /* - * Ensure we don't overflow the client's - * buffer. - */ - bytes = min(bytes, chnl_packet_obj->byte_size); - memcpy(chnl_packet_obj->host_sys_buf, - pio_mgr->input, bytes); - pchnl->bytes_moved += bytes; - chnl_packet_obj->byte_size = bytes; - chnl_packet_obj->arg = dw_arg; - chnl_packet_obj->status = CHNL_IOCSTATCOMPLETE; - - if (bytes == 0) { - /* - * This assertion fails if the DSP - * sends EOS more than once on this - * channel. - */ - if (pchnl->state & CHNL_STATEEOS) - goto func_end; - /* - * Zero bytes indicates EOS. Update - * IOC status for this chirp, and also - * the channel state. - */ - chnl_packet_obj->status |= - CHNL_IOCSTATEOS; - pchnl->state |= CHNL_STATEEOS; - /* - * Notify that end of stream has - * occurred. - */ - ntfy_notify(pchnl->ntfy_obj, - DSP_STREAMDONE); - } - /* Tell DSP if no more I/O buffers available */ - if (list_empty(&pchnl->io_requests)) - set_chnl_free(sm, pchnl->chnl_id); - clear_chnl = true; - notify_client = true; - } else { - /* - * Input full for this channel, but we have no - * buffers available. The channel must be - * "idling". Clear out the physical input - * channel. - */ - clear_chnl = true; - } - } else { - /* Input channel cancelled: clear input channel */ - clear_chnl = true; - } - } else { - /* DPC fired after host closed channel: clear input channel */ - clear_chnl = true; - } - if (clear_chnl) { - /* Indicate to the DSP we have read the input */ - sm->input_full = 0; - sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); - } - if (notify_client) { - /* Notify client with IO completion record */ - notify_chnl_complete(pchnl, chnl_packet_obj); - } -func_end: - return; -} - -/* - * ======== input_msg ======== - * Copies messages from shared memory to the message queues. - */ -static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) -{ - u32 num_msgs; - u32 i; - u8 *msg_input; - struct msg_queue *msg_queue_obj; - struct msg_frame *pmsg; - struct msg_dspmsg msg; - struct msg_ctrl *msg_ctr_obj; - u32 input_empty; - u32 addr; - - msg_ctr_obj = pio_mgr->msg_input_ctrl; - /* Get the number of input messages to be read */ - input_empty = msg_ctr_obj->buf_empty; - num_msgs = msg_ctr_obj->size; - if (input_empty) - return; - - msg_input = pio_mgr->msg_input; - for (i = 0; i < num_msgs; i++) { - /* Read the next message */ - addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.cmd); - msg.msg.cmd = - read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); - addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg1); - msg.msg.arg1 = - read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); - addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg2); - msg.msg.arg2 = - read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); - addr = (u32) &(((struct msg_dspmsg *)msg_input)->msgq_id); - msg.msgq_id = - read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); - msg_input += sizeof(struct msg_dspmsg); - - /* Determine which queue to put the message in */ - dev_dbg(bridge, "input msg: cmd=0x%x arg1=0x%x " - "arg2=0x%x msgq_id=0x%x\n", msg.msg.cmd, - msg.msg.arg1, msg.msg.arg2, msg.msgq_id); - /* - * Interrupt may occur before shared memory and message - * input locations have been set up. If all nodes were - * cleaned up, hmsg_mgr->max_msgs should be 0. - */ - list_for_each_entry(msg_queue_obj, &hmsg_mgr->queue_list, - list_elem) { - if (msg.msgq_id != msg_queue_obj->msgq_id) - continue; - /* Found it */ - if (msg.msg.cmd == RMS_EXITACK) { - /* - * Call the node exit notification. - * The exit message does not get - * queued. - */ - (*hmsg_mgr->on_exit)(msg_queue_obj->arg, - msg.msg.arg1); - break; - } - /* - * Not an exit acknowledgement, queue - * the message. - */ - if (list_empty(&msg_queue_obj->msg_free_list)) { - /* - * No free frame to copy the - * message into. - */ - pr_err("%s: no free msg frames," - " discarding msg\n", - __func__); - break; - } - - pmsg = list_first_entry(&msg_queue_obj->msg_free_list, - struct msg_frame, list_elem); - list_del(&pmsg->list_elem); - pmsg->msg_data = msg; - list_add_tail(&pmsg->list_elem, - &msg_queue_obj->msg_used_list); - ntfy_notify(msg_queue_obj->ntfy_obj, - DSP_NODEMESSAGEREADY); - sync_set_event(msg_queue_obj->sync_event); - } - } - /* Set the post SWI flag */ - if (num_msgs > 0) { - /* Tell the DSP we've read the messages */ - msg_ctr_obj->buf_empty = true; - msg_ctr_obj->post_swi = true; - sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); - } -} - -/* - * ======== notify_chnl_complete ======== - * Purpose: - * Signal the channel event, notifying the client that I/O has completed. - */ -static void notify_chnl_complete(struct chnl_object *pchnl, - struct chnl_irp *chnl_packet_obj) -{ - bool signal_event; - - if (!pchnl || !pchnl->sync_event || !chnl_packet_obj) - goto func_end; - - /* - * Note: we signal the channel event only if the queue of IO - * completions is empty. If it is not empty, the event is sure to be - * signalled by the only IO completion list consumer: - * bridge_chnl_get_ioc(). - */ - signal_event = list_empty(&pchnl->io_completions); - /* Enqueue the IO completion info for the client */ - list_add_tail(&chnl_packet_obj->link, &pchnl->io_completions); - pchnl->cio_cs++; - - if (pchnl->cio_cs > pchnl->chnl_packets) - goto func_end; - /* Signal the channel event (if not already set) that IO is complete */ - if (signal_event) - sync_set_event(pchnl->sync_event); - - /* Notify that IO is complete */ - ntfy_notify(pchnl->ntfy_obj, DSP_STREAMIOCOMPLETION); -func_end: - return; -} - -/* - * ======== output_chnl ======== - * Purpose: - * Dispatch a buffer on an output channel. - */ -static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, - u8 io_mode) -{ - struct chnl_mgr *chnl_mgr_obj; - struct shm *sm; - u32 chnl_id; - struct chnl_irp *chnl_packet_obj; - u32 dw_dsp_f_mask; - - chnl_mgr_obj = pio_mgr->chnl_mgr; - sm = pio_mgr->shared_mem; - /* Attempt to perform output */ - if (sm->output_full) - goto func_end; - - if (pchnl && !((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY)) - goto func_end; - - /* Look to see if both a PC and DSP output channel are ready */ - dw_dsp_f_mask = sm->dsp_free_mask; - chnl_id = - find_ready_output(chnl_mgr_obj, pchnl, - (chnl_mgr_obj->output_mask & dw_dsp_f_mask)); - if (chnl_id == OUTPUTNOTREADY) - goto func_end; - - pchnl = chnl_mgr_obj->channels[chnl_id]; - if (!pchnl || list_empty(&pchnl->io_requests)) { - /* Shouldn't get here */ - goto func_end; - } - - if (!pchnl->cio_reqs) - goto func_end; - - /* Get the I/O request, and attempt a transfer */ - chnl_packet_obj = list_first_entry(&pchnl->io_requests, - struct chnl_irp, link); - list_del(&chnl_packet_obj->link); - - pchnl->cio_reqs--; - - /* Record fact that no more I/O buffers available */ - if (list_empty(&pchnl->io_requests)) - chnl_mgr_obj->output_mask &= ~(1 << chnl_id); - - /* Transfer buffer to DSP side */ - chnl_packet_obj->byte_size = min(pio_mgr->sm_buf_size, - chnl_packet_obj->byte_size); - memcpy(pio_mgr->output, chnl_packet_obj->host_sys_buf, - chnl_packet_obj->byte_size); - pchnl->bytes_moved += chnl_packet_obj->byte_size; - /* Write all 32 bits of arg */ - sm->arg = chnl_packet_obj->arg; -#if _CHNL_WORDSIZE == 2 - /* Access can be different SM access word size (e.g. 16/32 bit words) */ - sm->output_id = (u16) chnl_id; - sm->output_size = (u16) (chnl_packet_obj->byte_size + - chnl_mgr_obj->word_size - 1) / - (u16) chnl_mgr_obj->word_size; -#else - sm->output_id = chnl_id; - sm->output_size = (chnl_packet_obj->byte_size + - chnl_mgr_obj->word_size - 1) / chnl_mgr_obj->word_size; -#endif - sm->output_full = 1; - /* Indicate to the DSP we have written the output */ - sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); - /* Notify client with IO completion record (keep EOS) */ - chnl_packet_obj->status &= CHNL_IOCSTATEOS; - notify_chnl_complete(pchnl, chnl_packet_obj); - /* Notify if stream is done. */ - if (chnl_packet_obj->status & CHNL_IOCSTATEOS) - ntfy_notify(pchnl->ntfy_obj, DSP_STREAMDONE); - -func_end: - return; -} - -/* - * ======== output_msg ======== - * Copies messages from the message queues to the shared memory. - */ -static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) -{ - u32 num_msgs = 0; - u32 i; - struct msg_dspmsg *msg_output; - struct msg_frame *pmsg; - struct msg_ctrl *msg_ctr_obj; - u32 val; - u32 addr; - - msg_ctr_obj = pio_mgr->msg_output_ctrl; - - /* Check if output has been cleared */ - if (!msg_ctr_obj->buf_empty) - return; - - num_msgs = (hmsg_mgr->msgs_pending > hmsg_mgr->max_msgs) ? - hmsg_mgr->max_msgs : hmsg_mgr->msgs_pending; - msg_output = (struct msg_dspmsg *) pio_mgr->msg_output; - - /* Copy num_msgs messages into shared memory */ - for (i = 0; i < num_msgs; i++) { - if (list_empty(&hmsg_mgr->msg_used_list)) - continue; - - pmsg = list_first_entry(&hmsg_mgr->msg_used_list, - struct msg_frame, list_elem); - list_del(&pmsg->list_elem); - - val = (pmsg->msg_data).msgq_id; - addr = (u32) &msg_output->msgq_id; - write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); - - val = (pmsg->msg_data).msg.cmd; - addr = (u32) &msg_output->msg.cmd; - write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); - - val = (pmsg->msg_data).msg.arg1; - addr = (u32) &msg_output->msg.arg1; - write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); - - val = (pmsg->msg_data).msg.arg2; - addr = (u32) &msg_output->msg.arg2; - write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); - - msg_output++; - list_add_tail(&pmsg->list_elem, &hmsg_mgr->msg_free_list); - sync_set_event(hmsg_mgr->sync_event); - } - - if (num_msgs > 0) { - hmsg_mgr->msgs_pending -= num_msgs; -#if _CHNL_WORDSIZE == 2 - /* - * Access can be different SM access word size - * (e.g. 16/32 bit words) - */ - msg_ctr_obj->size = (u16) num_msgs; -#else - msg_ctr_obj->size = num_msgs; -#endif - msg_ctr_obj->buf_empty = false; - /* Set the post SWI flag */ - msg_ctr_obj->post_swi = true; - /* Tell the DSP we have written the output. */ - sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); - } -} - -/* - * ======== register_shm_segs ======== - * purpose: - * Registers GPP SM segment with CMM. - */ -static int register_shm_segs(struct io_mgr *hio_mgr, - struct cod_manager *cod_man, - u32 dw_gpp_base_pa) -{ - int status = 0; - u32 ul_shm0_base = 0; - u32 shm0_end = 0; - u32 ul_shm0_rsrvd_start = 0; - u32 ul_rsrvd_size = 0; - u32 ul_gpp_phys; - u32 ul_dsp_virt; - u32 ul_shm_seg_id0 = 0; - u32 dw_offset, dw_gpp_base_va, ul_dsp_size; - - /* - * Read address and size info for first SM region. - * Get start of 1st SM Heap region. - */ - status = - cod_get_sym_value(cod_man, SHM0_SHARED_BASE_SYM, &ul_shm0_base); - if (ul_shm0_base == 0) { - status = -EPERM; - goto func_end; - } - /* Get end of 1st SM Heap region */ - if (!status) { - /* Get start and length of message part of shared memory */ - status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM, - &shm0_end); - if (shm0_end == 0) { - status = -EPERM; - goto func_end; - } - } - /* Start of Gpp reserved region */ - if (!status) { - /* Get start and length of message part of shared memory */ - status = - cod_get_sym_value(cod_man, SHM0_SHARED_RESERVED_BASE_SYM, - &ul_shm0_rsrvd_start); - if (ul_shm0_rsrvd_start == 0) { - status = -EPERM; - goto func_end; - } - } - /* Register with CMM */ - if (!status) { - status = dev_get_cmm_mgr(hio_mgr->dev_obj, &hio_mgr->cmm_mgr); - if (!status) { - status = cmm_un_register_gppsm_seg(hio_mgr->cmm_mgr, - CMM_ALLSEGMENTS); - } - } - /* Register new SM region(s) */ - if (!status && (shm0_end - ul_shm0_base) > 0) { - /* Calc size (bytes) of SM the GPP can alloc from */ - ul_rsrvd_size = - (shm0_end - ul_shm0_rsrvd_start + 1) * hio_mgr->word_size; - if (ul_rsrvd_size <= 0) { - status = -EPERM; - goto func_end; - } - /* Calc size of SM DSP can alloc from */ - ul_dsp_size = - (ul_shm0_rsrvd_start - ul_shm0_base) * hio_mgr->word_size; - if (ul_dsp_size <= 0) { - status = -EPERM; - goto func_end; - } - /* First TLB entry reserved for Bridge SM use. */ - ul_gpp_phys = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys; - /* Get size in bytes */ - ul_dsp_virt = - hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt * - hio_mgr->word_size; - /* - * Calc byte offset used to convert GPP phys <-> DSP byte - * address. - */ - if (dw_gpp_base_pa > ul_dsp_virt) - dw_offset = dw_gpp_base_pa - ul_dsp_virt; - else - dw_offset = ul_dsp_virt - dw_gpp_base_pa; - - if (ul_shm0_rsrvd_start * hio_mgr->word_size < ul_dsp_virt) { - status = -EPERM; - goto func_end; - } - /* - * Calc Gpp phys base of SM region. - * This is actually uncached kernel virtual address. - */ - dw_gpp_base_va = - ul_gpp_phys + ul_shm0_rsrvd_start * hio_mgr->word_size - - ul_dsp_virt; - /* - * Calc Gpp phys base of SM region. - * This is the physical address. - */ - dw_gpp_base_pa = - dw_gpp_base_pa + ul_shm0_rsrvd_start * hio_mgr->word_size - - ul_dsp_virt; - /* Register SM Segment 0. */ - status = - cmm_register_gppsm_seg(hio_mgr->cmm_mgr, dw_gpp_base_pa, - ul_rsrvd_size, dw_offset, - (dw_gpp_base_pa > - ul_dsp_virt) ? CMM_ADDTODSPPA : - CMM_SUBFROMDSPPA, - (u32) (ul_shm0_base * - hio_mgr->word_size), - ul_dsp_size, &ul_shm_seg_id0, - dw_gpp_base_va); - /* First SM region is seg_id = 1 */ - if (ul_shm_seg_id0 != 1) - status = -EPERM; - } -func_end: - return status; -} - -/* ZCPY IO routines. */ -/* - * ======== IO_SHMcontrol ======== - * Sets the requested shm setting. - */ -int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs) -{ -#ifdef CONFIG_TIDSPBRIDGE_DVFS - u32 i; - struct dspbridge_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - switch (desc) { - case SHM_CURROPP: - /* Update the shared memory with requested OPP information */ - if (pargs != NULL) - hio_mgr->shared_mem->opp_table_struct.curr_opp_pt = - *(u32 *) pargs; - else - return -EPERM; - break; - case SHM_OPPINFO: - /* - * Update the shared memory with the voltage, frequency, - * min and max frequency values for an OPP. - */ - for (i = 0; i <= dsp_max_opps; i++) { - hio_mgr->shared_mem->opp_table_struct.opp_point[i]. - voltage = vdd1_dsp_freq[i][0]; - dev_dbg(bridge, "OPP-shm: voltage: %d\n", - vdd1_dsp_freq[i][0]); - hio_mgr->shared_mem->opp_table_struct. - opp_point[i].frequency = vdd1_dsp_freq[i][1]; - dev_dbg(bridge, "OPP-shm: frequency: %d\n", - vdd1_dsp_freq[i][1]); - hio_mgr->shared_mem->opp_table_struct.opp_point[i]. - min_freq = vdd1_dsp_freq[i][2]; - dev_dbg(bridge, "OPP-shm: min freq: %d\n", - vdd1_dsp_freq[i][2]); - hio_mgr->shared_mem->opp_table_struct.opp_point[i]. - max_freq = vdd1_dsp_freq[i][3]; - dev_dbg(bridge, "OPP-shm: max freq: %d\n", - vdd1_dsp_freq[i][3]); - } - hio_mgr->shared_mem->opp_table_struct.num_opp_pts = - dsp_max_opps; - dev_dbg(bridge, "OPP-shm: max OPP number: %d\n", dsp_max_opps); - /* Update the current OPP number */ - if (pdata->dsp_get_opp) - i = (*pdata->dsp_get_opp) (); - hio_mgr->shared_mem->opp_table_struct.curr_opp_pt = i; - dev_dbg(bridge, "OPP-shm: value programmed = %d\n", i); - break; - case SHM_GETOPP: - /* Get the OPP that DSP has requested */ - *(u32 *) pargs = hio_mgr->shared_mem->opp_request.rqst_opp_pt; - break; - default: - break; - } -#endif - return 0; -} - -/* - * ======== bridge_io_get_proc_load ======== - * Gets the Processor's Load information - */ -int bridge_io_get_proc_load(struct io_mgr *hio_mgr, - struct dsp_procloadstat *proc_lstat) -{ - if (!hio_mgr->shared_mem) - return -EFAULT; - - proc_lstat->curr_load = - hio_mgr->shared_mem->load_mon_info.curr_dsp_load; - proc_lstat->predicted_load = - hio_mgr->shared_mem->load_mon_info.pred_dsp_load; - proc_lstat->curr_dsp_freq = - hio_mgr->shared_mem->load_mon_info.curr_dsp_freq; - proc_lstat->predicted_freq = - hio_mgr->shared_mem->load_mon_info.pred_dsp_freq; - - dev_dbg(bridge, "Curr Load = %d, Pred Load = %d, Curr Freq = %d, " - "Pred Freq = %d\n", proc_lstat->curr_load, - proc_lstat->predicted_load, proc_lstat->curr_dsp_freq, - proc_lstat->predicted_freq); - return 0; -} - - -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) -void print_dsp_debug_trace(struct io_mgr *hio_mgr) -{ - u32 ul_new_message_length = 0, ul_gpp_cur_pointer; - - while (true) { - /* Get the DSP current pointer */ - ul_gpp_cur_pointer = - *(u32 *) (hio_mgr->trace_buffer_current); - ul_gpp_cur_pointer = - hio_mgr->gpp_va + (ul_gpp_cur_pointer - - hio_mgr->dsp_va); - - /* No new debug messages available yet */ - if (ul_gpp_cur_pointer == hio_mgr->gpp_read_pointer) { - break; - } else if (ul_gpp_cur_pointer > hio_mgr->gpp_read_pointer) { - /* Continuous data */ - ul_new_message_length = - ul_gpp_cur_pointer - hio_mgr->gpp_read_pointer; - - memcpy(hio_mgr->msg, - (char *)hio_mgr->gpp_read_pointer, - ul_new_message_length); - hio_mgr->msg[ul_new_message_length] = '\0'; - /* - * Advance the GPP trace pointer to DSP current - * pointer. - */ - hio_mgr->gpp_read_pointer += ul_new_message_length; - /* Print the trace messages */ - pr_info("DSPTrace: %s\n", hio_mgr->msg); - } else if (ul_gpp_cur_pointer < hio_mgr->gpp_read_pointer) { - /* Handle trace buffer wraparound */ - memcpy(hio_mgr->msg, - (char *)hio_mgr->gpp_read_pointer, - hio_mgr->trace_buffer_end - - hio_mgr->gpp_read_pointer); - ul_new_message_length = - ul_gpp_cur_pointer - hio_mgr->trace_buffer_begin; - memcpy(&hio_mgr->msg[hio_mgr->trace_buffer_end - - hio_mgr->gpp_read_pointer], - (char *)hio_mgr->trace_buffer_begin, - ul_new_message_length); - hio_mgr->msg[hio_mgr->trace_buffer_end - - hio_mgr->gpp_read_pointer + - ul_new_message_length] = '\0'; - /* - * Advance the GPP trace pointer to DSP current - * pointer. - */ - hio_mgr->gpp_read_pointer = - hio_mgr->trace_buffer_begin + - ul_new_message_length; - /* Print the trace messages */ - pr_info("DSPTrace: %s\n", hio_mgr->msg); - } - } -} -#endif - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/* - * ======== print_dsp_trace_buffer ======== - * Prints the trace buffer returned from the DSP (if DBG_Trace is enabled). - * Parameters: - * hdeh_mgr: Handle to DEH manager object - * number of extra carriage returns to generate. - * Returns: - * 0: Success. - * -ENOMEM: Unable to allocate memory. - * Requires: - * hdeh_mgr muse be valid. Checked in bridge_deh_notify. - */ -int print_dsp_trace_buffer(struct bridge_dev_context *hbridge_context) -{ - int status = 0; - struct cod_manager *cod_mgr; - u32 ul_trace_end; - u32 ul_trace_begin; - u32 trace_cur_pos; - u32 ul_num_bytes = 0; - u32 ul_num_words = 0; - u32 ul_word_size = 2; - char *psz_buf; - char *str_beg; - char *trace_end; - char *buf_end; - char *new_line; - - struct bridge_dev_context *pbridge_context = hbridge_context; - struct bridge_drv_interface *intf_fxns; - struct dev_object *dev_obj = (struct dev_object *) - pbridge_context->dev_obj; - - status = dev_get_cod_mgr(dev_obj, &cod_mgr); - - if (cod_mgr) { - /* Look for SYS_PUTCBEG/SYS_PUTCEND */ - status = - cod_get_sym_value(cod_mgr, COD_TRACEBEG, &ul_trace_begin); - } else { - status = -EFAULT; - } - if (!status) - status = - cod_get_sym_value(cod_mgr, COD_TRACEEND, &ul_trace_end); - - if (!status) - /* trace_cur_pos will hold the address of a DSP pointer */ - status = cod_get_sym_value(cod_mgr, COD_TRACECURPOS, - &trace_cur_pos); - - if (status) - goto func_end; - - ul_num_bytes = (ul_trace_end - ul_trace_begin); - - ul_num_words = ul_num_bytes * ul_word_size; - status = dev_get_intf_fxns(dev_obj, &intf_fxns); - - if (status) - goto func_end; - - psz_buf = kzalloc(ul_num_bytes + 2, GFP_ATOMIC); - if (psz_buf != NULL) { - /* Read trace buffer data */ - status = (*intf_fxns->brd_read)(pbridge_context, - (u8 *)psz_buf, (u32)ul_trace_begin, - ul_num_bytes, 0); - - if (status) - goto func_end; - - /* Pack and do newline conversion */ - pr_debug("PrintDspTraceBuffer: " - "before pack and unpack.\n"); - pr_debug("%s: DSP Trace Buffer Begin:\n" - "=======================\n%s\n", - __func__, psz_buf); - - /* Read the value at the DSP address in trace_cur_pos. */ - status = (*intf_fxns->brd_read)(pbridge_context, - (u8 *)&trace_cur_pos, (u32)trace_cur_pos, - 4, 0); - if (status) - goto func_end; - /* Pack and do newline conversion */ - pr_info("DSP Trace Buffer Begin:\n" - "=======================\n%s\n", - psz_buf); - - - /* convert to offset */ - trace_cur_pos = trace_cur_pos - ul_trace_begin; - - if (ul_num_bytes) { - /* - * The buffer is not full, find the end of the - * data -- buf_end will be >= pszBuf after - * while. - */ - buf_end = &psz_buf[ul_num_bytes+1]; - /* DSP print position */ - trace_end = &psz_buf[trace_cur_pos]; - - /* - * Search buffer for a new_line and replace it - * with '\0', then print as string. - * Continue until end of buffer is reached. - */ - str_beg = trace_end; - ul_num_bytes = buf_end - str_beg; - - while (str_beg < buf_end) { - new_line = strnchr(str_beg, ul_num_bytes, - '\n'); - if (new_line && new_line < buf_end) { - *new_line = 0; - pr_debug("%s\n", str_beg); - str_beg = ++new_line; - ul_num_bytes = buf_end - str_beg; - } else { - /* - * Assume buffer empty if it contains - * a zero - */ - if (*str_beg != '\0') { - str_beg[ul_num_bytes] = 0; - pr_debug("%s\n", str_beg); - } - str_beg = buf_end; - ul_num_bytes = 0; - } - } - /* - * Search buffer for a nNewLine and replace it - * with '\0', then print as string. - * Continue until buffer is exhausted. - */ - str_beg = psz_buf; - ul_num_bytes = trace_end - str_beg; - - while (str_beg < trace_end) { - new_line = strnchr(str_beg, ul_num_bytes, '\n'); - if (new_line != NULL && new_line < trace_end) { - *new_line = 0; - pr_debug("%s\n", str_beg); - str_beg = ++new_line; - ul_num_bytes = trace_end - str_beg; - } else { - /* - * Assume buffer empty if it contains - * a zero - */ - if (*str_beg != '\0') { - str_beg[ul_num_bytes] = 0; - pr_debug("%s\n", str_beg); - } - str_beg = trace_end; - ul_num_bytes = 0; - } - } - } - pr_info("\n=======================\n" - "DSP Trace Buffer End:\n"); - kfree(psz_buf); - } else { - status = -ENOMEM; - } -func_end: - if (status) - dev_dbg(bridge, "%s Failed, status 0x%x\n", __func__, status); - return status; -} - -/** - * dump_dsp_stack() - This function dumps the data on the DSP stack. - * @bridge_context: Bridge driver's device context pointer. - * - */ -int dump_dsp_stack(struct bridge_dev_context *bridge_context) -{ - int status = 0; - struct cod_manager *code_mgr; - struct node_mgr *node_mgr; - u32 trace_begin; - char name[256]; - struct { - u32 head[2]; - u32 size; - } mmu_fault_dbg_info; - u32 *buffer; - u32 *buffer_beg; - u32 *buffer_end; - u32 exc_type; - u32 dyn_ext_base; - u32 i; - u32 offset_output; - u32 total_size; - u32 poll_cnt; - const char *dsp_regs[] = {"EFR", "IERR", "ITSR", "NTSR", - "IRP", "NRP", "AMR", "SSR", - "ILC", "RILC", "IER", "CSR"}; - const char *exec_ctxt[] = {"Task", "SWI", "HWI", "Unknown"}; - struct bridge_drv_interface *intf_fxns; - struct dev_object *dev_object = bridge_context->dev_obj; - - status = dev_get_cod_mgr(dev_object, &code_mgr); - if (!code_mgr) { - pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__); - status = -EFAULT; - } - - if (!status) { - status = dev_get_node_manager(dev_object, &node_mgr); - if (!node_mgr) { - pr_debug("%s: Failed on dev_get_node_manager.\n", - __func__); - status = -EFAULT; - } - } - - if (!status) { - /* Look for SYS_PUTCBEG/SYS_PUTCEND: */ - status = - cod_get_sym_value(code_mgr, COD_TRACEBEG, &trace_begin); - pr_debug("%s: trace_begin Value 0x%x\n", - __func__, trace_begin); - if (status) - pr_debug("%s: Failed on cod_get_sym_value.\n", - __func__); - } - if (!status) - status = dev_get_intf_fxns(dev_object, &intf_fxns); - /* - * Check for the "magic number" in the trace buffer. If it has - * yet to appear then poll the trace buffer to wait for it. Its - * appearance signals that the DSP has finished dumping its state. - */ - mmu_fault_dbg_info.head[0] = 0; - mmu_fault_dbg_info.head[1] = 0; - if (!status) { - poll_cnt = 0; - while ((mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 || - mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) && - poll_cnt < POLL_MAX) { - - /* Read DSP dump size from the DSP trace buffer... */ - status = (*intf_fxns->brd_read)(bridge_context, - (u8 *)&mmu_fault_dbg_info, (u32)trace_begin, - sizeof(mmu_fault_dbg_info), 0); - - if (status) - break; - - poll_cnt++; - } - - if (mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 && - mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) { - status = -ETIME; - pr_err("%s:No DSP MMU-Fault information available.\n", - __func__); - } - } - - if (!status) { - total_size = mmu_fault_dbg_info.size; - /* Limit the size in case DSP went crazy */ - if (total_size > MAX_MMU_DBGBUFF) - total_size = MAX_MMU_DBGBUFF; - - buffer = kzalloc(total_size, GFP_ATOMIC); - if (!buffer) { - status = -ENOMEM; - pr_debug("%s: Failed to " - "allocate stack dump buffer.\n", __func__); - goto func_end; - } - - buffer_beg = buffer; - buffer_end = buffer + total_size / 4; - - /* Read bytes from the DSP trace buffer... */ - status = (*intf_fxns->brd_read)(bridge_context, - (u8 *)buffer, (u32)trace_begin, - total_size, 0); - if (status) { - pr_debug("%s: Failed to Read Trace Buffer.\n", - __func__); - goto func_end; - } - - pr_err("\nAproximate Crash Position:\n" - "--------------------------\n"); - - exc_type = buffer[3]; - if (!exc_type) - i = buffer[79]; /* IRP */ - else - i = buffer[80]; /* NRP */ - - status = - cod_get_sym_value(code_mgr, DYNEXTBASE, &dyn_ext_base); - if (status) { - status = -EFAULT; - goto func_end; - } - - if ((i > dyn_ext_base) && (node_find_addr(node_mgr, i, - 0x1000, &offset_output, name) == 0)) - pr_err("0x%-8x [\"%s\" + 0x%x]\n", i, name, - i - offset_output); - else - pr_err("0x%-8x [Unable to match to a symbol.]\n", i); - - buffer += 4; - - pr_err("\nExecution Info:\n" - "---------------\n"); - - if (*buffer < ARRAY_SIZE(exec_ctxt)) { - pr_err("Execution context \t%s\n", - exec_ctxt[*buffer++]); - } else { - pr_err("Execution context corrupt\n"); - kfree(buffer_beg); - return -EFAULT; - } - pr_err("Task Handle\t\t0x%x\n", *buffer++); - pr_err("Stack Pointer\t\t0x%x\n", *buffer++); - pr_err("Stack Top\t\t0x%x\n", *buffer++); - pr_err("Stack Bottom\t\t0x%x\n", *buffer++); - pr_err("Stack Size\t\t0x%x\n", *buffer++); - pr_err("Stack Size In Use\t0x%x\n", *buffer++); - - pr_err("\nCPU Registers\n" - "---------------\n"); - - for (i = 0; i < 32; i++) { - if (i == 4 || i == 6 || i == 8) - pr_err("A%d 0x%-8x [Function Argument %d]\n", - i, *buffer++, i-3); - else if (i == 15) - pr_err("A15 0x%-8x [Frame Pointer]\n", - *buffer++); - else - pr_err("A%d 0x%x\n", i, *buffer++); - } - - pr_err("\nB0 0x%x\n", *buffer++); - pr_err("B1 0x%x\n", *buffer++); - pr_err("B2 0x%x\n", *buffer++); - - if ((*buffer > dyn_ext_base) && (node_find_addr(node_mgr, - *buffer, 0x1000, &offset_output, name) == 0)) - - pr_err("B3 0x%-8x [Function Return Pointer:" - " \"%s\" + 0x%x]\n", *buffer, name, - *buffer - offset_output); - else - pr_err("B3 0x%-8x [Function Return Pointer:" - "Unable to match to a symbol.]\n", *buffer); - - buffer++; - - for (i = 4; i < 32; i++) { - if (i == 4 || i == 6 || i == 8) - pr_err("B%d 0x%-8x [Function Argument %d]\n", - i, *buffer++, i-2); - else if (i == 14) - pr_err("B14 0x%-8x [Data Page Pointer]\n", - *buffer++); - else - pr_err("B%d 0x%x\n", i, *buffer++); - } - - pr_err("\n"); - - for (i = 0; i < ARRAY_SIZE(dsp_regs); i++) - pr_err("%s 0x%x\n", dsp_regs[i], *buffer++); - - pr_err("\nStack:\n" - "------\n"); - - for (i = 0; buffer < buffer_end; i++, buffer++) { - if ((*buffer > dyn_ext_base) && ( - node_find_addr(node_mgr, *buffer , 0x600, - &offset_output, name) == 0)) - pr_err("[%d] 0x%-8x [\"%s\" + 0x%x]\n", - i, *buffer, name, - *buffer - offset_output); - else - pr_err("[%d] 0x%x\n", i, *buffer); - } - kfree(buffer_beg); - } -func_end: - return status; -} - -/** - * dump_dl_modules() - This functions dumps the _DLModules loaded in DSP side - * @bridge_context: Bridge driver's device context pointer. - * - */ -void dump_dl_modules(struct bridge_dev_context *bridge_context) -{ - struct cod_manager *code_mgr; - struct bridge_drv_interface *intf_fxns; - struct bridge_dev_context *bridge_ctxt = bridge_context; - struct dev_object *dev_object = bridge_ctxt->dev_obj; - struct modules_header modules_hdr; - struct dll_module *module_struct = NULL; - u32 module_dsp_addr; - u32 module_size; - u32 module_struct_size = 0; - u32 sect_ndx; - char *sect_str; - int status = 0; - - status = dev_get_intf_fxns(dev_object, &intf_fxns); - if (status) { - pr_debug("%s: Failed on dev_get_intf_fxns.\n", __func__); - goto func_end; - } - - status = dev_get_cod_mgr(dev_object, &code_mgr); - if (!code_mgr) { - pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__); - status = -EFAULT; - goto func_end; - } - - /* Lookup the address of the modules_header structure */ - status = cod_get_sym_value(code_mgr, "_DLModules", &module_dsp_addr); - if (status) { - pr_debug("%s: Failed on cod_get_sym_value for _DLModules.\n", - __func__); - goto func_end; - } - - pr_debug("%s: _DLModules at 0x%x\n", __func__, module_dsp_addr); - - /* Copy the modules_header structure from DSP memory. */ - status = (*intf_fxns->brd_read)(bridge_context, (u8 *) &modules_hdr, - (u32) module_dsp_addr, sizeof(modules_hdr), 0); - - if (status) { - pr_debug("%s: Failed failed to read modules header.\n", - __func__); - goto func_end; - } - - module_dsp_addr = modules_hdr.first_module; - module_size = modules_hdr.first_module_size; - - pr_debug("%s: dll_module_header 0x%x %d\n", __func__, module_dsp_addr, - module_size); - - pr_err("\nDynamically Loaded Modules:\n" - "---------------------------\n"); - - /* For each dll_module structure in the list... */ - while (module_size) { - /* - * Allocate/re-allocate memory to hold the dll_module - * structure. The memory is re-allocated only if the existing - * allocation is too small. - */ - if (module_size > module_struct_size) { - kfree(module_struct); - module_struct = kzalloc(module_size+128, GFP_ATOMIC); - module_struct_size = module_size+128; - pr_debug("%s: allocated module struct %p %d\n", - __func__, module_struct, module_struct_size); - if (!module_struct) - goto func_end; - } - /* Copy the dll_module structure from DSP memory */ - status = (*intf_fxns->brd_read)(bridge_context, - (u8 *)module_struct, module_dsp_addr, module_size, 0); - - if (status) { - pr_debug( - "%s: Failed to read dll_module struct for 0x%x.\n", - __func__, module_dsp_addr); - break; - } - - /* Update info regarding the _next_ module in the list. */ - module_dsp_addr = module_struct->next_module; - module_size = module_struct->next_module_size; - - pr_debug("%s: next module 0x%x %d, this module num sects %d\n", - __func__, module_dsp_addr, module_size, - module_struct->num_sects); - - /* - * The section name strings start immediately following - * the array of dll_sect structures. - */ - sect_str = (char *) &module_struct-> - sects[module_struct->num_sects]; - pr_err("%s\n", sect_str); - - /* - * Advance to the first section name string. - * Each string follows the one before. - */ - sect_str += strlen(sect_str) + 1; - - /* Access each dll_sect structure and its name string. */ - for (sect_ndx = 0; - sect_ndx < module_struct->num_sects; sect_ndx++) { - pr_err(" Section: 0x%x ", - module_struct->sects[sect_ndx].sect_load_adr); - - if (((u32) sect_str - (u32) module_struct) < - module_struct_size) { - pr_err("%s\n", sect_str); - /* Each string follows the one before. */ - sect_str += strlen(sect_str)+1; - } else { - pr_err("<string error>\n"); - pr_debug("%s: section name sting address " - "is invalid %p\n", __func__, sect_str); - } - } - } -func_end: - kfree(module_struct); -} -#endif diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c deleted file mode 100644 index 7b517eb827f..00000000000 --- a/drivers/staging/tidspbridge/core/msg_sm.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * msg_sm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implements upper edge functions for Bridge message 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. - */ -#include <linux/types.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> - -/* ----------------------------------- Others */ -#include <dspbridge/io_sm.h> - -/* ----------------------------------- This */ -#include <_msg_sm.h> -#include <dspbridge/dspmsg.h> - -/* ----------------------------------- Function Prototypes */ -static int add_new_msg(struct list_head *msg_list); -static void delete_msg_mgr(struct msg_mgr *hmsg_mgr); -static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp); -static void free_msg_list(struct list_head *msg_list); - -/* - * ======== bridge_msg_create ======== - * Create an object to manage message queues. Only one of these objects - * can exist per device object. - */ -int bridge_msg_create(struct msg_mgr **msg_man, - struct dev_object *hdev_obj, - msg_onexit msg_callback) -{ - struct msg_mgr *msg_mgr_obj; - struct io_mgr *hio_mgr; - int status = 0; - - if (!msg_man || !msg_callback || !hdev_obj) - return -EFAULT; - - dev_get_io_mgr(hdev_obj, &hio_mgr); - if (!hio_mgr) - return -EFAULT; - - *msg_man = NULL; - /* Allocate msg_ctrl manager object */ - msg_mgr_obj = kzalloc(sizeof(struct msg_mgr), GFP_KERNEL); - if (!msg_mgr_obj) - return -ENOMEM; - - msg_mgr_obj->on_exit = msg_callback; - msg_mgr_obj->iomgr = hio_mgr; - /* List of MSG_QUEUEs */ - INIT_LIST_HEAD(&msg_mgr_obj->queue_list); - /* - * Queues of message frames for messages to the DSP. Message - * frames will only be added to the free queue when a - * msg_queue object is created. - */ - INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list); - INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list); - spin_lock_init(&msg_mgr_obj->msg_mgr_lock); - - /* - * Create an event to be used by bridge_msg_put() in waiting - * for an available free frame from the message manager. - */ - msg_mgr_obj->sync_event = - kzalloc(sizeof(struct sync_object), GFP_KERNEL); - if (!msg_mgr_obj->sync_event) { - kfree(msg_mgr_obj); - return -ENOMEM; - } - sync_init_event(msg_mgr_obj->sync_event); - - *msg_man = msg_mgr_obj; - - return status; -} - -/* - * ======== bridge_msg_create_queue ======== - * Create a msg_queue for sending/receiving messages to/from a node - * on the DSP. - */ -int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, struct msg_queue **msgq, - u32 msgq_id, u32 max_msgs, void *arg) -{ - u32 i; - u32 num_allocated = 0; - struct msg_queue *msg_q; - int status = 0; - - if (!hmsg_mgr || msgq == NULL) - return -EFAULT; - - *msgq = NULL; - /* Allocate msg_queue object */ - msg_q = kzalloc(sizeof(struct msg_queue), GFP_KERNEL); - if (!msg_q) - return -ENOMEM; - - msg_q->max_msgs = max_msgs; - msg_q->msg_mgr = hmsg_mgr; - msg_q->arg = arg; /* Node handle */ - msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */ - /* Queues of Message frames for messages from the DSP */ - INIT_LIST_HEAD(&msg_q->msg_free_list); - INIT_LIST_HEAD(&msg_q->msg_used_list); - - /* Create event that will be signalled when a message from - * the DSP is available. */ - msg_q->sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL); - if (!msg_q->sync_event) { - status = -ENOMEM; - goto out_err; - - } - sync_init_event(msg_q->sync_event); - - /* Create a notification list for message ready notification. */ - msg_q->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL); - if (!msg_q->ntfy_obj) { - status = -ENOMEM; - goto out_err; - } - ntfy_init(msg_q->ntfy_obj); - - /* Create events that will be used to synchronize cleanup - * when the object is deleted. sync_done will be set to - * unblock threads in MSG_Put() or MSG_Get(). sync_done_ack - * will be set by the unblocked thread to signal that it - * is unblocked and will no longer reference the object. */ - msg_q->sync_done = kzalloc(sizeof(struct sync_object), GFP_KERNEL); - if (!msg_q->sync_done) { - status = -ENOMEM; - goto out_err; - } - sync_init_event(msg_q->sync_done); - - msg_q->sync_done_ack = kzalloc(sizeof(struct sync_object), GFP_KERNEL); - if (!msg_q->sync_done_ack) { - status = -ENOMEM; - goto out_err; - } - sync_init_event(msg_q->sync_done_ack); - - /* Enter critical section */ - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - /* Initialize message frames and put in appropriate queues */ - for (i = 0; i < max_msgs && !status; i++) { - status = add_new_msg(&hmsg_mgr->msg_free_list); - if (!status) { - num_allocated++; - status = add_new_msg(&msg_q->msg_free_list); - } - } - if (status) { - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - goto out_err; - } - - list_add_tail(&msg_q->list_elem, &hmsg_mgr->queue_list); - *msgq = msg_q; - /* Signal that free frames are now available */ - if (!list_empty(&hmsg_mgr->msg_free_list)) - sync_set_event(hmsg_mgr->sync_event); - - /* Exit critical section */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - - return 0; -out_err: - delete_msg_queue(msg_q, num_allocated); - return status; -} - -/* - * ======== bridge_msg_delete ======== - * Delete a msg_ctrl manager allocated in bridge_msg_create(). - */ -void bridge_msg_delete(struct msg_mgr *hmsg_mgr) -{ - delete_msg_mgr(hmsg_mgr); -} - -/* - * ======== bridge_msg_delete_queue ======== - * Delete a msg_ctrl queue allocated in bridge_msg_create_queue. - */ -void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj) -{ - struct msg_mgr *hmsg_mgr; - u32 io_msg_pend; - - if (!msg_queue_obj || !msg_queue_obj->msg_mgr) - return; - - hmsg_mgr = msg_queue_obj->msg_mgr; - msg_queue_obj->done = true; - /* Unblock all threads blocked in MSG_Get() or MSG_Put(). */ - io_msg_pend = msg_queue_obj->io_msg_pend; - while (io_msg_pend) { - /* Unblock thread */ - sync_set_event(msg_queue_obj->sync_done); - /* Wait for acknowledgement */ - sync_wait_on_event(msg_queue_obj->sync_done_ack, SYNC_INFINITE); - io_msg_pend = msg_queue_obj->io_msg_pend; - } - /* Remove message queue from hmsg_mgr->queue_list */ - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - list_del(&msg_queue_obj->list_elem); - /* Free the message queue object */ - delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs); - if (list_empty(&hmsg_mgr->msg_free_list)) - sync_reset_event(hmsg_mgr->sync_event); - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); -} - -/* - * ======== bridge_msg_get ======== - * Get a message from a msg_ctrl queue. - */ -int bridge_msg_get(struct msg_queue *msg_queue_obj, - struct dsp_msg *pmsg, u32 utimeout) -{ - struct msg_frame *msg_frame_obj; - struct msg_mgr *hmsg_mgr; - struct sync_object *syncs[2]; - u32 index; - int status = 0; - - if (!msg_queue_obj || pmsg == NULL) - return -ENOMEM; - - hmsg_mgr = msg_queue_obj->msg_mgr; - - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - /* If a message is already there, get it */ - if (!list_empty(&msg_queue_obj->msg_used_list)) { - msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list, - struct msg_frame, list_elem); - list_del(&msg_frame_obj->list_elem); - *pmsg = msg_frame_obj->msg_data.msg; - list_add_tail(&msg_frame_obj->list_elem, - &msg_queue_obj->msg_free_list); - if (list_empty(&msg_queue_obj->msg_used_list)) - sync_reset_event(msg_queue_obj->sync_event); - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - return 0; - } - - if (msg_queue_obj->done) { - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - return -EPERM; - } - msg_queue_obj->io_msg_pend++; - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - - /* - * Wait til message is available, timeout, or done. We don't - * have to schedule the DPC, since the DSP will send messages - * when they are available. - */ - syncs[0] = msg_queue_obj->sync_event; - syncs[1] = msg_queue_obj->sync_done; - status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index); - - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - if (msg_queue_obj->done) { - msg_queue_obj->io_msg_pend--; - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - /* - * Signal that we're not going to access msg_queue_obj - * anymore, so it can be deleted. - */ - sync_set_event(msg_queue_obj->sync_done_ack); - return -EPERM; - } - if (!status && !list_empty(&msg_queue_obj->msg_used_list)) { - /* Get msg from used list */ - msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list, - struct msg_frame, list_elem); - list_del(&msg_frame_obj->list_elem); - /* Copy message into pmsg and put frame on the free list */ - *pmsg = msg_frame_obj->msg_data.msg; - list_add_tail(&msg_frame_obj->list_elem, - &msg_queue_obj->msg_free_list); - } - msg_queue_obj->io_msg_pend--; - /* Reset the event if there are still queued messages */ - if (!list_empty(&msg_queue_obj->msg_used_list)) - sync_set_event(msg_queue_obj->sync_event); - - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - - return status; -} - -/* - * ======== bridge_msg_put ======== - * Put a message onto a msg_ctrl queue. - */ -int bridge_msg_put(struct msg_queue *msg_queue_obj, - const struct dsp_msg *pmsg, u32 utimeout) -{ - struct msg_frame *msg_frame_obj; - struct msg_mgr *hmsg_mgr; - struct sync_object *syncs[2]; - u32 index; - int status; - - if (!msg_queue_obj || !pmsg || !msg_queue_obj->msg_mgr) - return -EFAULT; - - hmsg_mgr = msg_queue_obj->msg_mgr; - - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - - /* If a message frame is available, use it */ - if (!list_empty(&hmsg_mgr->msg_free_list)) { - msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list, - struct msg_frame, list_elem); - list_del(&msg_frame_obj->list_elem); - msg_frame_obj->msg_data.msg = *pmsg; - msg_frame_obj->msg_data.msgq_id = - msg_queue_obj->msgq_id; - list_add_tail(&msg_frame_obj->list_elem, - &hmsg_mgr->msg_used_list); - hmsg_mgr->msgs_pending++; - - if (list_empty(&hmsg_mgr->msg_free_list)) - sync_reset_event(hmsg_mgr->sync_event); - - /* Release critical section before scheduling DPC */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - /* Schedule a DPC, to do the actual data transfer: */ - iosm_schedule(hmsg_mgr->iomgr); - return 0; - } - - if (msg_queue_obj->done) { - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - return -EPERM; - } - msg_queue_obj->io_msg_pend++; - - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - - /* Wait til a free message frame is available, timeout, or done */ - syncs[0] = hmsg_mgr->sync_event; - syncs[1] = msg_queue_obj->sync_done; - status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index); - if (status) - return status; - - /* Enter critical section */ - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - if (msg_queue_obj->done) { - msg_queue_obj->io_msg_pend--; - /* Exit critical section */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - /* - * Signal that we're not going to access msg_queue_obj - * anymore, so it can be deleted. - */ - sync_set_event(msg_queue_obj->sync_done_ack); - return -EPERM; - } - - if (list_empty(&hmsg_mgr->msg_free_list)) { - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - return -EFAULT; - } - - /* Get msg from free list */ - msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list, - struct msg_frame, list_elem); - /* - * Copy message into pmsg and put frame on the - * used list. - */ - list_del(&msg_frame_obj->list_elem); - msg_frame_obj->msg_data.msg = *pmsg; - msg_frame_obj->msg_data.msgq_id = msg_queue_obj->msgq_id; - list_add_tail(&msg_frame_obj->list_elem, &hmsg_mgr->msg_used_list); - hmsg_mgr->msgs_pending++; - /* - * Schedule a DPC, to do the actual - * data transfer. - */ - iosm_schedule(hmsg_mgr->iomgr); - - msg_queue_obj->io_msg_pend--; - /* Reset event if there are still frames available */ - if (!list_empty(&hmsg_mgr->msg_free_list)) - sync_set_event(hmsg_mgr->sync_event); - - /* Exit critical section */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - - return 0; -} - -/* - * ======== bridge_msg_register_notify ======== - */ -int bridge_msg_register_notify(struct msg_queue *msg_queue_obj, - u32 event_mask, u32 notify_type, - struct dsp_notification *hnotification) -{ - int status = 0; - - if (!msg_queue_obj || !hnotification) { - status = -ENOMEM; - goto func_end; - } - - if (!(event_mask == DSP_NODEMESSAGEREADY || event_mask == 0)) { - status = -EPERM; - goto func_end; - } - - if (notify_type != DSP_SIGNALEVENT) { - status = -EBADR; - goto func_end; - } - - if (event_mask) - status = ntfy_register(msg_queue_obj->ntfy_obj, hnotification, - event_mask, notify_type); - else - status = ntfy_unregister(msg_queue_obj->ntfy_obj, - hnotification); - - if (status == -EINVAL) { - /* Not registered. Ok, since we couldn't have known. Node - * notifications are split between node state change handled - * by NODE, and message ready handled by msg_ctrl. */ - status = 0; - } -func_end: - return status; -} - -/* - * ======== bridge_msg_set_queue_id ======== - */ -void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, u32 msgq_id) -{ - /* - * A message queue must be created when a node is allocated, - * so that node_register_notify() can be called before the node - * is created. Since we don't know the node environment until the - * node is created, we need this function to set msg_queue_obj->msgq_id - * to the node environment, after the node is created. - */ - if (msg_queue_obj) - msg_queue_obj->msgq_id = msgq_id; -} - -/* - * ======== add_new_msg ======== - * Must be called in message manager critical section. - */ -static int add_new_msg(struct list_head *msg_list) -{ - struct msg_frame *pmsg; - - pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC); - if (!pmsg) - return -ENOMEM; - - list_add_tail(&pmsg->list_elem, msg_list); - - return 0; -} - -/* - * ======== delete_msg_mgr ======== - */ -static void delete_msg_mgr(struct msg_mgr *hmsg_mgr) -{ - if (!hmsg_mgr) - return; - - /* FIXME: free elements from queue_list? */ - free_msg_list(&hmsg_mgr->msg_free_list); - free_msg_list(&hmsg_mgr->msg_used_list); - kfree(hmsg_mgr->sync_event); - kfree(hmsg_mgr); -} - -/* - * ======== delete_msg_queue ======== - */ -static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp) -{ - struct msg_mgr *hmsg_mgr; - struct msg_frame *pmsg, *tmp; - u32 i; - - if (!msg_queue_obj || !msg_queue_obj->msg_mgr) - return; - - hmsg_mgr = msg_queue_obj->msg_mgr; - - /* Pull off num_to_dsp message frames from Msg manager and free */ - i = 0; - list_for_each_entry_safe(pmsg, tmp, &hmsg_mgr->msg_free_list, - list_elem) { - list_del(&pmsg->list_elem); - kfree(pmsg); - if (i++ >= num_to_dsp) - break; - } - - free_msg_list(&msg_queue_obj->msg_free_list); - free_msg_list(&msg_queue_obj->msg_used_list); - - if (msg_queue_obj->ntfy_obj) { - ntfy_delete(msg_queue_obj->ntfy_obj); - kfree(msg_queue_obj->ntfy_obj); - } - - kfree(msg_queue_obj->sync_event); - kfree(msg_queue_obj->sync_done); - kfree(msg_queue_obj->sync_done_ack); - - kfree(msg_queue_obj); -} - -/* - * ======== free_msg_list ======== - */ -static void free_msg_list(struct list_head *msg_list) -{ - struct msg_frame *pmsg, *tmp; - - if (!msg_list) - return; - - list_for_each_entry_safe(pmsg, tmp, msg_list, list_elem) { - list_del(&pmsg->list_elem); - kfree(pmsg); - } -} diff --git a/drivers/staging/tidspbridge/core/sync.c b/drivers/staging/tidspbridge/core/sync.c deleted file mode 100644 index 743ff09d82d..00000000000 --- a/drivers/staging/tidspbridge/core/sync.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * sync.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Synchronization services. - * - * 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> - -/* ----------------------------------- This */ -#include <dspbridge/sync.h> -#include <dspbridge/ntfy.h> - -DEFINE_SPINLOCK(sync_lock); - -/** - * sync_set_event() - set or signal and specified event - * @event: Event to be set.. - * - * set the @event, if there is an thread waiting for the event - * it will be waken up, this function only wakes one thread. - */ - -void sync_set_event(struct sync_object *event) -{ - spin_lock_bh(&sync_lock); - complete(&event->comp); - if (event->multi_comp) - complete(event->multi_comp); - spin_unlock_bh(&sync_lock); -} - -/** - * sync_wait_on_multiple_events() - waits for multiple events to be set. - * @events: Array of events to wait for them. - * @count: number of elements of the array. - * @timeout timeout on waiting for the evetns. - * @pu_index index of the event set. - * - * These functions will wait until any of the array element is set or until - * timeout. In case of success the function will return 0 and - * @pu_index will store the index of the array element set or in case - * of timeout the function will return -ETIME or in case of - * interrupting by a signal it will return -EPERM. - */ - -int sync_wait_on_multiple_events(struct sync_object **events, - unsigned count, unsigned timeout, - unsigned *index) -{ - unsigned i; - int status = -EPERM; - struct completion m_comp; - - init_completion(&m_comp); - - if (SYNC_INFINITE == timeout) - timeout = MAX_SCHEDULE_TIMEOUT; - - spin_lock_bh(&sync_lock); - for (i = 0; i < count; i++) { - if (completion_done(&events[i]->comp)) { - reinit_completion(&events[i]->comp); - *index = i; - spin_unlock_bh(&sync_lock); - status = 0; - goto func_end; - } - } - - for (i = 0; i < count; i++) - events[i]->multi_comp = &m_comp; - - spin_unlock_bh(&sync_lock); - - if (!wait_for_completion_interruptible_timeout(&m_comp, - msecs_to_jiffies(timeout))) - status = -ETIME; - - spin_lock_bh(&sync_lock); - for (i = 0; i < count; i++) { - if (completion_done(&events[i]->comp)) { - reinit_completion(&events[i]->comp); - *index = i; - status = 0; - } - events[i]->multi_comp = NULL; - } - spin_unlock_bh(&sync_lock); -func_end: - return status; -} - -/** - * dsp_notifier_event() - callback function to nofity events - * @this: pointer to itself struct notifier_block - * @event: event to be notified. - * @data: Currently not used. - * - */ -int dsp_notifier_event(struct notifier_block *this, unsigned long event, - void *data) -{ - struct ntfy_event *ne = container_of(this, struct ntfy_event, - noti_block); - if (ne->event & event) - sync_set_event(&ne->sync_obj); - return NOTIFY_OK; -} diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c deleted file mode 100644 index cb50120ed7b..00000000000 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ /dev/null @@ -1,1813 +0,0 @@ -/* - * tiomap.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Processor Manager Driver for TI OMAP3430 EVM. - * - * 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. - */ - -#include <linux/platform_data/dsp-omap.h> - -#include <linux/types.h> -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> -#include <linux/mm.h> -#include <linux/mmzone.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/drv.h> -#include <dspbridge/sync.h> - -/* ------------------------------------ Hardware Abstraction Layer */ -#include <hw_defs.h> -#include <hw_mmu.h> - -/* ----------------------------------- Link Driver */ -#include <dspbridge/dspdefs.h> -#include <dspbridge/dspchnl.h> -#include <dspbridge/dspdeh.h> -#include <dspbridge/dspio.h> -#include <dspbridge/dspmsg.h> -#include <dspbridge/pwr.h> -#include <dspbridge/io_sm.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> -#include <dspbridge/dspapi.h> -#include <dspbridge/dmm.h> -#include <dspbridge/wdt.h> - -/* ----------------------------------- Local */ -#include "_tiomap.h" -#include "_tiomap_pwr.h" -#include "tiomap_io.h" - -/* Offset in shared mem to write to in order to synchronize start with DSP */ -#define SHMSYNCOFFSET 4 /* GPP byte offset */ - -#define BUFFERSIZE 1024 - -#define TIHELEN_ACKTIMEOUT 10000 - -#define MMU_SECTION_ADDR_MASK 0xFFF00000 -#define MMU_SSECTION_ADDR_MASK 0xFF000000 -#define MMU_LARGE_PAGE_MASK 0xFFFF0000 -#define MMU_SMALL_PAGE_MASK 0xFFFFF000 -#define OMAP3_IVA2_BOOTADDR_MASK 0xFFFFFC00 -#define PAGES_II_LVL_TABLE 512 -#define PHYS_TO_PAGE(phys) pfn_to_page((phys) >> PAGE_SHIFT) - -/* IVA Boot modes */ -#define DIRECT 0 -#define IDLE 1 - -/* Forward Declarations: */ -static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt); -static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, - u32 dsp_addr, u32 ul_num_bytes, - u32 mem_type); -static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, - u32 dsp_addr); -static int bridge_brd_status(struct bridge_dev_context *dev_ctxt, - int *board_state); -static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt); -static int bridge_brd_write(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, - u32 dsp_addr, u32 ul_num_bytes, - u32 mem_type); -static int bridge_brd_set_state(struct bridge_dev_context *dev_ctxt, - u32 brd_state); -static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, - u32 dsp_dest_addr, u32 dsp_src_addr, - u32 ul_num_bytes, u32 mem_type); -static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type); -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages); -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, - u32 virt_addr, u32 ul_num_bytes); -static int bridge_dev_create(struct bridge_dev_context - **dev_cntxt, - struct dev_object *hdev_obj, - struct cfg_hostres *config_param); -static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, - u32 dw_cmd, void *pargs); -static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static u32 user_va2_pa(struct mm_struct *mm, u32 address); -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, - u32 va, u32 size, - struct hw_mmu_map_attrs_t *map_attrs); -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs); -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs); - -bool wait_for_start(struct bridge_dev_context *dev_context, - void __iomem *sync_addr); - -/* ----------------------------------- Globals */ - -/* Attributes of L2 page tables for DSP MMU */ -struct page_info { - u32 num_entries; /* Number of valid PTEs in the L2 PT */ -}; - -/* Attributes used to manage the DSP MMU page tables */ -struct pg_table_attrs { - spinlock_t pg_lock; /* Critical section object handle */ - - u32 l1_base_pa; /* Physical address of the L1 PT */ - u32 l1_base_va; /* Virtual address of the L1 PT */ - u32 l1_size; /* Size of the L1 PT */ - u32 l1_tbl_alloc_pa; - /* Physical address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_va; - /* Virtual address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_sz; - /* Size of consistent memory allocated for L1 table. - * May not be aligned */ - - u32 l2_base_pa; /* Physical address of the L2 PT */ - u32 l2_base_va; /* Virtual address of the L2 PT */ - u32 l2_size; /* Size of the L2 PT */ - u32 l2_tbl_alloc_pa; - /* Physical address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_va; - /* Virtual address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_sz; - /* Size of consistent memory allocated for L2 table. - * May not be aligned */ - - u32 l2_num_pages; /* Number of allocated L2 PT */ - /* Array [l2_num_pages] of L2 PT info structs */ - struct page_info *pg_info; -}; - -/* - * This Bridge driver's function interface table. - */ -static struct bridge_drv_interface drv_interface_fxns = { - /* Bridge API ver. for which this bridge driver is built. */ - BRD_API_MAJOR_VERSION, - BRD_API_MINOR_VERSION, - bridge_dev_create, - bridge_dev_destroy, - bridge_dev_ctrl, - bridge_brd_monitor, - bridge_brd_start, - bridge_brd_stop, - bridge_brd_status, - bridge_brd_read, - bridge_brd_write, - bridge_brd_set_state, - bridge_brd_mem_copy, - bridge_brd_mem_write, - bridge_brd_mem_map, - bridge_brd_mem_un_map, - /* The following CHNL functions are provided by chnl_io.lib: */ - bridge_chnl_create, - bridge_chnl_destroy, - bridge_chnl_open, - bridge_chnl_close, - bridge_chnl_add_io_req, - bridge_chnl_get_ioc, - bridge_chnl_cancel_io, - bridge_chnl_flush_io, - bridge_chnl_get_info, - bridge_chnl_get_mgr_info, - bridge_chnl_idle, - bridge_chnl_register_notify, - /* The following IO functions are provided by chnl_io.lib: */ - bridge_io_create, - bridge_io_destroy, - bridge_io_on_loaded, - bridge_io_get_proc_load, - /* The following msg_ctrl functions are provided by chnl_io.lib: */ - bridge_msg_create, - bridge_msg_create_queue, - bridge_msg_delete, - bridge_msg_delete_queue, - bridge_msg_get, - bridge_msg_put, - bridge_msg_register_notify, - bridge_msg_set_queue_id, -}; - -static struct notifier_block dsp_mbox_notifier = { - .notifier_call = io_mbox_msg, -}; - -static inline void flush_all(struct bridge_dev_context *dev_context) -{ - if (dev_context->brd_state == BRD_DSP_HIBERNATION || - dev_context->brd_state == BRD_HIBERNATION) - wake_dsp(dev_context, NULL); - - hw_mmu_tlb_flush_all(dev_context->dsp_mmu_base); -} - -static void bad_page_dump(u32 pa, struct page *pg) -{ - pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); - pr_emerg("Bad page state in process '%s'\n" - "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" - "Backtrace:\n", - current->comm, pg, (int)(2 * sizeof(unsigned long)), - (unsigned long)pg->flags, pg->mapping, - page_mapcount(pg), page_count(pg)); - dump_stack(); -} - -/* - * ======== bridge_drv_entry ======== - * purpose: - * Bridge Driver entry point. - */ -void bridge_drv_entry(struct bridge_drv_interface **drv_intf, - const char *driver_file_name) -{ - if (strcmp(driver_file_name, "UMA") == 0) - *drv_intf = &drv_interface_fxns; - else - dev_dbg(bridge, "%s Unknown Bridge file name", __func__); - -} - -/* - * ======== bridge_brd_monitor ======== - * purpose: - * This bridge_brd_monitor puts DSP into a Loadable state. - * i.e Application can load and start the device. - * - * Preconditions: - * Device in 'OFF' state. - */ -static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt) -{ - struct bridge_dev_context *dev_context = dev_ctxt; - u32 temp; - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - temp = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) & - OMAP_POWERSTATEST_MASK; - if (!(temp & 0x02)) { - /* IVA2 is not in ON state */ - /* Read and set PM_PWSTCTRL_IVA2 to ON */ - (*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK, - PWRDM_POWER_ON, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL); - /* Set the SW supervised state transition */ - (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, - OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); - - /* Wait until the state has moved to ON */ - while ((*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, - OMAP2_PM_PWSTST) & - OMAP_INTRANSITION_MASK) - ; - /* Disable Automatic transition */ - (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, - OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); - } - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, - OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - dsp_clk_enable(DSP_CLK_IVA2); - - /* set the device state to IDLE */ - dev_context->brd_state = BRD_IDLE; - - return 0; -} - -/* - * ======== bridge_brd_read ======== - * purpose: - * Reads buffers for DSP memory. - */ -static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type) -{ - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - u32 offset; - u32 dsp_base_addr = dev_ctxt->dsp_base_addr; - - if (dsp_addr < dev_context->dsp_start_add) { - status = -EPERM; - return status; - } - /* change here to account for the 3 bands of the DSP internal memory */ - if ((dsp_addr - dev_context->dsp_start_add) < - dev_context->internal_size) { - offset = dsp_addr - dev_context->dsp_start_add; - } else { - status = read_ext_dsp_data(dev_context, host_buff, dsp_addr, - ul_num_bytes, mem_type); - return status; - } - /* copy the data from DSP memory */ - memcpy(host_buff, (void *)(dsp_base_addr + offset), ul_num_bytes); - return status; -} - -/* - * ======== bridge_brd_set_state ======== - * purpose: - * This routine updates the Board status. - */ -static int bridge_brd_set_state(struct bridge_dev_context *dev_ctxt, - u32 brd_state) -{ - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - - dev_context->brd_state = brd_state; - return status; -} - -/* - * ======== bridge_brd_start ======== - * purpose: - * Initializes DSP MMU and Starts DSP. - * - * Preconditions: - * a) DSP domain is 'ACTIVE'. - * b) DSP_RST1 is asserted. - * b) DSP_RST2 is released. - */ -static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, - u32 dsp_addr) -{ - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - void __iomem *sync_addr; - u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */ - u32 ul_shm_base_virt; /* Dsp Virt SM base addr */ - u32 ul_tlb_base_virt; /* Base of MMU TLB entry */ - u32 shm_sync_pa; - /* Offset of shm_base_virt from tlb_base_virt */ - u32 ul_shm_offset_virt; - s32 entry_ndx; - s32 itmp_entry_ndx = 0; /* DSP-MMU TLB entry base address */ - struct cfg_hostres *resources = NULL; - u32 temp; - u32 ul_dsp_clk_rate; - u32 ul_dsp_clk_addr; - u32 ul_bios_gp_timer; - u32 clk_cmd; - struct io_mgr *hio_mgr; - u32 ul_load_monitor_timer; - u32 wdt_en = 0; - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - /* The device context contains all the mmu setup info from when the - * last dsp base image was loaded. The first entry is always - * SHMMEM base. */ - /* Get SHM_BEG - convert to byte address */ - (void)dev_get_symbol(dev_context->dev_obj, SHMBASENAME, - &ul_shm_base_virt); - ul_shm_base_virt *= DSPWORDSIZE; - /* DSP Virtual address */ - ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va; - ul_shm_offset_virt = - ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE); - /* Kernel logical address */ - ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt; - - /* SHM physical sync address */ - shm_sync_pa = dev_context->atlb_entry[0].gpp_pa + ul_shm_offset_virt + - SHMSYNCOFFSET; - - /* 2nd wd is used as sync field */ - sync_addr = ioremap(shm_sync_pa, SZ_32); - if (!sync_addr) - return -ENOMEM; - - /* Write a signature into the shm base + offset; this will - * get cleared when the DSP program starts. */ - if ((ul_shm_base_virt == 0) || (ul_shm_base == 0)) { - pr_err("%s: Illegal SM base\n", __func__); - status = -EPERM; - } else - __raw_writel(0xffffffff, sync_addr); - - if (!status) { - resources = dev_context->resources; - if (!resources) - status = -EPERM; - - /* Assert RST1 i.e only the RST only for DSP megacell */ - if (!status) { - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, - OMAP3430_RST1_IVA2_MASK, - OMAP3430_IVA2_MOD, - OMAP2_RM_RSTCTRL); - - /* Mask address with 1K for compatibility */ - pdata->set_bootaddr(dsp_addr & - OMAP3_IVA2_BOOTADDR_MASK); - pdata->set_bootmode(dsp_debug ? IDLE : DIRECT); - } - } - if (!status) { - /* Reset and Unreset the RST2, so that BOOTADDR is copied to - * IVA2 SYSC register */ - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, - OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, - OMAP2_RM_RSTCTRL); - udelay(100); - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, - OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - udelay(100); - - /* Disbale the DSP MMU */ - hw_mmu_disable(resources->dmmu_base); - /* Disable TWL */ - hw_mmu_twl_disable(resources->dmmu_base); - - /* Only make TLB entry if both addresses are non-zero */ - for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; - entry_ndx++) { - struct bridge_ioctl_extproc *e = - &dev_context->atlb_entry[entry_ndx]; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = e->endianism, - .element_size = e->elem_size, - .mixed_size = e->mixed_mode, - }; - - if (!e->gpp_pa || !e->dsp_va) - continue; - - dev_dbg(bridge, - "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x", - itmp_entry_ndx, - e->gpp_pa, - e->dsp_va, - e->size); - - hw_mmu_tlb_add(dev_context->dsp_mmu_base, - e->gpp_pa, - e->dsp_va, - e->size, - itmp_entry_ndx, - &map_attrs, 1, 1); - - itmp_entry_ndx++; - } - } - - /* Lock the above TLB entries and get the BIOS and load monitor timer - * information */ - if (!status) { - hw_mmu_num_locked_set(resources->dmmu_base, itmp_entry_ndx); - hw_mmu_victim_num_set(resources->dmmu_base, itmp_entry_ndx); - hw_mmu_ttb_set(resources->dmmu_base, - dev_context->pt_attrs->l1_base_pa); - hw_mmu_twl_enable(resources->dmmu_base); - /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */ - - temp = __raw_readl((resources->dmmu_base) + 0x10); - temp = (temp & 0xFFFFFFEF) | 0x11; - __raw_writel(temp, (resources->dmmu_base) + 0x10); - - /* Let the DSP MMU run */ - hw_mmu_enable(resources->dmmu_base); - - /* Enable the BIOS clock */ - (void)dev_get_symbol(dev_context->dev_obj, - BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer); - (void)dev_get_symbol(dev_context->dev_obj, - BRIDGEINIT_LOADMON_GPTIMER, - &ul_load_monitor_timer); - } - - if (!status) { - if (ul_load_monitor_timer != 0xFFFF) { - clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) | - ul_load_monitor_timer; - dsp_peripheral_clk_ctrl(dev_context, &clk_cmd); - } else { - dev_dbg(bridge, "Not able to get the symbol for Load " - "Monitor Timer\n"); - } - } - - if (!status) { - if (ul_bios_gp_timer != 0xFFFF) { - clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) | - ul_bios_gp_timer; - dsp_peripheral_clk_ctrl(dev_context, &clk_cmd); - } else { - dev_dbg(bridge, - "Not able to get the symbol for BIOS Timer\n"); - } - } - - if (!status) { - /* Set the DSP clock rate */ - (void)dev_get_symbol(dev_context->dev_obj, - "_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr); - /*Set Autoidle Mode for IVA2 PLL */ - (*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT, - OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL); - - if ((unsigned int *)ul_dsp_clk_addr != NULL) { - /* Get the clock rate */ - ul_dsp_clk_rate = dsp_clk_get_iva2_rate(); - dev_dbg(bridge, "%s: DSP clock rate (KHZ): 0x%x \n", - __func__, ul_dsp_clk_rate); - (void)bridge_brd_write(dev_context, - (u8 *) &ul_dsp_clk_rate, - ul_dsp_clk_addr, sizeof(u32), 0); - } - /* - * Enable Mailbox events and also drain any pending - * stale messages. - */ - dev_context->mbox = omap_mbox_get("dsp", &dsp_mbox_notifier); - if (IS_ERR(dev_context->mbox)) { - dev_context->mbox = NULL; - pr_err("%s: Failed to get dsp mailbox handle\n", - __func__); - status = -EPERM; - } - - } - if (!status) { -/*PM_IVA2GRPSEL_PER = 0xC0;*/ - temp = readl(resources->per_pm_base + 0xA8); - temp = (temp & 0xFFFFFF30) | 0xC0; - writel(temp, resources->per_pm_base + 0xA8); - -/*PM_MPUGRPSEL_PER &= 0xFFFFFF3F; */ - temp = readl(resources->per_pm_base + 0xA4); - temp = (temp & 0xFFFFFF3F); - writel(temp, resources->per_pm_base + 0xA4); -/*CM_SLEEPDEP_PER |= 0x04; */ - temp = readl(resources->per_base + 0x44); - temp = (temp & 0xFFFFFFFB) | 0x04; - writel(temp, resources->per_base + 0x44); - -/*CM_CLKSTCTRL_IVA2 = 0x00000003 -To Allow automatic transitions */ - (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, - OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); - - /* Let DSP go */ - dev_dbg(bridge, "%s Unreset\n", __func__); - /* Enable DSP MMU Interrupts */ - hw_mmu_event_enable(resources->dmmu_base, - HW_MMU_ALL_INTERRUPTS); - /* release the RST1, DSP starts executing now .. */ - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0, - OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - - dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", *(u32 *)sync_addr); - dev_dbg(bridge, "DSP c_int00 Address = 0x%x\n", dsp_addr); - if (dsp_debug) - while (__raw_readw(sync_addr)) - ; - - /* Wait for DSP to clear word in shared memory */ - /* Read the Location */ - if (!wait_for_start(dev_context, sync_addr)) - status = -ETIMEDOUT; - - dev_get_symbol(dev_context->dev_obj, "_WDT_enable", &wdt_en); - if (wdt_en) { - /* Start wdt */ - dsp_wdt_sm_set((void *)ul_shm_base); - dsp_wdt_enable(true); - } - - status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr); - if (hio_mgr) { - io_sh_msetting(hio_mgr, SHM_OPPINFO, NULL); - /* Write the synchronization bit to indicate the - * completion of OPP table update to DSP - */ - __raw_writel(0XCAFECAFE, sync_addr); - - /* update board state */ - dev_context->brd_state = BRD_RUNNING; - /* (void)chnlsm_enable_interrupt(dev_context); */ - } else { - dev_context->brd_state = BRD_UNKNOWN; - } - } - - iounmap(sync_addr); - - return status; -} - -/* - * ======== bridge_brd_stop ======== - * purpose: - * Puts DSP in self loop. - * - * Preconditions : - * a) None - */ -static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) -{ - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - struct pg_table_attrs *pt_attrs; - u32 dsp_pwr_state; - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - if (dev_context->brd_state == BRD_STOPPED) - return status; - - /* as per TRM, it is advised to first drive the IVA2 to 'Standby' mode, - * before turning off the clocks.. This is to ensure that there are no - * pending L3 or other transactons from IVA2 */ - dsp_pwr_state = (*pdata->dsp_prm_read) - (OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) & OMAP_POWERSTATEST_MASK; - if (dsp_pwr_state != PWRDM_POWER_OFF) { - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, - OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - sm_interrupt_dsp(dev_context, MBX_PM_DSPIDLE); - mdelay(10); - - /* IVA2 is not in OFF state */ - /* Set PM_PWSTCTRL_IVA2 to OFF */ - (*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK, - PWRDM_POWER_OFF, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL); - /* Set the SW supervised state transition for Sleep */ - (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, - OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); - } - udelay(10); - /* Release the Ext Base virtual Address as the next DSP Program - * may have a different load address */ - if (dev_context->dsp_ext_base_addr) - dev_context->dsp_ext_base_addr = 0; - - dev_context->brd_state = BRD_STOPPED; /* update board state */ - - dsp_wdt_enable(false); - - /* This is a good place to clear the MMU page tables as well */ - if (dev_context->pt_attrs) { - pt_attrs = dev_context->pt_attrs; - memset((u8 *) pt_attrs->l1_base_va, 0x00, pt_attrs->l1_size); - memset((u8 *) pt_attrs->l2_base_va, 0x00, pt_attrs->l2_size); - memset((u8 *) pt_attrs->pg_info, 0x00, - (pt_attrs->l2_num_pages * sizeof(struct page_info))); - } - /* Disable the mailbox interrupts */ - if (dev_context->mbox) { - omap_mbox_disable_irq(dev_context->mbox, IRQ_RX); - omap_mbox_put(dev_context->mbox, &dsp_mbox_notifier); - dev_context->mbox = NULL; - } - /* Reset IVA2 clocks*/ - (*pdata->dsp_prm_write)(OMAP3430_RST1_IVA2_MASK | - OMAP3430_RST2_IVA2_MASK | OMAP3430_RST3_IVA2_MASK, - OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - - dsp_clock_disable_all(dev_context->dsp_per_clks); - dsp_clk_disable(DSP_CLK_IVA2); - - return status; -} - -/* - * ======== bridge_brd_status ======== - * Returns the board status. - */ -static int bridge_brd_status(struct bridge_dev_context *dev_ctxt, - int *board_state) -{ - struct bridge_dev_context *dev_context = dev_ctxt; - *board_state = dev_context->brd_state; - return 0; -} - -/* - * ======== bridge_brd_write ======== - * Copies the buffers to DSP internal or external memory. - */ -static int bridge_brd_write(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type) -{ - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - - if (dsp_addr < dev_context->dsp_start_add) { - status = -EPERM; - return status; - } - if ((dsp_addr - dev_context->dsp_start_add) < - dev_context->internal_size) { - status = write_dsp_data(dev_ctxt, host_buff, dsp_addr, - ul_num_bytes, mem_type); - } else { - status = write_ext_dsp_data(dev_context, host_buff, dsp_addr, - ul_num_bytes, mem_type, false); - } - - return status; -} - -/* - * ======== bridge_dev_create ======== - * Creates a driver object. Puts DSP in self loop. - */ -static int bridge_dev_create(struct bridge_dev_context - **dev_cntxt, - struct dev_object *hdev_obj, - struct cfg_hostres *config_param) -{ - int status = 0; - struct bridge_dev_context *dev_context = NULL; - s32 entry_ndx; - struct cfg_hostres *resources = config_param; - struct pg_table_attrs *pt_attrs; - u32 pg_tbl_pa; - u32 pg_tbl_va; - u32 align_size; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - /* Allocate and initialize a data structure to contain the bridge driver - * state, which becomes the context for later calls into this driver */ - dev_context = kzalloc(sizeof(struct bridge_dev_context), GFP_KERNEL); - if (!dev_context) { - status = -ENOMEM; - goto func_end; - } - - dev_context->dsp_start_add = (u32) OMAP_GEM_BASE; - dev_context->self_loop = (u32) NULL; - dev_context->dsp_per_clks = 0; - dev_context->internal_size = OMAP_DSP_SIZE; - /* Clear dev context MMU table entries. - * These get set on bridge_io_on_loaded() call after program loaded. */ - for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; entry_ndx++) { - dev_context->atlb_entry[entry_ndx].gpp_pa = - dev_context->atlb_entry[entry_ndx].dsp_va = 0; - } - dev_context->dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *) - (config_param-> - mem_base - [3]), - config_param-> - mem_length - [3]); - if (!dev_context->dsp_base_addr) - status = -EPERM; - - pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL); - if (pt_attrs != NULL) { - pt_attrs->l1_size = SZ_16K; /* 4096 entries of 32 bits */ - align_size = pt_attrs->l1_size; - /* Align sizes are expected to be power of 2 */ - /* we like to get aligned on L1 table size */ - pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l1_size, - align_size, &pg_tbl_pa); - - /* Check if the PA is aligned for us */ - if ((pg_tbl_pa) & (align_size - 1)) { - /* PA not aligned to page table size , - * try with more allocation and align */ - mem_free_phys_mem((void *)pg_tbl_va, pg_tbl_pa, - pt_attrs->l1_size); - /* we like to get aligned on L1 table size */ - pg_tbl_va = - (u32) mem_alloc_phys_mem((pt_attrs->l1_size) * 2, - align_size, &pg_tbl_pa); - /* We should be able to get aligned table now */ - pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l1_tbl_alloc_va = pg_tbl_va; - pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size * 2; - /* Align the PA to the next 'align' boundary */ - pt_attrs->l1_base_pa = - ((pg_tbl_pa) + - (align_size - 1)) & (~(align_size - 1)); - pt_attrs->l1_base_va = - pg_tbl_va + (pt_attrs->l1_base_pa - pg_tbl_pa); - } else { - /* We got aligned PA, cool */ - pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l1_tbl_alloc_va = pg_tbl_va; - pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size; - pt_attrs->l1_base_pa = pg_tbl_pa; - pt_attrs->l1_base_va = pg_tbl_va; - } - if (pt_attrs->l1_base_va) - memset((u8 *) pt_attrs->l1_base_va, 0x00, - pt_attrs->l1_size); - - /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM + - * L4 pages */ - pt_attrs->l2_num_pages = ((DMMPOOLSIZE >> 20) + 6); - pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE * - pt_attrs->l2_num_pages; - align_size = 4; /* Make it u32 aligned */ - /* we like to get aligned on L1 table size */ - pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l2_size, - align_size, &pg_tbl_pa); - pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l2_tbl_alloc_va = pg_tbl_va; - pt_attrs->l2_tbl_alloc_sz = pt_attrs->l2_size; - pt_attrs->l2_base_pa = pg_tbl_pa; - pt_attrs->l2_base_va = pg_tbl_va; - - if (pt_attrs->l2_base_va) - memset((u8 *) pt_attrs->l2_base_va, 0x00, - pt_attrs->l2_size); - - pt_attrs->pg_info = kzalloc(pt_attrs->l2_num_pages * - sizeof(struct page_info), GFP_KERNEL); - dev_dbg(bridge, - "L1 pa %x, va %x, size %x\n L2 pa %x, va " - "%x, size %x\n", pt_attrs->l1_base_pa, - pt_attrs->l1_base_va, pt_attrs->l1_size, - pt_attrs->l2_base_pa, pt_attrs->l2_base_va, - pt_attrs->l2_size); - dev_dbg(bridge, "pt_attrs %p L2 NumPages %x pg_info %p\n", - pt_attrs, pt_attrs->l2_num_pages, pt_attrs->pg_info); - } - if ((pt_attrs != NULL) && (pt_attrs->l1_base_va != 0) && - (pt_attrs->l2_base_va != 0) && (pt_attrs->pg_info != NULL)) - dev_context->pt_attrs = pt_attrs; - else - status = -ENOMEM; - - if (!status) { - spin_lock_init(&pt_attrs->pg_lock); - dev_context->tc_word_swap_on = drv_datap->tc_wordswapon; - - /* Set the Clock Divisor for the DSP module */ - udelay(5); - /* MMU address is obtained from the host - * resources struct */ - dev_context->dsp_mmu_base = resources->dmmu_base; - } - if (!status) { - dev_context->dev_obj = hdev_obj; - /* Store current board state. */ - dev_context->brd_state = BRD_UNKNOWN; - dev_context->resources = resources; - dsp_clk_enable(DSP_CLK_IVA2); - bridge_brd_stop(dev_context); - /* Return ptr to our device state to the DSP API for storage */ - *dev_cntxt = dev_context; - } else { - if (pt_attrs != NULL) { - kfree(pt_attrs->pg_info); - - if (pt_attrs->l2_tbl_alloc_va) { - mem_free_phys_mem((void *) - pt_attrs->l2_tbl_alloc_va, - pt_attrs->l2_tbl_alloc_pa, - pt_attrs->l2_tbl_alloc_sz); - } - if (pt_attrs->l1_tbl_alloc_va) { - mem_free_phys_mem((void *) - pt_attrs->l1_tbl_alloc_va, - pt_attrs->l1_tbl_alloc_pa, - pt_attrs->l1_tbl_alloc_sz); - } - } - kfree(pt_attrs); - kfree(dev_context); - } -func_end: - return status; -} - -/* - * ======== bridge_dev_ctrl ======== - * Receives device specific commands. - */ -static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, - u32 dw_cmd, void *pargs) -{ - int status = 0; - struct bridge_ioctl_extproc *pa_ext_proc = - (struct bridge_ioctl_extproc *)pargs; - s32 ndx; - - switch (dw_cmd) { - case BRDIOCTL_CHNLREAD: - break; - case BRDIOCTL_CHNLWRITE: - break; - case BRDIOCTL_SETMMUCONFIG: - /* store away dsp-mmu setup values for later use */ - for (ndx = 0; ndx < BRDIOCTL_NUMOFMMUTLB; ndx++, pa_ext_proc++) - dev_context->atlb_entry[ndx] = *pa_ext_proc; - break; - case BRDIOCTL_DEEPSLEEP: - case BRDIOCTL_EMERGENCYSLEEP: - /* Currently only DSP Idle is supported Need to update for - * later releases */ - status = sleep_dsp(dev_context, PWR_DEEPSLEEP, pargs); - break; - case BRDIOCTL_WAKEUP: - status = wake_dsp(dev_context, pargs); - break; - case BRDIOCTL_CLK_CTRL: - status = 0; - /* Looking For Baseport Fix for Clocks */ - status = dsp_peripheral_clk_ctrl(dev_context, pargs); - break; - case BRDIOCTL_PWR_HIBERNATE: - status = handle_hibernation_from_dsp(dev_context); - break; - case BRDIOCTL_PRESCALE_NOTIFY: - status = pre_scale_dsp(dev_context, pargs); - break; - case BRDIOCTL_POSTSCALE_NOTIFY: - status = post_scale_dsp(dev_context, pargs); - break; - case BRDIOCTL_CONSTRAINT_REQUEST: - status = handle_constraints_set(dev_context, pargs); - break; - default: - status = -EPERM; - break; - } - return status; -} - -/* - * ======== bridge_dev_destroy ======== - * Destroys the driver object. - */ -static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) -{ - struct pg_table_attrs *pt_attrs; - int status = 0; - struct bridge_dev_context *dev_context = (struct bridge_dev_context *) - dev_ctxt; - struct cfg_hostres *host_res; - u32 shm_size; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - /* It should never happen */ - if (!dev_ctxt) - return -EFAULT; - - /* first put the device to stop state */ - bridge_brd_stop(dev_context); - if (dev_context->pt_attrs) { - pt_attrs = dev_context->pt_attrs; - kfree(pt_attrs->pg_info); - - if (pt_attrs->l2_tbl_alloc_va) { - mem_free_phys_mem((void *)pt_attrs->l2_tbl_alloc_va, - pt_attrs->l2_tbl_alloc_pa, - pt_attrs->l2_tbl_alloc_sz); - } - if (pt_attrs->l1_tbl_alloc_va) { - mem_free_phys_mem((void *)pt_attrs->l1_tbl_alloc_va, - pt_attrs->l1_tbl_alloc_pa, - pt_attrs->l1_tbl_alloc_sz); - } - kfree(pt_attrs); - - } - - if (dev_context->resources) { - host_res = dev_context->resources; - shm_size = drv_datap->shm_size; - if (shm_size >= 0x10000) { - if ((host_res->mem_base[1]) && - (host_res->mem_phys[1])) { - mem_free_phys_mem((void *) - host_res->mem_base - [1], - host_res->mem_phys - [1], shm_size); - } - } else { - dev_dbg(bridge, "%s: Error getting shm size " - "from registry: %x. Not calling " - "mem_free_phys_mem\n", __func__, - status); - } - host_res->mem_base[1] = 0; - host_res->mem_phys[1] = 0; - - if (host_res->mem_base[0]) - iounmap((void *)host_res->mem_base[0]); - if (host_res->mem_base[2]) - iounmap((void *)host_res->mem_base[2]); - if (host_res->mem_base[3]) - iounmap((void *)host_res->mem_base[3]); - if (host_res->mem_base[4]) - iounmap((void *)host_res->mem_base[4]); - if (host_res->dmmu_base) - iounmap(host_res->dmmu_base); - if (host_res->per_base) - iounmap(host_res->per_base); - if (host_res->per_pm_base) - iounmap((void *)host_res->per_pm_base); - if (host_res->core_pm_base) - iounmap((void *)host_res->core_pm_base); - - host_res->mem_base[0] = (u32) NULL; - host_res->mem_base[2] = (u32) NULL; - host_res->mem_base[3] = (u32) NULL; - host_res->mem_base[4] = (u32) NULL; - host_res->dmmu_base = NULL; - - kfree(host_res); - } - - /* Free the driver's device context: */ - kfree(drv_datap->base_img); - kfree((void *)dev_ctxt); - return status; -} - -static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, - u32 dsp_dest_addr, u32 dsp_src_addr, - u32 ul_num_bytes, u32 mem_type) -{ - int status = 0; - u32 src_addr = dsp_src_addr; - u32 dest_addr = dsp_dest_addr; - u32 copy_bytes = 0; - u32 total_bytes = ul_num_bytes; - u8 host_buf[BUFFERSIZE]; - struct bridge_dev_context *dev_context = dev_ctxt; - while (total_bytes > 0 && !status) { - copy_bytes = - total_bytes > BUFFERSIZE ? BUFFERSIZE : total_bytes; - /* Read from External memory */ - status = read_ext_dsp_data(dev_ctxt, host_buf, src_addr, - copy_bytes, mem_type); - if (!status) { - if (dest_addr < (dev_context->dsp_start_add + - dev_context->internal_size)) { - /* Write to Internal memory */ - status = write_dsp_data(dev_ctxt, host_buf, - dest_addr, copy_bytes, - mem_type); - } else { - /* Write to External memory */ - status = - write_ext_dsp_data(dev_ctxt, host_buf, - dest_addr, copy_bytes, - mem_type, false); - } - } - total_bytes -= copy_bytes; - src_addr += copy_bytes; - dest_addr += copy_bytes; - } - return status; -} - -/* Mem Write does not halt the DSP to write unlike bridge_brd_write */ -static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type) -{ - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - u32 ul_remain_bytes = 0; - u32 ul_bytes = 0; - ul_remain_bytes = ul_num_bytes; - while (ul_remain_bytes > 0 && !status) { - ul_bytes = - ul_remain_bytes > BUFFERSIZE ? BUFFERSIZE : ul_remain_bytes; - if (dsp_addr < (dev_context->dsp_start_add + - dev_context->internal_size)) { - status = - write_dsp_data(dev_ctxt, host_buff, dsp_addr, - ul_bytes, mem_type); - } else { - status = write_ext_dsp_data(dev_ctxt, host_buff, - dsp_addr, ul_bytes, - mem_type, true); - } - ul_remain_bytes -= ul_bytes; - dsp_addr += ul_bytes; - host_buff = host_buff + ul_bytes; - } - return status; -} - -/* - * ======== bridge_brd_mem_map ======== - * This function maps MPU buffer to the DSP address space. It performs - * linear to physical address translation if required. It translates each - * page since linear addresses can be physically non-contiguous - * All address & size arguments are assumed to be page aligned (in proc.c) - * - * TODO: Disable MMU while updating the page tables (but that'll stall DSP) - */ -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages) -{ - u32 attrs; - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - struct hw_mmu_map_attrs_t hw_attrs; - struct vm_area_struct *vma; - struct mm_struct *mm = current->mm; - u32 write = 0; - u32 num_usr_pgs = 0; - struct page *mapped_page, *pg; - s32 pg_num; - u32 va = virt_addr; - struct task_struct *curr_task = current; - u32 pg_i = 0; - u32 mpu_addr, pa; - - dev_dbg(bridge, - "%s hDevCtxt %p, pa %x, va %x, size %x, ul_map_attr %x\n", - __func__, dev_ctxt, ul_mpu_addr, virt_addr, ul_num_bytes, - ul_map_attr); - if (ul_num_bytes == 0) - return -EINVAL; - - if (ul_map_attr & DSP_MAP_DIR_MASK) { - attrs = ul_map_attr; - } else { - /* Assign default attributes */ - attrs = ul_map_attr | (DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16); - } - /* Take mapping properties */ - if (attrs & DSP_MAPBIGENDIAN) - hw_attrs.endianism = HW_BIG_ENDIAN; - else - hw_attrs.endianism = HW_LITTLE_ENDIAN; - - hw_attrs.mixed_size = (enum hw_mmu_mixed_size_t) - ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2); - /* Ignore element_size if mixed_size is enabled */ - if (hw_attrs.mixed_size == 0) { - if (attrs & DSP_MAPELEMSIZE8) { - /* Size is 8 bit */ - hw_attrs.element_size = HW_ELEM_SIZE8BIT; - } else if (attrs & DSP_MAPELEMSIZE16) { - /* Size is 16 bit */ - hw_attrs.element_size = HW_ELEM_SIZE16BIT; - } else if (attrs & DSP_MAPELEMSIZE32) { - /* Size is 32 bit */ - hw_attrs.element_size = HW_ELEM_SIZE32BIT; - } else if (attrs & DSP_MAPELEMSIZE64) { - /* Size is 64 bit */ - hw_attrs.element_size = HW_ELEM_SIZE64BIT; - } else { - /* - * Mixedsize isn't enabled, so size can't be - * zero here - */ - return -EINVAL; - } - } - if (attrs & DSP_MAPDONOTLOCK) - hw_attrs.donotlockmpupage = 1; - else - hw_attrs.donotlockmpupage = 0; - - if (attrs & DSP_MAPVMALLOCADDR) { - return mem_map_vmalloc(dev_ctxt, ul_mpu_addr, virt_addr, - ul_num_bytes, &hw_attrs); - } - /* - * Do OS-specific user-va to pa translation. - * Combine physically contiguous regions to reduce TLBs. - * Pass the translated pa to pte_update. - */ - if ((attrs & DSP_MAPPHYSICALADDR)) { - status = pte_update(dev_context, ul_mpu_addr, virt_addr, - ul_num_bytes, &hw_attrs); - goto func_cont; - } - - /* - * Important Note: ul_mpu_addr is mapped from user application process - * to current process - it must lie completely within the current - * virtual memory address space in order to be of use to us here! - */ - down_read(&mm->mmap_sem); - vma = find_vma(mm, ul_mpu_addr); - if (vma) - dev_dbg(bridge, - "VMAfor UserBuf: ul_mpu_addr=%x, ul_num_bytes=%x, " - "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr, - ul_num_bytes, vma->vm_start, vma->vm_end, - vma->vm_flags); - - /* - * It is observed that under some circumstances, the user buffer is - * spread across several VMAs. So loop through and check if the entire - * user buffer is covered - */ - while ((vma) && (ul_mpu_addr + ul_num_bytes > vma->vm_end)) { - /* jump to the next VMA region */ - vma = find_vma(mm, vma->vm_end + 1); - dev_dbg(bridge, - "VMA for UserBuf ul_mpu_addr=%x ul_num_bytes=%x, " - "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr, - ul_num_bytes, vma->vm_start, vma->vm_end, - vma->vm_flags); - } - if (!vma) { - pr_err("%s: Failed to get VMA region for 0x%x (%d)\n", - __func__, ul_mpu_addr, ul_num_bytes); - status = -EINVAL; - up_read(&mm->mmap_sem); - goto func_cont; - } - - if (vma->vm_flags & VM_IO) { - num_usr_pgs = ul_num_bytes / PG_SIZE4K; - mpu_addr = ul_mpu_addr; - - /* Get the physical addresses for user buffer */ - for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) { - pa = user_va2_pa(mm, mpu_addr); - if (!pa) { - status = -EPERM; - pr_err("DSPBRIDGE: VM_IO mapping physical" - "address is invalid\n"); - break; - } - if (pfn_valid(__phys_to_pfn(pa))) { - pg = PHYS_TO_PAGE(pa); - get_page(pg); - if (page_count(pg) < 1) { - pr_err("Bad page in VM_IO buffer\n"); - bad_page_dump(pa, pg); - } - } - status = pte_set(dev_context->pt_attrs, pa, - va, HW_PAGE_SIZE4KB, &hw_attrs); - if (status) - break; - - va += HW_PAGE_SIZE4KB; - mpu_addr += HW_PAGE_SIZE4KB; - pa += HW_PAGE_SIZE4KB; - } - } else { - num_usr_pgs = ul_num_bytes / PG_SIZE4K; - if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) - write = 1; - - for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) { - pg_num = get_user_pages(curr_task, mm, ul_mpu_addr, 1, - write, 1, &mapped_page, NULL); - if (pg_num > 0) { - if (page_count(mapped_page) < 1) { - pr_err("Bad page count after doing" - "get_user_pages on" - "user buffer\n"); - bad_page_dump(page_to_phys(mapped_page), - mapped_page); - } - status = pte_set(dev_context->pt_attrs, - page_to_phys(mapped_page), va, - HW_PAGE_SIZE4KB, &hw_attrs); - if (status) - break; - - if (mapped_pages) - mapped_pages[pg_i] = mapped_page; - - va += HW_PAGE_SIZE4KB; - ul_mpu_addr += HW_PAGE_SIZE4KB; - } else { - pr_err("DSPBRIDGE: get_user_pages FAILED," - "MPU addr = 0x%x," - "vma->vm_flags = 0x%lx," - "get_user_pages Err" - "Value = %d, Buffer" - "size=0x%x\n", ul_mpu_addr, - vma->vm_flags, pg_num, ul_num_bytes); - status = -EPERM; - break; - } - } - } - up_read(&mm->mmap_sem); -func_cont: - if (status) { - /* - * Roll out the mapped pages incase it failed in middle of - * mapping - */ - if (pg_i) { - bridge_brd_mem_un_map(dev_context, virt_addr, - (pg_i * PG_SIZE4K)); - } - status = -EPERM; - } - /* - * In any case, flush the TLB - * This is called from here instead from pte_update to avoid unnecessary - * repetition while mapping non-contiguous physical regions of a virtual - * region - */ - flush_all(dev_context); - dev_dbg(bridge, "%s status %x\n", __func__, status); - return status; -} - -/* - * ======== bridge_brd_mem_un_map ======== - * Invalidate the PTEs for the DSP VA block to be unmapped. - * - * PTEs of a mapped memory block are contiguous in any page table - * So, instead of looking up the PTE address for every 4K block, - * we clear consecutive PTEs until we unmap all the bytes - */ -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, - u32 virt_addr, u32 ul_num_bytes) -{ - u32 l1_base_va; - u32 l2_base_va; - u32 l2_base_pa; - u32 l2_page_num; - u32 pte_val; - u32 pte_size; - u32 pte_count; - u32 pte_addr_l1; - u32 pte_addr_l2 = 0; - u32 rem_bytes; - u32 rem_bytes_l2; - u32 va_curr; - struct page *pg = NULL; - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - struct pg_table_attrs *pt = dev_context->pt_attrs; - u32 temp; - u32 paddr; - u32 numof4k_pages = 0; - - va_curr = virt_addr; - rem_bytes = ul_num_bytes; - rem_bytes_l2 = 0; - l1_base_va = pt->l1_base_va; - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr); - dev_dbg(bridge, "%s dev_ctxt %p, va %x, NumBytes %x l1_base_va %x, " - "pte_addr_l1 %x\n", __func__, dev_ctxt, virt_addr, - ul_num_bytes, l1_base_va, pte_addr_l1); - - while (rem_bytes && !status) { - u32 va_curr_orig = va_curr; - /* Find whether the L1 PTE points to a valid L2 PT */ - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr); - pte_val = *(u32 *) pte_addr_l1; - pte_size = hw_mmu_pte_size_l1(pte_val); - - if (pte_size != HW_MMU_COARSE_PAGE_SIZE) - goto skip_coarse_page; - - /* - * Get the L2 PA from the L1 PTE, and find - * corresponding L2 VA - */ - l2_base_pa = hw_mmu_pte_coarse_l1(pte_val); - l2_base_va = l2_base_pa - pt->l2_base_pa + pt->l2_base_va; - l2_page_num = - (l2_base_pa - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE; - /* - * Find the L2 PTE address from which we will start - * clearing, the number of PTEs to be cleared on this - * page, and the size of VA space that needs to be - * cleared on this L2 page - */ - pte_addr_l2 = hw_mmu_pte_addr_l2(l2_base_va, va_curr); - pte_count = pte_addr_l2 & (HW_MMU_COARSE_PAGE_SIZE - 1); - pte_count = (HW_MMU_COARSE_PAGE_SIZE - pte_count) / sizeof(u32); - if (rem_bytes < (pte_count * PG_SIZE4K)) - pte_count = rem_bytes / PG_SIZE4K; - rem_bytes_l2 = pte_count * PG_SIZE4K; - - /* - * Unmap the VA space on this L2 PT. A quicker way - * would be to clear pte_count entries starting from - * pte_addr_l2. However, below code checks that we don't - * clear invalid entries or less than 64KB for a 64KB - * entry. Similar checking is done for L1 PTEs too - * below - */ - while (rem_bytes_l2 && !status) { - pte_val = *(u32 *) pte_addr_l2; - pte_size = hw_mmu_pte_size_l2(pte_val); - /* va_curr aligned to pte_size? */ - if (pte_size == 0 || rem_bytes_l2 < pte_size || - va_curr & (pte_size - 1)) { - status = -EPERM; - break; - } - - /* Collect Physical addresses from VA */ - paddr = (pte_val & ~(pte_size - 1)); - if (pte_size == HW_PAGE_SIZE64KB) - numof4k_pages = 16; - else - numof4k_pages = 1; - temp = 0; - while (temp++ < numof4k_pages) { - if (!pfn_valid(__phys_to_pfn(paddr))) { - paddr += HW_PAGE_SIZE4KB; - continue; - } - pg = PHYS_TO_PAGE(paddr); - if (page_count(pg) < 1) { - pr_info("DSPBRIDGE: UNMAP function: " - "COUNT 0 FOR PA 0x%x, size = " - "0x%x\n", paddr, ul_num_bytes); - bad_page_dump(paddr, pg); - } else { - set_page_dirty(pg); - page_cache_release(pg); - } - paddr += HW_PAGE_SIZE4KB; - } - if (hw_mmu_pte_clear(pte_addr_l2, va_curr, pte_size)) { - status = -EPERM; - goto EXIT_LOOP; - } - - status = 0; - rem_bytes_l2 -= pte_size; - va_curr += pte_size; - pte_addr_l2 += (pte_size >> 12) * sizeof(u32); - } - spin_lock(&pt->pg_lock); - if (rem_bytes_l2 == 0) { - pt->pg_info[l2_page_num].num_entries -= pte_count; - if (pt->pg_info[l2_page_num].num_entries == 0) { - /* - * Clear the L1 PTE pointing to the L2 PT - */ - if (!hw_mmu_pte_clear(l1_base_va, va_curr_orig, - HW_MMU_COARSE_PAGE_SIZE)) - status = 0; - else { - status = -EPERM; - spin_unlock(&pt->pg_lock); - goto EXIT_LOOP; - } - } - rem_bytes -= pte_count * PG_SIZE4K; - } else - status = -EPERM; - - spin_unlock(&pt->pg_lock); - continue; -skip_coarse_page: - /* va_curr aligned to pte_size? */ - /* pte_size = 1 MB or 16 MB */ - if (pte_size == 0 || rem_bytes < pte_size || - va_curr & (pte_size - 1)) { - status = -EPERM; - break; - } - - if (pte_size == HW_PAGE_SIZE1MB) - numof4k_pages = 256; - else - numof4k_pages = 4096; - temp = 0; - /* Collect Physical addresses from VA */ - paddr = (pte_val & ~(pte_size - 1)); - while (temp++ < numof4k_pages) { - if (pfn_valid(__phys_to_pfn(paddr))) { - pg = PHYS_TO_PAGE(paddr); - if (page_count(pg) < 1) { - pr_info("DSPBRIDGE: UNMAP function: " - "COUNT 0 FOR PA 0x%x, size = " - "0x%x\n", paddr, ul_num_bytes); - bad_page_dump(paddr, pg); - } else { - set_page_dirty(pg); - page_cache_release(pg); - } - } - paddr += HW_PAGE_SIZE4KB; - } - if (!hw_mmu_pte_clear(l1_base_va, va_curr, pte_size)) { - status = 0; - rem_bytes -= pte_size; - va_curr += pte_size; - } else { - status = -EPERM; - goto EXIT_LOOP; - } - } - /* - * It is better to flush the TLB here, so that any stale old entries - * get flushed - */ -EXIT_LOOP: - flush_all(dev_context); - dev_dbg(bridge, - "%s: va_curr %x, pte_addr_l1 %x pte_addr_l2 %x rem_bytes %x," - " rem_bytes_l2 %x status %x\n", __func__, va_curr, pte_addr_l1, - pte_addr_l2, rem_bytes, rem_bytes_l2, status); - return status; -} - -/* - * ======== user_va2_pa ======== - * Purpose: - * This function walks through the page tables to convert a userland - * virtual address to physical address - */ -static u32 user_va2_pa(struct mm_struct *mm, u32 address) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *ptep, pte; - - pgd = pgd_offset(mm, address); - if (pgd_none(*pgd) || pgd_bad(*pgd)) - return 0; - - pud = pud_offset(pgd, address); - if (pud_none(*pud) || pud_bad(*pud)) - return 0; - - pmd = pmd_offset(pud, address); - if (pmd_none(*pmd) || pmd_bad(*pmd)) - return 0; - - ptep = pte_offset_map(pmd, address); - if (ptep) { - pte = *ptep; - if (pte_present(pte)) - return pte & PAGE_MASK; - } - - return 0; -} - -/* - * ======== pte_update ======== - * This function calculates the optimum page-aligned addresses and sizes - * Caller must pass page-aligned values - */ -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, - u32 va, u32 size, - struct hw_mmu_map_attrs_t *map_attrs) -{ - u32 i; - u32 all_bits; - u32 pa_curr = pa; - u32 va_curr = va; - u32 num_bytes = size; - struct bridge_dev_context *dev_context = dev_ctxt; - int status = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; - - while (num_bytes && !status) { - /* To find the max. page size with which both PA & VA are - * aligned */ - all_bits = pa_curr | va_curr; - - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & - (page_size[i] - - 1)) == 0)) { - status = - pte_set(dev_context->pt_attrs, pa_curr, - va_curr, page_size[i], map_attrs); - pa_curr += page_size[i]; - va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* Don't try smaller sizes. Hopefully we have - * reached an address aligned to a bigger page - * size */ - break; - } - } - } - - return status; -} - -/* - * ======== pte_set ======== - * This function calculates PTE address (MPU virtual) to be updated - * It also manages the L2 page tables - */ -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs) -{ - u32 i; - u32 pte_val; - u32 pte_addr_l1; - u32 pte_size; - /* Base address of the PT that will be updated */ - u32 pg_tbl_va; - u32 l1_base_va; - /* Compiler warns that the next three variables might be used - * uninitialized in this function. Doesn't seem so. Working around, - * anyways. */ - u32 l2_base_va = 0; - u32 l2_base_pa = 0; - u32 l2_page_num = 0; - int status = 0; - - l1_base_va = pt->l1_base_va; - pg_tbl_va = l1_base_va; - if ((size == HW_PAGE_SIZE64KB) || (size == HW_PAGE_SIZE4KB)) { - /* Find whether the L1 PTE points to a valid L2 PT */ - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va); - if (pte_addr_l1 <= (pt->l1_base_va + pt->l1_size)) { - pte_val = *(u32 *) pte_addr_l1; - pte_size = hw_mmu_pte_size_l1(pte_val); - } else { - return -EPERM; - } - spin_lock(&pt->pg_lock); - if (pte_size == HW_MMU_COARSE_PAGE_SIZE) { - /* Get the L2 PA from the L1 PTE, and find - * corresponding L2 VA */ - l2_base_pa = hw_mmu_pte_coarse_l1(pte_val); - l2_base_va = - l2_base_pa - pt->l2_base_pa + pt->l2_base_va; - l2_page_num = - (l2_base_pa - - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE; - } else if (pte_size == 0) { - /* L1 PTE is invalid. Allocate a L2 PT and - * point the L1 PTE to it */ - /* Find a free L2 PT. */ - for (i = 0; (i < pt->l2_num_pages) && - (pt->pg_info[i].num_entries != 0); i++) - ; - if (i < pt->l2_num_pages) { - l2_page_num = i; - l2_base_pa = pt->l2_base_pa + (l2_page_num * - HW_MMU_COARSE_PAGE_SIZE); - l2_base_va = pt->l2_base_va + (l2_page_num * - HW_MMU_COARSE_PAGE_SIZE); - /* Endianness attributes are ignored for - * HW_MMU_COARSE_PAGE_SIZE */ - status = - hw_mmu_pte_set(l1_base_va, l2_base_pa, va, - HW_MMU_COARSE_PAGE_SIZE, - attrs); - } else { - status = -ENOMEM; - } - } else { - /* Found valid L1 PTE of another size. - * Should not overwrite it. */ - status = -EPERM; - } - if (!status) { - pg_tbl_va = l2_base_va; - if (size == HW_PAGE_SIZE64KB) - pt->pg_info[l2_page_num].num_entries += 16; - else - pt->pg_info[l2_page_num].num_entries++; - dev_dbg(bridge, "PTE: L2 BaseVa %x, BasePa %x, PageNum " - "%x, num_entries %x\n", l2_base_va, - l2_base_pa, l2_page_num, - pt->pg_info[l2_page_num].num_entries); - } - spin_unlock(&pt->pg_lock); - } - if (!status) { - dev_dbg(bridge, "PTE: pg_tbl_va %x, pa %x, va %x, size %x\n", - pg_tbl_va, pa, va, size); - dev_dbg(bridge, "PTE: endianism %x, element_size %x, " - "mixed_size %x\n", attrs->endianism, - attrs->element_size, attrs->mixed_size); - status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs); - } - - return status; -} - -/* Memory map kernel VA -- memory allocated with vmalloc */ -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs) -{ - int status = 0; - struct page *page[1]; - u32 i; - u32 pa_curr; - u32 pa_next; - u32 va_curr; - u32 size_curr; - u32 num_pages; - u32 pa; - u32 num_of4k_pages; - u32 temp = 0; - - /* - * Do Kernel va to pa translation. - * Combine physically contiguous regions to reduce TLBs. - * Pass the translated pa to pte_update. - */ - num_pages = ul_num_bytes / PAGE_SIZE; /* PAGE_SIZE = OS page size */ - i = 0; - va_curr = ul_mpu_addr; - page[0] = vmalloc_to_page((void *)va_curr); - pa_next = page_to_phys(page[0]); - while (!status && (i < num_pages)) { - /* - * Reuse pa_next from the previous iteration to avoid - * an extra va2pa call - */ - pa_curr = pa_next; - size_curr = PAGE_SIZE; - /* - * If the next page is physically contiguous, - * map it with the current one by increasing - * the size of the region to be mapped - */ - while (++i < num_pages) { - page[0] = - vmalloc_to_page((void *)(va_curr + size_curr)); - pa_next = page_to_phys(page[0]); - - if (pa_next == (pa_curr + size_curr)) - size_curr += PAGE_SIZE; - else - break; - - } - if (pa_next == 0) { - status = -ENOMEM; - break; - } - pa = pa_curr; - num_of4k_pages = size_curr / HW_PAGE_SIZE4KB; - while (temp++ < num_of4k_pages) { - get_page(PHYS_TO_PAGE(pa)); - pa += HW_PAGE_SIZE4KB; - } - status = pte_update(dev_context, pa_curr, virt_addr + - (va_curr - ul_mpu_addr), size_curr, - hw_attrs); - va_curr += size_curr; - } - /* - * In any case, flush the TLB - * This is called from here instead from pte_update to avoid unnecessary - * repetition while mapping non-contiguous physical regions of a virtual - * region - */ - flush_all(dev_context); - dev_dbg(bridge, "%s status %x\n", __func__, status); - return status; -} - -/* - * ======== wait_for_start ======== - * Wait for the singal from DSP that it has started, or time out. - */ -bool wait_for_start(struct bridge_dev_context *dev_context, - void __iomem *sync_addr) -{ - u16 timeout = TIHELEN_ACKTIMEOUT; - - /* Wait for response from board */ - while (__raw_readw(sync_addr) && --timeout) - udelay(10); - - /* If timed out: return false */ - if (!timeout) { - pr_err("%s: Timed out waiting DSP to Start\n", __func__); - return false; - } - return true; -} diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c deleted file mode 100644 index 657104f37f7..00000000000 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * tiomap_pwr.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implementation of DSP wake/sleep routines. - * - * Copyright (C) 2007-2008 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/platform_data/dsp-omap.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> -#include <dspbridge/drv.h> -#include <dspbridge/io_sm.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/brddefs.h> -#include <dspbridge/dev.h> -#include <dspbridge/io.h> - -/* ------------------------------------ Hardware Abstraction Layer */ -#include <hw_defs.h> -#include <hw_mmu.h> - -#include <dspbridge/pwr.h> - -/* ----------------------------------- Bridge Driver */ -#include <dspbridge/dspdeh.h> -#include <dspbridge/wdt.h> - -/* ----------------------------------- specific to this file */ -#include "_tiomap.h" -#include "_tiomap_pwr.h" -#include <mach-omap2/prm-regbits-34xx.h> -#include <mach-omap2/cm-regbits-34xx.h> - -#define PWRSTST_TIMEOUT 200 - -/* - * ======== handle_constraints_set ======== - * Sets new DSP constraint - */ -int handle_constraints_set(struct bridge_dev_context *dev_context, - void *pargs) -{ -#ifdef CONFIG_TIDSPBRIDGE_DVFS - u32 *constraint_val; - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - constraint_val = (u32 *) (pargs); - /* Read the target value requested by DSP */ - dev_dbg(bridge, "OPP: %s opp requested = 0x%x\n", __func__, - (u32) *(constraint_val + 1)); - - /* Set the new opp value */ - if (pdata->dsp_set_min_opp) - (*pdata->dsp_set_min_opp) ((u32) *(constraint_val + 1)); -#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */ - return 0; -} - -/* - * ======== handle_hibernation_from_dsp ======== - * Handle Hibernation requested from DSP - */ -int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context) -{ - int status = 0; -#ifdef CONFIG_PM - u16 timeout = PWRSTST_TIMEOUT / 10; - u32 pwr_state; -#ifdef CONFIG_TIDSPBRIDGE_DVFS - u32 opplevel; - struct io_mgr *hio_mgr; -#endif - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) & - OMAP_POWERSTATEST_MASK; - /* Wait for DSP to move into OFF state */ - while ((pwr_state != PWRDM_POWER_OFF) && --timeout) { - if (msleep_interruptible(10)) { - pr_err("Waiting for DSP OFF mode interrupted\n"); - return -EPERM; - } - pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, - OMAP2_PM_PWSTST) & - OMAP_POWERSTATEST_MASK; - } - if (timeout == 0) { - pr_err("%s: Timed out waiting for DSP off mode\n", __func__); - status = -ETIMEDOUT; - return status; - } else { - - /* Save mailbox settings */ - omap_mbox_save_ctx(dev_context->mbox); - - /* Turn off DSP Peripheral clocks and DSP Load monitor timer */ - status = dsp_clock_disable_all(dev_context->dsp_per_clks); - - /* Disable wdt on hibernation. */ - dsp_wdt_enable(false); - - if (!status) { - /* Update the Bridger Driver state */ - dev_context->brd_state = BRD_DSP_HIBERNATION; -#ifdef CONFIG_TIDSPBRIDGE_DVFS - status = - dev_get_io_mgr(dev_context->dev_obj, &hio_mgr); - if (!hio_mgr) { - status = DSP_EHANDLE; - return status; - } - io_sh_msetting(hio_mgr, SHM_GETOPP, &opplevel); - - /* - * Set the OPP to low level before moving to OFF - * mode - */ - if (pdata->dsp_set_min_opp) - (*pdata->dsp_set_min_opp) (VDD1_OPP1); - status = 0; -#endif /* CONFIG_TIDSPBRIDGE_DVFS */ - } - } -#endif - return status; -} - -/* - * ======== sleep_dsp ======== - * Put DSP in low power consuming state. - */ -int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd, - void *pargs) -{ - int status = 0; -#ifdef CONFIG_PM -#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR - struct deh_mgr *hdeh_mgr; -#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */ - u16 timeout = PWRSTST_TIMEOUT / 10; - u32 pwr_state, target_pwr_state; - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - /* Check if sleep code is valid */ - if ((dw_cmd != PWR_DEEPSLEEP) && (dw_cmd != PWR_EMERGENCYDEEPSLEEP)) - return -EINVAL; - - switch (dev_context->brd_state) { - case BRD_RUNNING: - omap_mbox_save_ctx(dev_context->mbox); - if (dsp_test_sleepstate == PWRDM_POWER_OFF) { - sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE); - dev_dbg(bridge, "PM: %s - sent hibernate cmd to DSP\n", - __func__); - target_pwr_state = PWRDM_POWER_OFF; - } else { - sm_interrupt_dsp(dev_context, MBX_PM_DSPRETENTION); - target_pwr_state = PWRDM_POWER_RET; - } - break; - case BRD_RETENTION: - omap_mbox_save_ctx(dev_context->mbox); - if (dsp_test_sleepstate == PWRDM_POWER_OFF) { - sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE); - target_pwr_state = PWRDM_POWER_OFF; - } else - return 0; - break; - case BRD_HIBERNATION: - case BRD_DSP_HIBERNATION: - /* Already in Hibernation, so just return */ - dev_dbg(bridge, "PM: %s - DSP already in hibernation\n", - __func__); - return 0; - case BRD_STOPPED: - dev_dbg(bridge, "PM: %s - Board in STOP state\n", __func__); - return 0; - default: - dev_dbg(bridge, "PM: %s - Bridge in Illegal state\n", __func__); - return -EPERM; - } - - /* Get the PRCM DSP power domain status */ - pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) & - OMAP_POWERSTATEST_MASK; - - /* Wait for DSP to move into target power state */ - while ((pwr_state != target_pwr_state) && --timeout) { - if (msleep_interruptible(10)) { - pr_err("Waiting for DSP to Suspend interrupted\n"); - return -EPERM; - } - pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, - OMAP2_PM_PWSTST) & - OMAP_POWERSTATEST_MASK; - } - - if (!timeout) { - pr_err("%s: Timed out waiting for DSP off mode, state %x\n", - __func__, pwr_state); -#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR - dev_get_deh_mgr(dev_context->dev_obj, &hdeh_mgr); - bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0); -#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */ - return -ETIMEDOUT; - } else { - /* Update the Bridger Driver state */ - if (dsp_test_sleepstate == PWRDM_POWER_OFF) - dev_context->brd_state = BRD_HIBERNATION; - else - dev_context->brd_state = BRD_RETENTION; - - /* Disable wdt on hibernation. */ - dsp_wdt_enable(false); - - /* Turn off DSP Peripheral clocks */ - status = dsp_clock_disable_all(dev_context->dsp_per_clks); - if (status) - return status; -#ifdef CONFIG_TIDSPBRIDGE_DVFS - else if (target_pwr_state == PWRDM_POWER_OFF) { - /* - * Set the OPP to low level before moving to OFF mode - */ - if (pdata->dsp_set_min_opp) - (*pdata->dsp_set_min_opp) (VDD1_OPP1); - } -#endif /* CONFIG_TIDSPBRIDGE_DVFS */ - } -#endif /* CONFIG_PM */ - return status; -} - -/* - * ======== wake_dsp ======== - * Wake up DSP from sleep. - */ -int wake_dsp(struct bridge_dev_context *dev_context, void *pargs) -{ - int status = 0; -#ifdef CONFIG_PM - - /* Check the board state, if it is not 'SLEEP' then return */ - if (dev_context->brd_state == BRD_RUNNING || - dev_context->brd_state == BRD_STOPPED) { - /* The Device is in 'RET' or 'OFF' state and Bridge state is not - * 'SLEEP', this means state inconsistency, so return */ - return 0; - } - - /* Send a wakeup message to DSP */ - sm_interrupt_dsp(dev_context, MBX_PM_DSPWAKEUP); - - /* Set the device state to RUNNIG */ - dev_context->brd_state = BRD_RUNNING; -#endif /* CONFIG_PM */ - return status; -} - -/* - * ======== dsp_peripheral_clk_ctrl ======== - * Enable/Disable the DSP peripheral clocks as needed.. - */ -int dsp_peripheral_clk_ctrl(struct bridge_dev_context *dev_context, - void *pargs) -{ - u32 ext_clk = 0; - u32 ext_clk_id = 0; - u32 ext_clk_cmd = 0; - u32 clk_id_index = MBX_PM_MAX_RESOURCES; - u32 tmp_index; - u32 dsp_per_clks_before; - int status = 0; - - dsp_per_clks_before = dev_context->dsp_per_clks; - - ext_clk = (u32) *((u32 *) pargs); - ext_clk_id = ext_clk & MBX_PM_CLK_IDMASK; - - /* process the power message -- TODO, keep it in a separate function */ - for (tmp_index = 0; tmp_index < MBX_PM_MAX_RESOURCES; tmp_index++) { - if (ext_clk_id == bpwr_clkid[tmp_index]) { - clk_id_index = tmp_index; - break; - } - } - /* TODO -- Assert may be a too hard restriction here.. May be we should - * just return with failure when the CLK ID does not match */ - if (clk_id_index == MBX_PM_MAX_RESOURCES) { - /* return with a more meaningfull error code */ - return -EPERM; - } - ext_clk_cmd = (ext_clk >> MBX_PM_CLK_CMDSHIFT) & MBX_PM_CLK_CMDMASK; - switch (ext_clk_cmd) { - case BPWR_DISABLE_CLOCK: - status = dsp_clk_disable(bpwr_clks[clk_id_index].clk); - dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id, - false); - if (!status) { - (dev_context->dsp_per_clks) &= - (~((u32) (1 << bpwr_clks[clk_id_index].clk))); - } - break; - case BPWR_ENABLE_CLOCK: - status = dsp_clk_enable(bpwr_clks[clk_id_index].clk); - dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id, true); - if (!status) - (dev_context->dsp_per_clks) |= - (1 << bpwr_clks[clk_id_index].clk); - break; - default: - dev_dbg(bridge, "%s: Unsupported CMD\n", __func__); - /* unsupported cmd */ - /* TODO -- provide support for AUTOIDLE Enable/Disable - * commands */ - } - return status; -} - -/* - * ========pre_scale_dsp======== - * Sends prescale notification to DSP - * - */ -int pre_scale_dsp(struct bridge_dev_context *dev_context, void *pargs) -{ -#ifdef CONFIG_TIDSPBRIDGE_DVFS - u32 level; - u32 voltage_domain; - - voltage_domain = *((u32 *) pargs); - level = *((u32 *) pargs + 1); - - dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n", - __func__, voltage_domain, level); - if ((dev_context->brd_state == BRD_HIBERNATION) || - (dev_context->brd_state == BRD_RETENTION) || - (dev_context->brd_state == BRD_DSP_HIBERNATION)) { - dev_dbg(bridge, "OPP: %s IVA in sleep. No message to DSP\n"); - return 0; - } else if (dev_context->brd_state == BRD_RUNNING) { - /* Send a prenotification to DSP */ - dev_dbg(bridge, "OPP: %s sent notification to DSP\n", __func__); - sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_PRENOTIFY); - return 0; - } else { - return -EPERM; - } -#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */ - return 0; -} - -/* - * ========post_scale_dsp======== - * Sends postscale notification to DSP - * - */ -int post_scale_dsp(struct bridge_dev_context *dev_context, - void *pargs) -{ - int status = 0; -#ifdef CONFIG_TIDSPBRIDGE_DVFS - u32 level; - u32 voltage_domain; - struct io_mgr *hio_mgr; - - status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr); - if (!hio_mgr) - return -EFAULT; - - voltage_domain = *((u32 *) pargs); - level = *((u32 *) pargs + 1); - dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n", - __func__, voltage_domain, level); - if ((dev_context->brd_state == BRD_HIBERNATION) || - (dev_context->brd_state == BRD_RETENTION) || - (dev_context->brd_state == BRD_DSP_HIBERNATION)) { - /* Update the OPP value in shared memory */ - io_sh_msetting(hio_mgr, SHM_CURROPP, &level); - dev_dbg(bridge, "OPP: %s IVA in sleep. Wrote to shm\n", - __func__); - } else if (dev_context->brd_state == BRD_RUNNING) { - /* Update the OPP value in shared memory */ - io_sh_msetting(hio_mgr, SHM_CURROPP, &level); - /* Send a post notification to DSP */ - sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_POSTNOTIFY); - dev_dbg(bridge, - "OPP: %s wrote to shm. Sent post notification to DSP\n", - __func__); - } else { - status = -EPERM; - } -#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */ - return status; -} - -void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) -{ - struct cfg_hostres *resources; - int status = 0; - u32 iva2_grpsel; - u32 mpu_grpsel; - struct dev_object *hdev_object = NULL; - struct bridge_dev_context *bridge_context = NULL; - - hdev_object = (struct dev_object *)drv_get_first_dev_object(); - if (!hdev_object) - return; - - status = dev_get_bridge_context(hdev_object, &bridge_context); - if (!bridge_context) - return; - - resources = bridge_context->resources; - if (!resources) - return; - - switch (clock_id) { - case BPWR_GP_TIMER5: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_GPT5_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_GPT5_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - case BPWR_GP_TIMER6: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_GPT6_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_GPT6_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - case BPWR_GP_TIMER7: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_GPT7_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_GPT7_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - case BPWR_GP_TIMER8: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_GPT8_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_GPT8_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - case BPWR_MCBSP1: - iva2_grpsel = readl(resources->core_pm_base + 0xA8); - mpu_grpsel = readl(resources->core_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK; - } - writel(iva2_grpsel, resources->core_pm_base + 0xA8); - writel(mpu_grpsel, resources->core_pm_base + 0xA4); - break; - case BPWR_MCBSP2: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - case BPWR_MCBSP3: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - case BPWR_MCBSP4: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - case BPWR_MCBSP5: - iva2_grpsel = readl(resources->per_pm_base + 0xA8); - mpu_grpsel = readl(resources->per_pm_base + 0xA4); - if (enable) { - iva2_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK; - mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK; - } else { - mpu_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK; - iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK; - } - writel(iva2_grpsel, resources->per_pm_base + 0xA8); - writel(mpu_grpsel, resources->per_pm_base + 0xA4); - break; - } -} diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c deleted file mode 100644 index f53ed98d18c..00000000000 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * tiomap_io.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implementation for the io read/write routines. - * - * 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. - */ - -#include <linux/platform_data/dsp-omap.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> -#include <dspbridge/drv.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/wdt.h> - -/* ----------------------------------- specific to this file */ -#include "_tiomap.h" -#include "_tiomap_pwr.h" -#include "tiomap_io.h" - -static u32 ul_ext_base; -static u32 ul_ext_end; - -static u32 shm0_end; -static u32 ul_dyn_ext_base; -static u32 ul_trace_sec_beg; -static u32 ul_trace_sec_end; -static u32 ul_shm_base_virt; - -bool symbols_reloaded = true; - -/* - * ======== read_ext_dsp_data ======== - * Copies DSP external memory buffers to the host side buffers. - */ -int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type) -{ - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - u32 offset; - u32 ul_tlb_base_virt = 0; - u32 ul_shm_offset_virt = 0; - u32 dw_ext_prog_virt_mem; - u32 dw_base_addr = dev_context->dsp_ext_base_addr; - bool trace_read = false; - - if (!ul_shm_base_virt) { - status = dev_get_symbol(dev_context->dev_obj, - SHMBASENAME, &ul_shm_base_virt); - } - - /* Check if it is a read of Trace section */ - if (!status && !ul_trace_sec_beg) { - status = dev_get_symbol(dev_context->dev_obj, - DSP_TRACESEC_BEG, &ul_trace_sec_beg); - } - - if (!status && !ul_trace_sec_end) { - status = dev_get_symbol(dev_context->dev_obj, - DSP_TRACESEC_END, &ul_trace_sec_end); - } - - if (!status) { - if ((dsp_addr <= ul_trace_sec_end) && - (dsp_addr >= ul_trace_sec_beg)) - trace_read = true; - } - - /* If reading from TRACE, force remap/unmap */ - if (trace_read && dw_base_addr) { - dw_base_addr = 0; - dev_context->dsp_ext_base_addr = 0; - } - - if (!dw_base_addr) { - /* Initialize ul_ext_base and ul_ext_end */ - ul_ext_base = 0; - ul_ext_end = 0; - - /* Get DYNEXT_BEG, EXT_BEG and EXT_END. */ - if (!status && !ul_dyn_ext_base) { - status = dev_get_symbol(dev_context->dev_obj, - DYNEXTBASE, &ul_dyn_ext_base); - } - - if (!status) { - status = dev_get_symbol(dev_context->dev_obj, - EXTBASE, &ul_ext_base); - } - - if (!status) { - status = dev_get_symbol(dev_context->dev_obj, - EXTEND, &ul_ext_end); - } - - /* Trace buffer is right after the shm SEG0, - * so set the base address to SHMBASE */ - if (trace_read) { - ul_ext_base = ul_shm_base_virt; - ul_ext_end = ul_trace_sec_end; - } - - - if (ul_ext_end < ul_ext_base) - status = -EPERM; - - if (!status) { - ul_tlb_base_virt = - dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE; - dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].gpp_va; - - if (!trace_read) { - ul_shm_offset_virt = - ul_shm_base_virt - ul_tlb_base_virt; - ul_shm_offset_virt += - PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base + - 1, HW_PAGE_SIZE64KB); - dw_ext_prog_virt_mem -= ul_shm_offset_virt; - dw_ext_prog_virt_mem += - (ul_ext_base - ul_dyn_ext_base); - dev_context->dsp_ext_base_addr = - dw_ext_prog_virt_mem; - - /* - * This dsp_ext_base_addr will get cleared - * only when the board is stopped. - */ - if (!dev_context->dsp_ext_base_addr) - status = -EPERM; - } - - dw_base_addr = dw_ext_prog_virt_mem; - } - } - - if (!dw_base_addr || !ul_ext_base || !ul_ext_end) - status = -EPERM; - - offset = dsp_addr - ul_ext_base; - - if (!status) - memcpy(host_buff, (u8 *) dw_base_addr + offset, ul_num_bytes); - - return status; -} - -/* - * ======== write_dsp_data ======== - * purpose: - * Copies buffers to the DSP internal/external memory. - */ -int write_dsp_data(struct bridge_dev_context *dev_context, - u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes, - u32 mem_type) -{ - u32 offset; - u32 dw_base_addr = dev_context->dsp_base_addr; - struct cfg_hostres *resources = dev_context->resources; - int status = 0; - u32 base1, base2, base3; - base1 = OMAP_DSP_MEM1_SIZE; - base2 = OMAP_DSP_MEM2_BASE - OMAP_DSP_MEM1_BASE; - base3 = OMAP_DSP_MEM3_BASE - OMAP_DSP_MEM1_BASE; - - if (!resources) - return -EPERM; - - offset = dsp_addr - dev_context->dsp_start_add; - if (offset < base1) { - dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[2], - resources->mem_length[2]); - } else if (offset > base1 && offset < base2 + OMAP_DSP_MEM2_SIZE) { - dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[3], - resources->mem_length[3]); - offset = offset - base2; - } else if (offset >= base2 + OMAP_DSP_MEM2_SIZE && - offset < base3 + OMAP_DSP_MEM3_SIZE) { - dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[4], - resources->mem_length[4]); - offset = offset - base3; - } else { - return -EPERM; - } - if (ul_num_bytes) - memcpy((u8 *) (dw_base_addr + offset), host_buff, ul_num_bytes); - else - *((u32 *) host_buff) = dw_base_addr + offset; - - return status; -} - -/* - * ======== write_ext_dsp_data ======== - * purpose: - * Copies buffers to the external memory. - * - */ -int write_ext_dsp_data(struct bridge_dev_context *dev_context, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type, - bool dynamic_load) -{ - u32 dw_base_addr = dev_context->dsp_ext_base_addr; - u32 dw_offset = 0; - u8 temp_byte1, temp_byte2; - u8 remain_byte[4]; - s32 i; - int ret = 0; - u32 dw_ext_prog_virt_mem; - u32 ul_tlb_base_virt = 0; - u32 ul_shm_offset_virt = 0; - struct cfg_hostres *host_res = dev_context->resources; - bool trace_load = false; - temp_byte1 = 0x0; - temp_byte2 = 0x0; - - if (symbols_reloaded) { - /* Check if it is a load to Trace section */ - ret = dev_get_symbol(dev_context->dev_obj, - DSP_TRACESEC_BEG, &ul_trace_sec_beg); - if (!ret) - ret = dev_get_symbol(dev_context->dev_obj, - DSP_TRACESEC_END, - &ul_trace_sec_end); - } - if (!ret) { - if ((dsp_addr <= ul_trace_sec_end) && - (dsp_addr >= ul_trace_sec_beg)) - trace_load = true; - } - - /* If dynamic, force remap/unmap */ - if ((dynamic_load || trace_load) && dw_base_addr) { - dw_base_addr = 0; - MEM_UNMAP_LINEAR_ADDRESS((void *) - dev_context->dsp_ext_base_addr); - dev_context->dsp_ext_base_addr = 0x0; - } - if (!dw_base_addr) { - if (symbols_reloaded) - /* Get SHM_BEG EXT_BEG and EXT_END. */ - ret = dev_get_symbol(dev_context->dev_obj, - SHMBASENAME, &ul_shm_base_virt); - if (dynamic_load) { - if (!ret) { - if (symbols_reloaded) - ret = - dev_get_symbol - (dev_context->dev_obj, DYNEXTBASE, - &ul_ext_base); - } - if (!ret) { - /* DR OMAPS00013235 : DLModules array may be - * in EXTMEM. It is expected that DYNEXTMEM and - * EXTMEM are contiguous, so checking for the - * upper bound at EXTEND should be Ok. */ - if (symbols_reloaded) - ret = - dev_get_symbol - (dev_context->dev_obj, EXTEND, - &ul_ext_end); - } - } else { - if (symbols_reloaded) { - if (!ret) - ret = - dev_get_symbol - (dev_context->dev_obj, EXTBASE, - &ul_ext_base); - if (!ret) - ret = - dev_get_symbol - (dev_context->dev_obj, EXTEND, - &ul_ext_end); - } - } - /* Trace buffer it right after the shm SEG0, so set the - * base address to SHMBASE */ - if (trace_load) - ul_ext_base = ul_shm_base_virt; - - if (ul_ext_end < ul_ext_base) - ret = -EPERM; - - if (!ret) { - ul_tlb_base_virt = - dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE; - - if (symbols_reloaded) { - ret = dev_get_symbol - (dev_context->dev_obj, - DSP_TRACESEC_END, &shm0_end); - if (!ret) { - ret = - dev_get_symbol - (dev_context->dev_obj, DYNEXTBASE, - &ul_dyn_ext_base); - } - } - ul_shm_offset_virt = - ul_shm_base_virt - ul_tlb_base_virt; - if (trace_load) { - dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].gpp_va; - } else { - dw_ext_prog_virt_mem = host_res->mem_base[1]; - dw_ext_prog_virt_mem += - (ul_ext_base - ul_dyn_ext_base); - } - - dev_context->dsp_ext_base_addr = - (u32) MEM_LINEAR_ADDRESS((void *) - dw_ext_prog_virt_mem, - ul_ext_end - ul_ext_base); - dw_base_addr += dev_context->dsp_ext_base_addr; - /* This dsp_ext_base_addr will get cleared only when - * the board is stopped. */ - if (!dev_context->dsp_ext_base_addr) - ret = -EPERM; - } - } - if (!dw_base_addr || !ul_ext_base || !ul_ext_end) - ret = -EPERM; - - if (!ret) { - for (i = 0; i < 4; i++) - remain_byte[i] = 0x0; - - dw_offset = dsp_addr - ul_ext_base; - /* Also make sure the dsp_addr is < ul_ext_end */ - if (dsp_addr > ul_ext_end || dw_offset > dsp_addr) - ret = -EPERM; - } - if (!ret) { - if (ul_num_bytes) - memcpy((u8 *) dw_base_addr + dw_offset, host_buff, - ul_num_bytes); - else - *((u32 *) host_buff) = dw_base_addr + dw_offset; - } - /* Unmap here to force remap for other Ext loads */ - if ((dynamic_load || trace_load) && dev_context->dsp_ext_base_addr) { - MEM_UNMAP_LINEAR_ADDRESS((void *) - dev_context->dsp_ext_base_addr); - dev_context->dsp_ext_base_addr = 0x0; - } - symbols_reloaded = false; - return ret; -} - -int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) -{ -#ifdef CONFIG_TIDSPBRIDGE_DVFS - u32 opplevel = 0; -#endif - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - struct cfg_hostres *resources = dev_context->resources; - int status = 0; - u32 temp; - - if (!dev_context->mbox) - return 0; - - if (!resources) - return -EPERM; - - if (dev_context->brd_state == BRD_DSP_HIBERNATION || - dev_context->brd_state == BRD_HIBERNATION) { -#ifdef CONFIG_TIDSPBRIDGE_DVFS - if (pdata->dsp_get_opp) - opplevel = (*pdata->dsp_get_opp) (); - if (opplevel == VDD1_OPP1) { - if (pdata->dsp_set_min_opp) - (*pdata->dsp_set_min_opp) (VDD1_OPP2); - } -#endif - /* Restart the peripheral clocks */ - dsp_clock_enable_all(dev_context->dsp_per_clks); - dsp_wdt_enable(true); - - /* - * 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control - * in CM_AUTOIDLE_PLL_IVA2 register - */ - (*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT, - OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL); - - /* - * 7:4 IVA2_DPLL_FREQSEL - IVA2 internal frq set to - * 0.75 MHz - 1.0 MHz - * 2:0 EN_IVA2_DPLL - Enable IVA2 DPLL in lock mode - */ - (*pdata->dsp_cm_rmw_bits)(OMAP3430_IVA2_DPLL_FREQSEL_MASK | - OMAP3430_EN_IVA2_DPLL_MASK, - 0x3 << OMAP3430_IVA2_DPLL_FREQSEL_SHIFT | - 0x7 << OMAP3430_EN_IVA2_DPLL_SHIFT, - OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL); - - /* Restore mailbox settings */ - omap_mbox_restore_ctx(dev_context->mbox); - - /* Access MMU SYS CONFIG register to generate a short wakeup */ - temp = readl(resources->dmmu_base + 0x10); - - dev_context->brd_state = BRD_RUNNING; - } else if (dev_context->brd_state == BRD_RETENTION) { - /* Restart the peripheral clocks */ - dsp_clock_enable_all(dev_context->dsp_per_clks); - } - - status = omap_mbox_msg_send(dev_context->mbox, mb_val); - - if (status) { - pr_err("omap_mbox_msg_send Fail and status = %d\n", status); - status = -EPERM; - } - - return 0; -} diff --git a/drivers/staging/tidspbridge/core/tiomap_io.h b/drivers/staging/tidspbridge/core/tiomap_io.h deleted file mode 100644 index a3f19c7b79f..00000000000 --- a/drivers/staging/tidspbridge/core/tiomap_io.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * tiomap_io.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Definitions, types and function prototypes for the io (r/w external mem). - * - * 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 _TIOMAP_IO_ -#define _TIOMAP_IO_ - -/* - * Symbol that defines beginning of shared memory. - * For OMAP (Helen) this is the DSP Virtual base address of SDRAM. - * This will be used to program DSP MMU to map DSP Virt to GPP phys. - * (see dspMmuTlbEntry()). - */ -#define SHMBASENAME "SHM_BEG" -#define EXTBASE "EXT_BEG" -#define EXTEND "_EXT_END" -#define DYNEXTBASE "_DYNEXT_BEG" -#define DYNEXTEND "_DYNEXT_END" -#define IVAEXTMEMBASE "_IVAEXTMEM_BEG" -#define IVAEXTMEMEND "_IVAEXTMEM_END" - -#define DSP_TRACESEC_BEG "_BRIDGE_TRACE_BEG" -#define DSP_TRACESEC_END "_BRIDGE_TRACE_END" - -#define SYS_PUTCBEG "_SYS_PUTCBEG" -#define SYS_PUTCEND "_SYS_PUTCEND" -#define BRIDGE_SYS_PUTC_CURRENT "_BRIDGE_SYS_PUTC_current" - -#define WORDSWAP_ENABLE 0x3 /* Enable word swap */ - -/* - * ======== read_ext_dsp_data ======== - * Reads it from DSP External memory. The external memory for the DSP - * is configured by the combination of DSP MMU and shm Memory manager in the CDB - */ -extern int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type); - -/* - * ======== write_dsp_data ======== - */ -extern int write_dsp_data(struct bridge_dev_context *dev_context, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type); - -/* - * ======== write_ext_dsp_data ======== - * Writes to the DSP External memory for external program. - * The ext mem for progra is configured by the combination of DSP MMU and - * shm Memory manager in the CDB - */ -extern int write_ext_dsp_data(struct bridge_dev_context *dev_context, - u8 *host_buff, u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type, - bool dynamic_load); - -/* - * ======== write_ext32_bit_dsp_data ======== - * Writes 32 bit data to the external memory - */ -extern inline void write_ext32_bit_dsp_data(const - struct bridge_dev_context *dev_context, - u32 dsp_addr, u32 val) -{ - *(u32 *) dsp_addr = ((dev_context->tc_word_swap_on) ? (((val << 16) & - 0xFFFF0000) | - ((val >> 16) & - 0x0000FFFF)) : - val); -} - -/* - * ======== read_ext32_bit_dsp_data ======== - * Reads 32 bit data from the external memory - */ -extern inline u32 read_ext32_bit_dsp_data(const struct bridge_dev_context - *dev_context, u32 dsp_addr) -{ - u32 ret; - ret = *(u32 *) dsp_addr; - - ret = ((dev_context->tc_word_swap_on) ? (((ret << 16) - & 0xFFFF0000) | ((ret >> 16) & - 0x0000FFFF)) - : ret); - return ret; -} - -#endif /* _TIOMAP_IO_ */ diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c deleted file mode 100644 index e68f0ba8e12..00000000000 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * ue_deh.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implements upper edge DSP exception handling (DEH) functions. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * Copyright (C) 2010 Felipe Contreras - * - * 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. - */ - -#include <linux/kernel.h> -#include <linux/interrupt.h> - -#include <dspbridge/dbdefs.h> -#include <dspbridge/dspdeh.h> -#include <dspbridge/dev.h> -#include "_tiomap.h" -#include "_deh.h" - -#include <dspbridge/io_sm.h> -#include <dspbridge/drv.h> -#include <dspbridge/wdt.h> - -static u32 fault_addr; - -static void mmu_fault_dpc(unsigned long data) -{ - struct deh_mgr *deh = (void *)data; - - if (!deh) - return; - - bridge_deh_notify(deh, DSP_MMUFAULT, 0); -} - -static irqreturn_t mmu_fault_isr(int irq, void *data) -{ - struct deh_mgr *deh = data; - struct cfg_hostres *resources; - u32 event; - - if (!deh) - return IRQ_HANDLED; - - resources = deh->bridge_context->resources; - if (!resources) { - dev_dbg(bridge, "%s: Failed to get Host Resources\n", - __func__); - return IRQ_HANDLED; - } - - hw_mmu_event_status(resources->dmmu_base, &event); - if (event == HW_MMU_TRANSLATION_FAULT) { - hw_mmu_fault_addr_read(resources->dmmu_base, &fault_addr); - dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__, - event, fault_addr); - /* - * Schedule a DPC directly. In the future, it may be - * necessary to check if DSP MMU fault is intended for - * Bridge. - */ - tasklet_schedule(&deh->dpc_tasklet); - - /* Disable the MMU events, else once we clear it will - * start to raise INTs again */ - hw_mmu_event_disable(resources->dmmu_base, - HW_MMU_TRANSLATION_FAULT); - } else { - hw_mmu_event_disable(resources->dmmu_base, - HW_MMU_ALL_INTERRUPTS); - } - return IRQ_HANDLED; -} - -int bridge_deh_create(struct deh_mgr **ret_deh, - struct dev_object *hdev_obj) -{ - int status; - struct deh_mgr *deh; - struct bridge_dev_context *hbridge_context = NULL; - - /* Message manager will be created when a file is loaded, since - * size of message buffer in shared memory is configurable in - * the base image. */ - /* Get Bridge context info. */ - dev_get_bridge_context(hdev_obj, &hbridge_context); - /* Allocate IO manager object: */ - deh = kzalloc(sizeof(*deh), GFP_KERNEL); - if (!deh) { - status = -ENOMEM; - goto err; - } - - /* Create an NTFY object to manage notifications */ - deh->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL); - if (!deh->ntfy_obj) { - status = -ENOMEM; - goto err; - } - ntfy_init(deh->ntfy_obj); - - /* Create a MMUfault DPC */ - tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh); - - /* Fill in context structure */ - deh->bridge_context = hbridge_context; - - /* Install ISR function for DSP MMU fault */ - status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0, - "DspBridge\tiommu fault", deh); - if (status < 0) - goto err; - - *ret_deh = deh; - return 0; - -err: - bridge_deh_destroy(deh); - *ret_deh = NULL; - return status; -} - -int bridge_deh_destroy(struct deh_mgr *deh) -{ - if (!deh) - return -EFAULT; - - /* If notification object exists, delete it */ - if (deh->ntfy_obj) { - ntfy_delete(deh->ntfy_obj); - kfree(deh->ntfy_obj); - } - /* Disable DSP MMU fault */ - free_irq(INT_DSP_MMU_IRQ, deh); - - /* Free DPC object */ - tasklet_kill(&deh->dpc_tasklet); - - /* Deallocate the DEH manager object */ - kfree(deh); - - return 0; -} - -int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask, - u32 notify_type, - struct dsp_notification *hnotification) -{ - if (!deh) - return -EFAULT; - - if (event_mask) - return ntfy_register(deh->ntfy_obj, hnotification, - event_mask, notify_type); - else - return ntfy_unregister(deh->ntfy_obj, hnotification); -} - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) -{ - struct cfg_hostres *resources; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = HW_LITTLE_ENDIAN, - .element_size = HW_ELEM_SIZE16BIT, - .mixed_size = HW_MMU_CPUES, - }; - void *dummy_va_addr; - - resources = dev_context->resources; - dummy_va_addr = (void *)__get_free_page(GFP_ATOMIC); - - /* - * Before acking the MMU fault, let's make sure MMU can only - * access entry #0. Then add a new entry so that the DSP OS - * can continue in order to dump the stack. - */ - hw_mmu_twl_disable(resources->dmmu_base); - hw_mmu_tlb_flush_all(resources->dmmu_base); - - hw_mmu_tlb_add(resources->dmmu_base, - virt_to_phys(dummy_va_addr), fault_addr, - HW_PAGE_SIZE4KB, 1, - &map_attrs, HW_SET, HW_SET); - - dsp_clk_enable(DSP_CLK_GPT8); - - dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); - - /* Clear MMU interrupt */ - hw_mmu_event_ack(resources->dmmu_base, - HW_MMU_TRANSLATION_FAULT); - dump_dsp_stack(dev_context); - dsp_clk_disable(DSP_CLK_GPT8); - - hw_mmu_disable(resources->dmmu_base); - free_page((unsigned long)dummy_va_addr); -} -#endif - -static inline const char *event_to_string(int event) -{ - switch (event) { - case DSP_SYSERROR: return "DSP_SYSERROR"; break; - case DSP_MMUFAULT: return "DSP_MMUFAULT"; break; - case DSP_PWRERROR: return "DSP_PWRERROR"; break; - case DSP_WDTOVERFLOW: return "DSP_WDTOVERFLOW"; break; - default: return "unknown event"; break; - } -} - -void bridge_deh_notify(struct deh_mgr *deh, int event, int info) -{ - struct bridge_dev_context *dev_context; - const char *str = event_to_string(event); - - if (!deh) - return; - - dev_dbg(bridge, "%s: device exception", __func__); - dev_context = deh->bridge_context; - - switch (event) { - case DSP_SYSERROR: - dev_err(bridge, "%s: %s, info=0x%x", __func__, - str, info); -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE - dump_dl_modules(dev_context); - dump_dsp_stack(dev_context); -#endif - break; - case DSP_MMUFAULT: - dev_err(bridge, "%s: %s, addr=0x%x", __func__, - str, fault_addr); -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE - print_dsp_trace_buffer(dev_context); - dump_dl_modules(dev_context); - mmu_fault_print_stack(dev_context); -#endif - break; - default: - dev_err(bridge, "%s: %s", __func__, str); - break; - } - - /* Filter subsequent notifications when an error occurs */ - if (dev_context->brd_state != BRD_ERROR) { - ntfy_notify(deh->ntfy_obj, event); -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - bridge_recover_schedule(); -#endif - } - - /* Set the Board state as ERROR */ - dev_context->brd_state = BRD_ERROR; - /* Disable all the clocks that were enabled by DSP */ - dsp_clock_disable_all(dev_context->dsp_per_clks); - /* - * Avoid the subsequent WDT if it happens once, - * also if fatal error occurs. - */ - dsp_wdt_enable(false); -} diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c deleted file mode 100644 index c7ee467f0f1..00000000000 --- a/drivers/staging/tidspbridge/core/wdt.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * wdt.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * IO dispatcher for a shared memory channel driver. - * - * Copyright (C) 2010 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. - */ -#include <linux/types.h> - -#include <dspbridge/dbdefs.h> -#include <dspbridge/dspdeh.h> -#include <dspbridge/dev.h> -#include <dspbridge/_chnl_sm.h> -#include <dspbridge/wdt.h> -#include <dspbridge/host_os.h> - - -#define OMAP34XX_WDT3_BASE (0x49000000 + 0x30000) -#define INT_34XX_WDT3_IRQ (36 + NR_IRQS) - -static struct dsp_wdt_setting dsp_wdt; - -void dsp_wdt_dpc(unsigned long data) -{ - struct deh_mgr *deh_mgr; - dev_get_deh_mgr(dev_get_first(), &deh_mgr); - if (deh_mgr) - bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0); -} - -irqreturn_t dsp_wdt_isr(int irq, void *data) -{ - u32 value; - /* ack wdt3 interrupt */ - value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET); - __raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET); - - tasklet_schedule(&dsp_wdt.wdt3_tasklet); - return IRQ_HANDLED; -} - -int dsp_wdt_init(void) -{ - int ret = 0; - - dsp_wdt.sm_wdt = NULL; - dsp_wdt.reg_base = ioremap(OMAP34XX_WDT3_BASE, SZ_4K); - if (!dsp_wdt.reg_base) - return -ENOMEM; - - tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0); - - dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); - - if (!IS_ERR(dsp_wdt.fclk)) { - clk_prepare(dsp_wdt.fclk); - - dsp_wdt.iclk = clk_get(NULL, "wdt3_ick"); - if (IS_ERR(dsp_wdt.iclk)) { - clk_put(dsp_wdt.fclk); - dsp_wdt.fclk = NULL; - ret = -EFAULT; - } else { - clk_prepare(dsp_wdt.iclk); - } - } else - ret = -EFAULT; - - if (!ret) - ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0, - "dsp_wdt", &dsp_wdt); - - /* Disable at this moment, it will be enabled when DSP starts */ - if (!ret) - disable_irq(INT_34XX_WDT3_IRQ); - - return ret; -} - -void dsp_wdt_sm_set(void *data) -{ - dsp_wdt.sm_wdt = data; - dsp_wdt.sm_wdt->wdt_overflow = 5; /* in seconds */ -} - - -void dsp_wdt_exit(void) -{ - free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt); - tasklet_kill(&dsp_wdt.wdt3_tasklet); - - if (dsp_wdt.fclk) { - clk_unprepare(dsp_wdt.fclk); - clk_put(dsp_wdt.fclk); - } - if (dsp_wdt.iclk) { - clk_unprepare(dsp_wdt.iclk); - clk_put(dsp_wdt.iclk); - } - - dsp_wdt.fclk = NULL; - dsp_wdt.iclk = NULL; - dsp_wdt.sm_wdt = NULL; - - if (dsp_wdt.reg_base) - iounmap(dsp_wdt.reg_base); - dsp_wdt.reg_base = NULL; -} - -void dsp_wdt_enable(bool enable) -{ - u32 tmp; - static bool wdt_enable; - - if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk) - return; - - wdt_enable = enable; - - if (enable) { - clk_enable(dsp_wdt.fclk); - clk_enable(dsp_wdt.iclk); - dsp_wdt.sm_wdt->wdt_setclocks = 1; - tmp = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET); - __raw_writel(tmp, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET); - enable_irq(INT_34XX_WDT3_IRQ); - } else { - disable_irq(INT_34XX_WDT3_IRQ); - dsp_wdt.sm_wdt->wdt_setclocks = 0; - clk_disable(dsp_wdt.iclk); - clk_disable(dsp_wdt.fclk); - } -} diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c deleted file mode 100644 index 9d54744805b..00000000000 --- a/drivers/staging/tidspbridge/dynload/cload.c +++ /dev/null @@ -1,1952 +0,0 @@ -/* - * cload.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -#include <linux/slab.h> - -#include "header.h" - -#include "module_list.h" -#define LINKER_MODULES_HEADER ("_" MODULES_HEADER) - -/* - * forward references - */ -static void dload_symbols(struct dload_state *dlthis); -static void dload_data(struct dload_state *dlthis); -static void allocate_sections(struct dload_state *dlthis); -static void string_table_free(struct dload_state *dlthis); -static void symbol_table_free(struct dload_state *dlthis); -static void section_table_free(struct dload_state *dlthis); -static void init_module_handle(struct dload_state *dlthis); -#if BITS_PER_AU > BITS_PER_BYTE -static char *unpack_name(struct dload_state *dlthis, u32 soffset); -#endif - -static const char cinitname[] = { ".cinit" }; -static const char loader_dllview_root[] = { "?DLModules?" }; - -/* - * Error strings - */ -static const char readstrm[] = { "Error reading %s from input stream" }; -static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" }; -static const char tgtalloc[] = { - "Target memory allocate failed, section %s size " FMT_UI32 }; -static const char initfail[] = { "%s to target address " FMT_UI32 " failed" }; -static const char dlvwrite[] = { "Write to DLLview list failed" }; -static const char iconnect[] = { "Connect call to init interface failed" }; -static const char err_checksum[] = { "Checksum failed on %s" }; - -/************************************************************************* - * Procedure dload_error - * - * Parameters: - * errtxt description of the error, printf style - * ... additional information - * - * Effect: - * Reports or records the error as appropriate. - *********************************************************************** */ -void dload_error(struct dload_state *dlthis, const char *errtxt, ...) -{ - va_list args; - - va_start(args, errtxt); - dlthis->mysym->error_report(dlthis->mysym, errtxt, args); - va_end(args); - dlthis->dload_errcount += 1; - -} /* dload_error */ - -#define DL_ERROR(zza, zzb) dload_error(dlthis, zza, zzb) - -/************************************************************************* - * Procedure dload_syms_error - * - * Parameters: - * errtxt description of the error, printf style - * ... additional information - * - * Effect: - * Reports or records the error as appropriate. - *********************************************************************** */ -void dload_syms_error(struct dynamic_loader_sym *syms, const char *errtxt, ...) -{ - va_list args; - - va_start(args, errtxt); - syms->error_report(syms, errtxt, args); - va_end(args); -} - -/************************************************************************* - * Procedure dynamic_load_module - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * init Target-side memory initialization - * options Option flags DLOAD_* - * mhandle A module handle for use with Dynamic_Unload - * - * Effect: - * The module image is read using *module. Target storage for the new - * image is - * obtained from *alloc. Symbols defined and referenced by the module are - * managed using *syms. The image is then relocated and references - * resolved as necessary, and the resulting executable bits are placed - * into target memory using *init. - * - * Returns: - * On a successful load, a module handle is placed in *mhandle, - * and zero is returned. On error, the number of errors detected is - * returned. Individual errors are reported during the load process - * using syms->error_report(). - ********************************************************************** */ -int dynamic_load_module(struct dynamic_loader_stream *module, - struct dynamic_loader_sym *syms, - struct dynamic_loader_allocate *alloc, - struct dynamic_loader_initialize *init, - unsigned options, void **mhandle) -{ - register unsigned *dp, sz; - struct dload_state dl_state; /* internal state for this call */ - - /* blast our internal state */ - dp = (unsigned *)&dl_state; - for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1) - *dp++ = 0; - - /* Enable _only_ BSS initialization if enabled by user */ - if ((options & DLOAD_INITBSS) == DLOAD_INITBSS) - dl_state.myoptions = DLOAD_INITBSS; - - /* Check that mandatory arguments are present */ - if (!module || !syms) { - dload_error(&dl_state, "Required parameter is NULL"); - } else { - dl_state.strm = module; - dl_state.mysym = syms; - dload_headers(&dl_state); - if (!dl_state.dload_errcount) - dload_strings(&dl_state, false); - if (!dl_state.dload_errcount) - dload_sections(&dl_state); - - if (init && !dl_state.dload_errcount) { - if (init->connect(init)) { - dl_state.myio = init; - dl_state.myalloc = alloc; - /* do now, before reducing symbols */ - allocate_sections(&dl_state); - } else - dload_error(&dl_state, iconnect); - } - - if (!dl_state.dload_errcount) { - /* fix up entry point address */ - unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1; - if (sref < dl_state.allocated_secn_count) - dl_state.dfile_hdr.df_entrypt += - dl_state.ldr_sections[sref].run_addr; - - dload_symbols(&dl_state); - } - - if (init && !dl_state.dload_errcount) - dload_data(&dl_state); - - init_module_handle(&dl_state); - - /* dl_state.myio is init or 0 at this point. */ - if (dl_state.myio) { - if ((!dl_state.dload_errcount) && - (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) && - (!init->execute(init, - dl_state.dfile_hdr.df_entrypt))) - dload_error(&dl_state, "Init->Execute Failed"); - init->release(init); - } - - symbol_table_free(&dl_state); - section_table_free(&dl_state); - string_table_free(&dl_state); - dload_tramp_cleanup(&dl_state); - - if (dl_state.dload_errcount) { - dynamic_unload_module(dl_state.myhandle, syms, alloc, - init); - dl_state.myhandle = NULL; - } - } - - if (mhandle) - *mhandle = dl_state.myhandle; /* give back the handle */ - - return dl_state.dload_errcount; -} /* DLOAD_File */ - -/************************************************************************* - * Procedure dynamic_open_module - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * init Target-side memory initialization - * options Option flags DLOAD_* - * mhandle A module handle for use with Dynamic_Unload - * - * Effect: - * The module image is read using *module. Target storage for the new - * image is - * obtained from *alloc. Symbols defined and referenced by the module are - * managed using *syms. The image is then relocated and references - * resolved as necessary, and the resulting executable bits are placed - * into target memory using *init. - * - * Returns: - * On a successful load, a module handle is placed in *mhandle, - * and zero is returned. On error, the number of errors detected is - * returned. Individual errors are reported during the load process - * using syms->error_report(). - ********************************************************************** */ -int -dynamic_open_module(struct dynamic_loader_stream *module, - struct dynamic_loader_sym *syms, - struct dynamic_loader_allocate *alloc, - struct dynamic_loader_initialize *init, - unsigned options, void **mhandle) -{ - register unsigned *dp, sz; - struct dload_state dl_state; /* internal state for this call */ - - /* blast our internal state */ - dp = (unsigned *)&dl_state; - for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1) - *dp++ = 0; - - /* Enable _only_ BSS initialization if enabled by user */ - if ((options & DLOAD_INITBSS) == DLOAD_INITBSS) - dl_state.myoptions = DLOAD_INITBSS; - - /* Check that mandatory arguments are present */ - if (!module || !syms) { - dload_error(&dl_state, "Required parameter is NULL"); - } else { - dl_state.strm = module; - dl_state.mysym = syms; - dload_headers(&dl_state); - if (!dl_state.dload_errcount) - dload_strings(&dl_state, false); - if (!dl_state.dload_errcount) - dload_sections(&dl_state); - - if (init && !dl_state.dload_errcount) { - if (init->connect(init)) { - dl_state.myio = init; - dl_state.myalloc = alloc; - /* do now, before reducing symbols */ - allocate_sections(&dl_state); - } else - dload_error(&dl_state, iconnect); - } - - if (!dl_state.dload_errcount) { - /* fix up entry point address */ - unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1; - if (sref < dl_state.allocated_secn_count) - dl_state.dfile_hdr.df_entrypt += - dl_state.ldr_sections[sref].run_addr; - - dload_symbols(&dl_state); - } - - init_module_handle(&dl_state); - - /* dl_state.myio is either 0 or init at this point. */ - if (dl_state.myio) { - if ((!dl_state.dload_errcount) && - (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) && - (!init->execute(init, - dl_state.dfile_hdr.df_entrypt))) - dload_error(&dl_state, "Init->Execute Failed"); - init->release(init); - } - - symbol_table_free(&dl_state); - section_table_free(&dl_state); - string_table_free(&dl_state); - - if (dl_state.dload_errcount) { - dynamic_unload_module(dl_state.myhandle, syms, alloc, - init); - dl_state.myhandle = NULL; - } - } - - if (mhandle) - *mhandle = dl_state.myhandle; /* give back the handle */ - - return dl_state.dload_errcount; -} /* DLOAD_File */ - -/************************************************************************* - * Procedure dload_headers - * - * Parameters: - * none - * - * Effect: - * Loads the DOFF header and verify record. Deals with any byte-order - * issues and checks them for validity. - *********************************************************************** */ -#define COMBINED_HEADER_SIZE (sizeof(struct doff_filehdr_t)+ \ - sizeof(struct doff_verify_rec_t)) - -void dload_headers(struct dload_state *dlthis) -{ - u32 map; - - /* Read the header and the verify record as one. If we don't get it - all, we're done */ - if (dlthis->strm->read_buffer(dlthis->strm, &dlthis->dfile_hdr, - COMBINED_HEADER_SIZE) != - COMBINED_HEADER_SIZE) { - DL_ERROR(readstrm, "File Headers"); - return; - } - /* - * Verify that we have the byte order of the file correct. - * If not, must fix it before we can continue - */ - map = REORDER_MAP(dlthis->dfile_hdr.df_byte_reshuffle); - if (map != REORDER_MAP(BYTE_RESHUFFLE_VALUE)) { - /* input is either byte-shuffled or bad */ - if ((map & 0xFCFCFCFC) == 0) { /* no obviously bogus bits */ - dload_reorder(&dlthis->dfile_hdr, COMBINED_HEADER_SIZE, - map); - } - if (dlthis->dfile_hdr.df_byte_reshuffle != - BYTE_RESHUFFLE_VALUE) { - /* didn't fix the problem, the byte swap map is bad */ - dload_error(dlthis, - "Bad byte swap map " FMT_UI32 " in header", - dlthis->dfile_hdr.df_byte_reshuffle); - return; - } - dlthis->reorder_map = map; /* keep map for future use */ - } - - /* - * Verify checksum of header and verify record - */ - if (~dload_checksum(&dlthis->dfile_hdr, - sizeof(struct doff_filehdr_t)) || - ~dload_checksum(&dlthis->verify, - sizeof(struct doff_verify_rec_t))) { - DL_ERROR(err_checksum, "header or verify record"); - return; - } -#if HOST_ENDIANNESS - dlthis->dfile_hdr.df_byte_reshuffle = map; /* put back for later */ -#endif - - /* Check for valid target ID */ - if ((dlthis->dfile_hdr.df_target_id != TARGET_ID) && - -(dlthis->dfile_hdr.df_target_id != TMS470_ID)) { - dload_error(dlthis, "Bad target ID 0x%x and TARGET_ID 0x%x", - dlthis->dfile_hdr.df_target_id, TARGET_ID); - return; - } - /* Check for valid file format */ - if ((dlthis->dfile_hdr.df_doff_version != DOFF0)) { - dload_error(dlthis, "Bad DOFF version 0x%x", - dlthis->dfile_hdr.df_doff_version); - return; - } - - /* - * Apply reasonableness checks to count fields - */ - if (dlthis->dfile_hdr.df_strtab_size > MAX_REASONABLE_STRINGTAB) { - dload_error(dlthis, "Excessive string table size " FMT_UI32, - dlthis->dfile_hdr.df_strtab_size); - return; - } - if (dlthis->dfile_hdr.df_no_scns > MAX_REASONABLE_SECTIONS) { - dload_error(dlthis, "Excessive section count 0x%x", - dlthis->dfile_hdr.df_no_scns); - return; - } -#ifndef TARGET_ENDIANNESS - /* - * Check that endianness does not disagree with explicit specification - */ - if ((dlthis->dfile_hdr.df_flags >> ALIGN_COFF_ENDIANNESS) & - dlthis->myoptions & ENDIANNESS_MASK) { - dload_error(dlthis, - "Input endianness disagrees with specified option"); - return; - } - dlthis->big_e_target = dlthis->dfile_hdr.df_flags & DF_BIG; -#endif - -} /* dload_headers */ - -/* COFF Section Processing - * - * COFF sections are read in and retained intact. Each record is embedded - * in a new structure that records the updated load and - * run addresses of the section */ - -static const char secn_errid[] = { "section" }; - -/************************************************************************* - * Procedure dload_sections - * - * Parameters: - * none - * - * Effect: - * Loads the section records into an internal table. - *********************************************************************** */ -void dload_sections(struct dload_state *dlthis) -{ - s16 siz; - struct doff_scnhdr_t *shp; - unsigned nsecs = dlthis->dfile_hdr.df_no_scns; - - /* allocate space for the DOFF section records */ - siz = nsecs * sizeof(struct doff_scnhdr_t); - shp = - (struct doff_scnhdr_t *)dlthis->mysym->dload_allocate(dlthis->mysym, - siz); - if (!shp) { /* not enough storage */ - DL_ERROR(err_alloc, siz); - return; - } - dlthis->sect_hdrs = shp; - - /* read in the section records */ - if (dlthis->strm->read_buffer(dlthis->strm, shp, siz) != siz) { - DL_ERROR(readstrm, secn_errid); - return; - } - - /* if we need to fix up byte order, do it now */ - if (dlthis->reorder_map) - dload_reorder(shp, siz, dlthis->reorder_map); - - /* check for validity */ - if (~dload_checksum(dlthis->sect_hdrs, siz) != - dlthis->verify.dv_scn_rec_checksum) { - DL_ERROR(err_checksum, secn_errid); - return; - } - -} /* dload_sections */ - -/***************************************************************************** - * Procedure allocate_sections - * - * Parameters: - * alloc target memory allocator class - * - * Effect: - * Assigns new (target) addresses for sections - **************************************************************************** */ -static void allocate_sections(struct dload_state *dlthis) -{ - u16 curr_sect, nsecs, siz; - struct doff_scnhdr_t *shp; - struct ldr_section_info *asecs; - struct my_handle *hndl; - nsecs = dlthis->dfile_hdr.df_no_scns; - if (!nsecs) - return; - if ((dlthis->myalloc == NULL) && - (dlthis->dfile_hdr.df_target_scns > 0)) { - DL_ERROR("Arg 3 (alloc) required but NULL", 0); - return; - } - /* - * allocate space for the module handle, which we will keep for unload - * purposes include an additional section store for an auto-generated - * trampoline section in case we need it. - */ - siz = (dlthis->dfile_hdr.df_target_scns + 1) * - sizeof(struct ldr_section_info) + MY_HANDLE_SIZE; - - hndl = - (struct my_handle *)dlthis->mysym->dload_allocate(dlthis->mysym, - siz); - if (!hndl) { /* not enough storage */ - DL_ERROR(err_alloc, siz); - return; - } - /* initialize the handle header */ - hndl->dm.next = hndl->dm.prev = hndl; /* circular list */ - hndl->dm.root = NULL; - hndl->dm.dbthis = 0; - dlthis->myhandle = hndl; /* save away for return */ - /* pointer to the section list of allocated sections */ - dlthis->ldr_sections = asecs = hndl->secns; - /* * Insert names into all sections, make copies of - the sections we allocate */ - shp = dlthis->sect_hdrs; - for (curr_sect = 0; curr_sect < nsecs; curr_sect++) { - u32 soffset = shp->ds_offset; -#if BITS_PER_AU <= BITS_PER_BYTE - /* attempt to insert the name of this section */ - if (soffset < dlthis->dfile_hdr.df_strtab_size) - ((struct ldr_section_info *)shp)->name = - dlthis->str_head + soffset; - else { - dload_error(dlthis, "Bad name offset in section %d", - curr_sect); - ((struct ldr_section_info *)shp)->name = NULL; - } -#endif - /* allocate target storage for sections that require it */ - if (ds_needs_allocation(shp)) { - *asecs = *(struct ldr_section_info *)shp; - asecs->context = 0; /* zero the context field */ -#if BITS_PER_AU > BITS_PER_BYTE - asecs->name = unpack_name(dlthis, soffset); - dlthis->debug_string_size = soffset + dlthis->temp_len; -#else - dlthis->debug_string_size = soffset; -#endif - if (dlthis->myalloc != NULL) { - if (!dlthis->myalloc-> - dload_allocate(dlthis->myalloc, asecs, - ds_alignment(asecs->type))) { - dload_error(dlthis, tgtalloc, - asecs->name, asecs->size); - return; - } - } - /* keep address deltas in original section table */ - shp->ds_vaddr = asecs->load_addr - shp->ds_vaddr; - shp->ds_paddr = asecs->run_addr - shp->ds_paddr; - dlthis->allocated_secn_count += 1; - } /* allocate target storage */ - shp += 1; - asecs += 1; - } -#if BITS_PER_AU <= BITS_PER_BYTE - dlthis->debug_string_size += - strlen(dlthis->str_head + dlthis->debug_string_size) + 1; -#endif -} /* allocate sections */ - -/************************************************************************* - * Procedure section_table_free - * - * Parameters: - * none - * - * Effect: - * Frees any state used by the symbol table. - * - * WARNING: - * This routine is not allowed to declare errors! - *********************************************************************** */ -static void section_table_free(struct dload_state *dlthis) -{ - struct doff_scnhdr_t *shp; - - shp = dlthis->sect_hdrs; - if (shp) - dlthis->mysym->dload_deallocate(dlthis->mysym, shp); - -} /* section_table_free */ - -/************************************************************************* - * Procedure dload_strings - * - * Parameters: - * sec_names_only If true only read in the "section names" - * portion of the string table - * - * Effect: - * Loads the DOFF string table into memory. DOFF keeps all strings in a - * big unsorted array. We just read that array into memory in bulk. - *********************************************************************** */ -static const char stringtbl[] = { "string table" }; - -void dload_strings(struct dload_state *dlthis, bool sec_names_only) -{ - u32 ssiz; - char *strbuf; - - if (sec_names_only) { - ssiz = BYTE_TO_HOST(DOFF_ALIGN - (dlthis->dfile_hdr.df_scn_name_size)); - } else { - ssiz = BYTE_TO_HOST(DOFF_ALIGN - (dlthis->dfile_hdr.df_strtab_size)); - } - if (ssiz == 0) - return; - - /* get some memory for the string table */ -#if BITS_PER_AU > BITS_PER_BYTE - strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz + - dlthis->dfile_hdr. - df_max_str_len); -#else - strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz); -#endif - if (strbuf == NULL) { - DL_ERROR(err_alloc, ssiz); - return; - } - dlthis->str_head = strbuf; -#if BITS_PER_AU > BITS_PER_BYTE - dlthis->str_temp = strbuf + ssiz; -#endif - /* read in the strings and verify them */ - if ((unsigned)(dlthis->strm->read_buffer(dlthis->strm, strbuf, - ssiz)) != ssiz) { - DL_ERROR(readstrm, stringtbl); - } - /* if we need to fix up byte order, do it now */ -#ifndef _BIG_ENDIAN - if (dlthis->reorder_map) - dload_reorder(strbuf, ssiz, dlthis->reorder_map); - - if ((!sec_names_only) && (~dload_checksum(strbuf, ssiz) != - dlthis->verify.dv_str_tab_checksum)) { - DL_ERROR(err_checksum, stringtbl); - } -#else - if (dlthis->dfile_hdr.df_byte_reshuffle != - HOST_BYTE_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) { - /* put strings in big-endian order, not in PC order */ - dload_reorder(strbuf, ssiz, - HOST_BYTE_ORDER(dlthis-> - dfile_hdr.df_byte_reshuffle)); - } - if ((!sec_names_only) && (~dload_reverse_checksum(strbuf, ssiz) != - dlthis->verify.dv_str_tab_checksum)) { - DL_ERROR(err_checksum, stringtbl); - } -#endif -} /* dload_strings */ - -/************************************************************************* - * Procedure string_table_free - * - * Parameters: - * none - * - * Effect: - * Frees any state used by the string table. - * - * WARNING: - * This routine is not allowed to declare errors! - ************************************************************************ */ -static void string_table_free(struct dload_state *dlthis) -{ - if (dlthis->str_head) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->str_head); - -} /* string_table_free */ - -/* - * Symbol Table Maintenance Functions - * - * COFF symbols are read by dload_symbols(), which is called after - * sections have been allocated. Symbols which might be used in - * relocation (ie, not debug info) are retained in an internal temporary - * compressed table (type local_symbol). A particular symbol is recovered - * by index by calling dload_find_symbol(). dload_find_symbol - * reconstructs a more explicit representation (type SLOTVEC) which is - * used by reloc.c - */ -/* real size of debug header */ -#define DBG_HDR_SIZE (sizeof(struct dll_module) - sizeof(struct dll_sect)) - -static const char sym_errid[] = { "symbol" }; - -/************************************************************************** - * Procedure dload_symbols - * - * Parameters: - * none - * - * Effect: - * Reads in symbols and retains ones that might be needed for relocation - * purposes. - *********************************************************************** */ -/* size of symbol buffer no bigger than target data buffer, to limit stack - * usage */ -#define MY_SYM_BUF_SIZ (BYTE_TO_HOST(IMAGE_PACKET_SIZE)/\ - sizeof(struct doff_syment_t)) - -static void dload_symbols(struct dload_state *dlthis) -{ - u32 sym_count, siz, dsiz, symbols_left; - u32 checks; - struct local_symbol *sp; - struct dynload_symbol *symp; - struct dynload_symbol *newsym; - struct doff_syment_t *my_sym_buf; - - sym_count = dlthis->dfile_hdr.df_no_syms; - if (sym_count == 0) - return; - - /* - * We keep a local symbol table for all of the symbols in the input. - * This table contains only section & value info, as we do not have - * to do any name processing for locals. We reuse this storage - * as a temporary for .dllview record construction. - * Allocate storage for the whole table. Add 1 to the section count - * in case a trampoline section is auto-generated as well as the - * size of the trampoline section name so DLLView doesn't get lost. - */ - - siz = sym_count * sizeof(struct local_symbol); - dsiz = DBG_HDR_SIZE + - (sizeof(struct dll_sect) * dlthis->allocated_secn_count) + - BYTE_TO_HOST_ROUND(dlthis->debug_string_size + 1); - if (dsiz > siz) - siz = dsiz; /* larger of symbols and .dllview temp */ - sp = (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym, - siz); - if (!sp) { - DL_ERROR(err_alloc, siz); - return; - } - dlthis->local_symtab = sp; - /* Read the symbols in the input, store them in the table, and post any - * globals to the global symbol table. In the process, externals - become defined from the global symbol table */ - checks = dlthis->verify.dv_sym_tab_checksum; - symbols_left = sym_count; - - my_sym_buf = kzalloc(sizeof(*my_sym_buf) * MY_SYM_BUF_SIZ, GFP_KERNEL); - if (!my_sym_buf) - return; - - do { /* read all symbols */ - char *sname; - u32 val; - s32 delta; - struct doff_syment_t *input_sym; - unsigned syms_in_buf; - - input_sym = my_sym_buf; - syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ? - MY_SYM_BUF_SIZ : symbols_left; - siz = syms_in_buf * sizeof(struct doff_syment_t); - if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) != - siz) { - DL_ERROR(readstrm, sym_errid); - goto free_sym_buf; - } - if (dlthis->reorder_map) - dload_reorder(input_sym, siz, dlthis->reorder_map); - - checks += dload_checksum(input_sym, siz); - do { /* process symbols in buffer */ - symbols_left -= 1; - /* attempt to derive the name of this symbol */ - sname = NULL; - if (input_sym->dn_offset > 0) { -#if BITS_PER_AU <= BITS_PER_BYTE - if ((u32) input_sym->dn_offset < - dlthis->dfile_hdr.df_strtab_size) - sname = dlthis->str_head + - BYTE_TO_HOST(input_sym->dn_offset); - else - dload_error(dlthis, - "Bad name offset in symbol " - " %d", symbols_left); -#else - sname = unpack_name(dlthis, - input_sym->dn_offset); -#endif - } - val = input_sym->dn_value; - delta = 0; - sp->sclass = input_sym->dn_sclass; - sp->secnn = input_sym->dn_scnum; - /* if this is an undefined symbol, - * define it (or fail) now */ - if (sp->secnn == DN_UNDEF) { - /* pointless for static undefined */ - if (input_sym->dn_sclass != DN_EXT) - goto loop_cont; - - /* try to define symbol from previously - * loaded images */ - symp = dlthis->mysym->find_matching_symbol - (dlthis->mysym, sname); - if (!symp) { - DL_ERROR - ("Undefined external symbol %s", - sname); - goto loop_cont; - } - val = delta = symp->value; -#ifdef ENABLE_TRAMP_DEBUG - dload_syms_error(dlthis->mysym, - "===> ext sym [%s] at %x", - sname, val); -#endif - - goto loop_cont; - } - /* symbol defined by this module */ - if (sp->secnn > 0) { - /* symbol references a section */ - if ((unsigned)sp->secnn <= - dlthis->allocated_secn_count) { - /* section was allocated */ - struct doff_scnhdr_t *srefp = - &dlthis->sect_hdrs[sp->secnn - 1]; - - if (input_sym->dn_sclass == - DN_STATLAB || - input_sym->dn_sclass == DN_EXTLAB) { - /* load */ - delta = srefp->ds_vaddr; - } else { - /* run */ - delta = srefp->ds_paddr; - } - val += delta; - } - goto loop_itr; - } - /* This symbol is an absolute symbol */ - if (sp->secnn == DN_ABS && ((sp->sclass == DN_EXT) || - (sp->sclass == - DN_EXTLAB))) { - symp = - dlthis->mysym->find_matching_symbol(dlthis-> - mysym, - sname); - if (!symp) - goto loop_itr; - /* This absolute symbol is already defined. */ - if (symp->value == input_sym->dn_value) { - /* If symbol values are equal, continue - * but don't add to the global symbol - * table */ - sp->value = val; - sp->delta = delta; - sp += 1; - input_sym += 1; - continue; - } else { - /* If symbol values are not equal, - * return with redefinition error */ - DL_ERROR("Absolute symbol %s is " - "defined multiple times with " - "different values", sname); - goto free_sym_buf; - } - } -loop_itr: - /* if this is a global symbol, post it to the - * global table */ - if (input_sym->dn_sclass == DN_EXT || - input_sym->dn_sclass == DN_EXTLAB) { - /* Keep this global symbol for subsequent - * modules. Don't complain on error, to allow - * symbol API to suppress global symbols */ - if (!sname) - goto loop_cont; - - newsym = dlthis->mysym->add_to_symbol_table - (dlthis->mysym, sname, - (unsigned)dlthis->myhandle); - if (newsym) - newsym->value = val; - - } /* global */ -loop_cont: - sp->value = val; - sp->delta = delta; - sp += 1; - input_sym += 1; - } while ((syms_in_buf -= 1) > 0); /* process sym in buf */ - } while (symbols_left > 0); /* read all symbols */ - if (~checks) - dload_error(dlthis, "Checksum of symbols failed"); - -free_sym_buf: - kfree(my_sym_buf); - return; -} /* dload_symbols */ - -/***************************************************************************** - * Procedure symbol_table_free - * - * Parameters: - * none - * - * Effect: - * Frees any state used by the symbol table. - * - * WARNING: - * This routine is not allowed to declare errors! - **************************************************************************** */ -static void symbol_table_free(struct dload_state *dlthis) -{ - if (dlthis->local_symtab) { - if (dlthis->dload_errcount) { /* blow off our symbols */ - dlthis->mysym->purge_symbol_table(dlthis->mysym, - (unsigned) - dlthis->myhandle); - } - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->local_symtab); - } -} /* symbol_table_free */ - -/* .cinit Processing - * - * The dynamic loader does .cinit interpretation. cload_cinit() - * acts as a special write-to-target function, in that it takes relocated - * data from the normal data flow, and interprets it as .cinit actions. - * Because the normal data flow does not necessarily process the whole - * .cinit section in one buffer, cload_cinit() must be prepared to - * interpret the data piecemeal. A state machine is used for this - * purpose. - */ - -/* The following are only for use by reloc.c and things it calls */ -static const struct ldr_section_info cinit_info_init = { cinitname, 0, 0, - (ldr_addr)-1, 0, DLOAD_BSS, 0 -}; - -/************************************************************************* - * Procedure cload_cinit - * - * Parameters: - * ipacket Pointer to data packet to be loaded - * - * Effect: - * Interprets the data in the buffer as .cinit data, and performs the - * appropriate initializations. - *********************************************************************** */ -static void cload_cinit(struct dload_state *dlthis, - struct image_packet_t *ipacket) -{ -#if TDATA_TO_HOST(CINIT_COUNT)*BITS_PER_AU > 16 - s32 init_count, left; -#else - s16 init_count, left; -#endif - unsigned char *pktp = ipacket->img_data; - unsigned char *pktend = pktp + BYTE_TO_HOST_ROUND(ipacket->packet_size); - int temp; - ldr_addr atmp; - struct ldr_section_info cinit_info; - - /* PROCESS ALL THE INITIALIZATION RECORDS THE BUFFER. */ - while (true) { - left = pktend - pktp; - switch (dlthis->cinit_state) { - case CI_COUNT: /* count field */ - if (left < TDATA_TO_HOST(CINIT_COUNT)) - goto loopexit; - temp = dload_unpack(dlthis, (tgt_au_t *) pktp, - CINIT_COUNT * TDATA_AU_BITS, 0, - ROP_SGN); - pktp += TDATA_TO_HOST(CINIT_COUNT); - /* negative signifies BSS table, zero means done */ - if (temp <= 0) { - dlthis->cinit_state = CI_DONE; - break; - } - dlthis->cinit_count = temp; - dlthis->cinit_state = CI_ADDRESS; - break; -#if CINIT_ALIGN < CINIT_ADDRESS - case CI_PARTADDRESS: - pktp -= TDATA_TO_HOST(CINIT_ALIGN); - /* back up pointer into space courtesy of caller */ - *(uint16_t *) pktp = dlthis->cinit_addr; - /* stuff in saved bits !! FALL THRU !! */ -#endif - case CI_ADDRESS: /* Address field for a copy packet */ - if (left < TDATA_TO_HOST(CINIT_ADDRESS)) { -#if CINIT_ALIGN < CINIT_ADDRESS - if (left == TDATA_TO_HOST(CINIT_ALIGN)) { - /* address broken into halves */ - dlthis->cinit_addr = *(uint16_t *) pktp; - /* remember 1st half */ - dlthis->cinit_state = CI_PARTADDRESS; - left = 0; - } -#endif - goto loopexit; - } - atmp = dload_unpack(dlthis, (tgt_au_t *) pktp, - CINIT_ADDRESS * TDATA_AU_BITS, 0, - ROP_UNS); - pktp += TDATA_TO_HOST(CINIT_ADDRESS); -#if CINIT_PAGE_BITS > 0 - dlthis->cinit_page = atmp & - ((1 << CINIT_PAGE_BITS) - 1); - atmp >>= CINIT_PAGE_BITS; -#else - dlthis->cinit_page = CINIT_DEFAULT_PAGE; -#endif - dlthis->cinit_addr = atmp; - dlthis->cinit_state = CI_COPY; - break; - case CI_COPY: /* copy bits to the target */ - init_count = HOST_TO_TDATA(left); - if (init_count > dlthis->cinit_count) - init_count = dlthis->cinit_count; - if (init_count == 0) - goto loopexit; /* get more bits */ - cinit_info = cinit_info_init; - cinit_info.page = dlthis->cinit_page; - if (!dlthis->myio->writemem(dlthis->myio, pktp, - TDATA_TO_TADDR - (dlthis->cinit_addr), - &cinit_info, - TDATA_TO_HOST(init_count))) { - dload_error(dlthis, initfail, "write", - dlthis->cinit_addr); - } - dlthis->cinit_count -= init_count; - if (dlthis->cinit_count <= 0) { - dlthis->cinit_state = CI_COUNT; - init_count = (init_count + CINIT_ALIGN - 1) & - -CINIT_ALIGN; - /* align to next init */ - } - pktp += TDATA_TO_HOST(init_count); - dlthis->cinit_addr += init_count; - break; - case CI_DONE: /* no more .cinit to do */ - return; - } /* switch (cinit_state) */ - } /* while */ - -loopexit: - if (left > 0) { - dload_error(dlthis, "%d bytes left over in cinit packet", left); - dlthis->cinit_state = CI_DONE; /* left over bytes are bad */ - } -} /* cload_cinit */ - -/* Functions to interface to reloc.c - * - * reloc.c is the relocation module borrowed from the linker, with - * minimal (we hope) changes for our purposes. cload_sect_data() invokes - * this module on a section to relocate and load the image data for that - * section. The actual read and write actions are supplied by the global - * routines below. - */ - -/************************************************************************ - * Procedure relocate_packet - * - * Parameters: - * ipacket Pointer to an image packet to relocate - * - * Effect: - * Performs the required relocations on the packet. Returns a checksum - * of the relocation operations. - *********************************************************************** */ -#define MY_RELOC_BUF_SIZ 8 -/* careful! exists at the same time as the image buffer */ -static int relocate_packet(struct dload_state *dlthis, - struct image_packet_t *ipacket, - u32 *checks, bool *tramps_generated) -{ - u32 rnum; - *tramps_generated = false; - - rnum = ipacket->num_relocs; - do { /* all relocs */ - unsigned rinbuf; - int siz; - struct reloc_record_t *rp, rrec[MY_RELOC_BUF_SIZ]; - rp = rrec; - rinbuf = rnum > MY_RELOC_BUF_SIZ ? MY_RELOC_BUF_SIZ : rnum; - siz = rinbuf * sizeof(struct reloc_record_t); - if (dlthis->strm->read_buffer(dlthis->strm, rp, siz) != siz) { - DL_ERROR(readstrm, "relocation"); - return 0; - } - /* reorder the bytes if need be */ - if (dlthis->reorder_map) - dload_reorder(rp, siz, dlthis->reorder_map); - - *checks += dload_checksum(rp, siz); - do { - /* perform the relocation operation */ - dload_relocate(dlthis, (tgt_au_t *) ipacket->img_data, - rp, tramps_generated, false); - rp += 1; - rnum -= 1; - } while ((rinbuf -= 1) > 0); - } while (rnum > 0); /* all relocs */ - /* If trampoline(s) were generated, we need to do an update of the - * trampoline copy of the packet since a 2nd phase relo will be done - * later. */ - if (*tramps_generated == true) { - dload_tramp_pkt_udpate(dlthis, - (dlthis->image_secn - - dlthis->ldr_sections), - dlthis->image_offset, ipacket); - } - - return 1; -} /* dload_read_reloc */ - -#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32)) - -/* VERY dangerous */ -static const char imagepak[] = { "image packet" }; - -struct img_buffer { - struct image_packet_t ipacket; - u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)]; -}; - -/************************************************************************* - * Procedure dload_data - * - * Parameters: - * none - * - * Effect: - * Read image data from input file, relocate it, and download it to the - * target. - *********************************************************************** */ -static void dload_data(struct dload_state *dlthis) -{ - u16 curr_sect; - struct doff_scnhdr_t *sptr = dlthis->sect_hdrs; - struct ldr_section_info *lptr = dlthis->ldr_sections; - struct img_buffer *ibuf; - u8 *dest; - - /* Indicates whether CINIT processing has occurred */ - bool cinit_processed = false; - - ibuf = kzalloc(sizeof(*ibuf), GFP_KERNEL); - if (!ibuf) - return; - - /* Loop through the sections and load them one at a time. - */ - for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns; - curr_sect += 1) { - if (ds_needs_download(sptr)) { - s32 nip; - ldr_addr image_offset = 0; - /* set relocation info for this section */ - if (curr_sect < dlthis->allocated_secn_count) - dlthis->delta_runaddr = sptr->ds_paddr; - else { - lptr = (struct ldr_section_info *)sptr; - dlthis->delta_runaddr = 0; - } - dlthis->image_secn = lptr; -#if BITS_PER_AU > BITS_PER_BYTE - lptr->name = unpack_name(dlthis, sptr->ds_offset); -#endif - nip = sptr->ds_nipacks; - while ((nip -= 1) >= 0) { /* process packets */ - - s32 ipsize; - u32 checks; - bool tramp_generated = false; - - /* get the fixed header bits */ - if (dlthis->strm->read_buffer(dlthis->strm, - &ibuf->ipacket, - IPH_SIZE) != - IPH_SIZE) { - DL_ERROR(readstrm, imagepak); - goto free_ibuf; - } - /* reorder the header if need be */ - if (dlthis->reorder_map) { - dload_reorder(&ibuf->ipacket, IPH_SIZE, - dlthis->reorder_map); - } - /* now read the rest of the packet */ - ipsize = - BYTE_TO_HOST(DOFF_ALIGN - (ibuf->ipacket.packet_size)); - if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) { - DL_ERROR("Bad image packet size %d", - ipsize); - goto free_ibuf; - } - dest = ibuf->bufr; - /* End of determination */ - - if (dlthis->strm->read_buffer(dlthis->strm, - ibuf->bufr, - ipsize) != - ipsize) { - DL_ERROR(readstrm, imagepak); - goto free_ibuf; - } - ibuf->ipacket.img_data = dest; - - /* reorder the bytes if need be */ -#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16) - if (dlthis->reorder_map) { - dload_reorder(dest, ipsize, - dlthis->reorder_map); - } - checks = dload_checksum(dest, ipsize); -#else - if (dlthis->dfile_hdr.df_byte_reshuffle != - TARGET_ORDER(REORDER_MAP - (BYTE_RESHUFFLE_VALUE))) { - /* put image bytes in big-endian order, - * not PC order */ - dload_reorder(dest, ipsize, - TARGET_ORDER - (dlthis->dfile_hdr. - df_byte_reshuffle)); - } -#if TARGET_AU_BITS > 8 - checks = dload_reverse_checksum16(dest, ipsize); -#else - checks = dload_reverse_checksum(dest, ipsize); -#endif -#endif - - checks += dload_checksum(&ibuf->ipacket, - IPH_SIZE); - /* relocate the image bits as needed */ - if (ibuf->ipacket.num_relocs) { - dlthis->image_offset = image_offset; - if (!relocate_packet(dlthis, - &ibuf->ipacket, - &checks, - &tramp_generated)) - goto free_ibuf; /* error */ - } - if (~checks) - DL_ERROR(err_checksum, imagepak); - /* Only write the result to the target if no - * trampoline was generated. Otherwise it - *will be done during trampoline finalize. */ - - if (tramp_generated == false) { - - /* stuff the result into target - * memory */ - if (dload_check_type(sptr, - DLOAD_CINIT)) { - cload_cinit(dlthis, - &ibuf->ipacket); - cinit_processed = true; - } else { - /* FIXME */ - if (!dlthis->myio-> - writemem(dlthis-> - myio, - ibuf->bufr, - lptr-> - load_addr + - image_offset, - lptr, - BYTE_TO_HOST - (ibuf-> - ipacket. - packet_size))) { - DL_ERROR - ("Write to " - FMT_UI32 - " failed", - lptr-> - load_addr + - image_offset); - } - } - } - image_offset += - BYTE_TO_TADDR(ibuf->ipacket.packet_size); - } /* process packets */ - /* if this is a BSS section, we may want to fill it */ - if (!dload_check_type(sptr, DLOAD_BSS)) - goto loop_cont; - - if (!(dlthis->myoptions & DLOAD_INITBSS)) - goto loop_cont; - - if (cinit_processed) { - /* Don't clear BSS after load-time - * initialization */ - DL_ERROR - ("Zero-initialization at " FMT_UI32 - " after " "load-time initialization!", - lptr->load_addr); - goto loop_cont; - } - /* fill the .bss area */ - dlthis->myio->fillmem(dlthis->myio, - TADDR_TO_HOST(lptr->load_addr), - lptr, TADDR_TO_HOST(lptr->size), - DLOAD_FILL_BSS); - goto loop_cont; - } - /* if DS_DOWNLOAD_MASK */ - /* If not loading, but BSS, zero initialize */ - if (!dload_check_type(sptr, DLOAD_BSS)) - goto loop_cont; - - if (!(dlthis->myoptions & DLOAD_INITBSS)) - goto loop_cont; - - if (curr_sect >= dlthis->allocated_secn_count) - lptr = (struct ldr_section_info *)sptr; - - if (cinit_processed) { - /*Don't clear BSS after load-time initialization */ - DL_ERROR("Zero-initialization at " FMT_UI32 - " attempted after " - "load-time initialization!", lptr->load_addr); - goto loop_cont; - } - /* fill the .bss area */ - dlthis->myio->fillmem(dlthis->myio, - TADDR_TO_HOST(lptr->load_addr), lptr, - TADDR_TO_HOST(lptr->size), - DLOAD_FILL_BSS); -loop_cont: - sptr += 1; - lptr += 1; - } /* load sections */ - - /* Finalize any trampolines that were created during the load */ - if (dload_tramp_finalize(dlthis) == 0) { - DL_ERROR("Finalization of auto-trampolines (size = " FMT_UI32 - ") failed", dlthis->tramp.tramp_sect_next_addr); - } -free_ibuf: - kfree(ibuf); - return; -} /* dload_data */ - -/************************************************************************* - * Procedure dload_reorder - * - * Parameters: - * data 32-bit aligned pointer to data to be byte-swapped - * dsiz size of the data to be reordered in sizeof() units. - * map 32-bit map defining how to reorder the data. Value - * must be REORDER_MAP() of some permutation - * of 0x00 01 02 03 - * - * Effect: - * Re-arranges the bytes in each word according to the map specified. - * - *********************************************************************** */ -/* mask for byte shift count */ -#define SHIFT_COUNT_MASK (3 << LOG_BITS_PER_BYTE) - -void dload_reorder(void *data, int dsiz, unsigned int map) -{ - register u32 tmp, tmap, datv; - u32 *dp = (u32 *) data; - - map <<= LOG_BITS_PER_BYTE; /* align map with SHIFT_COUNT_MASK */ - do { - tmp = 0; - datv = *dp; - tmap = map; - do { - tmp |= (datv & BYTE_MASK) << (tmap & SHIFT_COUNT_MASK); - tmap >>= BITS_PER_BYTE; - } while (datv >>= BITS_PER_BYTE); - *dp++ = tmp; - } while ((dsiz -= sizeof(u32)) > 0); -} /* dload_reorder */ - -/************************************************************************* - * Procedure dload_checksum - * - * Parameters: - * data 32-bit aligned pointer to data to be checksummed - * siz size of the data to be checksummed in sizeof() units. - * - * Effect: - * Returns a checksum of the specified block - * - *********************************************************************** */ -u32 dload_checksum(void *data, unsigned siz) -{ - u32 sum; - u32 *dp; - int left; - - sum = 0; - dp = (u32 *) data; - for (left = siz; left > 0; left -= sizeof(u32)) - sum += *dp++; - return sum; -} /* dload_checksum */ - -#if HOST_ENDIANNESS -/************************************************************************* - * Procedure dload_reverse_checksum - * - * Parameters: - * data 32-bit aligned pointer to data to be checksummed - * siz size of the data to be checksummed in sizeof() units. - * - * Effect: - * Returns a checksum of the specified block, which is assumed to be bytes - * in big-endian order. - * - * Notes: - * In a big-endian host, things like the string table are stored as bytes - * in host order. But dllcreate always checksums in little-endian order. - * It is most efficient to just handle the difference a word at a time. - * - ********************************************************************** */ -u32 dload_reverse_checksum(void *data, unsigned siz) -{ - u32 sum, temp; - u32 *dp; - int left; - - sum = 0; - dp = (u32 *) data; - - for (left = siz; left > 0; left -= sizeof(u32)) { - temp = *dp++; - sum += temp << BITS_PER_BYTE * 3; - sum += temp >> BITS_PER_BYTE * 3; - sum += (temp >> BITS_PER_BYTE) & (BYTE_MASK << BITS_PER_BYTE); - sum += (temp & (BYTE_MASK << BITS_PER_BYTE)) << BITS_PER_BYTE; - } - - return sum; -} /* dload_reverse_checksum */ - -#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32) -u32 dload_reverse_checksum16(void *data, unsigned siz) -{ - uint_fast32_t sum, temp; - u32 *dp; - int left; - - sum = 0; - dp = (u32 *) data; - - for (left = siz; left > 0; left -= sizeof(u32)) { - temp = *dp++; - sum += temp << BITS_PER_BYTE * 2; - sum += temp >> BITS_PER_BYTE * 2; - } - - return sum; -} /* dload_reverse_checksum16 */ -#endif -#endif - -/************************************************************************* - * Procedure swap_words - * - * Parameters: - * data 32-bit aligned pointer to data to be swapped - * siz size of the data to be swapped. - * bitmap Bit map of how to swap each 32-bit word; 1 => 2 shorts, - * 0 => 1 long - * - * Effect: - * Swaps the specified data according to the specified map - * - *********************************************************************** */ -static void swap_words(void *data, unsigned siz, unsigned bitmap) -{ - register int i; -#if TARGET_AU_BITS < 16 - register u16 *sp; -#endif - register u32 *lp; - - siz /= sizeof(u16); - -#if TARGET_AU_BITS < 16 - /* pass 1: do all the bytes */ - i = siz; - sp = (u16 *) data; - do { - register u16 tmp; - tmp = *sp; - *sp++ = SWAP16BY8(tmp); - } while ((i -= 1) > 0); -#endif - -#if TARGET_AU_BITS < 32 - /* pass 2: fixup the 32-bit words */ - i = siz >> 1; - lp = (u32 *) data; - do { - if ((bitmap & 1) == 0) { - register u32 tmp; - tmp = *lp; - *lp = SWAP32BY16(tmp); - } - lp += 1; - bitmap >>= 1; - } while ((i -= 1) > 0); -#endif -} /* swap_words */ - -/************************************************************************* - * Procedure copy_tgt_strings - * - * Parameters: - * dstp Destination address. Assumed to be 32-bit aligned - * srcp Source address. Assumed to be 32-bit aligned - * charcount Number of characters to copy. - * - * Effect: - * Copies strings from the source (which is in usual .dof file order on - * the loading processor) to the destination buffer (which should be in proper - * target addressable unit order). Makes sure the last string in the - * buffer is NULL terminated (for safety). - * Returns the first unused destination address. - *********************************************************************** */ -static char *copy_tgt_strings(void *dstp, void *srcp, unsigned charcount) -{ - register tgt_au_t *src = (tgt_au_t *) srcp; - register tgt_au_t *dst = (tgt_au_t *) dstp; - register int cnt = charcount; - do { -#if TARGET_AU_BITS <= BITS_PER_AU - /* byte-swapping issues may exist for strings on target */ - *dst++ = *src++; -#else - *dst++ = *src++; -#endif - } while ((cnt -= (sizeof(tgt_au_t) * BITS_PER_AU / BITS_PER_BYTE)) > 0); - /*apply force to make sure that the string table has null terminator */ -#if (BITS_PER_AU == BITS_PER_BYTE) && (TARGET_AU_BITS == BITS_PER_BYTE) - dst[-1] = 0; -#else - /* little endian */ - dst[-1] &= (1 << (BITS_PER_AU - BITS_PER_BYTE)) - 1; -#endif - return (char *)dst; -} /* copy_tgt_strings */ - -/************************************************************************* - * Procedure init_module_handle - * - * Parameters: - * none - * - * Effect: - * Initializes the module handle we use to enable unloading, and installs - * the debug information required by the target. - * - * Notes: - * The handle returned from dynamic_load_module needs to encapsulate all the - * allocations done for the module, and enable them plus the modules symbols to - * be deallocated. - * - *********************************************************************** */ -#ifndef _BIG_ENDIAN -static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0, - (ldr_addr)-1, DBG_LIST_PAGE, DLOAD_DATA, 0 -}; -#else -static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0, - (ldr_addr)-1, DLOAD_DATA, DBG_LIST_PAGE, 0 -}; -#endif -static void init_module_handle(struct dload_state *dlthis) -{ - struct my_handle *hndl; - u16 curr_sect; - struct ldr_section_info *asecs; - struct dll_module *dbmod; - struct dll_sect *dbsec; - struct dbg_mirror_root *mlist; - register char *cp; - struct modules_header mhdr; - struct ldr_section_info dllview_info; - struct dynload_symbol *debug_mirror_sym; - hndl = dlthis->myhandle; - if (!hndl) - return; /* must be errors detected, so forget it */ - - /* Store the section count */ - hndl->secn_count = dlthis->allocated_secn_count; - - /* If a trampoline section was created, add it in */ - if (dlthis->tramp.tramp_sect_next_addr != 0) - hndl->secn_count += 1; - - hndl->secn_count = hndl->secn_count << 1; - - hndl->secn_count = dlthis->allocated_secn_count << 1; -#ifndef TARGET_ENDIANNESS - if (dlthis->big_e_target) - hndl->secn_count += 1; /* flag for big-endian */ -#endif - if (dlthis->dload_errcount) - return; /* abandon if errors detected */ - /* Locate the symbol that names the header for the CCS debug list - of modules. If not found, we just don't generate the debug record. - If found, we create our modules list. We make sure to create the - loader_dllview_root even if there is no relocation info to record, - just to try to put both symbols in the same symbol table and - module. */ - debug_mirror_sym = dlthis->mysym->find_matching_symbol(dlthis->mysym, - loader_dllview_root); - if (!debug_mirror_sym) { - struct dynload_symbol *dlmodsym; - struct dbg_mirror_root *mlst; - - /* our root symbol is not yet present; - check if we have DLModules defined */ - dlmodsym = dlthis->mysym->find_matching_symbol(dlthis->mysym, - LINKER_MODULES_HEADER); - if (!dlmodsym) - return; /* no DLModules list so no debug info */ - /* if we have DLModules defined, construct our header */ - mlst = (struct dbg_mirror_root *) - dlthis->mysym->dload_allocate(dlthis->mysym, - sizeof(struct - dbg_mirror_root)); - if (!mlst) { - DL_ERROR(err_alloc, sizeof(struct dbg_mirror_root)); - return; - } - mlst->next = NULL; - mlst->changes = 0; - mlst->refcount = 0; - mlst->dbthis = TDATA_TO_TADDR(dlmodsym->value); - /* add our root symbol */ - debug_mirror_sym = dlthis->mysym->add_to_symbol_table - (dlthis->mysym, loader_dllview_root, - (unsigned)dlthis->myhandle); - if (!debug_mirror_sym) { - /* failed, recover memory */ - dlthis->mysym->dload_deallocate(dlthis->mysym, mlst); - return; - } - debug_mirror_sym->value = (u32) mlst; - } - /* First create the DLLview record and stuff it into the buffer. - Then write it to the DSP. Record pertinent locations in our hndl, - and add it to the per-processor list of handles with debug info. */ -#ifndef DEBUG_HEADER_IN_LOADER - mlist = (struct dbg_mirror_root *)debug_mirror_sym->value; - if (!mlist) - return; -#else - mlist = (struct dbg_mirror_root *)&debug_list_header; -#endif - hndl->dm.root = mlist; /* set pointer to root into our handle */ - if (!dlthis->allocated_secn_count) - return; /* no load addresses to be recorded */ - /* reuse temporary symbol storage */ - dbmod = (struct dll_module *)dlthis->local_symtab; - /* Create the DLLview record in the memory we retain for our handle */ - dbmod->num_sects = dlthis->allocated_secn_count; - dbmod->timestamp = dlthis->verify.dv_timdat; - dbmod->version = INIT_VERSION; - dbmod->verification = VERIFICATION; - asecs = dlthis->ldr_sections; - dbsec = dbmod->sects; - for (curr_sect = dlthis->allocated_secn_count; - curr_sect > 0; curr_sect -= 1) { - dbsec->sect_load_adr = asecs->load_addr; - dbsec->sect_run_adr = asecs->run_addr; - dbsec += 1; - asecs += 1; - } - - /* If a trampoline section was created go ahead and add its info */ - if (dlthis->tramp.tramp_sect_next_addr != 0) { - dbmod->num_sects++; - dbsec->sect_load_adr = asecs->load_addr; - dbsec->sect_run_adr = asecs->run_addr; - dbsec++; - asecs++; - } - - /* now cram in the names */ - cp = copy_tgt_strings(dbsec, dlthis->str_head, - dlthis->debug_string_size); - - /* If a trampoline section was created, add its name so DLLView - * can show the user the section info. */ - if (dlthis->tramp.tramp_sect_next_addr != 0) { - cp = copy_tgt_strings(cp, - dlthis->tramp.final_string_table, - strlen(dlthis->tramp.final_string_table) + - 1); - } - - /* round off the size of the debug record, and remember same */ - hndl->dm.dbsiz = HOST_TO_TDATA_ROUND(cp - (char *)dbmod); - *cp = 0; /* strictly to make our test harness happy */ - dllview_info = dllview_info_init; - dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz); - /* Initialize memory context to default heap */ - dllview_info.context = 0; - hndl->dm.context = 0; - /* fill in next pointer and size */ - if (mlist->next) { - dbmod->next_module = TADDR_TO_TDATA(mlist->next->dm.dbthis); - dbmod->next_module_size = mlist->next->dm.dbsiz; - } else { - dbmod->next_module_size = 0; - dbmod->next_module = 0; - } - /* allocate memory for on-DSP DLLview debug record */ - if (!dlthis->myalloc) - return; - if (!dlthis->myalloc->dload_allocate(dlthis->myalloc, &dllview_info, - HOST_TO_TADDR(sizeof(u32)))) { - return; - } - /* Store load address of .dllview section */ - hndl->dm.dbthis = dllview_info.load_addr; - /* Store memory context (segid) in which .dllview section - * was allocated */ - hndl->dm.context = dllview_info.context; - mlist->refcount += 1; - /* swap bytes in the entire debug record, but not the string table */ - if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) { - swap_words(dbmod, (char *)dbsec - (char *)dbmod, - DLL_MODULE_BITMAP); - } - /* Update the DLLview list on the DSP write new record */ - if (!dlthis->myio->writemem(dlthis->myio, dbmod, - dllview_info.load_addr, &dllview_info, - TADDR_TO_HOST(dllview_info.size))) { - return; - } - /* write new header */ - mhdr.first_module_size = hndl->dm.dbsiz; - mhdr.first_module = TADDR_TO_TDATA(dllview_info.load_addr); - /* swap bytes in the module header, if needed */ - if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) { - swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16), - MODULES_HEADER_BITMAP); - } - dllview_info = dllview_info_init; - if (!dlthis->myio->writemem(dlthis->myio, &mhdr, mlist->dbthis, - &dllview_info, - sizeof(struct modules_header) - - sizeof(u16))) { - return; - } - /* Add the module handle to this processor's list - of handles with debug info */ - hndl->dm.next = mlist->next; - if (hndl->dm.next) - hndl->dm.next->dm.prev = hndl; - hndl->dm.prev = (struct my_handle *)mlist; - mlist->next = hndl; /* insert after root */ -} /* init_module_handle */ - -/************************************************************************* - * Procedure dynamic_unload_module - * - * Parameters: - * mhandle A module handle from dynamic_load_module - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * - * Effect: - * The module specified by mhandle is unloaded. Unloading causes all - * target memory to be deallocated, all symbols defined by the module to - * be purged, and any host-side storage used by the dynamic loader for - * this module to be released. - * - * Returns: - * Zero for success. On error, the number of errors detected is returned. - * Individual errors are reported using syms->error_report(). - *********************************************************************** */ -int dynamic_unload_module(void *mhandle, - struct dynamic_loader_sym *syms, - struct dynamic_loader_allocate *alloc, - struct dynamic_loader_initialize *init) -{ - s16 curr_sect; - struct ldr_section_info *asecs; - struct my_handle *hndl; - struct dbg_mirror_root *root; - unsigned errcount = 0; - struct ldr_section_info dllview_info = dllview_info_init; - struct modules_header mhdr; - - hndl = (struct my_handle *)mhandle; - if (!hndl) - return 0; /* if handle is null, nothing to do */ - /* Clear out the module symbols - * Note that if this is the module that defined MODULES_HEADER - (the head of the target debug list) - * then this operation will blow away that symbol. - It will therefore be impossible for subsequent - * operations to add entries to this un-referenceable list. */ - if (!syms) - return 1; - syms->purge_symbol_table(syms, (unsigned)hndl); - /* Deallocate target memory for sections - * NOTE: The trampoline section, if created, gets deleted here, too */ - - asecs = hndl->secns; - if (alloc) - for (curr_sect = (hndl->secn_count >> 1); curr_sect > 0; - curr_sect -= 1) { - asecs->name = NULL; - alloc->dload_deallocate(alloc, asecs++); - } - root = hndl->dm.root; - if (!root) { - /* there is a debug list containing this module */ - goto func_end; - } - if (!hndl->dm.dbthis) { /* target-side dllview record exists */ - goto loop_end; - } - /* Retrieve memory context in which .dllview was allocated */ - dllview_info.context = hndl->dm.context; - if (hndl->dm.prev == hndl) - goto exitunltgt; - - /* target-side dllview record is in list */ - /* dequeue this record from our GPP-side mirror list */ - hndl->dm.prev->dm.next = hndl->dm.next; - if (hndl->dm.next) - hndl->dm.next->dm.prev = hndl->dm.prev; - /* Update next_module of previous entry in target list - * We are using mhdr here as a surrogate for either a - struct modules_header or a dll_module */ - if (hndl->dm.next) { - mhdr.first_module = TADDR_TO_TDATA(hndl->dm.next->dm.dbthis); - mhdr.first_module_size = hndl->dm.next->dm.dbsiz; - } else { - mhdr.first_module = 0; - mhdr.first_module_size = 0; - } - if (!init) - goto exitunltgt; - - if (!init->connect(init)) { - dload_syms_error(syms, iconnect); - errcount += 1; - goto exitunltgt; - } - /* swap bytes in the module header, if needed */ - if (TARGET_ENDIANNESS_DIFFERS(hndl->secn_count & 0x1)) { - swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16), - MODULES_HEADER_BITMAP); - } - if (!init->writemem(init, &mhdr, hndl->dm.prev->dm.dbthis, - &dllview_info, sizeof(struct modules_header) - - sizeof(mhdr.update_flag))) { - dload_syms_error(syms, dlvwrite); - errcount += 1; - } - /* update change counter */ - root->changes += 1; - if (!init->writemem(init, &(root->changes), - root->dbthis + HOST_TO_TADDR - (sizeof(mhdr.first_module) + - sizeof(mhdr.first_module_size)), - &dllview_info, sizeof(mhdr.update_flag))) { - dload_syms_error(syms, dlvwrite); - errcount += 1; - } - init->release(init); -exitunltgt: - /* release target storage */ - dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz); - dllview_info.load_addr = hndl->dm.dbthis; - if (alloc) - alloc->dload_deallocate(alloc, &dllview_info); - root->refcount -= 1; - /* target-side dllview record exists */ -loop_end: -#ifndef DEBUG_HEADER_IN_LOADER - if (root->refcount <= 0) { - /* if all references gone, blow off the header */ - /* our root symbol may be gone due to the Purge above, - but if not, do not destroy the root */ - if (syms->find_matching_symbol - (syms, loader_dllview_root) == NULL) - syms->dload_deallocate(syms, root); - } -#endif -func_end: - /* there is a debug list containing this module */ - syms->dload_deallocate(syms, mhandle); /* release our storage */ - return errcount; -} /* dynamic_unload_module */ - -#if BITS_PER_AU > BITS_PER_BYTE -/************************************************************************* - * Procedure unpack_name - * - * Parameters: - * soffset Byte offset into the string table - * - * Effect: - * Returns a pointer to the string specified by the offset supplied, or - * NULL for error. - * - *********************************************************************** */ -static char *unpack_name(struct dload_state *dlthis, u32 soffset) -{ - u8 tmp, *src; - char *dst; - - if (soffset >= dlthis->dfile_hdr.df_strtab_size) { - dload_error(dlthis, "Bad string table offset " FMT_UI32, - soffset); - return NULL; - } - src = (uint_least8_t *) dlthis->str_head + - (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)); - dst = dlthis->str_temp; - if (soffset & 1) - *dst++ = *src++; /* only 1 character in first word */ - do { - tmp = *src++; - *dst = (tmp >> BITS_PER_BYTE); - if (!(*dst++)) - break; - } while ((*dst++ = tmp & BYTE_MASK)); - dlthis->temp_len = dst - dlthis->str_temp; - /* squirrel away length including terminating null */ - return dlthis->str_temp; -} /* unpack_name */ -#endif diff --git a/drivers/staging/tidspbridge/dynload/dload_internal.h b/drivers/staging/tidspbridge/dynload/dload_internal.h deleted file mode 100644 index b9d079b9619..00000000000 --- a/drivers/staging/tidspbridge/dynload/dload_internal.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * dload_internal.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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 _DLOAD_INTERNAL_ -#define _DLOAD_INTERNAL_ - -#include <linux/types.h> - -/* - * Internal state definitions for the dynamic loader - */ - -/* type used for relocation intermediate results */ -typedef s32 rvalue; - -/* unsigned version of same; must have at least as many bits */ -typedef u32 urvalue; - -/* - * Dynamic loader configuration constants - */ -/* error issued if input has more sections than this limit */ -#define REASONABLE_SECTION_LIMIT 100 - -/* (Addressable unit) value used to clear BSS section */ -#define DLOAD_FILL_BSS 0 - -/* - * Reorder maps explained (?) - * - * The doff file format defines a 32-bit pattern used to determine the - * byte order of an image being read. That value is - * BYTE_RESHUFFLE_VALUE == 0x00010203 - * For purposes of the reorder routine, we would rather have the all-is-OK - * for 32-bits pattern be 0x03020100. This first macro makes the - * translation from doff file header value to MAP value: */ -#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303) -/* This translation is made in dload_headers. Thereafter, the all-is-OK - * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE). - * But sadly, not all bits of the doff file are 32-bit integers. - * The notable exceptions are strings and image bits. - * Strings obey host byte order: */ -#if defined(_BIG_ENDIAN) -#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303) -#else -#define HOST_BYTE_ORDER(cookedmap) (cookedmap) -#endif -/* Target bits consist of target AUs (could be bytes, or 16-bits, - * or 32-bits) stored as an array in host order. A target order - * map is defined by: */ -#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16 -#define TARGET_ORDER(cookedmap) (cookedmap) -#elif TARGET_AU_BITS > 8 -#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202) -#else -#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303) -#endif - -/* forward declaration for handle returned by dynamic loader */ -struct my_handle; - -/* - * a list of module handles, which mirrors the debug list on the target - */ -struct dbg_mirror_root { - /* must be same as dbg_mirror_list; __DLModules address on target */ - u32 dbthis; - struct my_handle *next; /* must be same as dbg_mirror_list */ - u16 changes; /* change counter */ - u16 refcount; /* number of modules referencing this root */ -}; - -struct dbg_mirror_list { - u32 dbthis; - struct my_handle *next, *prev; - struct dbg_mirror_root *root; - u16 dbsiz; - u32 context; /* Save context for .dllview memory allocation */ -}; - -#define VARIABLE_SIZE 1 -/* - * the structure we actually return as an opaque module handle - */ -struct my_handle { - struct dbg_mirror_list dm; /* !!! must be first !!! */ - /* sections following << 1, LSB is set for big-endian target */ - u16 secn_count; - struct ldr_section_info secns[VARIABLE_SIZE]; -}; -#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\ - sizeof(struct ldr_section_info)) -/* real size of my_handle */ - -/* - * reduced symbol structure used for symbols during relocation - */ -struct local_symbol { - s32 value; /* Relocated symbol value */ - s32 delta; /* Original value in input file */ - s16 secnn; /* section number */ - s16 sclass; /* symbol class */ -}; - -/* - * Trampoline data structures - */ -#define TRAMP_NO_GEN_AVAIL 65535 -#define TRAMP_SYM_PREFIX "__$dbTR__" -#define TRAMP_SECT_NAME ".dbTR" -/* MUST MATCH THE LENGTH ABOVE!! */ -#define TRAMP_SYM_PREFIX_LEN 9 -/* Includes NULL termination */ -#define TRAMP_SYM_HEX_ASCII_LEN 9 - -#define GET_CONTAINER(ptr, type, field) ((type *)((unsigned long)ptr -\ - (unsigned long)(&((type *)0)->field))) -#ifndef FIELD_OFFSET -#define FIELD_OFFSET(type, field) ((unsigned long)(&((type *)0)->field)) -#endif - -/* - The trampoline code for the target is located in a table called - "tramp_gen_info" with is indexed by looking up the index in the table - "tramp_map". The tramp_map index is acquired using the target - HASH_FUNC on the relocation type that caused the trampoline. Each - trampoline code table entry MUST follow this format: - - |----------------------------------------------| - | tramp_gen_code_hdr | - |----------------------------------------------| - | Trampoline image code | - | (the raw instruction code for the target) | - |----------------------------------------------| - | Relocation entries for the image code | - |----------------------------------------------| - - This is very similar to how image data is laid out in the DOFF file - itself. - */ -struct tramp_gen_code_hdr { - u32 tramp_code_size; /* in BYTES */ - u32 num_relos; - u32 relo_offset; /* in BYTES */ -}; - -struct tramp_img_pkt { - struct tramp_img_pkt *next; /* MUST BE FIRST */ - u32 base; - struct tramp_gen_code_hdr hdr; - u8 payload[VARIABLE_SIZE]; -}; - -struct tramp_img_dup_relo { - struct tramp_img_dup_relo *next; - struct reloc_record_t relo; -}; - -struct tramp_img_dup_pkt { - struct tramp_img_dup_pkt *next; /* MUST BE FIRST */ - s16 secnn; - u32 offset; - struct image_packet_t img_pkt; - struct tramp_img_dup_relo *relo_chain; - - /* PAYLOAD OF IMG PKT FOLLOWS */ -}; - -struct tramp_sym { - struct tramp_sym *next; /* MUST BE FIRST */ - u32 index; - u32 str_index; - struct local_symbol sym_info; -}; - -struct tramp_string { - struct tramp_string *next; /* MUST BE FIRST */ - u32 index; - char str[VARIABLE_SIZE]; /* NULL terminated */ -}; - -struct tramp_info { - u32 tramp_sect_next_addr; - struct ldr_section_info sect_info; - - struct tramp_sym *symbol_head; - struct tramp_sym *symbol_tail; - u32 tramp_sym_next_index; - struct local_symbol *final_sym_table; - - struct tramp_string *string_head; - struct tramp_string *string_tail; - u32 tramp_string_next_index; - u32 tramp_string_size; - char *final_string_table; - - struct tramp_img_pkt *tramp_pkts; - struct tramp_img_dup_pkt *dup_pkts; -}; - -/* - * States of the .cinit state machine - */ -enum cinit_mode { - CI_COUNT = 0, /* expecting a count */ - CI_ADDRESS, /* expecting an address */ -#if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */ - CI_PARTADDRESS, /* have only part of the address */ -#endif - CI_COPY, /* in the middle of copying data */ - CI_DONE /* end of .cinit table */ -}; - -/* - * The internal state of the dynamic loader, which is passed around as - * an object - */ -struct dload_state { - struct dynamic_loader_stream *strm; /* The module input stream */ - struct dynamic_loader_sym *mysym; /* Symbols for this session */ - /* target memory allocator */ - struct dynamic_loader_allocate *myalloc; - struct dynamic_loader_initialize *myio; /* target memory initializer */ - unsigned myoptions; /* Options parameter dynamic_load_module */ - - char *str_head; /* Pointer to string table */ -#if BITS_PER_AU > BITS_PER_BYTE - char *str_temp; /* Pointer to temporary buffer for strings */ - /* big enough to hold longest string */ - unsigned temp_len; /* length of last temporary string */ - char *xstrings; /* Pointer to buffer for expanded */ - /* strings for sec names */ -#endif - /* Total size of strings for DLLView section names */ - unsigned debug_string_size; - /* Pointer to parallel section info for allocated sections only */ - struct doff_scnhdr_t *sect_hdrs; /* Pointer to section table */ - struct ldr_section_info *ldr_sections; -#if TMS32060 - /* The address of the start of the .bss section */ - ldr_addr bss_run_base; -#endif - struct local_symbol *local_symtab; /* Relocation symbol table */ - - /* pointer to DL section info for the section being relocated */ - struct ldr_section_info *image_secn; - /* change in run address for current section during relocation */ - ldr_addr delta_runaddr; - ldr_addr image_offset; /* offset of current packet in section */ - enum cinit_mode cinit_state; /* current state of cload_cinit() */ - int cinit_count; /* the current count */ - ldr_addr cinit_addr; /* the current address */ - s16 cinit_page; /* the current page */ - /* Handle to be returned by dynamic_load_module */ - struct my_handle *myhandle; - unsigned dload_errcount; /* Total # of errors reported so far */ - /* Number of target sections that require allocation and relocation */ - unsigned allocated_secn_count; -#ifndef TARGET_ENDIANNESS - int big_e_target; /* Target data in big-endian format */ -#endif - /* map for reordering bytes, 0 if not needed */ - u32 reorder_map; - struct doff_filehdr_t dfile_hdr; /* DOFF file header structure */ - struct doff_verify_rec_t verify; /* Verify record */ - - struct tramp_info tramp; /* Trampoline data, if needed */ - - int relstkidx; /* index into relocation value stack */ - /* relocation value stack used in relexp.c */ - rvalue relstk[STATIC_EXPR_STK_SIZE]; - -}; - -#ifdef TARGET_ENDIANNESS -#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS -#else -#define TARGET_BIG_ENDIAN (dlthis->big_e_target) -#endif - -/* - * Exports from cload.c to rest of the world - */ -extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...); -extern void dload_syms_error(struct dynamic_loader_sym *syms, - const char *errtxt, ...); -extern void dload_headers(struct dload_state *dlthis); -extern void dload_strings(struct dload_state *dlthis, bool sec_names_only); -extern void dload_sections(struct dload_state *dlthis); -extern void dload_reorder(void *data, int dsiz, u32 map); -extern u32 dload_checksum(void *data, unsigned siz); - -#if HOST_ENDIANNESS -extern uint32_t dload_reverse_checksum(void *data, unsigned siz); -#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32) -extern uint32_t dload_reverse_checksum16(void *data, unsigned siz); -#endif -#endif - -/* - * exported by reloc.c - */ -extern void dload_relocate(struct dload_state *dlthis, tgt_au_t *data, - struct reloc_record_t *rp, bool *tramps_generated, - bool second_pass); - -extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, - int fieldsz, int offset, unsigned sgn); - -extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data, - int fieldsz, int offset, unsigned sgn); - -/* - * exported by tramp.c - */ -extern bool dload_tramp_avail(struct dload_state *dlthis, - struct reloc_record_t *rp); - -int dload_tramp_generate(struct dload_state *dlthis, s16 secnn, - u32 image_offset, struct image_packet_t *ipacket, - struct reloc_record_t *rp); - -extern int dload_tramp_pkt_udpate(struct dload_state *dlthis, - s16 secnn, u32 image_offset, - struct image_packet_t *ipacket); - -extern int dload_tramp_finalize(struct dload_state *dlthis); - -extern void dload_tramp_cleanup(struct dload_state *dlthis); - -#endif /* _DLOAD_INTERNAL_ */ diff --git a/drivers/staging/tidspbridge/dynload/doff.h b/drivers/staging/tidspbridge/dynload/doff.h deleted file mode 100644 index a7c3145746e..00000000000 --- a/drivers/staging/tidspbridge/dynload/doff.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - * doff.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Structures & definitions used for dynamically loaded modules file format. - * This format is a reformatted version of COFF. It optimizes the layout for - * the dynamic loader. - * - * .dof files, when viewed as a sequence of 32-bit integers, look the same - * on big-endian and little-endian machines. - * - * 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 _DOFF_H -#define _DOFF_H - - -#define BYTE_RESHUFFLE_VALUE 0x00010203 - -/* DOFF file header containing fields categorizing the remainder of the file */ -struct doff_filehdr_t { - - /* string table size, including filename, in bytes */ - u32 df_strtab_size; - - /* entry point if one exists */ - u32 df_entrypt; - - /* identifies byte ordering of file; - * always set to BYTE_RESHUFFLE_VALUE */ - u32 df_byte_reshuffle; - - /* Size of the string table up to and including the last section name */ - /* Size includes the name of the COFF file also */ - u32 df_scn_name_size; - -#ifndef _BIG_ENDIAN - /* number of symbols */ - u16 df_no_syms; - - /* length in bytes of the longest string, including terminating NULL */ - /* excludes the name of the file */ - u16 df_max_str_len; - - /* total number of sections including no-load ones */ - u16 df_no_scns; - - /* number of sections containing target code allocated or downloaded */ - u16 df_target_scns; - - /* unique id for dll file format & version */ - u16 df_doff_version; - - /* identifies ISA */ - u16 df_target_id; - - /* useful file flags */ - u16 df_flags; - - /* section reference for entry point, N_UNDEF for none, */ - /* N_ABS for absolute address */ - s16 df_entry_secn; -#else - /* length of the longest string, including terminating NULL */ - u16 df_max_str_len; - - /* number of symbols */ - u16 df_no_syms; - - /* number of sections containing target code allocated or downloaded */ - u16 df_target_scns; - - /* total number of sections including no-load ones */ - u16 df_no_scns; - - /* identifies ISA */ - u16 df_target_id; - - /* unique id for dll file format & version */ - u16 df_doff_version; - - /* section reference for entry point, N_UNDEF for none, */ - /* N_ABS for absolute address */ - s16 df_entry_secn; - - /* useful file flags */ - u16 df_flags; -#endif - /* checksum for file header record */ - u32 df_checksum; - -}; - -/* flags in the df_flags field */ -#define DF_LITTLE 0x100 -#define DF_BIG 0x200 -#define DF_BYTE_ORDER (DF_LITTLE | DF_BIG) - -/* Supported processors */ -#define TMS470_ID 0x97 -#define LEAD_ID 0x98 -#define TMS32060_ID 0x99 -#define LEAD3_ID 0x9c - -/* Primary processor for loading */ -#if TMS32060 -#define TARGET_ID TMS32060_ID -#endif - -/* Verification record containing values used to test integrity of the bits */ -struct doff_verify_rec_t { - - /* time and date stamp */ - u32 dv_timdat; - - /* checksum for all section records */ - u32 dv_scn_rec_checksum; - - /* checksum for string table */ - u32 dv_str_tab_checksum; - - /* checksum for symbol table */ - u32 dv_sym_tab_checksum; - - /* checksum for verification record */ - u32 dv_verify_rec_checksum; - -}; - -/* String table is an array of null-terminated strings. The first entry is - * the filename, which is added by DLLcreate. No new structure definitions - * are required. - */ - -/* Section Records including information on the corresponding image packets */ -/* - * !!WARNING!! - * - * This structure is expected to match in form ldr_section_info in - * dynamic_loader.h - */ - -struct doff_scnhdr_t { - - s32 ds_offset; /* offset into string table of name */ - s32 ds_paddr; /* RUN address, in target AU */ - s32 ds_vaddr; /* LOAD address, in target AU */ - s32 ds_size; /* section size, in target AU */ -#ifndef _BIG_ENDIAN - u16 ds_page; /* memory page id */ - u16 ds_flags; /* section flags */ -#else - u16 ds_flags; /* section flags */ - u16 ds_page; /* memory page id */ -#endif - u32 ds_first_pkt_offset; - /* Absolute byte offset into the file */ - /* where the first image record resides */ - - s32 ds_nipacks; /* number of image packets */ - -}; - -/* Symbol table entry */ -struct doff_syment_t { - - s32 dn_offset; /* offset into string table of name */ - s32 dn_value; /* value of symbol */ -#ifndef _BIG_ENDIAN - s16 dn_scnum; /* section number */ - s16 dn_sclass; /* storage class */ -#else - s16 dn_sclass; /* storage class */ - s16 dn_scnum; /* section number, 1-based */ -#endif - -}; - -/* special values for dn_scnum */ -#define DN_UNDEF 0 /* undefined symbol */ -#define DN_ABS (-1) /* value of symbol is absolute */ -/* special values for dn_sclass */ -#define DN_EXT 2 -#define DN_STATLAB 20 -#define DN_EXTLAB 21 - -/* Default value of image bits in packet */ -/* Configurable by user on the command line */ -#define IMAGE_PACKET_SIZE 1024 - -/* An image packet contains a chunk of data from a section along with */ -/* information necessary for its processing. */ -struct image_packet_t { - - s32 num_relocs; /* number of relocations for */ - /* this packet */ - - s32 packet_size; /* number of bytes in array */ - /* "bits" occupied by */ - /* valid data. Could be */ - /* < IMAGE_PACKET_SIZE to */ - /* prevent splitting a */ - /* relocation across packets. */ - /* Last packet of a section */ - /* will most likely contain */ - /* < IMAGE_PACKET_SIZE bytes */ - /* of valid data */ - - s32 img_chksum; /* Checksum for image packet */ - /* and the corresponding */ - /* relocation records */ - - u8 *img_data; /* Actual data in section */ - -}; - -/* The relocation structure definition matches the COFF version. Offsets */ -/* however are relative to the image packet base not the section base. */ -struct reloc_record_t { - - s32 vaddr; - - /* expressed in target AUs */ - - union { - struct { -#ifndef _BIG_ENDIAN - u8 _offset; /* bit offset of rel fld */ - u8 _fieldsz; /* size of rel fld */ - u8 _wordsz; /* # bytes containing rel fld */ - u8 _dum1; - u16 _dum2; - u16 _type; -#else - unsigned _dum1:8; - unsigned _wordsz:8; /* # bytes containing rel fld */ - unsigned _fieldsz:8; /* size of rel fld */ - unsigned _offset:8; /* bit offset of rel fld */ - u16 _type; - u16 _dum2; -#endif - } _r_field; - - struct { - u32 _spc; /* image packet relative PC */ -#ifndef _BIG_ENDIAN - u16 _dum; - u16 _type; /* relocation type */ -#else - u16 _type; /* relocation type */ - u16 _dum; -#endif - } _r_spc; - - struct { - u32 _uval; /* constant value */ -#ifndef _BIG_ENDIAN - u16 _dum; - u16 _type; /* relocation type */ -#else - u16 _type; /* relocation type */ - u16 _dum; -#endif - } _r_uval; - - struct { - s32 _symndx; /* 32-bit sym tbl index */ -#ifndef _BIG_ENDIAN - u16 _disp; /* extra addr encode data */ - u16 _type; /* relocation type */ -#else - u16 _type; /* relocation type */ - u16 _disp; /* extra addr encode data */ -#endif - } _r_sym; - } _u_reloc; - -}; - -/* abbreviations for convenience */ -#ifndef TYPE -#define TYPE _u_reloc._r_sym._type -#define UVAL _u_reloc._r_uval._uval -#define SYMNDX _u_reloc._r_sym._symndx -#define OFFSET _u_reloc._r_field._offset -#define FIELDSZ _u_reloc._r_field._fieldsz -#define WORDSZ _u_reloc._r_field._wordsz -#define R_DISP _u_reloc._r_sym._disp -#endif - -/**************************************************************************** */ -/* */ -/* Important DOFF macros used for file processing */ -/* */ -/**************************************************************************** */ - -/* DOFF Versions */ -#define DOFF0 0 - -/* Return the address/size >= to addr that is at a 32-bit boundary */ -/* This assumes that a byte is 8 bits */ -#define DOFF_ALIGN(addr) (((addr) + 3) & ~3UL) - -/**************************************************************************** */ -/* */ -/* The DOFF section header flags field is laid out as follows: */ -/* */ -/* Bits 0-3 : Section Type */ -/* Bit 4 : Set when section requires target memory to be allocated by DL */ -/* Bit 5 : Set when section requires downloading */ -/* Bits 8-11: Alignment, same as COFF */ -/* */ -/**************************************************************************** */ - -/* Enum for DOFF section types (bits 0-3 of flag): See dynamic_loader.h */ -#define DS_SECTION_TYPE_MASK 0xF -/* DS_ALLOCATE indicates whether a section needs space on the target */ -#define DS_ALLOCATE_MASK 0x10 -/* DS_DOWNLOAD indicates that the loader needs to copy bits */ -#define DS_DOWNLOAD_MASK 0x20 -/* Section alignment requirement in AUs */ -#define DS_ALIGNMENT_SHIFT 8 - -static inline bool dload_check_type(struct doff_scnhdr_t *sptr, u32 flag) -{ - return (sptr->ds_flags & DS_SECTION_TYPE_MASK) == flag; -} -static inline bool ds_needs_allocation(struct doff_scnhdr_t *sptr) -{ - return sptr->ds_flags & DS_ALLOCATE_MASK; -} - -static inline bool ds_needs_download(struct doff_scnhdr_t *sptr) -{ - return sptr->ds_flags & DS_DOWNLOAD_MASK; -} - -static inline int ds_alignment(u16 ds_flags) -{ - return 1 << ((ds_flags >> DS_ALIGNMENT_SHIFT) & DS_SECTION_TYPE_MASK); -} - - -#endif /* _DOFF_H */ diff --git a/drivers/staging/tidspbridge/dynload/getsection.c b/drivers/staging/tidspbridge/dynload/getsection.c deleted file mode 100644 index e0b37714dd6..00000000000 --- a/drivers/staging/tidspbridge/dynload/getsection.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * getsection.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -#include <dspbridge/getsection.h> -#include "header.h" - -/* - * Error strings - */ -static const char readstrm[] = { "Error reading %s from input stream" }; -static const char seek[] = { "Set file position to %d failed" }; -static const char isiz[] = { "Bad image packet size %d" }; -static const char err_checksum[] = { "Checksum failed on %s" }; - -static const char err_reloc[] = { "dload_get_section unable to read" - "sections containing relocation entries" -}; - -#if BITS_PER_AU > BITS_PER_BYTE -static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" }; -static const char stbl[] = { "Bad string table offset " FMT_UI32 }; -#endif - -/************************************************************** */ -/********************* SUPPORT FUNCTIONS ********************** */ -/************************************************************** */ - -#if BITS_PER_AU > BITS_PER_BYTE -/************************************************************************** - * Procedure unpack_sec_name - * - * Parameters: - * dlthis Handle from dload_module_open for this module - * soffset Byte offset into the string table - * dst Place to store the expanded string - * - * Effect: - * Stores a string from the string table into the destination, expanding - * it in the process. Returns a pointer just past the end of the stored - * string on success, or NULL on failure. - * - ************************************************************************ */ -static char *unpack_sec_name(struct dload_state *dlthis, u32 soffset, char *dst) -{ - u8 tmp, *src; - - if (soffset >= dlthis->dfile_hdr.df_scn_name_size) { - dload_error(dlthis, stbl, soffset); - return NULL; - } - src = (u8 *) dlthis->str_head + - (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)); - if (soffset & 1) - *dst++ = *src++; /* only 1 character in first word */ - do { - tmp = *src++; - *dst = (tmp >> BITS_PER_BYTE) - if (!(*dst++)) - break; - } while ((*dst++ = tmp & BYTE_MASK)); - - return dst; -} - -/************************************************************************** - * Procedure expand_sec_names - * - * Parameters: - * dlthis Handle from dload_module_open for this module - * - * Effect: - * Allocates a buffer, unpacks and copies strings from string table into it. - * Stores a pointer to the buffer into a state variable. - ************************************************************************* */ -static void expand_sec_names(struct dload_state *dlthis) -{ - char *xstrings, *curr, *next; - u32 xsize; - u16 sec; - struct ldr_section_info *shp; - /* assume worst-case size requirement */ - xsize = dlthis->dfile_hdr.df_max_str_len * dlthis->dfile_hdr.df_no_scns; - xstrings = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, xsize); - if (xstrings == NULL) { - dload_error(dlthis, err_alloc, xsize); - return; - } - dlthis->xstrings = xstrings; - /* For each sec, copy and expand its name */ - curr = xstrings; - for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { - shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec]; - next = unpack_sec_name(dlthis, *(u32 *) &shp->name, curr); - if (next == NULL) - break; /* error */ - shp->name = curr; - curr = next; - } -} - -#endif - -/************************************************************** */ -/********************* EXPORTED FUNCTIONS ********************* */ -/************************************************************** */ - -/************************************************************************** - * Procedure dload_module_open - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side malloc/free and error reporting functions. - * Other methods are unused. - * - * Effect: - * Reads header information from a dynamic loader module using the - specified - * stream object, and returns a handle for the module information. This - * handle may be used in subsequent query calls to obtain information - * contained in the module. - * - * Returns: - * NULL if an error is encountered, otherwise a module handle for use - * in subsequent operations. - ************************************************************************* */ -void *dload_module_open(struct dynamic_loader_stream *module, - struct dynamic_loader_sym *syms) -{ - struct dload_state *dlthis; /* internal state for this call */ - unsigned *dp, sz; - u32 sec_start; -#if BITS_PER_AU <= BITS_PER_BYTE - u16 sec; -#endif - - /* Check that mandatory arguments are present */ - if (!module || !syms) { - if (syms != NULL) - dload_syms_error(syms, "Required parameter is NULL"); - - return NULL; - } - - dlthis = (struct dload_state *) - syms->dload_allocate(syms, sizeof(struct dload_state)); - if (!dlthis) { - /* not enough storage */ - dload_syms_error(syms, "Can't allocate module info"); - return NULL; - } - - /* clear our internal state */ - dp = (unsigned *)dlthis; - for (sz = sizeof(struct dload_state) / sizeof(unsigned); - sz > 0; sz -= 1) - *dp++ = 0; - - dlthis->strm = module; - dlthis->mysym = syms; - - /* read in the doff image and store in our state variable */ - dload_headers(dlthis); - - if (!dlthis->dload_errcount) - dload_strings(dlthis, true); - - /* skip ahead past the unread portion of the string table */ - sec_start = sizeof(struct doff_filehdr_t) + - sizeof(struct doff_verify_rec_t) + - BYTE_TO_HOST(DOFF_ALIGN(dlthis->dfile_hdr.df_strtab_size)); - - if (dlthis->strm->set_file_posn(dlthis->strm, sec_start) != 0) { - dload_error(dlthis, seek, sec_start); - return NULL; - } - - if (!dlthis->dload_errcount) - dload_sections(dlthis); - - if (dlthis->dload_errcount) { - dload_module_close(dlthis); /* errors, blow off our state */ - dlthis = NULL; - return NULL; - } -#if BITS_PER_AU > BITS_PER_BYTE - /* Expand all section names from the string table into the */ - /* state variable, and convert section names from a relative */ - /* string table offset to a pointers to the expanded string. */ - expand_sec_names(dlthis); -#else - /* Convert section names from a relative string table offset */ - /* to a pointer into the string table. */ - for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { - struct ldr_section_info *shp = - (struct ldr_section_info *)&dlthis->sect_hdrs[sec]; - shp->name = dlthis->str_head + *(u32 *) &shp->name; - } -#endif - - return dlthis; -} - -/*************************************************************************** - * Procedure dload_get_section_info - * - * Parameters: - * minfo Handle from dload_module_open for this module - * section_name Pointer to the string name of the section desired - * section_info Address of a section info structure pointer to be - * initialized - * - * Effect: - * Finds the specified section in the module information, and initializes - * the provided struct ldr_section_info pointer. - * - * Returns: - * true for success, false for section not found - ************************************************************************* */ -int dload_get_section_info(void *minfo, const char *section_name, - const struct ldr_section_info **const section_info) -{ - struct dload_state *dlthis; - struct ldr_section_info *shp; - u16 sec; - - dlthis = (struct dload_state *)minfo; - if (!dlthis) - return false; - - for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { - shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec]; - if (strcmp(section_name, shp->name) == 0) { - *section_info = shp; - return true; - } - } - - return false; -} - -#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32)) - -/************************************************************************** - * Procedure dload_get_section - * - * Parameters: - * minfo Handle from dload_module_open for this module - * section_info Pointer to a section info structure for the desired - * section - * section_data Buffer to contain the section initialized data - * - * Effect: - * Copies the initialized data for the specified section into the - * supplied buffer. - * - * Returns: - * true for success, false for section not found - ************************************************************************* */ -int dload_get_section(void *minfo, - const struct ldr_section_info *section_info, - void *section_data) -{ - struct dload_state *dlthis; - u32 pos; - struct doff_scnhdr_t *sptr = NULL; - s32 nip; - struct image_packet_t ipacket; - s32 ipsize; - u32 checks; - s8 *dest = (s8 *) section_data; - - dlthis = (struct dload_state *)minfo; - if (!dlthis) - return false; - sptr = (struct doff_scnhdr_t *)section_info; - if (sptr == NULL) - return false; - - /* skip ahead to the start of the first packet */ - pos = BYTE_TO_HOST(DOFF_ALIGN((u32) sptr->ds_first_pkt_offset)); - if (dlthis->strm->set_file_posn(dlthis->strm, pos) != 0) { - dload_error(dlthis, seek, pos); - return false; - } - - nip = sptr->ds_nipacks; - while ((nip -= 1) >= 0) { /* for each packet */ - /* get the fixed header bits */ - if (dlthis->strm->read_buffer(dlthis->strm, &ipacket, - IPH_SIZE) != IPH_SIZE) { - dload_error(dlthis, readstrm, "image packet"); - return false; - } - /* reorder the header if need be */ - if (dlthis->reorder_map) - dload_reorder(&ipacket, IPH_SIZE, dlthis->reorder_map); - - /* Now read the packet image bits. Note: round the size up to - * the next multiple of 4 bytes; this is what checksum - * routines want. */ - ipsize = BYTE_TO_HOST(DOFF_ALIGN(ipacket.packet_size)); - if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) { - dload_error(dlthis, isiz, ipsize); - return false; - } - if (dlthis->strm->read_buffer - (dlthis->strm, dest, ipsize) != ipsize) { - dload_error(dlthis, readstrm, "image packet"); - return false; - } - /* reorder the bytes if need be */ -#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16) - if (dlthis->reorder_map) - dload_reorder(dest, ipsize, dlthis->reorder_map); - - checks = dload_checksum(dest, ipsize); -#else - if (dlthis->dfile_hdr.df_byte_reshuffle != - TARGET_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) { - /* put image bytes in big-endian order, not PC order */ - dload_reorder(dest, ipsize, - TARGET_ORDER(dlthis-> - dfile_hdr.df_byte_reshuffle)); - } -#if TARGET_AU_BITS > 8 - checks = dload_reverse_checksum16(dest, ipsize); -#else - checks = dload_reverse_checksum(dest, ipsize); -#endif -#endif - checks += dload_checksum(&ipacket, IPH_SIZE); - - /* NYI: unable to handle relocation entries here. Reloc - * entries referring to fields that span the packet boundaries - * may result in packets of sizes that are not multiple of - * 4 bytes. Our checksum implementation works on 32-bit words - * only. */ - if (ipacket.num_relocs != 0) { - dload_error(dlthis, err_reloc, ipsize); - return false; - } - - if (~checks) { - dload_error(dlthis, err_checksum, "image packet"); - return false; - } - - /*Advance destination ptr by the size of the just-read packet */ - dest += ipsize; - } - - return true; -} - -/*************************************************************************** - * Procedure dload_module_close - * - * Parameters: - * minfo Handle from dload_module_open for this module - * - * Effect: - * Releases any storage associated with the module handle. On return, - * the module handle is invalid. - * - * Returns: - * Zero for success. On error, the number of errors detected is returned. - * Individual errors are reported using syms->error_report(), where syms was - * an argument to dload_module_open - ************************************************************************* */ -void dload_module_close(void *minfo) -{ - struct dload_state *dlthis; - - dlthis = (struct dload_state *)minfo; - if (!dlthis) - return; - - if (dlthis->str_head) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->str_head); - - if (dlthis->sect_hdrs) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->sect_hdrs); - -#if BITS_PER_AU > BITS_PER_BYTE - if (dlthis->xstrings) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->xstrings); - -#endif - - dlthis->mysym->dload_deallocate(dlthis->mysym, dlthis); -} diff --git a/drivers/staging/tidspbridge/dynload/header.h b/drivers/staging/tidspbridge/dynload/header.h deleted file mode 100644 index 5b50a15a343..00000000000 --- a/drivers/staging/tidspbridge/dynload/header.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * header.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -#include <linux/string.h> -#define DL_STRCMP strcmp - -/* maximum parenthesis nesting in relocation stack expressions */ -#define STATIC_EXPR_STK_SIZE 10 - -#include <linux/types.h> - -#include "doff.h" -#include <dspbridge/dynamic_loader.h> -#include "params.h" -#include "dload_internal.h" -#include "reloc_table.h" - -/* - * Plausibility limits - * - * These limits are imposed upon the input DOFF file as a check for validity. - * They are hard limits, in that the load will fail if they are exceeded. - * The numbers selected are arbitrary, in that the loader implementation does - * not require these limits. - */ - -/* maximum number of bytes in string table */ -#define MAX_REASONABLE_STRINGTAB (0x100000) -/* maximum number of code,data,etc. sections */ -#define MAX_REASONABLE_SECTIONS (200) -/* maximum number of linker symbols */ -#define MAX_REASONABLE_SYMBOLS (100000) - -/* shift count to align F_BIG with DLOAD_LITTLE */ -#define ALIGN_COFF_ENDIANNESS 7 -#define ENDIANNESS_MASK (DF_BYTE_ORDER >> ALIGN_COFF_ENDIANNESS) diff --git a/drivers/staging/tidspbridge/dynload/module_list.h b/drivers/staging/tidspbridge/dynload/module_list.h deleted file mode 100644 index a216bb131a4..00000000000 --- a/drivers/staging/tidspbridge/dynload/module_list.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * dspbridge/mpu_driver/src/dynload/module_list.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2008 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. - */ - -/* - * This C header file gives the layout of the data structure created by the - * dynamic loader to describe the set of modules loaded into the DSP. - * - * Linked List Structure: - * ---------------------- - * The data structure defined here is a singly-linked list. The list - * represents the set of modules which are currently loaded in the DSP memory. - * The first entry in the list is a header record which contains a flag - * representing the state of the list. The rest of the entries in the list - * are module records. - * - * Global symbol _DLModules designates the first record in the list (i.e. the - * header record). This symbol must be defined in any program that wishes to - * use DLLview plug-in. - * - * String Representation: - * ---------------------- - * The string names of the module and its sections are stored in a block of - * memory which follows the module record itself. The strings are ordered: - * module name first, followed by section names in order from the first - * section to the last. String names are tightly packed arrays of 8-bit - * characters (two characters per 16-bit word on the C55x). Strings are - * zero-byte-terminated. - * - * Creating and updating the list: - * ------------------------------- - * Upon loading a new module into the DSP memory the dynamic loader inserts a - * new module record as the first module record in the list. The fields of - * this module record are initialized to reflect the properties of the module. - * The dynamic loader does NOT increment the flag/counter in the list's header - * record. - * - * Upon unloading a module from the DSP memory the dynamic loader removes the - * module's record from this list. The dynamic loader also increments the - * flag/counter in the list's header record to indicate that the list has been - * changed. - */ - -#ifndef _MODULE_LIST_H_ -#define _MODULE_LIST_H_ - -#include <linux/types.h> - -/* Global pointer to the modules_header structure */ -#define MODULES_HEADER "_DLModules" -#define MODULES_HEADER_NO_UNDERSCORE "DLModules" - -/* Initial version number */ -#define INIT_VERSION 1 - -/* Verification number -- to be recorded in each module record */ -#define VERIFICATION 0x79 - -/* forward declarations */ -struct dll_module; -struct dll_sect; - -/* the first entry in the list is the modules_header record; - * its address is contained in the global _DLModules pointer */ -struct modules_header { - - /* - * Address of the first dll_module record in the list or NULL. - * Note: for C55x this is a word address (C55x data is - * word-addressable) - */ - u32 first_module; - - /* Combined storage size (in target addressable units) of the - * dll_module record which follows this header record, or zero - * if the list is empty. This size includes the module's string table. - * Note: for C55x the unit is a 16-bit word */ - u16 first_module_size; - - /* Counter is incremented whenever a module record is removed from - * the list */ - u16 update_flag; - -}; - -/* for each 32-bits in above structure, a bitmap, LSB first, whose bits are: - * 0 => a 32-bit value, 1 => 2 16-bit values */ -/* swapping bitmap for type modules_header */ -#define MODULES_HEADER_BITMAP 0x2 - -/* information recorded about each section in a module */ -struct dll_sect { - - /* Load-time address of the section. - * Note: for C55x this is a byte address for program sections, and - * a word address for data sections. C55x program memory is - * byte-addressable, while data memory is word-addressable. */ - u32 sect_load_adr; - - /* Run-time address of the section. - * Note 1: for C55x this is a byte address for program sections, and - * a word address for data sections. - * Note 2: for C55x two most significant bits of this field indicate - * the section type: '00' for a code section, '11' for a data section - * (C55 addresses are really only 24-bits wide). */ - u32 sect_run_adr; - -}; - -/* the rest of the entries in the list are module records */ -struct dll_module { - - /* Address of the next dll_module record in the list, or 0 if this is - * the last record in the list. - * Note: for C55x this is a word address (C55x data is - * word-addressable) */ - u32 next_module; - - /* Combined storage size (in target addressable units) of the - * dll_module record which follows this one, or zero if this is the - * last record in the list. This size includes the module's string - * table. - * Note: for C55x the unit is a 16-bit word. */ - u16 next_module_size; - - /* version number of the tooling; set to INIT_VERSION for Phase 1 */ - u16 version; - - /* the verification word; set to VERIFICATION */ - u16 verification; - - /* Number of sections in the sects array */ - u16 num_sects; - - /* Module's "unique" id; copy of the timestamp from the host - * COFF file */ - u32 timestamp; - - /* Array of num_sects elements of the module's section records */ - struct dll_sect sects[1]; -}; - -/* for each 32 bits in above structure, a bitmap, LSB first, whose bits are: - * 0 => a 32-bit value, 1 => 2 16-bit values */ -#define DLL_MODULE_BITMAP 0x6 /* swapping bitmap for type dll_module */ - -#endif /* _MODULE_LIST_H_ */ diff --git a/drivers/staging/tidspbridge/dynload/params.h b/drivers/staging/tidspbridge/dynload/params.h deleted file mode 100644 index d797fcd3b66..00000000000 --- a/drivers/staging/tidspbridge/dynload/params.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * params.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This file defines host and target properties for all machines - * supported by the dynamic loader. To be tedious... - * - * host: the machine on which the dynamic loader runs - * target: the machine that the dynamic loader is loading - * - * Host and target may or may not be the same, depending upon the particular - * use. - * - * 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 Properties - * - **************************************************************************** */ - -#define BITS_PER_BYTE 8 /* bits in the standard PC/SUN byte */ -#define LOG_BITS_PER_BYTE 3 /* log base 2 of same */ -#define BYTE_MASK ((1U<<BITS_PER_BYTE)-1) - -#if defined(__TMS320C55X__) || defined(_TMS320C5XX) -#define BITS_PER_AU 16 -#define LOG_BITS_PER_AU 4 - /* use this print string in error messages for uint32_t */ -#define FMT_UI32 "0x%lx" -#define FMT8_UI32 "%08lx" /* same but no 0x, fixed width field */ -#else -/* bits in the smallest addressable data storage unit */ -#define BITS_PER_AU 8 -/* log base 2 of the same; useful for shift counts */ -#define LOG_BITS_PER_AU 3 -#define FMT_UI32 "0x%x" -#define FMT8_UI32 "%08x" -#endif - -/* generic fastest method for swapping bytes and shorts */ -#define SWAP32BY16(zz) (((zz) << 16) | ((zz) >> 16)) -#define SWAP16BY8(zz) (((zz) << 8) | ((zz) >> 8)) - -/* !! don't be tempted to insert type definitions here; use <stdint.h> !! */ - -/****************************************************************************** - * - * Target Properties - * - **************************************************************************** */ - -/*-------------------------------------------------------------------------- */ -/* TMS320C6x Target Specific Parameters (byte-addressable) */ -/*-------------------------------------------------------------------------- */ -#if TMS32060 -#define MEMORG 0x0L /* Size of configured memory */ -#define MEMSIZE 0x0L /* (full address space) */ - -#define CINIT_ALIGN 8 /* alignment of cinit record in TDATA AUs */ -#define CINIT_COUNT 4 /* width of count field in TDATA AUs */ -#define CINIT_ADDRESS 4 /* width of address field in TDATA AUs */ -#define CINIT_PAGE_BITS 0 /* Number of LSBs of address that - * are page number */ - -#define LENIENT_SIGNED_RELEXPS 0 /* DOES SIGNED ALLOW MAX UNSIGNED */ - -#undef TARGET_ENDIANNESS /* may be big or little endian */ - -/* align a target address to a word boundary */ -#define TARGET_WORD_ALIGN(zz) (((zz) + 0x3) & -0x4) -#endif - -/*-------------------------------------------------------------------------- - * - * DEFAULT SETTINGS and DERIVED PROPERTIES - * - * This section establishes defaults for values not specified above - *-------------------------------------------------------------------------- */ -#ifndef TARGET_AU_BITS -#define TARGET_AU_BITS 8 /* width of the target addressable unit */ -#define LOG_TARGET_AU_BITS 3 /* log2 of same */ -#endif - -#ifndef CINIT_DEFAULT_PAGE -#define CINIT_DEFAULT_PAGE 0 /* default .cinit page number */ -#endif - -#ifndef DATA_RUN2LOAD -#define DATA_RUN2LOAD(zz) (zz) /* translate data run address to load address */ -#endif - -#ifndef DBG_LIST_PAGE -#define DBG_LIST_PAGE 0 /* page number for .dllview section */ -#endif - -#ifndef TARGET_WORD_ALIGN -/* align a target address to a word boundary */ -#define TARGET_WORD_ALIGN(zz) (zz) -#endif - -#ifndef TDATA_TO_TADDR -#define TDATA_TO_TADDR(zz) (zz) /* target data address to target AU address */ -#define TADDR_TO_TDATA(zz) (zz) /* target AU address to target data address */ -#define TDATA_AU_BITS TARGET_AU_BITS /* bits per data AU */ -#define LOG_TDATA_AU_BITS LOG_TARGET_AU_BITS -#endif - -/* - * - * Useful properties and conversions derived from the above - * - */ - -/* - * Conversions between host and target addresses - */ -#if LOG_BITS_PER_AU == LOG_TARGET_AU_BITS -/* translate target addressable unit to host address */ -#define TADDR_TO_HOST(x) (x) -/* translate host address to target addressable unit */ -#define HOST_TO_TADDR(x) (x) -#elif LOG_BITS_PER_AU > LOG_TARGET_AU_BITS -#define TADDR_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS)) -#define HOST_TO_TADDR(x) ((x) << (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS)) -#else -#define TADDR_TO_HOST(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU)) -#define HOST_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU)) -#endif - -#if LOG_BITS_PER_AU == LOG_TDATA_AU_BITS -/* translate target addressable unit to host address */ -#define TDATA_TO_HOST(x) (x) -/* translate host address to target addressable unit */ -#define HOST_TO_TDATA(x) (x) -/* translate host address to target addressable unit, round up */ -#define HOST_TO_TDATA_ROUND(x) (x) -/* byte offset to host offset, rounded up for TDATA size */ -#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x) -#elif LOG_BITS_PER_AU > LOG_TDATA_AU_BITS -#define TDATA_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) -#define HOST_TO_TDATA(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) -#define HOST_TO_TDATA_ROUND(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) -#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x) -#else -#define TDATA_TO_HOST(x) ((x) << (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) -#define HOST_TO_TDATA(x) ((x) >> (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) -#define HOST_TO_TDATA_ROUND(x) (((x) +\ - (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))-1) >>\ - (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) -#define BYTE_TO_HOST_TDATA_ROUND(x) (BYTE_TO_HOST((x) +\ - (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_BYTE))-1) &\ - -(TDATA_AU_BITS/BITS_PER_AU)) -#endif - -/* - * Input in DOFF format is always expresed in bytes, regardless of loading host - * so we wind up converting from bytes to target and host units even when the - * host is not a byte machine. - */ -#if LOG_BITS_PER_AU == LOG_BITS_PER_BYTE -#define BYTE_TO_HOST(x) (x) -#define BYTE_TO_HOST_ROUND(x) (x) -#define HOST_TO_BYTE(x) (x) -#elif LOG_BITS_PER_AU >= LOG_BITS_PER_BYTE -#define BYTE_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) -#define BYTE_TO_HOST_ROUND(x) ((x + (BITS_PER_AU/BITS_PER_BYTE-1)) >>\ - (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) -#define HOST_TO_BYTE(x) ((x) << (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) -#else -/* lets not try to deal with sub-8-bit byte machines */ -#endif - -#if LOG_TARGET_AU_BITS == LOG_BITS_PER_BYTE -/* translate target addressable unit to byte address */ -#define TADDR_TO_BYTE(x) (x) -/* translate byte address to target addressable unit */ -#define BYTE_TO_TADDR(x) (x) -#elif LOG_TARGET_AU_BITS > LOG_BITS_PER_BYTE -#define TADDR_TO_BYTE(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE)) -#define BYTE_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE)) -#else -/* lets not try to deal with sub-8-bit byte machines */ -#endif - -#ifdef _BIG_ENDIAN -#define HOST_ENDIANNESS 1 -#else -#define HOST_ENDIANNESS 0 -#endif - -#ifdef TARGET_ENDIANNESS -#define TARGET_ENDIANNESS_DIFFERS(rtend) (HOST_ENDIANNESS^TARGET_ENDIANNESS) -#elif HOST_ENDIANNESS -#define TARGET_ENDIANNESS_DIFFERS(rtend) (!(rtend)) -#else -#define TARGET_ENDIANNESS_DIFFERS(rtend) (rtend) -#endif - -/* the unit in which we process target image data */ -#if TARGET_AU_BITS <= 8 -typedef u8 tgt_au_t; -#elif TARGET_AU_BITS <= 16 -typedef u16 tgt_au_t; -#else -typedef u32 tgt_au_t; -#endif - -/* size of that unit */ -#if TARGET_AU_BITS < BITS_PER_AU -#define TGTAU_BITS BITS_PER_AU -#define LOG_TGTAU_BITS LOG_BITS_PER_AU -#else -#define TGTAU_BITS TARGET_AU_BITS -#define LOG_TGTAU_BITS LOG_TARGET_AU_BITS -#endif diff --git a/drivers/staging/tidspbridge/dynload/reloc.c b/drivers/staging/tidspbridge/dynload/reloc.c deleted file mode 100644 index 463abdb6392..00000000000 --- a/drivers/staging/tidspbridge/dynload/reloc.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * reloc.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -#include "header.h" - -#if TMS32060 -/* the magic symbol for the start of BSS */ -static const char bsssymbol[] = { ".bss" }; -#endif - -#if TMS32060 -#include "reloc_table_c6000.c" -#endif - -#if TMS32060 -/* From coff.h - ignore these relocation operations */ -#define R_C60ALIGN 0x76 /* C60: Alignment info for compressor */ -#define R_C60FPHEAD 0x77 /* C60: Explicit assembly directive */ -#define R_C60NOCMP 0x100 /* C60: Don't compress this code scn */ -#endif - -/************************************************************************** - * Procedure dload_unpack - * - * Parameters: - * data pointer to storage unit containing lowest host address of - * image data - * fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU - * offset Offset from LSB, 0 <= offset < BITS_PER_AU - * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY) - * - * Effect: - * Extracts the specified field and returns it. - ************************************************************************* */ -rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, int fieldsz, - int offset, unsigned sgn) -{ - register rvalue objval; - register int shift, direction; - register tgt_au_t *dp = data; - - fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */ - /* * collect up enough bits to contain the desired field */ - if (TARGET_BIG_ENDIAN) { - dp += (fieldsz + offset) >> LOG_TGTAU_BITS; - direction = -1; - } else - direction = 1; - objval = *dp >> offset; - shift = TGTAU_BITS - offset; - while (shift <= fieldsz) { - dp += direction; - objval += (rvalue) *dp << shift; - shift += TGTAU_BITS; - } - - /* * sign or zero extend the value appropriately */ - if (sgn == ROP_UNS) - objval &= (2 << fieldsz) - 1; - else { - shift = sizeof(rvalue) * BITS_PER_AU - 1 - fieldsz; - objval = (objval << shift) >> shift; - } - - return objval; - -} /* dload_unpack */ - -/************************************************************************** - * Procedure dload_repack - * - * Parameters: - * val Value to insert - * data Pointer to storage unit containing lowest host address of - * image data - * fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU - * offset Offset from LSB, 0 <= offset < BITS_PER_AU - * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY) - * - * Effect: - * Stuffs the specified value in the specified field. Returns 0 for - * success - * or 1 if the value will not fit in the specified field according to the - * specified signedness rule. - ************************************************************************* */ -static const unsigned char ovf_limit[] = { 1, 2, 2 }; - -int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data, - int fieldsz, int offset, unsigned sgn) -{ - register urvalue objval, mask; - register int shift, direction; - register tgt_au_t *dp = data; - - fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */ - /* clip the bits */ - mask = (2UL << fieldsz) - 1; - objval = (val & mask); - /* * store the bits through the specified mask */ - if (TARGET_BIG_ENDIAN) { - dp += (fieldsz + offset) >> LOG_TGTAU_BITS; - direction = -1; - } else - direction = 1; - - /* insert LSBs */ - *dp = (*dp & ~(mask << offset)) + (objval << offset); - shift = TGTAU_BITS - offset; - /* align mask and objval with AU boundary */ - objval >>= shift; - mask >>= shift; - - while (mask) { - dp += direction; - *dp = (*dp & ~mask) + objval; - objval >>= TGTAU_BITS; - mask >>= TGTAU_BITS; - } - - /* - * check for overflow - */ - if (sgn) { - unsigned tmp = (val >> fieldsz) + (sgn & 0x1); - if (tmp > ovf_limit[sgn - 1]) - return 1; - } - return 0; - -} /* dload_repack */ - -/* lookup table for the scaling amount in a C6x instruction */ -#if TMS32060 -#define SCALE_BITS 4 /* there are 4 bits in the scale field */ -#define SCALE_MASK 0x7 /* we really only use the bottom 3 bits */ -static const u8 c60_scale[SCALE_MASK + 1] = { - 1, 0, 0, 0, 1, 1, 2, 2 -}; -#endif - -/************************************************************************** - * Procedure dload_relocate - * - * Parameters: - * data Pointer to base of image data - * rp Pointer to relocation operation - * - * Effect: - * Performs the specified relocation operation - ************************************************************************* */ -void dload_relocate(struct dload_state *dlthis, tgt_au_t *data, - struct reloc_record_t *rp, bool *tramps_generated, - bool second_pass) -{ - rvalue val, reloc_amt, orig_val = 0; - unsigned int fieldsz = 0; - unsigned int offset = 0; - unsigned int reloc_info = 0; - unsigned int reloc_action = 0; - register int rx = 0; - rvalue *stackp = NULL; - int top; - struct local_symbol *svp = NULL; -#ifdef RFV_SCALE - unsigned int scale = 0; -#endif - struct image_packet_t *img_pkt = NULL; - - /* The image packet data struct is only used during first pass - * relocation in the event that a trampoline is needed. 2nd pass - * relocation doesn't guarantee that data is coming from an - * image_packet_t structure. See cload.c, dload_data for how img_data is - * set. If that changes this needs to be updated!!! */ - if (second_pass == false) - img_pkt = (struct image_packet_t *)((u8 *) data - - sizeof(struct - image_packet_t)); - - rx = HASH_FUNC(rp->TYPE); - while (rop_map1[rx] != rp->TYPE) { - rx = HASH_L(rop_map2[rx]); - if (rx < 0) { -#if TMS32060 - switch (rp->TYPE) { - case R_C60ALIGN: - case R_C60NOCMP: - case R_C60FPHEAD: - /* Ignore these reloc types and return */ - break; - default: - /* Unknown reloc type, print error and return */ - dload_error(dlthis, "Bad coff operator 0x%x", - rp->TYPE); - } -#else - dload_error(dlthis, "Bad coff operator 0x%x", rp->TYPE); -#endif - return; - } - } - rx = HASH_I(rop_map2[rx]); - if ((rx < (sizeof(rop_action) / sizeof(u16))) - && (rx < (sizeof(rop_info) / sizeof(u16))) && (rx > 0)) { - reloc_action = rop_action[rx]; - reloc_info = rop_info[rx]; - } else { - dload_error(dlthis, "Buffer Overflow - Array Index Out " - "of Bounds"); - } - - /* Compute the relocation amount for the referenced symbol, if any */ - reloc_amt = rp->UVAL; - if (RFV_SYM(reloc_info)) { /* relocation uses a symbol reference */ - /* If this is first pass, use the module local symbol table, - * else use the trampoline symbol table. */ - if (second_pass == false) { - if ((u32) rp->SYMNDX < dlthis->dfile_hdr.df_no_syms) { - /* real symbol reference */ - svp = &dlthis->local_symtab[rp->SYMNDX]; - reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ? - svp->delta : svp->value; - } - /* reloc references current section */ - else if (rp->SYMNDX == -1) { - reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ? - dlthis->delta_runaddr : - dlthis->image_secn->run_addr; - } - } - } - /* relocation uses a symbol reference */ - /* Handle stack adjustment */ - val = 0; - top = RFV_STK(reloc_info); - if (top) { - top += dlthis->relstkidx - RSTK_UOP; - if (top >= STATIC_EXPR_STK_SIZE) { - dload_error(dlthis, - "Expression stack overflow in %s at offset " - FMT_UI32, dlthis->image_secn->name, - rp->vaddr + dlthis->image_offset); - return; - } - val = dlthis->relstk[dlthis->relstkidx]; - dlthis->relstkidx = top; - stackp = &dlthis->relstk[top]; - } - /* Derive field position and size, if we need them */ - if (reloc_info & ROP_RW) { /* read or write action in our future */ - fieldsz = RFV_WIDTH(reloc_action); - if (fieldsz) { /* field info from table */ - offset = RFV_POSN(reloc_action); - if (TARGET_BIG_ENDIAN) - /* make sure vaddr is the lowest target - * address containing bits */ - rp->vaddr += RFV_BIGOFF(reloc_info); - } else { /* field info from relocation op */ - fieldsz = rp->FIELDSZ; - offset = rp->OFFSET; - if (TARGET_BIG_ENDIAN) - /* make sure vaddr is the lowest target - address containing bits */ - rp->vaddr += (rp->WORDSZ - offset - fieldsz) - >> LOG_TARGET_AU_BITS; - } - data = (tgt_au_t *) ((char *)data + TADDR_TO_HOST(rp->vaddr)); - /* compute lowest host location of referenced data */ -#if BITS_PER_AU > TARGET_AU_BITS - /* conversion from target address to host address may lose - address bits; add loss to offset */ - if (TARGET_BIG_ENDIAN) { - offset += -((rp->vaddr << LOG_TARGET_AU_BITS) + - offset + fieldsz) & - (BITS_PER_AU - TARGET_AU_BITS); - } else { - offset += (rp->vaddr << LOG_TARGET_AU_BITS) & - (BITS_PER_AU - 1); - } -#endif -#ifdef RFV_SCALE - scale = RFV_SCALE(reloc_info); -#endif - } - /* read the object value from the current image, if so ordered */ - if (reloc_info & ROP_R) { - /* relocation reads current image value */ - val = dload_unpack(dlthis, data, fieldsz, offset, - RFV_SIGN(reloc_info)); - /* Save off the original value in case the relo overflows and - * we can trampoline it. */ - orig_val = val; - -#ifdef RFV_SCALE - val <<= scale; -#endif - } - /* perform the necessary arithmetic */ - switch (RFV_ACTION(reloc_action)) { /* relocation actions */ - case RACT_VAL: - break; - case RACT_ASGN: - val = reloc_amt; - break; - case RACT_ADD: - val += reloc_amt; - break; - case RACT_PCR: - /*----------------------------------------------------------- - * Handle special cases of jumping from absolute sections - * (special reloc type) or to absolute destination - * (symndx == -1). In either case, set the appropriate - * relocation amount to 0. - *----------------------------------------------------------- */ - if (rp->SYMNDX == -1) - reloc_amt = 0; - val += reloc_amt - dlthis->delta_runaddr; - break; - case RACT_ADDISP: - val += rp->R_DISP + reloc_amt; - break; - case RACT_ASGPC: - val = dlthis->image_secn->run_addr + reloc_amt; - break; - case RACT_PLUS: - if (stackp != NULL) - val += *stackp; - break; - case RACT_SUB: - if (stackp != NULL) - val = *stackp - val; - break; - case RACT_NEG: - val = -val; - break; - case RACT_MPY: - if (stackp != NULL) - val *= *stackp; - break; - case RACT_DIV: - if (stackp != NULL) - val = *stackp / val; - break; - case RACT_MOD: - if (stackp != NULL) - val = *stackp % val; - break; - case RACT_SR: - if (val >= sizeof(rvalue) * BITS_PER_AU) - val = 0; - else if (stackp != NULL) - val = (urvalue) *stackp >> val; - break; - case RACT_ASR: - if (val >= sizeof(rvalue) * BITS_PER_AU) - val = sizeof(rvalue) * BITS_PER_AU - 1; - else if (stackp != NULL) - val = *stackp >> val; - break; - case RACT_SL: - if (val >= sizeof(rvalue) * BITS_PER_AU) - val = 0; - else if (stackp != NULL) - val = *stackp << val; - break; - case RACT_AND: - if (stackp != NULL) - val &= *stackp; - break; - case RACT_OR: - if (stackp != NULL) - val |= *stackp; - break; - case RACT_XOR: - if (stackp != NULL) - val ^= *stackp; - break; - case RACT_NOT: - val = ~val; - break; -#if TMS32060 - case RACT_C6SECT: - /* actually needed address of secn containing symbol */ - if (svp != NULL) { - if (rp->SYMNDX >= 0) - if (svp->secnn > 0) - reloc_amt = dlthis->ldr_sections - [svp->secnn - 1].run_addr; - } - /* !!! FALL THRU !!! */ - case RACT_C6BASE: - if (dlthis->bss_run_base == 0) { - struct dynload_symbol *symp; - symp = dlthis->mysym->find_matching_symbol - (dlthis->mysym, bsssymbol); - /* lookup value of global BSS base */ - if (symp) - dlthis->bss_run_base = symp->value; - else - dload_error(dlthis, - "Global BSS base referenced in %s " - "offset" FMT_UI32 " but not " - "defined", - dlthis->image_secn->name, - rp->vaddr + dlthis->image_offset); - } - reloc_amt -= dlthis->bss_run_base; - /* !!! FALL THRU !!! */ - case RACT_C6DSPL: - /* scale factor determined by 3 LSBs of field */ - scale = c60_scale[val & SCALE_MASK]; - offset += SCALE_BITS; - fieldsz -= SCALE_BITS; - val >>= SCALE_BITS; /* ignore the scale field hereafter */ - val <<= scale; - val += reloc_amt; /* do the usual relocation */ - if (((1 << scale) - 1) & val) - dload_error(dlthis, - "Unaligned reference in %s offset " - FMT_UI32, dlthis->image_secn->name, - rp->vaddr + dlthis->image_offset); - break; -#endif - } /* relocation actions */ - /* * Put back result as required */ - if (reloc_info & ROP_W) { /* relocation writes image value */ -#ifdef RFV_SCALE - val >>= scale; -#endif - if (dload_repack(dlthis, val, data, fieldsz, offset, - RFV_SIGN(reloc_info))) { - /* Check to see if this relo can be trampolined, - * but only in first phase relocation. 2nd phase - * relocation cannot trampoline. */ - if ((second_pass == false) && - (dload_tramp_avail(dlthis, rp) == true)) { - - /* Before generating the trampoline, restore - * the value to its original so the 2nd pass - * relo will work. */ - dload_repack(dlthis, orig_val, data, fieldsz, - offset, RFV_SIGN(reloc_info)); - if (!dload_tramp_generate(dlthis, - (dlthis->image_secn - - dlthis->ldr_sections), - dlthis->image_offset, - img_pkt, rp)) { - dload_error(dlthis, - "Failed to " - "generate trampoline for " - "bit overflow"); - dload_error(dlthis, - "Relocation val " FMT_UI32 - " overflows %d bits in %s " - "offset " FMT_UI32, val, - fieldsz, - dlthis->image_secn->name, - dlthis->image_offset + - rp->vaddr); - } else - *tramps_generated = true; - } else { - dload_error(dlthis, "Relocation value " - FMT_UI32 " overflows %d bits in %s" - " offset " FMT_UI32, val, fieldsz, - dlthis->image_secn->name, - dlthis->image_offset + rp->vaddr); - } - } - } else if (top) - *stackp = val; -} /* reloc_value */ diff --git a/drivers/staging/tidspbridge/dynload/reloc_table.h b/drivers/staging/tidspbridge/dynload/reloc_table.h deleted file mode 100644 index 6aab03d4668..00000000000 --- a/drivers/staging/tidspbridge/dynload/reloc_table.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * reloc_table.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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 _RELOC_TABLE_H_ -#define _RELOC_TABLE_H_ -/* - * Table of relocation operator properties - */ -#include <linux/types.h> - -/* How does this relocation operation access the program image? */ -#define ROP_N 0 /* does not access image */ -#define ROP_R 1 /* read from image */ -#define ROP_W 2 /* write to image */ -#define ROP_RW 3 /* read from and write to image */ - -/* For program image access, what are the overflow rules for the bit field? */ -/* Beware! Procedure repack depends on this encoding */ -#define ROP_ANY 0 /* no overflow ever, just truncate the value */ -#define ROP_SGN 1 /* signed field */ -#define ROP_UNS 2 /* unsigned field */ -#define ROP_MAX 3 /* allow maximum range of either signed or unsigned */ - -/* How does the relocation operation use the symbol reference */ -#define ROP_IGN 0 /* no symbol is referenced */ -#define ROP_LIT 0 /* use rp->UVAL literal field */ -#define ROP_SYM 1 /* symbol value is used in relocation */ -#define ROP_SYMD 2 /* delta value vs last link is used */ - -/* How does the reloc op use the stack? */ -#define RSTK_N 0 /* Does not use */ -#define RSTK_POP 1 /* Does a POP */ -#define RSTK_UOP 2 /* Unary op, stack position unaffected */ -#define RSTK_PSH 3 /* Does a push */ - -/* - * Computational actions performed by the dynamic loader - */ -enum dload_actions { - /* don't alter the current val (from stack or mem fetch) */ - RACT_VAL, - /* set value to reference amount (from symbol reference) */ - RACT_ASGN, - RACT_ADD, /* add reference to value */ - RACT_PCR, /* add reference minus PC delta to value */ - RACT_ADDISP, /* add reference plus R_DISP */ - RACT_ASGPC, /* set value to section addr plus reference */ - - RACT_PLUS, /* stack + */ - RACT_SUB, /* stack - */ - RACT_NEG, /* stack unary - */ - - RACT_MPY, /* stack * */ - RACT_DIV, /* stack / */ - RACT_MOD, /* stack % */ - - RACT_SR, /* stack unsigned >> */ - RACT_ASR, /* stack signed >> */ - RACT_SL, /* stack << */ - RACT_AND, /* stack & */ - RACT_OR, /* stack | */ - RACT_XOR, /* stack ^ */ - RACT_NOT, /* stack ~ */ - RACT_C6SECT, /* for C60 R_SECT op */ - RACT_C6BASE, /* for C60 R_BASE op */ - RACT_C6DSPL, /* for C60 scaled 15-bit displacement */ - RACT_PCR23T /* for ARM Thumb long branch */ -}; - -/* - * macros used to extract values - */ -#define RFV_POSN(aaa) ((aaa) & 0xF) -#define RFV_WIDTH(aaa) (((aaa) >> 4) & 0x3F) -#define RFV_ACTION(aaa) ((aaa) >> 10) - -#define RFV_SIGN(iii) (((iii) >> 2) & 0x3) -#define RFV_SYM(iii) (((iii) >> 4) & 0x3) -#define RFV_STK(iii) (((iii) >> 6) & 0x3) -#define RFV_ACCS(iii) ((iii) & 0x3) - -#if (TMS32060) -#define RFV_SCALE(iii) ((iii) >> 11) -#define RFV_BIGOFF(iii) (((iii) >> 8) & 0x7) -#else -#define RFV_BIGOFF(iii) ((iii) >> 8) -#endif - -#endif /* _RELOC_TABLE_H_ */ diff --git a/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c b/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c deleted file mode 100644 index a28bc044249..00000000000 --- a/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * reloc_table_c6000.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -/* Tables generated for c6000 */ - -#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63) -#define HASH_L(zz) ((zz) >> 8) -#define HASH_I(zz) ((zz) & 0xFF) - -static const u16 rop_map1[] = { - 0, - 1, - 2, - 20, - 4, - 5, - 6, - 15, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 17, - 18, - 19, - 21, - 16, - 16394, - 16404, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 32, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 40, - 112, - 113, - 65535, - 16384, - 16385, - 16386, - 16387, - 16388, - 16389, - 16390, - 16391, - 16392, - 16393, - 16395, - 16396, - 16397, - 16398, - 16399, - 16400, - 16401, - 16402, - 16403, - 16405, - 16406, - 65535, - 65535, - 65535 -}; - -static const s16 rop_map2[] = { - -256, - -255, - -254, - -245, - -253, - -252, - -251, - -250, - -241, - -240, - -239, - -238, - -237, - -236, - 1813, - 5142, - -248, - -247, - 778, - -244, - -249, - -221, - -211, - -1, - -1, - -1, - -1, - -1, - -1, - -243, - -1, - -1, - -1, - -1, - -1, - -1, - -242, - -233, - -232, - -1, - -231, - -230, - -229, - -228, - -227, - -226, - -225, - -224, - -223, - 5410, - -220, - -219, - -218, - -217, - -216, - -215, - -214, - -213, - 5676, - -210, - -209, - -1, - -1, - -1 -}; - -static const u16 rop_action[] = { - 2560, - 2304, - 2304, - 2432, - 2432, - 2560, - 2176, - 2304, - 2560, - 3200, - 3328, - 3584, - 3456, - 2304, - 4208, - 20788, - 21812, - 3415, - 3245, - 2311, - 4359, - 19764, - 2311, - 3191, - 3280, - 6656, - 7680, - 8704, - 9728, - 10752, - 11776, - 12800, - 13824, - 14848, - 15872, - 16896, - 17920, - 18944, - 0, - 0, - 0, - 0, - 1536, - 1536, - 1536, - 5632, - 512, - 0 -}; - -static const u16 rop_info[] = { - 0, - 35, - 35, - 35, - 35, - 35, - 35, - 35, - 35, - 39, - 39, - 39, - 39, - 35, - 34, - 283, - 299, - 4135, - 4391, - 291, - 33059, - 283, - 295, - 4647, - 4135, - 64, - 64, - 128, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 128, - 201, - 197, - 74, - 70, - 208, - 196, - 200, - 192, - 192, - 66 -}; diff --git a/drivers/staging/tidspbridge/dynload/tramp.c b/drivers/staging/tidspbridge/dynload/tramp.c deleted file mode 100644 index 5f0431305fb..00000000000 --- a/drivers/staging/tidspbridge/dynload/tramp.c +++ /dev/null @@ -1,1143 +0,0 @@ -/* - * tramp.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2009 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. - */ - -#include "header.h" - -#if TMS32060 -#include "tramp_table_c6000.c" -#endif - -#define MAX_RELOS_PER_PASS 4 - -/* - * Function: priv_tramp_sect_tgt_alloc - * Description: Allocate target memory for the trampoline section. The - * target mem size is easily obtained as the next available address. - */ -static int priv_tramp_sect_tgt_alloc(struct dload_state *dlthis) -{ - int ret_val = 0; - struct ldr_section_info *sect_info; - - /* Populate the trampoline loader section and allocate it on the - * target. The section name is ALWAYS the first string in the final - * string table for trampolines. The trampoline section is always - * 1 beyond the total number of allocated sections. */ - sect_info = &dlthis->ldr_sections[dlthis->allocated_secn_count]; - - sect_info->name = dlthis->tramp.final_string_table; - sect_info->size = dlthis->tramp.tramp_sect_next_addr; - sect_info->context = 0; - sect_info->type = - (4 << 8) | DLOAD_TEXT | DS_ALLOCATE_MASK | DS_DOWNLOAD_MASK; - sect_info->page = 0; - sect_info->run_addr = 0; - sect_info->load_addr = 0; - ret_val = dlthis->myalloc->dload_allocate(dlthis->myalloc, - sect_info, - ds_alignment - (sect_info->type)); - - if (ret_val == 0) - dload_error(dlthis, "Failed to allocate target memory for" - " trampoline"); - - return ret_val; -} - -/* - * Function: priv_h2a - * Description: Helper function to convert a hex value to its ASCII - * representation. Used for trampoline symbol name generation. - */ -static u8 priv_h2a(u8 value) -{ - if (value > 0xF) - return 0xFF; - - if (value <= 9) - value += 0x30; - else - value += 0x37; - - return value; -} - -/* - * Function: priv_tramp_sym_gen_name - * Description: Generate a trampoline symbol name (ASCII) using the value - * of the symbol. This places the new name into the user buffer. - * The name is fixed in length and of the form: __$dbTR__xxxxxxxx - * (where "xxxxxxxx" is the hex value). - */ -static void priv_tramp_sym_gen_name(u32 value, char *dst) -{ - u32 i; - char *prefix = TRAMP_SYM_PREFIX; - char *dst_local = dst; - u8 tmp; - - /* Clear out the destination, including the ending NULL */ - for (i = 0; i < (TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN); i++) - *(dst_local + i) = 0; - - /* Copy the prefix to start */ - for (i = 0; i < strlen(TRAMP_SYM_PREFIX); i++) { - *dst_local = *(prefix + i); - dst_local++; - } - - /* Now convert the value passed in to a string equiv of the hex */ - for (i = 0; i < sizeof(value); i++) { -#ifndef _BIG_ENDIAN - tmp = *(((u8 *) &value) + (sizeof(value) - 1) - i); - *dst_local = priv_h2a((tmp & 0xF0) >> 4); - dst_local++; - *dst_local = priv_h2a(tmp & 0x0F); - dst_local++; -#else - tmp = *(((u8 *) &value) + i); - *dst_local = priv_h2a((tmp & 0xF0) >> 4); - dst_local++; - *dst_local = priv_h2a(tmp & 0x0F); - dst_local++; -#endif - } - - /* NULL terminate */ - *dst_local = 0; -} - -/* - * Function: priv_tramp_string_create - * Description: Create a new string specific to the trampoline loading and add - * it to the trampoline string list. This list contains the - * trampoline section name and trampoline point symbols. - */ -static struct tramp_string *priv_tramp_string_create(struct dload_state *dlthis, - u32 str_len, char *str) -{ - struct tramp_string *new_string = NULL; - u32 i; - - /* Create a new string object with the specified size. */ - new_string = - (struct tramp_string *)dlthis->mysym->dload_allocate(dlthis->mysym, - (sizeof - (struct - tramp_string) - + str_len + - 1)); - if (new_string != NULL) { - /* Clear the string first. This ensures the ending NULL is - * present and the optimizer won't touch it. */ - for (i = 0; i < (sizeof(struct tramp_string) + str_len + 1); - i++) - *((u8 *) new_string + i) = 0; - - /* Add this string to our virtual table by assigning it the - * next index and pushing it to the tail of the list. */ - new_string->index = dlthis->tramp.tramp_string_next_index; - dlthis->tramp.tramp_string_next_index++; - dlthis->tramp.tramp_string_size += str_len + 1; - - new_string->next = NULL; - if (dlthis->tramp.string_head == NULL) - dlthis->tramp.string_head = new_string; - else - dlthis->tramp.string_tail->next = new_string; - - dlthis->tramp.string_tail = new_string; - - /* Copy the string over to the new object */ - for (i = 0; i < str_len; i++) - new_string->str[i] = str[i]; - } - - return new_string; -} - -/* - * Function: priv_tramp_string_find - * Description: Walk the trampoline string list and find a match for the - * provided string. If not match is found, NULL is returned. - */ -static struct tramp_string *priv_tramp_string_find(struct dload_state *dlthis, - char *str) -{ - struct tramp_string *cur_str = NULL; - struct tramp_string *ret_val = NULL; - u32 i; - u32 str_len = strlen(str); - - for (cur_str = dlthis->tramp.string_head; - (ret_val == NULL) && (cur_str != NULL); cur_str = cur_str->next) { - /* If the string lengths aren't equal, don't bother - * comparing */ - if (str_len != strlen(cur_str->str)) - continue; - - /* Walk the strings until one of them ends */ - for (i = 0; i < str_len; i++) { - /* If they don't match in the current position then - * break out now, no sense in continuing to look at - * this string. */ - if (str[i] != cur_str->str[i]) - break; - } - - if (i == str_len) - ret_val = cur_str; - } - - return ret_val; -} - -/* - * Function: priv_string_tbl_finalize - * Description: Flatten the trampoline string list into a table of NULL - * terminated strings. This is the same format of string table - * as used by the COFF/DOFF file. - */ -static int priv_string_tbl_finalize(struct dload_state *dlthis) -{ - int ret_val = 0; - struct tramp_string *cur_string; - char *cur_loc; - char *tmp; - - /* Allocate enough space for all strings that have been created. The - * table is simply all strings concatenated together will NULL - * endings. */ - dlthis->tramp.final_string_table = - (char *)dlthis->mysym->dload_allocate(dlthis->mysym, - dlthis->tramp. - tramp_string_size); - if (dlthis->tramp.final_string_table != NULL) { - /* We got our buffer, walk the list and release the nodes as* - * we go */ - cur_loc = dlthis->tramp.final_string_table; - cur_string = dlthis->tramp.string_head; - while (cur_string != NULL) { - /* Move the head/tail pointers */ - dlthis->tramp.string_head = cur_string->next; - if (dlthis->tramp.string_tail == cur_string) - dlthis->tramp.string_tail = NULL; - - /* Copy the string contents */ - for (tmp = cur_string->str; - *tmp != '\0'; tmp++, cur_loc++) - *cur_loc = *tmp; - - /* Pick up the NULL termination since it was missed by - * breaking using it to end the above loop. */ - *cur_loc = '\0'; - cur_loc++; - - /* Free the string node, we don't need it any more. */ - dlthis->mysym->dload_deallocate(dlthis->mysym, - cur_string); - - /* Move our pointer to the next one */ - cur_string = dlthis->tramp.string_head; - } - - /* Update our return value to success */ - ret_val = 1; - } else - dload_error(dlthis, "Failed to allocate trampoline " - "string table"); - - return ret_val; -} - -/* - * Function: priv_tramp_sect_alloc - * Description: Virtually allocate space from the trampoline section. This - * function returns the next offset within the trampoline section - * that is available and moved the next available offset by the - * requested size. NO TARGET ALLOCATION IS DONE AT THIS TIME. - */ -static u32 priv_tramp_sect_alloc(struct dload_state *dlthis, u32 tramp_size) -{ - u32 ret_val; - - /* If the next available address is 0, this is our first allocation. - * Create a section name string to go into the string table . */ - if (dlthis->tramp.tramp_sect_next_addr == 0) { - dload_syms_error(dlthis->mysym, "*** WARNING *** created " - "dynamic TRAMPOLINE section for module %s", - dlthis->str_head); - } - - /* Reserve space for the new trampoline */ - ret_val = dlthis->tramp.tramp_sect_next_addr; - dlthis->tramp.tramp_sect_next_addr += tramp_size; - return ret_val; -} - -/* - * Function: priv_tramp_sym_create - * Description: Allocate and create a new trampoline specific symbol and add - * it to the trampoline symbol list. These symbols will include - * trampoline points as well as the external symbols they - * reference. - */ -static struct tramp_sym *priv_tramp_sym_create(struct dload_state *dlthis, - u32 str_index, - struct local_symbol *tmp_sym) -{ - struct tramp_sym *new_sym = NULL; - u32 i; - - /* Allocate new space for the symbol in the symbol table. */ - new_sym = - (struct tramp_sym *)dlthis->mysym->dload_allocate(dlthis->mysym, - sizeof(struct tramp_sym)); - if (new_sym != NULL) { - for (i = 0; i != sizeof(struct tramp_sym); i++) - *((char *)new_sym + i) = 0; - - /* Assign this symbol the next symbol index for easier - * reference later during relocation. */ - new_sym->index = dlthis->tramp.tramp_sym_next_index; - dlthis->tramp.tramp_sym_next_index++; - - /* Populate the symbol information. At this point any - * trampoline symbols will be the offset location, not the - * final. Copy over the symbol info to start, then be sure to - * get the string index from the trampoline string table. */ - new_sym->sym_info = *tmp_sym; - new_sym->str_index = str_index; - - /* Push the new symbol to the tail of the symbol table list */ - new_sym->next = NULL; - if (dlthis->tramp.symbol_head == NULL) - dlthis->tramp.symbol_head = new_sym; - else - dlthis->tramp.symbol_tail->next = new_sym; - - dlthis->tramp.symbol_tail = new_sym; - } - - return new_sym; -} - -/* - * Function: priv_tramp_sym_get - * Description: Search for the symbol with the matching string index (from - * the trampoline string table) and return the trampoline - * symbol object, if found. Otherwise return NULL. - */ -static struct tramp_sym *priv_tramp_sym_get(struct dload_state *dlthis, - u32 string_index) -{ - struct tramp_sym *sym_found = NULL; - - /* Walk the symbol table list and search vs. the string index */ - for (sym_found = dlthis->tramp.symbol_head; - sym_found != NULL; sym_found = sym_found->next) { - if (sym_found->str_index == string_index) - break; - } - - return sym_found; -} - -/* - * Function: priv_tramp_sym_find - * Description: Search for a trampoline symbol based on the string name of - * the symbol. Return the symbol object, if found, otherwise - * return NULL. - */ -static struct tramp_sym *priv_tramp_sym_find(struct dload_state *dlthis, - char *string) -{ - struct tramp_sym *sym_found = NULL; - struct tramp_string *str_found = NULL; - - /* First, search for the string, then search for the sym based on the - string index. */ - str_found = priv_tramp_string_find(dlthis, string); - if (str_found != NULL) - sym_found = priv_tramp_sym_get(dlthis, str_found->index); - - return sym_found; -} - -/* - * Function: priv_tramp_sym_finalize - * Description: Allocate a flat symbol table for the trampoline section, - * put each trampoline symbol into the table, adjust the - * symbol value based on the section address on the target and - * free the trampoline symbol list nodes. - */ -static int priv_tramp_sym_finalize(struct dload_state *dlthis) -{ - int ret_val = 0; - struct tramp_sym *cur_sym; - struct ldr_section_info *tramp_sect = - &dlthis->ldr_sections[dlthis->allocated_secn_count]; - struct local_symbol *new_sym; - - /* Allocate a table to hold a flattened version of all symbols - * created. */ - dlthis->tramp.final_sym_table = - (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym, - (sizeof(struct local_symbol) * dlthis->tramp. - tramp_sym_next_index)); - if (dlthis->tramp.final_sym_table != NULL) { - /* Walk the list of all symbols, copy it over to the flattened - * table. After it has been copied, the node can be freed as - * it is no longer needed. */ - new_sym = dlthis->tramp.final_sym_table; - cur_sym = dlthis->tramp.symbol_head; - while (cur_sym != NULL) { - /* Pop it off the list */ - dlthis->tramp.symbol_head = cur_sym->next; - if (cur_sym == dlthis->tramp.symbol_tail) - dlthis->tramp.symbol_tail = NULL; - - /* Copy the symbol contents into the flat table */ - *new_sym = cur_sym->sym_info; - - /* Now finalize the symbol. If it is in the tramp - * section, we need to adjust for the section start. - * If it is external then we don't need to adjust at - * all. - * NOTE: THIS CODE ASSUMES THAT THE TRAMPOLINE IS - * REFERENCED LIKE A CALL TO AN EXTERNAL SO VALUE AND - * DELTA ARE THE SAME. SEE THE FUNCTION dload_symbols - * WHERE DN_UNDEF IS HANDLED FOR MORE REFERENCE. */ - if (new_sym->secnn < 0) { - new_sym->value += tramp_sect->load_addr; - new_sym->delta = new_sym->value; - } - - /* Let go of the symbol node */ - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym); - - /* Move to the next node */ - cur_sym = dlthis->tramp.symbol_head; - new_sym++; - } - - ret_val = 1; - } else - dload_error(dlthis, "Failed to alloc trampoline sym table"); - - return ret_val; -} - -/* - * Function: priv_tgt_img_gen - * Description: Allocate storage for and copy the target specific image data - * and fix up its relocations for the new external symbol. If - * a trampoline image packet was successfully created it is added - * to the trampoline list. - */ -static int priv_tgt_img_gen(struct dload_state *dlthis, u32 base, - u32 gen_index, struct tramp_sym *new_ext_sym) -{ - struct tramp_img_pkt *new_img_pkt = NULL; - u32 i; - u32 pkt_size = tramp_img_pkt_size_get(); - u8 *gen_tbl_entry; - u8 *pkt_data; - struct reloc_record_t *cur_relo; - int ret_val = 0; - - /* Allocate a new image packet and set it up. */ - new_img_pkt = - (struct tramp_img_pkt *)dlthis->mysym->dload_allocate(dlthis->mysym, - pkt_size); - if (new_img_pkt != NULL) { - /* Save the base, this is where it goes in the section */ - new_img_pkt->base = base; - - /* Copy over the image data and relos from the target table */ - pkt_data = (u8 *) &new_img_pkt->hdr; - gen_tbl_entry = (u8 *) &tramp_gen_info[gen_index]; - for (i = 0; i < pkt_size; i++) { - *pkt_data = *gen_tbl_entry; - pkt_data++; - gen_tbl_entry++; - } - - /* Update the relocations to point to the external symbol */ - cur_relo = - (struct reloc_record_t *)((u8 *) &new_img_pkt->hdr + - new_img_pkt->hdr.relo_offset); - for (i = 0; i < new_img_pkt->hdr.num_relos; i++) - cur_relo[i].SYMNDX = new_ext_sym->index; - - /* Add it to the trampoline list. */ - new_img_pkt->next = dlthis->tramp.tramp_pkts; - dlthis->tramp.tramp_pkts = new_img_pkt; - - ret_val = 1; - } - - return ret_val; -} - -/* - * Function: priv_pkt_relo - * Description: Take the provided image data and the collection of relocations - * for it and perform the relocations. Note that all relocations - * at this stage are considered SECOND PASS since the original - * image has already been processed in the first pass. This means - * TRAMPOLINES ARE TREATED AS 2ND PASS even though this is really - * the first (and only) relocation that will be performed on them. - */ -static int priv_pkt_relo(struct dload_state *dlthis, tgt_au_t *data, - struct reloc_record_t *rp[], u32 relo_count) -{ - int ret_val = 1; - u32 i; - bool tmp; - - /* Walk through all of the relos and process them. This function is - * the equivalent of relocate_packet() from cload.c, but specialized - * for trampolines and 2nd phase relocations. */ - for (i = 0; i < relo_count; i++) - dload_relocate(dlthis, data, rp[i], &tmp, true); - - return ret_val; -} - -/* - * Function: priv_tramp_pkt_finalize - * Description: Walk the list of all trampoline packets and finalize them. - * Each trampoline image packet will be relocated now that the - * trampoline section has been allocated on the target. Once - * all of the relocations are done the trampoline image data - * is written into target memory and the trampoline packet - * is freed: it is no longer needed after this point. - */ -static int priv_tramp_pkt_finalize(struct dload_state *dlthis) -{ - int ret_val = 1; - struct tramp_img_pkt *cur_pkt = NULL; - struct reloc_record_t *relos[MAX_RELOS_PER_PASS]; - u32 relos_done; - u32 i; - struct reloc_record_t *cur_relo; - struct ldr_section_info *sect_info = - &dlthis->ldr_sections[dlthis->allocated_secn_count]; - - /* Walk the list of trampoline packets and relocate each packet. This - * function is the trampoline equivalent of dload_data() from - * cload.c. */ - cur_pkt = dlthis->tramp.tramp_pkts; - while ((ret_val != 0) && (cur_pkt != NULL)) { - /* Remove the pkt from the list */ - dlthis->tramp.tramp_pkts = cur_pkt->next; - - /* Setup section and image offset information for the relo */ - dlthis->image_secn = sect_info; - dlthis->image_offset = cur_pkt->base; - dlthis->delta_runaddr = sect_info->run_addr; - - /* Walk through all relos for the packet */ - relos_done = 0; - cur_relo = (struct reloc_record_t *)((u8 *) &cur_pkt->hdr + - cur_pkt->hdr.relo_offset); - while (relos_done < cur_pkt->hdr.num_relos) { -#ifdef ENABLE_TRAMP_DEBUG - dload_syms_error(dlthis->mysym, - "===> Trampoline %x branches to %x", - sect_info->run_addr + - dlthis->image_offset, - dlthis-> - tramp.final_sym_table[cur_relo-> - SYMNDX].value); -#endif - - for (i = 0; - ((i < MAX_RELOS_PER_PASS) && - ((i + relos_done) < cur_pkt->hdr.num_relos)); i++) - relos[i] = cur_relo + i; - - /* Do the actual relo */ - ret_val = priv_pkt_relo(dlthis, - (tgt_au_t *) &cur_pkt->payload, - relos, i); - if (ret_val == 0) { - dload_error(dlthis, - "Relocation of trampoline pkt at %x" - " failed", cur_pkt->base + - sect_info->run_addr); - break; - } - - relos_done += i; - cur_relo += i; - } - - /* Make sure we didn't hit a problem */ - if (ret_val != 0) { - /* Relos are done for the packet, write it to the - * target */ - ret_val = dlthis->myio->writemem(dlthis->myio, - &cur_pkt->payload, - sect_info->load_addr + - cur_pkt->base, - sect_info, - BYTE_TO_HOST - (cur_pkt->hdr. - tramp_code_size)); - if (ret_val == 0) { - dload_error(dlthis, - "Write to " FMT_UI32 " failed", - sect_info->load_addr + - cur_pkt->base); - } - - /* Done with the pkt, let it go */ - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt); - - /* Get the next packet to process */ - cur_pkt = dlthis->tramp.tramp_pkts; - } - } - - return ret_val; -} - -/* - * Function: priv_dup_pkt_finalize - * Description: Walk the list of duplicate image packets and finalize them. - * Each duplicate packet will be relocated again for the - * relocations that previously failed and have been adjusted - * to point at a trampoline. Once all relocations for a packet - * have been done, write the packet into target memory. The - * duplicate packet and its relocation chain are all freed - * after use here as they are no longer needed after this. - */ -static int priv_dup_pkt_finalize(struct dload_state *dlthis) -{ - int ret_val = 1; - struct tramp_img_dup_pkt *cur_pkt; - struct tramp_img_dup_relo *cur_relo; - struct reloc_record_t *relos[MAX_RELOS_PER_PASS]; - struct doff_scnhdr_t *sect_hdr = NULL; - s32 i; - - /* Similar to the trampoline pkt finalize, this function walks each dup - * pkt that was generated and performs all relocations that were - * deferred to a 2nd pass. This is the equivalent of dload_data() from - * cload.c, but does not need the additional reorder and checksum - * processing as it has already been done. */ - cur_pkt = dlthis->tramp.dup_pkts; - while ((ret_val != 0) && (cur_pkt != NULL)) { - /* Remove the node from the list, we'll be freeing it - * shortly */ - dlthis->tramp.dup_pkts = cur_pkt->next; - - /* Setup the section and image offset for relocation */ - dlthis->image_secn = &dlthis->ldr_sections[cur_pkt->secnn]; - dlthis->image_offset = cur_pkt->offset; - - /* In order to get the delta run address, we need to reference - * the original section header. It's a bit ugly, but needed - * for relo. */ - i = (s32) (dlthis->image_secn - dlthis->ldr_sections); - sect_hdr = dlthis->sect_hdrs + i; - dlthis->delta_runaddr = sect_hdr->ds_paddr; - - /* Walk all relos in the chain and process each. */ - cur_relo = cur_pkt->relo_chain; - while (cur_relo != NULL) { - /* Process them a chunk at a time to be efficient */ - for (i = 0; (i < MAX_RELOS_PER_PASS) - && (cur_relo != NULL); - i++, cur_relo = cur_relo->next) { - relos[i] = &cur_relo->relo; - cur_pkt->relo_chain = cur_relo->next; - } - - /* Do the actual relo */ - ret_val = priv_pkt_relo(dlthis, - cur_pkt->img_pkt.img_data, - relos, i); - if (ret_val == 0) { - dload_error(dlthis, - "Relocation of dup pkt at %x" - " failed", cur_pkt->offset + - dlthis->image_secn->run_addr); - break; - } - - /* Release all of these relos, we're done with them */ - while (i > 0) { - dlthis->mysym->dload_deallocate(dlthis->mysym, - GET_CONTAINER - (relos[i - 1], - struct tramp_img_dup_relo, - relo)); - i--; - } - - /* DO NOT ADVANCE cur_relo, IT IS ALREADY READY TO - * GO! */ - } - - /* Done with all relos. Make sure we didn't have a problem and - * write it out to the target */ - if (ret_val != 0) { - ret_val = dlthis->myio->writemem(dlthis->myio, - cur_pkt->img_pkt. - img_data, - dlthis->image_secn-> - load_addr + - cur_pkt->offset, - dlthis->image_secn, - BYTE_TO_HOST - (cur_pkt->img_pkt. - packet_size)); - if (ret_val == 0) { - dload_error(dlthis, - "Write to " FMT_UI32 " failed", - dlthis->image_secn->load_addr + - cur_pkt->offset); - } - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt); - - /* Advance to the next packet */ - cur_pkt = dlthis->tramp.dup_pkts; - } - } - - return ret_val; -} - -/* - * Function: priv_dup_find - * Description: Walk the list of existing duplicate packets and find a - * match based on the section number and image offset. Return - * the duplicate packet if found, otherwise NULL. - */ -static struct tramp_img_dup_pkt *priv_dup_find(struct dload_state *dlthis, - s16 secnn, u32 image_offset) -{ - struct tramp_img_dup_pkt *cur_pkt = NULL; - - for (cur_pkt = dlthis->tramp.dup_pkts; - cur_pkt != NULL; cur_pkt = cur_pkt->next) { - if ((cur_pkt->secnn == secnn) && - (cur_pkt->offset == image_offset)) { - /* Found a match, break out */ - break; - } - } - - return cur_pkt; -} - -/* - * Function: priv_img_pkt_dup - * Description: Duplicate the original image packet. If this is the first - * time this image packet has been seen (based on section number - * and image offset), create a new duplicate packet and add it - * to the dup packet list. If not, just get the existing one and - * update it with the current packet contents (since relocation - * on the packet is still ongoing in first pass.) Create a - * duplicate of the provided relocation, but update it to point - * to the new trampoline symbol. Add the new relocation dup to - * the dup packet's relo chain for 2nd pass relocation later. - */ -static int priv_img_pkt_dup(struct dload_state *dlthis, - s16 secnn, u32 image_offset, - struct image_packet_t *ipacket, - struct reloc_record_t *rp, - struct tramp_sym *new_tramp_sym) -{ - struct tramp_img_dup_pkt *dup_pkt = NULL; - u32 new_dup_size; - s32 i; - int ret_val = 0; - struct tramp_img_dup_relo *dup_relo = NULL; - - /* Determine if this image packet is already being tracked in the - dup list for other trampolines. */ - dup_pkt = priv_dup_find(dlthis, secnn, image_offset); - - if (dup_pkt == NULL) { - /* This image packet does not exist in our tracking, so create - * a new one and add it to the head of the list. */ - new_dup_size = sizeof(struct tramp_img_dup_pkt) + - ipacket->packet_size; - - dup_pkt = (struct tramp_img_dup_pkt *) - dlthis->mysym->dload_allocate(dlthis->mysym, new_dup_size); - if (dup_pkt != NULL) { - /* Save off the section and offset information */ - dup_pkt->secnn = secnn; - dup_pkt->offset = image_offset; - dup_pkt->relo_chain = NULL; - - /* Copy the original packet content */ - dup_pkt->img_pkt = *ipacket; - dup_pkt->img_pkt.img_data = (u8 *) (dup_pkt + 1); - for (i = 0; i < ipacket->packet_size; i++) - *(dup_pkt->img_pkt.img_data + i) = - *(ipacket->img_data + i); - - /* Add the packet to the dup list */ - dup_pkt->next = dlthis->tramp.dup_pkts; - dlthis->tramp.dup_pkts = dup_pkt; - } else - dload_error(dlthis, "Failed to create dup packet!"); - } else { - /* The image packet contents could have changed since - * trampoline detection happens during relocation of the image - * packets. So, we need to update the image packet contents - * before adding relo information. */ - for (i = 0; i < dup_pkt->img_pkt.packet_size; i++) - *(dup_pkt->img_pkt.img_data + i) = - *(ipacket->img_data + i); - } - - /* Since the previous code may have allocated a new dup packet for us, - double check that we actually have one. */ - if (dup_pkt != NULL) { - /* Allocate a new node for the relo chain. Each image packet - * can potentially have multiple relocations that cause a - * trampoline to be generated. So, we keep them in a chain, - * order is not important. */ - dup_relo = dlthis->mysym->dload_allocate(dlthis->mysym, - sizeof(struct tramp_img_dup_relo)); - if (dup_relo != NULL) { - /* Copy the relo contents, adjust for the new - * trampoline and add it to the list. */ - dup_relo->relo = *rp; - dup_relo->relo.SYMNDX = new_tramp_sym->index; - - dup_relo->next = dup_pkt->relo_chain; - dup_pkt->relo_chain = dup_relo; - - /* That's it, we're done. Make sure we update our - * return value to be success since everything finished - * ok */ - ret_val = 1; - } else - dload_error(dlthis, "Unable to alloc dup relo"); - } - - return ret_val; -} - -/* - * Function: dload_tramp_avail - * Description: Check to see if the target supports a trampoline for this type - * of relocation. Return true if it does, otherwise false. - */ -bool dload_tramp_avail(struct dload_state *dlthis, struct reloc_record_t *rp) -{ - bool ret_val = false; - u16 map_index; - u16 gen_index; - - /* Check type hash vs. target tramp table */ - map_index = HASH_FUNC(rp->TYPE); - gen_index = tramp_map[map_index]; - if (gen_index != TRAMP_NO_GEN_AVAIL) - ret_val = true; - - return ret_val; -} - -/* - * Function: dload_tramp_generate - * Description: Create a new trampoline for the provided image packet and - * relocation causing problems. This will create the trampoline - * as well as duplicate/update the image packet and relocation - * causing the problem, which will be relo'd again during - * finalization. - */ -int dload_tramp_generate(struct dload_state *dlthis, s16 secnn, - u32 image_offset, struct image_packet_t *ipacket, - struct reloc_record_t *rp) -{ - u16 map_index; - u16 gen_index; - int ret_val = 1; - char tramp_sym_str[TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN]; - struct local_symbol *ref_sym; - struct tramp_sym *new_tramp_sym; - struct tramp_sym *new_ext_sym; - struct tramp_string *new_tramp_str; - u32 new_tramp_base; - struct local_symbol tmp_sym; - struct local_symbol ext_tmp_sym; - - /* Hash the relo type to get our generator information */ - map_index = HASH_FUNC(rp->TYPE); - gen_index = tramp_map[map_index]; - if (gen_index != TRAMP_NO_GEN_AVAIL) { - /* If this is the first trampoline, create the section name in - * our string table for debug help later. */ - if (dlthis->tramp.string_head == NULL) { - priv_tramp_string_create(dlthis, - strlen(TRAMP_SECT_NAME), - TRAMP_SECT_NAME); - } -#ifdef ENABLE_TRAMP_DEBUG - dload_syms_error(dlthis->mysym, - "Trampoline at img loc %x, references %x", - dlthis->ldr_sections[secnn].run_addr + - image_offset + rp->vaddr, - dlthis->local_symtab[rp->SYMNDX].value); -#endif - - /* Generate the trampoline string, check if already defined. - * If the relo symbol index is -1, it means we need the section - * info for relo later. To do this we'll dummy up a symbol - * with the section delta and run addresses. */ - if (rp->SYMNDX == -1) { - ext_tmp_sym.value = - dlthis->ldr_sections[secnn].run_addr; - ext_tmp_sym.delta = dlthis->sect_hdrs[secnn].ds_paddr; - ref_sym = &ext_tmp_sym; - } else - ref_sym = &(dlthis->local_symtab[rp->SYMNDX]); - - priv_tramp_sym_gen_name(ref_sym->value, tramp_sym_str); - new_tramp_sym = priv_tramp_sym_find(dlthis, tramp_sym_str); - if (new_tramp_sym == NULL) { - /* If tramp string not defined, create it and a new - * string, and symbol for it as well as the original - * symbol which caused the trampoline. */ - new_tramp_str = priv_tramp_string_create(dlthis, - strlen - (tramp_sym_str), - tramp_sym_str); - if (new_tramp_str == NULL) { - dload_error(dlthis, "Failed to create new " - "trampoline string\n"); - ret_val = 0; - } else { - /* Allocate tramp section space for the new - * tramp from the target */ - new_tramp_base = priv_tramp_sect_alloc(dlthis, - tramp_size_get()); - - /* We have a string, create the new symbol and - * duplicate the external. */ - tmp_sym.value = new_tramp_base; - tmp_sym.delta = 0; - tmp_sym.secnn = -1; - tmp_sym.sclass = 0; - new_tramp_sym = priv_tramp_sym_create(dlthis, - new_tramp_str-> - index, - &tmp_sym); - - new_ext_sym = priv_tramp_sym_create(dlthis, -1, - ref_sym); - - if ((new_tramp_sym != NULL) && - (new_ext_sym != NULL)) { - /* Call the image generator to get the - * new image data and fix up its - * relocations for the external - * symbol. */ - ret_val = priv_tgt_img_gen(dlthis, - new_tramp_base, - gen_index, - new_ext_sym); - - /* Add generated image data to tramp - * image list */ - if (ret_val != 1) { - dload_error(dlthis, "Failed to " - "create img pkt for" - " trampoline\n"); - } - } else { - dload_error(dlthis, "Failed to create " - "new tramp syms " - "(%8.8X, %8.8X)\n", - new_tramp_sym, new_ext_sym); - ret_val = 0; - } - } - } - - /* Duplicate the image data and relo record that caused the - * tramp, including update the relo data to point to the tramp - * symbol. */ - if (ret_val == 1) { - ret_val = priv_img_pkt_dup(dlthis, secnn, image_offset, - ipacket, rp, new_tramp_sym); - if (ret_val != 1) { - dload_error(dlthis, "Failed to create dup of " - "original img pkt\n"); - } - } - } - - return ret_val; -} - -/* - * Function: dload_tramp_pkt_update - * Description: Update the duplicate copy of this image packet, which the - * trampoline layer is already tracking. This call is critical - * to make if trampolines were generated anywhere within the - * packet and first pass relo continued on the remainder. The - * trampoline layer needs the updates image data so when 2nd - * pass relo is done during finalize the image packet can be - * written to the target since all relo is done. - */ -int dload_tramp_pkt_udpate(struct dload_state *dlthis, s16 secnn, - u32 image_offset, struct image_packet_t *ipacket) -{ - struct tramp_img_dup_pkt *dup_pkt = NULL; - s32 i; - int ret_val = 0; - - /* Find the image packet in question, the caller needs us to update it - since a trampoline was previously generated. */ - dup_pkt = priv_dup_find(dlthis, secnn, image_offset); - if (dup_pkt != NULL) { - for (i = 0; i < dup_pkt->img_pkt.packet_size; i++) - *(dup_pkt->img_pkt.img_data + i) = - *(ipacket->img_data + i); - - ret_val = 1; - } else { - dload_error(dlthis, - "Unable to find existing DUP pkt for %x, offset %x", - secnn, image_offset); - - } - - return ret_val; -} - -/* - * Function: dload_tramp_finalize - * Description: If any trampolines were created, finalize everything on the - * target by allocating the trampoline section on the target, - * finalizing the trampoline symbols, finalizing the trampoline - * packets (write the new section to target memory) and finalize - * the duplicate packets by doing 2nd pass relo over them. - */ -int dload_tramp_finalize(struct dload_state *dlthis) -{ - int ret_val = 1; - - if (dlthis->tramp.tramp_sect_next_addr != 0) { - /* Finalize strings into a flat table. This is needed so it - * can be added to the debug string table later. */ - ret_val = priv_string_tbl_finalize(dlthis); - - /* Do target allocation for section BEFORE finalizing - * symbols. */ - if (ret_val != 0) - ret_val = priv_tramp_sect_tgt_alloc(dlthis); - - /* Finalize symbols with their correct target information and - * flatten */ - if (ret_val != 0) - ret_val = priv_tramp_sym_finalize(dlthis); - - /* Finalize all trampoline packets. This performs the - * relocation on the packets as well as writing them to target - * memory. */ - if (ret_val != 0) - ret_val = priv_tramp_pkt_finalize(dlthis); - - /* Perform a 2nd pass relocation on the dup list. */ - if (ret_val != 0) - ret_val = priv_dup_pkt_finalize(dlthis); - } - - return ret_val; -} - -/* - * Function: dload_tramp_cleanup - * Description: Release all temporary resources used in the trampoline layer. - * Note that the target memory which may have been allocated and - * written to store the trampolines is NOT RELEASED HERE since it - * is potentially still in use. It is automatically released - * when the module is unloaded. - */ -void dload_tramp_cleanup(struct dload_state *dlthis) -{ - struct tramp_info *tramp = &dlthis->tramp; - struct tramp_sym *cur_sym; - struct tramp_string *cur_string; - struct tramp_img_pkt *cur_tramp_pkt; - struct tramp_img_dup_pkt *cur_dup_pkt; - struct tramp_img_dup_relo *cur_dup_relo; - - /* If there were no tramps generated, just return */ - if (tramp->tramp_sect_next_addr == 0) - return; - - /* Destroy all tramp information */ - for (cur_sym = tramp->symbol_head; - cur_sym != NULL; cur_sym = tramp->symbol_head) { - tramp->symbol_head = cur_sym->next; - if (tramp->symbol_tail == cur_sym) - tramp->symbol_tail = NULL; - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym); - } - - if (tramp->final_sym_table != NULL) - dlthis->mysym->dload_deallocate(dlthis->mysym, - tramp->final_sym_table); - - for (cur_string = tramp->string_head; - cur_string != NULL; cur_string = tramp->string_head) { - tramp->string_head = cur_string->next; - if (tramp->string_tail == cur_string) - tramp->string_tail = NULL; - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_string); - } - - if (tramp->final_string_table != NULL) - dlthis->mysym->dload_deallocate(dlthis->mysym, - tramp->final_string_table); - - for (cur_tramp_pkt = tramp->tramp_pkts; - cur_tramp_pkt != NULL; cur_tramp_pkt = tramp->tramp_pkts) { - tramp->tramp_pkts = cur_tramp_pkt->next; - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_tramp_pkt); - } - - for (cur_dup_pkt = tramp->dup_pkts; - cur_dup_pkt != NULL; cur_dup_pkt = tramp->dup_pkts) { - tramp->dup_pkts = cur_dup_pkt->next; - - for (cur_dup_relo = cur_dup_pkt->relo_chain; - cur_dup_relo != NULL; - cur_dup_relo = cur_dup_pkt->relo_chain) { - cur_dup_pkt->relo_chain = cur_dup_relo->next; - dlthis->mysym->dload_deallocate(dlthis->mysym, - cur_dup_relo); - } - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_dup_pkt); - } -} diff --git a/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c b/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c deleted file mode 100644 index 09cc64f213c..00000000000 --- a/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * tramp_table_c6000.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -#include "dload_internal.h" - -/* These are defined in coff.h, but may not be available on all platforms - so we'll go ahead and define them here. */ -#ifndef R_C60LO16 -#define R_C60LO16 0x54 /* C60: MVK Low Half Register */ -#define R_C60HI16 0x55 /* C60: MVKH/MVKLH High Half Register */ -#endif - -#define C6X_TRAMP_WORD_COUNT 8 -#define C6X_TRAMP_MAX_RELOS 8 - -/* THIS HASH FUNCTION MUST MATCH THE ONE reloc_table_c6000.c */ -#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63) - -/* THIS MUST MATCH reloc_record_t FOR A SYMBOL BASED RELO */ -struct c6000_relo_record { - s32 vaddr; - s32 symndx; -#ifndef _BIG_ENDIAN - u16 disp; - u16 type; -#else - u16 type; - u16 disp; -#endif -}; - -struct c6000_gen_code { - struct tramp_gen_code_hdr hdr; - u32 tramp_instrs[C6X_TRAMP_WORD_COUNT]; - struct c6000_relo_record relos[C6X_TRAMP_MAX_RELOS]; -}; - -/* Hash mapping for relos that can cause trampolines. */ -static const u16 tramp_map[] = { - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 0, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535 -}; - -static const struct c6000_gen_code tramp_gen_info[] = { - /* Tramp caused by R_C60PCR21 */ - { - /* Header - 8 instructions, 2 relos */ - { - sizeof(u32) * C6X_TRAMP_WORD_COUNT, - 2, - FIELD_OFFSET(struct c6000_gen_code, relos) - }, - - /* Trampoline instructions */ - { - 0x053C54F7, /* STW.D2T2 B10, *sp--[2] */ - 0x0500002A, /* || MVK.S2 <blank>, B10 */ - 0x0500006A, /* MVKH.S2 <blank>, B10 */ - 0x00280362, /* B.S2 B10 */ - 0x053C52E6, /* LDW.D2T2 *++sp[2], B10 */ - 0x00006000, /* NOP 4 */ - 0x00000000, /* NOP */ - 0x00000000 /* NOP */ - }, - - /* Relocations */ - { - {4, 0, 0, R_C60LO16}, - {8, 0, 0, R_C60HI16}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000} - } - } -}; - -/* TARGET SPECIFIC FUNCTIONS THAT MUST BE DEFINED */ -static u32 tramp_size_get(void) -{ - return sizeof(u32) * C6X_TRAMP_WORD_COUNT; -} - -static u32 tramp_img_pkt_size_get(void) -{ - return sizeof(struct c6000_gen_code); -} diff --git a/drivers/staging/tidspbridge/gen/gh.c b/drivers/staging/tidspbridge/gen/gh.c deleted file mode 100644 index 936470cb608..00000000000 --- a/drivers/staging/tidspbridge/gen/gh.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * gh.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -#include <linux/err.h> -#include <linux/hashtable.h> -#include <linux/slab.h> - -struct gh_node { - struct hlist_node hl; - u8 data[0]; -}; - -#define GH_HASH_ORDER 8 - -struct gh_t_hash_tab { - u32 val_size; - DECLARE_HASHTABLE(hash_table, GH_HASH_ORDER); - u32 (*hash)(const void *key); - bool (*match)(const void *key, const void *value); - void (*delete)(void *key); -}; - -/* - * ======== gh_create ======== - */ - -struct gh_t_hash_tab *gh_create(u32 val_size, u32 (*hash)(const void *), - bool (*match)(const void *, const void *), - void (*delete)(void *)) -{ - struct gh_t_hash_tab *hash_tab; - - hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL); - if (!hash_tab) - return ERR_PTR(-ENOMEM); - - hash_init(hash_tab->hash_table); - - hash_tab->val_size = val_size; - hash_tab->hash = hash; - hash_tab->match = match; - hash_tab->delete = delete; - - return hash_tab; -} - -/* - * ======== gh_delete ======== - */ -void gh_delete(struct gh_t_hash_tab *hash_tab) -{ - struct gh_node *n; - struct hlist_node *tmp; - u32 i; - - if (hash_tab) { - hash_for_each_safe(hash_tab->hash_table, i, tmp, n, hl) { - hash_del(&n->hl); - if (hash_tab->delete) - hash_tab->delete(n->data); - kfree(n); - } - - kfree(hash_tab); - } -} - -/* - * ======== gh_find ======== - */ - -void *gh_find(struct gh_t_hash_tab *hash_tab, const void *key) -{ - struct gh_node *n; - u32 key_hash = hash_tab->hash(key); - - hash_for_each_possible(hash_tab->hash_table, n, hl, key_hash) { - if (hash_tab->match(key, n->data)) - return n->data; - } - - return ERR_PTR(-ENODATA); -} - -/* - * ======== gh_insert ======== - */ - -void *gh_insert(struct gh_t_hash_tab *hash_tab, const void *key, - const void *value) -{ - struct gh_node *n; - - n = kmalloc(sizeof(struct gh_node) + hash_tab->val_size, - GFP_KERNEL); - - if (!n) - return ERR_PTR(-ENOMEM); - - INIT_HLIST_NODE(&n->hl); - hash_add(hash_tab->hash_table, &n->hl, hash_tab->hash(key)); - memcpy(n->data, value, hash_tab->val_size); - - return n->data; -} - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/** - * gh_iterate() - This function goes through all the elements in the hash table - * looking for the dsp symbols. - * @hash_tab: Hash table - * @callback: pointer to callback function - * @user_data: User data, contains the find_symbol_context pointer - * - */ -void gh_iterate(struct gh_t_hash_tab *hash_tab, - void (*callback)(void *, void *), void *user_data) -{ - struct gh_node *n; - u32 i; - - if (!hash_tab) - return; - - hash_for_each(hash_tab->hash_table, i, n, hl) - callback(&n->data, user_data); -} -#endif diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h deleted file mode 100644 index e48d7f67c60..00000000000 --- a/drivers/staging/tidspbridge/hw/EasiGlobal.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * EasiGlobal.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 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 _EASIGLOBAL_H -#define _EASIGLOBAL_H -#include <linux/types.h> - -/* - * DEFINE: READ_ONLY, WRITE_ONLY & READ_WRITE - * - * DESCRIPTION: Defines used to describe register types for EASI-checker tests. - */ - -#define READ_ONLY 1 -#define WRITE_ONLY 2 -#define READ_WRITE 3 - -/* - * MACRO: _DEBUG_LEVEL1_EASI - * - * DESCRIPTION: A MACRO which can be used to indicate that a particular beach - * register access function was called. - * - * NOTE: We currently dont use this functionality. - */ -#define _DEBUG_LEVEL1_EASI(easi_num) ((void)0) - -#endif /* _EASIGLOBAL_H */ diff --git a/drivers/staging/tidspbridge/hw/MMUAccInt.h b/drivers/staging/tidspbridge/hw/MMUAccInt.h deleted file mode 100644 index 1cefca321d7..00000000000 --- a/drivers/staging/tidspbridge/hw/MMUAccInt.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * MMUAccInt.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 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 _MMU_ACC_INT_H -#define _MMU_ACC_INT_H - -/* Mappings of level 1 EASI function numbers to function names */ - -#define EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32 (MMU_BASE_EASIL1 + 3) -#define EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32 (MMU_BASE_EASIL1 + 17) -#define EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32 (MMU_BASE_EASIL1 + 39) -#define EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 51) -#define EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32 (MMU_BASE_EASIL1 + 102) -#define EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 103) -#define EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32 (MMU_BASE_EASIL1 + 156) -#define EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32 (MMU_BASE_EASIL1 + 174) -#define EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 180) -#define EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 190) -#define EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32 (MMU_BASE_EASIL1 + 194) -#define EASIL1_MMUMMU_TTB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 198) -#define EASIL1_MMUMMU_LOCK_READ_REGISTER32 (MMU_BASE_EASIL1 + 203) -#define EASIL1_MMUMMU_LOCK_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 204) -#define EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32 (MMU_BASE_EASIL1 + 205) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32 (MMU_BASE_EASIL1 + 209) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32 (MMU_BASE_EASIL1 + 211) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32 (MMU_BASE_EASIL1 + 212) -#define EASIL1_MMUMMU_LD_TLB_READ_REGISTER32 (MMU_BASE_EASIL1 + 213) -#define EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 214) -#define EASIL1_MMUMMU_CAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 226) -#define EASIL1_MMUMMU_RAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 268) -#define EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 322) - -/* Register offset address definitions */ -#define MMU_MMU_SYSCONFIG_OFFSET 0x10 -#define MMU_MMU_IRQSTATUS_OFFSET 0x18 -#define MMU_MMU_IRQENABLE_OFFSET 0x1c -#define MMU_MMU_WALKING_ST_OFFSET 0x40 -#define MMU_MMU_CNTL_OFFSET 0x44 -#define MMU_MMU_FAULT_AD_OFFSET 0x48 -#define MMU_MMU_TTB_OFFSET 0x4c -#define MMU_MMU_LOCK_OFFSET 0x50 -#define MMU_MMU_LD_TLB_OFFSET 0x54 -#define MMU_MMU_CAM_OFFSET 0x58 -#define MMU_MMU_RAM_OFFSET 0x5c -#define MMU_MMU_GFLUSH_OFFSET 0x60 -#define MMU_MMU_FLUSH_ENTRY_OFFSET 0x64 -/* Bitfield mask and offset declarations */ -#define MMU_MMU_SYSCONFIG_IDLE_MODE_MASK 0x18 -#define MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET 3 -#define MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK 0x1 -#define MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET 0 -#define MMU_MMU_WALKING_ST_TWL_RUNNING_MASK 0x1 -#define MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET 0 -#define MMU_MMU_CNTL_TWL_ENABLE_MASK 0x4 -#define MMU_MMU_CNTL_TWL_ENABLE_OFFSET 2 -#define MMU_MMU_CNTL_MMU_ENABLE_MASK 0x2 -#define MMU_MMU_CNTL_MMU_ENABLE_OFFSET 1 -#define MMU_MMU_LOCK_BASE_VALUE_MASK 0xfc00 -#define MMU_MMU_LOCK_BASE_VALUE_OFFSET 10 -#define MMU_MMU_LOCK_CURRENT_VICTIM_MASK 0x3f0 -#define MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET 4 - -#endif /* _MMU_ACC_INT_H */ diff --git a/drivers/staging/tidspbridge/hw/MMURegAcM.h b/drivers/staging/tidspbridge/hw/MMURegAcM.h deleted file mode 100644 index ab1a16da731..00000000000 --- a/drivers/staging/tidspbridge/hw/MMURegAcM.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * MMURegAcM.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 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 _MMU_REG_ACM_H -#define _MMU_REG_ACM_H - -#include <linux/io.h> -#include <EasiGlobal.h> - -#include "MMUAccInt.h" - -#if defined(USE_LEVEL_1_MACROS) - -#define MMUMMU_SYSCONFIG_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_SYSCONFIG_OFFSET)) - -#define MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32);\ - data &= ~(MMU_MMU_SYSCONFIG_IDLE_MODE_MASK);\ - new_value <<= MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET;\ - new_value &= MMU_MMU_SYSCONFIG_IDLE_MODE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32);\ - data &= ~(MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK);\ - new_value <<= MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET;\ - new_value &= MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_IRQSTATUS_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(easil1_mmummu_irqstatus_read_register32),\ - __raw_readl((base_address)+MMU_MMU_IRQSTATUS_OFFSET)) - -#define MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_IRQENABLE_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_IRQENABLE_OFFSET)) - -#define MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_WALKING_STTWL_RUNNING_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_WALKING_ST_OFFSET))))\ - & MMU_MMU_WALKING_ST_TWL_RUNNING_MASK) >>\ - MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET)) - -#define MMUMMU_CNTLTWL_ENABLE_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\ - MMU_MMU_CNTL_TWL_ENABLE_MASK) >>\ - MMU_MMU_CNTL_TWL_ENABLE_OFFSET)) - -#define MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CNTL_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32);\ - data &= ~(MMU_MMU_CNTL_TWL_ENABLE_MASK);\ - new_value <<= MMU_MMU_CNTL_TWL_ENABLE_OFFSET;\ - new_value &= MMU_MMU_CNTL_TWL_ENABLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CNTL_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32);\ - data &= ~(MMU_MMU_CNTL_MMU_ENABLE_MASK);\ - new_value <<= MMU_MMU_CNTL_MMU_ENABLE_OFFSET;\ - new_value &= MMU_MMU_CNTL_MMU_ENABLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_FAULT_AD_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_FAULT_AD_OFFSET)) - -#define MMUMMU_TTB_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_TTB_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_TTB_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_LOCK_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_LOCK_OFFSET)) - -#define MMUMMU_LOCK_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_LOCK_BASE_VALUE_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ - MMU_MMU_LOCK_BASE_VALUE_MASK) >>\ - MMU_MMU_LOCK_BASE_VALUE_OFFSET)) - -#define MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(easil1_mmummu_lock_base_value_write32);\ - data &= ~(MMU_MMU_LOCK_BASE_VALUE_MASK);\ - new_value <<= MMU_MMU_LOCK_BASE_VALUE_OFFSET;\ - new_value &= MMU_MMU_LOCK_BASE_VALUE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_LOCK_CURRENT_VICTIM_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ - MMU_MMU_LOCK_CURRENT_VICTIM_MASK) >>\ - MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET)) - -#define MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32);\ - data &= ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK);\ - new_value <<= MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET;\ - new_value &= MMU_MMU_LOCK_CURRENT_VICTIM_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_LOCK_CURRENT_VICTIM_SET32(var, value)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32),\ - (((var) & ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK)) |\ - (((value) << MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET) &\ - MMU_MMU_LOCK_CURRENT_VICTIM_MASK))) - -#define MMUMMU_LD_TLB_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_LD_TLB_OFFSET)) - -#define MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LD_TLB_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_CAM_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CAM_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CAM_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_RAM_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_RAM_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_RAM_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#endif /* USE_LEVEL_1_MACROS */ - -#endif /* _MMU_REG_ACM_H */ diff --git a/drivers/staging/tidspbridge/hw/hw_defs.h b/drivers/staging/tidspbridge/hw/hw_defs.h deleted file mode 100644 index d5266d4c163..00000000000 --- a/drivers/staging/tidspbridge/hw/hw_defs.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * hw_defs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global HW definitions - * - * Copyright (C) 2007 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 _HW_DEFS_H -#define _HW_DEFS_H - -/* Page size */ -#define HW_PAGE_SIZE4KB 0x1000 -#define HW_PAGE_SIZE64KB 0x10000 -#define HW_PAGE_SIZE1MB 0x100000 -#define HW_PAGE_SIZE16MB 0x1000000 - -/* hw_status: return type for HW API */ -typedef long hw_status; - -/* Macro used to set and clear any bit */ -#define HW_CLEAR 0 -#define HW_SET 1 - -/* hw_endianism_t: Enumerated Type used to specify the endianism - * Do NOT change these values. They are used as bit fields. */ -enum hw_endianism_t { - HW_LITTLE_ENDIAN, - HW_BIG_ENDIAN -}; - -/* hw_element_size_t: Enumerated Type used to specify the element size - * Do NOT change these values. They are used as bit fields. */ -enum hw_element_size_t { - HW_ELEM_SIZE8BIT, - HW_ELEM_SIZE16BIT, - HW_ELEM_SIZE32BIT, - HW_ELEM_SIZE64BIT -}; - -/* hw_idle_mode_t: Enumerated Type used to specify Idle modes */ -enum hw_idle_mode_t { - HW_FORCE_IDLE, - HW_NO_IDLE, - HW_SMART_IDLE -}; - -#endif /* _HW_DEFS_H */ diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c deleted file mode 100644 index 50244a47417..00000000000 --- a/drivers/staging/tidspbridge/hw/hw_mmu.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * hw_mmu.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * API definitions to setup MMU TLB and PTE - * - * Copyright (C) 2007 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. - */ - -#include <linux/io.h> -#include "MMURegAcM.h" -#include <hw_defs.h> -#include <hw_mmu.h> -#include <linux/types.h> -#include <linux/err.h> - -#define MMU_BASE_VAL_MASK 0xFC00 -#define MMU_PAGE_MAX 3 -#define MMU_ELEMENTSIZE_MAX 3 -#define MMU_ADDR_MASK 0xFFFFF000 -#define MMU_TTB_MASK 0xFFFFC000 -#define MMU_SECTION_ADDR_MASK 0xFFF00000 -#define MMU_SSECTION_ADDR_MASK 0xFF000000 -#define MMU_PAGE_TABLE_MASK 0xFFFFFC00 -#define MMU_LARGE_PAGE_MASK 0xFFFF0000 -#define MMU_SMALL_PAGE_MASK 0xFFFFF000 - -#define MMU_LOAD_TLB 0x00000001 -#define MMU_GFLUSH 0x60 - -/* - * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS) - */ -enum hw_mmu_page_size_t { - HW_MMU_SECTION, - HW_MMU_LARGE_PAGE, - HW_MMU_SMALL_PAGE, - HW_MMU_SUPERSECTION -}; - -/* - * FUNCTION : mmu_set_cam_entry - * - * INPUTS: - * - * Identifier : base_address - * Type : void __iomem * - * Description : Base Address of instance of MMU module - * - * Identifier : page_sz - * TypE : const u32 - * Description : It indicates the page size - * - * Identifier : preserved_bit - * Type : const u32 - * Description : It indicates the TLB entry is preserved entry - * or not - * - * Identifier : valid_bit - * Type : const u32 - * Description : It indicates the TLB entry is valid entry or not - * - * - * Identifier : virtual_addr_tag - * Type : const u32 - * Description : virtual Address - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occurred - * RET_BAD_NULL_PARAM -- A Pointer Parameter - * was set to NULL - * RET_PARAM_OUT_OF_RANGE -- Input Parameter out - * of Range - * - * PURPOSE: : Set MMU_CAM reg - * - * METHOD: : Check the Input parameters and set the CAM entry. - */ -static hw_status mmu_set_cam_entry(void __iomem *base_address, - const u32 page_sz, - const u32 preserved_bit, - const u32 valid_bit, - const u32 virtual_addr_tag); - -/* - * FUNCTION : mmu_set_ram_entry - * - * INPUTS: - * - * Identifier : base_address - * Type : void __iomem * - * Description : Base Address of instance of MMU module - * - * Identifier : physical_addr - * Type : const u32 - * Description : Physical Address to which the corresponding - * virtual Address shouldpoint - * - * Identifier : endianism - * Type : hw_endianism_t - * Description : endianism for the given page - * - * Identifier : element_size - * Type : hw_element_size_t - * Description : The element size ( 8,16, 32 or 64 bit) - * - * Identifier : mixed_size - * Type : hw_mmu_mixed_size_t - * Description : Element Size to follow CPU or TLB - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occurred - * RET_BAD_NULL_PARAM -- A Pointer Parameter - * was set to NULL - * RET_PARAM_OUT_OF_RANGE -- Input Parameter - * out of Range - * - * PURPOSE: : Set MMU_CAM reg - * - * METHOD: : Check the Input parameters and set the RAM entry. - */ -static hw_status mmu_set_ram_entry(void __iomem *base_address, - const u32 physical_addr, - enum hw_endianism_t endianism, - enum hw_element_size_t element_size, - enum hw_mmu_mixed_size_t mixed_size); - -/* HW FUNCTIONS */ - -hw_status hw_mmu_enable(void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET); - - return status; -} - -hw_status hw_mmu_disable(void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR); - - return status; -} - -hw_status hw_mmu_num_locked_set(void __iomem *base_address, - u32 num_locked_entries) -{ - hw_status status = 0; - - MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, num_locked_entries); - - return status; -} - -hw_status hw_mmu_victim_num_set(void __iomem *base_address, - u32 victim_entry_num) -{ - hw_status status = 0; - - MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victim_entry_num); - - return status; -} - -hw_status hw_mmu_event_ack(void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - - MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irq_mask); - - return status; -} - -hw_status hw_mmu_event_disable(void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - u32 irq_reg; - - irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address); - - MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irq_mask); - - return status; -} - -hw_status hw_mmu_event_enable(void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - u32 irq_reg; - - irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address); - - MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irq_mask); - - return status; -} - -hw_status hw_mmu_event_status(void __iomem *base_address, u32 *irq_mask) -{ - hw_status status = 0; - - *irq_mask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address); - - return status; -} - -hw_status hw_mmu_fault_addr_read(void __iomem *base_address, u32 *addr) -{ - hw_status status = 0; - - /* read values from register */ - *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address); - - return status; -} - -hw_status hw_mmu_ttb_set(void __iomem *base_address, u32 ttb_phys_addr) -{ - hw_status status = 0; - u32 load_ttb; - - load_ttb = ttb_phys_addr & ~0x7FUL; - /* write values to register */ - MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb); - - return status; -} - -hw_status hw_mmu_twl_enable(void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET); - - return status; -} - -hw_status hw_mmu_twl_disable(void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR); - - return status; -} - -hw_status hw_mmu_tlb_add(void __iomem *base_address, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - u32 entry_num, - struct hw_mmu_map_attrs_t *map_attrs, - s8 preserved_bit, s8 valid_bit) -{ - hw_status status = 0; - u32 lock_reg; - u32 virtual_addr_tag; - enum hw_mmu_page_size_t mmu_pg_size; - - /*Check the input Parameters */ - switch (page_sz) { - case HW_PAGE_SIZE4KB: - mmu_pg_size = HW_MMU_SMALL_PAGE; - break; - - case HW_PAGE_SIZE64KB: - mmu_pg_size = HW_MMU_LARGE_PAGE; - break; - - case HW_PAGE_SIZE1MB: - mmu_pg_size = HW_MMU_SECTION; - break; - - case HW_PAGE_SIZE16MB: - mmu_pg_size = HW_MMU_SUPERSECTION; - break; - - default: - return -EINVAL; - } - - lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address); - - /* Generate the 20-bit tag from virtual address */ - virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); - - /* Write the fields in the CAM Entry Register */ - mmu_set_cam_entry(base_address, mmu_pg_size, preserved_bit, valid_bit, - virtual_addr_tag); - - /* Write the different fields of the RAM Entry Register */ - /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */ - mmu_set_ram_entry(base_address, physical_addr, map_attrs->endianism, - map_attrs->element_size, map_attrs->mixed_size); - - /* Update the MMU Lock Register */ - /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */ - MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entry_num); - - /* Enable loading of an entry in TLB by writing 1 - into LD_TLB_REG register */ - MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB); - - MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg); - - return status; -} - -hw_status hw_mmu_pte_set(const u32 pg_tbl_va, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, struct hw_mmu_map_attrs_t *map_attrs) -{ - hw_status status = 0; - u32 pte_addr, pte_val; - s32 num_entries = 1; - - switch (page_sz) { - case HW_PAGE_SIZE4KB: - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_SMALL_PAGE_MASK); - pte_val = - ((physical_addr & MMU_SMALL_PAGE_MASK) | - (map_attrs->endianism << 9) | (map_attrs-> - element_size << 4) | - (map_attrs->mixed_size << 11) | 2); - break; - - case HW_PAGE_SIZE64KB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_LARGE_PAGE_MASK); - pte_val = - ((physical_addr & MMU_LARGE_PAGE_MASK) | - (map_attrs->endianism << 9) | (map_attrs-> - element_size << 4) | - (map_attrs->mixed_size << 11) | 1); - break; - - case HW_PAGE_SIZE1MB: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - pte_val = - ((((physical_addr & MMU_SECTION_ADDR_MASK) | - (map_attrs->endianism << 15) | (map_attrs-> - element_size << 10) | - (map_attrs->mixed_size << 17)) & ~0x40000) | 0x2); - break; - - case HW_PAGE_SIZE16MB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SSECTION_ADDR_MASK); - pte_val = - (((physical_addr & MMU_SSECTION_ADDR_MASK) | - (map_attrs->endianism << 15) | (map_attrs-> - element_size << 10) | - (map_attrs->mixed_size << 17) - ) | 0x40000 | 0x2); - break; - - case HW_MMU_COARSE_PAGE_SIZE: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1; - break; - - default: - return -EINVAL; - } - - while (--num_entries >= 0) - ((u32 *) pte_addr)[num_entries] = pte_val; - - return status; -} - -hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size) -{ - hw_status status = 0; - u32 pte_addr; - s32 num_entries = 1; - - switch (page_size) { - case HW_PAGE_SIZE4KB: - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_SMALL_PAGE_MASK); - break; - - case HW_PAGE_SIZE64KB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_LARGE_PAGE_MASK); - break; - - case HW_PAGE_SIZE1MB: - case HW_MMU_COARSE_PAGE_SIZE: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - break; - - case HW_PAGE_SIZE16MB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SSECTION_ADDR_MASK); - break; - - default: - return -EINVAL; - } - - while (--num_entries >= 0) - ((u32 *) pte_addr)[num_entries] = 0; - - return status; -} - -/* mmu_set_cam_entry */ -static hw_status mmu_set_cam_entry(void __iomem *base_address, - const u32 page_sz, - const u32 preserved_bit, - const u32 valid_bit, - const u32 virtual_addr_tag) -{ - hw_status status = 0; - u32 mmu_cam_reg; - - mmu_cam_reg = (virtual_addr_tag << 12); - mmu_cam_reg = (mmu_cam_reg) | (page_sz) | (valid_bit << 2) | - (preserved_bit << 3); - - /* write values to register */ - MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg); - - return status; -} - -/* mmu_set_ram_entry */ -static hw_status mmu_set_ram_entry(void __iomem *base_address, - const u32 physical_addr, - enum hw_endianism_t endianism, - enum hw_element_size_t element_size, - enum hw_mmu_mixed_size_t mixed_size) -{ - hw_status status = 0; - u32 mmu_ram_reg; - - mmu_ram_reg = (physical_addr & MMU_ADDR_MASK); - mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) | - (mixed_size << 6)); - - /* write values to register */ - MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg); - - return status; - -} - -void hw_mmu_tlb_flush_all(void __iomem *base) -{ - __raw_writel(1, base + MMU_GFLUSH); -} diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h deleted file mode 100644 index 1c50bb36edf..00000000000 --- a/drivers/staging/tidspbridge/hw/hw_mmu.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * hw_mmu.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * MMU types and API declarations - * - * Copyright (C) 2007 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 _HW_MMU_H -#define _HW_MMU_H - -#include <linux/types.h> - -/* Bitmasks for interrupt sources */ -#define HW_MMU_TRANSLATION_FAULT 0x2 -#define HW_MMU_ALL_INTERRUPTS 0x1F - -#define HW_MMU_COARSE_PAGE_SIZE 0x400 - -/* hw_mmu_mixed_size_t: Enumerated Type used to specify whether to follow - CPU/TLB Element size */ -enum hw_mmu_mixed_size_t { - HW_MMU_TLBES, - HW_MMU_CPUES -}; - -/* hw_mmu_map_attrs_t: Struct containing MMU mapping attributes */ -struct hw_mmu_map_attrs_t { - enum hw_endianism_t endianism; - enum hw_element_size_t element_size; - enum hw_mmu_mixed_size_t mixed_size; - bool donotlockmpupage; -}; - -extern hw_status hw_mmu_enable(void __iomem *base_address); - -extern hw_status hw_mmu_disable(void __iomem *base_address); - -extern hw_status hw_mmu_num_locked_set(void __iomem *base_address, - u32 num_locked_entries); - -extern hw_status hw_mmu_victim_num_set(void __iomem *base_address, - u32 victim_entry_num); - -/* For MMU faults */ -extern hw_status hw_mmu_event_ack(void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_disable(void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_enable(void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_status(void __iomem *base_address, - u32 *irq_mask); - -extern hw_status hw_mmu_fault_addr_read(void __iomem *base_address, - u32 *addr); - -/* Set the TT base address */ -extern hw_status hw_mmu_ttb_set(void __iomem *base_address, - u32 ttb_phys_addr); - -extern hw_status hw_mmu_twl_enable(void __iomem *base_address); - -extern hw_status hw_mmu_twl_disable(void __iomem *base_address); - -extern hw_status hw_mmu_tlb_add(void __iomem *base_address, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - u32 entry_num, - struct hw_mmu_map_attrs_t *map_attrs, - s8 preserved_bit, s8 valid_bit); - -/* For PTEs */ -extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - struct hw_mmu_map_attrs_t *map_attrs); - -extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, - u32 virtual_addr, u32 page_size); - -void hw_mmu_tlb_flush_all(void __iomem *base); - -static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va) -{ - u32 pte_addr; - u32 va31_to20; - - va31_to20 = va >> (20 - 2); /* Left-shift by 2 here itself */ - va31_to20 &= 0xFFFFFFFCUL; - pte_addr = l1_base + va31_to20; - - return pte_addr; -} - -static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va) -{ - u32 pte_addr; - - pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC); - - return pte_addr; -} - -static inline u32 hw_mmu_pte_coarse_l1(u32 pte_val) -{ - u32 pte_coarse; - - pte_coarse = pte_val & 0xFFFFFC00; - - return pte_coarse; -} - -static inline u32 hw_mmu_pte_size_l1(u32 pte_val) -{ - u32 pte_size = 0; - - if ((pte_val & 0x3) == 0x1) { - /* Points to L2 PT */ - pte_size = HW_MMU_COARSE_PAGE_SIZE; - } - - if ((pte_val & 0x3) == 0x2) { - if (pte_val & (1 << 18)) - pte_size = HW_PAGE_SIZE16MB; - else - pte_size = HW_PAGE_SIZE1MB; - } - - return pte_size; -} - -static inline u32 hw_mmu_pte_size_l2(u32 pte_val) -{ - u32 pte_size = 0; - - if (pte_val & 0x2) - pte_size = HW_PAGE_SIZE4KB; - else if (pte_val & 0x1) - pte_size = HW_PAGE_SIZE64KB; - - return pte_size; -} - -#endif /* _HW_MMU_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h deleted file mode 100644 index cc95a18f1db..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * _chnl_sm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Private header file defining channel manager and channel objects for - * a shared memory channel driver. - * - * Shared between the modules implementing the shared memory channel class - * library. - * - * 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 _CHNL_SM_ -#define _CHNL_SM_ - -#include <dspbridge/dspapi.h> -#include <dspbridge/dspdefs.h> - -#include <linux/list.h> -#include <dspbridge/ntfy.h> - -/* - * These target side symbols define the beginning and ending addresses - * of shared memory buffer. They are defined in the *cfg.cmd file by - * cdb code. - */ -#define CHNL_SHARED_BUFFER_BASE_SYM "_SHM_BEG" -#define CHNL_SHARED_BUFFER_LIMIT_SYM "_SHM_END" -#define BRIDGEINIT_BIOSGPTIMER "_BRIDGEINIT_BIOSGPTIMER" -#define BRIDGEINIT_LOADMON_GPTIMER "_BRIDGEINIT_LOADMON_GPTIMER" - -#ifndef _CHNL_WORDSIZE -#define _CHNL_WORDSIZE 4 /* default _CHNL_WORDSIZE is 2 bytes/word */ -#endif - -#define MAXOPPS 16 - -/* Shared memory config options */ -#define SHM_CURROPP 0 /* Set current OPP in shm */ -#define SHM_OPPINFO 1 /* Set dsp voltage and freq table values */ -#define SHM_GETOPP 2 /* Get opp requested by DSP */ - -struct opp_table_entry { - u32 voltage; - u32 frequency; - u32 min_freq; - u32 max_freq; -}; - -struct opp_struct { - u32 curr_opp_pt; - u32 num_opp_pts; - struct opp_table_entry opp_point[MAXOPPS]; -}; - -/* Request to MPU */ -struct opp_rqst_struct { - u32 rqst_dsp_freq; - u32 rqst_opp_pt; -}; - -/* Info to MPU */ -struct load_mon_struct { - u32 curr_dsp_load; - u32 curr_dsp_freq; - u32 pred_dsp_load; - u32 pred_dsp_freq; -}; - -/* Structure in shared between DSP and PC for communication. */ -struct shm { - u32 dsp_free_mask; /* Written by DSP, read by PC. */ - u32 host_free_mask; /* Written by PC, read by DSP */ - - u32 input_full; /* Input channel has unread data. */ - u32 input_id; /* Channel for which input is available. */ - u32 input_size; /* Size of data block (in DSP words). */ - - u32 output_full; /* Output channel has unread data. */ - u32 output_id; /* Channel for which output is available. */ - u32 output_size; /* Size of data block (in DSP words). */ - - u32 arg; /* Arg for Issue/Reclaim (23 bits for 55x). */ - u32 resvd; /* Keep structure size even for 32-bit DSPs */ - - /* Operating Point structure */ - struct opp_struct opp_table_struct; - /* Operating Point Request structure */ - struct opp_rqst_struct opp_request; - /* load monitor information structure */ - struct load_mon_struct load_mon_info; - /* Flag for WDT enable/disable F/I clocks */ - u32 wdt_setclocks; - u32 wdt_overflow; /* WDT overflow time */ - char dummy[176]; /* padding to 256 byte boundary */ - u32 shm_dbg_var[64]; /* shared memory debug variables */ -}; - - /* Channel Manager: only one created per board: */ -struct chnl_mgr { - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; - struct io_mgr *iomgr; /* IO manager */ - /* Device this board represents */ - struct dev_object *dev_obj; - - /* These fields initialized in bridge_chnl_create(): */ - u32 output_mask; /* Host output channels w/ full buffers */ - u32 last_output; /* Last output channel fired from DPC */ - /* Critical section object handle */ - spinlock_t chnl_mgr_lock; - u32 word_size; /* Size in bytes of DSP word */ - u8 max_channels; /* Total number of channels */ - u8 open_channels; /* Total number of open channels */ - struct chnl_object **channels; /* Array of channels */ - u8 type; /* Type of channel class library */ - /* If no shm syms, return for CHNL_Open */ - int chnl_open_status; -}; - -/* - * Channel: up to CHNL_MAXCHANNELS per board or if DSP-DMA supported then - * up to CHNL_MAXCHANNELS + CHNL_MAXDDMACHNLS per board. - */ -struct chnl_object { - /* Pointer back to channel manager */ - struct chnl_mgr *chnl_mgr_obj; - u32 chnl_id; /* Channel id */ - u8 state; /* Current channel state */ - s8 chnl_mode; /* Chnl mode and attributes */ - /* Chnl I/O completion event (user mode) */ - void *user_event; - /* Abstract synchronization object */ - struct sync_object *sync_event; - u32 process; /* Process which created this channel */ - u32 cb_arg; /* Argument to use with callback */ - struct list_head io_requests; /* List of IOR's to driver */ - s32 cio_cs; /* Number of IOC's in queue */ - s32 cio_reqs; /* Number of IORequests in queue */ - s32 chnl_packets; /* Initial number of free Irps */ - /* List of IOC's from driver */ - struct list_head io_completions; - struct list_head free_packets_list; /* List of free Irps */ - struct ntfy_object *ntfy_obj; - u32 bytes_moved; /* Total number of bytes transferred */ - - /* For DSP-DMA */ - - /* Type of chnl transport:CHNL_[PCPY][DDMA] */ - u32 chnl_type; -}; - -/* I/O Request/completion packet: */ -struct chnl_irp { - struct list_head link; /* Link to next CHIRP in queue. */ - /* Buffer to be filled/emptied. (User) */ - u8 *host_user_buf; - /* Buffer to be filled/emptied. (System) */ - u8 *host_sys_buf; - u32 arg; /* Issue/Reclaim argument. */ - u32 dsp_tx_addr; /* Transfer address on DSP side. */ - u32 byte_size; /* Bytes transferred. */ - u32 buf_size; /* Actual buffer size when allocated. */ - u32 status; /* Status of IO completion. */ -}; - -#endif /* _CHNL_SM_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/brddefs.h b/drivers/staging/tidspbridge/include/dspbridge/brddefs.h deleted file mode 100644 index 725d7b37414..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/brddefs.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * brddefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global BRD constants and types, shared between DSP API and 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 BRDDEFS_ -#define BRDDEFS_ - -/* platform status values */ -#define BRD_STOPPED 0x0 /* No Monitor Loaded, Not running. */ -#define BRD_IDLE 0x1 /* Monitor Loaded, but suspended. */ -#define BRD_RUNNING 0x2 /* Monitor loaded, and executing. */ -#define BRD_UNKNOWN 0x3 /* Board state is indeterminate. */ -#define BRD_LOADED 0x5 -#define BRD_SLEEP_TRANSITION 0x6 /* Sleep transition in progress */ -#define BRD_HIBERNATION 0x7 /* MPU initiated hibernation */ -#define BRD_RETENTION 0x8 /* Retention mode */ -#define BRD_DSP_HIBERNATION 0x9 /* DSP initiated hibernation */ -#define BRD_ERROR 0xA /* Board state is Error */ - -/* BRD Object */ -struct brd_object; - -#endif /* BRDDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h deleted file mode 100644 index b32c75673ab..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * cfgdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global CFG constants and types, shared between DSP API and 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 CFGDEFS_ -#define CFGDEFS_ - -/* Host Resources: */ -#define CFG_MAXMEMREGISTERS 9 - -/* IRQ flag */ -#define CFG_IRQSHARED 0x01 /* IRQ can be shared */ - -/* A platform-related device handle: */ -struct cfg_devnode; - -/* - * Host resource structure. - */ -struct cfg_hostres { - u32 num_mem_windows; /* Set to default */ - /* This is the base.memory */ - u32 mem_base[CFG_MAXMEMREGISTERS]; /* shm virtual address */ - u32 mem_length[CFG_MAXMEMREGISTERS]; /* Length of the Base */ - u32 mem_phys[CFG_MAXMEMREGISTERS]; /* shm Physical address */ - u8 birq_registers; /* IRQ Number */ - u8 birq_attrib; /* IRQ Attribute */ - u32 offset_for_monitor; /* The Shared memory starts from - * mem_base + this offset */ - /* - * Info needed by NODE for allocating channels to communicate with RMS: - * chnl_offset: Offset of RMS channels. Lower channels are - * reserved. - * chnl_buf_size: Size of channel buffer to send to RMS - * num_chnls: Total number of channels - * (including reserved). - */ - u32 chnl_offset; - u32 chnl_buf_size; - u32 num_chnls; - void __iomem *per_base; - void __iomem *per_pm_base; - void __iomem *core_pm_base; - void __iomem *dmmu_base; -}; - -#endif /* CFGDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnl.h b/drivers/staging/tidspbridge/include/dspbridge/chnl.h deleted file mode 100644 index 9b018b1f9bf..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/chnl.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * chnl.h - * - * 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 driver. - * - * See DSP API chnl.h for more details. - * - * 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 CHNL_ -#define CHNL_ - -#include <dspbridge/chnlpriv.h> - -/* - * ======== chnl_create ======== - * Purpose: - * Create a channel manager object, responsible for opening new channels - * and closing old ones for a given board. - * Parameters: - * channel_mgr: Location to store a channel manager object on output. - * hdev_obj: Handle to a device object. - * mgr_attrts: Channel manager attributes. - * mgr_attrts->max_channels: Max channels - * mgr_attrts->birq: Channel's I/O IRQ number. - * mgr_attrts->irq_shared: TRUE if the IRQ is shareable. - * mgr_attrts->word_size: DSP Word size in equivalent PC bytes.. - * Returns: - * 0: Success; - * -EFAULT: hdev_obj is invalid. - * -EINVAL: max_channels is 0. - * Invalid DSP word size (must be > 0). - * Invalid base address for DSP communications. - * -ENOMEM: Insufficient memory for requested resources. - * -EIO: Unable to plug channel ISR for configured IRQ. - * -ECHRNG: This manager cannot handle this many channels. - * -EEXIST: Channel manager already exists for this device. - * Requires: - * channel_mgr != NULL. - * mgr_attrts != NULL. - * Ensures: - * 0: Subsequent calls to chnl_create() for the same - * board without an intervening call to - * chnl_destroy() will fail. - */ -extern int chnl_create(struct chnl_mgr **channel_mgr, - struct dev_object *hdev_obj, - const struct chnl_mgrattrs *mgr_attrts); - -/* - * ======== chnl_destroy ======== - * Purpose: - * Close all open channels, and destroy the channel manager. - * Parameters: - * hchnl_mgr: Channel manager object. - * Returns: - * 0: Success. - * -EFAULT: hchnl_mgr was invalid. - * Requires: - * Ensures: - * 0: Cancels I/O on each open channel. - * Closes each open channel. - * chnl_create may subsequently be called for the - * same board. - */ -extern int chnl_destroy(struct chnl_mgr *hchnl_mgr); - -#endif /* CHNL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h deleted file mode 100644 index cb67c309b6c..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * chnldefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * System-wide channel objects and constants. - * - * 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 CHNLDEFS_ -#define CHNLDEFS_ - -/* Channel id option. */ -#define CHNL_PICKFREE (~0UL) /* Let manager pick a free channel. */ - -/* Channel modes */ -#define CHNL_MODETODSP 0 /* Data streaming to the DSP. */ -#define CHNL_MODEFROMDSP 1 /* Data streaming from the DSP. */ - -/* GetIOCompletion flags */ -#define CHNL_IOCINFINITE 0xffffffff /* Wait forever for IO completion. */ -#define CHNL_IOCNOWAIT 0x0 /* Dequeue an IOC, if available. */ - -/* IO Completion Record status: */ -#define CHNL_IOCSTATCOMPLETE 0x0000 /* IO Completed. */ -#define CHNL_IOCSTATCANCEL 0x0002 /* IO was cancelled */ -#define CHNL_IOCSTATTIMEOUT 0x0008 /* Wait for IOC timed out. */ -#define CHNL_IOCSTATEOS 0x8000 /* End Of Stream reached. */ - -/* Macros for checking I/O Completion status: */ -#define CHNL_IS_IO_COMPLETE(ioc) (!(ioc.status & ~CHNL_IOCSTATEOS)) -#define CHNL_IS_IO_CANCELLED(ioc) (ioc.status & CHNL_IOCSTATCANCEL) -#define CHNL_IS_TIMED_OUT(ioc) (ioc.status & CHNL_IOCSTATTIMEOUT) - -/* Channel attributes: */ -struct chnl_attr { - u32 uio_reqs; /* Max # of preallocated I/O requests. */ - void *event_obj; /* User supplied auto-reset event object. */ - char *str_event_name; /* Ptr to name of user event object. */ - void *reserved1; /* Reserved for future use. */ - u32 reserved2; /* Reserved for future use. */ - -}; - -/* I/O completion record: */ -struct chnl_ioc { - void *buf; /* Buffer to be filled/emptied. */ - u32 byte_size; /* Bytes transferred. */ - u32 buf_size; /* Actual buffer size in bytes */ - u32 status; /* Status of IO completion. */ - u32 arg; /* User argument associated with buf. */ -}; - -#endif /* CHNLDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h deleted file mode 100644 index 4114c79e246..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * chnlpriv.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Private channel header shared between DSPSYS, DSPAPI and - * Bridge driver modules. - * - * 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 CHNLPRIV_ -#define CHNLPRIV_ - -#include <dspbridge/chnldefs.h> -#include <dspbridge/devdefs.h> -#include <dspbridge/sync.h> - -/* Channel manager limits: */ -#define CHNL_MAXCHANNELS 32 /* Max channels available per transport */ - -/* - * Trans port channel Id definitions:(must match dsp-side). - * - * For CHNL_MAXCHANNELS = 16: - * - * ChnlIds: - * 0-15 (PCPY) - transport 0) - * 16-31 (DDMA) - transport 1) - * 32-47 (ZCPY) - transport 2) - */ -#define CHNL_PCPY 0 /* Proc-copy transport 0 */ - -/* Higher level channel states: */ -#define CHNL_STATEREADY 0 /* Channel ready for I/O. */ -#define CHNL_STATECANCEL 1 /* I/O was cancelled. */ -#define CHNL_STATEEOS 2 /* End Of Stream reached. */ - -/* Macros for checking mode: */ -#define CHNL_IS_INPUT(mode) (mode & CHNL_MODEFROMDSP) -#define CHNL_IS_OUTPUT(mode) (!CHNL_IS_INPUT(mode)) - -/* Types of channel class libraries: */ -#define CHNL_TYPESM 1 /* Shared memory driver. */ - -/* Channel info. */ -struct chnl_info { - struct chnl_mgr *chnl_mgr; /* Owning channel manager. */ - u32 cnhl_id; /* Channel ID. */ - void *event_obj; /* Channel I/O completion event. */ - /*Abstraction of I/O completion event. */ - struct sync_object *sync_event; - s8 mode; /* Channel mode. */ - u8 state; /* Current channel state. */ - u32 bytes_tx; /* Total bytes transferred. */ - u32 cio_cs; /* Number of IOCs in queue. */ - u32 cio_reqs; /* Number of IO Requests in queue. */ - u32 process; /* Process owning this channel. */ -}; - -/* Channel manager info: */ -struct chnl_mgrinfo { - u8 type; /* Type of channel class library. */ - /* Channel handle, given the channel id. */ - struct chnl_object *chnl_obj; - u8 open_channels; /* Number of open channels. */ - u8 max_channels; /* total # of chnls supported */ -}; - -/* Channel Manager Attrs: */ -struct chnl_mgrattrs { - /* Max number of channels this manager can use. */ - u8 max_channels; - u32 word_size; /* DSP Word size. */ -}; - -#endif /* CHNLPRIV_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/clk.h b/drivers/staging/tidspbridge/include/dspbridge/clk.h deleted file mode 100644 index 685341c5069..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/clk.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * clk.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Provides Clock functions. - * - * 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 _CLK_H -#define _CLK_H - -enum dsp_clk_id { - DSP_CLK_IVA2 = 0, - DSP_CLK_GPT5, - DSP_CLK_GPT6, - DSP_CLK_GPT7, - DSP_CLK_GPT8, - DSP_CLK_WDT3, - DSP_CLK_MCBSP1, - DSP_CLK_MCBSP2, - DSP_CLK_MCBSP3, - DSP_CLK_MCBSP4, - DSP_CLK_MCBSP5, - DSP_CLK_SSI, - DSP_CLK_NOT_DEFINED -}; - -/* - * ======== dsp_clk_exit ======== - * Purpose: - * Discontinue usage of module; free resources when reference count - * reaches 0. - * Parameters: - * Returns: - * Requires: - * CLK initialized. - * Ensures: - * Resources used by module are freed when cRef reaches zero. - */ -extern void dsp_clk_exit(void); - -/* - * ======== dsp_clk_init ======== - * Purpose: - * Initializes private state of CLK module. - * Parameters: - * Returns: - * TRUE if initialized; FALSE if error occurred. - * Requires: - * Ensures: - * CLK initialized. - */ -extern void dsp_clk_init(void); - -void dsp_gpt_wait_overflow(short int clk_id, unsigned int load); - -/* - * ======== dsp_clk_enable ======== - * Purpose: - * Enables the clock requested. - * Parameters: - * Returns: - * 0: Success. - * -EPERM: Error occurred while enabling the clock. - * Requires: - * Ensures: - */ -extern int dsp_clk_enable(enum dsp_clk_id clk_id); - -u32 dsp_clock_enable_all(u32 dsp_per_clocks); - -/* - * ======== dsp_clk_disable ======== - * Purpose: - * Disables the clock requested. - * Parameters: - * Returns: - * 0: Success. - * -EPERM: Error occurred while disabling the clock. - * Requires: - * Ensures: - */ -extern int dsp_clk_disable(enum dsp_clk_id clk_id); - -extern u32 dsp_clk_get_iva2_rate(void); - -u32 dsp_clock_disable_all(u32 dsp_per_clocks); - -extern void ssi_clk_prepare(bool FLAG); - -#endif /* _SYNC_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmm.h b/drivers/staging/tidspbridge/include/dspbridge/cmm.h deleted file mode 100644 index 2adf9ecdf07..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/cmm.h +++ /dev/null @@ -1,337 +0,0 @@ -/* - * cmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Communication Memory Management(CMM) module provides shared memory - * management services for DSP/BIOS Bridge data streaming and messaging. - * Multiple shared memory segments can be registered with CMM. Memory is - * coelesced back to the appropriate pool when a buffer is freed. - * - * The CMM_Xlator[xxx] functions are used for node messaging and data - * streaming address translation to perform zero-copy inter-processor - * data transfer(GPP<->DSP). A "translator" object is created for a node or - * stream object that contains per thread virtual address information. This - * translator info is used at runtime to perform SM address translation - * to/from the DSP address space. - * - * Notes: - * cmm_xlator_alloc_buf - Used by Node and Stream modules for SM address - * translation. - * - * Copyright (C) 2008 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 CMM_ -#define CMM_ - -#include <dspbridge/devdefs.h> - -#include <dspbridge/cmmdefs.h> -#include <dspbridge/host_os.h> - -/* - * ======== cmm_calloc_buf ======== - * Purpose: - * Allocate memory buffers that can be used for data streaming or - * messaging. - * Parameters: - * hcmm_mgr: Cmm Mgr handle. - * usize: Number of bytes to allocate. - * pattr: Attributes of memory to allocate. - * pp_buf_va: Address of where to place VA. - * Returns: - * Pointer to a zero'd block of SM memory; - * NULL if memory couldn't be allocated, - * or if byte_size == 0, - * Requires: - * Valid hcmm_mgr. - * CMM initialized. - * Ensures: - * The returned pointer, if not NULL, points to a valid memory block of - * the size requested. - * - */ -extern void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, - u32 usize, struct cmm_attrs *pattrs, - void **pp_buf_va); - -/* - * ======== cmm_create ======== - * Purpose: - * Create a communication memory manager object. - * Parameters: - * ph_cmm_mgr: Location to store a communication manager handle on - * output. - * hdev_obj: Handle to a device object. - * mgr_attrts: Comm mem manager attributes. - * Returns: - * 0: Success; - * -ENOMEM: Insufficient memory for requested resources. - * -EPERM: Failed to initialize critical sect sync object. - * - * Requires: - * ph_cmm_mgr != NULL. - * mgr_attrts->min_block_size >= 4 bytes. - * Ensures: - * - */ -extern int cmm_create(struct cmm_object **ph_cmm_mgr, - struct dev_object *hdev_obj, - const struct cmm_mgrattrs *mgr_attrts); - -/* - * ======== cmm_destroy ======== - * Purpose: - * Destroy the communication memory manager object. - * Parameters: - * hcmm_mgr: Cmm Mgr handle. - * force: Force deallocation of all cmm memory immediately if set TRUE. - * If FALSE, and outstanding allocations will return -EPERM - * status. - * Returns: - * 0: CMM object & resources deleted. - * -EPERM: Unable to free CMM object due to outstanding allocation. - * -EFAULT: Unable to free CMM due to bad handle. - * Requires: - * CMM is initialized. - * hcmm_mgr != NULL. - * Ensures: - * Memory resources used by Cmm Mgr are freed. - */ -extern int cmm_destroy(struct cmm_object *hcmm_mgr, bool force); - -/* - * ======== cmm_free_buf ======== - * Purpose: - * Free the given buffer. - * Parameters: - * hcmm_mgr: Cmm Mgr handle. - * pbuf: Pointer to memory allocated by cmm_calloc_buf(). - * ul_seg_id: SM segment Id used in CMM_Calloc() attrs. - * Set to 0 to use default segment. - * Returns: - * 0 - * -EPERM - * Requires: - * CMM initialized. - * buf_pa != NULL - * Ensures: - * - */ -extern int cmm_free_buf(struct cmm_object *hcmm_mgr, - void *buf_pa, u32 ul_seg_id); - -/* - * ======== cmm_get_handle ======== - * Purpose: - * Return the handle to the cmm mgr for the given device obj. - * Parameters: - * hprocessor: Handle to a Processor. - * ph_cmm_mgr: Location to store the shared memory mgr handle on - * output. - * - * Returns: - * 0: Cmm Mgr opaque handle returned. - * -EFAULT: Invalid handle. - * Requires: - * ph_cmm_mgr != NULL - * hdev_obj != NULL - * Ensures: - */ -extern int cmm_get_handle(void *hprocessor, - struct cmm_object **ph_cmm_mgr); - -/* - * ======== cmm_get_info ======== - * Purpose: - * Return the current SM and VM utilization information. - * Parameters: - * hcmm_mgr: Handle to a Cmm Mgr. - * cmm_info_obj: Location to store the Cmm information on output. - * - * Returns: - * 0: Success. - * -EFAULT: Invalid handle. - * -EINVAL Invalid input argument. - * Requires: - * Ensures: - * - */ -extern int cmm_get_info(struct cmm_object *hcmm_mgr, - struct cmm_info *cmm_info_obj); - -/* - * ======== cmm_register_gppsm_seg ======== - * Purpose: - * Register a block of SM with the CMM. - * Parameters: - * hcmm_mgr: Handle to a Cmm Mgr. - * lpGPPBasePA: GPP Base Physical address. - * ul_size: Size in GPP bytes. - * dsp_addr_offset GPP PA to DSP PA Offset. - * c_factor: Add offset if CMM_ADDTODSPPA, sub if CMM_SUBFROMDSPPA. - * dw_dsp_base: DSP virtual base byte address. - * ul_dsp_size: Size of DSP segment in bytes. - * sgmt_id: Address to store segment Id. - * - * Returns: - * 0: Success. - * -EFAULT: Invalid hcmm_mgr handle. - * -EINVAL: Invalid input argument. - * -EPERM: Unable to register. - * - On success *sgmt_id is a valid SM segment ID. - * Requires: - * ul_size > 0 - * sgmt_id != NULL - * dw_gpp_base_pa != 0 - * c_factor = CMM_ADDTODSPPA || c_factor = CMM_SUBFROMDSPPA - * Ensures: - * - */ -extern int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, - unsigned int dw_gpp_base_pa, - u32 ul_size, - u32 dsp_addr_offset, - s8 c_factor, - unsigned int dw_dsp_base, - u32 ul_dsp_size, - u32 *sgmt_id, u32 gpp_base_va); - -/* - * ======== cmm_un_register_gppsm_seg ======== - * Purpose: - * Unregister the given memory segment that was previously registered - * by cmm_register_gppsm_seg. - * Parameters: - * hcmm_mgr: Handle to a Cmm Mgr. - * ul_seg_id Segment identifier returned by cmm_register_gppsm_seg. - * Returns: - * 0: Success. - * -EFAULT: Invalid handle. - * -EINVAL: Invalid ul_seg_id. - * -EPERM: Unable to unregister for unknown reason. - * Requires: - * Ensures: - * - */ -extern int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr, - u32 ul_seg_id); - -/* - * ======== cmm_xlator_alloc_buf ======== - * Purpose: - * Allocate the specified SM buffer and create a local memory descriptor. - * Place on the descriptor on the translator's HaQ (Host Alloc'd Queue). - * Parameters: - * xlator: Handle to a Xlator object. - * va_buf: Virtual address ptr(client context) - * pa_size: Size of SM memory to allocate. - * Returns: - * Ptr to valid physical address(Pa) of pa_size bytes, NULL if failed. - * Requires: - * va_buf != 0. - * pa_size != 0. - * Ensures: - * - */ -extern void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, - void *va_buf, u32 pa_size); - -/* - * ======== cmm_xlator_create ======== - * Purpose: - * Create a translator(xlator) object used for process specific Va<->Pa - * address translation. Node messaging and streams use this to perform - * inter-processor(GPP<->DSP) zero-copy data transfer. - * Parameters: - * xlator: Address to place handle to a new Xlator handle. - * hcmm_mgr: Handle to Cmm Mgr associated with this translator. - * xlator_attrs: Translator attributes used for the client NODE or STREAM. - * Returns: - * 0: Success. - * -EINVAL: Bad input Attrs. - * -ENOMEM: Insufficient memory(local) for requested resources. - * Requires: - * xlator != NULL - * hcmm_mgr != NULL - * xlator_attrs != NULL - * Ensures: - * - */ -extern int cmm_xlator_create(struct cmm_xlatorobject **xlator, - struct cmm_object *hcmm_mgr, - struct cmm_xlatorattrs *xlator_attrs); - -/* - * ======== cmm_xlator_free_buf ======== - * Purpose: - * Free SM buffer and descriptor. - * Does not free client process VM. - * Parameters: - * xlator: handle to translator. - * buf_va Virtual address of PA to free. - * Returns: - * 0: Success. - * -EFAULT: Bad translator handle. - * Requires: - * Ensures: - * - */ -extern int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, - void *buf_va); - -/* - * ======== cmm_xlator_info ======== - * Purpose: - * Set/Get process specific "translator" address info. - * This is used to perform fast virtual address translation - * for shared memory buffers between the GPP and DSP. - * Parameters: - * xlator: handle to translator. - * paddr: Virtual base address of segment. - * ul_size: Size in bytes. - * segm_id: Segment identifier of SM segment(s) - * set_info Set xlator fields if TRUE, else return base addr - * Returns: - * 0: Success. - * -EFAULT: Bad translator handle. - * Requires: - * (paddr != NULL) - * (ul_size > 0) - * Ensures: - * - */ -extern int cmm_xlator_info(struct cmm_xlatorobject *xlator, - u8 **paddr, - u32 ul_size, u32 segm_id, bool set_info); - -/* - * ======== cmm_xlator_translate ======== - * Purpose: - * Perform address translation VA<->PA for the specified stream or - * message shared memory buffer. - * Parameters: - * xlator: handle to translator. - * paddr address of buffer to translate. - * xtype Type of address xlation. CMM_PA2VA or CMM_VA2PA. - * Returns: - * Valid address on success, else NULL. - * Requires: - * paddr != NULL - * xtype >= CMM_VA2PA) && (xtype <= CMM_DSPPA2PA) - * Ensures: - * - */ -extern void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, - void *paddr, enum cmm_xlatetype xtype); - -#endif /* CMM_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h deleted file mode 100644 index a264fa69a4f..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * cmmdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global MEM constants and types. - * - * Copyright (C) 2008 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 CMMDEFS_ -#define CMMDEFS_ - - -/* Cmm attributes used in cmm_create() */ -struct cmm_mgrattrs { - /* Minimum SM allocation; default 32 bytes. */ - u32 min_block_size; -}; - -/* Attributes for CMM_AllocBuf() & CMM_AllocDesc() */ -struct cmm_attrs { - u32 seg_id; /* 1,2... are SM segments. 0 is not. */ - u32 alignment; /* 0,1,2,4....min_block_size */ -}; - -/* - * DSPPa to GPPPa Conversion Factor. - * - * For typical platforms: - * converted Address = PaDSP + ( c_factor * addressToConvert). - */ -#define CMM_SUBFROMDSPPA -1 -#define CMM_ADDTODSPPA 1 - -#define CMM_ALLSEGMENTS 0xFFFFFF /* All SegIds */ -#define CMM_MAXGPPSEGS 1 /* Maximum # of SM segs */ - -/* - * SMSEGs are SM segments the DSP allocates from. - * - * This info is used by the GPP to xlate DSP allocated PAs. - */ - -struct cmm_seginfo { - u32 seg_base_pa; /* Start Phys address of SM segment */ - /* Total size in bytes of segment: DSP+GPP */ - u32 total_seg_size; - u32 gpp_base_pa; /* Start Phys addr of Gpp SM seg */ - u32 gpp_size; /* Size of Gpp SM seg in bytes */ - u32 dsp_base_va; /* DSP virt base byte address */ - u32 dsp_size; /* DSP seg size in bytes */ - /* # of current GPP allocations from this segment */ - u32 in_use_cnt; - u32 seg_base_va; /* Start Virt address of SM seg */ - -}; - -/* CMM useful information */ -struct cmm_info { - /* # of SM segments registered with this Cmm. */ - u32 num_gppsm_segs; - /* Total # of allocations outstanding for CMM */ - u32 total_in_use_cnt; - /* Min SM block size allocation from cmm_create() */ - u32 min_block_size; - /* Info per registered SM segment. */ - struct cmm_seginfo seg_info[CMM_MAXGPPSEGS]; -}; - -/* XlatorCreate attributes */ -struct cmm_xlatorattrs { - u32 seg_id; /* segment Id used for SM allocations */ - u32 dsp_bufs; /* # of DSP-side bufs */ - u32 dsp_buf_size; /* size of DSP-side bufs in GPP bytes */ - /* Vm base address alloc'd in client process context */ - void *vm_base; - /* vm_size must be >= (dwMaxNumBufs * dwMaxSize) */ - u32 vm_size; -}; - -/* - * Cmm translation types. Use to map SM addresses to process context. - */ -enum cmm_xlatetype { - CMM_VA2PA = 0, /* Virtual to GPP physical address xlation */ - CMM_PA2VA = 1, /* GPP Physical to virtual */ - CMM_VA2DSPPA = 2, /* Va to DSP Pa */ - CMM_PA2DSPPA = 3, /* GPP Pa to DSP Pa */ - CMM_DSPPA2PA = 4, /* DSP Pa to GPP Pa */ -}; - -struct cmm_object; -struct cmm_xlatorobject; - -#endif /* CMMDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cod.h b/drivers/staging/tidspbridge/include/dspbridge/cod.h deleted file mode 100644 index ba2005d0242..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/cod.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * cod.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Code management module for DSPs. This module provides an interface - * 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. - */ - -#ifndef COD_ -#define COD_ - -#include <dspbridge/dblldefs.h> - -#define COD_MAXPATHLENGTH 255 -#define COD_TRACEBEG "SYS_PUTCBEG" -#define COD_TRACEEND "SYS_PUTCEND" -#define COD_TRACECURPOS "BRIDGE_SYS_PUTC_current" - -#define COD_NOLOAD DBLL_NOLOAD -#define COD_SYMB DBLL_SYMB - -/* COD code manager handle */ -struct cod_manager; - -/* COD library handle */ -struct cod_libraryobj; - -/* - * Function prototypes for writing memory to a DSP system, allocating - * and freeing DSP memory. - */ -typedef u32(*cod_writefxn) (void *priv_ref, u32 dsp_add, - void *pbuf, u32 ul_num_bytes, u32 mem_space); - -/* - * ======== cod_close ======== - * Purpose: - * Close a library opened with cod_open(). - * Parameters: - * lib - Library handle returned by cod_open(). - * Returns: - * None. - * Requires: - * COD module initialized. - * valid lib. - * Ensures: - * - */ -extern void cod_close(struct cod_libraryobj *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. - * Symbol table information is managed by this object and can be retrieved - * using the cod_get_sym_value() function. - * Parameters: - * manager: created manager object - * str_zl_file: ZL DLL filename, of length < COD_MAXPATHLENGTH. - * Returns: - * 0: Success. - * -ESPIPE: ZL_Create failed. - * -ENOSYS: attrs was not NULL. We don't yet support - * non default values of attrs. - * Requires: - * COD module initialized. - * str_zl_file != NULL - * Ensures: - */ -extern int cod_create(struct cod_manager **mgr, - char *str_zl_file); - -/* - * ======== cod_delete ======== - * Purpose: - * Delete a code manager object. - * Parameters: - * cod_mgr_obj: handle of manager to be deleted - * Returns: - * None. - * Requires: - * COD module initialized. - * valid cod_mgr_obj. - * Ensures: - */ -extern void cod_delete(struct cod_manager *cod_mgr_obj); - -/* - * ======== cod_get_base_lib ======== - * Purpose: - * Get handle to the base image DBL library. - * Parameters: - * cod_mgr_obj: handle of manager to be deleted - * plib: location to store library handle on output. - * Returns: - * 0: Success. - * Requires: - * COD module initialized. - * valid cod_mgr_obj. - * plib != NULL. - * Ensures: - */ -extern int cod_get_base_lib(struct cod_manager *cod_mgr_obj, - struct dbll_library_obj **plib); - -/* - * ======== cod_get_base_name ======== - * Purpose: - * Get the name of the base image DBL library. - * Parameters: - * cod_mgr_obj: handle of manager to be deleted - * sz_name: location to store library name on output. - * usize: size of name buffer. - * Returns: - * 0: Success. - * -EPERM: Buffer too small. - * Requires: - * COD module initialized. - * valid cod_mgr_obj. - * sz_name != NULL. - * Ensures: - */ -extern int cod_get_base_name(struct cod_manager *cod_mgr_obj, - char *sz_name, u32 usize); - -/* - * ======== cod_get_entry ======== - * Purpose: - * Retrieve the entry point of a loaded DSP program image - * Parameters: - * cod_mgr_obj: handle of manager to be deleted - * entry_pt: pointer to location for entry point - * Returns: - * 0: Success. - * Requires: - * COD module initialized. - * valid cod_mgr_obj. - * entry_pt != NULL. - * Ensures: - */ -extern int cod_get_entry(struct cod_manager *cod_mgr_obj, - u32 *entry_pt); - -/* - * ======== cod_get_loader ======== - * Purpose: - * Get handle to the DBL loader. - * Parameters: - * cod_mgr_obj: handle of manager to be deleted - * loader: location to store loader handle on output. - * Returns: - * 0: Success. - * Requires: - * COD module initialized. - * valid cod_mgr_obj. - * loader != NULL. - * Ensures: - */ -extern int cod_get_loader(struct cod_manager *cod_mgr_obj, - struct dbll_tar_obj **loader); - -/* - * ======== cod_get_section ======== - * Purpose: - * Retrieve the starting address and length of a section in the COFF file - * given the section name. - * Parameters: - * lib Library handle returned from cod_open(). - * str_sect: name of the section, with or without leading "." - * addr: Location to store address. - * len: Location to store length. - * Returns: - * 0: Success - * -ESPIPE: Symbols could not be found or have not been loaded onto - * the board. - * Requires: - * COD module initialized. - * valid cod_mgr_obj. - * str_sect != NULL; - * addr != NULL; - * len != NULL; - * Ensures: - * 0: *addr and *len contain the address and length of the - * section. - * else: *addr == 0 and *len == 0; - * - */ -extern int cod_get_section(struct cod_libraryobj *lib, - char *str_sect, - u32 *addr, u32 *len); - -/* - * ======== 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. - * Parameters: - * lib: library handle returned from cod_open(). - * pstrSymbol: name of the symbol - * value: value of the symbol - * Returns: - * 0: Success. - * -ESPIPE: Symbols could not be found or have not been loaded onto - * the board. - * Requires: - * COD module initialized. - * Valid cod_mgr_obj. - * str_sym != NULL. - * pul_value != NULL. - * Ensures: - */ -extern int cod_get_sym_value(struct cod_manager *cod_mgr_obj, - char *str_sym, u32 * pul_value); - -/* - * ======== 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. - * Parameters: - * hmgr: manager to load the code with - * num_argc: number of arguments in the args array - * args: array of strings for arguments to DSP program - * write_fxn: board-specific function to write data to DSP system - * arb: arbitrary pointer to be passed as first arg to write_fxn - * envp: array of environment strings for DSP exec. - * Returns: - * 0: Success. - * -EBADF: Failed to open target code. - * Requires: - * COD module initialized. - * hmgr is valid. - * num_argc > 0. - * args != NULL. - * args[0] != NULL. - * pfn_write != NULL. - * Ensures: - */ -extern int cod_load_base(struct cod_manager *cod_mgr_obj, - u32 num_argc, char *args[], - cod_writefxn pfn_write, void *arb, - char *envp[]); - -/* - * ======== cod_open ======== - * Purpose: - * Open a library for reading sections. Does not load or set the base. - * Parameters: - * hmgr: manager to load the code with - * sz_coff_path: Coff file to open. - * flags: COD_NOLOAD (don't load symbols) or COD_SYMB (load - * symbols). - * lib_obj: Handle returned that can be used in calls to cod_close - * and cod_get_section. - * Returns: - * S_OK: Success. - * -EBADF: Failed to open target code. - * Requires: - * COD module initialized. - * hmgr is valid. - * flags == COD_NOLOAD || flags == COD_SYMB. - * sz_coff_path != NULL. - * Ensures: - */ -extern int cod_open(struct cod_manager *hmgr, - char *sz_coff_path, - u32 flags, struct cod_libraryobj **lib_obj); - -/* - * ======== cod_open_base ======== - * Purpose: - * Open base image for reading sections. Does not load the base. - * Parameters: - * hmgr: manager to load the code with - * sz_coff_path: Coff file to open. - * flags: Specifies whether to load symbols. - * Returns: - * 0: Success. - * -EBADF: Failed to open target code. - * Requires: - * COD module initialized. - * hmgr is valid. - * sz_coff_path != NULL. - * Ensures: - */ -extern int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path, - dbll_flags flags); - -/* - * ======== cod_read_section ======== - * Purpose: - * Retrieve the content of a code section given the section name. - * Parameters: - * cod_mgr_obj - manager in which to search for the symbol - * str_sect - name of the section, with or without leading "." - * str_content - buffer to store content of the section. - * Returns: - * 0: on success, error code on failure - * -ESPIPE: Symbols have not been loaded onto the board. - * Requires: - * COD module initialized. - * valid cod_mgr_obj. - * str_sect != NULL; - * str_content != NULL; - * Ensures: - * 0: *str_content stores the content of the named section. - */ -extern int cod_read_section(struct cod_libraryobj *lib, - char *str_sect, - char *str_content, u32 content_size); - -#endif /* COD_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h deleted file mode 100644 index 7cc3e12686e..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - * dbdcd.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Defines the DSP/BIOS Bridge Configuration Database (DCD) API. - * - * Copyright (C) 2008 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 DBDCD_ -#define DBDCD_ - -#include <dspbridge/dbdcddef.h> -#include <dspbridge/host_os.h> -#include <dspbridge/nldrdefs.h> - -/* - * ======== dcd_auto_register ======== - * Purpose: - * This function automatically registers DCD objects specified in a - * special COFF section called ".dcd_register" - * Parameters: - * hdcd_mgr: A DCD manager handle. - * sz_coff_path: Pointer to name of COFF file containing DCD - * objects to be registered. - * Returns: - * 0: Success. - * -EACCES: Unable to find auto-registration/read/load section. - * -EFAULT: Invalid DCD_HMANAGER handle.. - * Requires: - * DCD initialized. - * Ensures: - * Note: - * Due to the DCD database construction, it is essential for a DCD-enabled - * COFF file to contain the right COFF sections, especially - * ".dcd_register", which is used for auto registration. - */ -extern int dcd_auto_register(struct dcd_manager *hdcd_mgr, - char *sz_coff_path); - -/* - * ======== dcd_auto_unregister ======== - * Purpose: - * This function automatically unregisters DCD objects specified in a - * special COFF section called ".dcd_register" - * Parameters: - * hdcd_mgr: A DCD manager handle. - * sz_coff_path: Pointer to name of COFF file containing - * DCD objects to be unregistered. - * Returns: - * 0: Success. - * -EACCES: Unable to find auto-registration/read/load section. - * -EFAULT: Invalid DCD_HMANAGER handle.. - * Requires: - * DCD initialized. - * Ensures: - * Note: - * Due to the DCD database construction, it is essential for a DCD-enabled - * COFF file to contain the right COFF sections, especially - * ".dcd_register", which is used for auto unregistration. - */ -extern int dcd_auto_unregister(struct dcd_manager *hdcd_mgr, - char *sz_coff_path); - -/* - * ======== dcd_create_manager ======== - * Purpose: - * This function creates a DCD module manager. - * Parameters: - * sz_zl_dll_name: Pointer to a DLL name string. - * dcd_mgr: A pointer to a DCD manager handle. - * Returns: - * 0: Success. - * -ENOMEM: Unable to allocate memory for DCD manager handle. - * -EPERM: General failure. - * Requires: - * DCD initialized. - * sz_zl_dll_name is non-NULL. - * dcd_mgr is non-NULL. - * Ensures: - * A DCD manager handle is created. - */ -extern int dcd_create_manager(char *sz_zl_dll_name, - struct dcd_manager **dcd_mgr); - -/* - * ======== dcd_destroy_manager ======== - * Purpose: - * This function destroys a DCD module manager. - * Parameters: - * hdcd_mgr: A DCD manager handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid DCD manager handle. - * Requires: - * DCD initialized. - * Ensures: - */ -extern int dcd_destroy_manager(struct dcd_manager *hdcd_mgr); - -/* - * ======== dcd_enumerate_object ======== - * Purpose: - * This function enumerates currently visible DSP/BIOS Bridge objects - * and returns the UUID and type of each enumerated object. - * Parameters: - * index: The object enumeration index. - * obj_type: Type of object to enumerate. - * uuid_obj: Pointer to a dsp_uuid object. - * Returns: - * 0: Success. - * -EPERM: Unable to enumerate through the DCD database. - * ENODATA: Enumeration completed. This is not an error code. - * Requires: - * DCD initialized. - * uuid_obj is a valid pointer. - * Ensures: - * Details: - * This function can be used in conjunction with dcd_get_object_def to - * retrieve object properties. - */ -extern int dcd_enumerate_object(s32 index, - enum dsp_dcdobjtype obj_type, - struct dsp_uuid *uuid_obj); - -/* - * ======== dcd_exit ======== - * Purpose: - * This function cleans up the DCD module. - * Parameters: - * Returns: - * Requires: - * DCD initialized. - * Ensures: - */ -extern void dcd_exit(void); - -/* - * ======== dcd_get_dep_libs ======== - * Purpose: - * Given the uuid of a library and size of array of uuids, this function - * fills the array with the uuids of all dependent libraries of the input - * library. - * Parameters: - * hdcd_mgr: A DCD manager handle. - * uuid_obj: Pointer to a dsp_uuid for a library. - * num_libs: Size of uuid array (number of library uuids). - * dep_lib_uuids: Array of dependent library uuids to be filled in. - * prstnt_dep_libs: Array indicating if corresponding lib is persistent. - * phase: phase to obtain correct input library - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation failure. - * -EACCES: Failure to read section containing library info. - * -EPERM: General failure. - * Requires: - * DCD initialized. - * Valid hdcd_mgr. - * uuid_obj != NULL - * dep_lib_uuids != NULL. - * Ensures: - */ -extern int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - u16 num_libs, - struct dsp_uuid *dep_lib_uuids, - bool *prstnt_dep_libs, - enum nldr_phase phase); - -/* - * ======== dcd_get_num_dep_libs ======== - * Purpose: - * Given the uuid of a library, determine its number of dependent - * libraries. - * Parameters: - * hdcd_mgr: A DCD manager handle. - * uuid_obj: Pointer to a dsp_uuid for a library. - * num_libs: Size of uuid array (number of library uuids). - * num_pers_libs: number of persistent dependent library. - * phase: Phase to obtain correct input library - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation failure. - * -EACCES: Failure to read section containing library info. - * -EPERM: General failure. - * Requires: - * DCD initialized. - * Valid hdcd_mgr. - * uuid_obj != NULL - * num_libs != NULL. - * Ensures: - */ -extern int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - u16 *num_libs, - u16 *num_pers_libs, - enum nldr_phase phase); - -/* - * ======== dcd_get_library_name ======== - * Purpose: - * This function returns the name of a (dynamic) library for a given - * UUID. - * Parameters: - * hdcd_mgr: A DCD manager handle. - * uuid_obj: Pointer to a dsp_uuid that represents a unique DSP/BIOS - * Bridge object. - * str_lib_name: Buffer to hold library name. - * buff_size: Contains buffer size. Set to string size on output. - * phase: Which phase to load - * phase_split: Are phases in multiple libraries - * Returns: - * 0: Success. - * -EPERM: General failure. - * Requires: - * DCD initialized. - * Valid hdcd_mgr. - * str_lib_name != NULL. - * uuid_obj != NULL - * buff_size != NULL. - * Ensures: - */ -extern int dcd_get_library_name(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - char *str_lib_name, - u32 *buff_size, - enum nldr_phase phase, - bool *phase_split); - -/* - * ======== dcd_get_object_def ======== - * Purpose: - * This function returns the properties/attributes of a DSP/BIOS Bridge - * object. - * Parameters: - * hdcd_mgr: A DCD manager handle. - * uuid_obj: Pointer to a dsp_uuid that represents a unique - * DSP/BIOS Bridge object. - * obj_type: The type of DSP/BIOS Bridge object to be - * referenced (node, processor, etc). - * obj_def: Pointer to an object definition structure. A - * union of various possible DCD object types. - * Returns: - * 0: Success. - * -EACCES: Unable to access/read/parse/load content of object code - * section. - * -EPERM: General failure. - * -EFAULT: Invalid DCD_HMANAGER handle. - * Requires: - * DCD initialized. - * obj_uuid is non-NULL. - * obj_def is non-NULL. - * Ensures: - */ -extern int dcd_get_object_def(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *obj_uuid, - enum dsp_dcdobjtype obj_type, - struct dcd_genericobj *obj_def); - -/* - * ======== dcd_get_objects ======== - * Purpose: - * This function finds all DCD objects specified in a special - * COFF section called ".dcd_register", and for each object, - * call a "register" function. The "register" function may perform - * various actions, such as 1) register nodes in the node database, 2) - * unregister nodes from the node database, and 3) add overlay nodes. - * Parameters: - * hdcd_mgr: A DCD manager handle. - * sz_coff_path: Pointer to name of COFF file containing DCD - * objects. - * register_fxn: Callback fxn to be applied on each located - * DCD object. - * handle: Handle to pass to callback. - * Returns: - * 0: Success. - * -EACCES: Unable to access/read/parse/load content of object code - * section. - * -EFAULT: Invalid DCD_HMANAGER handle.. - * Requires: - * DCD initialized. - * Ensures: - * Note: - * Due to the DCD database construction, it is essential for a DCD-enabled - * COFF file to contain the right COFF sections, especially - * ".dcd_register", which is used for auto registration. - */ -extern int dcd_get_objects(struct dcd_manager *hdcd_mgr, - char *sz_coff_path, - dcd_registerfxn register_fxn, void *handle); - -/* - * ======== dcd_init ======== - * Purpose: - * This function initializes DCD. - * Parameters: - * Returns: - * FALSE: Initialization failed. - * TRUE: Initialization succeeded. - * Requires: - * Ensures: - * DCD initialized. - */ -extern bool dcd_init(void); - -/* - * ======== dcd_register_object ======== - * Purpose: - * This function registers a DSP/BIOS Bridge object in the DCD database. - * Parameters: - * uuid_obj: Pointer to a dsp_uuid that identifies a DSP/BIOS - * Bridge object. - * obj_type: Type of object. - * psz_path_name: Path to the object's COFF file. - * Returns: - * 0: Success. - * -EPERM: Failed to register object. - * Requires: - * DCD initialized. - * uuid_obj and szPathName are non-NULL values. - * obj_type is a valid type value. - * Ensures: - */ -extern int dcd_register_object(struct dsp_uuid *uuid_obj, - enum dsp_dcdobjtype obj_type, - char *psz_path_name); - -/* - * ======== dcd_unregister_object ======== - * Purpose: - * This function de-registers a valid DSP/BIOS Bridge object from the DCD - * database. - * Parameters: - * uuid_obj: Pointer to a dsp_uuid that identifies a DSP/BIOS Bridge - * object. - * obj_type: Type of object. - * Returns: - * 0: Success. - * -EPERM: Unable to de-register the specified object. - * Requires: - * DCD initialized. - * uuid_obj is a non-NULL value. - * obj_type is a valid type value. - * Ensures: - */ -extern int dcd_unregister_object(struct dsp_uuid *uuid_obj, - enum dsp_dcdobjtype obj_type); - -#endif /* _DBDCD_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h deleted file mode 100644 index bc201b32903..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * dbdcddef.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DCD (DSP/BIOS Bridge Configuration Database) constants and types. - * - * Copyright (C) 2008 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 DBDCDDEF_ -#define DBDCDDEF_ - -#include <dspbridge/dbdefs.h> -#include <dspbridge/mgrpriv.h> /* for mgr_processorextinfo */ - -/* - * The following defines are critical elements for the DCD module: - * - * - DCD_REGKEY enables DCD functions to locate registered DCD objects. - * - DCD_REGISTER_SECTION identifies the COFF section where the UUID of - * registered DCD objects are stored. - */ -#define DCD_REGKEY "Software\\TexasInstruments\\DspBridge\\DCD" -#define DCD_REGISTER_SECTION ".dcd_register" - -#define DCD_MAXPATHLENGTH 255 - -/* DCD Manager Object */ -struct dcd_manager; - -struct dcd_key_elem { - struct list_head link; /* Make it linked to a list */ - char name[DCD_MAXPATHLENGTH]; /* Name of a given value entry */ - char *path; /* Pointer to the actual data */ -}; - -/* DCD Node Properties */ -struct dcd_nodeprops { - struct dsp_ndbprops ndb_props; - u32 msg_segid; - u32 msg_notify_type; - char *str_create_phase_fxn; - char *str_delete_phase_fxn; - char *str_execute_phase_fxn; - char *str_i_alg_name; - - /* Dynamic load properties */ - u16 load_type; /* Static, dynamic, overlay */ - u32 data_mem_seg_mask; /* Data memory requirements */ - u32 code_mem_seg_mask; /* Code memory requirements */ -}; - -/* DCD Generic Object Type */ -struct dcd_genericobj { - union dcd_obj { - struct dcd_nodeprops node_obj; /* node object. */ - /* processor object. */ - struct dsp_processorinfo proc_info; - /* extended proc object (private) */ - struct mgr_processorextinfo ext_proc_obj; - } obj_data; -}; - -/* DCD Internal Callback Type */ -typedef int(*dcd_registerfxn) (struct dsp_uuid *uuid_obj, - enum dsp_dcdobjtype obj_type, - void *handle); - -#endif /* DBDCDDEF_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h deleted file mode 100644 index c8f464505ef..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ /dev/null @@ -1,488 +0,0 @@ -/* - * dbdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global definitions and constants for DSP/BIOS Bridge. - * - * 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 DBDEFS_ -#define DBDEFS_ - -#include <linux/types.h> - -#include <dspbridge/rms_sh.h> /* Types shared between GPP and DSP */ - -#define PG_SIZE4K 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)) - -/* API return value and calling convention */ -#define DBAPI int - -/* Maximum length of node name, used in dsp_ndbprops */ -#define DSP_MAXNAMELEN 32 - -/* notify_type values for the RegisterNotify() functions. */ -#define DSP_SIGNALEVENT 0x00000001 - -/* Types of events for processors */ -#define DSP_PROCESSORSTATECHANGE 0x00000001 -#define DSP_PROCESSORATTACH 0x00000002 -#define DSP_PROCESSORDETACH 0x00000004 -#define DSP_PROCESSORRESTART 0x00000008 - -/* DSP exception events (DSP/BIOS and DSP MMU fault) */ -#define DSP_MMUFAULT 0x00000010 -#define DSP_SYSERROR 0x00000020 -#define DSP_EXCEPTIONABORT 0x00000300 -#define DSP_PWRERROR 0x00000080 -#define DSP_WDTOVERFLOW 0x00000040 - -/* IVA exception events (IVA MMU fault) */ -#define IVA_MMUFAULT 0x00000040 -/* Types of events for nodes */ -#define DSP_NODESTATECHANGE 0x00000100 -#define DSP_NODEMESSAGEREADY 0x00000200 - -/* Types of events for streams */ -#define DSP_STREAMDONE 0x00001000 -#define DSP_STREAMIOCOMPLETION 0x00002000 - -/* Handle definition representing the GPP node in DSPNode_Connect() calls */ -#define DSP_HGPPNODE 0xFFFFFFFF - -/* Node directions used in DSPNode_Connect() */ -#define DSP_TONODE 1 -#define DSP_FROMNODE 2 - -/* Define Node Minimum and Maximum Priorities */ -#define DSP_NODE_MIN_PRIORITY 1 -#define DSP_NODE_MAX_PRIORITY 15 - -/* msg_ctrl contains SM buffer description */ -#define DSP_RMSBUFDESC RMS_BUFDESC - -/* Processor ID numbers */ -#define DSP_UNIT 0 -#define IVA_UNIT 1 - -#define DSPWORD unsigned char -#define DSPWORDSIZE sizeof(DSPWORD) - -#define MAX_PROFILES 16 - -/* DSP chip type */ -#define DSPTYPE64 0x99 - -/* Handy Macros */ -#define VALID_PROC_EVENT (DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH | \ - DSP_PROCESSORDETACH | DSP_PROCESSORRESTART | DSP_NODESTATECHANGE | \ - DSP_STREAMDONE | DSP_STREAMIOCOMPLETION | DSP_MMUFAULT | \ - DSP_SYSERROR | DSP_WDTOVERFLOW | DSP_PWRERROR) - -static inline bool is_valid_proc_event(u32 x) -{ - return (x == 0 || (x & VALID_PROC_EVENT && !(x & ~VALID_PROC_EVENT))); -} - -/* The Node UUID structure */ -struct dsp_uuid { - u32 data1; - u16 data2; - u16 data3; - u8 data4; - u8 data5; - u8 data6[6]; -}; - -/* DCD types */ -enum dsp_dcdobjtype { - DSP_DCDNODETYPE, - DSP_DCDPROCESSORTYPE, - DSP_DCDLIBRARYTYPE, - DSP_DCDCREATELIBTYPE, - DSP_DCDEXECUTELIBTYPE, - DSP_DCDDELETELIBTYPE, - /* DSP_DCDMAXOBJTYPE is meant to be the last DCD object type */ - DSP_DCDMAXOBJTYPE -}; - -/* Processor states */ -enum dsp_procstate { - PROC_STOPPED, - PROC_LOADED, - PROC_RUNNING, - PROC_ERROR -}; - -/* - * Node types: Message node, task node, xDAIS socket node, and - * device node. _NODE_GPP is used when defining a stream connection - * between a task or socket node and the GPP. - * - */ -enum node_type { - NODE_DEVICE, - NODE_TASK, - NODE_DAISSOCKET, - NODE_MESSAGE, - NODE_GPP -}; - -/* - * ======== node_state ======== - * Internal node states. - */ -enum node_state { - NODE_ALLOCATED, - NODE_CREATED, - NODE_RUNNING, - NODE_PAUSED, - NODE_DONE, - NODE_CREATING, - NODE_STARTING, - NODE_PAUSING, - NODE_TERMINATING, - NODE_DELETING, -}; - -/* Stream states */ -enum dsp_streamstate { - STREAM_IDLE, - STREAM_READY, - STREAM_PENDING, - STREAM_DONE -}; - -/* Stream connect types */ -enum dsp_connecttype { - CONNECTTYPE_NODEOUTPUT, - CONNECTTYPE_GPPOUTPUT, - CONNECTTYPE_NODEINPUT, - CONNECTTYPE_GPPINPUT -}; - -/* Stream mode types */ -enum dsp_strmmode { - STRMMODE_PROCCOPY, /* Processor(s) copy stream data payloads */ - STRMMODE_ZEROCOPY, /* Strm buffer ptrs swapped no data copied */ - STRMMODE_LDMA, /* Local DMA : OMAP's System-DMA device */ - STRMMODE_RDMA /* Remote DMA: OMAP's DSP-DMA device */ -}; - -/* Resource Types */ -enum dsp_resourceinfotype { - DSP_RESOURCE_DYNDARAM = 0, - DSP_RESOURCE_DYNSARAM, - DSP_RESOURCE_DYNEXTERNAL, - DSP_RESOURCE_DYNSRAM, - DSP_RESOURCE_PROCLOAD -}; - -/* Memory Segment Types */ -enum dsp_memtype { - DSP_DYNDARAM = 0, - DSP_DYNSARAM, - DSP_DYNEXTERNAL, - DSP_DYNSRAM -}; - -/* Memory Flush Types */ -enum dsp_flushtype { - PROC_INVALIDATE_MEM = 0, - PROC_WRITEBACK_MEM, - PROC_WRITEBACK_INVALIDATE_MEM, -}; - -/* Memory Segment Status Values */ -struct dsp_memstat { - u32 size; - u32 total_free_size; - u32 len_max_free_block; - u32 num_free_blocks; - u32 num_alloc_blocks; -}; - -/* Processor Load information Values */ -struct dsp_procloadstat { - u32 curr_load; - u32 predicted_load; - u32 curr_dsp_freq; - u32 predicted_freq; -}; - -/* Attributes for STRM connections between nodes */ -struct dsp_strmattr { - u32 seg_id; /* Memory segment on DSP to allocate buffers */ - u32 buf_size; /* Buffer size (DSP words) */ - u32 num_bufs; /* Number of buffers */ - u32 buf_alignment; /* Buffer alignment */ - u32 timeout; /* Timeout for blocking STRM calls */ - enum dsp_strmmode strm_mode; /* mode of stream when opened */ - /* DMA chnl id if dsp_strmmode is LDMA or RDMA */ - u32 dma_chnl_id; - u32 dma_priority; /* DMA channel priority 0=lowest, >0=high */ -}; - -/* The dsp_cbdata structure */ -struct dsp_cbdata { - u32 cb_data; - u8 node_data[1]; -}; - -/* The dsp_msg structure */ -struct dsp_msg { - u32 cmd; - u32 arg1; - u32 arg2; -}; - -/* The dsp_resourcereqmts structure for node's resource requirements */ -struct dsp_resourcereqmts { - u32 cb_struct; - u32 static_data_size; - u32 global_data_size; - u32 program_mem_size; - u32 wc_execution_time; - u32 wc_period; - u32 wc_deadline; - u32 avg_exection_time; - u32 minimum_period; -}; - -/* - * The dsp_streamconnect structure describes a stream connection - * between two nodes, or between a node and the GPP - */ -struct dsp_streamconnect { - u32 cb_struct; - enum dsp_connecttype connect_type; - u32 this_node_stream_index; - void *connected_node; - struct dsp_uuid ui_connected_node_id; - u32 connected_node_stream_index; -}; - -struct dsp_nodeprofs { - u32 heap_size; -}; - -/* The dsp_ndbprops structure reports the attributes of a node */ -struct dsp_ndbprops { - u32 cb_struct; - struct dsp_uuid ui_node_id; - char ac_name[DSP_MAXNAMELEN]; - enum node_type ntype; - u32 cache_on_gpp; - struct dsp_resourcereqmts dsp_resource_reqmts; - s32 prio; - u32 stack_size; - u32 sys_stack_size; - u32 stack_seg; - u32 message_depth; - u32 num_input_streams; - u32 num_output_streams; - u32 timeout; - u32 count_profiles; /* Number of supported profiles */ - /* Array of profiles */ - struct dsp_nodeprofs node_profiles[MAX_PROFILES]; - u32 stack_seg_name; /* Stack Segment Name */ -}; - - /* The dsp_nodeattrin structure describes the attributes of a - * node client */ -struct dsp_nodeattrin { - u32 cb_struct; - s32 prio; - u32 timeout; - u32 profile_id; - /* Reserved, for Bridge Internal use only */ - u32 heap_size; - void *pgpp_virt_addr; /* Reserved, for Bridge Internal use only */ -}; - - /* The dsp_nodeinfo structure is used to retrieve information - * about a node */ -struct dsp_nodeinfo { - u32 cb_struct; - struct dsp_ndbprops nb_node_database_props; - u32 execution_priority; - enum node_state ns_execution_state; - void *device_owner; - u32 number_streams; - struct dsp_streamconnect sc_stream_connection[16]; - u32 node_env; -}; - - /* The dsp_nodeattr structure describes the attributes of a node */ -struct dsp_nodeattr { - u32 cb_struct; - struct dsp_nodeattrin in_node_attr_in; - u32 node_attr_inputs; - u32 node_attr_outputs; - struct dsp_nodeinfo node_info; -}; - -/* - * Notification type: either the name of an opened event, or an event or - * window handle. - */ -struct dsp_notification { - char *name; - void *handle; -}; - -/* The dsp_processorattrin structure describes the attributes of a processor */ -struct dsp_processorattrin { - u32 cb_struct; - u32 timeout; -}; -/* - * The dsp_processorinfo structure describes basic capabilities of a - * DSP processor - */ -struct dsp_processorinfo { - u32 cb_struct; - int processor_family; - int processor_type; - u32 clock_rate; - u32 internal_mem_size; - u32 external_mem_size; - u32 processor_id; - int ty_running_rtos; - s32 node_min_priority; - s32 node_max_priority; -}; - -/* Error information of last DSP exception signalled to the GPP */ -struct dsp_errorinfo { - u32 err_mask; - u32 val1; - u32 val2; - u32 val3; -}; - -/* The dsp_processorstate structure describes the state of a DSP processor */ -struct dsp_processorstate { - u32 cb_struct; - enum dsp_procstate proc_state; -}; - -/* - * The dsp_resourceinfo structure is used to retrieve information about a - * processor's resources - */ -struct dsp_resourceinfo { - u32 cb_struct; - enum dsp_resourceinfotype resource_type; - union { - u32 resource; - struct dsp_memstat mem_stat; - struct dsp_procloadstat proc_load_stat; - } result; -}; - -/* - * The dsp_streamattrin structure describes the attributes of a stream, - * including segment and alignment of data buffers allocated with - * DSPStream_AllocateBuffers(), if applicable - */ -struct dsp_streamattrin { - u32 cb_struct; - u32 timeout; - u32 segment_id; - u32 buf_alignment; - u32 num_bufs; - enum dsp_strmmode strm_mode; - u32 dma_chnl_id; - u32 dma_priority; -}; - -/* The dsp_bufferattr structure describes the attributes of a data buffer */ -struct dsp_bufferattr { - u32 cb_struct; - u32 segment_id; - u32 buf_alignment; -}; - -/* - * The dsp_streaminfo structure is used to retrieve information - * about a stream. - */ -struct dsp_streaminfo { - u32 cb_struct; - u32 number_bufs_allowed; - u32 number_bufs_in_stream; - u32 number_bytes; - void *sync_object_handle; - enum dsp_streamstate ss_stream_state; -}; - -/* DMM MAP attributes -It is a bit mask with each bit value indicating a specific attribute -bit 0 - GPP address type (user virtual=0, physical=1) -bit 1 - MMU Endianism (Big Endian=1, Little Endian=0) -bit 2 - MMU mixed page attribute (Mixed/ CPUES=1, TLBES =0) -bit 3 - MMU element size = 8bit (valid only for non mixed page entries) -bit 4 - MMU element size = 16bit (valid only for non mixed page entries) -bit 5 - MMU element size = 32bit (valid only for non mixed page entries) -bit 6 - MMU element size = 64bit (valid only for non mixed page entries) - -bit 14 - Input (read only) buffer -bit 15 - Output (writeable) buffer -*/ - -/* Types of mapping attributes */ - -/* MPU address is virtual and needs to be translated to physical addr */ -#define DSP_MAPVIRTUALADDR 0x00000000 -#define DSP_MAPPHYSICALADDR 0x00000001 - -/* Mapped data is big endian */ -#define DSP_MAPBIGENDIAN 0x00000002 -#define DSP_MAPLITTLEENDIAN 0x00000000 - -/* Element size is based on DSP r/w access size */ -#define DSP_MAPMIXEDELEMSIZE 0x00000004 - -/* - * Element size for MMU mapping (8, 16, 32, or 64 bit) - * Ignored if DSP_MAPMIXEDELEMSIZE enabled - */ -#define DSP_MAPELEMSIZE8 0x00000008 -#define DSP_MAPELEMSIZE16 0x00000010 -#define DSP_MAPELEMSIZE32 0x00000020 -#define DSP_MAPELEMSIZE64 0x00000040 - -#define DSP_MAPVMALLOCADDR 0x00000080 - -#define DSP_MAPDONOTLOCK 0x00000100 - -#define DSP_MAP_DIR_MASK 0x3FFF - -#define GEM_CACHE_LINE_SIZE 128 -#define GEM_L1P_PREFETCH_SIZE 128 - -/* - * Definitions from dbreg.h - */ - -#define DSPPROCTYPE_C64 6410 -#define IVAPROCTYPE_ARM7 470 - -/* Max registry path length. Also the max registry value length. */ -#define MAXREGPATHLENGTH 255 - -#endif /* DBDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbll.h b/drivers/staging/tidspbridge/include/dspbridge/dbll.h deleted file mode 100644 index 46a9e0027ea..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dbll.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * dbll.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge Dynamic load library module interface. Function header - * comments are in the file dblldefs.h. - * - * 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 DBLL_ -#define DBLL_ - -#include <dspbridge/dbdefs.h> -#include <dspbridge/dblldefs.h> - -extern bool symbols_reloaded; - -extern void dbll_close(struct dbll_library_obj *zl_lib); -extern int dbll_create(struct dbll_tar_obj **target_obj, - struct dbll_attrs *pattrs); -extern void dbll_delete(struct dbll_tar_obj *target); -extern void dbll_exit(void); -extern bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name, - struct dbll_sym_val **sym_val); -extern void dbll_get_attrs(struct dbll_tar_obj *target, - struct dbll_attrs *pattrs); -extern bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name, - struct dbll_sym_val **sym_val); -extern int dbll_get_sect(struct dbll_library_obj *lib, char *name, - u32 *paddr, u32 *psize); -extern bool dbll_init(void); -extern int dbll_load(struct dbll_library_obj *lib, - dbll_flags flags, - struct dbll_attrs *attrs, u32 * entry); -extern int dbll_open(struct dbll_tar_obj *target, char *file, - dbll_flags flags, - struct dbll_library_obj **lib_obj); -extern int dbll_read_sect(struct dbll_library_obj *lib, - char *name, char *buf, u32 size); -extern void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs); -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address, - u32 offset_range, u32 *sym_addr_output, char *name_output); -#endif - -#endif /* DBLL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h deleted file mode 100644 index 30e0aa0540d..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * dblldefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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 DBLLDEFS_ -#define DBLLDEFS_ - -/* - * Bit masks for dbl_flags. - */ -#define DBLL_NOLOAD 0x0 /* Don't load symbols, code, or data */ -#define DBLL_SYMB 0x1 /* load symbols */ -#define DBLL_CODE 0x2 /* load code */ -#define DBLL_DATA 0x4 /* load data */ -#define DBLL_DYNAMIC 0x8 /* dynamic load */ -#define DBLL_BSS 0x20 /* Unitialized section */ - -#define DBLL_MAXPATHLENGTH 255 - -/* - * ======== DBLL_Target ======== - * - */ -struct dbll_tar_obj; - -/* - * ======== dbll_flags ======== - * Specifies whether to load code, data, or symbols - */ -typedef s32 dbll_flags; - -/* - * ======== DBLL_Library ======== - * - */ -struct dbll_library_obj; - -/* - * ======== dbll_sect_info ======== - * For collecting info on overlay sections - */ -struct dbll_sect_info { - const char *name; /* name of section */ - u32 sect_run_addr; /* run address of section */ - u32 sect_load_addr; /* load address of section */ - u32 size; /* size of section (target MAUs) */ - dbll_flags type; /* Code, data, or BSS */ -}; - -/* - * ======== dbll_sym_val ======== - * (Needed for dynamic load library) - */ -struct dbll_sym_val { - u32 value; -}; - -/* - * ======== dbll_alloc_fxn ======== - * Allocate memory function. Allocate or reserve (if reserved == TRUE) - * "size" bytes of memory from segment "space" and return the address in - * *dsp_address (or starting at *dsp_address if reserve == TRUE). Returns 0 on - * success, or an error code on failure. - */ -typedef s32(*dbll_alloc_fxn) (void *hdl, s32 space, u32 size, u32 align, - u32 *dsp_address, s32 seg_id, s32 req, - bool reserved); - -/* - * ======== dbll_close_fxn ======== - */ -typedef s32(*dbll_f_close_fxn) (void *); - -/* - * ======== dbll_free_fxn ======== - * Free memory function. Free, or unreserve (if reserved == TRUE) "size" - * bytes of memory from segment "space" - */ -typedef bool(*dbll_free_fxn) (void *hdl, u32 addr, s32 space, u32 size, - bool reserved); - -/* - * ======== dbll_f_open_fxn ======== - */ -typedef void *(*dbll_f_open_fxn) (const char *, const char *); - -/* - * ======== dbll_log_write_fxn ======== - * Function to call when writing data from a section, to log the info. - * Can be NULL if no logging is required. - */ -typedef int(*dbll_log_write_fxn) (void *handle, - struct dbll_sect_info *sect, u32 addr, - u32 bytes); - -/* - * ======== dbll_read_fxn ======== - */ -typedef s32(*dbll_read_fxn) (void *, size_t, size_t, void *); - -/* - * ======== dbll_seek_fxn ======== - */ -typedef s32(*dbll_seek_fxn) (void *, long, int); - -/* - * ======== dbll_sym_lookup ======== - * Symbol lookup function - Find the symbol name and return its value. - * - * Parameters: - * handle - Opaque handle - * parg - Opaque argument. - * name - Name of symbol to lookup. - * sym - Location to store address of symbol structure. - * - * Returns: - * TRUE: Success (symbol was found). - * FALSE: Failed to find symbol. - */ -typedef bool(*dbll_sym_lookup) (void *handle, void *parg, void *rmm_handle, - const char *name, struct dbll_sym_val ** sym); - -/* - * ======== dbll_tell_fxn ======== - */ -typedef s32(*dbll_tell_fxn) (void *); - -/* - * ======== dbll_write_fxn ======== - * Write memory function. Write "n" HOST bytes of memory to segment "mtype" - * starting at address "dsp_address" from the buffer "buf". The buffer is - * formatted as an array of words appropriate for the DSP. - */ -typedef s32(*dbll_write_fxn) (void *hdl, u32 dsp_address, void *buf, - u32 n, s32 mtype); - -/* - * ======== dbll_attrs ======== - */ -struct dbll_attrs { - dbll_alloc_fxn alloc; - dbll_free_fxn free; - void *rmm_handle; /* Handle to pass to alloc, free functions */ - dbll_write_fxn write; - void *input_params; /* Handle to pass to write, cinit function */ - bool base_image; - dbll_log_write_fxn log_write; - void *log_write_handle; - - /* Symbol matching function and handle to pass to it */ - dbll_sym_lookup sym_lookup; - void *sym_handle; - void *sym_arg; - - /* - * These file manipulation functions should be compatible with the - * "C" run time library functions of the same name. - */ - s32(*fread) (void *, size_t, size_t, void *); - s32(*fseek) (void *, long, int); - s32(*ftell) (void *); - s32(*fclose) (void *); - void *(*fopen) (const char *, const char *); -}; - -/* - * ======== dbll_close ======== - * Close library opened with dbll_open. - * Parameters: - * lib - Handle returned from dbll_open(). - * Returns: - * Requires: - * DBL initialized. - * Valid lib. - * Ensures: - */ -typedef void (*dbll_close_fxn) (struct dbll_library_obj *library); - -/* - * ======== dbll_create ======== - * Create a target object, specifying the alloc, free, and write functions. - * Parameters: - * target_obj - Location to store target handle on output. - * pattrs - Attributes. - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation failed. - * Requires: - * DBL initialized. - * pattrs != NULL. - * target_obj != NULL; - * Ensures: - * Success: *target_obj != NULL. - * Failure: *target_obj == NULL. - */ -typedef int(*dbll_create_fxn) (struct dbll_tar_obj **target_obj, - struct dbll_attrs *attrs); - -/* - * ======== dbll_delete ======== - * Delete target object and free resources for any loaded libraries. - * Parameters: - * target - Handle returned from DBLL_Create(). - * Returns: - * Requires: - * DBL initialized. - * Valid target. - * Ensures: - */ -typedef void (*dbll_delete_fxn) (struct dbll_tar_obj *target); - -/* - * ======== dbll_exit ======== - * Discontinue use of DBL module. - * Parameters: - * Returns: - * Requires: - * refs > 0. - * Ensures: - * refs >= 0. - */ -typedef void (*dbll_exit_fxn) (void); - -/* - * ======== dbll_get_addr ======== - * Get address of name in the specified library. - * Parameters: - * lib - Handle returned from dbll_open(). - * name - Name of symbol - * sym_val - Location to store symbol address on output. - * Returns: - * TRUE: Success. - * FALSE: Symbol not found. - * Requires: - * DBL initialized. - * Valid library. - * name != NULL. - * sym_val != NULL. - * Ensures: - */ -typedef bool(*dbll_get_addr_fxn) (struct dbll_library_obj *lib, char *name, - struct dbll_sym_val **sym_val); - -/* - * ======== dbll_get_attrs ======== - * Retrieve the attributes of the target. - * Parameters: - * target - Handle returned from DBLL_Create(). - * pattrs - Location to store attributes on output. - * Returns: - * Requires: - * DBL initialized. - * Valid target. - * pattrs != NULL. - * Ensures: - */ -typedef void (*dbll_get_attrs_fxn) (struct dbll_tar_obj *target, - struct dbll_attrs *attrs); - -/* - * ======== dbll_get_c_addr ======== - * Get address of "C" name on the specified library. - * Parameters: - * lib - Handle returned from dbll_open(). - * name - Name of symbol - * sym_val - Location to store symbol address on output. - * Returns: - * TRUE: Success. - * FALSE: Symbol not found. - * Requires: - * DBL initialized. - * Valid target. - * name != NULL. - * sym_val != NULL. - * Ensures: - */ -typedef bool(*dbll_get_c_addr_fxn) (struct dbll_library_obj *lib, char *name, - struct dbll_sym_val **sym_val); - -/* - * ======== dbll_get_sect ======== - * Get address and size of a named section. - * Parameters: - * lib - Library handle returned from dbll_open(). - * name - Name of section. - * paddr - Location to store section address on output. - * psize - Location to store section size on output. - * Returns: - * 0: Success. - * -ENXIO: Section not found. - * Requires: - * DBL initialized. - * Valid lib. - * name != NULL. - * paddr != NULL; - * psize != NULL. - * Ensures: - */ -typedef int(*dbll_get_sect_fxn) (struct dbll_library_obj *lib, - char *name, u32 * addr, u32 * size); - -/* - * ======== dbll_init ======== - * Initialize DBL module. - * Parameters: - * Returns: - * TRUE: Success. - * FALSE: Failure. - * Requires: - * refs >= 0. - * Ensures: - * Success: refs > 0. - * Failure: refs >= 0. - */ -typedef bool(*dbll_init_fxn) (void); - -/* - * ======== dbll_load ======== - * Load library onto the target. - * - * Parameters: - * lib - Library handle returned from dbll_open(). - * flags - Load code, data and/or symbols. - * attrs - May contain alloc, free, and write function. - * entry_pt - Location to store program entry on output. - * Returns: - * 0: Success. - * -EBADF: File read failed. - * -EILSEQ: Failure in dynamic loader library. - * Requires: - * DBL initialized. - * Valid lib. - * entry != NULL. - * Ensures: - */ -typedef int(*dbll_load_fxn) (struct dbll_library_obj *lib, - dbll_flags flags, - struct dbll_attrs *attrs, u32 *entry); -/* - * ======== dbll_open ======== - * dbll_open() returns a library handle that can be used to load/unload - * the symbols/code/data via dbll_load()/dbll_unload(). - * Parameters: - * target - Handle returned from dbll_create(). - * file - Name of file to open. - * flags - If flags & DBLL_SYMB, load symbols. - * lib_obj - Location to store library handle on output. - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation failure. - * -EBADF: File open/read failure. - * Unable to determine target type. - * Requires: - * DBL initialized. - * Valid target. - * file != NULL. - * lib_obj != NULL. - * dbll_attrs fopen function non-NULL. - * Ensures: - * Success: Valid *lib_obj. - * Failure: *lib_obj == NULL. - */ -typedef int(*dbll_open_fxn) (struct dbll_tar_obj *target, char *file, - dbll_flags flags, - struct dbll_library_obj **lib_obj); - -/* - * ======== dbll_read_sect ======== - * Read COFF section into a character buffer. - * Parameters: - * lib - Library handle returned from dbll_open(). - * name - Name of section. - * pbuf - Buffer to write section contents into. - * size - Buffer size - * Returns: - * 0: Success. - * -ENXIO: Named section does not exists. - * Requires: - * DBL initialized. - * Valid lib. - * name != NULL. - * pbuf != NULL. - * size != 0. - * Ensures: - */ -typedef int(*dbll_read_sect_fxn) (struct dbll_library_obj *lib, - char *name, char *content, - u32 cont_size); -/* - * ======== dbll_unload ======== - * Unload library loaded with dbll_load(). - * Parameters: - * lib - Handle returned from dbll_open(). - * attrs - Contains free() function and handle to pass to it. - * Returns: - * Requires: - * DBL initialized. - * Valid lib. - * Ensures: - */ -typedef void (*dbll_unload_fxn) (struct dbll_library_obj *library, - struct dbll_attrs *attrs); -struct dbll_fxns { - dbll_close_fxn close_fxn; - dbll_create_fxn create_fxn; - dbll_delete_fxn delete_fxn; - dbll_exit_fxn exit_fxn; - dbll_get_attrs_fxn get_attrs_fxn; - dbll_get_addr_fxn get_addr_fxn; - dbll_get_c_addr_fxn get_c_addr_fxn; - dbll_get_sect_fxn get_sect_fxn; - dbll_init_fxn init_fxn; - dbll_load_fxn load_fxn; - dbll_open_fxn open_fxn; - dbll_read_sect_fxn read_sect_fxn; - dbll_unload_fxn unload_fxn; -}; - -#endif /* DBLDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h deleted file mode 100644 index fa2d79ef6cc..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ /dev/null @@ -1,620 +0,0 @@ -/* - * dev.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Bridge Bridge driver device operations. - * - * 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 DEV_ -#define DEV_ - -/* ----------------------------------- Module Dependent Headers */ -#include <dspbridge/chnldefs.h> -#include <dspbridge/cmm.h> -#include <dspbridge/cod.h> -#include <dspbridge/dspdeh.h> -#include <dspbridge/nodedefs.h> -#include <dspbridge/disp.h> -#include <dspbridge/dspdefs.h> -#include <dspbridge/dmm.h> -#include <dspbridge/host_os.h> - -/* ----------------------------------- This */ -#include <dspbridge/devdefs.h> - -/* - * ======== dev_brd_write_fxn ======== - * Purpose: - * Exported function to be used as the COD write function. This function - * is passed a handle to a DEV_hObject by ZL in arb, then calls the - * device's bridge_brd_write() function. - * Parameters: - * arb: Handle to a Device Object. - * dev_ctxt: Handle to Bridge driver defined device info. - * dsp_addr: Address on DSP board (Destination). - * host_buf: Pointer to host buffer (Source). - * ul_num_bytes: Number of bytes to transfer. - * mem_type: Memory space on DSP to which to transfer. - * Returns: - * Number of bytes written. Returns 0 if the DEV_hObject passed in via - * arb is invalid. - * Requires: - * DEV Initialized. - * host_buf != NULL - * Ensures: - */ -extern u32 dev_brd_write_fxn(void *arb, - u32 dsp_add, - void *host_buf, u32 ul_num_bytes, u32 mem_space); - -/* - * ======== dev_create_device ======== - * Purpose: - * Called by the operating system to load the Bridge Driver for a - * 'Bridge device. - * Parameters: - * device_obj: Ptr to location to receive the device object handle. - * driver_file_name: Name of Bridge driver PE DLL file to load. If the - * absolute path is not provided, the file is loaded - * through 'Bridge's module search path. - * host_config: Host configuration information, to be passed down - * to the Bridge driver when bridge_dev_create() is called. - * pDspConfig: DSP resources, to be passed down to the Bridge driver - * when bridge_dev_create() is called. - * dev_node_obj: Platform specific device node. - * Returns: - * 0: Module is loaded, device object has been created - * -ENOMEM: Insufficient memory to create needed resources. - * -EPERM: Unable to find Bridge driver entry point function. - * -ESPIPE: Unable to load ZL DLL. - * Requires: - * DEV Initialized. - * device_obj != NULL. - * driver_file_name != NULL. - * host_config != NULL. - * pDspConfig != NULL. - * Ensures: - * 0: *device_obj will contain handle to the new device object. - * Otherwise, does not create the device object, ensures the Bridge driver - * module is unloaded, and sets *device_obj to NULL. - */ -extern int dev_create_device(struct dev_object - **device_obj, - const char *driver_file_name, - struct cfg_devnode *dev_node_obj); - -/* - * ======== dev_create2 ======== - * Purpose: - * After successful loading of the image from api_init_complete2 - * (PROC Auto_Start) or proc_load this fxn is called. This creates - * the Node Manager and updates the DEV Object. - * Parameters: - * hdev_obj: Handle to device object created with dev_create_device(). - * Returns: - * 0: Successful Creation of Node Manager - * -EPERM: Some Error Occurred. - * Requires: - * DEV Initialized - * Valid hdev_obj - * Ensures: - * 0 and hdev_obj->node_mgr != NULL - * else hdev_obj->node_mgr == NULL - */ -extern int dev_create2(struct dev_object *hdev_obj); - -/* - * ======== dev_destroy2 ======== - * Purpose: - * Destroys the Node manager for this device. - * Parameters: - * hdev_obj: Handle to device object created with dev_create_device(). - * Returns: - * 0: Successful Creation of Node Manager - * -EPERM: Some Error Occurred. - * Requires: - * DEV Initialized - * Valid hdev_obj - * Ensures: - * 0 and hdev_obj->node_mgr == NULL - * else -EPERM. - */ -extern int dev_destroy2(struct dev_object *hdev_obj); - -/* - * ======== dev_destroy_device ======== - * Purpose: - * Destroys the channel manager for this device, if any, calls - * bridge_dev_destroy(), and then attempts to unload the Bridge module. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * -EPERM: The Bridge driver failed it's bridge_dev_destroy() function. - * Requires: - * DEV Initialized. - * Ensures: - */ -extern int dev_destroy_device(struct dev_object - *hdev_obj); - -/* - * ======== dev_get_chnl_mgr ======== - * Purpose: - * Retrieve the handle to the channel manager created for this device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0: *mgr contains a handle to a channel manager object, - * or NULL. - * else: *mgr is NULL. - */ -extern int dev_get_chnl_mgr(struct dev_object *hdev_obj, - struct chnl_mgr **mgr); - -/* - * ======== dev_get_cmm_mgr ======== - * Purpose: - * Retrieve the handle to the shared memory manager created for this - * device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0: *mgr contains a handle to a channel manager object, - * or NULL. - * else: *mgr is NULL. - */ -extern int dev_get_cmm_mgr(struct dev_object *hdev_obj, - struct cmm_object **mgr); - -/* - * ======== dev_get_dmm_mgr ======== - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0: *mgr contains a handle to a channel manager object, - * or NULL. - * else: *mgr is NULL. - */ -extern int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr); - -/* - * ======== dev_get_cod_mgr ======== - * Purpose: - * Retrieve the COD manager create for this device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *cod_mgr: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * cod_mgr != NULL. - * DEV Initialized. - * Ensures: - * 0: *cod_mgr contains a handle to a COD manager object. - * else: *cod_mgr is NULL. - */ -extern int dev_get_cod_mgr(struct dev_object *hdev_obj, - struct cod_manager **cod_mgr); - -/* - * ======== dev_get_deh_mgr ======== - * Purpose: - * Retrieve the DEH manager created for this device. - * Parameters: - * hdev_obj: Handle to device object created with dev_create_device(). - * *deh_manager: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * deh_manager != NULL. - * DEH Initialized. - * Ensures: - * 0: *deh_manager contains a handle to a DEH manager object. - * else: *deh_manager is NULL. - */ -extern int dev_get_deh_mgr(struct dev_object *hdev_obj, - struct deh_mgr **deh_manager); - -/* - * ======== dev_get_dev_node ======== - * Purpose: - * Retrieve the platform specific device ID for this device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * dev_nde: Ptr to location to get the device node handle. - * Returns: - * 0: Returns a DEVNODE in *dev_node_obj. - * -EFAULT: Invalid hdev_obj. - * Requires: - * dev_nde != NULL. - * DEV Initialized. - * Ensures: - * 0: *dev_nde contains a platform specific device ID; - * else: *dev_nde is NULL. - */ -extern int dev_get_dev_node(struct dev_object *hdev_obj, - struct cfg_devnode **dev_nde); - -/* - * ======== dev_get_dev_type ======== - * Purpose: - * Retrieve the platform specific device ID for this device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * dev_nde: Ptr to location to get the device node handle. - * Returns: - * 0: Success - * -EFAULT: Invalid hdev_obj. - * Requires: - * dev_nde != NULL. - * DEV Initialized. - * Ensures: - * 0: *dev_nde contains a platform specific device ID; - * else: *dev_nde is NULL. - */ -extern int dev_get_dev_type(struct dev_object *device_obj, - u8 *dev_type); - -/* - * ======== dev_get_first ======== - * Purpose: - * Retrieve the first Device Object handle from an internal linked list of - * of DEV_OBJECTs maintained by DEV. - * Parameters: - * Returns: - * NULL if there are no device objects stored; else - * a valid DEV_HOBJECT. - * Requires: - * No calls to dev_create_device or dev_destroy_device (which my modify the - * internal device object list) may occur between calls to dev_get_first - * and dev_get_next. - * Ensures: - * The DEV_HOBJECT returned is valid. - * A subsequent call to dev_get_next will return the next device object in - * the list. - */ -extern struct dev_object *dev_get_first(void); - -/* - * ======== dev_get_intf_fxns ======== - * Purpose: - * Retrieve the Bridge driver interface function structure for the - * loaded Bridge driver. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *if_fxns: Ptr to location to store fxn interface. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * if_fxns != NULL. - * DEV Initialized. - * Ensures: - * 0: *if_fxns contains a pointer to the Bridge - * driver interface; - * else: *if_fxns is NULL. - */ -extern int dev_get_intf_fxns(struct dev_object *hdev_obj, - struct bridge_drv_interface **if_fxns); - -/* - * ======== dev_get_io_mgr ======== - * Purpose: - * Retrieve the handle to the IO manager created for this device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0: *mgr contains a handle to an IO manager object. - * else: *mgr is NULL. - */ -extern int dev_get_io_mgr(struct dev_object *hdev_obj, - struct io_mgr **mgr); - -/* - * ======== dev_get_next ======== - * Purpose: - * Retrieve the next Device Object handle from an internal linked list of - * of DEV_OBJECTs maintained by DEV, after having previously called - * dev_get_first() and zero or more dev_get_next - * Parameters: - * hdev_obj: Handle to the device object returned from a previous - * call to dev_get_first() or dev_get_next(). - * Returns: - * NULL if there are no further device objects on the list or hdev_obj - * was invalid; - * else the next valid DEV_HOBJECT in the list. - * Requires: - * No calls to dev_create_device or dev_destroy_device (which my modify the - * internal device object list) may occur between calls to dev_get_first - * and dev_get_next. - * Ensures: - * The DEV_HOBJECT returned is valid. - * A subsequent call to dev_get_next will return the next device object in - * the list. - */ -extern struct dev_object *dev_get_next(struct dev_object - *hdev_obj); - -/* - * ========= dev_get_msg_mgr ======== - * Purpose: - * Retrieve the msg_ctrl Manager Handle from the DevObject. - * Parameters: - * hdev_obj: Handle to the Dev Object - * msg_man: Location where msg_ctrl Manager handle will be returned. - * Returns: - * Requires: - * DEV Initialized. - * Valid hdev_obj. - * node_man != NULL. - * Ensures: - */ -extern void dev_get_msg_mgr(struct dev_object *hdev_obj, - struct msg_mgr **msg_man); - -/* - * ========= dev_get_node_manager ======== - * Purpose: - * Retrieve the Node Manager Handle from the DevObject. It is an - * accessor function - * Parameters: - * hdev_obj: Handle to the Dev Object - * node_man: Location where Handle to the Node Manager will be - * returned.. - * Returns: - * 0: Success - * -EFAULT: Invalid Dev Object handle. - * Requires: - * DEV Initialized. - * node_man is not null - * Ensures: - * 0: *node_man contains a handle to a Node manager object. - * else: *node_man is NULL. - */ -extern int dev_get_node_manager(struct dev_object - *hdev_obj, - struct node_mgr **node_man); - -/* - * ======== dev_get_symbol ======== - * Purpose: - * Get the value of a symbol in the currently loaded program. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * str_sym: Name of symbol to look up. - * pul_value: Ptr to symbol value. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * -ESPIPE: Symbols couldn not be found or have not been loaded onto - * the board. - * Requires: - * str_sym != NULL. - * pul_value != NULL. - * DEV Initialized. - * Ensures: - * 0: *pul_value contains the symbol value; - */ -extern int dev_get_symbol(struct dev_object *hdev_obj, - const char *str_sym, u32 * pul_value); - -/* - * ======== dev_get_bridge_context ======== - * Purpose: - * Retrieve the Bridge Context handle, as returned by the - * bridge_dev_create fxn. - * Parameters: - * hdev_obj: Handle to device object created with dev_create_device() - * *phbridge_context: Ptr to location to store context handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * phbridge_context != NULL. - * DEV Initialized. - * Ensures: - * 0: *phbridge_context contains context handle; - * else: *phbridge_context is NULL; - */ -extern int dev_get_bridge_context(struct dev_object *hdev_obj, - struct bridge_dev_context - **phbridge_context); - -/* - * ======== dev_insert_proc_object ======== - * Purpose: - * Inserts the Processor Object into the List of PROC Objects - * kept in the DEV Object - * Parameters: - * proc_obj: Handle to the Proc Object - * hdev_obj Handle to the Dev Object - * bAttachedNew Specifies if there are already processors attached - * Returns: - * 0: Successfully inserted into the list - * Requires: - * proc_obj is not NULL - * hdev_obj is a valid handle to the DEV. - * DEV Initialized. - * List(of Proc object in Dev) Exists. - * Ensures: - * 0 & the PROC Object is inserted and the list is not empty - * Details: - * If the List of Proc Object is empty bAttachedNew is TRUE, it indicated - * this is the first Processor attaching. - * If it is False, there are already processors attached. - */ -extern int dev_insert_proc_object(struct dev_object - *hdev_obj, - u32 proc_obj, - bool *already_attached); - -/* - * ======== dev_remove_proc_object ======== - * Purpose: - * Search for and remove a Proc object from the given list maintained - * by the DEV - * Parameters: - * p_proc_object: Ptr to ProcObject to insert. - * dev_obj: Ptr to Dev Object where the list is. - * already_attached: Ptr to return the bool - * Returns: - * 0: If successful. - * -EPERM Failure to Remove the PROC Object from the list - * Requires: - * DevObject is Valid - * proc_obj != 0 - * dev_obj->proc_list != NULL - * !LST_IS_EMPTY(dev_obj->proc_list) - * already_attached !=NULL - * Ensures: - * Details: - * List will be deleted when the DEV is destroyed. - * - */ -extern int dev_remove_proc_object(struct dev_object - *hdev_obj, u32 proc_obj); - -/* - * ======== dev_notify_clients ======== - * Purpose: - * Notify all clients of this device of a change in device status. - * Clients may include multiple users of BRD, as well as CHNL. - * This function is asychronous, and may be called by a timer event - * set up by a watchdog timer. - * Parameters: - * hdev_obj: Handle to device object created with dev_create_device(). - * ret: A status word, most likely a BRD_STATUS. - * Returns: - * 0: All registered clients were asynchronously notified. - * -EINVAL: Invalid hdev_obj. - * Requires: - * DEV Initialized. - * Ensures: - * 0: Notifications are queued by the operating system to be - * delivered to clients. This function does not ensure that - * the notifications will ever be delivered. - */ -extern int dev_notify_clients(struct dev_object *hdev_obj, u32 ret); - -/* - * ======== dev_remove_device ======== - * Purpose: - * Destroys the Device Object created by dev_start_device. - * Parameters: - * dev_node_obj: Device node as it is know to OS. - * Returns: - * 0: If success; - * <error code> Otherwise. - * Requires: - * Ensures: - */ -extern int dev_remove_device(struct cfg_devnode *dev_node_obj); - -/* - * ======== dev_set_chnl_mgr ======== - * Purpose: - * Set the channel manager for this device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * hmgr: Handle to a channel manager, or NULL. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * DEV Initialized. - * Ensures: - */ -extern int dev_set_chnl_mgr(struct dev_object *hdev_obj, - struct chnl_mgr *hmgr); - -/* - * ======== dev_set_msg_mgr ======== - * Purpose: - * Set the Message manager for this device. - * Parameters: - * hdev_obj: Handle to device object created with dev_create_device(). - * hmgr: Handle to a message manager, or NULL. - * Returns: - * Requires: - * DEV Initialized. - * Ensures: - */ -extern void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr); - -/* - * ======== dev_start_device ======== - * Purpose: - * Initializes the new device with bridge environment. This involves - * querying CM for allocated resources, querying the registry for - * necessary dsp resources (requested in the INF file), and using this - * information to create a bridge device object. - * Parameters: - * dev_node_obj: Device node as it is know to OS. - * Returns: - * 0: If success; - * <error code> Otherwise. - * Requires: - * DEV initialized. - * Ensures: - */ -extern int dev_start_device(struct cfg_devnode *dev_node_obj); - -#endif /* DEV_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/devdefs.h b/drivers/staging/tidspbridge/include/dspbridge/devdefs.h deleted file mode 100644 index a2f9241ff13..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/devdefs.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * devdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Definition of common include typedef between dspdefs.h and dev.h. Required - * to break circular dependency between Bridge driver and DEV include files. - * - * Copyright (C) 2008 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 DEVDEFS_ -#define DEVDEFS_ - -/* Bridge Device Object */ -struct dev_object; - -#endif /* DEVDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/disp.h b/drivers/staging/tidspbridge/include/dspbridge/disp.h deleted file mode 100644 index 39d3cea9ca8..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/disp.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * disp.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge Node Dispatcher. - * - * 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 DISP_ -#define DISP_ - -#include <dspbridge/dbdefs.h> -#include <dspbridge/nodedefs.h> -#include <dspbridge/nodepriv.h> - -struct disp_object; - -/* Node Dispatcher attributes */ -struct disp_attr { - u32 chnl_offset; /* Offset of channel ids reserved for RMS */ - /* Size of buffer for sending data to RMS */ - u32 chnl_buf_size; - int proc_family; /* eg, 5000 */ - int proc_type; /* eg, 5510 */ - void *reserved1; /* Reserved for future use. */ - u32 reserved2; /* Reserved for future use. */ -}; - - -/* - * ======== disp_create ======== - * Create a NODE Dispatcher object. This object handles the creation, - * deletion, and execution of nodes on the DSP target, through communication - * with the Resource Manager Server running on the target. Each NODE - * Manager object should have exactly one NODE Dispatcher. - * - * Parameters: - * dispatch_obj: Location to store node dispatcher object on output. - * hdev_obj: Device for this processor. - * disp_attrs: Node dispatcher attributes. - * Returns: - * 0: Success; - * -ENOMEM: Insufficient memory for requested resources. - * -EPERM: Unable to create dispatcher. - * Requires: - * disp_attrs != NULL. - * hdev_obj != NULL. - * dispatch_obj != NULL. - * Ensures: - * 0: IS_VALID(*dispatch_obj). - * error: *dispatch_obj == NULL. - */ -extern int disp_create(struct disp_object **dispatch_obj, - struct dev_object *hdev_obj, - const struct disp_attr *disp_attrs); - -/* - * ======== disp_delete ======== - * Delete the NODE Dispatcher. - * - * Parameters: - * disp_obj: Node Dispatcher object. - * Returns: - * Requires: - * Valid disp_obj. - * Ensures: - * disp_obj is invalid. - */ -extern void disp_delete(struct disp_object *disp_obj); - -/* - * ======== disp_node_change_priority ======== - * Change the priority of a node currently running on the target. - * - * Parameters: - * disp_obj: Node Dispatcher object. - * hnode: Node object representing a node currently - * allocated or running on the DSP. - * ulFxnAddress: Address of RMS function for changing priority. - * node_env: Address of node's environment structure. - * prio: New priority level to set node's priority to. - * Returns: - * 0: Success. - * -ETIME: A timeout occurred before the DSP responded. - * Requires: - * Valid disp_obj. - * hnode != NULL. - * Ensures: - */ -extern int disp_node_change_priority(struct disp_object - *disp_obj, - struct node_object *hnode, - u32 rms_fxn, - nodeenv node_env, s32 prio); - -/* - * ======== disp_node_create ======== - * Create a node on the DSP by remotely calling the node's create function. - * - * Parameters: - * disp_obj: Node Dispatcher object. - * hnode: Node handle obtained from node_allocate(). - * ul_fxn_addr: Address or RMS create node function. - * ul_create_fxn: Address of node's create function. - * pargs: Arguments to pass to RMS node create function. - * node_env: Location to store node environment pointer on - * output. - * Returns: - * 0: Success. - * -ETIME: A timeout occurred before the DSP responded. - * -EPERM: A failure occurred, unable to create node. - * Requires: - * Valid disp_obj. - * pargs != NULL. - * hnode != NULL. - * node_env != NULL. - * node_get_type(hnode) != NODE_DEVICE. - * Ensures: - */ -extern int disp_node_create(struct disp_object *disp_obj, - struct node_object *hnode, - u32 rms_fxn, - u32 ul_create_fxn, - const struct node_createargs - *pargs, nodeenv *node_env); - -/* - * ======== disp_node_delete ======== - * Delete a node on the DSP by remotely calling the node's delete function. - * - * Parameters: - * disp_obj: Node Dispatcher object. - * hnode: Node object representing a node currently - * loaded on the DSP. - * ul_fxn_addr: Address or RMS delete node function. - * ul_delete_fxn: Address of node's delete function. - * node_env: Address of node's environment structure. - * Returns: - * 0: Success. - * -ETIME: A timeout occurred before the DSP responded. - * Requires: - * Valid disp_obj. - * hnode != NULL. - * Ensures: - */ -extern int disp_node_delete(struct disp_object *disp_obj, - struct node_object *hnode, - u32 rms_fxn, - u32 ul_delete_fxn, nodeenv node_env); - -/* - * ======== disp_node_run ======== - * Start execution of a node's execute phase, or resume execution of a node - * that has been suspended (via DISP_NodePause()) on the DSP. - * - * Parameters: - * disp_obj: Node Dispatcher object. - * hnode: Node object representing a node to be executed - * on the DSP. - * ul_fxn_addr: Address or RMS node execute function. - * ul_execute_fxn: Address of node's execute function. - * node_env: Address of node's environment structure. - * Returns: - * 0: Success. - * -ETIME: A timeout occurred before the DSP responded. - * Requires: - * Valid disp_obj. - * hnode != NULL. - * Ensures: - */ -extern int disp_node_run(struct disp_object *disp_obj, - struct node_object *hnode, - u32 rms_fxn, - u32 ul_execute_fxn, nodeenv node_env); - -#endif /* DISP_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h deleted file mode 100644 index c3487be8fcf..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dmm.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * dmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory 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. - */ - -#ifndef DMM_ -#define DMM_ - -#include <dspbridge/dbdefs.h> - -struct dmm_object; - -/* DMM attributes used in dmm_create() */ -struct dmm_mgrattrs { - u32 reserved; -}; - -#define DMMPOOLSIZE 0x4000000 - -/* - * ======== dmm_get_handle ======== - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ - -extern int dmm_get_handle(void *hprocessor, - struct dmm_object **dmm_manager); - -extern int dmm_reserve_memory(struct dmm_object *dmm_mgr, - u32 size, u32 *prsv_addr); - -extern int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, - u32 rsv_addr); - -extern int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, - u32 size); - -extern int dmm_un_map_memory(struct dmm_object *dmm_mgr, - u32 addr, u32 *psize); - -extern int dmm_destroy(struct dmm_object *dmm_mgr); - -extern int dmm_delete_tables(struct dmm_object *dmm_mgr); - -extern int dmm_create(struct dmm_object **dmm_manager, - struct dev_object *hdev_obj, - const struct dmm_mgrattrs *mgr_attrts); - -extern int dmm_create_tables(struct dmm_object *dmm_mgr, - u32 addr, u32 size); - -#ifdef DSP_DMM_DEBUG -u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr); -#endif - -#endif /* DMM_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h deleted file mode 100644 index b0c7708321b..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ /dev/null @@ -1,468 +0,0 @@ -/* - * drv.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DRV Resource allocation module. Driver Object gets Created - * at the time of Loading. It holds the List of Device Objects - * in the system. - * - * 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 DRV_ -#define DRV_ - -#include <dspbridge/devdefs.h> - -#include <linux/idr.h> - -/* Bridge Driver Object */ -struct drv_object; - -/* Provide the DSP Internal memory windows that can be accessed from L3 address - * space */ - -#define OMAP_GEM_BASE 0x107F8000 -#define OMAP_DSP_SIZE 0x00720000 - -/* MEM1 is L2 RAM + L2 Cache space */ -#define OMAP_DSP_MEM1_BASE 0x5C7F8000 -#define OMAP_DSP_MEM1_SIZE 0x18000 - -/* MEM2 is L1P RAM/CACHE space */ -#define OMAP_DSP_MEM2_BASE 0x5CE00000 -#define OMAP_DSP_MEM2_SIZE 0x8000 - -/* MEM3 is L1D RAM/CACHE space */ -#define OMAP_DSP_MEM3_BASE 0x5CF04000 -#define OMAP_DSP_MEM3_SIZE 0x14000 - -#define OMAP_PER_CM_BASE 0x48005000 -#define OMAP_PER_CM_SIZE 0x1000 - -#define OMAP_PER_PRM_BASE 0x48307000 -#define OMAP_PER_PRM_SIZE 0x1000 - -#define OMAP_CORE_PRM_BASE 0x48306A00 -#define OMAP_CORE_PRM_SIZE 0x1000 - -#define OMAP_DMMU_BASE 0x5D000000 -#define OMAP_DMMU_SIZE 0x1000 - -/* GPP PROCESS CLEANUP Data structures */ - -/* New structure (member of process context) abstracts NODE resource info */ -struct node_res_object { - void *node; - s32 node_allocated; /* Node status */ - s32 heap_allocated; /* Heap status */ - s32 streams_allocated; /* Streams status */ - int id; -}; - -/* used to cache dma mapping information */ -struct bridge_dma_map_info { - /* direction of DMA in action, or DMA_NONE */ - enum dma_data_direction dir; - /* number of elements requested by us */ - int num_pages; - /* number of elements returned from dma_map_sg */ - int sg_num; - /* list of buffers used in this DMA action */ - struct scatterlist *sg; -}; - -/* Used for DMM mapped memory accounting */ -struct dmm_map_object { - struct list_head link; - u32 dsp_addr; - u32 mpu_addr; - u32 size; - u32 num_usr_pgs; - struct page **pages; - struct bridge_dma_map_info dma_info; -}; - -/* Used for DMM reserved memory accounting */ -struct dmm_rsv_object { - struct list_head link; - u32 dsp_reserved_addr; -}; - -/* New structure (member of process context) abstracts stream resource info */ -struct strm_res_object { - s32 stream_allocated; /* Stream status */ - void *stream; - u32 num_bufs; - u32 dir; - int id; -}; - -/* Overall Bridge process resource usage state */ -enum gpp_proc_res_state { - PROC_RES_ALLOCATED, - PROC_RES_FREED -}; - -/* Bridge Data */ -struct drv_data { - char *base_img; - s32 shm_size; - int tc_wordswapon; - void *drv_object; - void *dev_object; - void *mgr_object; -}; - -/* Process Context */ -struct process_context { - /* Process State */ - enum gpp_proc_res_state res_state; - - /* Handle to Processor */ - void *processor; - - /* DSP Node resources */ - struct idr *node_id; - - /* DMM mapped memory resources */ - struct list_head dmm_map_list; - spinlock_t dmm_map_lock; - - /* DMM reserved memory resources */ - struct list_head dmm_rsv_list; - spinlock_t dmm_rsv_lock; - - /* Stream resources */ - struct idr *stream_id; -}; - -/* - * ======== drv_create ======== - * Purpose: - * Creates the Driver Object. This is done during the driver loading. - * There is only one Driver Object in the DSP/BIOS Bridge. - * Parameters: - * drv_obj: Location to store created DRV Object handle. - * Returns: - * 0: Success - * -ENOMEM: Failed in Memory allocation - * -EPERM: General Failure - * Requires: - * DRV Initialized (refs > 0 ) - * drv_obj != NULL. - * Ensures: - * 0: - *drv_obj is a valid DRV interface to the device. - * - List of DevObject Created and Initialized. - * - List of dev_node String created and initialized. - * - Registry is updated with the DRV Object. - * !0: DRV Object not created - * Details: - * There is one Driver Object for the Driver representing - * the driver itself. It contains the list of device - * Objects and the list of Device Extensions in the system. - * Also it can hold other necessary - * information in its storage area. - */ -extern int drv_create(struct drv_object **drv_obj); - -/* - * ======== drv_destroy ======== - * Purpose: - * destroys the Dev Object list, DrvExt list - * and destroy the DRV object - * Called upon driver unLoading.or unsuccessful loading of the driver. - * Parameters: - * driver_obj: Handle to Driver object . - * Returns: - * 0: Success. - * -EPERM: Failed to destroy DRV Object - * Requires: - * DRV Initialized (cRegs > 0 ) - * hdrv_obj is not NULL and a valid DRV handle . - * List of DevObject is Empty. - * List of DrvExt is Empty - * Ensures: - * 0: - DRV Object destroyed and hdrv_obj is not a valid - * DRV handle. - * - Registry is updated with "0" as the DRV Object. - */ -extern int drv_destroy(struct drv_object *driver_obj); - -/* - * ======== drv_get_first_dev_object ======== - * Purpose: - * Returns the Ptr to the FirstDev Object in the List - * Parameters: - * Requires: - * DRV Initialized - * Returns: - * dw_dev_object: Ptr to the First Dev Object as a u32 - * 0 if it fails to retrieve the First Dev Object - * Ensures: - */ -extern u32 drv_get_first_dev_object(void); - -/* - * ======== drv_get_first_dev_extension ======== - * Purpose: - * Returns the Ptr to the First Device Extension in the List - * Parameters: - * Requires: - * DRV Initialized - * Returns: - * dw_dev_extension: Ptr to the First Device Extension as a u32 - * 0: Failed to Get the Device Extension - * Ensures: - */ -extern u32 drv_get_first_dev_extension(void); - -/* - * ======== drv_get_dev_object ======== - * Purpose: - * Given a index, returns a handle to DevObject from the list - * Parameters: - * hdrv_obj: Handle to the Manager - * device_obj: Location to store the Dev Handle - * Requires: - * DRV Initialized - * index >= 0 - * hdrv_obj is not NULL and Valid DRV Object - * device_obj is not NULL - * Device Object List not Empty - * Returns: - * 0: Success - * -EPERM: Failed to Get the Dev Object - * Ensures: - * 0: *device_obj != NULL - * -EPERM: *device_obj = NULL - */ -extern int drv_get_dev_object(u32 index, - struct drv_object *hdrv_obj, - struct dev_object **device_obj); - -/* - * ======== drv_get_next_dev_object ======== - * Purpose: - * Returns the Ptr to the Next Device Object from the the List - * Parameters: - * hdev_obj: Handle to the Device Object - * Requires: - * DRV Initialized - * hdev_obj != 0 - * Returns: - * dw_dev_object: Ptr to the Next Dev Object as a u32 - * 0: If it fail to get the next Dev Object. - * Ensures: - */ -extern u32 drv_get_next_dev_object(u32 hdev_obj); - -/* - * ======== drv_get_next_dev_extension ======== - * Purpose: - * Returns the Ptr to the Next Device Extension from the the List - * Parameters: - * dev_extension: Handle to the Device Extension - * Requires: - * DRV Initialized - * dev_extension != 0. - * Returns: - * dw_dev_extension: Ptr to the Next Dev Extension - * 0: If it fail to Get the next Dev Extension - * Ensures: - */ -extern u32 drv_get_next_dev_extension(u32 dev_extension); - -/* - * ======== drv_insert_dev_object ======== - * Purpose: - * Insert a DeviceObject into the list of Driver object. - * Parameters: - * driver_obj: Handle to DrvObject - * hdev_obj: Handle to DeviceObject to insert. - * Returns: - * 0: If successful. - * -EPERM: General Failure: - * Requires: - * hdrv_obj != NULL and Valid DRV Handle. - * hdev_obj != NULL. - * Ensures: - * 0: Device Object is inserted and the List is not empty. - */ -extern int drv_insert_dev_object(struct drv_object *driver_obj, - struct dev_object *hdev_obj); - -/* - * ======== drv_remove_dev_object ======== - * Purpose: - * Search for and remove a Device object from the given list of Device Obj - * objects. - * Parameters: - * driver_obj: Handle to DrvObject - * hdev_obj: Handle to DevObject to Remove - * Returns: - * 0: Success. - * -EPERM: Unable to find dev_obj. - * Requires: - * hdrv_obj != NULL and a Valid DRV Handle. - * hdev_obj != NULL. - * List exists and is not empty. - * Ensures: - * List either does not exist (NULL), or is not empty if it does exist. - */ -extern int drv_remove_dev_object(struct drv_object *driver_obj, - struct dev_object *hdev_obj); - -/* - * ======== drv_request_resources ======== - * Purpose: - * Assigns the Resources or Releases them. - * Parameters: - * dw_context: Path to the driver Registry Key. - * dev_node_strg: Ptr to dev_node String stored in the Device Ext. - * Returns: - * TRUE if success; FALSE otherwise. - * Requires: - * Ensures: - * The Resources are assigned based on Bus type. - * The hardware is initialized. Resource information is - * gathered from the Registry(ISA, PCMCIA)or scanned(PCI) - * Resource structure is stored in the registry which will be - * later used by the CFG module. - */ -extern int drv_request_resources(u32 dw_context, - u32 *dev_node_strg); - -/* - * ======== drv_release_resources ======== - * Purpose: - * Assigns the Resources or Releases them. - * Parameters: - * dw_context: Path to the driver Registry Key. - * hdrv_obj: Handle to the Driver Object. - * Returns: - * TRUE if success; FALSE otherwise. - * Requires: - * Ensures: - * The Resources are released based on Bus type. - * Resource structure is deleted from the registry - */ -extern int drv_release_resources(u32 dw_context, - struct drv_object *hdrv_obj); - -/** - * drv_request_bridge_res_dsp() - Reserves shared memory for bridge. - * @phost_resources: pointer to host resources. - */ -int drv_request_bridge_res_dsp(void **phost_resources); - -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY -void bridge_recover_schedule(void); -#endif - -/* - * ======== mem_ext_phys_pool_init ======== - * Purpose: - * Uses the physical memory chunk passed for internal consistent memory - * allocations. - * physical address based on the page frame address. - * Parameters: - * pool_phys_base starting address of the physical memory pool. - * pool_size size of the physical memory pool. - * Returns: - * none. - * Requires: - * - MEM initialized. - * - valid physical address for the base and size > 0 - */ -extern void mem_ext_phys_pool_init(u32 pool_phys_base, u32 pool_size); - -/* - * ======== mem_ext_phys_pool_release ======== - */ -extern void mem_ext_phys_pool_release(void); - -/* ======== mem_alloc_phys_mem ======== - * Purpose: - * Allocate physically contiguous, uncached memory - * Parameters: - * byte_size: Number of bytes to allocate. - * align_mask: Alignment Mask. - * physical_address: Physical address of allocated memory. - * Returns: - * Pointer to a block of memory; - * NULL if memory couldn't be allocated, or if byte_size == 0. - * Requires: - * MEM initialized. - * Ensures: - * The returned pointer, if not NULL, points to a valid memory block of - * the size requested. Returned physical address refers to physical - * location of memory. - */ -extern void *mem_alloc_phys_mem(u32 byte_size, - u32 align_mask, u32 *physical_address); - -/* - * ======== mem_free_phys_mem ======== - * Purpose: - * Free the given block of physically contiguous memory. - * Parameters: - * virtual_address: Pointer to virtual memory region allocated - * by mem_alloc_phys_mem(). - * physical_address: Pointer to physical memory region allocated - * by mem_alloc_phys_mem(). - * byte_size: Size of the memory region allocated by mem_alloc_phys_mem(). - * Returns: - * Requires: - * MEM initialized. - * virtual_address is a valid memory address returned by - * mem_alloc_phys_mem() - * Ensures: - * virtual_address is no longer a valid pointer to memory. - */ -extern void mem_free_phys_mem(void *virtual_address, - u32 physical_address, u32 byte_size); - -/* - * ======== MEM_LINEAR_ADDRESS ======== - * Purpose: - * Get the linear address corresponding to the given physical address. - * Parameters: - * phys_addr: Physical address to be mapped. - * byte_size: Number of bytes in physical range to map. - * Returns: - * The corresponding linear address, or NULL if unsuccessful. - * Requires: - * MEM initialized. - * Ensures: - * Notes: - * If valid linear address is returned, be sure to call - * MEM_UNMAP_LINEAR_ADDRESS(). - */ -#define MEM_LINEAR_ADDRESS(phy_addr, byte_size) phy_addr - -/* - * ======== MEM_UNMAP_LINEAR_ADDRESS ======== - * Purpose: - * Unmap the linear address mapped in MEM_LINEAR_ADDRESS. - * Parameters: - * base_addr: Ptr to mapped memory (as returned by MEM_LINEAR_ADDRESS()). - * Returns: - * Requires: - * - MEM initialized. - * - base_addr is a valid linear address mapped in MEM_LINEAR_ADDRESS. - * Ensures: - * - base_addr no longer points to a valid linear address. - */ -#define MEM_UNMAP_LINEAR_ADDRESS(base_addr) {} - -#endif /* DRV_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h deleted file mode 100644 index 6ff808297c1..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ /dev/null @@ -1,467 +0,0 @@ -/* - * dspapi-ioctl.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Contains structures and commands that are used for interaction - * between the DDSP API and Bridge driver. - * - * Copyright (C) 2008 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 DSPAPIIOCTL_ -#define DSPAPIIOCTL_ - -#include <dspbridge/cmm.h> -#include <dspbridge/strmdefs.h> -#include <dspbridge/dbdcd.h> - -union trapped_args { - - /* MGR Module */ - struct { - u32 node_id; - struct dsp_ndbprops __user *ndb_props; - u32 ndb_props_size; - u32 __user *num_nodes; - } args_mgr_enumnode_info; - - struct { - u32 processor_id; - struct dsp_processorinfo __user *processor_info; - u32 processor_info_size; - u32 __user *num_procs; - } args_mgr_enumproc_info; - - struct { - struct dsp_uuid *uuid_obj; - enum dsp_dcdobjtype obj_type; - char *sz_path_name; - } args_mgr_registerobject; - - struct { - struct dsp_uuid *uuid_obj; - enum dsp_dcdobjtype obj_type; - } args_mgr_unregisterobject; - - struct { - struct dsp_notification __user *__user *anotifications; - u32 count; - u32 __user *index; - u32 timeout; - } args_mgr_wait; - - /* PROC Module */ - struct { - u32 processor_id; - struct dsp_processorattrin __user *attr_in; - void *__user *ph_processor; - } args_proc_attach; - - struct { - void *processor; - u32 cmd; - struct dsp_cbdata __user *args; - } args_proc_ctrl; - - struct { - void *processor; - } args_proc_detach; - - struct { - void *processor; - void *__user *node_tab; - u32 node_tab_size; - u32 __user *num_nodes; - u32 __user *allocated; - } args_proc_enumnode_info; - - struct { - void *processor; - u32 resource_type; - struct dsp_resourceinfo *resource_info; - u32 resource_info_size; - } args_proc_enumresources; - - struct { - void *processor; - struct dsp_processorstate __user *proc_state_obj; - u32 state_info_size; - } args_proc_getstate; - - struct { - void *processor; - u8 __user *buf; - u8 __user *size; - u32 max_size; - } args_proc_gettrace; - - struct { - void *processor; - s32 argc_index; - char __user *__user *user_args; - char *__user *user_envp; - } args_proc_load; - - struct { - void *processor; - u32 event_mask; - u32 notify_type; - struct dsp_notification __user *notification; - } args_proc_register_notify; - - struct { - void *processor; - u32 size; - void *__user *rsv_addr; - } args_proc_rsvmem; - - struct { - void *processor; - u32 size; - void *rsv_addr; - } args_proc_unrsvmem; - - struct { - void *processor; - void *mpu_addr; - u32 size; - void *req_addr; - void *__user *map_addr; - u32 map_attr; - } args_proc_mapmem; - - struct { - void *processor; - u32 size; - void *map_addr; - } args_proc_unmapmem; - - struct { - void *processor; - void *mpu_addr; - u32 size; - u32 dir; - } args_proc_dma; - - struct { - void *processor; - void *mpu_addr; - u32 size; - u32 flags; - } args_proc_flushmemory; - - struct { - void *processor; - void *mpu_addr; - u32 size; - } args_proc_invalidatememory; - - /* NODE Module */ - struct { - void *processor; - struct dsp_uuid __user *node_id_ptr; - struct dsp_cbdata __user *args; - struct dsp_nodeattrin __user *attr_in; - void *__user *node; - } args_node_allocate; - - struct { - void *node; - u32 size; - struct dsp_bufferattr __user *attr; - u8 *__user *buffer; - } args_node_allocmsgbuf; - - struct { - void *node; - s32 prio; - } args_node_changepriority; - - struct { - void *node; - u32 stream_id; - void *other_node; - u32 other_stream; - struct dsp_strmattr __user *attrs; - struct dsp_cbdata __user *conn_param; - } args_node_connect; - - struct { - void *node; - } args_node_create; - - struct { - void *node; - } args_node_delete; - - struct { - void *node; - struct dsp_bufferattr __user *attr; - u8 *buffer; - } args_node_freemsgbuf; - - struct { - void *node; - struct dsp_nodeattr __user *attr; - u32 attr_size; - } args_node_getattr; - - struct { - void *node; - struct dsp_msg __user *message; - u32 timeout; - } args_node_getmessage; - - struct { - void *node; - } args_node_pause; - - struct { - void *node; - struct dsp_msg __user *message; - u32 timeout; - } args_node_putmessage; - - struct { - void *node; - u32 event_mask; - u32 notify_type; - struct dsp_notification __user *notification; - } args_node_registernotify; - - struct { - void *node; - } args_node_run; - - struct { - void *node; - int __user *status; - } args_node_terminate; - - struct { - void *processor; - struct dsp_uuid __user *node_id_ptr; - struct dsp_ndbprops __user *node_props; - } args_node_getuuidprops; - - /* STRM module */ - - struct { - void *stream; - u32 size; - u8 *__user *ap_buffer; - u32 num_bufs; - } args_strm_allocatebuffer; - - struct { - void *stream; - } args_strm_close; - - struct { - void *stream; - u8 *__user *ap_buffer; - u32 num_bufs; - } args_strm_freebuffer; - - struct { - void *stream; - void **event; - } args_strm_geteventhandle; - - struct { - void *stream; - struct stream_info __user *stream_info; - u32 stream_info_size; - } args_strm_getinfo; - - struct { - void *stream; - bool flush_flag; - } args_strm_idle; - - struct { - void *stream; - u8 *buffer; - u32 bytes; - u32 buf_size; - u32 arg; - } args_strm_issue; - - struct { - void *node; - u32 direction; - u32 index; - struct strm_attr __user *attr_in; - void *__user *stream; - } args_strm_open; - - struct { - void *stream; - u8 *__user *buf_ptr; - u32 __user *bytes; - u32 __user *buf_size_ptr; - u32 __user *arg; - } args_strm_reclaim; - - struct { - void *stream; - u32 event_mask; - u32 notify_type; - struct dsp_notification __user *notification; - } args_strm_registernotify; - - struct { - void *__user *stream_tab; - u32 strm_num; - u32 __user *mask; - u32 timeout; - } args_strm_select; - - /* CMM Module */ - struct { - struct cmm_object *cmm_mgr; - u32 size; - struct cmm_attrs *attrs; - void **buf_va; - } args_cmm_allocbuf; - - struct { - struct cmm_object *cmm_mgr; - void *buf_pa; - u32 seg_id; - } args_cmm_freebuf; - - struct { - void *processor; - struct cmm_object *__user *cmm_mgr; - } args_cmm_gethandle; - - struct { - struct cmm_object *cmm_mgr; - struct cmm_info __user *cmm_info_obj; - } args_cmm_getinfo; - - /* UTIL module */ - struct { - s32 util_argc; - char **argv; - } args_util_testdll; -}; - -/* - * 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 - -/* Ioctl module masks */ -#define DB_MGR 0x0 -#define DB_PROC 0x20 -#define DB_NODE 0x40 -#define DB_STRM 0x60 -#define DB_CMM 0x80 - -#define DB_MODULE_SHIFT 5 - -/* Used to calculate the ioctl per dspbridge module */ -#define DB_IOC(module, num) \ - (((module) & DB_MODULE_MASK) | ((num) & DB_IOC_MASK)) -/* Used to get dspbridge ioctl module */ -#define DB_GET_MODULE(cmd) ((cmd) & DB_MODULE_MASK) -/* Used to get dspbridge ioctl number */ -#define DB_GET_IOC(cmd) ((cmd) & DB_IOC_MASK) - -/* TODO: Remove deprecated and not implemented */ - -/* MGR Module */ -#define MGR_ENUMNODE_INFO _IOWR(DB, DB_IOC(DB_MGR, 0), unsigned long) -#define MGR_ENUMPROC_INFO _IOWR(DB, DB_IOC(DB_MGR, 1), 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) -#define MGR_WAIT _IOWR(DB, DB_IOC(DB_MGR, 4), unsigned long) -/* MGR_GET_PROC_RES Deprecated */ -#define MGR_GET_PROC_RES _IOR(DB, DB_IOC(DB_MGR, 5), unsigned long) - -/* PROC Module */ -#define PROC_ATTACH _IOWR(DB, DB_IOC(DB_PROC, 0), unsigned long) -#define PROC_CTRL _IOR(DB, DB_IOC(DB_PROC, 1), unsigned long) -/* PROC_DETACH Deprecated */ -#define PROC_DETACH _IOR(DB, DB_IOC(DB_PROC, 2), unsigned long) -#define PROC_ENUMNODE _IOWR(DB, DB_IOC(DB_PROC, 3), unsigned long) -#define PROC_ENUMRESOURCES _IOWR(DB, DB_IOC(DB_PROC, 4), unsigned long) -#define PROC_GET_STATE _IOWR(DB, DB_IOC(DB_PROC, 5), unsigned long) -#define PROC_GET_TRACE _IOWR(DB, DB_IOC(DB_PROC, 6), unsigned long) -#define PROC_LOAD _IOW(DB, DB_IOC(DB_PROC, 7), unsigned long) -#define PROC_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_PROC, 8), unsigned long) -#define PROC_START _IOW(DB, DB_IOC(DB_PROC, 9), 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_STOP _IOWR(DB, DB_IOC(DB_PROC, 15), unsigned long) -#define PROC_INVALIDATEMEMORY _IOW(DB, DB_IOC(DB_PROC, 16), 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_ALLOCATE _IOWR(DB, DB_IOC(DB_NODE, 0), unsigned long) -#define NODE_ALLOCMSGBUF _IOWR(DB, DB_IOC(DB_NODE, 1), unsigned long) -#define NODE_CHANGEPRIORITY _IOW(DB, DB_IOC(DB_NODE, 2), unsigned long) -#define NODE_CONNECT _IOW(DB, DB_IOC(DB_NODE, 3), unsigned long) -#define NODE_CREATE _IOW(DB, DB_IOC(DB_NODE, 4), unsigned long) -#define NODE_DELETE _IOW(DB, DB_IOC(DB_NODE, 5), unsigned long) -#define NODE_FREEMSGBUF _IOW(DB, DB_IOC(DB_NODE, 6), unsigned long) -#define NODE_GETATTR _IOWR(DB, DB_IOC(DB_NODE, 7), unsigned long) -#define NODE_GETMESSAGE _IOWR(DB, DB_IOC(DB_NODE, 8), unsigned long) -#define NODE_PAUSE _IOW(DB, DB_IOC(DB_NODE, 9), unsigned long) -#define NODE_PUTMESSAGE _IOW(DB, DB_IOC(DB_NODE, 10), unsigned long) -#define NODE_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_NODE, 11), 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_GETUUIDPROPS _IOWR(DB, DB_IOC(DB_NODE, 14), unsigned long) - -/* STRM Module */ -#define STRM_ALLOCATEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 0), unsigned long) -#define STRM_CLOSE _IOW(DB, DB_IOC(DB_STRM, 1), unsigned long) -#define STRM_FREEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 2), unsigned long) -#define STRM_GETEVENTHANDLE _IO(DB, DB_IOC(DB_STRM, 3)) /* Not Impl'd */ -#define STRM_GETINFO _IOWR(DB, DB_IOC(DB_STRM, 4), unsigned long) -#define STRM_IDLE _IOW(DB, DB_IOC(DB_STRM, 5), unsigned long) -#define STRM_ISSUE _IOW(DB, DB_IOC(DB_STRM, 6), unsigned long) -#define STRM_OPEN _IOWR(DB, DB_IOC(DB_STRM, 7), unsigned long) -#define STRM_RECLAIM _IOWR(DB, DB_IOC(DB_STRM, 8), unsigned long) -#define STRM_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_STRM, 9), unsigned long) -#define STRM_SELECT _IOWR(DB, DB_IOC(DB_STRM, 10), unsigned long) - -/* CMM Module */ -#define CMM_ALLOCBUF _IO(DB, DB_IOC(DB_CMM, 0)) /* Not Impl'd */ -#define CMM_FREEBUF _IO(DB, DB_IOC(DB_CMM, 1)) /* Not Impl'd */ -#define CMM_GETHANDLE _IOR(DB, DB_IOC(DB_CMM, 2), unsigned long) -#define CMM_GETINFO _IOR(DB, DB_IOC(DB_CMM, 3), unsigned long) - -#endif /* DSPAPIIOCTL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi.h deleted file mode 100644 index c99c68738b0..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * dspapi.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Includes the wrapper functions called directly by the - * DeviceIOControl interface. - * - * Notes: - * Bridge services exported to Bridge driver are initialized by the DSPAPI on - * behalf of the Bridge driver. Bridge driver must not call module Init/Exit - * functions. - * - * To ensure Bridge driver binary compatibility across different platforms, - * for the same processor, a Bridge driver must restrict its usage of system - * services to those exported by the DSPAPI library. - * - * 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 DSPAPI_ -#define DSPAPI_ - -#include <dspbridge/dspapi-ioctl.h> - -/* This BRD API Library Version: */ -#define BRD_API_MAJOR_VERSION (u32)8 /* .8x - Alpha, .9x - Beta, 1.x FCS */ -#define BRD_API_MINOR_VERSION (u32)0 - -/* - * ======== api_call_dev_ioctl ======== - * Purpose: - * Call the (wrapper) function for the corresponding API IOCTL. - * Parameters: - * cmd: IOCTL id, base 0. - * args: Argument structure. - * result: - * Returns: - * 0 if command called; -EINVAL if command not in IOCTL - * table. - * Requires: - * Ensures: - */ -extern int api_call_dev_ioctl(unsigned int cmd, - union trapped_args *args, - u32 *result, void *pr_ctxt); - -/* - * ======== api_init ======== - * Purpose: - * Initialize modules used by Bridge API. - * This procedure is called when the driver is loaded. - * Parameters: - * Returns: - * TRUE if success; FALSE otherwise. - * Requires: - * Ensures: - */ -extern bool api_init(void); - -/* - * ======== api_init_complete2 ======== - * Purpose: - * Perform any required bridge initialization which cannot - * be performed in api_init() or dev_start_device() due - * to the fact that some services are not yet - * completely initialized. - * Parameters: - * Returns: - * 0: Allow this device to load - * -EPERM: Failure. - * Requires: - * Bridge API initialized. - * Ensures: - */ -extern int api_init_complete2(void); - -/* - * ======== api_exit ======== - * Purpose: - * Exit all modules initialized in api_init(void). - * This procedure is called when the driver is unloaded. - * Parameters: - * Returns: - * Requires: - * api_init(void) was previously called. - * Ensures: - * Resources acquired in api_init(void) are freed. - */ -extern void api_exit(void); - -/* MGR wrapper functions */ -extern u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt); -extern u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt); -extern u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt); -extern u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt); -extern u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, - void *pr_ctxt); - -extern u32 mgrwrap_get_process_resources_info(union trapped_args *args, - void *pr_ctxt); - -/* CPRC (Processor) wrapper Functions */ -extern u32 procwrap_attach(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_detach(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_load(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_start(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_map(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_stop(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt); -extern u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt); - -/* NODE wrapper functions */ -extern u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_create(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_run(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt); -extern u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt); - -/* STRM wrapper functions */ -extern u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_close(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_get_event_handle(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_open(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt); -extern u32 strmwrap_select(union trapped_args *args, void *pr_ctxt); - -extern u32 cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt); -extern u32 cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt); -extern u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt); -extern u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt); - -#endif /* DSPAPI_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h b/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h deleted file mode 100644 index 7146a5057e2..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * dspchnl.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Declares the upper edge channel class library functions required by - * all Bridge driver / DSP API driver interface tables. These functions are - * implemented by every class of Bridge channel library. - * - * Notes: - * The function comment headers reside in dspdefs.h. - * - * 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 DSPCHNL_ -#define DSPCHNL_ - -extern int bridge_chnl_create(struct chnl_mgr **channel_mgr, - struct dev_object *hdev_obj, - const struct chnl_mgrattrs - *mgr_attrts); - -extern int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr); - -extern int bridge_chnl_open(struct chnl_object **chnl, - struct chnl_mgr *hchnl_mgr, - s8 chnl_mode, - u32 ch_id, - const struct chnl_attr - *pattrs); - -extern int bridge_chnl_close(struct chnl_object *chnl_obj); - -extern int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, - void *host_buf, - u32 byte_size, u32 buf_size, - u32 dw_dsp_addr, u32 dw_arg); - -extern int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, - u32 timeout, struct chnl_ioc *chan_ioc); - -extern int bridge_chnl_cancel_io(struct chnl_object *chnl_obj); - -extern int bridge_chnl_flush_io(struct chnl_object *chnl_obj, - u32 timeout); - -extern int bridge_chnl_get_info(struct chnl_object *chnl_obj, - struct chnl_info *channel_info); - -extern int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr, - u32 ch_id, struct chnl_mgrinfo - *mgr_info); - -extern int bridge_chnl_idle(struct chnl_object *chnl_obj, - u32 timeout, bool flush_data); - -extern int bridge_chnl_register_notify(struct chnl_object *chnl_obj, - u32 event_mask, - u32 notify_type, - struct dsp_notification - *hnotification); - -#endif /* DSPCHNL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h deleted file mode 100644 index ed32bf38313..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ /dev/null @@ -1,1048 +0,0 @@ -/* - * dspdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Bridge driver entry point and interface function declarations. - * - * Notes: - * The DSP API obtains it's function interface to - * the Bridge driver via a call to bridge_drv_entry(). - * - * Bridge services exported to Bridge drivers are initialized by the - * DSP API on behalf of the Bridge driver. - * - * Bridge function DBC Requires and Ensures are also made by the DSP API on - * behalf of the Bridge driver, to simplify the Bridge driver code. - * - * 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 DSPDEFS_ -#define DSPDEFS_ - -#include <dspbridge/brddefs.h> -#include <dspbridge/cfgdefs.h> -#include <dspbridge/chnlpriv.h> -#include <dspbridge/dspdeh.h> -#include <dspbridge/devdefs.h> -#include <dspbridge/io.h> -#include <dspbridge/msgdefs.h> - -/* Handle to Bridge driver's private device context. */ -struct bridge_dev_context; - -/*--------------------------------------------------------------------------- */ -/* BRIDGE DRIVER FUNCTION TYPES */ -/*--------------------------------------------------------------------------- */ - -/* - * ======== bridge_brd_monitor ======== - * Purpose: - * Bring the board to the BRD_IDLE (monitor) state. - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device context. - * Returns: - * 0: Success. - * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL - * Ensures: - * 0: Board is in BRD_IDLE state; - * else: Board state is indeterminate. - */ -typedef int(*fxn_brd_monitor) (struct bridge_dev_context *dev_ctxt); - -/* - * ======== fxn_brd_setstate ======== - * Purpose: - * Sets the Bridge driver state - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * brd_state: Board state - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * brd_state <= BRD_LASTSTATE. - * Ensures: - * brd_state <= BRD_LASTSTATE. - * Update the Board state to the specified state. - */ -typedef int(*fxn_brd_setstate) (struct bridge_dev_context - * dev_ctxt, u32 brd_state); - -/* - * ======== bridge_brd_start ======== - * Purpose: - * Bring board to the BRD_RUNNING (start) state. - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device context. - * dsp_addr: DSP address at which to start execution. - * Returns: - * 0: Success. - * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL - * Board is in monitor (BRD_IDLE) state. - * Ensures: - * 0: Board is in BRD_RUNNING state. - * Interrupts to the PC are enabled. - * else: Board state is indeterminate. - */ -typedef int(*fxn_brd_start) (struct bridge_dev_context - * dev_ctxt, u32 dsp_addr); - -/* - * ======== bridge_brd_mem_copy ======== - * Purpose: - * Copy memory from one DSP address to another - * Parameters: - * dev_context: Pointer to context handle - * dsp_dest_addr: DSP address to copy to - * dsp_src_addr: DSP address to copy from - * ul_num_bytes: Number of bytes to copy - * mem_type: What section of memory to copy to - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_context != NULL - * Ensures: - * 0: Board is in BRD_RUNNING state. - * Interrupts to the PC are enabled. - * else: Board state is indeterminate. - */ -typedef int(*fxn_brd_memcopy) (struct bridge_dev_context - * dev_ctxt, - u32 dsp_dest_addr, - u32 dsp_src_addr, - u32 ul_num_bytes, u32 mem_type); -/* - * ======== bridge_brd_mem_write ======== - * Purpose: - * Write a block of host memory into a DSP address, into a given memory - * space. Unlike bridge_brd_write, this API does reset the DSP - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * dsp_addr: Address on DSP board (Destination). - * host_buf: Pointer to host buffer (Source). - * ul_num_bytes: Number of bytes to transfer. - * mem_type: Memory space on DSP to which to transfer. - * Returns: - * 0: Success. - * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * host_buf != NULL. - * Ensures: - */ -typedef int(*fxn_brd_memwrite) (struct bridge_dev_context - * dev_ctxt, - u8 *host_buf, - u32 dsp_addr, u32 ul_num_bytes, - u32 mem_type); - -/* - * ======== bridge_brd_mem_map ======== - * Purpose: - * Map a MPU memory region to a DSP/IVA memory space - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * ul_mpu_addr: MPU memory region start address. - * virt_addr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to map. - * map_attrs: Mapping attributes (e.g. endianness). - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memmap) (struct bridge_dev_context - * dev_ctxt, u32 ul_mpu_addr, - u32 virt_addr, u32 ul_num_bytes, - u32 map_attr, - struct page **mapped_pages); - -/* - * ======== bridge_brd_mem_un_map ======== - * Purpose: - * UnMap an MPU memory region from DSP/IVA memory space - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * virt_addr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to unmap. - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memunmap) (struct bridge_dev_context - * dev_ctxt, - u32 virt_addr, u32 ul_num_bytes); - -/* - * ======== bridge_brd_stop ======== - * Purpose: - * Bring board to the BRD_STOPPED state. - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device context. - * Returns: - * 0: Success. - * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL - * Ensures: - * 0: Board is in BRD_STOPPED (stop) state; - * Interrupts to the PC are disabled. - * else: Board state is indeterminate. - */ -typedef int(*fxn_brd_stop) (struct bridge_dev_context *dev_ctxt); - -/* - * ======== bridge_brd_status ======== - * Purpose: - * Report the current state of the board. - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device context. - * board_state: Ptr to BRD status variable. - * Returns: - * 0: - * Requires: - * board_state != NULL; - * dev_ctxt != NULL - * Ensures: - * *board_state is one of - * {BRD_STOPPED, BRD_IDLE, BRD_RUNNING, BRD_UNKNOWN}; - */ -typedef int(*fxn_brd_status) (struct bridge_dev_context *dev_ctxt, - int *board_state); - -/* - * ======== bridge_brd_read ======== - * Purpose: - * Read a block of DSP memory, from a given memory space, into a host - * buffer. - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * host_buf: Pointer to host buffer (Destination). - * dsp_addr: Address on DSP board (Source). - * ul_num_bytes: Number of bytes to transfer. - * mem_type: Memory space on DSP from which to transfer. - * Returns: - * 0: Success. - * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * host_buf != NULL. - * Ensures: - * Will not write more than ul_num_bytes bytes into host_buf. - */ -typedef int(*fxn_brd_read) (struct bridge_dev_context *dev_ctxt, - u8 *host_buf, - u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type); - -/* - * ======== bridge_brd_write ======== - * Purpose: - * Write a block of host memory into a DSP address, into a given memory - * space. - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * dsp_addr: Address on DSP board (Destination). - * host_buf: Pointer to host buffer (Source). - * ul_num_bytes: Number of bytes to transfer. - * mem_type: Memory space on DSP to which to transfer. - * Returns: - * 0: Success. - * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * host_buf != NULL. - * Ensures: - */ -typedef int(*fxn_brd_write) (struct bridge_dev_context *dev_ctxt, - u8 *host_buf, - u32 dsp_addr, - u32 ul_num_bytes, u32 mem_type); - -/* - * ======== bridge_chnl_create ======== - * Purpose: - * Create a channel manager object, responsible for opening new channels - * and closing old ones for a given 'Bridge board. - * Parameters: - * channel_mgr: Location to store a channel manager object on output. - * hdev_obj: Handle to a device object. - * mgr_attrts: Channel manager attributes. - * mgr_attrts->max_channels: Max channels - * mgr_attrts->birq: Channel's I/O IRQ number. - * mgr_attrts->irq_shared: TRUE if the IRQ is shareable. - * mgr_attrts->word_size: DSP Word size in equivalent PC bytes.. - * mgr_attrts->shm_base: Base physical address of shared memory, if any. - * mgr_attrts->sm_length: Bytes of shared memory block. - * Returns: - * 0: Success; - * -ENOMEM: Insufficient memory for requested resources. - * -EIO: Unable to plug ISR for given IRQ. - * -EFAULT: Couldn't map physical address to a virtual one. - * Requires: - * channel_mgr != NULL. - * mgr_attrts != NULL - * mgr_attrts field are all valid: - * 0 < max_channels <= CHNL_MAXCHANNELS. - * birq <= 15. - * word_size > 0. - * hdev_obj != NULL - * No channel manager exists for this board. - * Ensures: - */ -typedef int(*fxn_chnl_create) (struct chnl_mgr - **channel_mgr, - struct dev_object - * hdev_obj, - const struct - chnl_mgrattrs * mgr_attrts); - -/* - * ======== bridge_chnl_destroy ======== - * Purpose: - * Close all open channels, and destroy the channel manager. - * Parameters: - * hchnl_mgr: Channel manager object. - * Returns: - * 0: Success. - * -EFAULT: hchnl_mgr was invalid. - * Requires: - * Ensures: - * 0: Cancels I/O on each open channel. Closes each open channel. - * chnl_create may subsequently be called for the same device. - */ -typedef int(*fxn_chnl_destroy) (struct chnl_mgr *hchnl_mgr); -/* - * ======== bridge_deh_notify ======== - * Purpose: - * When notified of DSP error, take appropriate action. - * Parameters: - * hdeh_mgr: Handle to DEH manager object. - * evnt_mask: Indicate the type of exception - * error_info: Error information - * Returns: - * - * Requires: - * hdeh_mgr != NULL; - * evnt_mask with a valid exception - * Ensures: - */ -typedef void (*fxn_deh_notify) (struct deh_mgr *hdeh_mgr, - u32 evnt_mask, u32 error_info); - -/* - * ======== bridge_chnl_open ======== - * Purpose: - * Open a new half-duplex channel to the DSP board. - * Parameters: - * chnl: Location to store a channel object handle. - * hchnl_mgr: Handle to channel manager, as returned by - * CHNL_GetMgr(). - * chnl_mode: One of {CHNL_MODETODSP, CHNL_MODEFROMDSP} specifies - * direction of data transfer. - * ch_id: If CHNL_PICKFREE is specified, the channel manager will - * select a free channel id (default); - * otherwise this field specifies the id of the channel. - * pattrs: Channel attributes. Attribute fields are as follows: - * pattrs->uio_reqs: Specifies the maximum number of I/O requests which can - * be pending at any given time. All request packets are - * preallocated when the channel is opened. - * pattrs->event_obj: This field allows the user to supply an auto reset - * event object for channel I/O completion notifications. - * It is the responsibility of the user to destroy this - * object AFTER closing the channel. - * This channel event object can be retrieved using - * CHNL_GetEventHandle(). - * pattrs->hReserved: The kernel mode handle of this event object. - * - * Returns: - * 0: Success. - * -EFAULT: hchnl_mgr is invalid. - * -ENOMEM: Insufficient memory for requested resources. - * -EINVAL: Invalid number of IOReqs. - * -ENOSR: No free channels available. - * -ECHRNG: Channel ID is out of range. - * -EALREADY: Channel is in use. - * -EIO: No free IO request packets available for - * queuing. - * Requires: - * chnl != NULL. - * pattrs != NULL. - * pattrs->event_obj is a valid event handle. - * pattrs->hReserved is the kernel mode handle for pattrs->event_obj. - * Ensures: - * 0: *chnl is a valid channel. - * else: *chnl is set to NULL if (chnl != NULL); - */ -typedef int(*fxn_chnl_open) (struct chnl_object - **chnl, - struct chnl_mgr *hchnl_mgr, - s8 chnl_mode, - u32 ch_id, - const struct - chnl_attr * pattrs); - -/* - * ======== bridge_chnl_close ======== - * Purpose: - * Ensures all pending I/O on this channel is cancelled, discards all - * queued I/O completion notifications, then frees the resources allocated - * for this channel, and makes the corresponding logical channel id - * available for subsequent use. - * Parameters: - * chnl_obj: Handle to a channel object. - * Returns: - * 0: Success; - * -EFAULT: Invalid chnl_obj. - * Requires: - * No thread must be blocked on this channel's I/O completion event. - * Ensures: - * 0: chnl_obj is no longer valid. - */ -typedef int(*fxn_chnl_close) (struct chnl_object *chnl_obj); - -/* - * ======== bridge_chnl_add_io_req ======== - * Purpose: - * Enqueue an I/O request for data transfer on a channel to the DSP. - * The direction (mode) is specified in the channel object. Note the DSP - * address is specified for channels opened in direct I/O mode. - * Parameters: - * chnl_obj: Channel object handle. - * host_buf: Host buffer address source. - * byte_size: Number of PC bytes to transfer. A zero value indicates - * that this buffer is the last in the output channel. - * A zero value is invalid for an input channel. - *! buf_size: Actual buffer size in host bytes. - * dw_dsp_addr: DSP address for transfer. (Currently ignored). - * dw_arg: A user argument that travels with the buffer. - * Returns: - * 0: Success; - * -EFAULT: Invalid chnl_obj or host_buf. - * -EPERM: User cannot mark EOS on an input channel. - * -ECANCELED: I/O has been cancelled on this channel. No further - * I/O is allowed. - * -EPIPE: End of stream was already marked on a previous - * IORequest on this channel. No further I/O is expected. - * -EINVAL: Buffer submitted to this output channel is larger than - * the size of the physical shared memory output window. - * Requires: - * Ensures: - * 0: The buffer will be transferred if the channel is ready; - * otherwise, will be queued for transfer when the channel becomes - * ready. In any case, notifications of I/O completion are - * asynchronous. - * If byte_size is 0 for an output channel, subsequent CHNL_AddIOReq's - * on this channel will fail with error code -EPIPE. The - * corresponding IOC for this I/O request will have its status flag - * set to CHNL_IOCSTATEOS. - */ -typedef int(*fxn_chnl_addioreq) (struct chnl_object - * chnl_obj, - void *host_buf, - u32 byte_size, - u32 buf_size, - u32 dw_dsp_addr, u32 dw_arg); - -/* - * ======== bridge_chnl_get_ioc ======== - * Purpose: - * Dequeue an I/O completion record, which contains information about the - * completed I/O request. - * Parameters: - * chnl_obj: Channel object handle. - * timeout: A value of CHNL_IOCNOWAIT will simply dequeue the - * first available IOC. - * chan_ioc: On output, contains host buffer address, bytes - * transferred, and status of I/O completion. - * chan_ioc->status: See chnldefs.h. - * Returns: - * 0: Success. - * -EFAULT: Invalid chnl_obj or chan_ioc. - * -EREMOTEIO: CHNL_IOCNOWAIT was specified as the timeout parameter - * yet no I/O completions were queued. - * Requires: - * timeout == CHNL_IOCNOWAIT. - * Ensures: - * 0: if there are any remaining IOC's queued before this call - * returns, the channel event object will be left in a signalled - * state. - */ -typedef int(*fxn_chnl_getioc) (struct chnl_object *chnl_obj, - u32 timeout, - struct chnl_ioc *chan_ioc); - -/* - * ======== bridge_chnl_cancel_io ======== - * Purpose: - * Return all I/O requests to the client which have not yet been - * transferred. The channel's I/O completion object is - * signalled, and all the I/O requests are queued as IOC's, with the - * status field set to CHNL_IOCSTATCANCEL. - * This call is typically used in abort situations, and is a prelude to - * chnl_close(); - * Parameters: - * chnl_obj: Channel object handle. - * Returns: - * 0: Success; - * -EFAULT: Invalid chnl_obj. - * Requires: - * Ensures: - * Subsequent I/O requests to this channel will not be accepted. - */ -typedef int(*fxn_chnl_cancelio) (struct chnl_object *chnl_obj); - -/* - * ======== bridge_chnl_flush_io ======== - * Purpose: - * For an output stream (to the DSP), indicates if any IO requests are in - * the output request queue. For input streams (from the DSP), will - * cancel all pending IO requests. - * Parameters: - * chnl_obj: Channel object handle. - * timeout: Timeout value for flush operation. - * Returns: - * 0: Success; - * S_CHNLIOREQUEST: Returned if any IORequests are in the output queue. - * -EFAULT: Invalid chnl_obj. - * Requires: - * Ensures: - * 0: No I/O requests will be pending on this channel. - */ -typedef int(*fxn_chnl_flushio) (struct chnl_object *chnl_obj, - u32 timeout); - -/* - * ======== bridge_chnl_get_info ======== - * Purpose: - * Retrieve information related to a channel. - * Parameters: - * chnl_obj: Handle to a valid channel object, or NULL. - * channel_info: Location to store channel info. - * Returns: - * 0: Success; - * -EFAULT: Invalid chnl_obj or channel_info. - * Requires: - * Ensures: - * 0: channel_info points to a filled in chnl_info struct, - * if (channel_info != NULL). - */ -typedef int(*fxn_chnl_getinfo) (struct chnl_object *chnl_obj, - struct chnl_info *channel_info); - -/* - * ======== bridge_chnl_get_mgr_info ======== - * Purpose: - * Retrieve information related to the channel manager. - * Parameters: - * hchnl_mgr: Handle to a valid channel manager, or NULL. - * ch_id: Channel ID. - * mgr_info: Location to store channel manager info. - * Returns: - * 0: Success; - * -EFAULT: Invalid hchnl_mgr or mgr_info. - * -ECHRNG: Invalid channel ID. - * Requires: - * Ensures: - * 0: mgr_info points to a filled in chnl_mgrinfo - * struct, if (mgr_info != NULL). - */ -typedef int(*fxn_chnl_getmgrinfo) (struct chnl_mgr - * hchnl_mgr, - u32 ch_id, - struct chnl_mgrinfo *mgr_info); - -/* - * ======== bridge_chnl_idle ======== - * Purpose: - * Idle a channel. If this is an input channel, or if this is an output - * channel and flush_data is TRUE, all currently enqueued buffers will be - * dequeued (data discarded for output channel). - * If this is an output channel and flush_data is FALSE, this function - * will block until all currently buffered data is output, or the timeout - * specified has been reached. - * - * Parameters: - * chnl_obj: Channel object handle. - * timeout: If output channel and flush_data is FALSE, timeout value - * to wait for buffers to be output. (Not used for - * input channel). - * flush_data: If output channel and flush_data is TRUE, discard any - * currently buffered data. If FALSE, wait for currently - * buffered data to be output, or timeout, whichever - * occurs first. flush_data is ignored for input channel. - * Returns: - * 0: Success; - * -EFAULT: Invalid chnl_obj. - * -ETIMEDOUT: Timeout occurred before channel could be idled. - * Requires: - * Ensures: - */ -typedef int(*fxn_chnl_idle) (struct chnl_object *chnl_obj, - u32 timeout, bool flush_data); - -/* - * ======== bridge_chnl_register_notify ======== - * Purpose: - * Register for notification of events on a channel. - * Parameters: - * chnl_obj: Channel object handle. - * event_mask: Type of events to be notified about: IO completion - * (DSP_STREAMIOCOMPLETION) or end of stream - * (DSP_STREAMDONE). - * notify_type: DSP_SIGNALEVENT. - * hnotification: Handle of a dsp_notification object. - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory. - * -EINVAL: event_mask is 0 and hnotification was not - * previously registered. - * -EFAULT: NULL hnotification, hnotification event name - * too long, or hnotification event name NULL. - * Requires: - * Valid chnl_obj. - * hnotification != NULL. - * (event_mask & ~(DSP_STREAMIOCOMPLETION | DSP_STREAMDONE)) == 0. - * notify_type == DSP_SIGNALEVENT. - * Ensures: - */ -typedef int(*fxn_chnl_registernotify) - (struct chnl_object *chnl_obj, - u32 event_mask, u32 notify_type, struct dsp_notification *hnotification); - -/* - * ======== bridge_dev_create ======== - * Purpose: - * Complete creation of the device object for this board. - * Parameters: - * device_ctx: Ptr to location to store a Bridge device context. - * hdev_obj: Handle to a Device Object, created and managed by DSP API. - * config_param: Ptr to configuration parameters provided by the - * Configuration Manager during device loading. - * pDspConfig: DSP resources, as specified in the registry key for this - * device. - * Returns: - * 0: Success. - * -ENOMEM: Unable to allocate memory for device context. - * Requires: - * device_ctx != NULL; - * hdev_obj != NULL; - * config_param != NULL; - * pDspConfig != NULL; - * Fields in config_param and pDspConfig contain valid values. - * Ensures: - * 0: All Bridge driver specific DSP resource and other - * board context has been allocated. - * -ENOMEM: Bridge failed to allocate resources. - * Any acquired resources have been freed. The DSP API - * will not call bridge_dev_destroy() if - * bridge_dev_create() fails. - * Details: - * Called during the CONFIGMG's Device_Init phase. Based on host and - * DSP configuration information, create a board context, a handle to - * which is passed into other Bridge BRD and CHNL functions. The - * board context contains state information for the device. Since the - * addresses of all pointer parameters may be invalid when this - * function returns, they must not be stored into the device context - * structure. - */ -typedef int(*fxn_dev_create) (struct bridge_dev_context - **device_ctx, - struct dev_object - * hdev_obj, - struct cfg_hostres - * config_param); - -/* - * ======== bridge_dev_ctrl ======== - * Purpose: - * Bridge driver specific interface. - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * dw_cmd: Bridge driver defined command code. - * pargs: Pointer to an arbitrary argument structure. - * Returns: - * 0 or -EPERM. Actual command error codes should be passed back in - * the pargs structure, and are defined by the Bridge driver implementor. - * Requires: - * All calls are currently assumed to be synchronous. There are no - * IOCTL completion routines provided. - * Ensures: - */ -typedef int(*fxn_dev_ctrl) (struct bridge_dev_context *dev_ctxt, - u32 dw_cmd, void *pargs); - -/* - * ======== bridge_dev_destroy ======== - * Purpose: - * Deallocate Bridge device extension structures and all other resources - * acquired by the Bridge driver. - * No calls to other Bridge driver functions may subsequently - * occur, except for bridge_dev_create(). - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device information. - * Returns: - * 0: Success. - * -EPERM: Failed to release a resource previously acquired. - * Requires: - * dev_ctxt != NULL; - * Ensures: - * 0: Device context is freed. - */ -typedef int(*fxn_dev_destroy) (struct bridge_dev_context *dev_ctxt); - -/* - * ======== bridge_io_create ======== - * Purpose: - * Create an object that manages I/O between CHNL and msg_ctrl. - * Parameters: - * io_man: Location to store IO manager on output. - * hchnl_mgr: Handle to channel manager. - * hmsg_mgr: Handle to message manager. - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation failure. - * -EPERM: Creation failed. - * Requires: - * hdev_obj != NULL; - * Channel manager already created; - * Message manager already created; - * mgr_attrts != NULL; - * io_man != NULL; - * Ensures: - */ -typedef int(*fxn_io_create) (struct io_mgr **io_man, - struct dev_object *hdev_obj, - const struct io_attrs *mgr_attrts); - -/* - * ======== bridge_io_destroy ======== - * Purpose: - * Destroy object created in bridge_io_create. - * Parameters: - * hio_mgr: IO Manager. - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation failure. - * -EPERM: Creation failed. - * Requires: - * Valid hio_mgr; - * Ensures: - */ -typedef int(*fxn_io_destroy) (struct io_mgr *hio_mgr); - -/* - * ======== bridge_io_on_loaded ======== - * Purpose: - * Called whenever a program is loaded to update internal data. For - * example, if shared memory is used, this function would update the - * shared memory location and address. - * Parameters: - * hio_mgr: IO Manager. - * Returns: - * 0: Success. - * -EPERM: Internal failure occurred. - * Requires: - * Valid hio_mgr; - * Ensures: - */ -typedef int(*fxn_io_onloaded) (struct io_mgr *hio_mgr); - -/* - * ======== fxn_io_getprocload ======== - * Purpose: - * Called to get the Processor's current and predicted load - * Parameters: - * hio_mgr: IO Manager. - * proc_load_stat Processor Load statistics - * Returns: - * 0: Success. - * -EPERM: Internal failure occurred. - * Requires: - * Valid hio_mgr; - * Ensures: - */ -typedef int(*fxn_io_getprocload) (struct io_mgr *hio_mgr, - struct dsp_procloadstat * - proc_load_stat); - -/* - * ======== bridge_msg_create ======== - * Purpose: - * Create an object to manage message queues. Only one of these objects - * can exist per device object. - * Parameters: - * msg_man: Location to store msg_ctrl manager on output. - * hdev_obj: Handle to a device object. - * msg_callback: Called whenever an RMS_EXIT message is received. - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory. - * Requires: - * msg_man != NULL. - * msg_callback != NULL. - * hdev_obj != NULL. - * Ensures: - */ -typedef int(*fxn_msg_create) - (struct msg_mgr **msg_man, - struct dev_object *hdev_obj, msg_onexit msg_callback); - -/* - * ======== bridge_msg_create_queue ======== - * Purpose: - * Create a msg_ctrl queue for sending or receiving messages from a Message - * node on the DSP. - * Parameters: - * hmsg_mgr: msg_ctrl queue manager handle returned from - * bridge_msg_create. - * msgq: Location to store msg_ctrl queue on output. - * msgq_id: Identifier for messages (node environment pointer). - * max_msgs: Max number of simultaneous messages for the node. - * h: Handle passed to hmsg_mgr->msg_callback(). - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory. - * Requires: - * msgq != NULL. - * h != NULL. - * max_msgs > 0. - * Ensures: - * msgq !=NULL <==> 0. - */ -typedef int(*fxn_msg_createqueue) - (struct msg_mgr *hmsg_mgr, - struct msg_queue **msgq, u32 msgq_id, u32 max_msgs, void *h); - -/* - * ======== bridge_msg_delete ======== - * Purpose: - * Delete a msg_ctrl manager allocated in bridge_msg_create(). - * Parameters: - * hmsg_mgr: Handle returned from bridge_msg_create(). - * Returns: - * Requires: - * Valid hmsg_mgr. - * Ensures: - */ -typedef void (*fxn_msg_delete) (struct msg_mgr *hmsg_mgr); - -/* - * ======== bridge_msg_delete_queue ======== - * Purpose: - * Delete a msg_ctrl queue allocated in bridge_msg_create_queue. - * Parameters: - * msg_queue_obj: Handle to msg_ctrl queue returned from - * bridge_msg_create_queue. - * Returns: - * Requires: - * Valid msg_queue_obj. - * Ensures: - */ -typedef void (*fxn_msg_deletequeue) (struct msg_queue *msg_queue_obj); - -/* - * ======== bridge_msg_get ======== - * Purpose: - * Get a message from a msg_ctrl queue. - * Parameters: - * msg_queue_obj: Handle to msg_ctrl queue returned from - * bridge_msg_create_queue. - * pmsg: Location to copy message into. - * utimeout: Timeout to wait for a message. - * Returns: - * 0: Success. - * -ETIME: Timeout occurred. - * -EPERM: No frames available for message (max_msgs too - * small). - * Requires: - * Valid msg_queue_obj. - * pmsg != NULL. - * Ensures: - */ -typedef int(*fxn_msg_get) (struct msg_queue *msg_queue_obj, - struct dsp_msg *pmsg, u32 utimeout); - -/* - * ======== bridge_msg_put ======== - * Purpose: - * Put a message onto a msg_ctrl queue. - * Parameters: - * msg_queue_obj: Handle to msg_ctrl queue returned from - * bridge_msg_create_queue. - * pmsg: Pointer to message. - * utimeout: Timeout to wait for a message. - * Returns: - * 0: Success. - * -ETIME: Timeout occurred. - * -EPERM: No frames available for message (max_msgs too - * small). - * Requires: - * Valid msg_queue_obj. - * pmsg != NULL. - * Ensures: - */ -typedef int(*fxn_msg_put) (struct msg_queue *msg_queue_obj, - const struct dsp_msg *pmsg, u32 utimeout); - -/* - * ======== bridge_msg_register_notify ======== - * Purpose: - * Register notification for when a message is ready. - * Parameters: - * msg_queue_obj: Handle to msg_ctrl queue returned from - * bridge_msg_create_queue. - * event_mask: Type of events to be notified about: Must be - * DSP_NODEMESSAGEREADY, or 0 to unregister. - * notify_type: DSP_SIGNALEVENT. - * hnotification: Handle of notification object. - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory. - * Requires: - * Valid msg_queue_obj. - * hnotification != NULL. - * notify_type == DSP_SIGNALEVENT. - * event_mask == DSP_NODEMESSAGEREADY || event_mask == 0. - * Ensures: - */ -typedef int(*fxn_msg_registernotify) - (struct msg_queue *msg_queue_obj, - u32 event_mask, u32 notify_type, struct dsp_notification *hnotification); - -/* - * ======== bridge_msg_set_queue_id ======== - * Purpose: - * Set message queue id to node environment. Allows bridge_msg_create_queue - * to be called in node_allocate, before the node environment is known. - * Parameters: - * msg_queue_obj: Handle to msg_ctrl queue returned from - * bridge_msg_create_queue. - * msgq_id: Node environment pointer. - * Returns: - * Requires: - * Valid msg_queue_obj. - * msgq_id != 0. - * Ensures: - */ -typedef void (*fxn_msg_setqueueid) (struct msg_queue *msg_queue_obj, - u32 msgq_id); - -/* - * Bridge Driver interface function table. - * - * The information in this table is filled in by the specific Bridge driver, - * and copied into the DSP API's own space. If any interface - * function field is set to a value of NULL, then the DSP API will - * consider that function not implemented, and return the error code - * -ENOSYS when a Bridge driver client attempts to call that function. - * - * This function table contains DSP API version numbers, which are used by the - * Bridge driver loader to help ensure backwards compatility between older - * Bridge drivers and newer DSP API. These must be set to - * BRD_API_MAJOR_VERSION and BRD_API_MINOR_VERSION, respectively. - * - * A Bridge driver need not export a CHNL interface. In this case, *all* of - * the bridge_chnl_* entries must be set to NULL. - */ -struct bridge_drv_interface { - u32 brd_api_major_version; /* Set to BRD_API_MAJOR_VERSION. */ - u32 brd_api_minor_version; /* Set to BRD_API_MINOR_VERSION. */ - fxn_dev_create dev_create; /* Create device context */ - fxn_dev_destroy dev_destroy; /* Destroy device context */ - fxn_dev_ctrl dev_cntrl; /* Optional vendor interface */ - fxn_brd_monitor brd_monitor; /* Load and/or start monitor */ - fxn_brd_start brd_start; /* Start DSP program. */ - fxn_brd_stop brd_stop; /* Stop/reset board. */ - fxn_brd_status brd_status; /* Get current board status. */ - fxn_brd_read brd_read; /* Read board memory */ - fxn_brd_write brd_write; /* Write board memory. */ - fxn_brd_setstate brd_set_state; /* Sets the Board State */ - fxn_brd_memcopy brd_mem_copy; /* Copies DSP Memory */ - fxn_brd_memwrite brd_mem_write; /* Write DSP Memory w/o halt */ - fxn_brd_memmap brd_mem_map; /* Maps MPU mem to DSP mem */ - fxn_brd_memunmap brd_mem_un_map; /* Unmaps MPU mem to DSP mem */ - fxn_chnl_create chnl_create; /* Create channel manager. */ - fxn_chnl_destroy chnl_destroy; /* Destroy channel manager. */ - fxn_chnl_open chnl_open; /* Create a new channel. */ - fxn_chnl_close chnl_close; /* Close a channel. */ - fxn_chnl_addioreq chnl_add_io_req; /* Req I/O on a channel. */ - fxn_chnl_getioc chnl_get_ioc; /* Wait for I/O completion. */ - fxn_chnl_cancelio chnl_cancel_io; /* Cancl I/O on a channel. */ - fxn_chnl_flushio chnl_flush_io; /* Flush I/O. */ - fxn_chnl_getinfo chnl_get_info; /* Get channel specific info */ - /* Get channel manager info. */ - fxn_chnl_getmgrinfo chnl_get_mgr_info; - fxn_chnl_idle chnl_idle; /* Idle the channel */ - /* Register for notif. */ - fxn_chnl_registernotify chnl_register_notify; - fxn_io_create io_create; /* Create IO manager */ - fxn_io_destroy io_destroy; /* Destroy IO manager */ - fxn_io_onloaded io_on_loaded; /* Notify of program loaded */ - /* Get Processor's current and predicted load */ - fxn_io_getprocload io_get_proc_load; - fxn_msg_create msg_create; /* Create message manager */ - /* Create message queue */ - fxn_msg_createqueue msg_create_queue; - fxn_msg_delete msg_delete; /* Delete message manager */ - /* Delete message queue */ - fxn_msg_deletequeue msg_delete_queue; - fxn_msg_get msg_get; /* Get a message */ - fxn_msg_put msg_put; /* Send a message */ - /* Register for notif. */ - fxn_msg_registernotify msg_register_notify; - /* Set message queue id */ - fxn_msg_setqueueid msg_set_queue_id; -}; - -/* - * ======== bridge_drv_entry ======== - * Purpose: - * Registers Bridge driver functions with the DSP API. Called only once - * by the DSP API. The caller will first check DSP API version - * compatibility, and then copy the interface functions into its own - * memory space. - * Parameters: - * drv_intf Pointer to a location to receive a pointer to the - * Bridge driver interface. - * Returns: - * Requires: - * The code segment this function resides in must expect to be discarded - * after completion. - * Ensures: - * drv_intf pointer initialized to Bridge driver's function - * interface. No system resources are acquired by this function. - * Details: - * Called during the Device_Init phase. - */ -void bridge_drv_entry(struct bridge_drv_interface **drv_intf, - const char *driver_file_name); - -#endif /* DSPDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h b/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h deleted file mode 100644 index d258ab6a41d..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * dspdeh.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Defines upper edge DEH functions required by all Bridge driver/DSP API - * interface tables. - * - * Notes: - * Function comment headers reside with the function typedefs in dspdefs.h. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * Copyright (C) 2010 Felipe Contreras - * - * 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 DSPDEH_ -#define DSPDEH_ - -struct deh_mgr; -struct dev_object; -struct dsp_notification; - -int bridge_deh_create(struct deh_mgr **ret_deh, - struct dev_object *hdev_obj); - -int bridge_deh_destroy(struct deh_mgr *deh); - -int bridge_deh_register_notify(struct deh_mgr *deh, - u32 event_mask, - u32 notify_type, - struct dsp_notification *hnotification); - -void bridge_deh_notify(struct deh_mgr *deh, int event, int info); - -#endif /* DSPDEH_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h b/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h deleted file mode 100644 index 7adf1e70531..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * dspdrv.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This is the Stream Interface for the DSp API. - * All Device operations are performed via DeviceIOControl. - * - * 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. - */ - -#if !defined _DSPDRV_H_ -#define _DSPDRV_H_ - -/* - * ======== dsp_deinit ======== - * Purpose: - * This function is called by Device Manager to de-initialize a device. - * This function is not called by applications. - * Parameters: - * device_context:Handle to the device context. The XXX_Init function - * creates and returns this identifier. - * Returns: - * TRUE indicates the device successfully de-initialized. Otherwise it - * returns FALSE. - * Requires: - * device_context!= NULL. For a built in device this should never - * get called. - * Ensures: - */ -extern bool dsp_deinit(u32 device_context); - -/* - * ======== dsp_init ======== - * Purpose: - * This function is called by Device Manager to initialize a device. - * This function is not called by applications - * Parameters: - * dw_context: Specifies a pointer to a string containing the registry - * path to the active key for the stream interface driver. - * HKEY_LOCAL_MACHINE\Drivers\Active - * Returns: - * Returns a handle to the device context created. This is the our actual - * Device Object representing the DSP Device instance. - * Requires: - * Ensures: - * Succeeded: device context > 0 - * Failed: device Context = 0 - */ -extern u32 dsp_init(u32 *init_status); - -#endif diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspio.h b/drivers/staging/tidspbridge/include/dspbridge/dspio.h deleted file mode 100644 index 66b64fadf19..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspio.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * dspio.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Declares the upper edge IO functions required by all Bridge driver /DSP API - * interface tables. - * - * Notes: - * Function comment headers reside in dspdefs.h. - * - * 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 DSPIO_ -#define DSPIO_ - -#include <dspbridge/devdefs.h> -#include <dspbridge/io.h> - - -extern int bridge_io_create(struct io_mgr **io_man, - struct dev_object *hdev_obj, - const struct io_attrs *mgr_attrts); - -extern int bridge_io_destroy(struct io_mgr *hio_mgr); - -extern int bridge_io_on_loaded(struct io_mgr *hio_mgr); - -extern int bridge_io_get_proc_load(struct io_mgr *hio_mgr, - struct dsp_procloadstat *proc_lstat); - -#endif /* DSPIO_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h deleted file mode 100644 index 0fcda197892..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * dspioctl.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Bridge driver BRD_IOCtl reserved command definitions. - * - * 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 DSPIOCTL_ -#define DSPIOCTL_ - -/* ------------------------------------ Hardware Abstraction Layer */ -#include <hw_defs.h> -#include <hw_mmu.h> - -/* - * Any IOCTLS at or above this value are reserved for standard Bridge driver - * interfaces. - */ -#define BRDIOCTL_RESERVEDBASE 0x8000 - -#define BRDIOCTL_CHNLREAD (BRDIOCTL_RESERVEDBASE + 0x10) -#define BRDIOCTL_CHNLWRITE (BRDIOCTL_RESERVEDBASE + 0x20) -/* DMMU */ -#define BRDIOCTL_SETMMUCONFIG (BRDIOCTL_RESERVEDBASE + 0x60) -/* PWR */ -#define BRDIOCTL_PWRCONTROL (BRDIOCTL_RESERVEDBASE + 0x70) - -/* attention, modifiers: - * Some of these control enumerations are made visible to user for power - * control, so any changes to this list, should also be updated in the user - * header file 'dbdefs.h' ***/ -/* These ioctls are reserved for PWR power commands for the DSP */ -#define BRDIOCTL_DEEPSLEEP (BRDIOCTL_PWRCONTROL + 0x0) -#define BRDIOCTL_EMERGENCYSLEEP (BRDIOCTL_PWRCONTROL + 0x1) -#define BRDIOCTL_WAKEUP (BRDIOCTL_PWRCONTROL + 0x2) -#define BRDIOCTL_CLK_CTRL (BRDIOCTL_PWRCONTROL + 0x7) -/* DSP Initiated Hibernate */ -#define BRDIOCTL_PWR_HIBERNATE (BRDIOCTL_PWRCONTROL + 0x8) -#define BRDIOCTL_PRESCALE_NOTIFY (BRDIOCTL_PWRCONTROL + 0x9) -#define BRDIOCTL_POSTSCALE_NOTIFY (BRDIOCTL_PWRCONTROL + 0xA) -#define BRDIOCTL_CONSTRAINT_REQUEST (BRDIOCTL_PWRCONTROL + 0xB) - -/* Number of actual DSP-MMU TLB entries */ -#define BRDIOCTL_NUMOFMMUTLB 32 - -struct bridge_ioctl_extproc { - u32 dsp_va; /* DSP virtual address */ - u32 gpp_pa; /* GPP physical address */ - /* GPP virtual address. __va does not work for ioremapped addresses */ - u32 gpp_va; - u32 size; /* Size of the mapped memory in bytes */ - enum hw_endianism_t endianism; - enum hw_mmu_mixed_size_t mixed_mode; - enum hw_element_size_t elem_size; -}; - -#endif /* DSPIOCTL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h b/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h deleted file mode 100644 index d4bd458bc8b..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * dspmsg.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Declares the upper edge message class library functions required by - * all Bridge driver / DSP API interface tables. These functions are - * implemented by every class of Bridge driver channel library. - * - * Notes: - * Function comment headers reside in dspdefs.h. - * - * 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 DSPMSG_ -#define DSPMSG_ - -#include <dspbridge/msgdefs.h> - -extern int bridge_msg_create(struct msg_mgr **msg_man, - struct dev_object *hdev_obj, - msg_onexit msg_callback); - -extern int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, - struct msg_queue **msgq, - u32 msgq_id, u32 max_msgs, void *arg); - -extern void bridge_msg_delete(struct msg_mgr *hmsg_mgr); - -extern void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj); - -extern int bridge_msg_get(struct msg_queue *msg_queue_obj, - struct dsp_msg *pmsg, u32 utimeout); - -extern int bridge_msg_put(struct msg_queue *msg_queue_obj, - const struct dsp_msg *pmsg, u32 utimeout); - -extern int bridge_msg_register_notify(struct msg_queue *msg_queue_obj, - u32 event_mask, - u32 notify_type, - struct dsp_notification - *hnotification); - -extern void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, - u32 msgq_id); - -#endif /* DSPMSG_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h b/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h deleted file mode 100644 index 052d27ee8b1..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h +++ /dev/null @@ -1,490 +0,0 @@ -/* - * dynamic_loader.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2008 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 _DYNAMIC_LOADER_H_ -#define _DYNAMIC_LOADER_H_ -#include <linux/kernel.h> -#include <linux/types.h> - -/* - * Dynamic Loader - * - * The function of the dynamic loader is to load a "module" containing - * instructions for a "target" processor into that processor. In the process - * it assigns memory for the module, resolves symbol references made by the - * module, and remembers symbols defined by the module. - * - * The dynamic loader is parameterized for a particular system by 4 classes - * that supply the module and system specific functions it requires - */ - /* The read functions for the module image to be loaded */ -struct dynamic_loader_stream; - - /* This class defines "host" symbol and support functions */ -struct dynamic_loader_sym; - - /* This class defines the allocator for "target" memory */ -struct dynamic_loader_allocate; - - /* This class defines the copy-into-target-memory functions */ -struct dynamic_loader_initialize; - -/* - * Option flags to modify the behavior of module loading - */ -#define DLOAD_INITBSS 0x1 /* initialize BSS sections to zero */ - -/***************************************************************************** - * Procedure dynamic_load_module - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * init Target-side memory initialization, or NULL for symbol read only - * options Option flags DLOAD_* - * mhandle A module handle for use with Dynamic_Unload - * - * Effect: - * The module image is read using *module. Target storage for the new image is - * obtained from *alloc. Symbols defined and referenced by the module are - * managed using *syms. The image is then relocated and references resolved - * as necessary, and the resulting executable bits are placed into target memory - * using *init. - * - * Returns: - * On a successful load, a module handle is placed in *mhandle, and zero is - * returned. On error, the number of errors detected is returned. Individual - * errors are reported during the load process using syms->error_report(). - **************************************************************************** */ -extern int dynamic_load_module( - /* the source for the module image */ - struct dynamic_loader_stream *module, - /* host support for symbols and storage */ - struct dynamic_loader_sym *syms, - /* the target memory allocator */ - struct dynamic_loader_allocate *alloc, - /* the target memory initializer */ - struct dynamic_loader_initialize *init, - unsigned options, /* option flags */ - /* the returned module handle */ - void **mhandle); - -/***************************************************************************** - * Procedure dynamic_open_module - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * init Target-side memory initialization, or NULL for symbol read only - * options Option flags DLOAD_* - * mhandle A module handle for use with Dynamic_Unload - * - * Effect: - * The module image is read using *module. Target storage for the new image is - * obtained from *alloc. Symbols defined and referenced by the module are - * managed using *syms. The image is then relocated and references resolved - * as necessary, and the resulting executable bits are placed into target memory - * using *init. - * - * Returns: - * On a successful load, a module handle is placed in *mhandle, and zero is - * returned. On error, the number of errors detected is returned. Individual - * errors are reported during the load process using syms->error_report(). - **************************************************************************** */ -extern int dynamic_open_module( - /* the source for the module image */ - struct dynamic_loader_stream *module, - /* host support for symbols and storage */ - struct dynamic_loader_sym *syms, - /* the target memory allocator */ - struct dynamic_loader_allocate *alloc, - /* the target memory initializer */ - struct dynamic_loader_initialize *init, - unsigned options, /* option flags */ - /* the returned module handle */ - void **mhandle); - -/***************************************************************************** - * Procedure dynamic_unload_module - * - * Parameters: - * mhandle A module handle from dynamic_load_module - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * - * Effect: - * The module specified by mhandle is unloaded. Unloading causes all - * target memory to be deallocated, all symbols defined by the module to - * be purged, and any host-side storage used by the dynamic loader for - * this module to be released. - * - * Returns: - * Zero for success. On error, the number of errors detected is returned. - * Individual errors are reported using syms->error_report(). - **************************************************************************** */ -extern int dynamic_unload_module(void *mhandle, /* the module - * handle */ - /* host support for symbols and - * storage */ - struct dynamic_loader_sym *syms, - /* the target memory allocator */ - struct dynamic_loader_allocate *alloc, - /* the target memory initializer */ - struct dynamic_loader_initialize *init); - -/***************************************************************************** - ***************************************************************************** - * A class used by the dynamic loader for input of the module image - ***************************************************************************** - **************************************************************************** */ -struct dynamic_loader_stream { -/* public: */ - /************************************************************************* - * read_buffer - * - * PARAMETERS : - * buffer Pointer to the buffer to fill - * bufsiz Amount of data desired in sizeof() units - * - * EFFECT : - * Reads the specified amount of data from the module input stream - * into the specified buffer. Returns the amount of data read in sizeof() - * units (which if less than the specification, represents an error). - * - * NOTES: - * In release 1 increments the file position by the number of bytes read - * - ************************************************************************ */ - int (*read_buffer) (struct dynamic_loader_stream *thisptr, - void *buffer, unsigned bufsiz); - - /************************************************************************* - * set_file_posn (release 1 only) - * - * PARAMETERS : - * posn Desired file position relative to start of file in sizeof() units. - * - * EFFECT : - * Adjusts the internal state of the stream object so that the next - * read_buffer call will begin to read at the specified offset from - * the beginning of the input module. Returns 0 for success, non-zero - * for failure. - * - ************************************************************************ */ - int (*set_file_posn) (struct dynamic_loader_stream *thisptr, - /* to be eliminated in release 2 */ - unsigned int posn); - -}; - -/***************************************************************************** - ***************************************************************************** - * A class used by the dynamic loader for symbol table support and - * miscellaneous host-side functions - ***************************************************************************** - **************************************************************************** */ - -typedef u32 ldr_addr; - -/* - * the structure of a symbol known to the dynamic loader - */ -struct dynload_symbol { - ldr_addr value; -}; - -struct dynamic_loader_sym { -/* public: */ - /************************************************************************* - * find_matching_symbol - * - * PARAMETERS : - * name The name of the desired symbol - * - * EFFECT : - * Locates a symbol matching the name specified. A pointer to the - * symbol is returned if it exists; 0 is returned if no such symbol is - * found. - * - ************************************************************************ */ - struct dynload_symbol *(*find_matching_symbol) - (struct dynamic_loader_sym *thisptr, const char *name); - - /************************************************************************* - * add_to_symbol_table - * - * PARAMETERS : - * nname Pointer to the name of the new symbol - * moduleid An opaque module id assigned by the dynamic loader - * - * EFFECT : - * The new symbol is added to the table. A pointer to the symbol is - * returned, or NULL is returned for failure. - * - * NOTES: - * It is permissible for this function to return NULL; the effect is that - * the named symbol will not be available to resolve references in - * subsequent loads. Returning NULL will not cause the current load - * to fail. - ************************************************************************ */ - struct dynload_symbol *(*add_to_symbol_table) - (struct dynamic_loader_sym * - thisptr, const char *nname, unsigned moduleid); - - /************************************************************************* - * purge_symbol_table - * - * PARAMETERS : - * moduleid An opaque module id assigned by the dynamic loader - * - * EFFECT : - * Each symbol in the symbol table whose moduleid matches the argument - * is removed from the table. - ************************************************************************ */ - void (*purge_symbol_table) (struct dynamic_loader_sym *thisptr, - unsigned moduleid); - - /************************************************************************* - * dload_allocate - * - * PARAMETERS : - * memsiz size of desired memory in sizeof() units - * - * EFFECT : - * Returns a pointer to some "host" memory for use by the dynamic - * loader, or NULL for failure. - * This function is serves as a replaceable form of "malloc" to - * allow the user to configure the memory usage of the dynamic loader. - ************************************************************************ */ - void *(*dload_allocate) (struct dynamic_loader_sym *thisptr, - unsigned memsiz); - - /************************************************************************* - * dload_deallocate - * - * PARAMETERS : - * memptr pointer to previously allocated memory - * - * EFFECT : - * Releases the previously allocated "host" memory. - ************************************************************************ */ - void (*dload_deallocate) (struct dynamic_loader_sym *thisptr, - void *memptr); - - /************************************************************************* - * error_report - * - * PARAMETERS : - * errstr pointer to an error string - * args additional arguments - * - * EFFECT : - * This function provides an error reporting interface for the dynamic - * loader. The error string and arguments are designed as for the - * library function vprintf. - ************************************************************************ */ - void (*error_report) (struct dynamic_loader_sym *thisptr, - const char *errstr, va_list args); - -}; /* class dynamic_loader_sym */ - -/***************************************************************************** - ***************************************************************************** - * A class used by the dynamic loader to allocate and deallocate target memory. - ***************************************************************************** - **************************************************************************** */ - -struct ldr_section_info { - /* Name of the memory section assigned at build time */ - const char *name; - ldr_addr run_addr; /* execution address of the section */ - ldr_addr load_addr; /* load address of the section */ - ldr_addr size; /* size of the section in addressable units */ -#ifndef _BIG_ENDIAN - u16 page; /* memory page or view */ - u16 type; /* one of the section types below */ -#else - u16 type; /* one of the section types below */ - u16 page; /* memory page or view */ -#endif - /* a context field for use by dynamic_loader_allocate; - * ignored but maintained by the dynamic loader */ - u32 context; -}; - -/* use this macro to extract type of section from ldr_section_info.type field */ -#define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF) - -/* type of section to be allocated */ -#define DLOAD_TEXT 0 -#define DLOAD_DATA 1 -#define DLOAD_BSS 2 - /* internal use only, run-time cinit will be of type DLOAD_DATA */ -#define DLOAD_CINIT 3 - -struct dynamic_loader_allocate { -/* public: */ - - /************************************************************************* - * Function allocate - * - * Parameters: - * info A pointer to an information block for the section - * align The alignment of the storage in target AUs - * - * Effect: - * Allocates target memory for the specified section and fills in the - * load_addr and run_addr fields of the section info structure. Returns TRUE - * for success, FALSE for failure. - * - * Notes: - * Frequently load_addr and run_addr are the same, but if they are not - * load_addr is used with dynamic_loader_initialize, and run_addr is - * used for almost all relocations. This function should always initialize - * both fields. - ************************************************************************ */ - int (*dload_allocate) (struct dynamic_loader_allocate *thisptr, - struct ldr_section_info *info, unsigned align); - - /************************************************************************* - * Function deallocate - * - * Parameters: - * info A pointer to an information block for the section - * - * Effect: - * Releases the target memory previously allocated. - * - * Notes: - * The content of the info->name field is undefined on call to this function. - ************************************************************************ */ - void (*dload_deallocate) (struct dynamic_loader_allocate *thisptr, - struct ldr_section_info *info); - -}; /* class dynamic_loader_allocate */ - -/***************************************************************************** - ***************************************************************************** - * A class used by the dynamic loader to load data into a target. This class - * provides the interface-specific functions needed to load data. - ***************************************************************************** - **************************************************************************** */ - -struct dynamic_loader_initialize { -/* public: */ - /************************************************************************* - * Function connect - * - * Parameters: - * none - * - * Effect: - * Connect to the initialization interface. Returns TRUE for success, - * FALSE for failure. - * - * Notes: - * This function is called prior to use of any other functions in - * this interface. - ************************************************************************ */ - int (*connect) (struct dynamic_loader_initialize *thisptr); - - /************************************************************************* - * Function readmem - * - * Parameters: - * bufr Pointer to a word-aligned buffer for the result - * locn Target address of first data element - * info Section info for the section in which the address resides - * bytsiz Size of the data to be read in sizeof() units - * - * Effect: - * Fills the specified buffer with data from the target. Returns TRUE for - * success, FALSE for failure. - ************************************************************************ */ - int (*readmem) (struct dynamic_loader_initialize *thisptr, - void *bufr, - ldr_addr locn, - struct ldr_section_info *info, unsigned bytsiz); - - /************************************************************************* - * Function writemem - * - * Parameters: - * bufr Pointer to a word-aligned buffer of data - * locn Target address of first data element to be written - * info Section info for the section in which the address resides - * bytsiz Size of the data to be written in sizeof() units - * - * Effect: - * Writes the specified buffer to the target. Returns TRUE for success, - * FALSE for failure. - ************************************************************************ */ - int (*writemem) (struct dynamic_loader_initialize *thisptr, - void *bufr, - ldr_addr locn, - struct ldr_section_info *info, unsigned bytsiz); - - /************************************************************************* - * Function fillmem - * - * Parameters: - * locn Target address of first data element to be written - * info Section info for the section in which the address resides - * bytsiz Size of the data to be written in sizeof() units - * val Value to be written in each byte - * Effect: - * Fills the specified area of target memory. Returns TRUE for success, - * FALSE for failure. - ************************************************************************ */ - int (*fillmem) (struct dynamic_loader_initialize *thisptr, - ldr_addr locn, struct ldr_section_info *info, - unsigned bytsiz, unsigned val); - - /************************************************************************* - * Function execute - * - * Parameters: - * start Starting address - * - * Effect: - * The target code at the specified starting address is executed. - * - * Notes: - * This function is called at the end of the dynamic load process - * if the input module has specified a starting address. - ************************************************************************ */ - int (*execute) (struct dynamic_loader_initialize *thisptr, - ldr_addr start); - - /************************************************************************* - * Function release - * - * Parameters: - * none - * - * Effect: - * Releases the connection to the load interface. - * - * Notes: - * This function is called at the end of the dynamic load process. - ************************************************************************ */ - void (*release) (struct dynamic_loader_initialize *thisptr); - -}; /* class dynamic_loader_initialize */ - -#endif /* _DYNAMIC_LOADER_H_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/getsection.h b/drivers/staging/tidspbridge/include/dspbridge/getsection.h deleted file mode 100644 index 626063dd9df..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/getsection.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * getsection.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This file provides an API add-on to the dynamic loader that allows the user - * to query section information and extract section data from dynamic load - * modules. - * - * Notes: - * Functions in this API assume that the supplied dynamic_loader_stream - * object supports the set_file_posn method. - * - * Copyright (C) 2008 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 _GETSECTION_H_ -#define _GETSECTION_H_ - -#include "dynamic_loader.h" - -/* - * Procedure dload_module_open - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side malloc/free and error reporting functions. - * Other methods are unused. - * - * Effect: - * Reads header information from a dynamic loader module using the specified - * stream object, and returns a handle for the module information. This - * handle may be used in subsequent query calls to obtain information - * contained in the module. - * - * Returns: - * NULL if an error is encountered, otherwise a module handle for use - * in subsequent operations. - */ -extern void *dload_module_open(struct dynamic_loader_stream - *module, struct dynamic_loader_sym - *syms); - -/* - * Procedure dload_get_section_info - * - * Parameters: - * minfo Handle from dload_module_open for this module - * section_name Pointer to the string name of the section desired - * section_info Address of a section info structure pointer to be initialized - * - * Effect: - * Finds the specified section in the module information, and fills in - * the provided ldr_section_info structure. - * - * Returns: - * TRUE for success, FALSE for section not found - */ -extern int dload_get_section_info(void *minfo, - const char *section_name, - const struct ldr_section_info - **const section_info); - -/* - * Procedure dload_get_section - * - * Parameters: - * minfo Handle from dload_module_open for this module - * section_info Pointer to a section info structure for the desired section - * section_data Buffer to contain the section initialized data - * - * Effect: - * Copies the initialized data for the specified section into the - * supplied buffer. - * - * Returns: - * TRUE for success, FALSE for section not found - */ -extern int dload_get_section(void *minfo, - const struct ldr_section_info *section_info, - void *section_data); - -/* - * Procedure dload_module_close - * - * Parameters: - * minfo Handle from dload_module_open for this module - * - * Effect: - * Releases any storage associated with the module handle. On return, - * the module handle is invalid. - * - * Returns: - * Zero for success. On error, the number of errors detected is returned. - * Individual errors are reported using syms->error_report(), where syms was - * an argument to dload_module_open - */ -extern void dload_module_close(void *minfo); - -#endif /* _GETSECTION_H_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/gh.h b/drivers/staging/tidspbridge/include/dspbridge/gh.h deleted file mode 100644 index e4303b4bf5f..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/gh.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * gh.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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 GH_ -#define GH_ -#include <dspbridge/host_os.h> - -extern struct gh_t_hash_tab *gh_create(u32 val_size, - u32 (*hash)(const void *), bool (*match)(const void *, - const void *), void (*delete) (void *)); -extern void gh_delete(struct gh_t_hash_tab *hash_tab); -extern void *gh_find(struct gh_t_hash_tab *hash_tab, const void *key); -extern void *gh_insert(struct gh_t_hash_tab *hash_tab, const void *key, - const void *value); -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -void gh_iterate(struct gh_t_hash_tab *hash_tab, - void (*callback)(void *, void *), void *user_data); -#endif -#endif /* GH_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h deleted file mode 100644 index d1441db469f..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/host_os.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * host_os.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2008 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 _HOST_OS_H_ -#define _HOST_OS_H_ - -#include <linux/atomic.h> -#include <linux/semaphore.h> -#include <linux/uaccess.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/syscalls.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/stddef.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/ctype.h> -#include <linux/mm.h> -#include <linux/device.h> -#include <linux/vmalloc.h> -#include <linux/ioport.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/omap-mailbox.h> -#include <linux/pagemap.h> -#include <asm/cacheflush.h> -#include <linux/dma-mapping.h> - -/* TODO -- Remove, once omap-iommu is used */ -#define INT_DSP_MMU_IRQ (28 + NR_IRQS) - -#define PRCM_VDD1 1 - -extern struct platform_device *omap_dspbridge_dev; -extern struct device *bridge; - -#endif diff --git a/drivers/staging/tidspbridge/include/dspbridge/io.h b/drivers/staging/tidspbridge/include/dspbridge/io.h deleted file mode 100644 index 75057185690..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/io.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * io.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The io module 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. - */ - -#ifndef IO_ -#define IO_ - -#include <dspbridge/cfgdefs.h> -#include <dspbridge/devdefs.h> - -/* IO Objects: */ -struct io_mgr; - -/* IO manager attributes: */ -struct io_attrs { - u8 birq; /* Channel's I/O IRQ number. */ - bool irq_shared; /* TRUE if the IRQ is shareable. */ - u32 word_size; /* DSP Word size. */ - u32 shm_base; /* Physical base address of shared memory. */ - u32 sm_length; /* Size (in bytes) of shared memory. */ -}; - - -/* - * ======== io_create ======== - * Purpose: - * Create an IO manager object, responsible for managing IO between - * CHNL and msg_ctrl. - * Parameters: - * channel_mgr: Location to store a channel manager object on - * output. - * hdev_obj: Handle to a device object. - * mgr_attrts: IO manager attributes. - * mgr_attrts->birq: I/O IRQ number. - * mgr_attrts->irq_shared: TRUE if the IRQ is shareable. - * mgr_attrts->word_size: DSP Word size in equivalent PC bytes.. - * Returns: - * 0: Success; - * -ENOMEM: Insufficient memory for requested resources. - * -EIO: Unable to plug channel ISR for configured IRQ. - * -EINVAL: Invalid DSP word size (must be > 0). - * Invalid base address for DSP communications. - * Requires: - * io_man != NULL. - * mgr_attrts != NULL. - * Ensures: - */ -extern int io_create(struct io_mgr **io_man, - struct dev_object *hdev_obj, - const struct io_attrs *mgr_attrts); - -/* - * ======== io_destroy ======== - * Purpose: - * Destroy the IO manager. - * Parameters: - * hio_mgr: IOmanager object. - * Returns: - * 0: Success. - * -EFAULT: hio_mgr was invalid. - * Requires: - * Ensures: - */ -extern int io_destroy(struct io_mgr *hio_mgr); - -#endif /* CHNL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h deleted file mode 100644 index 903ff12b14d..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * io_sm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * IO dispatcher for a shared memory channel driver. - * Also, includes macros to simulate shm via port io calls. - * - * 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 IOSM_ -#define IOSM_ - -#include <dspbridge/_chnl_sm.h> -#include <dspbridge/host_os.h> - -#include <dspbridge/io.h> -#include <dspbridge/mbx_sh.h> /* shared mailbox codes */ - -/* Magic code used to determine if DSP signaled exception. */ -#define DEH_BASE MBX_DEH_BASE -#define DEH_LIMIT MBX_DEH_LIMIT - -#define IO_INPUT 0 -#define IO_OUTPUT 1 -#define IO_SERVICE 2 - -#ifdef CONFIG_TIDSPBRIDGE_DVFS -/* The maximum number of OPPs that are supported */ -extern s32 dsp_max_opps; -/* The Vdd1 opp table information */ -extern u32 vdd1_dsp_freq[6][4]; -#endif - -/* - * ======== io_cancel_chnl ======== - * Purpose: - * Cancel IO on a given channel. - * Parameters: - * hio_mgr: IO Manager. - * chnl: Index of channel to cancel IO on. - * Returns: - * Requires: - * Valid hio_mgr. - * Ensures: - */ -extern void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl); - -/* - * ======== io_dpc ======== - * Purpose: - * Deferred procedure call for shared memory channel driver ISR. Carries - * out the dispatch of I/O. - * Parameters: - * ref_data: Pointer to reference data registered via a call to - * DPC_Create(). - * Returns: - * Requires: - * Must not block. - * Must not acquire resources. - * All data touched must be locked in memory if running in kernel mode. - * Ensures: - * Non-preemptible (but interruptible). - */ -extern void io_dpc(unsigned long ref_data); - -/* - * ======== io_mbox_msg ======== - * Purpose: - * Main message handler for the shared memory Bridge channel manager. - * Determine if this message is ours, then schedules a DPC to - * dispatch I/O. - * Parameters: - * self: Pointer to its own notifier_block struct. - * len: Length of message. - * msg: Message code received. - * Returns: - * NOTIFY_OK if handled; NOTIFY_BAD otherwise. - */ -int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg); - -/* - * ======== io_request_chnl ======== - * Purpose: - * Request I/O from the DSP. Sets flags in shared memory, then interrupts - * the DSP. - * Parameters: - * hio_mgr: IO manager handle. - * pchnl: Ptr to the channel requesting I/O. - * io_mode: Mode of channel: {IO_INPUT | IO_OUTPUT}. - * Returns: - * Requires: - * pchnl != NULL - * Ensures: - */ -extern void io_request_chnl(struct io_mgr *io_manager, - struct chnl_object *pchnl, - u8 io_mode, u16 *mbx_val); - -/* - * ======== iosm_schedule ======== - * Purpose: - * Schedule DPC for IO. - * Parameters: - * pio_mgr: Ptr to a I/O manager. - * Returns: - * Requires: - * pchnl != NULL - * Ensures: - */ -extern void iosm_schedule(struct io_mgr *io_manager); - -/* - * ======== io_sh_msetting ======== - * Purpose: - * Sets the shared memory setting - * Parameters: - * hio_mgr: Handle to a I/O manager. - * desc: Shared memory type - * pargs: Ptr to shm setting - * Returns: - * Requires: - * hio_mgr != NULL - * pargs != NULL - * Ensures: - */ -extern int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs); - -/* - * Misc functions for the CHNL_IO shared memory library: - */ - -/* Maximum channel bufsize that can be used. */ -extern u32 io_buf_size(struct io_mgr *hio_mgr); - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/* - * ========print_dsp_trace_buffer ======== - * Print DSP tracebuffer. - */ -extern int print_dsp_trace_buffer(struct bridge_dev_context - *hbridge_context); - -int dump_dsp_stack(struct bridge_dev_context *bridge_context); - -void dump_dl_modules(struct bridge_dev_context *bridge_context); - -void print_dsp_debug_trace(struct io_mgr *hio_mgr); -#endif - -#endif /* IOSM_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h b/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h deleted file mode 100644 index d4cb3948bab..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * mbx_sh.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Definitions for shared mailbox cmd/data values.(used on both - * the GPP and DSP sides). - * - * Copyright (C) 2008 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. - */ - -/* - * Bridge usage of OMAP mailbox 1 is determined by the "class" of the - * mailbox interrupt's cmd value received. The class value are defined - * as a bit (10 thru 15) being set. - * - * Note: Only 16 bits of each is used. Other 16 bit data reg available. - * - * 16 bit Mbx bit defns: - * - * A). Exception/Error handling (Module DEH) : class = 0. - * - * 15 10 0 - * --------------------------------- - * |0|0|0|0|0|0|x|x|x|x|x|x|x|x|x|x| - * --------------------------------- - * | (class) | (module specific) | - * - * - * B: DSP-DMA link driver channels (DDMA) : class = 1. - * - * 15 10 0 - * --------------------------------- - * |0|0|0|0|0|1|b|b|b|b|b|c|c|c|c|c| - * --------------------------------- - * | (class) | (module specific) | - * - * where b -> buffer index (32 DDMA buffers/chnl max) - * c -> channel Id (32 DDMA chnls max) - * - * - * C: Proc-copy link driver channels (PCPY) : class = 2. - * - * 15 10 0 - * --------------------------------- - * |0|0|0|0|1|0|x|x|x|x|x|x|x|x|x|x| - * --------------------------------- - * | (class) | (module specific) | - * - * - * D: Zero-copy link driver channels (DDZC) : class = 4. - * - * 15 10 0 - * --------------------------------- - * |0|0|0|1|0|0|x|x|x|x|x|c|c|c|c|c| - * --------------------------------- - * | (class) | (module specific) | - * - * where x -> not used - * c -> channel Id (32 ZCPY chnls max) - * - * - * E: Power management : class = 8. - * - * 15 10 0 - * --------------------------------- - * |0|0|1|0|0|0|x|x|x|x|x|c|c|c|c|c| - - * 0010 00xx xxxc cccc - * 0010 00nn pppp qqqq - * nn: - * 00 = reserved - * 01 = pwr state change - * 10 = opp pre-change - * 11 = opp post-change - * - * if nn = pwr state change: - * pppp = don't care - * qqqq: - * 0010 = hibernate - * 0010 0001 0000 0010 - * 0110 = retention - * 0010 0001 0000 0110 - * others reserved - * - * if nn = opp pre-change: - * pppp = current opp - * qqqq = next opp - * - * if nn = opp post-change: - * pppp = prev opp - * qqqq = current opp - * - * --------------------------------- - * | (class) | (module specific) | - * - * where x -> not used - * c -> Power management command - * - */ - -#ifndef _MBX_SH_H -#define _MBX_SH_H - -#define MBX_PCPY_CLASS 0x0800 /* PROC-COPY " */ -#define MBX_PM_CLASS 0x2000 /* Power Management */ -#define MBX_DBG_CLASS 0x4000 /* For debugging purpose */ - -/* - * Exception Handler codes - * Magic code used to determine if DSP signaled exception. - */ -#define MBX_DEH_BASE 0x0 -#define MBX_DEH_USERS_BASE 0x100 /* 256 */ -#define MBX_DEH_LIMIT 0x3FF /* 1023 */ -#define MBX_DEH_RESET 0x101 /* DSP RESET (DEH) */ - -/* - * Link driver command/status codes. - */ - -/* Power Management Commands */ -#define MBX_PM_DSPIDLE (MBX_PM_CLASS + 0x0) -#define MBX_PM_DSPWAKEUP (MBX_PM_CLASS + 0x1) -#define MBX_PM_EMERGENCYSLEEP (MBX_PM_CLASS + 0x2) -#define MBX_PM_SETPOINT_PRENOTIFY (MBX_PM_CLASS + 0x6) -#define MBX_PM_SETPOINT_POSTNOTIFY (MBX_PM_CLASS + 0x7) -#define MBX_PM_DSPRETENTION (MBX_PM_CLASS + 0x8) -#define MBX_PM_DSPHIBERNATE (MBX_PM_CLASS + 0x9) -#define MBX_PM_HIBERNATE_EN (MBX_PM_CLASS + 0xA) -#define MBX_PM_OPP_REQ (MBX_PM_CLASS + 0xB) - -/* Bridge Debug Commands */ -#define MBX_DBG_SYSPRINTF (MBX_DBG_CLASS + 0x0) - -#endif /* _MBX_SH_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/memdefs.h b/drivers/staging/tidspbridge/include/dspbridge/memdefs.h deleted file mode 100644 index 78d2c5d0045..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/memdefs.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * memdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global MEM constants and types, shared between Bridge driver and DSP API. - * - * Copyright (C) 2008 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 MEMDEFS_ -#define MEMDEFS_ - -/* - * MEM_VIRTUALSEGID is used by Node & Strm to access virtual address space in - * the correct client process context. - */ -#define MEM_SETVIRTUALSEGID 0x10000000 -#define MEM_GETVIRTUALSEGID 0x20000000 -#define MEM_MASKVIRTUALSEGID (MEM_SETVIRTUALSEGID | MEM_GETVIRTUALSEGID) - -#endif /* MEMDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgr.h b/drivers/staging/tidspbridge/include/dspbridge/mgr.h deleted file mode 100644 index 47b0318430e..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/mgr.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * mgr.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This is the DSP API RM module interface. - * - * 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 MGR_ -#define MGR_ - -#include <dspbridge/mgrpriv.h> - -#define MAX_EVENTS 32 - -/* - * ======== mgr_wait_for_bridge_events ======== - * Purpose: - * Block on any Bridge event(s) - * Parameters: - * anotifications : array of pointers to notification objects. - * count : number of elements in above array - * pu_index : index of signaled event object - * utimeout : timeout interval in milliseocnds - * Returns: - * 0 : Success. - * -ETIME : Wait timed out. *pu_index is undetermined. - * Details: - */ - -int mgr_wait_for_bridge_events(struct dsp_notification - **anotifications, - u32 count, u32 *pu_index, - u32 utimeout); - -/* - * ======== mgr_create ======== - * Purpose: - * Creates the Manager Object. This is done during the driver loading. - * There is only one Manager Object in the DSP/BIOS Bridge. - * Parameters: - * mgr_obj: Location to store created MGR Object handle. - * dev_node_obj: Device object as known to the system. - * Returns: - * 0: Success - * -ENOMEM: Failed to Create the Object - * -EPERM: General Failure - * Requires: - * MGR Initialized (refs > 0 ) - * mgr_obj != NULL. - * Ensures: - * 0: *mgr_obj is a valid MGR interface to the device. - * MGR Object stores the DCD Manager Handle. - * MGR Object stored in the Regsitry. - * !0: MGR Object not created - * Details: - * DCD Dll is loaded and MGR Object stores the handle of the DLL. - */ -extern int mgr_create(struct mgr_object **mgr_obj, - struct cfg_devnode *dev_node_obj); - -/* - * ======== mgr_destroy ======== - * Purpose: - * Destroys the MGR object. Called upon driver unloading. - * Parameters: - * hmgr_obj: Handle to Manager object . - * Returns: - * 0: Success. - * DCD Manager freed; MGR Object destroyed; - * MGR Object deleted from the Registry. - * -EPERM: Failed to destroy MGR Object - * Requires: - * MGR Initialized (refs > 0 ) - * hmgr_obj is a valid MGR handle . - * Ensures: - * 0: MGR Object destroyed and hmgr_obj is Invalid MGR - * Handle. - */ -extern int mgr_destroy(struct mgr_object *hmgr_obj); - -/* - * ======== mgr_enum_node_info ======== - * Purpose: - * Enumerate and get configuration information about nodes configured - * in the node database. - * Parameters: - * node_id: The node index (base 0). - * pndb_props: Ptr to the dsp_ndbprops structure for output. - * undb_props_size: Size of the dsp_ndbprops structure. - * pu_num_nodes: Location where the number of nodes configured - * in the database will be returned. - * Returns: - * 0: Success. - * -EINVAL: Parameter node_id is > than the number of nodes. - * configutred in the system - * -EIDRM: During Enumeration there has been a change in - * the number of nodes configured or in the - * the properties of the enumerated nodes. - * -EPERM: Failed to querry the Node Data Base - * Requires: - * pNDBPROPS is not null - * undb_props_size >= sizeof(dsp_ndbprops) - * pu_num_nodes is not null - * MGR Initialized (refs > 0 ) - * Ensures: - * SUCCESS on successful retreival of data and *pu_num_nodes > 0 OR - * DSP_FAILED && *pu_num_nodes == 0. - * Details: - */ -extern int mgr_enum_node_info(u32 node_id, - struct dsp_ndbprops *pndb_props, - u32 undb_props_size, - u32 *pu_num_nodes); - -/* - * ======== mgr_enum_processor_info ======== - * Purpose: - * Enumerate and get configuration information about available DSP - * processors - * Parameters: - * processor_id: The processor index (zero-based). - * processor_info: Ptr to the dsp_processorinfo structure . - * processor_info_size: Size of dsp_processorinfo structure. - * pu_num_procs: Location where the number of DSPs configured - * in the database will be returned - * Returns: - * 0: Success. - * -EINVAL: Parameter processor_id is > than the number of - * DSP Processors in the system. - * -EPERM: Failed to querry the Node Data Base - * Requires: - * processor_info is not null - * pu_num_procs is not null - * processor_info_size >= sizeof(dsp_processorinfo) - * MGR Initialized (refs > 0 ) - * Ensures: - * SUCCESS on successful retreival of data and *pu_num_procs > 0 OR - * DSP_FAILED && *pu_num_procs == 0. - * Details: - */ -extern int mgr_enum_processor_info(u32 processor_id, - struct dsp_processorinfo - *processor_info, - u32 processor_info_size, - u8 *pu_num_procs); -/* - * ======== mgr_exit ======== - * Purpose: - * Decrement reference count, and free resources when reference count is - * 0. - * Parameters: - * Returns: - * Requires: - * MGR is initialized. - * Ensures: - * When reference count == 0, MGR's private resources are freed. - */ -extern void mgr_exit(void); - -/* - * ======== mgr_get_dcd_handle ======== - * Purpose: - * Retrieves the MGR handle. Accessor Function - * Parameters: - * mgr_handle: Handle to the Manager Object - * dcd_handle: Ptr to receive the DCD Handle. - * Returns: - * 0: Success - * -EPERM: Failure to get the Handle - * Requires: - * MGR is initialized. - * dcd_handle != NULL - * Ensures: - * 0 and *dcd_handle != NULL || - * -EPERM and *dcd_handle == NULL - */ -extern int mgr_get_dcd_handle(struct mgr_object - *mgr_handle, u32 *dcd_handle); - -/* - * ======== mgr_init ======== - * Purpose: - * Initialize MGR's private state, keeping a reference count on each - * call. Initializes the DCD. - * Parameters: - * Returns: - * TRUE if initialized; FALSE if error occurred. - * Requires: - * Ensures: - * TRUE: A requirement for the other public MGR functions. - */ -extern bool mgr_init(void); - -#endif /* MGR_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h b/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h deleted file mode 100644 index 3a4e337c040..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * mgrpriv.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global MGR constants and types, shared by PROC, MGR, and DSP API. - * - * Copyright (C) 2008 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 MGRPRIV_ -#define MGRPRIV_ - -/* - * OMAP1510 specific - */ -#define MGR_MAXTLBENTRIES 32 - -/* RM MGR Object */ -struct mgr_object; - -struct mgr_tlbentry { - u32 dsp_virt; /* DSP virtual address */ - u32 gpp_phys; /* GPP physical address */ -}; - -/* - * The DSP_PROCESSOREXTINFO structure describes additional extended - * capabilities of a DSP processor not exposed to user. - */ -struct mgr_processorextinfo { - struct dsp_processorinfo ty_basic; /* user processor info */ - /* private dsp mmu entries */ - struct mgr_tlbentry ty_tlb[MGR_MAXTLBENTRIES]; -}; - -#endif /* MGRPRIV_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/msg.h b/drivers/staging/tidspbridge/include/dspbridge/msg.h deleted file mode 100644 index 2c8712c933f..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/msg.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * msg.h - * - * 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. - */ - -#ifndef MSG_ -#define MSG_ - -#include <dspbridge/devdefs.h> -#include <dspbridge/msgdefs.h> - -/* - * ======== msg_create ======== - * Purpose: - * Create an object to manage message queues. Only one of these objects - * can exist per device object. The msg_ctrl manager must be created before - * the IO Manager. - * Parameters: - * msg_man: Location to store msg_ctrl manager handle on output. - * hdev_obj: The device object. - * msg_callback: Called whenever an RMS_EXIT message is received. - * Returns: - * Requires: - * msg_man != NULL. - * hdev_obj != NULL. - * msg_callback != NULL. - * Ensures: - */ -extern int msg_create(struct msg_mgr **msg_man, - struct dev_object *hdev_obj, - msg_onexit msg_callback); - -/* - * ======== msg_delete ======== - * Purpose: - * Delete a msg_ctrl manager allocated in msg_create(). - * Parameters: - * hmsg_mgr: Handle returned from msg_create(). - * Returns: - * Requires: - * Valid hmsg_mgr. - * Ensures: - */ -extern void msg_delete(struct msg_mgr *hmsg_mgr); - -#endif /* MSG_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h deleted file mode 100644 index 80a3fa1a8a3..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * msgdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global msg_ctrl constants and types. - * - * 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 MSGDEFS_ -#define MSGDEFS_ - -/* msg_ctrl Objects: */ -struct msg_mgr; -struct msg_queue; - -/* Function prototype for callback to be called on RMS_EXIT message received */ -typedef void (*msg_onexit) (void *h, s32 node_status); - -#endif /* MSGDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldr.h b/drivers/staging/tidspbridge/include/dspbridge/nldr.h deleted file mode 100644 index c5e48ca6c54..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/nldr.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * nldr.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge dynamic loader interface. - * - * 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. - */ - -#include <dspbridge/dbdefs.h> -#include <dspbridge/dbdcddef.h> -#include <dspbridge/dev.h> -#include <dspbridge/rmm.h> -#include <dspbridge/nldrdefs.h> - -#ifndef NLDR_ -#define NLDR_ - -extern int nldr_allocate(struct nldr_object *nldr_obj, - void *priv_ref, const struct dcd_nodeprops - *node_props, - struct nldr_nodeobject **nldr_nodeobj, - bool *pf_phase_split); - -extern int nldr_create(struct nldr_object **nldr, - struct dev_object *hdev_obj, - const struct nldr_attrs *pattrs); - -extern void nldr_delete(struct nldr_object *nldr_obj); - -extern int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj, - char *str_fxn, u32 * addr); - -extern int nldr_get_rmm_manager(struct nldr_object *nldr, - struct rmm_target_obj **rmm_mgr); - -extern int nldr_load(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase); -extern int nldr_unload(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase); -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr, - u32 offset_range, void *offset_output, char *sym_name); -#endif - -#endif /* NLDR_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h deleted file mode 100644 index 7e3c7f58b49..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * nldrdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global Dynamic + static/overlay Node loader (NLDR) constants and types. - * - * Copyright (C) 2008 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 NLDRDEFS_ -#define NLDRDEFS_ - -#include <dspbridge/dbdcddef.h> -#include <dspbridge/devdefs.h> - -#define NLDR_MAXPATHLENGTH 255 -/* NLDR Objects: */ -struct nldr_object; -struct nldr_nodeobject; - -/* - * ======== nldr_loadtype ======== - * Load types for a node. Must match values in node.h55. - */ -enum nldr_loadtype { - NLDR_STATICLOAD, /* Linked in base image, not overlay */ - NLDR_DYNAMICLOAD, /* Dynamically loaded node */ - NLDR_OVLYLOAD /* Linked in base image, overlay node */ -}; - -/* - * ======== nldr_ovlyfxn ======== - * Causes code or data to be copied from load address to run address. This - * is the "cod_writefxn" that gets passed to the DBLL_Library and is used as - * the ZL write function. - * - * Parameters: - * priv_ref: Handle to identify the node. - * dsp_run_addr: Run address of code or data. - * dsp_load_addr: Load address of code or data. - * ul_num_bytes: Number of (GPP) bytes to copy. - * mem_space: RMS_CODE or RMS_DATA. - * Returns: - * ul_num_bytes: Success. - * 0: Failure. - * Requires: - * Ensures: - */ -typedef u32(*nldr_ovlyfxn) (void *priv_ref, u32 dsp_run_addr, - u32 dsp_load_addr, u32 ul_num_bytes, u32 mem_space); - -/* - * ======== nldr_writefxn ======== - * Write memory function. Used for dynamic load writes. - * Parameters: - * priv_ref: Handle to identify the node. - * dsp_add: Address of code or data. - * pbuf: Code or data to be written - * ul_num_bytes: Number of (GPP) bytes to write. - * mem_space: DBLL_DATA or DBLL_CODE. - * Returns: - * ul_num_bytes: Success. - * 0: Failure. - * Requires: - * Ensures: - */ -typedef u32(*nldr_writefxn) (void *priv_ref, - u32 dsp_add, void *pbuf, - u32 ul_num_bytes, u32 mem_space); - -/* - * ======== nldr_attrs ======== - * Attributes passed to nldr_create function. - */ -struct nldr_attrs { - nldr_ovlyfxn ovly; - nldr_writefxn write; - u16 dsp_word_size; - u16 dsp_mau_size; -}; - -/* - * ======== nldr_phase ======== - * Indicates node create, delete, or execute phase function. - */ -enum nldr_phase { - NLDR_CREATE, - NLDR_DELETE, - NLDR_EXECUTE, - NLDR_NOPHASE -}; - -/* - * Typedefs of loader functions imported from a DLL, or defined in a - * function table. - */ - -/* - * ======== nldr_allocate ======== - * Allocate resources to manage the loading of a node on the DSP. - * - * Parameters: - * nldr_obj: Handle of loader that will load the node. - * priv_ref: Handle to identify the node. - * node_props: Pointer to a dcd_nodeprops for the node. - * nldr_nodeobj: Location to store node handle on output. This handle - * will be passed to nldr_load/nldr_unload. - * pf_phase_split: pointer to int variable referenced in node.c - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory on GPP. - * Requires: - * Valid nldr_obj. - * node_props != NULL. - * nldr_nodeobj != NULL. - * Ensures: - * 0: IsValidNode(*nldr_nodeobj). - * error: *nldr_nodeobj == NULL. - */ -typedef int(*nldr_allocatefxn) (struct nldr_object *nldr_obj, - void *priv_ref, - const struct dcd_nodeprops - * node_props, - struct nldr_nodeobject - **nldr_nodeobj, - bool *pf_phase_split); - -/* - * ======== nldr_create ======== - * Create a loader object. This object handles the loading and unloading of - * create, delete, and execute phase functions of nodes on the DSP target. - * - * Parameters: - * nldr: Location to store loader handle on output. - * hdev_obj: Device for this processor. - * pattrs: Loader attributes. - * Returns: - * 0: Success; - * -ENOMEM: Insufficient memory for requested resources. - * Requires: - * nldr != NULL. - * hdev_obj != NULL. - * pattrs != NULL. - * Ensures: - * 0: Valid *nldr. - * error: *nldr == NULL. - */ -typedef int(*nldr_createfxn) (struct nldr_object **nldr, - struct dev_object *hdev_obj, - const struct nldr_attrs *pattrs); - -/* - * ======== nldr_delete ======== - * Delete the NLDR loader. - * - * Parameters: - * nldr_obj: Node manager object. - * Returns: - * Requires: - * Valid nldr_obj. - * Ensures: - * nldr_obj invalid - */ -typedef void (*nldr_deletefxn) (struct nldr_object *nldr_obj); - -/* - * ======== NLDR_Free ======== - * Free resources allocated in nldr_allocate. - * - * Parameters: - * nldr_node_obj: Handle returned from nldr_allocate(). - * Returns: - * Requires: - * Valid nldr_node_obj. - * Ensures: - */ -typedef void (*nldr_freefxn) (struct nldr_nodeobject *nldr_node_obj); - -/* - * ======== nldr_get_fxn_addr ======== - * Get address of create, delete, or execute phase function of a node on - * the DSP. - * - * Parameters: - * nldr_node_obj: Handle returned from nldr_allocate(). - * str_fxn: Name of function. - * addr: Location to store function address. - * Returns: - * 0: Success. - * -ESPIPE: Address of function not found. - * Requires: - * Valid nldr_node_obj. - * addr != NULL; - * str_fxn != NULL; - * Ensures: - */ -typedef int(*nldr_getfxnaddrfxn) (struct nldr_nodeobject - * nldr_node_obj, - char *str_fxn, u32 * addr); - -/* - * ======== nldr_load ======== - * Load create, delete, or execute phase function of a node on the DSP. - * - * Parameters: - * nldr_node_obj: Handle returned from nldr_allocate(). - * phase: Type of function to load (create, delete, or execute). - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory on GPP. - * -ENXIO: Can't overlay phase because overlay memory - * is already in use. - * -EILSEQ: Failure in dynamic loader library. - * Requires: - * Valid nldr_node_obj. - * Ensures: - */ -typedef int(*nldr_loadfxn) (struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase); - -/* - * ======== nldr_unload ======== - * Unload create, delete, or execute phase function of a node on the DSP. - * - * Parameters: - * nldr_node_obj: Handle returned from nldr_allocate(). - * phase: Node function to unload (create, delete, or execute). - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory on GPP. - * Requires: - * Valid nldr_node_obj. - * Ensures: - */ -typedef int(*nldr_unloadfxn) (struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase); - -/* - * ======== node_ldr_fxns ======== - */ -struct node_ldr_fxns { - nldr_allocatefxn allocate; - nldr_createfxn create; - nldr_deletefxn delete; - nldr_getfxnaddrfxn get_fxn_addr; - nldr_loadfxn load; - nldr_unloadfxn unload; -}; - -#endif /* NLDRDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h deleted file mode 100644 index 68ed74a86c9..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/node.h +++ /dev/null @@ -1,524 +0,0 @@ -/* - * node.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge Node Manager. - * - * 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 NODE_ -#define NODE_ - -#include <dspbridge/procpriv.h> - -#include <dspbridge/nodedefs.h> -#include <dspbridge/disp.h> -#include <dspbridge/nldrdefs.h> -#include <dspbridge/drv.h> - -/* - * ======== node_allocate ======== - * Purpose: - * Allocate GPP resources to manage a node on the DSP. - * Parameters: - * hprocessor: Handle of processor that is allocating the node. - * node_uuid: Pointer to a dsp_uuid for the node. - * pargs: Optional arguments to be passed to the node. - * attr_in: Optional pointer to node attributes (priority, - * timeout...) - * noderes: Location to store node resource info. - * Returns: - * 0: Success. - * -ENOMEM: Insufficient memory on GPP. - * -ENOKEY: Node UUID has not been registered. - * -ESPIPE: iAlg functions not found for a DAIS node. - * -EDOM: attr_in != NULL and attr_in->prio out of - * range. - * -EPERM: A failure occurred, unable to allocate node. - * -EBADR: Proccessor is not in the running state. - * Requires: - * hprocessor != NULL. - * node_uuid != NULL. - * noderes != NULL. - * Ensures: - * 0: IsValidNode(*ph_node). - * error: *noderes == NULL. - */ -extern int node_allocate(struct proc_object *hprocessor, - const struct dsp_uuid *node_uuid, - const struct dsp_cbdata - *pargs, const struct dsp_nodeattrin - *attr_in, - struct node_res_object **noderes, - struct process_context *pr_ctxt); - -/* - * ======== node_alloc_msg_buf ======== - * Purpose: - * Allocate and Prepare a buffer whose descriptor will be passed to a - * Node within a (dsp_msg)message - * Parameters: - * hnode: The node handle. - * usize: The size of the buffer to be allocated. - * pattr: Pointer to a dsp_bufferattr structure. - * pbuffer: Location to store the address of the allocated - * buffer on output. - * Returns: - * 0: Success. - * -EFAULT: Invalid node handle. - * -ENOMEM: Insufficent memory. - * -EPERM: General Failure. - * -EINVAL: Invalid Size. - * Requires: - * pbuffer != NULL. - * Ensures: - */ -extern int node_alloc_msg_buf(struct node_object *hnode, - u32 usize, struct dsp_bufferattr - *pattr, u8 **pbuffer); - -/* - * ======== node_change_priority ======== - * Purpose: - * Change the priority of an allocated node. - * Parameters: - * hnode: Node handle returned from node_allocate. - * prio: New priority level to set node's priority to. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -EDOM: prio is out of range. - * -EPERM: The specified node is not a task node. - * Unable to change node's runtime priority level. - * -EBADR: Node is not in the NODE_ALLOCATED, NODE_PAUSED, - * or NODE_RUNNING state. - * -ETIME: A timeout occurred before the DSP responded. - * Requires: - * Ensures: - * 0 && (Node's current priority == prio) - */ -extern int node_change_priority(struct node_object *hnode, s32 prio); - -/* - * ======== node_connect ======== - * Purpose: - * Connect two nodes on the DSP, or a node on the DSP to the GPP. In the - * case that the connection is being made between a node on the DSP and - * the GPP, one of the node handles (either node1 or node2) must be - * the constant NODE_HGPPNODE. - * Parameters: - * node1: Handle of first node to connect to second node. If - * this is a connection from the GPP to node2, node1 - * must be the constant NODE_HGPPNODE. Otherwise, node1 - * must be a node handle returned from a successful call - * to Node_Allocate(). - * node2: Handle of second node. Must be either NODE_HGPPNODE - * if this is a connection from DSP node to GPP, or a - * node handle returned from a successful call to - * node_allocate(). - * stream1: Output stream index on first node, to be connected - * to second node's input stream. Value must range from - * 0 <= stream1 < number of output streams. - * stream2: Input stream index on second node. Value must range - * from 0 <= stream2 < number of input streams. - * pattrs: Stream attributes (NULL ==> use defaults). - * conn_param: A pointer to a dsp_cbdata structure that defines - * connection parameter for device nodes to pass to DSP - * side. - * If the value of this parameter is NULL, then this API - * behaves like DSPNode_Connect. This parameter will have - * length of the string and the null terminated string in - * dsp_cbdata struct. This can be extended in future tp - * pass binary data. - * Returns: - * 0: Success. - * -EFAULT: Invalid node1 or node2. - * -ENOMEM: Insufficient host memory. - * -EINVAL: A stream index parameter is invalid. - * -EISCONN: A connection already exists for one of the - * indices stream1 or stream2. - * -EBADR: Either node1 or node2 is not in the - * NODE_ALLOCATED state. - * -ECONNREFUSED: No more connections available. - * -EPERM: Attempt to make an illegal connection (eg, - * Device node to device node, or device node to - * GPP), the two nodes are on different DSPs. - * Requires: - * Ensures: - */ -extern int node_connect(struct node_object *node1, - u32 stream1, - struct node_object *node2, - u32 stream2, - struct dsp_strmattr *pattrs, - struct dsp_cbdata - *conn_param); - -/* - * ======== node_create ======== - * Purpose: - * Create a node on the DSP by remotely calling the node's create - * function. If necessary, load code that contains the node's create - * function. - * Parameters: - * hnode: Node handle returned from node_allocate(). - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -ESPIPE: Create function not found in the COFF file. - * -EBADR: Node is not in the NODE_ALLOCATED state. - * -ENOMEM: Memory allocation failure on the DSP. - * -ETIME: A timeout occurred before the DSP responded. - * -EPERM: A failure occurred, unable to create node. - * Requires: - * Ensures: - */ -extern int node_create(struct node_object *hnode); - -/* - * ======== node_create_mgr ======== - * Purpose: - * Create a NODE Manager object. This object handles the creation, - * deletion, and execution of nodes on the DSP target. The NODE Manager - * also maintains a pipe map of used and available node connections. - * Each DEV object should have exactly one NODE Manager object. - * - * Parameters: - * node_man: Location to store node manager handle on output. - * hdev_obj: Device for this processor. - * Returns: - * 0: Success; - * -ENOMEM: Insufficient memory for requested resources. - * -EPERM: General failure. - * Requires: - * node_man != NULL. - * hdev_obj != NULL. - * Ensures: - * 0: Valide *node_man. - * error: *node_man == NULL. - */ -extern int node_create_mgr(struct node_mgr **node_man, - struct dev_object *hdev_obj); - -/* - * ======== node_delete ======== - * Purpose: - * Delete resources allocated in node_allocate(). If the node was - * created, delete the node on the DSP by remotely calling the node's - * delete function. Loads the node's delete function if necessary. - * GPP side resources are freed after node's delete function returns. - * Parameters: - * noderes: Node resource info handle returned from - * node_allocate(). - * pr_ctxt: Pointer to process context data. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -ETIME: A timeout occurred before the DSP responded. - * -EPERM: A failure occurred in deleting the node. - * -ESPIPE: Delete function not found in the COFF file. - * Requires: - * Ensures: - * 0: hnode is invalid. - */ -extern int node_delete(struct node_res_object *noderes, - struct process_context *pr_ctxt); - -/* - * ======== node_delete_mgr ======== - * Purpose: - * Delete the NODE Manager. - * Parameters: - * hnode_mgr: Node manager object. - * Returns: - * 0: Success. - * Requires: - * Valid hnode_mgr. - * Ensures: - */ -extern int node_delete_mgr(struct node_mgr *hnode_mgr); - -/* - * ======== node_enum_nodes ======== - * Purpose: - * Enumerate the nodes currently allocated for the DSP. - * Parameters: - * hnode_mgr: Node manager returned from node_create_mgr(). - * node_tab: Array to copy node handles into. - * node_tab_size: Number of handles that can be written to node_tab. - * pu_num_nodes: Location where number of node handles written to - * node_tab will be written. - * pu_allocated: Location to write total number of allocated nodes. - * Returns: - * 0: Success. - * -EINVAL: node_tab is too small to hold all node handles. - * Requires: - * Valid hnode_mgr. - * node_tab != NULL || node_tab_size == 0. - * pu_num_nodes != NULL. - * pu_allocated != NULL. - * Ensures: - * - (-EINVAL && *pu_num_nodes == 0) - * - || (0 && *pu_num_nodes <= node_tab_size) && - * (*pu_allocated == *pu_num_nodes) - */ -extern int node_enum_nodes(struct node_mgr *hnode_mgr, - void **node_tab, - u32 node_tab_size, - u32 *pu_num_nodes, - u32 *pu_allocated); - -/* - * ======== node_free_msg_buf ======== - * Purpose: - * Free a message buffer previously allocated with node_alloc_msg_buf. - * Parameters: - * hnode: The node handle. - * pbuffer: (Address) Buffer allocated by node_alloc_msg_buf. - * pattr: Same buffer attributes passed to node_alloc_msg_buf. - * Returns: - * 0: Success. - * -EFAULT: Invalid node handle. - * -EPERM: Failure to free the buffer. - * Requires: - * pbuffer != NULL. - * Ensures: - */ -extern int node_free_msg_buf(struct node_object *hnode, - u8 *pbuffer, - struct dsp_bufferattr - *pattr); - -/* - * ======== node_get_attr ======== - * Purpose: - * Copy the current attributes of the specified node into a dsp_nodeattr - * structure. - * Parameters: - * hnode: Node object allocated from node_allocate(). - * pattr: Pointer to dsp_nodeattr structure to copy node's - * attributes. - * attr_size: Size of pattr. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * Requires: - * pattr != NULL. - * Ensures: - * 0: *pattrs contains the node's current attributes. - */ -extern int node_get_attr(struct node_object *hnode, - struct dsp_nodeattr *pattr, u32 attr_size); - -/* - * ======== node_get_message ======== - * Purpose: - * Retrieve a message from a node on the DSP. The node must be either a - * message node, task node, or XDAIS socket node. - * If a message is not available, this function will block until a - * message is available, or the node's timeout value is reached. - * Parameters: - * hnode: Node handle returned from node_allocate(). - * message: Pointer to dsp_msg structure to copy the - * message into. - * utimeout: Timeout in milliseconds to wait for message. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -EPERM: Cannot retrieve messages from this type of node. - * Error occurred while trying to retrieve a message. - * -ETIME: Timeout occurred and no message is available. - * Requires: - * message != NULL. - * Ensures: - */ -extern int node_get_message(struct node_object *hnode, - struct dsp_msg *message, u32 utimeout); - -/* - * ======== node_get_nldr_obj ======== - * Purpose: - * Retrieve the Nldr manager - * Parameters: - * hnode_mgr: Node Manager - * nldr_ovlyobj: Pointer to a Nldr manager handle - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * Ensures: - */ -extern int node_get_nldr_obj(struct node_mgr *hnode_mgr, - struct nldr_object **nldr_ovlyobj); - -/* - * ======== node_on_exit ======== - * Purpose: - * Gets called when RMS_EXIT is received for a node. PROC needs to pass - * this function as a parameter to msg_create(). This function then gets - * called by the Bridge driver when an exit message for a node is received. - * Parameters: - * hnode: Handle of the node that the exit message is for. - * node_status: Return status of the node's execute phase. - * Returns: - * Ensures: - */ -void node_on_exit(struct node_object *hnode, s32 node_status); - -/* - * ======== node_pause ======== - * Purpose: - * Suspend execution of a node currently running on the DSP. - * Parameters: - * hnode: Node object representing a node currently - * running on the DSP. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -EPERM: Node is not a task or socket node. - * Failed to pause node. - * -ETIME: A timeout occurred before the DSP responded. - * DSP_EWRONGSTSATE: Node is not in NODE_RUNNING state. - * Requires: - * Ensures: - */ -extern int node_pause(struct node_object *hnode); - -/* - * ======== node_put_message ======== - * Purpose: - * Send a message to a message node, task node, or XDAIS socket node. - * This function will block until the message stream can accommodate - * the message, or a timeout occurs. The message will be copied, so Msg - * can be re-used immediately after return. - * Parameters: - * hnode: Node handle returned by node_allocate(). - * pmsg: Location of message to be sent to the node. - * utimeout: Timeout in msecs to wait. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -EPERM: Messages can't be sent to this type of node. - * Unable to send message. - * -ETIME: Timeout occurred before message could be set. - * -EBADR: Node is in invalid state for sending messages. - * Requires: - * pmsg != NULL. - * Ensures: - */ -extern int node_put_message(struct node_object *hnode, - const struct dsp_msg *pmsg, u32 utimeout); - -/* - * ======== node_register_notify ======== - * Purpose: - * Register to be notified on specific events for this node. - * Parameters: - * hnode: Node handle returned by node_allocate(). - * event_mask: Mask of types of events to be notified about. - * notify_type: Type of notification to be sent. - * hnotification: Handle to be used for notification. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -ENOMEM: Insufficient memory on GPP. - * -EINVAL: event_mask is invalid. - * -ENOSYS: Notification type specified by notify_type is not - * supported. - * Requires: - * hnotification != NULL. - * Ensures: - */ -extern int node_register_notify(struct node_object *hnode, - u32 event_mask, u32 notify_type, - struct dsp_notification - *hnotification); - -/* - * ======== node_run ======== - * Purpose: - * Start execution of a node's execute phase, or resume execution of - * a node that has been suspended (via node_pause()) on the DSP. Load - * the node's execute function if necessary. - * Parameters: - * hnode: Node object representing a node currently - * running on the DSP. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -EPERM: hnode doesn't represent a message, task or dais socket node. - * Unable to start or resume execution. - * -ETIME: A timeout occurred before the DSP responded. - * DSP_EWRONGSTSATE: Node is not in NODE_PAUSED or NODE_CREATED state. - * -ESPIPE: Execute function not found in the COFF file. - * Requires: - * Ensures: - */ -extern int node_run(struct node_object *hnode); - -/* - * ======== node_terminate ======== - * Purpose: - * Signal a node running on the DSP that it should exit its execute - * phase function. - * Parameters: - * hnode: Node object representing a node currently - * running on the DSP. - * pstatus: Location to store execute-phase function return - * value. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -ETIME: A timeout occurred before the DSP responded. - * -EPERM: Type of node specified cannot be terminated. - * Unable to terminate the node. - * -EBADR: Operation not valid for the current node state. - * Requires: - * pstatus != NULL. - * Ensures: - */ -extern int node_terminate(struct node_object *hnode, - int *pstatus); - -/* - * ======== node_get_uuid_props ======== - * Purpose: - * Fetch Node properties given the UUID - * Parameters: - * - */ -extern int node_get_uuid_props(void *hprocessor, - const struct dsp_uuid *node_uuid, - struct dsp_ndbprops - *node_props); - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/** - * node_find_addr() - Find the closest symbol to the given address. - * - * @node_mgr: Node manager handle - * @sym_addr: Given address to find the closest symbol - * @offset_range: offset range to look fo the closest symbol - * @sym_addr_output: Symbol Output address - * @sym_name: String with the symbol name of the closest symbol - * - * This function finds the closest symbol to the address where a MMU - * Fault occurred on the DSP side. - */ -int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr, - u32 offset_range, void *sym_addr_output, - char *sym_name); - -enum node_state node_get_state(void *hnode); -#endif - -#endif /* NODE_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h b/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h deleted file mode 100644 index fb9623d8a79..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * nodedefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global NODE constants and types, shared by PROCESSOR, NODE, and DISP. - * - * 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 NODEDEFS_ -#define NODEDEFS_ - -#define NODE_SUSPENDEDPRI -1 - -/* NODE Objects: */ -struct node_mgr; -struct node_object; - -#endif /* NODEDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h b/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h deleted file mode 100644 index d5b54bb81e8..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * nodepriv.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Private node header shared by NODE and DISP. - * - * 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 NODEPRIV_ -#define NODEPRIV_ - -#include <dspbridge/strmdefs.h> -#include <dspbridge/nodedefs.h> -#include <dspbridge/nldrdefs.h> - -/* DSP address of node environment structure */ -typedef u32 nodeenv; - -/* - * Node create structures - */ - -/* Message node */ -struct node_msgargs { - u32 max_msgs; /* Max # of simultaneous messages for node */ - u32 seg_id; /* Segment for allocating message buffers */ - u32 notify_type; /* Notify type (SEM_post, SWI_post, etc.) */ - u32 arg_length; /* Length in 32-bit words of arg data block */ - u8 *pdata; /* Argument data for node */ -}; - -struct node_strmdef { - u32 buf_size; /* Size of buffers for SIO stream */ - u32 num_bufs; /* max # of buffers in SIO stream at once */ - u32 seg_id; /* Memory segment id to allocate buffers */ - u32 timeout; /* Timeout for blocking SIO calls */ - u32 buf_alignment; /* Buffer alignment */ - char *sz_device; /* Device name for stream */ -}; - -/* Task node */ -struct node_taskargs { - struct node_msgargs node_msg_args; - s32 prio; - u32 stack_size; - u32 sys_stack_size; - u32 stack_seg; - u32 dsp_heap_res_addr; /* DSP virtual heap address */ - u32 dsp_heap_addr; /* DSP virtual heap address */ - u32 heap_size; /* Heap size */ - u32 gpp_heap_addr; /* GPP virtual heap address */ - u32 profile_id; /* Profile ID */ - u32 num_inputs; - u32 num_outputs; - u32 dais_arg; /* Address of iAlg object */ - struct node_strmdef *strm_in_def; - struct node_strmdef *strm_out_def; -}; - -/* - * ======== node_createargs ======== - */ -struct node_createargs { - union { - struct node_msgargs node_msg_args; - struct node_taskargs task_arg_obj; - } asa; -}; - -/* - * ======== node_get_channel_id ======== - * Purpose: - * Get the channel index reserved for a stream connection between the - * host and a node. This index is reserved when node_connect() is called - * to connect the node with the host. This index should be passed to - * the CHNL_Open function when the stream is actually opened. - * Parameters: - * hnode: Node object allocated from node_allocate(). - * dir: Input (DSP_TONODE) or output (DSP_FROMNODE). - * index: Stream index. - * chan_id: Location to store channel index. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -EPERM: Not a task or DAIS socket node. - * -EINVAL: The node's stream corresponding to index and dir - * is not a stream to or from the host. - * Requires: - * Valid dir. - * chan_id != NULL. - * Ensures: - */ -extern int node_get_channel_id(struct node_object *hnode, - u32 dir, u32 index, u32 *chan_id); - -/* - * ======== node_get_strm_mgr ======== - * Purpose: - * Get the STRM manager for a node. - * Parameters: - * hnode: Node allocated with node_allocate(). - * strm_man: Location to store STRM manager on output. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * Requires: - * strm_man != NULL. - * Ensures: - */ -extern int node_get_strm_mgr(struct node_object *hnode, - struct strm_mgr **strm_man); - -/* - * ======== node_get_timeout ======== - * Purpose: - * Get the timeout value of a node. - * Parameters: - * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE. - * Returns: - * Node's timeout value. - * Requires: - * Valid hnode. - * Ensures: - */ -extern u32 node_get_timeout(struct node_object *hnode); - -/* - * ======== node_get_type ======== - * Purpose: - * Get the type (device, message, task, or XDAIS socket) of a node. - * Parameters: - * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE. - * Returns: - * Node type: NODE_DEVICE, NODE_TASK, NODE_XDAIS, or NODE_GPP. - * Requires: - * Valid hnode. - * Ensures: - */ -extern enum node_type node_get_type(struct node_object *hnode); - -/* - * ======== get_node_info ======== - * Purpose: - * Get node information without holding semaphore. - * Parameters: - * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE. - * Returns: - * Node info: priority, device owner, no. of streams, execution state - * NDB properties. - * Requires: - * Valid hnode. - * Ensures: - */ -extern void get_node_info(struct node_object *hnode, - struct dsp_nodeinfo *node_info); - -/* - * ======== node_get_load_type ======== - * Purpose: - * Get the load type (dynamic, overlay, static) of a node. - * Parameters: - * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE. - * Returns: - * Node type: NLDR_DYNAMICLOAD, NLDR_OVLYLOAD, NLDR_STATICLOAD - * Requires: - * Valid hnode. - * Ensures: - */ -extern enum nldr_loadtype node_get_load_type(struct node_object *hnode); - -#endif /* NODEPRIV_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/ntfy.h b/drivers/staging/tidspbridge/include/dspbridge/ntfy.h deleted file mode 100644 index 6bb94d20e99..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/ntfy.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * ntfy.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Manage lists of notification events. - * - * 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 NTFY_ -#define NTFY_ - -#include <dspbridge/host_os.h> -#include <dspbridge/dbdefs.h> -#include <dspbridge/sync.h> - -/** - * ntfy_object - head structure to nofify dspbridge events - * @head: List of notify objects - * @ntfy_lock: lock for list access. - * - */ -struct ntfy_object { - struct raw_notifier_head head;/* List of notifier objects */ - spinlock_t ntfy_lock; /* For critical sections */ -}; - -/** - * ntfy_event - structure store specify event to be notified - * @noti_block: List of notify objects - * @event: event that it respond - * @type: event type (only DSP_SIGNALEVENT supported) - * @sync_obj: sync_event used to set the event - * - */ -struct ntfy_event { - struct notifier_block noti_block; - u32 event; /* Events to be notified about */ - u32 type; /* Type of notification to be sent */ - struct sync_object sync_obj; -}; - - -/** - * dsp_notifier_event() - callback function to nofity events - * @this: pointer to itself struct notifier_block - * @event: event to be notified. - * @data: Currently not used. - * - */ -int dsp_notifier_event(struct notifier_block *this, unsigned long event, - void *data); - -/** - * ntfy_init() - Set the initial state of the ntfy_object structure. - * @no: pointer to ntfy_object structure. - * - * This function sets the initial state of the ntfy_object in order it - * can be used by the other ntfy functions. - */ - -static inline void ntfy_init(struct ntfy_object *no) -{ - spin_lock_init(&no->ntfy_lock); - RAW_INIT_NOTIFIER_HEAD(&no->head); -} - -/** - * ntfy_delete() - delete list of nofy events registered. - * @ntfy_obj: Pointer to the ntfy object structure. - * - * This function is used to remove all the notify events registered. - * unregister function is not needed in this function, to unregister - * a ntfy_event please look at ntfy_register function. - * - */ -static inline void ntfy_delete(struct ntfy_object *ntfy_obj) -{ - struct ntfy_event *ne; - struct notifier_block *nb; - - spin_lock_bh(&ntfy_obj->ntfy_lock); - nb = ntfy_obj->head.head; - while (nb) { - ne = container_of(nb, struct ntfy_event, noti_block); - nb = nb->next; - kfree(ne); - } - spin_unlock_bh(&ntfy_obj->ntfy_lock); -} - -/** - * ntfy_notify() - nofity all event register for an specific event. - * @ntfy_obj: Pointer to the ntfy_object structure. - * @event: event to be notified. - * - * This function traverses all the ntfy events registers and - * set the event with mach with @event. - */ -static inline void ntfy_notify(struct ntfy_object *ntfy_obj, u32 event) -{ - spin_lock_bh(&ntfy_obj->ntfy_lock); - raw_notifier_call_chain(&ntfy_obj->head, event, NULL); - spin_unlock_bh(&ntfy_obj->ntfy_lock); -} - - - -/** - * ntfy_init() - Create and initialize a ntfy_event structure. - * @event: event that the ntfy event will respond - * @type event type (only DSP_SIGNALEVENT supported) - * - * This function create a ntfy_event element and sets the event it will - * respond the ntfy_event in order it can be used by the other ntfy functions. - * In case of success it will return a pointer to the ntfy_event struct - * created. Otherwise it will return NULL; - */ - -static inline struct ntfy_event *ntfy_event_create(u32 event, u32 type) -{ - struct ntfy_event *ne; - ne = kmalloc(sizeof(struct ntfy_event), GFP_KERNEL); - if (ne) { - sync_init_event(&ne->sync_obj); - ne->noti_block.notifier_call = dsp_notifier_event; - ne->event = event; - ne->type = type; - } - return ne; -} - -/** - * ntfy_register() - register new ntfy_event into a given ntfy_object - * @ntfy_obj: Pointer to the ntfy_object structure. - * @noti: Pointer to the handle to be returned to the user space. - * @event event that the ntfy event will respond - * @type event type (only DSP_SIGNALEVENT supported) - * - * This function register a new ntfy_event into the ntfy_object list, - * which will respond to the @event passed. - * This function will return 0 in case of error. - * -EFAULT in case of bad pointers and - * DSP_EMemory in case of no memory to create ntfy_event. - */ -static inline int ntfy_register(struct ntfy_object *ntfy_obj, - struct dsp_notification *noti, - u32 event, u32 type) -{ - struct ntfy_event *ne; - int status = 0; - - if (!noti || !ntfy_obj) { - status = -EFAULT; - goto func_end; - } - if (!event) { - status = -EINVAL; - goto func_end; - } - ne = ntfy_event_create(event, type); - if (!ne) { - status = -ENOMEM; - goto func_end; - } - noti->handle = &ne->sync_obj; - - spin_lock_bh(&ntfy_obj->ntfy_lock); - raw_notifier_chain_register(&ntfy_obj->head, &ne->noti_block); - spin_unlock_bh(&ntfy_obj->ntfy_lock); -func_end: - return status; -} - -/** - * ntfy_unregister() - unregister a ntfy_event from a given ntfy_object - * @ntfy_obj: Pointer to the ntfy_object structure. - * @noti: Pointer to the event that will be removed. - * - * This function unregister a ntfy_event from the ntfy_object list, - * @noti contains the event which is wanted to be removed. - * This function will return 0 in case of error. - * -EFAULT in case of bad pointers and - * DSP_EMemory in case of no memory to create ntfy_event. - */ -static inline int ntfy_unregister(struct ntfy_object *ntfy_obj, - struct dsp_notification *noti) -{ - int status = 0; - struct ntfy_event *ne; - - if (!noti || !ntfy_obj) { - status = -EFAULT; - goto func_end; - } - - ne = container_of((struct sync_object *)noti, struct ntfy_event, - sync_obj); - spin_lock_bh(&ntfy_obj->ntfy_lock); - raw_notifier_chain_unregister(&ntfy_obj->head, - &ne->noti_block); - kfree(ne); - spin_unlock_bh(&ntfy_obj->ntfy_lock); -func_end: - return status; -} - -#endif /* NTFY_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h deleted file mode 100644 index 64c2457aae9..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ /dev/null @@ -1,591 +0,0 @@ -/* - * proc.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This is the DSP API RM module interface. - * - * 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 PROC_ -#define PROC_ - -#include <dspbridge/cfgdefs.h> -#include <dspbridge/devdefs.h> -#include <dspbridge/drv.h> - -/* - * ======== proc_attach ======== - * Purpose: - * Prepare for communication with a particular DSP processor, and return - * a handle to the processor object. The PROC Object gets created - * Parameters: - * processor_id : The processor index (zero-based). - * hmgr_obj : Handle to the Manager Object - * attr_in : Ptr to the dsp_processorattrin structure. - * A NULL value means use default values. - * ph_processor : Ptr to location to store processor handle. - * Returns: - * 0 : Success. - * -EPERM : General failure. - * -EFAULT : Invalid processor handle. - * 0: Success; Processor already attached. - * Requires: - * ph_processor != NULL. - * PROC Initialized. - * Ensures: - * -EPERM, and *ph_processor == NULL, OR - * Success and *ph_processor is a Valid Processor handle OR - * 0 and *ph_processor is a Valid Processor. - * Details: - * When attr_in is NULL, the default timeout value is 10 seconds. - */ -extern int proc_attach(u32 processor_id, - const struct dsp_processorattrin - *attr_in, void **ph_processor, - struct process_context *pr_ctxt); - -/* - * ======== proc_auto_start ========= - * Purpose: - * A Particular device gets loaded with the default image - * if the AutoStart flag is set. - * Parameters: - * hdev_obj : Handle to the Device - * Returns: - * 0 : On Successful Loading - * -ENOENT : No DSP exec file found. - * -EPERM : General Failure - * Requires: - * hdev_obj != NULL. - * dev_node_obj != NULL. - * PROC Initialized. - * Ensures: - */ -extern int proc_auto_start(struct cfg_devnode *dev_node_obj, - struct dev_object *hdev_obj); - -/* - * ======== proc_ctrl ======== - * Purpose: - * Pass control information to the GPP device driver managing the DSP - * processor. This will be an OEM-only function, and not part of the - * 'Bridge application developer's API. - * Parameters: - * hprocessor : The processor handle. - * dw_cmd : Private driver IOCTL cmd ID. - * pargs : Ptr to an driver defined argument structure. - * Returns: - * 0 : SUCCESS - * -EFAULT : Invalid processor handle. - * -ETIME: A Timeout Occurred before the Control information - * could be sent. - * -EPERM : General Failure. - * Requires: - * PROC Initialized. - * Ensures - * Details: - * This function Calls bridge_dev_ctrl. - */ -extern int proc_ctrl(void *hprocessor, - u32 dw_cmd, struct dsp_cbdata *arg); - -/* - * ======== proc_detach ======== - * Purpose: - * Close a DSP processor and de-allocate all (GPP) resources reserved - * for it. The Processor Object is deleted. - * Parameters: - * pr_ctxt : The processor handle. - * Returns: - * 0 : Success. - * -EFAULT : InValid Handle. - * -EPERM : General failure. - * Requires: - * PROC Initialized. - * Ensures: - * PROC Object is destroyed. - */ -extern int proc_detach(struct process_context *pr_ctxt); - -/* - * ======== proc_enum_nodes ======== - * Purpose: - * Enumerate the nodes currently allocated on a processor. - * Parameters: - * hprocessor : The processor handle. - * node_tab : The first Location of an array allocated for node - * handles. - * node_tab_size: The number of (DSP_HNODE) handles that can be held - * to the memory the client has allocated for node_tab - * pu_num_nodes : Location where DSPProcessor_EnumNodes will return - * the number of valid handles written to node_tab - * pu_allocated : Location where DSPProcessor_EnumNodes will return - * the number of nodes that are allocated on the DSP. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EINVAL : The amount of memory allocated for node_tab is - * insufficent. That is the number of nodes actually - * allocated on the DSP is greater than the value - * specified for node_tab_size. - * -EPERM : Unable to get Resource Information. - * Details: - * Requires - * pu_num_nodes is not NULL. - * pu_allocated is not NULL. - * node_tab is not NULL. - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_enum_nodes(void *hprocessor, - void **node_tab, - u32 node_tab_size, - u32 *pu_num_nodes, - u32 *pu_allocated); - -/* - * ======== proc_get_resource_info ======== - * Purpose: - * Enumerate the resources currently available on a processor. - * Parameters: - * hprocessor : The processor handle. - * resource_type: Type of resource . - * resource_info: Ptr to the dsp_resourceinfo structure. - * resource_info_size: Size of the structure. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EBADR: The processor is not in the PROC_RUNNING state. - * -ETIME: A timeout occurred before the DSP responded to the - * querry. - * -EPERM : Unable to get Resource Information - * Requires: - * resource_info is not NULL. - * Parameter resource_type is Valid.[TBD] - * resource_info_size is >= sizeof dsp_resourceinfo struct. - * PROC Initialized. - * Ensures: - * Details: - * This function currently returns - * -ENOSYS, and does not write any data to the resource_info struct. - */ -extern int proc_get_resource_info(void *hprocessor, - u32 resource_type, - struct dsp_resourceinfo - *resource_info, - u32 resource_info_size); - -/* - * ======== proc_get_dev_object ========= - * Purpose: - * Returns the DEV Hanlde for a given Processor handle - * Parameters: - * hprocessor : Processor Handle - * device_obj : Location to store the DEV Handle. - * Returns: - * 0 : Success; *device_obj has Dev handle - * -EPERM : Failure; *device_obj is zero. - * Requires: - * device_obj is not NULL - * PROC Initialized. - * Ensures: - * 0 : *device_obj is not NULL - * -EPERM : *device_obj is NULL. - */ -extern int proc_get_dev_object(void *hprocessor, - struct dev_object **device_obj); - -/* - * ======== proc_get_state ======== - * Purpose: - * Report the state of the specified DSP processor. - * Parameters: - * hprocessor : The processor handle. - * proc_state_obj : Ptr to location to store the dsp_processorstate - * structure. - * state_info_size: Size of dsp_processorstate. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure while querying processor state. - * Requires: - * proc_state_obj is not NULL - * state_info_size is >= than the size of dsp_processorstate structure. - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_get_state(void *hprocessor, struct dsp_processorstate - *proc_state_obj, u32 state_info_size); - -/* - * ======== PROC_GetProcessorID ======== - * Purpose: - * Report the state of the specified DSP processor. - * Parameters: - * hprocessor : The processor handle. - * proc_id : Processor ID - * - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure while querying processor state. - * Requires: - * proc_state_obj is not NULL - * state_info_size is >= than the size of dsp_processorstate structure. - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_get_processor_id(void *proc, u32 * proc_id); - -/* - * ======== proc_get_trace ======== - * Purpose: - * Retrieve the trace buffer from the specified DSP processor. - * Parameters: - * hprocessor : The processor handle. - * pbuf : Ptr to buffer to hold trace output. - * max_size : Maximum size of the output buffer. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure while retrieving processor trace - * Buffer. - * Requires: - * pbuf is not NULL - * max_size is > 0. - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_get_trace(void *hprocessor, u8 * pbuf, u32 max_size); - -/* - * ======== proc_load ======== - * Purpose: - * Reset a processor and load a new base program image. - * This will be an OEM-only function. - * Parameters: - * hprocessor: The processor handle. - * argc_index: The number of Arguments(strings)in the aArgV[] - * user_args: An Array of Arguments(Unicode Strings) - * user_envp: An Array of Environment settings(Unicode Strings) - * Returns: - * 0: Success. - * -ENOENT: The DSP Executable was not found. - * -EFAULT: Invalid processor handle. - * -EPERM : Unable to Load the Processor - * Requires: - * user_args is not NULL - * argc_index is > 0 - * PROC Initialized. - * Ensures: - * Success and ProcState == PROC_LOADED - * or DSP_FAILED status. - * Details: - * Does not implement access rights to control which GPP application - * can load the processor. - */ -extern int proc_load(void *hprocessor, - const s32 argc_index, const char **user_args, - const char **user_envp); - -/* - * ======== proc_register_notify ======== - * Purpose: - * Register to be notified of specific processor events - * Parameters: - * hprocessor : The processor handle. - * event_mask : Mask of types of events to be notified about. - * notify_type : Type of notification to be sent. - * hnotification: Handle to be used for notification. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle or hnotification. - * -EINVAL : Parameter event_mask is Invalid - * DSP_ENOTIMP : The notification type specified in uNotifyMask - * is not supported. - * -EPERM : Unable to register for notification. - * Requires: - * hnotification is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_register_notify(void *hprocessor, - u32 event_mask, u32 notify_type, - struct dsp_notification - *hnotification); - -/* - * ======== proc_notify_clients ======== - * Purpose: - * Notify the Processor Clients - * Parameters: - * proc : The processor handle. - * events : Event to be notified about. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : Failure to Set or Reset the Event - * Requires: - * events is Supported or Valid type of Event - * proc is a valid handle - * PROC Initialized. - * Ensures: - */ -extern int proc_notify_clients(void *proc, u32 events); - -/* - * ======== proc_notify_all_clients ======== - * Purpose: - * Notify the Processor Clients - * Parameters: - * proc : The processor handle. - * events : Event to be notified about. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : Failure to Set or Reset the Event - * Requires: - * events is Supported or Valid type of Event - * proc is a valid handle - * PROC Initialized. - * Ensures: - * Details: - * NODE And STRM would use this function to notify their clients - * about the state changes in NODE or STRM. - */ -extern int proc_notify_all_clients(void *proc, u32 events); - -/* - * ======== proc_start ======== - * Purpose: - * Start a processor running. - * Processor must be in PROC_LOADED state. - * This will be an OEM-only function, and not part of the 'Bridge - * application developer's API. - * Parameters: - * hprocessor : The processor handle. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EBADR: Processor is not in PROC_LOADED state. - * -EPERM : Unable to start the processor. - * Requires: - * PROC Initialized. - * Ensures: - * Success and ProcState == PROC_RUNNING or DSP_FAILED status. - * Details: - */ -extern int proc_start(void *hprocessor); - -/* - * ======== proc_stop ======== - * Purpose: - * Start a processor running. - * Processor must be in PROC_LOADED state. - * This will be an OEM-only function, and not part of the 'Bridge - * application developer's API. - * Parameters: - * hprocessor : The processor handle. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EBADR: Processor is not in PROC_LOADED state. - * -EPERM : Unable to start the processor. - * Requires: - * PROC Initialized. - * Ensures: - * Success and ProcState == PROC_RUNNING or DSP_FAILED status. - * Details: - */ -extern int proc_stop(void *hprocessor); - -/* - * ======== proc_end_dma ======== - * Purpose: - * Begin a DMA transfer - * Parameters: - * hprocessor : The processor handle. - * pmpu_addr : Buffer start address - * ul_size : Buffer size - * dir : The direction of the transfer - * Requires: - * Memory was previously mapped. - */ -extern int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, - enum dma_data_direction dir); -/* - * ======== proc_begin_dma ======== - * Purpose: - * Begin a DMA transfer - * Parameters: - * hprocessor : The processor handle. - * pmpu_addr : Buffer start address - * ul_size : Buffer size - * dir : The direction of the transfer - * Requires: - * Memory was previously mapped. - */ -extern int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, - enum dma_data_direction dir); - -/* - * ======== proc_flush_memory ======== - * Purpose: - * Flushes a buffer from the MPU data cache. - * Parameters: - * hprocessor : The processor handle. - * pmpu_addr : Buffer start address - * ul_size : Buffer size - * ul_flags : Reserved. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * Requires: - * PROC Initialized. - * Ensures: - * Details: - * All the arguments are currently ignored. - */ -extern int proc_flush_memory(void *hprocessor, - void *pmpu_addr, u32 ul_size, u32 ul_flags); - -/* - * ======== proc_invalidate_memory ======== - * Purpose: - * Invalidates a buffer from the MPU data cache. - * Parameters: - * hprocessor : The processor handle. - * pmpu_addr : Buffer start address - * ul_size : Buffer size - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * Requires: - * PROC Initialized. - * Ensures: - * Details: - * All the arguments are currently ignored. - */ -extern int proc_invalidate_memory(void *hprocessor, - void *pmpu_addr, u32 ul_size); - -/* - * ======== proc_map ======== - * Purpose: - * Maps a MPU buffer to DSP address space. - * Parameters: - * hprocessor : The processor handle. - * pmpu_addr : Starting address of the memory region to map. - * ul_size : Size of the memory region to map. - * req_addr : Requested DSP start address. Offset-adjusted actual - * mapped address is in the last argument. - * pp_map_addr : Ptr to DSP side mapped u8 address. - * ul_map_attr : Optional endianness attributes, virt to phys flag. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOMEM : MPU side memory allocation error. - * -ENOENT : Cannot find a reserved region starting with this - * : address. - * Requires: - * pmpu_addr is not NULL - * ul_size is not zero - * pp_map_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_map(void *hprocessor, - void *pmpu_addr, - u32 ul_size, - void *req_addr, - void **pp_map_addr, u32 ul_map_attr, - struct process_context *pr_ctxt); - -/* - * ======== proc_reserve_memory ======== - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * ul_size : Size of the address space to reserve. - * pp_rsv_addr : Ptr to DSP side reserved u8 address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOMEM : Cannot reserve chunk of this size. - * Requires: - * pp_rsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_reserve_memory(void *hprocessor, - u32 ul_size, void **pp_rsv_addr, - struct process_context *pr_ctxt); - -/* - * ======== proc_un_map ======== - * Purpose: - * Removes a MPU buffer mapping from the DSP address space. - * Parameters: - * hprocessor : The processor handle. - * map_addr : Starting address of the mapped memory region. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOENT : Cannot find a mapped region starting with this - * : address. - * Requires: - * map_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_un_map(void *hprocessor, void *map_addr, - struct process_context *pr_ctxt); - -/* - * ======== proc_un_reserve_memory ======== - * Purpose: - * Frees a previously reserved region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * prsv_addr : Ptr to DSP side reservedBYTE address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOENT : Cannot find a reserved region starting with this - * : address. - * Requires: - * prsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_un_reserve_memory(void *hprocessor, - void *prsv_addr, - struct process_context *pr_ctxt); - -#endif /* PROC_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/procpriv.h b/drivers/staging/tidspbridge/include/dspbridge/procpriv.h deleted file mode 100644 index 77d1f0ef95c..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/procpriv.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * procpriv.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global PROC constants and types, shared by PROC, MGR and DSP API. - * - * 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 PROCPRIV_ -#define PROCPRIV_ - -/* RM PROC Object */ -struct proc_object; - -#endif /* PROCPRIV_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr.h b/drivers/staging/tidspbridge/include/dspbridge/pwr.h deleted file mode 100644 index 0fb066488da..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/pwr.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * pwr.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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 PWR_ -#define PWR_ - -#include <dspbridge/dbdefs.h> -#include <dspbridge/mbx_sh.h> - -/* valid sleep command codes that can be sent by GPP via mailbox: */ -#define PWR_DEEPSLEEP MBX_PM_DSPIDLE -#define PWR_EMERGENCYDEEPSLEEP MBX_PM_EMERGENCYSLEEP -#define PWR_WAKEUP MBX_PM_DSPWAKEUP - - -/* - * ======== pwr_sleep_dsp ======== - * Signal the DSP to go to sleep. - * - * Parameters: - * sleep_code: New sleep state for DSP. (Initially, valid codes - * are PWR_DEEPSLEEP or PWR_EMERGENCYDEEPSLEEP; both of - * these codes will simply put the DSP in deep sleep.) - * - * timeout: Maximum time (msec) that PWR should wait for - * confirmation that the DSP sleep state has been - * reached. If PWR should simply send the command to - * the DSP to go to sleep and then return (i.e., - * asynchrounous sleep), the timeout should be - * specified as zero. - * - * Returns: - * 0: Success. - * 0: Success, but the DSP was already asleep. - * -EINVAL: The specified sleep_code is not supported. - * -ETIME: A timeout occurred while waiting for DSP sleep - * confirmation. - * -EPERM: General failure, unable to send sleep command to - * the DSP. - */ -extern int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout); - -/* - * ======== pwr_wake_dsp ======== - * Signal the DSP to wake from sleep. - * - * Parameters: - * timeout: Maximum time (msec) that PWR should wait for - * confirmation that the DSP is awake. If PWR should - * simply send a command to the DSP to wake and then - * return (i.e., asynchrounous wake), timeout should - * be specified as zero. - * - * Returns: - * 0: Success. - * 0: Success, but the DSP was already awake. - * -ETIME: A timeout occurred while waiting for wake - * confirmation. - * -EPERM: General failure, unable to send wake command to - * the DSP. - */ -extern int pwr_wake_dsp(const u32 timeout); - -/* - * ======== pwr_pm_pre_scale ======== - * Prescale notification to DSP. - * - * Parameters: - * voltage_domain: The voltage domain for which notification is sent - * level: The level of voltage domain - * - * Returns: - * 0: Success. - * 0: Success, but the DSP was already awake. - * -ETIME: A timeout occurred while waiting for wake - * confirmation. - * -EPERM: General failure, unable to send wake command to - * the DSP. - */ -extern int pwr_pm_pre_scale(u16 voltage_domain, u32 level); - -/* - * ======== pwr_pm_post_scale ======== - * PostScale notification to DSP. - * - * Parameters: - * voltage_domain: The voltage domain for which notification is sent - * level: The level of voltage domain - * - * Returns: - * 0: Success. - * 0: Success, but the DSP was already awake. - * -ETIME: A timeout occurred while waiting for wake - * confirmation. - * -EPERM: General failure, unable to send wake command to - * the DSP. - */ -extern int pwr_pm_post_scale(u16 voltage_domain, u32 level); - -#endif /* PWR_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h deleted file mode 100644 index 8c9c902a043..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * resourcecleanup.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -#include <dspbridge/nodepriv.h> -#include <dspbridge/drv.h> - -extern int drv_remove_all_dmm_res_elements(void *process_ctxt); - -extern int drv_remove_all_node_res_elements(void *process_ctxt); - -extern int drv_remove_all_resources(void *process_ctxt); - -extern int drv_insert_node_res_element(void *hnode, void *node_resource, - void *process_ctxt); - -extern void drv_proc_node_update_heap_status(void *node_resource, s32 status); - -extern void drv_proc_node_update_status(void *node_resource, s32 status); - -extern int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources); - -extern int drv_proc_insert_strm_res_element(void *stream_obj, - void *strm_res, - void *process_ctxt); - -extern int drv_remove_all_strm_res_elements(void *process_ctxt); - -extern enum node_state node_get_state(void *hnode); diff --git a/drivers/staging/tidspbridge/include/dspbridge/rmm.h b/drivers/staging/tidspbridge/include/dspbridge/rmm.h deleted file mode 100644 index f7a4dc8ecb4..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/rmm.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * rmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This memory manager provides general heap management and arbitrary - * alignment for any number of memory segments, and management of overlay - * memory. - * - * 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 RMM_ -#define RMM_ - -/* - * ======== rmm_addr ======== - * DSP address + segid - */ -struct rmm_addr { - u32 addr; - s32 segid; -}; - -/* - * ======== rmm_segment ======== - * Memory segment on the DSP available for remote allocations. - */ -struct rmm_segment { - u32 base; /* Base of the segment */ - u32 length; /* Size of the segment (target MAUs) */ - s32 space; /* Code or data */ - u32 number; /* Number of Allocated Blocks */ -}; - -/* - * ======== RMM_Target ======== - */ -struct rmm_target_obj; - -/* - * ======== rmm_alloc ======== - * - * rmm_alloc is used to remotely allocate or reserve memory on the DSP. - * - * Parameters: - * target - Target returned from rmm_create(). - * segid - Memory segment to allocate from. - * size - Size (target MAUS) to allocate. - * align - alignment. - * dsp_address - If reserve is FALSE, the location to store allocated - * address on output, otherwise, the DSP address to - * reserve. - * reserve - If TRUE, reserve the memory specified by dsp_address. - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation on GPP failed. - * -ENXIO: Cannot "allocate" overlay memory because it's - * already in use. - * Requires: - * RMM initialized. - * Valid target. - * dsp_address != NULL. - * size > 0 - * reserve || target->num_segs > 0. - * Ensures: - */ -extern int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, - u32 align, u32 *dsp_address, bool reserve); - -/* - * ======== rmm_create ======== - * Create a target object with memory segments for remote allocation. If - * seg_tab == NULL or num_segs == 0, memory can only be reserved through - * rmm_alloc(). - * - * Parameters: - * target_obj: - Location to store target on output. - * seg_tab: - Table of memory segments. - * num_segs: - Number of memory segments. - * Returns: - * 0: Success. - * -ENOMEM: Memory allocation failed. - * Requires: - * RMM initialized. - * target_obj != NULL. - * num_segs == 0 || seg_tab != NULL. - * Ensures: - * Success: Valid *target_obj. - * Failure: *target_obj == NULL. - */ -extern int rmm_create(struct rmm_target_obj **target_obj, - struct rmm_segment seg_tab[], u32 num_segs); - -/* - * ======== rmm_delete ======== - * Delete target allocated in rmm_create(). - * - * Parameters: - * target - Target returned from rmm_create(). - * Returns: - * Requires: - * RMM initialized. - * Valid target. - * Ensures: - */ -extern void rmm_delete(struct rmm_target_obj *target); - -/* - * ======== rmm_free ======== - * Free or unreserve memory allocated through rmm_alloc(). - * - * Parameters: - * target: - Target returned from rmm_create(). - * segid: - Segment of memory to free. - * dsp_address: - Address to free or unreserve. - * size: - Size of memory to free or unreserve. - * reserved: - TRUE if memory was reserved only, otherwise FALSE. - * Returns: - * Requires: - * RMM initialized. - * Valid target. - * reserved || segid < target->num_segs. - * reserve || [dsp_address, dsp_address + size] is a valid memory range. - * Ensures: - */ -extern bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, - u32 size, bool reserved); - -/* - * ======== rmm_stat ======== - * Obtain memory segment status - * - * Parameters: - * segid: Segment ID of the dynamic loading segment. - * mem_stat_buf: Pointer to allocated buffer into which memory stats are - * placed. - * Returns: - * TRUE: Success. - * FALSE: Failure. - * Requires: - * segid < target->num_segs - * Ensures: - */ -extern bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid, - struct dsp_memstat *mem_stat_buf); - -#endif /* RMM_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h b/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h deleted file mode 100644 index ba7f4784567..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * rms_sh.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge Resource Manager Server shared definitions (used on both - * GPP and DSP sides). - * - * Copyright (C) 2008 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 RMS_SH_ -#define RMS_SH_ - -#include <dspbridge/rmstypes.h> - -/* Memory Types: */ -#define RMS_CODE 0 /* Program space */ -#define RMS_DATA 1 /* Data space */ - -/* RM Server Command and Response Buffer Sizes: */ -#define RMS_COMMANDBUFSIZE 256 /* Size of command buffer */ - -/* Pre-Defined Command/Response Codes: */ -#define RMS_EXIT 0x80000000 /* GPP->Node: shutdown */ -#define RMS_EXITACK 0x40000000 /* Node->GPP: ack shutdown */ -#define RMS_BUFDESC 0x20000000 /* Arg1 SM buf, Arg2 SM size */ -#define RMS_KILLTASK 0x10000000 /* GPP->Node: Kill Task */ - -/* RM Server RPC Command Structure: */ -struct rms_command { - rms_word fxn; /* Server function address */ - rms_word arg1; /* First argument */ - rms_word arg2; /* Second argument */ - rms_word data; /* Function-specific data array */ -}; - -/* - * The rms_strm_def structure defines the parameters for both input and output - * streams, and is passed to a node's create function. - */ -struct rms_strm_def { - rms_word bufsize; /* Buffer size (in DSP words) */ - rms_word nbufs; /* Max number of bufs in stream */ - rms_word segid; /* Segment to allocate buffers */ - rms_word align; /* Alignment for allocated buffers */ - rms_word timeout; /* Timeout (msec) for blocking calls */ - char name[1]; /* Device Name (terminated by '\0') */ -}; - -/* Message node create args structure: */ -struct rms_msg_args { - rms_word max_msgs; /* Max # simultaneous msgs to node */ - rms_word segid; /* Mem segment for NODE_allocMsgBuf */ - rms_word notify_type; /* Type of message notification */ - rms_word arg_length; /* Length (in DSP chars) of arg data */ - rms_word arg_data; /* Arg data for node */ -}; - -/* Partial task create args structure */ -struct rms_more_task_args { - rms_word priority; /* Task's runtime priority level */ - rms_word stack_size; /* Task's stack size */ - rms_word sysstack_size; /* Task's system stack size (55x) */ - rms_word stack_seg; /* Memory segment for task's stack */ - rms_word heap_addr; /* base address of the node memory heap in - * external memory (DSP virtual address) */ - rms_word heap_size; /* size in MAUs of the node memory heap in - * external memory */ - rms_word misc; /* Misc field. Not used for 'normal' - * task nodes; for xDAIS socket nodes - * specifies the IALG_Fxn pointer. - */ - /* # input STRM definition structures */ - rms_word num_input_streams; -}; - -#endif /* RMS_SH_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h b/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h deleted file mode 100644 index 83c0f1d9619..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * rmstypes.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge Resource Manager Server shared data type definitions. - * - * Copyright (C) 2008 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 RMSTYPES_ -#define RMSTYPES_ -#include <linux/types.h> -typedef u32 rms_word; - -#endif /* RMSTYPES_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/strm.h b/drivers/staging/tidspbridge/include/dspbridge/strm.h deleted file mode 100644 index 97aee4c63d2..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/strm.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - * strm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSPBridge Stream Manager. - * - * 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 STRM_ -#define STRM_ - -#include <dspbridge/dev.h> - -#include <dspbridge/strmdefs.h> -#include <dspbridge/proc.h> - -/* - * ======== strm_allocate_buffer ======== - * Purpose: - * Allocate data buffer(s) for use with a stream. - * Parameter: - * strmres: Stream resource info handle returned from strm_open(). - * usize: Size (GPP bytes) of the buffer(s). - * num_bufs: Number of buffers to allocate. - * ap_buffer: Array to hold buffer addresses. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -ENOMEM: Insufficient memory. - * -EPERM: Failure occurred, unable to allocate buffers. - * -EINVAL: usize must be > 0 bytes. - * Requires: - * ap_buffer != NULL. - * Ensures: - */ -extern int strm_allocate_buffer(struct strm_res_object *strmres, - u32 usize, - u8 **ap_buffer, - u32 num_bufs, - struct process_context *pr_ctxt); - -/* - * ======== strm_close ======== - * Purpose: - * Close a stream opened with strm_open(). - * Parameter: - * strmres: Stream resource info handle returned from strm_open(). - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -EPIPE: Some data buffers issued to the stream have not - * been reclaimed. - * -EPERM: Failure to close stream. - * Requires: - * Ensures: - */ -extern int strm_close(struct strm_res_object *strmres, - struct process_context *pr_ctxt); - -/* - * ======== strm_create ======== - * Purpose: - * Create a STRM manager object. This object holds information about the - * device needed to open streams. - * Parameters: - * strm_man: Location to store handle to STRM manager object on - * output. - * dev_obj: Device for this processor. - * Returns: - * 0: Success; - * -ENOMEM: Insufficient memory for requested resources. - * -EPERM: General failure. - * Requires: - * strm_man != NULL. - * dev_obj != NULL. - * Ensures: - * 0: Valid *strm_man. - * error: *strm_man == NULL. - */ -extern int strm_create(struct strm_mgr **strm_man, - struct dev_object *dev_obj); - -/* - * ======== strm_delete ======== - * Purpose: - * Delete the STRM Object. - * Parameters: - * strm_mgr_obj: Handle to STRM manager object from strm_create. - * Returns: - * Requires: - * Valid strm_mgr_obj. - * Ensures: - * strm_mgr_obj is not valid. - */ -extern void strm_delete(struct strm_mgr *strm_mgr_obj); - -/* - * ======== strm_free_buffer ======== - * Purpose: - * Free buffer(s) allocated with strm_allocate_buffer. - * Parameter: - * strmres: Stream resource info handle returned from strm_open(). - * ap_buffer: Array containing buffer addresses. - * num_bufs: Number of buffers to be freed. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream handle. - * -EPERM: Failure occurred, unable to free buffers. - * Requires: - * ap_buffer != NULL. - * Ensures: - */ -extern int strm_free_buffer(struct strm_res_object *strmres, - u8 **ap_buffer, u32 num_bufs, - struct process_context *pr_ctxt); - -/* - * ======== strm_get_info ======== - * Purpose: - * Get information about a stream. User's dsp_streaminfo is contained - * in stream_info struct. stream_info also contains Bridge private info. - * Parameters: - * stream_obj: Stream handle returned from strm_open(). - * stream_info: Location to store stream info on output. - * uSteamInfoSize: Size of user's dsp_streaminfo structure. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -EINVAL: stream_info_size < sizeof(dsp_streaminfo). - * -EPERM: Unable to get stream info. - * Requires: - * stream_info != NULL. - * Ensures: - */ -extern int strm_get_info(struct strm_object *stream_obj, - struct stream_info *stream_info, - u32 stream_info_size); - -/* - * ======== strm_idle ======== - * Purpose: - * Idle a stream and optionally flush output data buffers. - * If this is an output stream and flush_data is TRUE, all data currently - * enqueued will be discarded. - * If this is an output stream and flush_data is FALSE, this function - * will block until all currently buffered data is output, or the timeout - * specified has been reached. - * After a successful call to strm_idle(), all buffers can immediately - * be reclaimed. - * Parameters: - * stream_obj: Stream handle returned from strm_open(). - * flush_data: If TRUE, discard output buffers. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -ETIME: A timeout occurred before the stream could be idled. - * -EPERM: Unable to idle stream. - * Requires: - * Ensures: - */ -extern int strm_idle(struct strm_object *stream_obj, bool flush_data); - -/* - * ======== strm_issue ======== - * Purpose: - * Send a buffer of data to a stream. - * Parameters: - * stream_obj: Stream handle returned from strm_open(). - * pbuf: Pointer to buffer of data to be sent to the stream. - * ul_bytes: Number of bytes of data in the buffer. - * ul_buf_size: Actual buffer size in bytes. - * dw_arg: A user argument that travels with the buffer. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -ENOSR: The stream is full. - * -EPERM: Failure occurred, unable to issue buffer. - * Requires: -* pbuf != NULL. - * Ensures: - */ -extern int strm_issue(struct strm_object *stream_obj, u8 * pbuf, - u32 ul_bytes, u32 ul_buf_size, u32 dw_arg); - -/* - * ======== strm_open ======== - * Purpose: - * Open a stream for sending/receiving data buffers to/from a task of - * DAIS socket node on the DSP. - * Parameters: - * hnode: Node handle returned from node_allocate(). - * dir: DSP_TONODE or DSP_FROMNODE. - * index: Stream index. - * pattr: Pointer to structure containing attributes to be - * applied to stream. Cannot be NULL. - * strmres: Location to store stream resource info handle on output. - * Returns: - * 0: Success. - * -EFAULT: Invalid hnode. - * -EPERM: Invalid direction. - * hnode is not a task or DAIS socket node. - * Unable to open stream. - * -EINVAL: Invalid index. - * Requires: - * strmres != NULL. - * pattr != NULL. - * Ensures: - * 0: *strmres is valid. - * error: *strmres == NULL. - */ -extern int strm_open(struct node_object *hnode, u32 dir, - u32 index, struct strm_attr *pattr, - struct strm_res_object **strmres, - struct process_context *pr_ctxt); - -/* - * ======== strm_reclaim ======== - * Purpose: - * Request a buffer back from a stream. - * Parameters: - * stream_obj: Stream handle returned from strm_open(). - * buf_ptr: Location to store pointer to reclaimed buffer. - * nbytes: Location where number of bytes of data in the - * buffer will be written. - * buff_size: Location where actual buffer size will be written. - * pdw_arg: Location where user argument that travels with - * the buffer will be written. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -ETIME: A timeout occurred before a buffer could be - * retrieved. - * -EPERM: Failure occurred, unable to reclaim buffer. - * Requires: - * buf_ptr != NULL. - * nbytes != NULL. - * pdw_arg != NULL. - * Ensures: - */ -extern int strm_reclaim(struct strm_object *stream_obj, - u8 **buf_ptr, u32 * nbytes, - u32 *buff_size, u32 *pdw_arg); - -/* - * ======== strm_register_notify ======== - * Purpose: - * Register to be notified on specific events for this stream. - * Parameters: - * stream_obj: Stream handle returned by strm_open(). - * event_mask: Mask of types of events to be notified about. - * notify_type: Type of notification to be sent. - * hnotification: Handle to be used for notification. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -ENOMEM: Insufficient memory on GPP. - * -EINVAL: event_mask is invalid. - * -ENOSYS: Notification type specified by notify_type is not - * supported. - * Requires: - * hnotification != NULL. - * Ensures: - */ -extern int strm_register_notify(struct strm_object *stream_obj, - u32 event_mask, u32 notify_type, - struct dsp_notification - *hnotification); - -/* - * ======== strm_select ======== - * Purpose: - * Select a ready stream. - * Parameters: - * strm_tab: Array of stream handles returned from strm_open(). - * strms: Number of stream handles in array. - * pmask: Location to store mask of ready streams on output. - * utimeout: Timeout value (milliseconds). - * Returns: - * 0: Success. - * -EDOM: strms out of range. - - * -EFAULT: Invalid stream handle in array. - * -ETIME: A timeout occurred before a stream became ready. - * -EPERM: Failure occurred, unable to select a stream. - * Requires: - * strm_tab != NULL. - * strms > 0. - * pmask != NULL. - * Ensures: - * 0: *pmask != 0 || utimeout == 0. - * Error: *pmask == 0. - */ -extern int strm_select(struct strm_object **strm_tab, - u32 strms, u32 *pmask, u32 utimeout); - -#endif /* STRM_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h deleted file mode 100644 index 4f90e6ba69e..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * strmdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global STRM constants and types. - * - * 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 STRMDEFS_ -#define STRMDEFS_ - -struct strm_mgr; - -struct strm_object; - -struct strm_attr { - void *user_event; - char *str_event_name; - void *virt_base; /* Process virtual base address of - * mapped SM */ - u32 virt_size; /* Size of virtual space in bytes */ - struct dsp_streamattrin *stream_attr_in; -}; - -struct stream_info { - enum dsp_strmmode strm_mode; /* transport mode of - * stream(DMA, ZEROCOPY..) */ - u32 segment_id; /* Segment strm allocs from. 0 is local mem */ - void *virt_base; /* " " Stream'process virt base */ - struct dsp_streaminfo *user_strm; /* User's stream information - * returned */ -}; - -#endif /* STRMDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/sync.h b/drivers/staging/tidspbridge/include/dspbridge/sync.h deleted file mode 100644 index fc19b970708..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/sync.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * sync.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Provide synchronization services. - * - * 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 _SYNC_H -#define _SYNC_H - -#include <dspbridge/dbdefs.h> -#include <dspbridge/host_os.h> - - -/* Special timeout value indicating an infinite wait: */ -#define SYNC_INFINITE 0xffffffff - -/** - * struct sync_object - the basic sync_object structure - * @comp: use to signal events - * @multi_comp: use to signal multiple events. - * - */ -struct sync_object{ - struct completion comp; - struct completion *multi_comp; -}; - -/** - * sync_init_event() - set initial state for a sync_event element - * @event: event to be initialized. - * - * Set the initial state for a sync_event element. - */ - -static inline void sync_init_event(struct sync_object *event) -{ - init_completion(&event->comp); - event->multi_comp = NULL; -} - -/** - * sync_reset_event() - reset a sync_event element - * @event: event to be reset. - * - * This function reset to the initial state to @event. - */ - -static inline void sync_reset_event(struct sync_object *event) -{ - reinit_completion(&event->comp); - event->multi_comp = NULL; -} - -/** - * sync_set_event() - set or signal and specified event - * @event: Event to be set.. - * - * set the @event, if there is an thread waiting for the event - * it will be waken up, this function only wakes one thread. - */ - -void sync_set_event(struct sync_object *event); - -/** - * sync_wait_on_event() - waits for a event to be set. - * @event: events to wait for it. - * @timeout timeout on waiting for the evetn. - * - * This function will wait until @event is set or until timeout. In case of - * success the function will return 0 and - * in case of timeout the function will return -ETIME - * in case of signal the function will return -ERESTARTSYS - */ - -static inline int sync_wait_on_event(struct sync_object *event, - unsigned timeout) -{ - int res; - - res = wait_for_completion_interruptible_timeout(&event->comp, - msecs_to_jiffies(timeout)); - if (!res) - res = -ETIME; - else if (res > 0) - res = 0; - - return res; -} - -/** - * sync_wait_on_multiple_events() - waits for multiple events to be set. - * @events: Array of events to wait for them. - * @count: number of elements of the array. - * @timeout timeout on waiting for the evetns. - * @pu_index index of the event set. - * - * This function will wait until any of the array element is set or until - * timeout. In case of success the function will return 0 and - * @pu_index will store the index of the array element set and in case - * of timeout the function will return -ETIME. - */ - -int sync_wait_on_multiple_events(struct sync_object **events, - unsigned count, unsigned timeout, - unsigned *index); - -#endif /* _SYNC_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h b/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h deleted file mode 100644 index b4951a1381e..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * uuidutil.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This file contains the specification of UUID helper functions. - * - * 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 UUIDUTIL_ -#define UUIDUTIL_ - -#define MAXUUIDLEN 37 - -#endif /* UUIDUTIL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/wdt.h b/drivers/staging/tidspbridge/include/dspbridge/wdt.h deleted file mode 100644 index 36193db2e9a..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/wdt.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * wdt.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * IO dispatcher for a shared memory channel driver. - * - * Copyright (C) 2010 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 __DSP_WDT3_H_ -#define __DSP_WDT3_H_ - -/* WDT defines */ -#define OMAP3_WDT3_ISR_OFFSET 0x0018 - - -/** - * struct dsp_wdt_setting - the basic dsp_wdt_setting structure - * @reg_base: pointer to the base of the wdt registers - * @sm_wdt: pointer to flags in shared memory - * @wdt3_tasklet tasklet to manage wdt event - * @fclk handle to wdt3 functional clock - * @iclk handle to wdt3 interface clock - * - * This struct is used in the function to manage wdt3. - */ - -struct dsp_wdt_setting { - void __iomem *reg_base; - struct shm *sm_wdt; - struct tasklet_struct wdt3_tasklet; - struct clk *fclk; - struct clk *iclk; -}; - -/** - * dsp_wdt_init() - initialize wdt3 module. - * - * This function initialize to wdt3 module, so that - * other wdt3 function can be used. - */ -int dsp_wdt_init(void); - -/** - * dsp_wdt_exit() - initialize wdt3 module. - * - * This function frees all resources allocated for wdt3 module. - */ -void dsp_wdt_exit(void); - -/** - * dsp_wdt_enable() - enable/disable wdt3 - * @enable: bool value to enable/disable wdt3 - * - * This function enables or disables wdt3 base on @enable value. - * - */ -void dsp_wdt_enable(bool enable); - -/** - * dsp_wdt_sm_set() - store pointer to the share memory - * @data: pointer to dspbridge share memory - * - * This function is used to pass a valid pointer to share memory, - * so that the flags can be set in order DSP side can read them. - * - */ -void dsp_wdt_sm_set(void *data); - -#endif - diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c deleted file mode 100644 index 4bd8686f235..00000000000 --- a/drivers/staging/tidspbridge/pmgr/chnl.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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. - */ - -#include <linux/types.h> -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#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> - -/* - * ======== 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(struct chnl_mgr **channel_mgr, - struct dev_object *hdev_obj, - const struct chnl_mgrattrs *mgr_attrts) -{ - int status; - struct chnl_mgr *hchnl_mgr; - struct chnl_mgr_ *chnl_mgr_obj = NULL; - - *channel_mgr = NULL; - - /* Validate args: */ - if ((0 < mgr_attrts->max_channels) && - (mgr_attrts->max_channels <= CHNL_MAXCHANNELS)) - status = 0; - else if (mgr_attrts->max_channels == 0) - status = -EINVAL; - else - status = -ECHRNG; - - if (mgr_attrts->word_size == 0) - status = -EINVAL; - - if (!status) { - status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr); - if (!status && hchnl_mgr != NULL) - status = -EEXIST; - - } - - if (!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->chnl_create) (&hchnl_mgr, hdev_obj, - mgr_attrts); - if (!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: */ - *channel_mgr = hchnl_mgr; - } - } - - 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; - - if (chnl_mgr_obj) { - intf_fxns = chnl_mgr_obj->intf_fxns; - /* Let Bridge channel module destroy the chnl_mgr: */ - status = (*intf_fxns->chnl_destroy) (hchnl_mgr); - } else { - status = -EFAULT; - } - - return status; -} diff --git a/drivers/staging/tidspbridge/pmgr/chnlobj.h b/drivers/staging/tidspbridge/pmgr/chnlobj.h deleted file mode 100644 index 6795e0aa8fd..00000000000 --- a/drivers/staging/tidspbridge/pmgr/chnlobj.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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_ */ diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c deleted file mode 100644 index f961e0ec9da..00000000000 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * cmm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Communication(Shared) Memory Management(CMM) module provides - * shared memory management services for DSP/BIOS Bridge data streaming - * and messaging. - * - * Multiple shared memory segments can be registered with CMM. - * Each registered SM segment is represented by a SM "allocator" that - * describes a block of physically contiguous shared memory used for - * future allocations by CMM. - * - * Memory is coalesced back to the appropriate heap when a buffer is - * freed. - * - * Notes: - * Va: Virtual address. - * Pa: Physical or kernel system address. - * - * 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. - */ -#include <linux/types.h> -#include <linux/list.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> -#include <dspbridge/proc.h> - -/* ----------------------------------- This */ -#include <dspbridge/cmm.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define NEXT_PA(pnode) (pnode->pa + pnode->size) - -/* Other bus/platform translations */ -#define DSPPA2GPPPA(base, x, y) ((x)+(y)) -#define GPPPA2DSPPA(base, x, y) ((x)-(y)) - -/* - * Allocators define a block of contiguous memory used for future allocations. - * - * sma - shared memory allocator. - * vma - virtual memory allocator.(not used). - */ -struct cmm_allocator { /* sma */ - unsigned int shm_base; /* Start of physical SM block */ - u32 sm_size; /* Size of SM block in bytes */ - unsigned int vm_base; /* Start of VM block. (Dev driver - * context for 'sma') */ - u32 dsp_phys_addr_offset; /* DSP PA to GPP PA offset for this - * SM space */ - s8 c_factor; /* DSPPa to GPPPa Conversion Factor */ - unsigned int dsp_base; /* DSP virt base byte address */ - u32 dsp_size; /* DSP seg size in bytes */ - struct cmm_object *cmm_mgr; /* back ref to parent mgr */ - /* node list of available memory */ - struct list_head free_list; - /* node list of memory in use */ - struct list_head in_use_list; -}; - -struct cmm_xlator { /* Pa<->Va translator object */ - /* CMM object this translator associated */ - struct cmm_object *cmm_mgr; - /* - * Client process virtual base address that corresponds to phys SM - * base address for translator's seg_id. - * Only 1 segment ID currently supported. - */ - unsigned int virt_base; /* virtual base address */ - u32 virt_size; /* size of virt space in bytes */ - u32 seg_id; /* Segment Id */ -}; - -/* CMM Mgr */ -struct cmm_object { - /* - * Cmm Lock is used to serialize access mem manager for multi-threads. - */ - struct mutex cmm_lock; /* Lock to access cmm mgr */ - struct list_head node_free_list; /* Free list of memory nodes */ - u32 min_block_size; /* Min SM block; default 16 bytes */ - u32 page_size; /* Memory Page size (1k/4k) */ - /* GPP SM segment ptrs */ - struct cmm_allocator *pa_gppsm_seg_tab[CMM_MAXGPPSEGS]; -}; - -/* Default CMM Mgr attributes */ -static struct cmm_mgrattrs cmm_dfltmgrattrs = { - /* min_block_size, min block size(bytes) allocated by cmm mgr */ - 16 -}; - -/* Default allocation attributes */ -static struct cmm_attrs cmm_dfltalctattrs = { - 1 /* seg_id, default segment Id for allocator */ -}; - -/* Address translator default attrs */ -static struct cmm_xlatorattrs cmm_dfltxlatorattrs = { - /* seg_id, does not have to match cmm_dfltalctattrs ul_seg_id */ - 1, - 0, /* dsp_bufs */ - 0, /* dsp_buf_size */ - NULL, /* vm_base */ - 0, /* vm_size */ -}; - -/* SM node representing a block of memory. */ -struct cmm_mnode { - struct list_head link; /* must be 1st element */ - u32 pa; /* Phys addr */ - u32 va; /* Virtual address in device process context */ - u32 size; /* SM block size in bytes */ - u32 client_proc; /* Process that allocated this mem block */ -}; - -/* ----------------------------------- Function Prototypes */ -static void add_to_free_list(struct cmm_allocator *allocator, - struct cmm_mnode *pnode); -static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj, - u32 ul_seg_id); -static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, - u32 usize); -static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, - u32 dw_va, u32 ul_size); -/* get available slot for new allocator */ -static s32 get_slot(struct cmm_object *cmm_mgr_obj); -static void un_register_gppsm_seg(struct cmm_allocator *psma); - -/* - * ======== cmm_calloc_buf ======== - * Purpose: - * Allocate a SM buffer, zero contents, and return the physical address - * and optional driver context virtual address(pp_buf_va). - * - * The freelist is sorted in increasing size order. Get the first - * block that satifies the request and sort the remaining back on - * the freelist; if large enough. The kept block is placed on the - * inUseList. - */ -void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, - struct cmm_attrs *pattrs, void **pp_buf_va) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - void *buf_pa = NULL; - struct cmm_mnode *pnode = NULL; - struct cmm_mnode *new_node = NULL; - struct cmm_allocator *allocator = NULL; - u32 delta_size; - u8 *pbyte = NULL; - s32 cnt; - - if (pattrs == NULL) - pattrs = &cmm_dfltalctattrs; - - if (pp_buf_va != NULL) - *pp_buf_va = NULL; - - if (cmm_mgr_obj && (usize != 0)) { - if (pattrs->seg_id > 0) { - /* SegId > 0 is SM */ - /* get the allocator object for this segment id */ - allocator = - get_allocator(cmm_mgr_obj, pattrs->seg_id); - /* keep block size a multiple of min_block_size */ - usize = - ((usize - 1) & ~(cmm_mgr_obj->min_block_size - - 1)) - + cmm_mgr_obj->min_block_size; - mutex_lock(&cmm_mgr_obj->cmm_lock); - pnode = get_free_block(allocator, usize); - } - if (pnode) { - delta_size = (pnode->size - usize); - if (delta_size >= cmm_mgr_obj->min_block_size) { - /* create a new block with the leftovers and - * add to freelist */ - new_node = - get_node(cmm_mgr_obj, pnode->pa + usize, - pnode->va + usize, - (u32) delta_size); - /* leftovers go free */ - add_to_free_list(allocator, new_node); - /* adjust our node's size */ - pnode->size = usize; - } - /* Tag node with client process requesting allocation - * We'll need to free up a process's alloc'd SM if the - * client process goes away. - */ - /* Return TGID instead of process handle */ - pnode->client_proc = current->tgid; - - /* put our node on InUse list */ - list_add_tail(&pnode->link, &allocator->in_use_list); - buf_pa = (void *)pnode->pa; /* physical address */ - /* clear mem */ - pbyte = (u8 *) pnode->va; - for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++) - *pbyte = 0; - - if (pp_buf_va != NULL) { - /* Virtual address */ - *pp_buf_va = (void *)pnode->va; - } - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - } - return buf_pa; -} - -/* - * ======== cmm_create ======== - * Purpose: - * Create a communication memory manager object. - */ -int cmm_create(struct cmm_object **ph_cmm_mgr, - struct dev_object *hdev_obj, - const struct cmm_mgrattrs *mgr_attrts) -{ - struct cmm_object *cmm_obj = NULL; - int status = 0; - - *ph_cmm_mgr = NULL; - /* create, zero, and tag a cmm mgr object */ - cmm_obj = kzalloc(sizeof(struct cmm_object), GFP_KERNEL); - if (!cmm_obj) - return -ENOMEM; - - if (mgr_attrts == NULL) - mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */ - - /* save away smallest block allocation for this cmm mgr */ - cmm_obj->min_block_size = mgr_attrts->min_block_size; - cmm_obj->page_size = PAGE_SIZE; - - /* create node free list */ - INIT_LIST_HEAD(&cmm_obj->node_free_list); - mutex_init(&cmm_obj->cmm_lock); - *ph_cmm_mgr = cmm_obj; - - return status; -} - -/* - * ======== cmm_destroy ======== - * Purpose: - * Release the communication memory manager resources. - */ -int cmm_destroy(struct cmm_object *hcmm_mgr, bool force) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - struct cmm_info temp_info; - int status = 0; - s32 slot_seg; - struct cmm_mnode *node, *tmp; - - if (!hcmm_mgr) { - status = -EFAULT; - return status; - } - mutex_lock(&cmm_mgr_obj->cmm_lock); - /* If not force then fail if outstanding allocations exist */ - if (!force) { - /* Check for outstanding memory allocations */ - status = cmm_get_info(hcmm_mgr, &temp_info); - if (!status) { - if (temp_info.total_in_use_cnt > 0) { - /* outstanding allocations */ - status = -EPERM; - } - } - } - if (!status) { - /* UnRegister SM allocator */ - for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) { - if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] != NULL) { - un_register_gppsm_seg - (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg]); - /* Set slot to NULL for future reuse */ - cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = NULL; - } - } - } - list_for_each_entry_safe(node, tmp, &cmm_mgr_obj->node_free_list, - link) { - list_del(&node->link); - kfree(node); - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - if (!status) { - /* delete CS & cmm mgr object */ - mutex_destroy(&cmm_mgr_obj->cmm_lock); - kfree(cmm_mgr_obj); - } - return status; -} - -/* - * ======== cmm_free_buf ======== - * Purpose: - * Free the given buffer. - */ -int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - int status = -EFAULT; - struct cmm_mnode *curr, *tmp; - struct cmm_allocator *allocator; - struct cmm_attrs *pattrs; - - if (ul_seg_id == 0) { - pattrs = &cmm_dfltalctattrs; - ul_seg_id = pattrs->seg_id; - } - if (!hcmm_mgr || !(ul_seg_id > 0)) { - status = -EFAULT; - return status; - } - - allocator = get_allocator(cmm_mgr_obj, ul_seg_id); - if (!allocator) - return status; - - mutex_lock(&cmm_mgr_obj->cmm_lock); - list_for_each_entry_safe(curr, tmp, &allocator->in_use_list, link) { - if (curr->pa == (u32) buf_pa) { - list_del(&curr->link); - add_to_free_list(allocator, curr); - status = 0; - break; - } - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - - return status; -} - -/* - * ======== cmm_get_handle ======== - * Purpose: - * Return the communication memory manager object for this device. - * This is typically called from the client process. - */ -int cmm_get_handle(void *hprocessor, struct cmm_object **ph_cmm_mgr) -{ - int status = 0; - struct dev_object *hdev_obj; - - if (hprocessor != NULL) - status = proc_get_dev_object(hprocessor, &hdev_obj); - else - hdev_obj = dev_get_first(); /* default */ - - if (!status) - status = dev_get_cmm_mgr(hdev_obj, ph_cmm_mgr); - - return status; -} - -/* - * ======== cmm_get_info ======== - * Purpose: - * Return the current memory utilization information. - */ -int cmm_get_info(struct cmm_object *hcmm_mgr, - struct cmm_info *cmm_info_obj) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - u32 ul_seg; - int status = 0; - struct cmm_allocator *altr; - struct cmm_mnode *curr; - - if (!hcmm_mgr) { - status = -EFAULT; - return status; - } - mutex_lock(&cmm_mgr_obj->cmm_lock); - cmm_info_obj->num_gppsm_segs = 0; /* # of SM segments */ - /* Total # of outstanding alloc */ - cmm_info_obj->total_in_use_cnt = 0; - /* min block size */ - cmm_info_obj->min_block_size = cmm_mgr_obj->min_block_size; - /* check SM memory segments */ - for (ul_seg = 1; ul_seg <= CMM_MAXGPPSEGS; ul_seg++) { - /* get the allocator object for this segment id */ - altr = get_allocator(cmm_mgr_obj, ul_seg); - if (!altr) - continue; - cmm_info_obj->num_gppsm_segs++; - cmm_info_obj->seg_info[ul_seg - 1].seg_base_pa = - altr->shm_base - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].total_seg_size = - altr->dsp_size + altr->sm_size; - cmm_info_obj->seg_info[ul_seg - 1].gpp_base_pa = - altr->shm_base; - cmm_info_obj->seg_info[ul_seg - 1].gpp_size = - altr->sm_size; - cmm_info_obj->seg_info[ul_seg - 1].dsp_base_va = - altr->dsp_base; - cmm_info_obj->seg_info[ul_seg - 1].dsp_size = - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].seg_base_va = - altr->vm_base - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt = 0; - - list_for_each_entry(curr, &altr->in_use_list, link) { - cmm_info_obj->total_in_use_cnt++; - cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt++; - } - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - return status; -} - -/* - * ======== cmm_register_gppsm_seg ======== - * Purpose: - * Register a block of SM with the CMM to be used for later GPP SM - * allocations. - */ -int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, - u32 dw_gpp_base_pa, u32 ul_size, - u32 dsp_addr_offset, s8 c_factor, - u32 dw_dsp_base, u32 ul_dsp_size, - u32 *sgmt_id, u32 gpp_base_va) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - struct cmm_allocator *psma = NULL; - int status = 0; - struct cmm_mnode *new_node; - s32 slot_seg; - - dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", - __func__, dw_gpp_base_pa, ul_size, dsp_addr_offset, - dw_dsp_base, ul_dsp_size, gpp_base_va); - - if (!hcmm_mgr) - return -EFAULT; - - /* make sure we have room for another allocator */ - mutex_lock(&cmm_mgr_obj->cmm_lock); - - slot_seg = get_slot(cmm_mgr_obj); - if (slot_seg < 0) { - status = -EPERM; - goto func_end; - } - - /* Check if input ul_size is big enough to alloc at least one block */ - if (ul_size < cmm_mgr_obj->min_block_size) { - status = -EINVAL; - goto func_end; - } - - /* create, zero, and tag an SM allocator object */ - psma = kzalloc(sizeof(struct cmm_allocator), GFP_KERNEL); - if (!psma) { - status = -ENOMEM; - goto func_end; - } - - psma->cmm_mgr = hcmm_mgr; /* ref to parent */ - psma->shm_base = dw_gpp_base_pa; /* SM Base phys */ - psma->sm_size = ul_size; /* SM segment size in bytes */ - psma->vm_base = gpp_base_va; - psma->dsp_phys_addr_offset = dsp_addr_offset; - psma->c_factor = c_factor; - psma->dsp_base = dw_dsp_base; - psma->dsp_size = ul_dsp_size; - if (psma->vm_base == 0) { - status = -EPERM; - goto func_end; - } - /* return the actual segment identifier */ - *sgmt_id = (u32) slot_seg + 1; - - INIT_LIST_HEAD(&psma->free_list); - INIT_LIST_HEAD(&psma->in_use_list); - - /* Get a mem node for this hunk-o-memory */ - new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa, - psma->vm_base, ul_size); - /* Place node on the SM allocator's free list */ - if (new_node) { - list_add_tail(&new_node->link, &psma->free_list); - } else { - status = -ENOMEM; - goto func_end; - } - /* make entry */ - cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = psma; - -func_end: - /* Cleanup allocator */ - if (status && psma) - un_register_gppsm_seg(psma); - mutex_unlock(&cmm_mgr_obj->cmm_lock); - - return status; -} - -/* - * ======== cmm_un_register_gppsm_seg ======== - * Purpose: - * UnRegister GPP SM segments with the CMM. - */ -int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr, - u32 ul_seg_id) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - int status = 0; - struct cmm_allocator *psma; - u32 ul_id = ul_seg_id; - - if (!hcmm_mgr) - return -EFAULT; - - if (ul_seg_id == CMM_ALLSEGMENTS) - ul_id = 1; - - if ((ul_id <= 0) || (ul_id > CMM_MAXGPPSEGS)) - return -EINVAL; - - /* - * FIXME: CMM_MAXGPPSEGS == 1. why use a while cycle? Seems to me like - * the ul_seg_id is not needed here. It must be always 1. - */ - while (ul_id <= CMM_MAXGPPSEGS) { - mutex_lock(&cmm_mgr_obj->cmm_lock); - /* slot = seg_id-1 */ - psma = cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1]; - if (psma != NULL) { - un_register_gppsm_seg(psma); - /* Set alctr ptr to NULL for future reuse */ - cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1] = NULL; - } else if (ul_seg_id != CMM_ALLSEGMENTS) { - status = -EPERM; - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - if (ul_seg_id != CMM_ALLSEGMENTS) - break; - - ul_id++; - } /* end while */ - return status; -} - -/* - * ======== un_register_gppsm_seg ======== - * Purpose: - * UnRegister the SM allocator by freeing all its resources and - * nulling cmm mgr table entry. - * Note: - * This routine is always called within cmm lock crit sect. - */ -static void un_register_gppsm_seg(struct cmm_allocator *psma) -{ - struct cmm_mnode *curr, *tmp; - - /* free nodes on free list */ - list_for_each_entry_safe(curr, tmp, &psma->free_list, link) { - list_del(&curr->link); - kfree(curr); - } - - /* free nodes on InUse list */ - list_for_each_entry_safe(curr, tmp, &psma->in_use_list, link) { - list_del(&curr->link); - kfree(curr); - } - - if ((void *)psma->vm_base != NULL) - MEM_UNMAP_LINEAR_ADDRESS((void *)psma->vm_base); - - /* Free allocator itself */ - kfree(psma); -} - -/* - * ======== get_slot ======== - * Purpose: - * An available slot # is returned. Returns negative on failure. - */ -static s32 get_slot(struct cmm_object *cmm_mgr_obj) -{ - s32 slot_seg = -1; /* neg on failure */ - /* get first available slot in cmm mgr SMSegTab[] */ - for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) { - if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] == NULL) - break; - - } - if (slot_seg == CMM_MAXGPPSEGS) - slot_seg = -1; /* failed */ - - return slot_seg; -} - -/* - * ======== get_node ======== - * Purpose: - * Get a memory node from freelist or create a new one. - */ -static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, - u32 dw_va, u32 ul_size) -{ - struct cmm_mnode *pnode; - - /* Check cmm mgr's node freelist */ - if (list_empty(&cmm_mgr_obj->node_free_list)) { - pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL); - if (!pnode) - return NULL; - } else { - /* surely a valid element */ - pnode = list_first_entry(&cmm_mgr_obj->node_free_list, - struct cmm_mnode, link); - list_del_init(&pnode->link); - } - - pnode->pa = dw_pa; - pnode->va = dw_va; - pnode->size = ul_size; - - return pnode; -} - -/* - * ======== delete_node ======== - * Purpose: - * Put a memory node on the cmm nodelist for later use. - * Doesn't actually delete the node. Heap thrashing friendly. - */ -static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode) -{ - list_add_tail(&pnode->link, &cmm_mgr_obj->node_free_list); -} - -/* - * ====== get_free_block ======== - * Purpose: - * Scan the free block list and return the first block that satisfies - * the size. - */ -static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, - u32 usize) -{ - struct cmm_mnode *node, *tmp; - - if (!allocator) - return NULL; - - list_for_each_entry_safe(node, tmp, &allocator->free_list, link) { - if (usize <= node->size) { - list_del(&node->link); - return node; - } - } - - return NULL; -} - -/* - * ======== add_to_free_list ======== - * Purpose: - * Coalesce node into the freelist in ascending size order. - */ -static void add_to_free_list(struct cmm_allocator *allocator, - struct cmm_mnode *node) -{ - struct cmm_mnode *curr; - - if (!node) { - pr_err("%s: failed - node is NULL\n", __func__); - return; - } - - list_for_each_entry(curr, &allocator->free_list, link) { - if (NEXT_PA(curr) == node->pa) { - curr->size += node->size; - delete_node(allocator->cmm_mgr, node); - return; - } - if (curr->pa == NEXT_PA(node)) { - curr->pa = node->pa; - curr->va = node->va; - curr->size += node->size; - delete_node(allocator->cmm_mgr, node); - return; - } - } - list_for_each_entry(curr, &allocator->free_list, link) { - if (curr->size >= node->size) { - list_add_tail(&node->link, &curr->link); - return; - } - } - list_add_tail(&node->link, &allocator->free_list); -} - -/* - * ======== get_allocator ======== - * Purpose: - * Return the allocator for the given SM Segid. - * SegIds: 1,2,3..max. - */ -static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj, - u32 ul_seg_id) -{ - return cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1]; -} - -/* - * The CMM_Xlator[xxx] routines below are used by Node and Stream - * to perform SM address translation to the client process address space. - * A "translator" object is created by a node/stream for each SM seg used. - */ - -/* - * ======== cmm_xlator_create ======== - * Purpose: - * Create an address translator object. - */ -int cmm_xlator_create(struct cmm_xlatorobject **xlator, - struct cmm_object *hcmm_mgr, - struct cmm_xlatorattrs *xlator_attrs) -{ - struct cmm_xlator *xlator_object = NULL; - int status = 0; - - *xlator = NULL; - if (xlator_attrs == NULL) - xlator_attrs = &cmm_dfltxlatorattrs; /* set defaults */ - - xlator_object = kzalloc(sizeof(struct cmm_xlator), GFP_KERNEL); - if (xlator_object != NULL) { - xlator_object->cmm_mgr = hcmm_mgr; /* ref back to CMM */ - /* SM seg_id */ - xlator_object->seg_id = xlator_attrs->seg_id; - } else { - status = -ENOMEM; - } - if (!status) - *xlator = (struct cmm_xlatorobject *)xlator_object; - - return status; -} - -/* - * ======== cmm_xlator_alloc_buf ======== - */ -void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *va_buf, - u32 pa_size) -{ - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - void *pbuf = NULL; - void *tmp_va_buff; - struct cmm_attrs attrs; - - if (xlator_obj) { - attrs.seg_id = xlator_obj->seg_id; - __raw_writel(0, va_buf); - /* Alloc SM */ - pbuf = - cmm_calloc_buf(xlator_obj->cmm_mgr, pa_size, &attrs, NULL); - if (pbuf) { - /* convert to translator(node/strm) process Virtual - * address */ - tmp_va_buff = cmm_xlator_translate(xlator, - pbuf, CMM_PA2VA); - __raw_writel((u32)tmp_va_buff, va_buf); - } - } - return pbuf; -} - -/* - * ======== cmm_xlator_free_buf ======== - * Purpose: - * Free the given SM buffer and descriptor. - * Does not free virtual memory. - */ -int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va) -{ - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - int status = -EPERM; - void *buf_pa = NULL; - - if (xlator_obj) { - /* convert Va to Pa so we can free it. */ - buf_pa = cmm_xlator_translate(xlator, buf_va, CMM_VA2PA); - if (buf_pa) { - status = cmm_free_buf(xlator_obj->cmm_mgr, buf_pa, - xlator_obj->seg_id); - if (status) { - /* Uh oh, this shouldn't happen. Descriptor - * gone! */ - pr_err("%s, line %d: Assertion failed\n", - __FILE__, __LINE__); - } - } - } - return status; -} - -/* - * ======== cmm_xlator_info ======== - * Purpose: - * Set/Get translator info. - */ -int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 **paddr, - u32 ul_size, u32 segm_id, bool set_info) -{ - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - int status = 0; - - if (xlator_obj) { - if (set_info) { - /* set translators virtual address range */ - xlator_obj->virt_base = (u32) *paddr; - xlator_obj->virt_size = ul_size; - } else { /* return virt base address */ - *paddr = (u8 *) xlator_obj->virt_base; - } - } else { - status = -EFAULT; - } - return status; -} - -/* - * ======== cmm_xlator_translate ======== - */ -void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, - enum cmm_xlatetype xtype) -{ - u32 dw_addr_xlate = 0; - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - struct cmm_object *cmm_mgr_obj = NULL; - struct cmm_allocator *allocator = NULL; - u32 dw_offset = 0; - - if (!xlator_obj) - goto loop_cont; - - cmm_mgr_obj = (struct cmm_object *)xlator_obj->cmm_mgr; - /* get this translator's default SM allocator */ - allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->seg_id - 1]; - if (!allocator) - goto loop_cont; - - if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_VA2PA) || - (xtype == CMM_PA2VA)) { - if (xtype == CMM_PA2VA) { - /* Gpp Va = Va Base + offset */ - dw_offset = (u8 *) paddr - (u8 *) (allocator->shm_base - - allocator-> - dsp_size); - dw_addr_xlate = xlator_obj->virt_base + dw_offset; - /* Check if translated Va base is in range */ - if ((dw_addr_xlate < xlator_obj->virt_base) || - (dw_addr_xlate >= - (xlator_obj->virt_base + - xlator_obj->virt_size))) { - dw_addr_xlate = 0; /* bad address */ - } - } else { - /* Gpp PA = Gpp Base + offset */ - dw_offset = - (u8 *) paddr - (u8 *) xlator_obj->virt_base; - dw_addr_xlate = - allocator->shm_base - allocator->dsp_size + - dw_offset; - } - } else { - dw_addr_xlate = (u32) paddr; - } - /*Now convert address to proper target physical address if needed */ - if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_PA2DSPPA)) { - /* Got Gpp Pa now, convert to DSP Pa */ - dw_addr_xlate = - GPPPA2DSPPA((allocator->shm_base - allocator->dsp_size), - dw_addr_xlate, - allocator->dsp_phys_addr_offset * - allocator->c_factor); - } else if (xtype == CMM_DSPPA2PA) { - /* Got DSP Pa, convert to GPP Pa */ - dw_addr_xlate = - DSPPA2GPPPA(allocator->shm_base - allocator->dsp_size, - dw_addr_xlate, - allocator->dsp_phys_addr_offset * - allocator->c_factor); - } -loop_cont: - return (void *)dw_addr_xlate; -} diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c deleted file mode 100644 index 6c29379baf6..00000000000 --- a/drivers/staging/tidspbridge/pmgr/cod.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * 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. - */ - -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> -#include <linux/fs.h> -#include <linux/uaccess.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -/* Include appropriate loader header file */ -#include <dspbridge/dbll.h> - -/* ----------------------------------- This */ -#include <dspbridge/cod.h> - -/* - * ======== cod_manager ======== - */ -struct cod_manager { - struct dbll_tar_obj *target; - struct dbll_library_obj *base_lib; - bool loaded; /* Base library loaded? */ - u32 entry; - struct dbll_fxns fxns; - struct dbll_attrs attrs; - char sz_zl_file[COD_MAXPATHLENGTH]; -}; - -/* - * ======== cod_libraryobj ======== - */ -struct cod_libraryobj { - struct dbll_library_obj *dbll_lib; - struct cod_manager *cod_mgr; -}; - -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_open_fxn) dbll_open, - (dbll_read_sect_fxn) dbll_read_sect, - (dbll_unload_fxn) dbll_unload, -}; - -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 *sz_mode) -{ - 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 count, - struct file *filp) -{ - /* check for valid file handle */ - if (!filp) - return -EFAULT; - - if ((size > 0) && (count > 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 * count, - &(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 offset, s32 origin) -{ - 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, offset, origin); - - 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; - - 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(struct cod_manager **mgr, char *str_zl_file) -{ - struct cod_manager *mgr_new; - struct dbll_attrs zl_attrs; - int status = 0; - - /* assume failure */ - *mgr = NULL; - - mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL); - if (mgr_new == NULL) - return -ENOMEM; - - /* 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 (status) { - cod_delete(mgr_new); - return -ESPIPE; - } - - /* return the new manager */ - *mgr = mgr_new; - - return 0; -} - -/* - * ======== cod_delete ======== - * Purpose: - * Delete a code manager object. - */ -void cod_delete(struct cod_manager *cod_mgr_obj) -{ - if (cod_mgr_obj->base_lib) { - if (cod_mgr_obj->loaded) - cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib, - &cod_mgr_obj->attrs); - - cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib); - } - if (cod_mgr_obj->target) { - cod_mgr_obj->fxns.delete_fxn(cod_mgr_obj->target); - cod_mgr_obj->fxns.exit_fxn(); - } - kfree(cod_mgr_obj); -} - -/* - * ======== 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; - - *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 *sz_name, - u32 usize) -{ - int status = 0; - - if (usize <= COD_MAXPATHLENGTH) - strlcpy(sz_name, 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 *entry_pt) -{ - *entry_pt = cod_mgr_obj->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 **loader) -{ - int status = 0; - - *loader = (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, char *str_sect, - u32 *addr, u32 *len) -{ - struct cod_manager *cod_mgr_obj; - int status = 0; - - *addr = 0; - *len = 0; - if (lib != NULL) { - cod_mgr_obj = lib->cod_mgr; - status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, str_sect, - addr, len); - } else { - status = -ESPIPE; - } - - 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 *cod_mgr_obj, char *str_sym, - u32 *pul_value) -{ - struct dbll_sym_val *dbll_sym; - - dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n", - __func__, cod_mgr_obj, str_sym, pul_value); - if (cod_mgr_obj->base_lib) { - if (!cod_mgr_obj->fxns. - get_addr_fxn(cod_mgr_obj->base_lib, str_sym, &dbll_sym)) { - if (!cod_mgr_obj->fxns. - get_c_addr_fxn(cod_mgr_obj->base_lib, str_sym, - &dbll_sym)) - return -ESPIPE; - } - } else { - return -ESPIPE; - } - - *pul_value = dbll_sym->value; - - return 0; -} - -/* - * ======== 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 num_argc doesn't match the number of arguments in the args array, the - * args array is searched for a NULL terminating entry, and argc is - * recalculated to reflect this. In this way, we can support NULL - * terminating args arrays, if num_argc is very large. - */ -int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[], - cod_writefxn pfn_write, void *arb, char *envp[]) -{ - dbll_flags flags; - struct dbll_attrs save_attrs; - struct dbll_attrs new_attrs; - int status; - u32 i; - - /* - * 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 < num_argc; i++) { - if (args[i] == NULL) { - num_argc = i; - break; - } - } - - /* set the write function for this operation */ - cod_mgr_obj->fxns.get_attrs_fxn(cod_mgr_obj->target, &save_attrs); - - new_attrs = save_attrs; - new_attrs.write = (dbll_write_fxn) pfn_write; - new_attrs.input_params = arb; - 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 = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags, - &new_attrs, - &cod_mgr_obj->entry); - if (status) - cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib); - - if (!status) - cod_mgr_obj->loaded = true; - else - cod_mgr_obj->base_lib = NULL; - - return status; -} - -/* - * ======== cod_open ======== - * Open library for reading sections. - */ -int cod_open(struct cod_manager *hmgr, char *sz_coff_path, - u32 flags, struct cod_libraryobj **lib_obj) -{ - int status = 0; - struct cod_libraryobj *lib = NULL; - - *lib_obj = NULL; - - lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL); - if (lib == NULL) - status = -ENOMEM; - - if (!status) { - lib->cod_mgr = hmgr; - status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, - &lib->dbll_lib); - if (!status) - *lib_obj = lib; - } - - if (status) - pr_err("%s: error status 0x%x, sz_coff_path: %s flags: 0x%x\n", - __func__, status, sz_coff_path, flags); - return status; -} - -/* - * ======== cod_open_base ======== - * Purpose: - * Open base image for reading sections. - */ -int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path, - dbll_flags flags) -{ - int status = 0; - struct dbll_library_obj *lib; - - /* 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, sz_coff_path, flags, &lib); - if (!status) { - /* hang onto the library for subsequent sym table usage */ - hmgr->base_lib = lib; - strncpy(hmgr->sz_zl_file, sz_coff_path, COD_MAXPATHLENGTH - 1); - hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0'; - } - - if (status) - pr_err("%s: error status 0x%x sz_coff_path: %s\n", __func__, - status, sz_coff_path); - 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, char *str_sect, - char *str_content, u32 content_size) -{ - int status = 0; - - if (lib != NULL) - status = - lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect, - str_content, content_size); - else - status = -ESPIPE; - - return status; -} - -/* - * ======== no_op ======== - * Purpose: - * No Operation. - * - */ -static bool no_op(void) -{ - return true; -} diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c deleted file mode 100644 index 8e21d1e47c9..00000000000 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ /dev/null @@ -1,1421 +0,0 @@ -/* - * dbll.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -#include <dspbridge/gh.h> - -/* ----------------------------------- OS Adaptation Layer */ - -/* Dynamic loader library interface */ -#include <dspbridge/dynamic_loader.h> -#include <dspbridge/getsection.h> - -/* ----------------------------------- This */ -#include <dspbridge/dbll.h> -#include <dspbridge/rmm.h> - -/* Max buffer length */ -#define MAXEXPR 128 - -#define DOFF_ALIGN(x) (((x) + 3) & ~3UL) - -/* - * ======== struct dbll_tar_obj* ======== - * A target may have one or more libraries of symbols/code/data loaded - * onto it, where a library is simply the symbols/code/data contained - * in a DOFF file. - */ -/* - * ======== dbll_tar_obj ======== - */ -struct dbll_tar_obj { - struct dbll_attrs attrs; - struct dbll_library_obj *head; /* List of all opened libraries */ -}; - -/* - * The following 4 typedefs are "super classes" of the dynamic loader - * library types used in dynamic loader functions (dynamic_loader.h). - */ -/* - * ======== dbll_stream ======== - * Contains dynamic_loader_stream - */ -struct dbll_stream { - struct dynamic_loader_stream dl_stream; - struct dbll_library_obj *lib; -}; - -/* - * ======== ldr_symbol ======== - */ -struct ldr_symbol { - struct dynamic_loader_sym dl_symbol; - struct dbll_library_obj *lib; -}; - -/* - * ======== dbll_alloc ======== - */ -struct dbll_alloc { - struct dynamic_loader_allocate dl_alloc; - struct dbll_library_obj *lib; -}; - -/* - * ======== dbll_init_obj ======== - */ -struct dbll_init_obj { - struct dynamic_loader_initialize dl_init; - struct dbll_library_obj *lib; -}; - -/* - * ======== DBLL_Library ======== - * A library handle is returned by DBLL_Open() and is passed to dbll_load() - * to load symbols/code/data, and to dbll_unload(), to remove the - * symbols/code/data loaded by dbll_load(). - */ - -/* - * ======== dbll_library_obj ======== - */ -struct dbll_library_obj { - struct dbll_library_obj *next; /* Next library in target's list */ - struct dbll_library_obj *prev; /* Previous in the list */ - struct dbll_tar_obj *target_obj; /* target for this library */ - - /* Objects needed by dynamic loader */ - struct dbll_stream stream; - struct ldr_symbol symbol; - struct dbll_alloc allocate; - struct dbll_init_obj init; - void *dload_mod_obj; - - char *file_name; /* COFF file name */ - void *fp; /* Opaque file handle */ - u32 entry; /* Entry point */ - void *desc; /* desc of DOFF file loaded */ - u32 open_ref; /* Number of times opened */ - u32 load_ref; /* Number of times loaded */ - struct gh_t_hash_tab *sym_tab; /* Hash table of symbols */ - u32 pos; -}; - -/* - * ======== dbll_symbol ======== - */ -struct dbll_symbol { - struct dbll_sym_val value; - char *name; -}; - -static void dof_close(struct dbll_library_obj *zl_lib); -static int dof_open(struct dbll_library_obj *zl_lib); -static s32 no_op(struct dynamic_loader_initialize *thisptr, void *bufr, - ldr_addr locn, struct ldr_section_info *info, - unsigned bytsize); - -/* - * Functions called by dynamic loader - * - */ -/* dynamic_loader_stream */ -static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer, - unsigned bufsize); -static int dbll_set_file_posn(struct dynamic_loader_stream *this, - unsigned int pos); -/* dynamic_loader_sym */ -static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this, - const char *name); -static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned module_id); -static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned moduleid); -static void dbll_purge_symbol_table(struct dynamic_loader_sym *this, - unsigned module_id); -static void *allocate(struct dynamic_loader_sym *this, unsigned memsize); -static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr); -static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr, - va_list args); -/* dynamic_loader_allocate */ -static int dbll_rmm_alloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info, unsigned align); -static void rmm_dealloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info); - -/* dynamic_loader_initialize */ -static int connect(struct dynamic_loader_initialize *this); -static int read_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned bytes); -static int write_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned nbytes); -static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr, - struct ldr_section_info *info, unsigned bytes, - unsigned val); -static int execute(struct dynamic_loader_initialize *this, ldr_addr start); -static void release(struct dynamic_loader_initialize *this); - -/* symbol table hash functions */ -static u32 name_hash(const void *key); -static bool name_match(const void *key, const void *sp); -static void sym_delete(void *value); - -/* Symbol Redefinition */ -static int redefined_symbol; -static int gbl_search = 1; - -/* - * ======== dbll_close ======== - */ -void dbll_close(struct dbll_library_obj *zl_lib) -{ - struct dbll_tar_obj *zl_target; - - zl_target = zl_lib->target_obj; - zl_lib->open_ref--; - if (zl_lib->open_ref == 0) { - /* Remove library from list */ - if (zl_target->head == zl_lib) - zl_target->head = zl_lib->next; - - if (zl_lib->prev) - (zl_lib->prev)->next = zl_lib->next; - - if (zl_lib->next) - (zl_lib->next)->prev = zl_lib->prev; - - /* Free DOF resources */ - dof_close(zl_lib); - kfree(zl_lib->file_name); - - /* remove symbols from symbol table */ - if (zl_lib->sym_tab) - gh_delete(zl_lib->sym_tab); - - /* remove the library object itself */ - kfree(zl_lib); - zl_lib = NULL; - } -} - -/* - * ======== dbll_create ======== - */ -int dbll_create(struct dbll_tar_obj **target_obj, - struct dbll_attrs *pattrs) -{ - struct dbll_tar_obj *pzl_target; - int status = 0; - - /* Allocate DBL target object */ - pzl_target = kzalloc(sizeof(struct dbll_tar_obj), GFP_KERNEL); - if (target_obj != NULL) { - if (pzl_target == NULL) { - *target_obj = NULL; - status = -ENOMEM; - } else { - pzl_target->attrs = *pattrs; - *target_obj = (struct dbll_tar_obj *)pzl_target; - } - } - - return status; -} - -/* - * ======== dbll_delete ======== - */ -void dbll_delete(struct dbll_tar_obj *target) -{ - struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - - kfree(zl_target); - -} - -/* - * ======== dbll_exit ======== - * Discontinue usage of DBL module. - */ -void dbll_exit(void) -{ - /* do nothing */ -} - -/* - * ======== dbll_get_addr ======== - * Get address of name in the specified library. - */ -bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name, - struct dbll_sym_val **sym_val) -{ - struct dbll_symbol *sym; - - sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, name); - if (IS_ERR(sym)) - return false; - - *sym_val = &sym->value; - - dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p\n", - __func__, zl_lib, name, sym_val); - return true; -} - -/* - * ======== dbll_get_attrs ======== - * Retrieve the attributes of the target. - */ -void dbll_get_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs) -{ - struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - - if ((pattrs != NULL) && (zl_target != NULL)) - *pattrs = zl_target->attrs; - -} - -/* - * ======== dbll_get_c_addr ======== - * Get address of a "C" name in the specified library. - */ -bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name, - struct dbll_sym_val **sym_val) -{ - struct dbll_symbol *sym; - char cname[MAXEXPR + 1]; - - cname[0] = '_'; - - strncpy(cname + 1, name, sizeof(cname) - 2); - cname[MAXEXPR] = '\0'; /* insure '\0' string termination */ - - /* Check for C name, if not found */ - sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, cname); - if (IS_ERR(sym)) - return false; - - *sym_val = &sym->value; - - return true; -} - -/* - * ======== dbll_get_sect ======== - * Get the base address and size (in bytes) of a COFF section. - */ -int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr, - u32 *psize) -{ - u32 byte_size; - bool opened_doff = false; - const struct ldr_section_info *sect = NULL; - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - int status = 0; - - /* If DOFF file is not open, we open it. */ - if (zl_lib != NULL) { - if (zl_lib->fp == NULL) { - status = dof_open(zl_lib); - if (!status) - opened_doff = true; - - } else { - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - zl_lib->pos, - SEEK_SET); - } - } else { - status = -EFAULT; - } - if (!status) { - byte_size = 1; - if (dload_get_section_info(zl_lib->desc, name, §)) { - *paddr = sect->load_addr; - *psize = sect->size * byte_size; - /* Make sure size is even for good swap */ - if (*psize % 2) - (*psize)++; - - /* Align size */ - *psize = DOFF_ALIGN(*psize); - } else { - status = -ENXIO; - } - } - if (opened_doff) { - dof_close(zl_lib); - opened_doff = false; - } - - dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, status 0x%x\n", - __func__, lib, name, paddr, psize, status); - - return status; -} - -/* - * ======== dbll_init ======== - */ -bool dbll_init(void) -{ - /* do nothing */ - - return true; -} - -/* - * ======== dbll_load ======== - */ -int dbll_load(struct dbll_library_obj *lib, dbll_flags flags, - struct dbll_attrs *attrs, u32 *entry) -{ - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - struct dbll_tar_obj *dbzl; - bool got_symbols = true; - s32 err; - int status = 0; - bool opened_doff = false; - - /* - * Load if not already loaded. - */ - if (zl_lib->load_ref == 0 || !(flags & DBLL_DYNAMIC)) { - dbzl = zl_lib->target_obj; - dbzl->attrs = *attrs; - /* Create a hash table for symbols if not already created */ - if (zl_lib->sym_tab == NULL) { - got_symbols = false; - zl_lib->sym_tab = gh_create(sizeof(struct dbll_symbol), - name_hash, - name_match, sym_delete); - if (IS_ERR(zl_lib->sym_tab)) { - status = PTR_ERR(zl_lib->sym_tab); - zl_lib->sym_tab = NULL; - } - - } - /* - * Set up objects needed by the dynamic loader - */ - /* Stream */ - zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer; - zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn; - zl_lib->stream.lib = zl_lib; - /* Symbol */ - zl_lib->symbol.dl_symbol.find_matching_symbol = - dbll_find_symbol; - if (got_symbols) { - zl_lib->symbol.dl_symbol.add_to_symbol_table = - find_in_symbol_table; - } else { - zl_lib->symbol.dl_symbol.add_to_symbol_table = - dbll_add_to_symbol_table; - } - zl_lib->symbol.dl_symbol.purge_symbol_table = - dbll_purge_symbol_table; - zl_lib->symbol.dl_symbol.dload_allocate = allocate; - zl_lib->symbol.dl_symbol.dload_deallocate = deallocate; - zl_lib->symbol.dl_symbol.error_report = dbll_err_report; - zl_lib->symbol.lib = zl_lib; - /* Allocate */ - zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc; - zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc; - zl_lib->allocate.lib = zl_lib; - /* Init */ - zl_lib->init.dl_init.connect = connect; - zl_lib->init.dl_init.readmem = read_mem; - zl_lib->init.dl_init.writemem = write_mem; - zl_lib->init.dl_init.fillmem = fill_mem; - zl_lib->init.dl_init.execute = execute; - zl_lib->init.dl_init.release = release; - zl_lib->init.lib = zl_lib; - /* If COFF file is not open, we open it. */ - if (zl_lib->fp == NULL) { - status = dof_open(zl_lib); - if (!status) - opened_doff = true; - - } - if (!status) { - zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) - (zl_lib->fp); - /* Reset file cursor */ - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - (long)0, - SEEK_SET); - symbols_reloaded = true; - /* The 5th argument, DLOAD_INITBSS, tells the DLL - * module to zero-init all BSS sections. In general, - * this is not necessary and also increases load time. - * We may want to make this configurable by the user */ - err = dynamic_load_module(&zl_lib->stream.dl_stream, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init, - DLOAD_INITBSS, - &zl_lib->dload_mod_obj); - - if (err != 0) { - status = -EILSEQ; - } else if (redefined_symbol) { - zl_lib->load_ref++; - dbll_unload(zl_lib, (struct dbll_attrs *)attrs); - redefined_symbol = false; - status = -EILSEQ; - } else { - *entry = zl_lib->entry; - } - } - } - if (!status) - zl_lib->load_ref++; - - /* Clean up DOFF resources */ - if (opened_doff) - dof_close(zl_lib); - - dev_dbg(bridge, "%s: lib: %p flags: 0x%x entry: %p, status 0x%x\n", - __func__, lib, flags, entry, status); - - return status; -} - -/* - * ======== dbll_open ======== - */ -int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags, - struct dbll_library_obj **lib_obj) -{ - struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - struct dbll_library_obj *zl_lib = NULL; - s32 err; - int status = 0; - - zl_lib = zl_target->head; - while (zl_lib != NULL) { - if (strcmp(zl_lib->file_name, file) == 0) { - /* Library is already opened */ - zl_lib->open_ref++; - break; - } - zl_lib = zl_lib->next; - } - if (zl_lib == NULL) { - /* Allocate DBL library object */ - zl_lib = kzalloc(sizeof(struct dbll_library_obj), GFP_KERNEL); - if (zl_lib == NULL) { - status = -ENOMEM; - } else { - zl_lib->pos = 0; - /* Increment ref count to allow close on failure - * later on */ - zl_lib->open_ref++; - zl_lib->target_obj = zl_target; - /* Keep a copy of the file name */ - zl_lib->file_name = kzalloc(strlen(file) + 1, - GFP_KERNEL); - if (zl_lib->file_name == NULL) { - status = -ENOMEM; - } else { - strncpy(zl_lib->file_name, file, - strlen(file) + 1); - } - zl_lib->sym_tab = NULL; - } - } - /* - * Set up objects needed by the dynamic loader - */ - if (status) - goto func_cont; - - /* Stream */ - zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer; - zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn; - zl_lib->stream.lib = zl_lib; - /* Symbol */ - zl_lib->symbol.dl_symbol.add_to_symbol_table = dbll_add_to_symbol_table; - zl_lib->symbol.dl_symbol.find_matching_symbol = dbll_find_symbol; - zl_lib->symbol.dl_symbol.purge_symbol_table = dbll_purge_symbol_table; - zl_lib->symbol.dl_symbol.dload_allocate = allocate; - zl_lib->symbol.dl_symbol.dload_deallocate = deallocate; - zl_lib->symbol.dl_symbol.error_report = dbll_err_report; - zl_lib->symbol.lib = zl_lib; - /* Allocate */ - zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc; - zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc; - zl_lib->allocate.lib = zl_lib; - /* Init */ - zl_lib->init.dl_init.connect = connect; - zl_lib->init.dl_init.readmem = read_mem; - zl_lib->init.dl_init.writemem = write_mem; - zl_lib->init.dl_init.fillmem = fill_mem; - zl_lib->init.dl_init.execute = execute; - zl_lib->init.dl_init.release = release; - zl_lib->init.lib = zl_lib; - if (!status && zl_lib->fp == NULL) - status = dof_open(zl_lib); - - zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp); - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, SEEK_SET); - /* Create a hash table for symbols if flag is set */ - if (zl_lib->sym_tab != NULL || !(flags & DBLL_SYMB)) - goto func_cont; - - zl_lib->sym_tab = - gh_create(sizeof(struct dbll_symbol), name_hash, name_match, - sym_delete); - if (IS_ERR(zl_lib->sym_tab)) { - status = PTR_ERR(zl_lib->sym_tab); - zl_lib->sym_tab = NULL; - } else { - /* Do a fake load to get symbols - set write func to no_op */ - zl_lib->init.dl_init.writemem = no_op; - err = dynamic_open_module(&zl_lib->stream.dl_stream, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init, 0, - &zl_lib->dload_mod_obj); - if (err != 0) { - status = -EILSEQ; - } else { - /* Now that we have the symbol table, we can unload */ - err = dynamic_unload_module(zl_lib->dload_mod_obj, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init); - if (err != 0) - status = -EILSEQ; - - zl_lib->dload_mod_obj = NULL; - } - } -func_cont: - if (!status) { - if (zl_lib->open_ref == 1) { - /* First time opened - insert in list */ - if (zl_target->head) - (zl_target->head)->prev = zl_lib; - - zl_lib->prev = NULL; - zl_lib->next = zl_target->head; - zl_target->head = zl_lib; - } - *lib_obj = (struct dbll_library_obj *)zl_lib; - } else { - *lib_obj = NULL; - if (zl_lib != NULL) - dbll_close((struct dbll_library_obj *)zl_lib); - - } - - dev_dbg(bridge, "%s: target: %p file: %s lib_obj: %p, status 0x%x\n", - __func__, target, file, lib_obj, status); - - return status; -} - -/* - * ======== dbll_read_sect ======== - * Get the content of a COFF section. - */ -int dbll_read_sect(struct dbll_library_obj *lib, char *name, - char *buf, u32 size) -{ - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - bool opened_doff = false; - u32 byte_size; /* size of bytes */ - u32 ul_sect_size; /* size of section */ - const struct ldr_section_info *sect = NULL; - int status = 0; - - /* If DOFF file is not open, we open it. */ - if (zl_lib != NULL) { - if (zl_lib->fp == NULL) { - status = dof_open(zl_lib); - if (!status) - opened_doff = true; - - } else { - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - zl_lib->pos, - SEEK_SET); - } - } else { - status = -EFAULT; - } - if (status) - goto func_cont; - - byte_size = 1; - if (!dload_get_section_info(zl_lib->desc, name, §)) { - status = -ENXIO; - goto func_cont; - } - /* - * Ensure the supplied buffer size is sufficient to store - * the section buf to be read. - */ - ul_sect_size = sect->size * byte_size; - /* Make sure size is even for good swap */ - if (ul_sect_size % 2) - ul_sect_size++; - - /* Align size */ - ul_sect_size = DOFF_ALIGN(ul_sect_size); - if (ul_sect_size > size) { - status = -EPERM; - } else { - if (!dload_get_section(zl_lib->desc, sect, buf)) - status = -EBADF; - - } -func_cont: - if (opened_doff) { - dof_close(zl_lib); - opened_doff = false; - } - - dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, status 0x%x\n", - __func__, lib, name, buf, size, status); - return status; -} - -/* - * ======== dbll_unload ======== - */ -void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs) -{ - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - s32 err = 0; - - dev_dbg(bridge, "%s: lib: %p\n", __func__, lib); - zl_lib->load_ref--; - /* Unload only if reference count is 0 */ - if (zl_lib->load_ref != 0) - return; - - zl_lib->target_obj->attrs = *attrs; - if (zl_lib->dload_mod_obj) { - err = dynamic_unload_module(zl_lib->dload_mod_obj, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init); - if (err != 0) - dev_dbg(bridge, "%s: failed: 0x%x\n", __func__, err); - } - /* remove symbols from symbol table */ - if (zl_lib->sym_tab != NULL) { - gh_delete(zl_lib->sym_tab); - zl_lib->sym_tab = NULL; - } - /* delete DOFF desc since it holds *lots* of host OS - * resources */ - dof_close(zl_lib); -} - -/* - * ======== dof_close ======== - */ -static void dof_close(struct dbll_library_obj *zl_lib) -{ - if (zl_lib->desc) { - dload_module_close(zl_lib->desc); - zl_lib->desc = NULL; - } - /* close file */ - if (zl_lib->fp) { - (zl_lib->target_obj->attrs.fclose) (zl_lib->fp); - zl_lib->fp = NULL; - } -} - -/* - * ======== dof_open ======== - */ -static int dof_open(struct dbll_library_obj *zl_lib) -{ - void *open = *(zl_lib->target_obj->attrs.fopen); - int status = 0; - - /* First open the file for the dynamic loader, then open COF */ - zl_lib->fp = - (void *)((dbll_f_open_fxn) (open)) (zl_lib->file_name, "rb"); - - /* Open DOFF module */ - if (zl_lib->fp && zl_lib->desc == NULL) { - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, - SEEK_SET); - zl_lib->desc = - dload_module_open(&zl_lib->stream.dl_stream, - &zl_lib->symbol.dl_symbol); - if (zl_lib->desc == NULL) { - (zl_lib->target_obj->attrs.fclose) (zl_lib->fp); - zl_lib->fp = NULL; - status = -EBADF; - } - } else { - status = -EBADF; - } - - return status; -} - -/* - * ======== name_hash ======== - */ -static u32 name_hash(const void *key) -{ - u32 hash; - const char *name = key; - - hash = 0; - - while (*name) { - hash <<= 1; - hash ^= *name++; - } - - return hash; -} - -/* - * ======== name_match ======== - */ -static bool name_match(const void *key, const void *sp) -{ - if ((key != NULL) && (sp != NULL)) { - if (strcmp(key, ((struct dbll_symbol *)sp)->name) == 0) - return true; - } - return false; -} - -/* - * ======== no_op ======== - */ -static int no_op(struct dynamic_loader_initialize *thisptr, void *bufr, - ldr_addr locn, struct ldr_section_info *info, unsigned bytsize) -{ - return 1; -} - -/* - * ======== sym_delete ======== - */ -static void sym_delete(void *value) -{ - struct dbll_symbol *sp = (struct dbll_symbol *)value; - - kfree(sp->name); -} - -/* - * Dynamic Loader Functions - */ - -/* dynamic_loader_stream */ -/* - * ======== dbll_read_buffer ======== - */ -static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer, - unsigned bufsize) -{ - struct dbll_stream *pstream = (struct dbll_stream *)this; - struct dbll_library_obj *lib; - int bytes_read = 0; - - lib = pstream->lib; - if (lib != NULL) { - bytes_read = - (*(lib->target_obj->attrs.fread)) (buffer, 1, bufsize, - lib->fp); - } - return bytes_read; -} - -/* - * ======== dbll_set_file_posn ======== - */ -static int dbll_set_file_posn(struct dynamic_loader_stream *this, - unsigned int pos) -{ - struct dbll_stream *pstream = (struct dbll_stream *)this; - struct dbll_library_obj *lib; - int status = 0; /* Success */ - - lib = pstream->lib; - if (lib != NULL) { - status = (*(lib->target_obj->attrs.fseek)) (lib->fp, (long)pos, - SEEK_SET); - } - - return status; -} - -/* dynamic_loader_sym */ - -/* - * ======== dbll_find_symbol ======== - */ -static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this, - const char *name) -{ - struct dynload_symbol *ret_sym; - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - struct dbll_sym_val *dbll_sym = NULL; - bool status = false; /* Symbol not found yet */ - - lib = ldr_sym->lib; - if (lib != NULL) { - if (lib->target_obj->attrs.sym_lookup) { - /* Check current lib + base lib + dep lib + - * persistent lib */ - status = (*(lib->target_obj->attrs.sym_lookup)) - (lib->target_obj->attrs.sym_handle, - lib->target_obj->attrs.sym_arg, - lib->target_obj->attrs.rmm_handle, name, - &dbll_sym); - } else { - /* Just check current lib for symbol */ - status = dbll_get_addr((struct dbll_library_obj *)lib, - (char *)name, &dbll_sym); - if (!status) { - status = dbll_get_c_addr( - (struct dbll_library_obj *) - lib, (char *)name, - &dbll_sym); - } - } - } - - if (!status && gbl_search) - dev_dbg(bridge, "%s: Symbol not found: %s\n", __func__, name); - - ret_sym = (struct dynload_symbol *)dbll_sym; - return ret_sym; -} - -/* - * ======== find_in_symbol_table ======== - */ -static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned moduleid) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - struct dbll_symbol *sym; - - lib = ldr_sym->lib; - sym = (struct dbll_symbol *)gh_find(lib->sym_tab, (char *)name); - - if (IS_ERR(sym)) - return NULL; - - return (struct dynload_symbol *)&sym->value; -} - -/* - * ======== dbll_add_to_symbol_table ======== - */ -static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned module_id) -{ - struct dbll_symbol *sym_ptr = NULL; - struct dbll_symbol symbol; - struct dynload_symbol *dbll_sym = NULL; - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - struct dynload_symbol *ret; - - lib = ldr_sym->lib; - - /* Check to see if symbol is already defined in symbol table */ - if (!(lib->target_obj->attrs.base_image)) { - gbl_search = false; - dbll_sym = dbll_find_symbol(this, name); - gbl_search = true; - if (dbll_sym) { - redefined_symbol = true; - dev_dbg(bridge, "%s already defined in symbol table\n", - name); - return NULL; - } - } - /* Allocate string to copy symbol name */ - symbol.name = kzalloc(strlen((char *const)name) + 1, GFP_KERNEL); - if (symbol.name == NULL) - return NULL; - - if (symbol.name != NULL) { - /* Just copy name (value will be filled in by dynamic loader) */ - strncpy(symbol.name, (char *const)name, - strlen((char *const)name) + 1); - - /* Add symbol to symbol table */ - sym_ptr = - (struct dbll_symbol *)gh_insert(lib->sym_tab, (void *)name, - (void *)&symbol); - if (IS_ERR(sym_ptr)) { - kfree(symbol.name); - sym_ptr = NULL; - } - - } - if (sym_ptr != NULL) - ret = (struct dynload_symbol *)&sym_ptr->value; - else - ret = NULL; - - return ret; -} - -/* - * ======== dbll_purge_symbol_table ======== - */ -static void dbll_purge_symbol_table(struct dynamic_loader_sym *this, - unsigned module_id) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - - lib = ldr_sym->lib; - /* May not need to do anything */ -} - -/* - * ======== allocate ======== - */ -static void *allocate(struct dynamic_loader_sym *this, unsigned memsize) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - void *buf; - - lib = ldr_sym->lib; - - buf = kzalloc(memsize, GFP_KERNEL); - - return buf; -} - -/* - * ======== deallocate ======== - */ -static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - - lib = ldr_sym->lib; - - kfree(mem_ptr); -} - -/* - * ======== dbll_err_report ======== - */ -static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr, - va_list args) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - char temp_buf[MAXEXPR]; - - lib = ldr_sym->lib; - vsnprintf((char *)temp_buf, MAXEXPR, (char *)errstr, args); - dev_dbg(bridge, "%s\n", temp_buf); -} - -/* dynamic_loader_allocate */ - -/* - * ======== dbll_rmm_alloc ======== - */ -static int dbll_rmm_alloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info, unsigned align) -{ - struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this; - struct dbll_library_obj *lib; - int status = 0; - u32 mem_sect_type; - struct rmm_addr rmm_addr_obj; - s32 ret = true; - unsigned stype = DLOAD_SECTION_TYPE(info->type); - char *token = NULL; - char *sz_sec_last_token = NULL; - char *sz_last_token = NULL; - char *sz_sect_name = NULL; - char *psz_cur; - s32 token_len = 0; - s32 seg_id = -1; - s32 req = -1; - s32 count = 0; - u32 alloc_size = 0; - u32 run_addr_flag = 0; - - lib = dbll_alloc_obj->lib; - - mem_sect_type = - (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == - DLOAD_BSS) ? DBLL_BSS : - DBLL_DATA; - - /* Attempt to extract the segment ID and requirement information from - the name of the section */ - token_len = strlen((char *)(info->name)) + 1; - - sz_sect_name = kzalloc(token_len, GFP_KERNEL); - sz_last_token = kzalloc(token_len, GFP_KERNEL); - sz_sec_last_token = kzalloc(token_len, GFP_KERNEL); - - if (sz_sect_name == NULL || sz_sec_last_token == NULL || - sz_last_token == NULL) { - status = -ENOMEM; - goto func_cont; - } - strncpy(sz_sect_name, (char *)(info->name), token_len); - psz_cur = sz_sect_name; - while ((token = strsep(&psz_cur, ":")) && *token != '\0') { - strncpy(sz_sec_last_token, sz_last_token, - strlen(sz_last_token) + 1); - strncpy(sz_last_token, token, strlen(token) + 1); - token = strsep(&psz_cur, ":"); - count++; /* optimizes processing */ - } - /* If token is 0 or 1, and sz_sec_last_token is DYN_DARAM or DYN_SARAM, - or DYN_EXTERNAL, then mem granularity information is present - within the section name - only process if there are at least three - tokens within the section name (just a minor optimization) */ - if (count >= 3) { - status = kstrtos32(sz_last_token, 10, &req); - if (status) - goto func_cont; - } - - if ((req == 0) || (req == 1)) { - if (strcmp(sz_sec_last_token, "DYN_DARAM") == 0) { - seg_id = 0; - } else { - if (strcmp(sz_sec_last_token, "DYN_SARAM") == 0) { - seg_id = 1; - } else { - if (strcmp(sz_sec_last_token, - "DYN_EXTERNAL") == 0) - seg_id = 2; - } - } - } -func_cont: - kfree(sz_sect_name); - sz_sect_name = NULL; - kfree(sz_last_token); - sz_last_token = NULL; - kfree(sz_sec_last_token); - sz_sec_last_token = NULL; - - if (mem_sect_type == DBLL_CODE) - alloc_size = info->size + GEM_L1P_PREFETCH_SIZE; - else - alloc_size = info->size; - - if (info->load_addr != info->run_addr) - run_addr_flag = 1; - /* TODO - ideally, we can pass the alignment requirement also - * from here */ - if (lib != NULL) { - status = - (lib->target_obj->attrs.alloc) (lib->target_obj->attrs. - rmm_handle, mem_sect_type, - alloc_size, align, - (u32 *) &rmm_addr_obj, - seg_id, req, false); - } - if (status) { - ret = false; - } else { - /* RMM gives word address. Need to convert to byte address */ - info->load_addr = rmm_addr_obj.addr * DSPWORDSIZE; - if (!run_addr_flag) - info->run_addr = info->load_addr; - info->context = (u32) rmm_addr_obj.segid; - dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, info->run_addr 0x%x, info->load_addr 0x%x\n", - __func__, info->name, info->load_addr / DSPWORDSIZE, - info->size / DSPWORDSIZE, info->run_addr, - info->load_addr); - } - return ret; -} - -/* - * ======== rmm_dealloc ======== - */ -static void rmm_dealloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info) -{ - struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this; - struct dbll_library_obj *lib; - u32 segid; - int status = 0; - unsigned stype = DLOAD_SECTION_TYPE(info->type); - u32 mem_sect_type; - u32 free_size = 0; - - mem_sect_type = - (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == - DLOAD_BSS) ? DBLL_BSS : - DBLL_DATA; - lib = dbll_alloc_obj->lib; - /* segid was set by alloc function */ - segid = (u32) info->context; - if (mem_sect_type == DBLL_CODE) - free_size = info->size + GEM_L1P_PREFETCH_SIZE; - else - free_size = info->size; - if (lib != NULL) { - status = - (lib->target_obj->attrs.free) (lib->target_obj->attrs. - sym_handle, segid, - info->load_addr / - DSPWORDSIZE, free_size, - false); - } -} - -/* dynamic_loader_initialize */ -/* - * ======== connect ======== - */ -static int connect(struct dynamic_loader_initialize *this) -{ - return true; -} - -/* - * ======== read_mem ======== - * This function does not need to be implemented. - */ -static int read_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned nbytes) -{ - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - struct dbll_library_obj *lib; - int bytes_read = 0; - - lib = init_obj->lib; - /* Need bridge_brd_read function */ - return bytes_read; -} - -/* - * ======== write_mem ======== - */ -static int write_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned bytes) -{ - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - struct dbll_library_obj *lib; - struct dbll_tar_obj *target_obj; - struct dbll_sect_info sect_info; - u32 mem_sect_type; - bool ret = true; - - lib = init_obj->lib; - if (!lib) - return false; - - target_obj = lib->target_obj; - - mem_sect_type = - (DLOAD_SECTION_TYPE(info->type) == - DLOAD_TEXT) ? DBLL_CODE : DBLL_DATA; - if (target_obj && target_obj->attrs.write) { - ret = - (*target_obj->attrs.write) (target_obj->attrs.input_params, - addr, buf, bytes, - mem_sect_type); - - if (target_obj->attrs.log_write) { - sect_info.name = info->name; - sect_info.sect_run_addr = info->run_addr; - sect_info.sect_load_addr = info->load_addr; - sect_info.size = info->size; - sect_info.type = mem_sect_type; - /* Pass the information about what we've written to - * another module */ - (*target_obj->attrs.log_write) (target_obj->attrs. - log_write_handle, - §_info, addr, - bytes); - } - } - return ret; -} - -/* - * ======== fill_mem ======== - * Fill bytes of memory at a given address with a given value by - * writing from a buffer containing the given value. Write in - * sets of MAXEXPR (128) bytes to avoid large stack buffer issues. - */ -static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr, - struct ldr_section_info *info, unsigned bytes, unsigned val) -{ - bool ret = true; - char *pbuf; - struct dbll_library_obj *lib; - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - - lib = init_obj->lib; - pbuf = NULL; - /* Pass the NULL pointer to write_mem to get the start address of Shared - memory. This is a trick to just get the start address, there is no - writing taking place with this Writemem - */ - if ((lib->target_obj->attrs.write) != (dbll_write_fxn) no_op) - write_mem(this, &pbuf, addr, info, 0); - if (pbuf) - memset(pbuf, val, bytes); - - return ret; -} - -/* - * ======== execute ======== - */ -static int execute(struct dynamic_loader_initialize *this, ldr_addr start) -{ - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - struct dbll_library_obj *lib; - bool ret = true; - - lib = init_obj->lib; - /* Save entry point */ - if (lib != NULL) - lib->entry = (u32) start; - - return ret; -} - -/* - * ======== release ======== - */ -static void release(struct dynamic_loader_initialize *this) -{ -} - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/** - * find_symbol_context - Basic symbol context structure - * @address: Symbol Address - * @offset_range: Offset range where the search for the DSP symbol - * started. - * @cur_best_offset: Best offset to start looking for the DSP symbol - * @sym_addr: Address of the DSP symbol - * @name: Symbol name - * - */ -struct find_symbol_context { - /* input */ - u32 address; - u32 offset_range; - /* state */ - u32 cur_best_offset; - /* output */ - u32 sym_addr; - char name[120]; -}; - -/** - * find_symbol_callback() - Validates symbol address and copies the symbol name - * to the user data. - * @elem: dsp library context - * @user_data: Find symbol context - * - */ -void find_symbol_callback(void *elem, void *user_data) -{ - struct dbll_symbol *symbol = elem; - struct find_symbol_context *context = user_data; - u32 symbol_addr = symbol->value.value; - u32 offset = context->address - symbol_addr; - - /* - * Address given should be greater than symbol address, - * symbol address should be within specified range - * and the offset should be better than previous one - */ - if (context->address >= symbol_addr && symbol_addr < (u32)-1 && - offset < context->cur_best_offset) { - context->cur_best_offset = offset; - context->sym_addr = symbol_addr; - strlcpy(context->name, symbol->name, sizeof(context->name)); - } - - return; -} - -/** - * dbll_find_dsp_symbol() - This function retrieves the dsp symbol from the dsp binary. - * @zl_lib: DSP binary obj library pointer - * @address: Given address to find the dsp symbol - * @offset_range: offset range to look for dsp symbol - * @sym_addr_output: Symbol Output address - * @name_output: String with the dsp symbol - * - * This function retrieves the dsp symbol from the dsp binary. - */ -bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address, - u32 offset_range, u32 *sym_addr_output, - char *name_output) -{ - bool status = false; - struct find_symbol_context context; - - context.address = address; - context.offset_range = offset_range; - context.cur_best_offset = offset_range; - context.sym_addr = 0; - context.name[0] = '\0'; - - gh_iterate(zl_lib->sym_tab, find_symbol_callback, &context); - - if (context.name[0]) { - status = true; - strcpy(name_output, context.name); - *sym_addr_output = context.sym_addr; - } - - return status; -} -#endif diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c deleted file mode 100644 index 616dc1f6307..00000000000 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * dev.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implementation of Bridge Bridge driver device operations. - * - * 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. - */ -#include <linux/types.h> -#include <linux/list.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/cod.h> -#include <dspbridge/drv.h> -#include <dspbridge/proc.h> -#include <dspbridge/dmm.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/mgr.h> -#include <dspbridge/node.h> - -/* ----------------------------------- Others */ -#include <dspbridge/dspapi.h> /* DSP API version info. */ - -#include <dspbridge/chnl.h> -#include <dspbridge/io.h> -#include <dspbridge/msg.h> -#include <dspbridge/cmm.h> -#include <dspbridge/dspdeh.h> - -/* ----------------------------------- This */ -#include <dspbridge/dev.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ - -#define MAKEVERSION(major, minor) (major * 10 + minor) -#define BRD_API_VERSION MAKEVERSION(BRD_API_MAJOR_VERSION, \ - BRD_API_MINOR_VERSION) - -/* The Bridge device object: */ -struct dev_object { - struct list_head link; /* Link to next dev_object. */ - u8 dev_type; /* Device Type */ - struct cfg_devnode *dev_node_obj; /* Platform specific dev id */ - /* Bridge Context Handle */ - struct bridge_dev_context *bridge_context; - /* Function interface to Bridge driver. */ - struct bridge_drv_interface bridge_interface; - struct brd_object *lock_owner; /* Client with exclusive access. */ - struct cod_manager *cod_mgr; /* Code manager handle. */ - struct chnl_mgr *chnl_mgr; /* Channel manager. */ - struct deh_mgr *deh_mgr; /* DEH manager. */ - struct msg_mgr *msg_mgr; /* Message manager. */ - struct io_mgr *iomgr; /* IO manager (CHNL, msg_ctrl) */ - struct cmm_object *cmm_mgr; /* SM memory manager. */ - struct dmm_object *dmm_mgr; /* Dynamic memory manager. */ - u32 word_size; /* DSP word size: quick access. */ - struct drv_object *drv_obj; /* Driver Object */ - /* List of Processors attached to this device */ - struct list_head proc_list; - struct node_mgr *node_mgr; -}; - -struct drv_ext { - struct list_head link; - char sz_string[MAXREGPATHLENGTH]; -}; - -/* ----------------------------------- Function Prototypes */ -static int fxn_not_implemented(int arg, ...); -static int init_cod_mgr(struct dev_object *dev_obj); -static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, - struct bridge_drv_interface *intf_fxns); -/* - * ======== dev_brd_write_fxn ======== - * Purpose: - * Exported function to be used as the COD write function. This function - * is passed a handle to a DEV_hObject, then calls the - * device's bridge_brd_write() function. - */ -u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf, - u32 ul_num_bytes, u32 mem_space) -{ - struct dev_object *dev_obj = (struct dev_object *)arb; - u32 ul_written = 0; - int status; - - if (dev_obj) { - /* Require of BrdWrite() */ - status = (*dev_obj->bridge_interface.brd_write) ( - dev_obj->bridge_context, host_buf, - dsp_add, ul_num_bytes, mem_space); - /* Special case of getting the address only */ - if (ul_num_bytes == 0) - ul_num_bytes = 1; - if (!status) - ul_written = ul_num_bytes; - - } - return ul_written; -} - -/* - * ======== dev_create_device ======== - * Purpose: - * Called by the operating system to load the PM Bridge Driver for a - * PM board (device). - */ -int dev_create_device(struct dev_object **device_obj, - const char *driver_file_name, - struct cfg_devnode *dev_node_obj) -{ - struct cfg_hostres *host_res; - struct bridge_drv_interface *drv_fxns = NULL; - struct dev_object *dev_obj = NULL; - struct chnl_mgrattrs mgr_attrs; - struct io_attrs io_mgr_attrs; - u32 num_windows; - struct drv_object *hdrv_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - int status = 0; - - status = drv_request_bridge_res_dsp((void *)&host_res); - - if (status) { - dev_dbg(bridge, "%s: Failed to reserve bridge resources\n", - __func__); - goto leave; - } - - /* Get the Bridge driver interface functions */ - bridge_drv_entry(&drv_fxns, driver_file_name); - - /* Retrieve the Object handle from the driver data */ - if (drv_datap && drv_datap->drv_object) { - hdrv_obj = drv_datap->drv_object; - } else { - status = -EPERM; - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } - - /* Create the device object, and pass a handle to the Bridge driver for - * storage. */ - if (!status) { - dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL); - if (dev_obj) { - /* Fill out the rest of the Dev Object structure: */ - dev_obj->dev_node_obj = dev_node_obj; - dev_obj->cod_mgr = NULL; - dev_obj->chnl_mgr = NULL; - dev_obj->deh_mgr = NULL; - dev_obj->lock_owner = NULL; - dev_obj->word_size = DSPWORDSIZE; - dev_obj->drv_obj = hdrv_obj; - dev_obj->dev_type = DSP_UNIT; - /* Store this Bridge's interface functions, based on its - * version. */ - store_interface_fxns(drv_fxns, - &dev_obj->bridge_interface); - - /* Call fxn_dev_create() to get the Bridge's device - * context handle. */ - status = (dev_obj->bridge_interface.dev_create) - (&dev_obj->bridge_context, dev_obj, - host_res); - } else { - status = -ENOMEM; - } - } - /* Attempt to create the COD manager for this device: */ - if (!status) - status = init_cod_mgr(dev_obj); - - /* Attempt to create the channel manager for this device: */ - if (!status) { - mgr_attrs.max_channels = CHNL_MAXCHANNELS; - io_mgr_attrs.birq = host_res->birq_registers; - io_mgr_attrs.irq_shared = - (host_res->birq_attrib & CFG_IRQSHARED); - io_mgr_attrs.word_size = DSPWORDSIZE; - mgr_attrs.word_size = DSPWORDSIZE; - num_windows = host_res->num_mem_windows; - if (num_windows) { - /* Assume last memory window is for CHNL */ - io_mgr_attrs.shm_base = host_res->mem_base[1] + - host_res->offset_for_monitor; - io_mgr_attrs.sm_length = - host_res->mem_length[1] - - host_res->offset_for_monitor; - } else { - io_mgr_attrs.shm_base = 0; - io_mgr_attrs.sm_length = 0; - pr_err("%s: No memory reserved for shared structures\n", - __func__); - } - status = chnl_create(&dev_obj->chnl_mgr, dev_obj, &mgr_attrs); - if (status == -ENOSYS) { - /* It's OK for a device not to have a channel - * manager: */ - status = 0; - } - /* Create CMM mgr even if Msg Mgr not impl. */ - status = cmm_create(&dev_obj->cmm_mgr, - (struct dev_object *)dev_obj, NULL); - /* Only create IO manager if we have a channel manager */ - if (!status && dev_obj->chnl_mgr) { - status = io_create(&dev_obj->iomgr, dev_obj, - &io_mgr_attrs); - } - /* Only create DEH manager if we have an IO manager */ - if (!status) { - /* Instantiate the DEH module */ - status = bridge_deh_create(&dev_obj->deh_mgr, dev_obj); - } - /* Create DMM mgr . */ - status = dmm_create(&dev_obj->dmm_mgr, - (struct dev_object *)dev_obj, NULL); - } - /* Add the new DEV_Object to the global list: */ - if (!status) - status = drv_insert_dev_object(hdrv_obj, dev_obj); - - /* Create the Processor List */ - if (!status) - INIT_LIST_HEAD(&dev_obj->proc_list); -leave: - /* If all went well, return a handle to the dev object; - * else, cleanup and return NULL in the OUT parameter. */ - if (!status) { - *device_obj = dev_obj; - } else { - if (dev_obj) { - if (dev_obj->cod_mgr) - cod_delete(dev_obj->cod_mgr); - if (dev_obj->dmm_mgr) - dmm_destroy(dev_obj->dmm_mgr); - kfree(dev_obj); - } - - *device_obj = NULL; - } - - return status; -} - -/* - * ======== dev_create2 ======== - * Purpose: - * After successful loading of the image from api_init_complete2 - * (PROC Auto_Start) or proc_load this fxn is called. This creates - * the Node Manager and updates the DEV Object. - */ -int dev_create2(struct dev_object *hdev_obj) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - /* There can be only one Node Manager per DEV object */ - status = node_create_mgr(&dev_obj->node_mgr, hdev_obj); - if (status) - dev_obj->node_mgr = NULL; - - return status; -} - -/* - * ======== dev_destroy2 ======== - * Purpose: - * Destroys the Node manager for this device. - */ -int dev_destroy2(struct dev_object *hdev_obj) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (dev_obj->node_mgr) { - if (node_delete_mgr(dev_obj->node_mgr)) - status = -EPERM; - else - dev_obj->node_mgr = NULL; - - } - - return status; -} - -/* - * ======== dev_destroy_device ======== - * Purpose: - * Destroys the channel manager for this device, if any, calls - * bridge_dev_destroy(), and then attempts to unload the Bridge module. - */ -int dev_destroy_device(struct dev_object *hdev_obj) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - if (dev_obj->cod_mgr) { - cod_delete(dev_obj->cod_mgr); - dev_obj->cod_mgr = NULL; - } - - if (dev_obj->node_mgr) { - node_delete_mgr(dev_obj->node_mgr); - dev_obj->node_mgr = NULL; - } - - /* Free the io, channel, and message managers for this board: */ - if (dev_obj->iomgr) { - io_destroy(dev_obj->iomgr); - dev_obj->iomgr = NULL; - } - if (dev_obj->chnl_mgr) { - chnl_destroy(dev_obj->chnl_mgr); - dev_obj->chnl_mgr = NULL; - } - if (dev_obj->msg_mgr) { - msg_delete(dev_obj->msg_mgr); - dev_obj->msg_mgr = NULL; - } - - if (dev_obj->deh_mgr) { - /* Uninitialize DEH module. */ - bridge_deh_destroy(dev_obj->deh_mgr); - dev_obj->deh_mgr = NULL; - } - if (dev_obj->cmm_mgr) { - cmm_destroy(dev_obj->cmm_mgr, true); - dev_obj->cmm_mgr = NULL; - } - - if (dev_obj->dmm_mgr) { - dmm_destroy(dev_obj->dmm_mgr); - dev_obj->dmm_mgr = NULL; - } - - /* Call the driver's bridge_dev_destroy() function: */ - /* Require of DevDestroy */ - if (dev_obj->bridge_context) { - status = (*dev_obj->bridge_interface.dev_destroy) - (dev_obj->bridge_context); - dev_obj->bridge_context = NULL; - } else - status = -EPERM; - if (!status) { - /* Remove this DEV_Object from the global list: */ - drv_remove_dev_object(dev_obj->drv_obj, dev_obj); - /* Free The library * LDR_FreeModule - * (dev_obj->module_obj); */ - /* Free this dev object: */ - kfree(dev_obj); - dev_obj = NULL; - } - } else { - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_chnl_mgr ======== - * Purpose: - * Retrieve the handle to the channel manager handle created for this - * device. - */ -int dev_get_chnl_mgr(struct dev_object *hdev_obj, - struct chnl_mgr **mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *mgr = dev_obj->chnl_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_cmm_mgr ======== - * Purpose: - * Retrieve the handle to the shared memory manager created for this - * device. - */ -int dev_get_cmm_mgr(struct dev_object *hdev_obj, - struct cmm_object **mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *mgr = dev_obj->cmm_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_dmm_mgr ======== - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - */ -int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *mgr = dev_obj->dmm_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_cod_mgr ======== - * Purpose: - * Retrieve the COD manager create for this device. - */ -int dev_get_cod_mgr(struct dev_object *hdev_obj, - struct cod_manager **cod_mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *cod_mgr = dev_obj->cod_mgr; - } else { - *cod_mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ========= dev_get_deh_mgr ======== - */ -int dev_get_deh_mgr(struct dev_object *hdev_obj, - struct deh_mgr **deh_manager) -{ - int status = 0; - - if (hdev_obj) { - *deh_manager = hdev_obj->deh_mgr; - } else { - *deh_manager = NULL; - status = -EFAULT; - } - return status; -} - -/* - * ======== dev_get_dev_node ======== - * Purpose: - * Retrieve the platform specific device ID for this device. - */ -int dev_get_dev_node(struct dev_object *hdev_obj, - struct cfg_devnode **dev_nde) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *dev_nde = dev_obj->dev_node_obj; - } else { - *dev_nde = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_first ======== - * Purpose: - * Retrieve the first Device Object handle from an internal linked list - * DEV_OBJECTs maintained by DEV. - */ -struct dev_object *dev_get_first(void) -{ - struct dev_object *dev_obj = NULL; - - dev_obj = (struct dev_object *)drv_get_first_dev_object(); - - return dev_obj; -} - -/* - * ======== dev_get_intf_fxns ======== - * Purpose: - * Retrieve the Bridge interface function structure for the loaded driver. - * if_fxns != NULL. - */ -int dev_get_intf_fxns(struct dev_object *hdev_obj, - struct bridge_drv_interface **if_fxns) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *if_fxns = &dev_obj->bridge_interface; - } else { - *if_fxns = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ========= dev_get_io_mgr ======== - */ -int dev_get_io_mgr(struct dev_object *hdev_obj, - struct io_mgr **io_man) -{ - int status = 0; - - if (hdev_obj) { - *io_man = hdev_obj->iomgr; - } else { - *io_man = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_next ======== - * Purpose: - * Retrieve the next Device Object handle from an internal linked list - * of DEV_OBJECTs maintained by DEV, after having previously called - * dev_get_first() and zero or more dev_get_next - */ -struct dev_object *dev_get_next(struct dev_object *hdev_obj) -{ - struct dev_object *next_dev_object = NULL; - - if (hdev_obj) { - next_dev_object = (struct dev_object *) - drv_get_next_dev_object((u32) hdev_obj); - } - - return next_dev_object; -} - -/* - * ========= dev_get_msg_mgr ======== - */ -void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man) -{ - *msg_man = hdev_obj->msg_mgr; -} - -/* - * ======== dev_get_node_manager ======== - * Purpose: - * Retrieve the Node Manager Handle - */ -int dev_get_node_manager(struct dev_object *hdev_obj, - struct node_mgr **node_man) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *node_man = dev_obj->node_mgr; - } else { - *node_man = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_symbol ======== - */ -int dev_get_symbol(struct dev_object *hdev_obj, - const char *str_sym, u32 *pul_value) -{ - int status = 0; - struct cod_manager *cod_mgr; - - if (hdev_obj) { - status = dev_get_cod_mgr(hdev_obj, &cod_mgr); - if (cod_mgr) - status = cod_get_sym_value(cod_mgr, (char *)str_sym, - pul_value); - else - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_bridge_context ======== - * Purpose: - * Retrieve the Bridge Context handle, as returned by the - * bridge_dev_create fxn. - */ -int dev_get_bridge_context(struct dev_object *hdev_obj, - struct bridge_dev_context **phbridge_context) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *phbridge_context = dev_obj->bridge_context; - } else { - *phbridge_context = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_notify_clients ======== - * Purpose: - * Notify all clients of this device of a change in device status. - */ -int dev_notify_clients(struct dev_object *dev_obj, u32 ret) -{ - struct list_head *curr; - - /* - * FIXME: this code needs struct proc_object to have a list_head - * at the beginning. If not, this can go horribly wrong. - */ - list_for_each(curr, &dev_obj->proc_list) - proc_notify_clients((void *)curr, ret); - - return 0; -} - -/* - * ======== dev_remove_device ======== - */ -int dev_remove_device(struct cfg_devnode *dev_node_obj) -{ - struct dev_object *hdev_obj; /* handle to device object */ - int status = 0; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - if (!drv_datap) - status = -ENODATA; - - if (!dev_node_obj) - status = -EFAULT; - - /* Retrieve the device object handle originally stored with - * the dev_node: */ - if (!status) { - /* check the device string and then store dev object */ - if (!strcmp((char *)((struct drv_ext *)dev_node_obj)->sz_string, - "TIOMAP1510")) { - hdev_obj = drv_datap->dev_object; - /* Destroy the device object. */ - status = dev_destroy_device(hdev_obj); - } else { - status = -EPERM; - } - } - - if (status) - pr_err("%s: Failed, status 0x%x\n", __func__, status); - - return status; -} - -/* - * ======== dev_set_chnl_mgr ======== - * Purpose: - * Set the channel manager for this device. - */ -int dev_set_chnl_mgr(struct dev_object *hdev_obj, - struct chnl_mgr *hmgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) - dev_obj->chnl_mgr = hmgr; - else - status = -EFAULT; - - return status; -} - -/* - * ======== dev_set_msg_mgr ======== - * Purpose: - * Set the message manager for this device. - */ -void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr) -{ - hdev_obj->msg_mgr = hmgr; -} - -/* - * ======== dev_start_device ======== - * Purpose: - * Initializes the new device with the BRIDGE environment. - */ -int dev_start_device(struct cfg_devnode *dev_node_obj) -{ - struct dev_object *hdev_obj = NULL; /* handle to 'Bridge Device */ - /* Bridge driver filename */ - char *bridge_file_name = "UMA"; - int status; - struct mgr_object *hmgr_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - /* Given all resources, create a device object. */ - status = dev_create_device(&hdev_obj, bridge_file_name, - dev_node_obj); - if (!status) { - /* Store away the hdev_obj with the DEVNODE */ - if (!drv_datap || !dev_node_obj) { - status = -EFAULT; - pr_err("%s: Failed, status 0x%x\n", __func__, status); - } else if (!(strcmp((char *)dev_node_obj, "TIOMAP1510"))) { - drv_datap->dev_object = (void *) hdev_obj; - } - if (!status) { - /* Create the Manager Object */ - status = mgr_create(&hmgr_obj, dev_node_obj); - if (status && !(strcmp((char *)dev_node_obj, - "TIOMAP1510"))) { - /* Ensure the device extension is NULL */ - drv_datap->dev_object = NULL; - } - } - if (status) { - /* Clean up */ - dev_destroy_device(hdev_obj); - hdev_obj = NULL; - } - } - - return status; -} - -/* - * ======== fxn_not_implemented ======== - * Purpose: - * Takes the place of a Bridge Null Function. - * Parameters: - * Multiple, optional. - * Returns: - * -ENOSYS: Always. - */ -static int fxn_not_implemented(int arg, ...) -{ - return -ENOSYS; -} - -/* - * ======== init_cod_mgr ======== - * Purpose: - * Create a COD manager for this device. - * Parameters: - * dev_obj: Pointer to device object created with - * dev_create_device() - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * Should only be called once by dev_create_device() for a given DevObject. - * Ensures: - */ -static int init_cod_mgr(struct dev_object *dev_obj) -{ - int status = 0; - char *sz_dummy_file = "dummy"; - - status = cod_create(&dev_obj->cod_mgr, sz_dummy_file); - - return status; -} - -/* - * ======== dev_insert_proc_object ======== - * Purpose: - * Insert a ProcObject into the list maintained by DEV. - * Parameters: - * p_proc_object: Ptr to ProcObject to insert. - * dev_obj: Ptr to Dev Object where the list is. - * already_attached: Ptr to return the bool - * Returns: - * 0: If successful. - * Requires: - * List Exists - * hdev_obj is Valid handle - * DEV Initialized - * already_attached != NULL - * proc_obj != 0 - * Ensures: - * 0 and List is not Empty. - */ -int dev_insert_proc_object(struct dev_object *hdev_obj, - u32 proc_obj, bool *already_attached) -{ - struct dev_object *dev_obj = (struct dev_object *)hdev_obj; - - if (!list_empty(&dev_obj->proc_list)) - *already_attached = true; - - /* Add DevObject to tail. */ - /* - * FIXME: this code needs struct proc_object to have a list_head - * at the beginning. If not, this can go horribly wrong. - */ - list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list); - - return 0; -} - -/* - * ======== dev_remove_proc_object ======== - * Purpose: - * Search for and remove a Proc object from the given list maintained - * by the DEV - * Parameters: - * p_proc_object: Ptr to ProcObject to insert. - * dev_obj Ptr to Dev Object where the list is. - * Returns: - * 0: If successful. - * Requires: - * List exists and is not empty - * proc_obj != 0 - * hdev_obj is a valid Dev handle. - * Ensures: - * Details: - * List will be deleted when the DEV is destroyed. - */ -int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj) -{ - int status = -EPERM; - struct list_head *cur_elem; - struct dev_object *dev_obj = (struct dev_object *)hdev_obj; - - /* Search list for dev_obj: */ - list_for_each(cur_elem, &dev_obj->proc_list) { - if ((u32) cur_elem == proc_obj) { - list_del(cur_elem); - status = 0; - break; - } - } - - return status; -} - -int dev_get_dev_type(struct dev_object *dev_obj, u8 *dev_type) -{ - *dev_type = dev_obj->dev_type; - return 0; -} - -/* - * ======== store_interface_fxns ======== - * Purpose: - * Copy the Bridge's interface functions into the device object, - * ensuring that fxn_not_implemented() is set for: - * - * 1. All Bridge function pointers which are NULL; and - * 2. All function slots in the struct dev_object structure which have no - * corresponding slots in the the Bridge's interface, because the Bridge - * is of an *older* version. - * Parameters: - * intf_fxns: Interface fxn Structure of the Bridge's Dev Object. - * drv_fxns: Interface Fxns offered by the Bridge during DEV_Create(). - * Returns: - * Requires: - * Input pointers are valid. - * Bridge driver is *not* written for a newer DSP API. - * Ensures: - * All function pointers in the dev object's fxn interface are not NULL. - */ -static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, - struct bridge_drv_interface *intf_fxns) -{ - u32 bridge_version; - - /* Local helper macro: */ -#define STORE_FXN(cast, pfn) \ - (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \ - (cast)fxn_not_implemented)) - - bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version, - drv_fxns->brd_api_minor_version); - intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version; - intf_fxns->brd_api_minor_version = drv_fxns->brd_api_minor_version; - /* Install functions up to DSP API version .80 (first alpha): */ - if (bridge_version > 0) { - STORE_FXN(fxn_dev_create, dev_create); - STORE_FXN(fxn_dev_destroy, dev_destroy); - STORE_FXN(fxn_dev_ctrl, dev_cntrl); - STORE_FXN(fxn_brd_monitor, brd_monitor); - STORE_FXN(fxn_brd_start, brd_start); - STORE_FXN(fxn_brd_stop, brd_stop); - STORE_FXN(fxn_brd_status, brd_status); - STORE_FXN(fxn_brd_read, brd_read); - STORE_FXN(fxn_brd_write, brd_write); - STORE_FXN(fxn_brd_setstate, brd_set_state); - STORE_FXN(fxn_brd_memcopy, brd_mem_copy); - STORE_FXN(fxn_brd_memwrite, brd_mem_write); - STORE_FXN(fxn_brd_memmap, brd_mem_map); - STORE_FXN(fxn_brd_memunmap, brd_mem_un_map); - STORE_FXN(fxn_chnl_create, chnl_create); - STORE_FXN(fxn_chnl_destroy, chnl_destroy); - STORE_FXN(fxn_chnl_open, chnl_open); - STORE_FXN(fxn_chnl_close, chnl_close); - STORE_FXN(fxn_chnl_addioreq, chnl_add_io_req); - STORE_FXN(fxn_chnl_getioc, chnl_get_ioc); - STORE_FXN(fxn_chnl_cancelio, chnl_cancel_io); - STORE_FXN(fxn_chnl_flushio, chnl_flush_io); - STORE_FXN(fxn_chnl_getinfo, chnl_get_info); - STORE_FXN(fxn_chnl_getmgrinfo, chnl_get_mgr_info); - STORE_FXN(fxn_chnl_idle, chnl_idle); - STORE_FXN(fxn_chnl_registernotify, chnl_register_notify); - STORE_FXN(fxn_io_create, io_create); - STORE_FXN(fxn_io_destroy, io_destroy); - STORE_FXN(fxn_io_onloaded, io_on_loaded); - STORE_FXN(fxn_io_getprocload, io_get_proc_load); - STORE_FXN(fxn_msg_create, msg_create); - STORE_FXN(fxn_msg_createqueue, msg_create_queue); - STORE_FXN(fxn_msg_delete, msg_delete); - STORE_FXN(fxn_msg_deletequeue, msg_delete_queue); - STORE_FXN(fxn_msg_get, msg_get); - STORE_FXN(fxn_msg_put, msg_put); - STORE_FXN(fxn_msg_registernotify, msg_register_notify); - STORE_FXN(fxn_msg_setqueueid, msg_set_queue_id); - } - /* Add code for any additional functions in newerBridge versions here */ -#undef STORE_FXN -} diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c deleted file mode 100644 index fcf564aa566..00000000000 --- a/drivers/staging/tidspbridge/pmgr/dmm.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * 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. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.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 */ -}; - -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 len); -static struct map_page *get_mapped_region(u32 addrs); - -/* ======== 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 (!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 (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(struct dmm_object **dmm_manager, - struct dev_object *hdev_obj, - const struct dmm_mgrattrs *mgr_attrts) -{ - struct dmm_object *dmm_obj = NULL; - int status = 0; - - *dmm_manager = 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); - *dmm_manager = 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; - - if (dmm_mgr) { - status = dmm_delete_tables(dmm_obj); - if (!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; - - /* Delete all DMM tables */ - if (dmm_mgr) - vfree(virtual_mapping_table); - else - status = -EFAULT; - return status; -} - -/* - * ======== 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, struct dmm_object **dmm_manager) -{ - int status = 0; - struct dev_object *hdev_obj; - - if (hprocessor != NULL) - status = proc_get_dev_object(hprocessor, &hdev_obj); - else - hdev_obj = dev_get_first(); /* default */ - - if (!status) - status = dev_get_dmm_mgr(hdev_obj, dmm_manager); - - return status; -} - -/* - * ======== 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 (!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 (!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 addr) -{ - 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(addr); - 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 len) -{ - 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 (len > 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 (len <= free_size) { - curr_region = virtual_mapping_table + free_region; - free_region += (len / PG_SIZE4K); - free_size -= len; - } - return curr_region; -} - -/* - * ======== get_mapped_region ======== - * Purpose: - * Returns the requestedmapped region - */ -static struct map_page *get_mapped_region(u32 addrs) -{ - u32 i = 0; - struct map_page *curr_region = NULL; - - if (virtual_mapping_table == NULL) - return curr_region; - - i = DMM_ADDR_TO_INDEX(addrs); - 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) { - /*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); - dev_info(bridge, "Total DSP VA FREE memory = %d Mbytes\n", - freemem / (1024 * 1024)); - dev_info(bridge, "Total DSP VA USED memory= %d Mbytes\n", - (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024)); - dev_info(bridge, "DSP VA - Biggest FREE block = %d Mbytes\n", - (bigsize * PG_SIZE4K / (1024 * 1024))); - - return 0; -} -#endif diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c deleted file mode 100644 index b7d5c8cbb2a..00000000000 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ /dev/null @@ -1,1843 +0,0 @@ -/* - * dspapi.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Common DSP API functions, also includes the wrapper - * functions called directly by the DeviceIOControl interface. - * - * 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. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/ntfy.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/chnl.h> -#include <dspbridge/dev.h> -#include <dspbridge/drv.h> - -#include <dspbridge/proc.h> -#include <dspbridge/strm.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/disp.h> -#include <dspbridge/mgr.h> -#include <dspbridge/node.h> -#include <dspbridge/rmm.h> - -/* ----------------------------------- Others */ -#include <dspbridge/msg.h> -#include <dspbridge/cmm.h> -#include <dspbridge/io.h> - -/* ----------------------------------- This */ -#include <dspbridge/dspapi.h> -#include <dspbridge/dbdcd.h> - -#include <dspbridge/resourcecleanup.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define MAX_TRACEBUFLEN 255 -#define MAX_LOADARGS 16 -#define MAX_NODES 64 -#define MAX_STREAMS 16 -#define MAX_BUFS 64 - -/* Used to get dspbridge ioctl table */ -#define DB_GET_IOC_TABLE(cmd) (DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT) - -/* Device IOCtl function pointer */ -struct api_cmd { - u32(*fxn) (union trapped_args *args, void *pr_ctxt); - u32 index; -}; - -/* ----------------------------------- Globals */ -static u32 api_c_refs; - -/* - * Function tables. - * The order of these functions MUST be the same as the order of the command - * numbers defined in dspapi-ioctl.h This is how an IOCTL number in user mode - * turns into a function call in kernel mode. - */ - -/* MGR wrapper functions */ -static struct api_cmd mgr_cmd[] = { - {mgrwrap_enum_node_info}, /* MGR_ENUMNODE_INFO */ - {mgrwrap_enum_proc_info}, /* MGR_ENUMPROC_INFO */ - {mgrwrap_register_object}, /* MGR_REGISTEROBJECT */ - {mgrwrap_unregister_object}, /* MGR_UNREGISTEROBJECT */ - {mgrwrap_wait_for_bridge_events}, /* MGR_WAIT */ - {mgrwrap_get_process_resources_info}, /* MGR_GET_PROC_RES */ -}; - -/* PROC wrapper functions */ -static struct api_cmd proc_cmd[] = { - {procwrap_attach}, /* PROC_ATTACH */ - {procwrap_ctrl}, /* PROC_CTRL */ - {procwrap_detach}, /* PROC_DETACH */ - {procwrap_enum_node_info}, /* PROC_ENUMNODE */ - {procwrap_enum_resources}, /* PROC_ENUMRESOURCES */ - {procwrap_get_state}, /* PROC_GET_STATE */ - {procwrap_get_trace}, /* PROC_GET_TRACE */ - {procwrap_load}, /* PROC_LOAD */ - {procwrap_register_notify}, /* PROC_REGISTERNOTIFY */ - {procwrap_start}, /* PROC_START */ - {procwrap_reserve_memory}, /* PROC_RSVMEM */ - {procwrap_un_reserve_memory}, /* PROC_UNRSVMEM */ - {procwrap_map}, /* PROC_MAPMEM */ - {procwrap_un_map}, /* PROC_UNMAPMEM */ - {procwrap_flush_memory}, /* PROC_FLUSHMEMORY */ - {procwrap_stop}, /* PROC_STOP */ - {procwrap_invalidate_memory}, /* PROC_INVALIDATEMEMORY */ - {procwrap_begin_dma}, /* PROC_BEGINDMA */ - {procwrap_end_dma}, /* PROC_ENDDMA */ -}; - -/* NODE wrapper functions */ -static struct api_cmd node_cmd[] = { - {nodewrap_allocate}, /* NODE_ALLOCATE */ - {nodewrap_alloc_msg_buf}, /* NODE_ALLOCMSGBUF */ - {nodewrap_change_priority}, /* NODE_CHANGEPRIORITY */ - {nodewrap_connect}, /* NODE_CONNECT */ - {nodewrap_create}, /* NODE_CREATE */ - {nodewrap_delete}, /* NODE_DELETE */ - {nodewrap_free_msg_buf}, /* NODE_FREEMSGBUF */ - {nodewrap_get_attr}, /* NODE_GETATTR */ - {nodewrap_get_message}, /* NODE_GETMESSAGE */ - {nodewrap_pause}, /* NODE_PAUSE */ - {nodewrap_put_message}, /* NODE_PUTMESSAGE */ - {nodewrap_register_notify}, /* NODE_REGISTERNOTIFY */ - {nodewrap_run}, /* NODE_RUN */ - {nodewrap_terminate}, /* NODE_TERMINATE */ - {nodewrap_get_uuid_props}, /* NODE_GETUUIDPROPS */ -}; - -/* STRM wrapper functions */ -static struct api_cmd strm_cmd[] = { - {strmwrap_allocate_buffer}, /* STRM_ALLOCATEBUFFER */ - {strmwrap_close}, /* STRM_CLOSE */ - {strmwrap_free_buffer}, /* STRM_FREEBUFFER */ - {strmwrap_get_event_handle}, /* STRM_GETEVENTHANDLE */ - {strmwrap_get_info}, /* STRM_GETINFO */ - {strmwrap_idle}, /* STRM_IDLE */ - {strmwrap_issue}, /* STRM_ISSUE */ - {strmwrap_open}, /* STRM_OPEN */ - {strmwrap_reclaim}, /* STRM_RECLAIM */ - {strmwrap_register_notify}, /* STRM_REGISTERNOTIFY */ - {strmwrap_select}, /* STRM_SELECT */ -}; - -/* CMM wrapper functions */ -static struct api_cmd cmm_cmd[] = { - {cmmwrap_calloc_buf}, /* CMM_ALLOCBUF */ - {cmmwrap_free_buf}, /* CMM_FREEBUF */ - {cmmwrap_get_handle}, /* CMM_GETHANDLE */ - {cmmwrap_get_info}, /* CMM_GETINFO */ -}; - -/* Array used to store ioctl table sizes. It can hold up to 8 entries */ -static u8 size_cmd[] = { - ARRAY_SIZE(mgr_cmd), - ARRAY_SIZE(proc_cmd), - ARRAY_SIZE(node_cmd), - ARRAY_SIZE(strm_cmd), - ARRAY_SIZE(cmm_cmd), -}; - -static inline void _cp_fm_usr(void *to, const void __user *from, - int *err, unsigned long bytes) -{ - if (*err) - return; - - if (unlikely(!from)) { - *err = -EFAULT; - return; - } - - if (unlikely(copy_from_user(to, from, bytes))) - *err = -EFAULT; -} - -#define CP_FM_USR(to, from, err, n) \ - _cp_fm_usr(to, from, &(err), (n) * sizeof(*(to))) - -static inline void _cp_to_usr(void __user *to, const void *from, - int *err, unsigned long bytes) -{ - if (*err) - return; - - if (unlikely(!to)) { - *err = -EFAULT; - return; - } - - if (unlikely(copy_to_user(to, from, bytes))) - *err = -EFAULT; -} - -#define CP_TO_USR(to, from, err, n) \ - _cp_to_usr(to, from, &(err), (n) * sizeof(*(from))) - -/* - * ======== api_call_dev_ioctl ======== - * Purpose: - * Call the (wrapper) function for the corresponding API IOCTL. - */ -inline int api_call_dev_ioctl(u32 cmd, union trapped_args *args, - u32 *result, void *pr_ctxt) -{ - u32(*ioctl_cmd) (union trapped_args *args, void *pr_ctxt) = NULL; - int i; - - if (_IOC_TYPE(cmd) != DB) { - pr_err("%s: Incompatible dspbridge ioctl number\n", __func__); - goto err; - } - - if (DB_GET_IOC_TABLE(cmd) > ARRAY_SIZE(size_cmd)) { - pr_err("%s: undefined ioctl module\n", __func__); - goto err; - } - - /* Check the size of the required cmd table */ - i = DB_GET_IOC(cmd); - if (i > size_cmd[DB_GET_IOC_TABLE(cmd)]) { - pr_err("%s: requested ioctl %d out of bounds for table %d\n", - __func__, i, DB_GET_IOC_TABLE(cmd)); - goto err; - } - - switch (DB_GET_MODULE(cmd)) { - case DB_MGR: - ioctl_cmd = mgr_cmd[i].fxn; - break; - case DB_PROC: - ioctl_cmd = proc_cmd[i].fxn; - break; - case DB_NODE: - ioctl_cmd = node_cmd[i].fxn; - break; - case DB_STRM: - ioctl_cmd = strm_cmd[i].fxn; - break; - case DB_CMM: - ioctl_cmd = cmm_cmd[i].fxn; - break; - } - - if (!ioctl_cmd) { - pr_err("%s: requested ioctl not defined\n", __func__); - goto err; - } else { - *result = (*ioctl_cmd) (args, pr_ctxt); - } - - return 0; - -err: - return -EINVAL; -} - -/* - * ======== api_exit ======== - */ -void api_exit(void) -{ - api_c_refs--; - - if (api_c_refs == 0) - mgr_exit(); -} - -/* - * ======== api_init ======== - * Purpose: - * Module initialization used by Bridge API. - */ -bool api_init(void) -{ - bool ret = true; - - if (api_c_refs == 0) - ret = mgr_init(); - - if (ret) - api_c_refs++; - - return ret; -} - -/* - * ======== api_init_complete2 ======== - * Purpose: - * Perform any required bridge initialization which cannot - * be performed in api_init() or dev_start_device() due - * to the fact that some services are not yet - * completely initialized. - * Parameters: - * Returns: - * 0: Allow this device to load - * -EPERM: Failure. - * Requires: - * Bridge API initialized. - * Ensures: - */ -int api_init_complete2(void) -{ - int status = 0; - struct cfg_devnode *dev_node; - struct dev_object *hdev_obj; - struct drv_data *drv_datap; - u8 dev_type; - - /* Walk the list of DevObjects, get each devnode, and attempting to - * autostart the board. Note that this requires COF loading, which - * requires KFILE. */ - for (hdev_obj = dev_get_first(); hdev_obj != NULL; - hdev_obj = dev_get_next(hdev_obj)) { - if (dev_get_dev_node(hdev_obj, &dev_node)) - continue; - - if (dev_get_dev_type(hdev_obj, &dev_type)) - continue; - - if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) { - drv_datap = dev_get_drvdata(bridge); - - if (drv_datap && drv_datap->base_img) - proc_auto_start(dev_node, hdev_obj); - } - } - - return status; -} - -/* TODO: Remove deprecated and not implemented ioctl wrappers */ - -/* - * ======== mgrwrap_enum_node_info ======== - */ -u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) -{ - u8 *pndb_props; - u32 num_nodes; - int status = 0; - u32 size = args->args_mgr_enumnode_info.ndb_props_size; - - if (size < sizeof(struct dsp_ndbprops)) - return -EINVAL; - - pndb_props = kmalloc(size, GFP_KERNEL); - if (pndb_props == NULL) - status = -ENOMEM; - - if (!status) { - status = - mgr_enum_node_info(args->args_mgr_enumnode_info.node_id, - (struct dsp_ndbprops *)pndb_props, size, - &num_nodes); - } - CP_TO_USR(args->args_mgr_enumnode_info.ndb_props, pndb_props, status, - size); - CP_TO_USR(args->args_mgr_enumnode_info.num_nodes, &num_nodes, status, - 1); - kfree(pndb_props); - - return status; -} - -/* - * ======== mgrwrap_enum_proc_info ======== - */ -u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt) -{ - u8 *processor_info; - u8 num_procs; - int status = 0; - u32 size = args->args_mgr_enumproc_info.processor_info_size; - - if (size < sizeof(struct dsp_processorinfo)) - return -EINVAL; - - processor_info = kmalloc(size, GFP_KERNEL); - if (processor_info == NULL) - status = -ENOMEM; - - if (!status) { - status = - mgr_enum_processor_info(args->args_mgr_enumproc_info. - processor_id, - (struct dsp_processorinfo *) - processor_info, size, &num_procs); - } - CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info, - status, size); - CP_TO_USR(args->args_mgr_enumproc_info.num_procs, &num_procs, - status, 1); - kfree(processor_info); - - return status; -} - -#define WRAP_MAP2CALLER(x) x -/* - * ======== mgrwrap_register_object ======== - */ -u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct dsp_uuid uuid_obj; - u32 path_size = 0; - char *psz_path_name = NULL; - int status = 0; - - CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1); - if (status) - goto func_end; - path_size = strlen_user((char *) - args->args_mgr_registerobject.sz_path_name); - if (!path_size) { - status = -EINVAL; - goto func_end; - } - - psz_path_name = kmalloc(path_size, GFP_KERNEL); - if (!psz_path_name) { - status = -ENOMEM; - goto func_end; - } - ret = strncpy_from_user(psz_path_name, - (char *)args->args_mgr_registerobject. - sz_path_name, path_size); - if (!ret) { - status = -EFAULT; - goto func_end; - } - - if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE) { - status = -EINVAL; - goto func_end; - } - - status = dcd_register_object(&uuid_obj, - args->args_mgr_registerobject.obj_type, - (char *)psz_path_name); -func_end: - kfree(psz_path_name); - return status; -} - -/* - * ======== mgrwrap_unregister_object ======== - */ -u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_uuid uuid_obj; - - CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1); - if (status) - goto func_end; - - status = dcd_unregister_object(&uuid_obj, - args->args_mgr_unregisterobject. - obj_type); -func_end: - return status; - -} - -/* - * ======== mgrwrap_wait_for_bridge_events ======== - */ -u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_notification *anotifications[MAX_EVENTS]; - struct dsp_notification notifications[MAX_EVENTS]; - u32 index, i; - u32 count = args->args_mgr_wait.count; - - if (count > MAX_EVENTS) - status = -EINVAL; - - /* get the array of pointers to user structures */ - CP_FM_USR(anotifications, args->args_mgr_wait.anotifications, - status, count); - /* get the events */ - for (i = 0; i < count; i++) { - CP_FM_USR(¬ifications[i], anotifications[i], status, 1); - if (status || !notifications[i].handle) { - status = -EINVAL; - break; - } - /* set the array of pointers to kernel structures */ - anotifications[i] = ¬ifications[i]; - } - if (!status) { - status = mgr_wait_for_bridge_events(anotifications, count, - &index, - args->args_mgr_wait. - timeout); - } - CP_TO_USR(args->args_mgr_wait.index, &index, status, 1); - return status; -} - -/* - * ======== MGRWRAP_GetProcessResourceInfo ======== - */ -u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args *args, - void *pr_ctxt) -{ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return 0; -} - -/* - * ======== procwrap_attach ======== - */ -u32 procwrap_attach(union trapped_args *args, void *pr_ctxt) -{ - void *processor; - int status = 0; - struct dsp_processorattrin proc_attr_in, *attr_in = NULL; - - /* Optional argument */ - if (args->args_proc_attach.attr_in) { - CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status, - 1); - if (!status) - attr_in = &proc_attr_in; - else - goto func_end; - - } - status = proc_attach(args->args_proc_attach.processor_id, attr_in, - &processor, pr_ctxt); - CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1); -func_end: - return status; -} - -/* - * ======== procwrap_ctrl ======== - */ -u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt) -{ - u32 cb_data_size, __user * psize = (u32 __user *) - args->args_proc_ctrl.args; - u8 *pargs = NULL; - int status = 0; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (psize) { - if (get_user(cb_data_size, psize)) { - status = -EPERM; - goto func_end; - } - cb_data_size += sizeof(u32); - pargs = kmalloc(cb_data_size, GFP_KERNEL); - if (pargs == NULL) { - status = -ENOMEM; - goto func_end; - } - - CP_FM_USR(pargs, args->args_proc_ctrl.args, status, - cb_data_size); - } - if (!status) { - status = proc_ctrl(hprocessor, - args->args_proc_ctrl.cmd, - (struct dsp_cbdata *)pargs); - } - - /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */ - kfree(pargs); -func_end: - return status; -} - -/* - * ======== procwrap_detach ======== - */ -u32 __deprecated procwrap_detach(union trapped_args *args, void *pr_ctxt) -{ - /* proc_detach called at bridge_release only */ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return 0; -} - -/* - * ======== procwrap_enum_node_info ======== - */ -u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *node_tab[MAX_NODES]; - u32 num_nodes; - u32 alloc_cnt; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (!args->args_proc_enumnode_info.node_tab_size) - return -EINVAL; - - status = proc_enum_nodes(hprocessor, - node_tab, - args->args_proc_enumnode_info.node_tab_size, - &num_nodes, &alloc_cnt); - CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status, - num_nodes); - CP_TO_USR(args->args_proc_enumnode_info.num_nodes, &num_nodes, - status, 1); - CP_TO_USR(args->args_proc_enumnode_info.allocated, &alloc_cnt, - status, 1); - return status; -} - -u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt) -{ - int status; - - if (args->args_proc_dma.dir >= DMA_NONE) - return -EINVAL; - - status = proc_end_dma(pr_ctxt, - args->args_proc_dma.mpu_addr, - args->args_proc_dma.size, - args->args_proc_dma.dir); - return status; -} - -u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt) -{ - int status; - - if (args->args_proc_dma.dir >= DMA_NONE) - return -EINVAL; - - status = proc_begin_dma(pr_ctxt, - args->args_proc_dma.mpu_addr, - args->args_proc_dma.size, - args->args_proc_dma.dir); - return status; -} - -/* - * ======== procwrap_flush_memory ======== - */ -u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - - if (args->args_proc_flushmemory.flags > - PROC_WRITEBACK_INVALIDATE_MEM) - return -EINVAL; - - status = proc_flush_memory(pr_ctxt, - args->args_proc_flushmemory.mpu_addr, - args->args_proc_flushmemory.size, - args->args_proc_flushmemory.flags); - return status; -} - -/* - * ======== procwrap_invalidate_memory ======== - */ -u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - - status = - proc_invalidate_memory(pr_ctxt, - args->args_proc_invalidatememory.mpu_addr, - args->args_proc_invalidatememory.size); - return status; -} - -/* - * ======== procwrap_enum_resources ======== - */ -u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_resourceinfo resource_info; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (args->args_proc_enumresources.resource_info_size < - sizeof(struct dsp_resourceinfo)) - return -EINVAL; - - status = - proc_get_resource_info(hprocessor, - args->args_proc_enumresources.resource_type, - &resource_info, - args->args_proc_enumresources. - resource_info_size); - - CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info, - status, 1); - - return status; - -} - -/* - * ======== procwrap_get_state ======== - */ -u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt) -{ - int status; - struct dsp_processorstate proc_state; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (args->args_proc_getstate.state_info_size < - sizeof(struct dsp_processorstate)) - return -EINVAL; - - status = proc_get_state(hprocessor, &proc_state, - args->args_proc_getstate.state_info_size); - CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status, - 1); - return status; - -} - -/* - * ======== procwrap_get_trace ======== - */ -u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt) -{ - int status; - u8 *pbuf; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN) - return -EINVAL; - - pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL); - if (pbuf != NULL) { - status = proc_get_trace(hprocessor, pbuf, - args->args_proc_gettrace.max_size); - } else { - status = -ENOMEM; - } - CP_TO_USR(args->args_proc_gettrace.buf, pbuf, status, - args->args_proc_gettrace.max_size); - kfree(pbuf); - - return status; -} - -/* - * ======== procwrap_load ======== - */ -u32 procwrap_load(union trapped_args *args, void *pr_ctxt) -{ - s32 i, len; - int status = 0; - char *temp; - s32 count = args->args_proc_load.argc_index; - u8 **argv = NULL, **envp = NULL; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (count <= 0 || count > MAX_LOADARGS) { - status = -EINVAL; - goto func_cont; - } - - argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL); - if (!argv) { - status = -ENOMEM; - goto func_cont; - } - - CP_FM_USR(argv, args->args_proc_load.user_args, status, count); - if (status) { - kfree(argv); - argv = NULL; - goto func_cont; - } - - for (i = 0; i < count; i++) { - if (argv[i]) { - /* User space pointer to argument */ - temp = (char *)argv[i]; - /* len is increased by 1 to accommodate NULL */ - len = strlen_user((char *)temp) + 1; - /* Kernel space pointer to argument */ - argv[i] = kmalloc(len, GFP_KERNEL); - if (argv[i]) { - CP_FM_USR(argv[i], temp, status, len); - if (status) { - kfree(argv[i]); - argv[i] = NULL; - goto func_cont; - } - } else { - status = -ENOMEM; - goto func_cont; - } - } - } - /* TODO: validate this */ - if (args->args_proc_load.user_envp) { - /* number of elements in the envp array including NULL */ - count = 0; - do { - if (get_user(temp, - args->args_proc_load.user_envp + count)) { - status = -EFAULT; - goto func_cont; - } - count++; - } while (temp); - envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL); - if (!envp) { - status = -ENOMEM; - goto func_cont; - } - - CP_FM_USR(envp, args->args_proc_load.user_envp, status, count); - if (status) { - kfree(envp); - envp = NULL; - goto func_cont; - } - for (i = 0; envp[i]; i++) { - /* User space pointer to argument */ - temp = (char *)envp[i]; - /* len is increased by 1 to accommodate NULL */ - len = strlen_user((char *)temp) + 1; - /* Kernel space pointer to argument */ - envp[i] = kmalloc(len, GFP_KERNEL); - if (envp[i]) { - CP_FM_USR(envp[i], temp, status, len); - if (status) { - kfree(envp[i]); - envp[i] = NULL; - goto func_cont; - } - } else { - status = -ENOMEM; - goto func_cont; - } - } - } - - if (!status) { - status = proc_load(hprocessor, - args->args_proc_load.argc_index, - (const char **)argv, (const char **)envp); - } -func_cont: - if (envp) { - i = 0; - while (envp[i]) - kfree(envp[i++]); - - kfree(envp); - } - - if (argv) { - count = args->args_proc_load.argc_index; - for (i = 0; (i < count) && argv[i]; i++) - kfree(argv[i]); - - kfree(argv); - } - - return status; -} - -/* - * ======== procwrap_map ======== - */ -u32 procwrap_map(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *map_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (!args->args_proc_mapmem.size) - return -EINVAL; - - status = proc_map(args->args_proc_mapmem.processor, - args->args_proc_mapmem.mpu_addr, - args->args_proc_mapmem.size, - args->args_proc_mapmem.req_addr, &map_addr, - args->args_proc_mapmem.map_attr, pr_ctxt); - if (!status) { - if (put_user(map_addr, args->args_proc_mapmem.map_addr)) { - status = -EINVAL; - proc_un_map(hprocessor, map_addr, pr_ctxt); - } - - } - return status; -} - -/* - * ======== procwrap_register_notify ======== - */ -u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) -{ - int status; - struct dsp_notification notification; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - status = proc_register_notify(hprocessor, - args->args_proc_register_notify.event_mask, - args->args_proc_register_notify.notify_type, - ¬ification); - CP_TO_USR(args->args_proc_register_notify.notification, ¬ification, - status, 1); - return status; -} - -/* - * ======== procwrap_reserve_memory ======== - */ -u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *prsv_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if ((args->args_proc_rsvmem.size <= 0) || - (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0) - return -EINVAL; - - status = proc_reserve_memory(hprocessor, - args->args_proc_rsvmem.size, &prsv_addr, - pr_ctxt); - if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) { - status = -EINVAL; - proc_un_reserve_memory(args->args_proc_rsvmem. - processor, prsv_addr, pr_ctxt); - } - } - return status; -} - -/* - * ======== procwrap_start ======== - */ -u32 procwrap_start(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - - ret = proc_start(((struct process_context *)pr_ctxt)->processor); - return ret; -} - -/* - * ======== procwrap_un_map ======== - */ -u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) -{ - int status; - - status = proc_un_map(((struct process_context *)pr_ctxt)->processor, - args->args_proc_unmapmem.map_addr, pr_ctxt); - return status; -} - -/* - * ======== procwrap_un_reserve_memory ======== - */ -u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.rsv_addr, - pr_ctxt); - return status; -} - -/* - * ======== procwrap_stop ======== - */ -u32 procwrap_stop(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - - ret = proc_stop(((struct process_context *)pr_ctxt)->processor); - - return ret; -} - -/* - * ======== find_handle ========= - */ -inline void find_node_handle(struct node_res_object **noderes, - void *pr_ctxt, void *hnode) -{ - rcu_read_lock(); - *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id, - (int)hnode - 1); - rcu_read_unlock(); - return; -} - - -/* - * ======== nodewrap_allocate ======== - */ -u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_uuid node_uuid; - u32 cb_data_size = 0; - u32 __user *psize = (u32 __user *) args->args_node_allocate.args; - u8 *pargs = NULL; - struct dsp_nodeattrin proc_attr_in, *attr_in = NULL; - struct node_res_object *node_res; - int nodeid; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - /* Optional argument */ - if (psize) { - if (get_user(cb_data_size, psize)) - status = -EPERM; - - cb_data_size += sizeof(u32); - if (!status) { - pargs = kmalloc(cb_data_size, GFP_KERNEL); - if (pargs == NULL) - status = -ENOMEM; - - } - CP_FM_USR(pargs, args->args_node_allocate.args, status, - cb_data_size); - } - CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1); - if (status) - goto func_cont; - /* Optional argument */ - if (args->args_node_allocate.attr_in) { - CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in, - status, 1); - if (!status) - attr_in = &proc_attr_in; - else - status = -ENOMEM; - - } - if (!status) { - status = node_allocate(hprocessor, - &node_uuid, (struct dsp_cbdata *)pargs, - attr_in, &node_res, pr_ctxt); - } - if (!status) { - nodeid = node_res->id + 1; - CP_TO_USR(args->args_node_allocate.node, &nodeid, - status, 1); - if (status) { - status = -EFAULT; - node_delete(node_res, pr_ctxt); - } - } -func_cont: - kfree(pargs); - - return status; -} - -/* - * ======== nodewrap_alloc_msg_buf ======== - */ -u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_bufferattr *pattr = NULL; - struct dsp_bufferattr attr; - u8 *pbuffer = NULL; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, - args->args_node_allocmsgbuf.node); - - if (!node_res) - return -EFAULT; - - if (!args->args_node_allocmsgbuf.size) - return -EINVAL; - - if (args->args_node_allocmsgbuf.attr) { /* Optional argument */ - CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1); - if (!status) - pattr = &attr; - - } - /* argument */ - CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1); - if (!status) { - status = node_alloc_msg_buf(node_res->node, - args->args_node_allocmsgbuf.size, - pattr, &pbuffer); - } - CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1); - return status; -} - -/* - * ======== nodewrap_change_priority ======== - */ -u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, - args->args_node_changepriority.node); - - if (!node_res) - return -EFAULT; - - ret = node_change_priority(node_res->node, - args->args_node_changepriority.prio); - - return ret; -} - -/* - * ======== nodewrap_connect ======== - */ -u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_strmattr attrs; - struct dsp_strmattr *pattrs = NULL; - u32 cb_data_size; - u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param; - u8 *pargs = NULL; - struct node_res_object *node_res1, *node_res2; - struct node_object *node1 = NULL, *node2 = NULL; - - if ((int)args->args_node_connect.node != DSP_HGPPNODE) { - find_node_handle(&node_res1, pr_ctxt, - args->args_node_connect.node); - if (node_res1) - node1 = node_res1->node; - } else { - node1 = args->args_node_connect.node; - } - - if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) { - find_node_handle(&node_res2, pr_ctxt, - args->args_node_connect.other_node); - if (node_res2) - node2 = node_res2->node; - } else { - node2 = args->args_node_connect.other_node; - } - - if (!node1 || !node2) - return -EFAULT; - - /* Optional argument */ - if (psize) { - if (get_user(cb_data_size, psize)) - status = -EPERM; - - cb_data_size += sizeof(u32); - if (!status) { - pargs = kmalloc(cb_data_size, GFP_KERNEL); - if (pargs == NULL) { - status = -ENOMEM; - goto func_cont; - } - - } - CP_FM_USR(pargs, args->args_node_connect.conn_param, status, - cb_data_size); - if (status) - goto func_cont; - } - if (args->args_node_connect.attrs) { /* Optional argument */ - CP_FM_USR(&attrs, args->args_node_connect.attrs, status, 1); - if (!status) - pattrs = &attrs; - - } - if (!status) { - status = node_connect(node1, - args->args_node_connect.stream_id, - node2, - args->args_node_connect.other_stream, - pattrs, (struct dsp_cbdata *)pargs); - } -func_cont: - kfree(pargs); - - return status; -} - -/* - * ======== nodewrap_create ======== - */ -u32 nodewrap_create(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_create.node); - - if (!node_res) - return -EFAULT; - - ret = node_create(node_res->node); - - return ret; -} - -/* - * ======== nodewrap_delete ======== - */ -u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_delete.node); - - if (!node_res) - return -EFAULT; - - ret = node_delete(node_res, pr_ctxt); - - return ret; -} - -/* - * ======== nodewrap_free_msg_buf ======== - */ -u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_bufferattr *pattr = NULL; - struct dsp_bufferattr attr; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.node); - - if (!node_res) - return -EFAULT; - - if (args->args_node_freemsgbuf.attr) { /* Optional argument */ - CP_FM_USR(&attr, args->args_node_freemsgbuf.attr, status, 1); - if (!status) - pattr = &attr; - - } - - if (!args->args_node_freemsgbuf.buffer) - return -EFAULT; - - if (!status) { - status = node_free_msg_buf(node_res->node, - args->args_node_freemsgbuf.buffer, - pattr); - } - - return status; -} - -/* - * ======== nodewrap_get_attr ======== - */ -u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_nodeattr attr; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.node); - - if (!node_res) - return -EFAULT; - - status = node_get_attr(node_res->node, &attr, - args->args_node_getattr.attr_size); - CP_TO_USR(args->args_node_getattr.attr, &attr, status, 1); - - return status; -} - -/* - * ======== nodewrap_get_message ======== - */ -u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt) -{ - int status; - struct dsp_msg msg; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.node); - - if (!node_res) - return -EFAULT; - - status = node_get_message(node_res->node, &msg, - args->args_node_getmessage.timeout); - - CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1); - - return status; -} - -/* - * ======== nodewrap_pause ======== - */ -u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_pause.node); - - if (!node_res) - return -EFAULT; - - ret = node_pause(node_res->node); - - return ret; -} - -/* - * ======== nodewrap_put_message ======== - */ -u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_msg msg; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.node); - - if (!node_res) - return -EFAULT; - - CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1); - - if (!status) { - status = - node_put_message(node_res->node, &msg, - args->args_node_putmessage.timeout); - } - - return status; -} - -/* - * ======== nodewrap_register_notify ======== - */ -u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_notification notification; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, - args->args_node_registernotify.node); - - if (!node_res) - return -EFAULT; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - if (!args->args_proc_register_notify.event_mask) - CP_FM_USR(¬ification, - args->args_proc_register_notify.notification, - status, 1); - - status = node_register_notify(node_res->node, - args->args_node_registernotify.event_mask, - args->args_node_registernotify. - notify_type, ¬ification); - CP_TO_USR(args->args_node_registernotify.notification, ¬ification, - status, 1); - return status; -} - -/* - * ======== nodewrap_run ======== - */ -u32 nodewrap_run(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_run.node); - - if (!node_res) - return -EFAULT; - - ret = node_run(node_res->node); - - return ret; -} - -/* - * ======== nodewrap_terminate ======== - */ -u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt) -{ - int status; - int tempstatus; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.node); - - if (!node_res) - return -EFAULT; - - status = node_terminate(node_res->node, &tempstatus); - - CP_TO_USR(args->args_node_terminate.status, &tempstatus, status, 1); - - return status; -} - -/* - * ======== nodewrap_get_uuid_props ======== - */ -u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_uuid node_uuid; - struct dsp_ndbprops *pnode_props = NULL; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status, - 1); - if (status) - goto func_cont; - pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL); - if (pnode_props != NULL) { - status = - node_get_uuid_props(hprocessor, &node_uuid, pnode_props); - CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props, - status, 1); - } else - status = -ENOMEM; -func_cont: - kfree(pnode_props); - return status; -} - -/* - * ======== find_strm_handle ========= - */ -inline void find_strm_handle(struct strm_res_object **strmres, - void *pr_ctxt, void *hstream) -{ - rcu_read_lock(); - *strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id, - (int)hstream - 1); - rcu_read_unlock(); - return; -} - -/* - * ======== strmwrap_allocate_buffer ======== - */ -u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt) -{ - int status; - u8 **ap_buffer = NULL; - u32 num_bufs = args->args_strm_allocatebuffer.num_bufs; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_allocatebuffer.stream); - - if (!strm_res) - return -EFAULT; - - if (num_bufs > MAX_BUFS) - return -EINVAL; - - ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL); - if (ap_buffer == NULL) - return -ENOMEM; - - status = strm_allocate_buffer(strm_res, - args->args_strm_allocatebuffer.size, - ap_buffer, num_bufs, pr_ctxt); - if (!status) { - CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer, - status, num_bufs); - if (status) { - status = -EFAULT; - strm_free_buffer(strm_res, - ap_buffer, num_bufs, pr_ctxt); - } - } - kfree(ap_buffer); - - return status; -} - -/* - * ======== strmwrap_close ======== - */ -u32 strmwrap_close(union trapped_args *args, void *pr_ctxt) -{ - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.stream); - - if (!strm_res) - return -EFAULT; - - return strm_close(strm_res, pr_ctxt); -} - -/* - * ======== strmwrap_free_buffer ======== - */ -u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - u8 **ap_buffer = NULL; - u32 num_bufs = args->args_strm_freebuffer.num_bufs; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_freebuffer.stream); - - if (!strm_res) - return -EFAULT; - - if (num_bufs > MAX_BUFS) - return -EINVAL; - - ap_buffer = kmalloc_array(num_bufs, sizeof(u8 *), GFP_KERNEL); - if (ap_buffer == NULL) - return -ENOMEM; - - CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status, - num_bufs); - - if (!status) - status = strm_free_buffer(strm_res, - ap_buffer, num_bufs, pr_ctxt); - - CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status, - num_bufs); - kfree(ap_buffer); - - return status; -} - -/* - * ======== strmwrap_get_event_handle ======== - */ -u32 __deprecated strmwrap_get_event_handle(union trapped_args *args, - void *pr_ctxt) -{ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return -ENOSYS; -} - -/* - * ======== strmwrap_get_info ======== - */ -u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct stream_info strm_info; - struct dsp_streaminfo user; - struct dsp_streaminfo *temp; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_getinfo.stream); - - if (!strm_res) - return -EFAULT; - - CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1); - temp = strm_info.user_strm; - - strm_info.user_strm = &user; - - if (!status) { - status = strm_get_info(strm_res->stream, - &strm_info, - args->args_strm_getinfo. - stream_info_size); - } - CP_TO_USR(temp, strm_info.user_strm, status, 1); - strm_info.user_strm = temp; - CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1); - return status; -} - -/* - * ======== strmwrap_idle ======== - */ -u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.stream); - - if (!strm_res) - return -EFAULT; - - ret = strm_idle(strm_res->stream, args->args_strm_idle.flush_flag); - - return ret; -} - -/* - * ======== strmwrap_issue ======== - */ -u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.stream); - - if (!strm_res) - return -EFAULT; - - if (!args->args_strm_issue.buffer) - return -EFAULT; - - /* No need of doing CP_FM_USR for the user buffer (pbuffer) - as this is done in Bridge internal function bridge_chnl_add_io_req - in chnl_sm.c */ - status = strm_issue(strm_res->stream, - args->args_strm_issue.buffer, - args->args_strm_issue.bytes, - args->args_strm_issue.buf_size, - args->args_strm_issue.arg); - - return status; -} - -/* - * ======== strmwrap_open ======== - */ -u32 strmwrap_open(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct strm_attr attr; - struct strm_res_object *strm_res_obj; - struct dsp_streamattrin strm_attr_in; - struct node_res_object *node_res; - int strmid; - - find_node_handle(&node_res, pr_ctxt, args->args_strm_open.node); - - if (!node_res) - return -EFAULT; - - CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1); - - if (attr.stream_attr_in != NULL) { /* Optional argument */ - CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1); - if (!status) { - attr.stream_attr_in = &strm_attr_in; - if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA) - return -ENOSYS; - } - - } - status = strm_open(node_res->node, - args->args_strm_open.direction, - args->args_strm_open.index, &attr, &strm_res_obj, - pr_ctxt); - if (!status) { - strmid = strm_res_obj->id + 1; - CP_TO_USR(args->args_strm_open.stream, &strmid, status, 1); - } - return status; -} - -/* - * ======== strmwrap_reclaim ======== - */ -u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - u8 *buf_ptr; - u32 ul_bytes; - u32 dw_arg; - u32 ul_buf_size; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.stream); - - if (!strm_res) - return -EFAULT; - - status = strm_reclaim(strm_res->stream, &buf_ptr, - &ul_bytes, &ul_buf_size, &dw_arg); - CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1); - CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1); - CP_TO_USR(args->args_strm_reclaim.arg, &dw_arg, status, 1); - - if (args->args_strm_reclaim.buf_size_ptr != NULL) { - CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size, - status, 1); - } - - return status; -} - -/* - * ======== strmwrap_register_notify ======== - */ -u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_notification notification; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_registernotify.stream); - - if (!strm_res) - return -EFAULT; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - status = strm_register_notify(strm_res->stream, - args->args_strm_registernotify.event_mask, - args->args_strm_registernotify. - notify_type, ¬ification); - CP_TO_USR(args->args_strm_registernotify.notification, ¬ification, - status, 1); - - return status; -} - -/* - * ======== strmwrap_select ======== - */ -u32 strmwrap_select(union trapped_args *args, void *pr_ctxt) -{ - u32 mask; - struct strm_object *strm_tab[MAX_STREAMS]; - int status = 0; - struct strm_res_object *strm_res; - int *ids[MAX_STREAMS]; - int i; - - if (args->args_strm_select.strm_num > MAX_STREAMS) - return -EINVAL; - - CP_FM_USR(ids, args->args_strm_select.stream_tab, status, - args->args_strm_select.strm_num); - - if (status) - return status; - - for (i = 0; i < args->args_strm_select.strm_num; i++) { - find_strm_handle(&strm_res, pr_ctxt, ids[i]); - - if (!strm_res) - return -EFAULT; - - strm_tab[i] = strm_res->stream; - } - - if (!status) { - status = strm_select(strm_tab, args->args_strm_select.strm_num, - &mask, args->args_strm_select.timeout); - } - CP_TO_USR(args->args_strm_select.mask, &mask, status, 1); - return status; -} - -/* CMM */ - -/* - * ======== cmmwrap_calloc_buf ======== - */ -u32 __deprecated cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt) -{ - /* This operation is done in kernel */ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return -ENOSYS; -} - -/* - * ======== cmmwrap_free_buf ======== - */ -u32 __deprecated cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt) -{ - /* This operation is done in kernel */ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return -ENOSYS; -} - -/* - * ======== cmmwrap_get_handle ======== - */ -u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct cmm_object *hcmm_mgr; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - status = cmm_get_handle(hprocessor, &hcmm_mgr); - - CP_TO_USR(args->args_cmm_gethandle.cmm_mgr, &hcmm_mgr, status, 1); - - return status; -} - -/* - * ======== cmmwrap_get_info ======== - */ -u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct cmm_info cmm_info_obj; - - status = cmm_get_info(args->args_cmm_getinfo.cmm_mgr, &cmm_info_obj); - - CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status, - 1); - - return status; -} diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c deleted file mode 100644 index 4073c9c672f..00000000000 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> - -/* ----------------------------------- This */ -#include <ioobj.h> -#include <dspbridge/io.h> - -/* - * ======== io_create ======== - * Purpose: - * Create an IO manager object, responsible for managing IO between - * CHNL and msg_ctrl - */ -int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, - const struct io_attrs *mgr_attrts) -{ - struct bridge_drv_interface *intf_fxns; - struct io_mgr *hio_mgr = NULL; - struct io_mgr_ *pio_mgr = NULL; - int status = 0; - - *io_man = NULL; - - /* A memory base of 0 implies no memory base: */ - if ((mgr_attrts->shm_base != 0) && (mgr_attrts->sm_length == 0)) - status = -EINVAL; - - if (mgr_attrts->word_size == 0) - status = -EINVAL; - - if (!status) { - dev_get_intf_fxns(hdev_obj, &intf_fxns); - - /* Let Bridge channel module finish the create: */ - status = (*intf_fxns->io_create) (&hio_mgr, hdev_obj, - mgr_attrts); - - if (!status) { - pio_mgr = (struct io_mgr_ *)hio_mgr; - pio_mgr->intf_fxns = intf_fxns; - pio_mgr->dev_obj = hdev_obj; - - /* Return the new channel manager handle: */ - *io_man = 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; - - intf_fxns = pio_mgr->intf_fxns; - - /* Let Bridge channel module destroy the io_mgr: */ - status = (*intf_fxns->io_destroy) (hio_mgr); - - return status; -} diff --git a/drivers/staging/tidspbridge/pmgr/ioobj.h b/drivers/staging/tidspbridge/pmgr/ioobj.h deleted file mode 100644 index 7defd948145..00000000000 --- a/drivers/staging/tidspbridge/pmgr/ioobj.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 *bridge_context; /* Bridge context. */ - /* Function interface to Bridge driver. */ - struct bridge_drv_interface *intf_fxns; - struct dev_object *dev_obj; /* Device this board represents. */ -}; - -#endif /* IOOBJ_ */ diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c deleted file mode 100644 index f093cfb51c0..00000000000 --- a/drivers/staging/tidspbridge/pmgr/msg.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Bridge Driver */ -#include <dspbridge/dspdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> - -/* ----------------------------------- This */ -#include <msgobj.h> -#include <dspbridge/msg.h> - -/* - * ======== msg_create ======== - * Purpose: - * Create an object to manage message queues. Only one of these objects - * can exist per device object. - */ -int msg_create(struct msg_mgr **msg_man, - struct dev_object *hdev_obj, msg_onexit msg_callback) -{ - struct bridge_drv_interface *intf_fxns; - struct msg_mgr_ *msg_mgr_obj; - struct msg_mgr *hmsg_mgr; - int status = 0; - - *msg_man = NULL; - - dev_get_intf_fxns(hdev_obj, &intf_fxns); - - /* Let Bridge message module finish the create: */ - status = - (*intf_fxns->msg_create) (&hmsg_mgr, hdev_obj, msg_callback); - - if (!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: */ - *msg_man = 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; - - if (msg_mgr_obj) { - intf_fxns = msg_mgr_obj->intf_fxns; - - /* Let Bridge message module destroy the msg_mgr: */ - (*intf_fxns->msg_delete) (hmsg_mgr); - } else { - dev_dbg(bridge, "%s: Error hmsg_mgr handle: %p\n", - __func__, hmsg_mgr); - } -} diff --git a/drivers/staging/tidspbridge/pmgr/msgobj.h b/drivers/staging/tidspbridge/pmgr/msgobj.h deleted file mode 100644 index 14ca633c56c..00000000000 --- a/drivers/staging/tidspbridge/pmgr/msgobj.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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_ */ diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c deleted file mode 100644 index 2ae48c9a936..00000000000 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * dbdcd.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This file contains the implementation of the DSP/BIOS Bridge - * Configuration Database (DCD). - * - * Notes: - * The fxn dcd_get_objects can apply a callback fxn to each DCD object - * that is located in a specified COFF file. At the moment, - * dcd_auto_register, dcd_auto_unregister, and NLDR module all use - * dcd_get_objects. - * - * 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. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/cod.h> - -/* ----------------------------------- Others */ -#include <dspbridge/uuidutil.h> - -/* ----------------------------------- This */ -#include <dspbridge/dbdcd.h> - -/* ----------------------------------- Global defines. */ -#define MAX_INT2CHAR_LENGTH 16 /* Max int2char len of 32 bit int */ - -/* Name of section containing dependent libraries */ -#define DEPLIBSECT ".dspbridge_deplibs" - -/* DCD specific structures. */ -struct dcd_manager { - struct cod_manager *cod_mgr; /* Handle to COD manager object. */ -}; - -/* Pointer to the registry support key */ -static struct list_head reg_key_list; -static DEFINE_SPINLOCK(dbdcd_lock); - -/* Global reference variables. */ -static u32 refs; -static u32 enum_refs; - -/* Helper function prototypes. */ -static s32 atoi(char *psz_buf); -static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, - enum dsp_dcdobjtype obj_type, - struct dcd_genericobj *gen_obj); -static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size); -static char dsp_char2_gpp_char(char *word, s32 dsp_char_size); -static int get_dep_lib_info(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - u16 *num_libs, - u16 *num_pers_libs, - struct dsp_uuid *dep_lib_uuids, - bool *prstnt_dep_libs, - enum nldr_phase phase); - -/* - * ======== dcd_uuid_from_string ======== - * Purpose: - * Converts an ANSI string to a dsp_uuid. - * Parameters: - * sz_uuid: Pointer to a string that represents a dsp_uuid object. - * uuid_obj: Pointer to a dsp_uuid object. - * Returns: - * 0: Success. - * -EINVAL: Coversion failed - * Requires: - * uuid_obj & sz_uuid are non-NULL values. - * Ensures: - * Details: - * We assume the string representation of a UUID has the following format: - * "12345678_1234_1234_1234_123456789abc". - */ -static int dcd_uuid_from_string(char *sz_uuid, struct dsp_uuid *uuid_obj) -{ - char c; - u64 t; - struct dsp_uuid uuid_tmp; - - /* - * sscanf implementation cannot deal with hh format modifier - * if the converted value doesn't fit in u32. So, convert the - * last six bytes to u64 and memcpy what is needed - */ - if (sscanf(sz_uuid, "%8x%c%4hx%c%4hx%c%2hhx%2hhx%c%llx", - &uuid_tmp.data1, &c, &uuid_tmp.data2, &c, - &uuid_tmp.data3, &c, &uuid_tmp.data4, - &uuid_tmp.data5, &c, &t) != 10) - return -EINVAL; - - t = cpu_to_be64(t); - memcpy(&uuid_tmp.data6[0], ((char *)&t) + 2, 6); - *uuid_obj = uuid_tmp; - - return 0; -} - -/* - * ======== dcd_auto_register ======== - * Purpose: - * Parses the supplied image and resigsters with DCD. - */ -int dcd_auto_register(struct dcd_manager *hdcd_mgr, - char *sz_coff_path) -{ - int status = 0; - - if (hdcd_mgr) - status = dcd_get_objects(hdcd_mgr, sz_coff_path, - (dcd_registerfxn) dcd_register_object, - (void *)sz_coff_path); - else - status = -EFAULT; - - return status; -} - -/* - * ======== dcd_auto_unregister ======== - * Purpose: - * Parses the supplied DSP image and unresiters from DCD. - */ -int dcd_auto_unregister(struct dcd_manager *hdcd_mgr, - char *sz_coff_path) -{ - int status = 0; - - if (hdcd_mgr) - status = dcd_get_objects(hdcd_mgr, sz_coff_path, - (dcd_registerfxn) dcd_register_object, - NULL); - else - status = -EFAULT; - - return status; -} - -/* - * ======== dcd_create_manager ======== - * Purpose: - * Creates DCD manager. - */ -int dcd_create_manager(char *sz_zl_dll_name, - struct dcd_manager **dcd_mgr) -{ - struct cod_manager *cod_mgr; /* COD manager handle */ - struct dcd_manager *dcd_mgr_obj = NULL; /* DCD Manager pointer */ - int status = 0; - - status = cod_create(&cod_mgr, sz_zl_dll_name); - if (status) - goto func_end; - - /* Create a DCD object. */ - dcd_mgr_obj = kzalloc(sizeof(struct dcd_manager), GFP_KERNEL); - if (dcd_mgr_obj != NULL) { - /* Fill out the object. */ - dcd_mgr_obj->cod_mgr = cod_mgr; - - /* Return handle to this DCD interface. */ - *dcd_mgr = dcd_mgr_obj; - } else { - status = -ENOMEM; - - /* - * If allocation of DcdManager object failed, delete the - * COD manager. - */ - cod_delete(cod_mgr); - } - -func_end: - return status; -} - -/* - * ======== dcd_destroy_manager ======== - * Purpose: - * Frees DCD Manager object. - */ -int dcd_destroy_manager(struct dcd_manager *hdcd_mgr) -{ - struct dcd_manager *dcd_mgr_obj = hdcd_mgr; - int status = -EFAULT; - - if (hdcd_mgr) { - /* Delete the COD manager. */ - cod_delete(dcd_mgr_obj->cod_mgr); - - /* Deallocate a DCD manager object. */ - kfree(dcd_mgr_obj); - - status = 0; - } - - return status; -} - -/* - * ======== dcd_enumerate_object ======== - * Purpose: - * Enumerates objects in the DCD. - */ -int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type, - struct dsp_uuid *uuid_obj) -{ - int status = 0; - char sz_reg_key[DCD_MAXPATHLENGTH]; - char sz_value[DCD_MAXPATHLENGTH]; - struct dsp_uuid dsp_uuid_obj; - char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */ - u32 dw_key_len = 0; - struct dcd_key_elem *dcd_key; - int len; - - if ((index != 0) && (enum_refs == 0)) { - /* - * If an enumeration is being performed on an index greater - * than zero, then the current enum_refs must have been - * incremented to greater than zero. - */ - status = -EIDRM; - } else { - /* - * Pre-determine final key length. It's length of DCD_REGKEY + - * "_\0" + length of sz_obj_type string + terminating NULL. - */ - dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - - /* Create proper REG key; concatenate DCD_REGKEY with - * obj_type. */ - strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); - if ((strlen(sz_reg_key) + strlen("_\0")) < - DCD_MAXPATHLENGTH) { - strncat(sz_reg_key, "_\0", 2); - } else { - status = -EPERM; - } - - /* This snprintf is guaranteed not to exceed max size of an - * integer. */ - status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", - obj_type); - - if (status == -1) { - status = -EPERM; - } else { - status = 0; - if ((strlen(sz_reg_key) + strlen(sz_obj_type)) < - DCD_MAXPATHLENGTH) { - strncat(sz_reg_key, sz_obj_type, - strlen(sz_obj_type) + 1); - } else { - status = -EPERM; - } - } - - if (!status) { - len = strlen(sz_reg_key); - spin_lock(&dbdcd_lock); - list_for_each_entry(dcd_key, ®_key_list, link) { - if (!strncmp(dcd_key->name, sz_reg_key, len) - && !index--) { - strncpy(sz_value, &dcd_key->name[len], - strlen(&dcd_key->name[len]) + 1); - break; - } - } - spin_unlock(&dbdcd_lock); - - if (&dcd_key->link == ®_key_list) - status = -ENODATA; - } - - if (!status) { - /* Create UUID value using string retrieved from - * registry. */ - status = dcd_uuid_from_string(sz_value, &dsp_uuid_obj); - - if (!status) { - *uuid_obj = dsp_uuid_obj; - - /* Increment enum_refs to update reference - * count. */ - enum_refs++; - } - } else if (status == -ENODATA) { - /* At the end of enumeration. Reset enum_refs. */ - enum_refs = 0; - - /* - * TODO: Revisit, this is not an error case but code - * expects non-zero value. - */ - status = ENODATA; - } else { - status = -EPERM; - } - } - - return status; -} - -/* - * ======== dcd_exit ======== - * Purpose: - * Discontinue usage of the DCD module. - */ -void dcd_exit(void) -{ - struct dcd_key_elem *rv, *rv_tmp; - - refs--; - if (refs == 0) { - list_for_each_entry_safe(rv, rv_tmp, ®_key_list, link) { - list_del(&rv->link); - kfree(rv->path); - kfree(rv); - } - } - -} - -/* - * ======== dcd_get_dep_libs ======== - */ -int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - u16 num_libs, struct dsp_uuid *dep_lib_uuids, - bool *prstnt_dep_libs, - enum nldr_phase phase) -{ - int status = 0; - - status = - get_dep_lib_info(hdcd_mgr, uuid_obj, &num_libs, NULL, dep_lib_uuids, - prstnt_dep_libs, phase); - - return status; -} - -/* - * ======== dcd_get_num_dep_libs ======== - */ -int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - u16 *num_libs, u16 *num_pers_libs, - enum nldr_phase phase) -{ - int status = 0; - - status = get_dep_lib_info(hdcd_mgr, uuid_obj, num_libs, num_pers_libs, - NULL, NULL, phase); - - return status; -} - -/* - * ======== dcd_get_object_def ======== - * Purpose: - * Retrieves the properties of a node or processor based on the UUID and - * object type. - */ -int dcd_get_object_def(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *obj_uuid, - enum dsp_dcdobjtype obj_type, - struct dcd_genericobj *obj_def) -{ - struct dcd_manager *dcd_mgr_obj = hdcd_mgr; /* ptr to DCD mgr */ - struct cod_libraryobj *lib = NULL; - int status = 0; - int len; - u32 ul_addr = 0; /* Used by cod_get_section */ - u32 ul_len = 0; /* Used by cod_get_section */ - u32 dw_buf_size; /* Used by REG functions */ - char sz_reg_key[DCD_MAXPATHLENGTH]; - char *sz_uuid; /*[MAXUUIDLEN]; */ - char *tmp; - struct dcd_key_elem *dcd_key = NULL; - char sz_sect_name[MAXUUIDLEN + 2]; /* ".[UUID]\0" */ - char *psz_coff_buf; - u32 dw_key_len; /* Len of REG key. */ - char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */ - - sz_uuid = kzalloc(MAXUUIDLEN, GFP_KERNEL); - if (!sz_uuid) { - status = -ENOMEM; - goto func_end; - } - - if (!hdcd_mgr) { - status = -EFAULT; - goto func_end; - } - - /* Pre-determine final key length. It's length of DCD_REGKEY + - * "_\0" + length of sz_obj_type string + terminating NULL */ - dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - - /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */ - strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); - - if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH) - strncat(sz_reg_key, "_\0", 2); - else - status = -EPERM; - - status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type); - if (status == -1) { - status = -EPERM; - } else { - status = 0; - - if ((strlen(sz_reg_key) + strlen(sz_obj_type)) < - DCD_MAXPATHLENGTH) { - strncat(sz_reg_key, sz_obj_type, - strlen(sz_obj_type) + 1); - } else { - status = -EPERM; - } - - /* Create UUID value to set in registry. */ - snprintf(sz_uuid, MAXUUIDLEN, "%pUL", obj_uuid); - - if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) - strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); - else - status = -EPERM; - - /* Retrieve paths from the registry based on struct dsp_uuid */ - dw_buf_size = DCD_MAXPATHLENGTH; - } - if (!status) { - spin_lock(&dbdcd_lock); - list_for_each_entry(dcd_key, ®_key_list, link) { - if (!strncmp(dcd_key->name, sz_reg_key, - strlen(sz_reg_key) + 1)) - break; - } - spin_unlock(&dbdcd_lock); - if (&dcd_key->link == ®_key_list) { - status = -ENOKEY; - goto func_end; - } - } - - - /* Open COFF file. */ - status = cod_open(dcd_mgr_obj->cod_mgr, dcd_key->path, - COD_NOLOAD, &lib); - if (status) { - status = -EACCES; - goto func_end; - } - - /* Ensure sz_uuid + 1 is not greater than sizeof sz_sect_name. */ - len = strlen(sz_uuid); - if (len + 1 > sizeof(sz_sect_name)) { - status = -EPERM; - goto func_end; - } - - /* Create section name based on node UUID. A period is - * pre-pended to the UUID string to form the section name. - * I.e. ".24BC8D90_BB45_11d4_B756_006008BDB66F" */ - - len -= 4; /* uuid has 4 delimiters '-' */ - tmp = sz_uuid; - - strncpy(sz_sect_name, ".", 2); - do { - char *uuid = strsep(&tmp, "-"); - if (!uuid) - break; - len -= strlen(uuid); - strncat(sz_sect_name, uuid, strlen(uuid) + 1); - } while (len && strncat(sz_sect_name, "_", 2)); - - /* Get section information. */ - status = cod_get_section(lib, sz_sect_name, &ul_addr, &ul_len); - if (status) { - status = -EACCES; - goto func_end; - } - - /* Allocate zeroed buffer. */ - psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL); - if (psz_coff_buf == NULL) { - status = -ENOMEM; - goto func_end; - } -#ifdef _DB_TIOMAP - if (strstr(dcd_key->path, "iva") == NULL) { - /* Locate section by objectID and read its content. */ - status = - cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len); - } else { - status = - cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len); - dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__); - } -#else - status = cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len); -#endif - if (!status) { - /* Compress DSP buffer to conform to PC format. */ - if (strstr(dcd_key->path, "iva") == NULL) { - compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE); - } else { - compress_buf(psz_coff_buf, ul_len, 1); - dev_dbg(bridge, "%s: Compressing IVA COFF buffer by 1 " - "for IVA!!\n", __func__); - } - - /* Parse the content of the COFF buffer. */ - status = - get_attrs_from_buf(psz_coff_buf, ul_len, obj_type, obj_def); - if (status) - status = -EACCES; - } else { - status = -EACCES; - } - - /* Free the previously allocated dynamic buffer. */ - kfree(psz_coff_buf); -func_end: - if (lib) - cod_close(lib); - - kfree(sz_uuid); - - return status; -} - -/* - * ======== dcd_get_objects ======== - */ -int dcd_get_objects(struct dcd_manager *hdcd_mgr, - char *sz_coff_path, dcd_registerfxn register_fxn, - void *handle) -{ - struct dcd_manager *dcd_mgr_obj = hdcd_mgr; - int status = 0; - char *psz_coff_buf; - char *psz_cur; - struct cod_libraryobj *lib = NULL; - u32 ul_addr = 0; /* Used by cod_get_section */ - u32 ul_len = 0; /* Used by cod_get_section */ - char seps[] = ":, "; - char *token = NULL; - struct dsp_uuid dsp_uuid_obj; - s32 object_type; - - if (!hdcd_mgr) { - status = -EFAULT; - goto func_end; - } - - /* Open DSP coff file, don't load symbols. */ - status = cod_open(dcd_mgr_obj->cod_mgr, sz_coff_path, COD_NOLOAD, &lib); - if (status) { - status = -EACCES; - goto func_cont; - } - - /* Get DCD_RESIGER_SECTION section information. */ - status = cod_get_section(lib, DCD_REGISTER_SECTION, &ul_addr, &ul_len); - if (status || !(ul_len > 0)) { - status = -EACCES; - goto func_cont; - } - - /* Allocate zeroed buffer. */ - psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL); - if (psz_coff_buf == NULL) { - status = -ENOMEM; - goto func_cont; - } -#ifdef _DB_TIOMAP - if (strstr(sz_coff_path, "iva") == NULL) { - /* Locate section by objectID and read its content. */ - status = cod_read_section(lib, DCD_REGISTER_SECTION, - psz_coff_buf, ul_len); - } else { - dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__); - status = cod_read_section(lib, DCD_REGISTER_SECTION, - psz_coff_buf, ul_len); - } -#else - status = - cod_read_section(lib, DCD_REGISTER_SECTION, psz_coff_buf, ul_len); -#endif - if (!status) { - /* Compress DSP buffer to conform to PC format. */ - if (strstr(sz_coff_path, "iva") == NULL) { - compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE); - } else { - compress_buf(psz_coff_buf, ul_len, 1); - dev_dbg(bridge, "%s: Compress COFF buffer with 1 word " - "for IVA!!\n", __func__); - } - - /* Read from buffer and register object in buffer. */ - psz_cur = psz_coff_buf; - while ((token = strsep(&psz_cur, seps)) && *token != '\0') { - /* Retrieve UUID string. */ - status = dcd_uuid_from_string(token, &dsp_uuid_obj); - - if (!status) { - /* Retrieve object type */ - token = strsep(&psz_cur, seps); - - /* Retrieve object type */ - object_type = atoi(token); - - /* - * Apply register_fxn to the found DCD object. - * Possible actions include: - * - * 1) Register found DCD object. - * 2) Unregister found DCD object - * (when handle == NULL) - * 3) Add overlay node. - */ - status = - register_fxn(&dsp_uuid_obj, object_type, - handle); - } - if (status) { - /* if error occurs, break from while loop. */ - break; - } - } - } else { - status = -EACCES; - } - - /* Free the previously allocated dynamic buffer. */ - kfree(psz_coff_buf); -func_cont: - if (lib) - cod_close(lib); - -func_end: - return status; -} - -/* - * ======== dcd_get_library_name ======== - * Purpose: - * Retrieves the library name for the given UUID. - * - */ -int dcd_get_library_name(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - char *str_lib_name, - u32 *buff_size, - enum nldr_phase phase, bool *phase_split) -{ - char sz_reg_key[DCD_MAXPATHLENGTH]; - char sz_uuid[MAXUUIDLEN]; - u32 dw_key_len; /* Len of REG key. */ - char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */ - int status = 0; - struct dcd_key_elem *dcd_key = NULL; - - dev_dbg(bridge, "%s: hdcd_mgr %p, uuid_obj %p, str_lib_name %p," - " buff_size %p\n", __func__, hdcd_mgr, uuid_obj, str_lib_name, - buff_size); - - /* - * Pre-determine final key length. It's length of DCD_REGKEY + - * "_\0" + length of sz_obj_type string + terminating NULL. - */ - dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - - /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */ - strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); - if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH) - strncat(sz_reg_key, "_\0", 2); - else - status = -EPERM; - - switch (phase) { - case NLDR_CREATE: - /* create phase type */ - sprintf(sz_obj_type, "%d", DSP_DCDCREATELIBTYPE); - break; - case NLDR_EXECUTE: - /* execute phase type */ - sprintf(sz_obj_type, "%d", DSP_DCDEXECUTELIBTYPE); - break; - case NLDR_DELETE: - /* delete phase type */ - sprintf(sz_obj_type, "%d", DSP_DCDDELETELIBTYPE); - break; - case NLDR_NOPHASE: - /* known to be a dependent library */ - sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE); - break; - default: - status = -EINVAL; - } - if (!status) { - if ((strlen(sz_reg_key) + strlen(sz_obj_type)) < - DCD_MAXPATHLENGTH) { - strncat(sz_reg_key, sz_obj_type, - strlen(sz_obj_type) + 1); - } else { - status = -EPERM; - } - /* Create UUID value to find match in registry. */ - snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj); - if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) - strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); - else - status = -EPERM; - } - if (!status) { - spin_lock(&dbdcd_lock); - list_for_each_entry(dcd_key, ®_key_list, link) { - /* See if the name matches. */ - if (!strncmp(dcd_key->name, sz_reg_key, - strlen(sz_reg_key) + 1)) - break; - } - spin_unlock(&dbdcd_lock); - } - - if (&dcd_key->link == ®_key_list) - status = -ENOKEY; - - /* If can't find, phases might be registered as generic LIBRARYTYPE */ - if (status && phase != NLDR_NOPHASE) { - if (phase_split) - *phase_split = false; - - strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); - if ((strlen(sz_reg_key) + strlen("_\0")) < - DCD_MAXPATHLENGTH) { - strncat(sz_reg_key, "_\0", 2); - } else { - status = -EPERM; - } - sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE); - if ((strlen(sz_reg_key) + strlen(sz_obj_type)) - < DCD_MAXPATHLENGTH) { - strncat(sz_reg_key, sz_obj_type, - strlen(sz_obj_type) + 1); - } else { - status = -EPERM; - } - snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj); - if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) - strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); - else - status = -EPERM; - - spin_lock(&dbdcd_lock); - list_for_each_entry(dcd_key, ®_key_list, link) { - /* See if the name matches. */ - if (!strncmp(dcd_key->name, sz_reg_key, - strlen(sz_reg_key) + 1)) - break; - } - spin_unlock(&dbdcd_lock); - - status = (&dcd_key->link != ®_key_list) ? - 0 : -ENOKEY; - } - - if (!status) - memcpy(str_lib_name, dcd_key->path, strlen(dcd_key->path) + 1); - return status; -} - -/* - * ======== dcd_init ======== - * Purpose: - * Initialize the DCD module. - */ -bool dcd_init(void) -{ - bool ret = true; - - if (refs == 0) - INIT_LIST_HEAD(®_key_list); - - if (ret) - refs++; - - return ret; -} - -/* - * ======== dcd_register_object ======== - * Purpose: - * Registers a node or a processor with the DCD. - * If psz_path_name == NULL, unregister the specified DCD object. - */ -int dcd_register_object(struct dsp_uuid *uuid_obj, - enum dsp_dcdobjtype obj_type, - char *psz_path_name) -{ - int status = 0; - char sz_reg_key[DCD_MAXPATHLENGTH]; - char sz_uuid[MAXUUIDLEN + 1]; - u32 dw_path_size = 0; - u32 dw_key_len; /* Len of REG key. */ - char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */ - struct dcd_key_elem *dcd_key = NULL; - - dev_dbg(bridge, "%s: object UUID %p, obj_type %d, szPathName %s\n", - __func__, uuid_obj, obj_type, psz_path_name); - - /* - * Pre-determine final key length. It's length of DCD_REGKEY + - * "_\0" + length of sz_obj_type string + terminating NULL. - */ - dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - - /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */ - strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); - if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH) - strncat(sz_reg_key, "_\0", 2); - else { - status = -EPERM; - goto func_end; - } - - status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type); - if (status == -1) { - status = -EPERM; - } else { - status = 0; - if ((strlen(sz_reg_key) + strlen(sz_obj_type)) < - DCD_MAXPATHLENGTH) { - strncat(sz_reg_key, sz_obj_type, - strlen(sz_obj_type) + 1); - } else - status = -EPERM; - - /* Create UUID value to set in registry. */ - snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj); - if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH) - strncat(sz_reg_key, sz_uuid, MAXUUIDLEN); - else - status = -EPERM; - } - - if (status) - goto func_end; - - /* - * If psz_path_name != NULL, perform registration, otherwise, - * perform unregistration. - */ - - if (psz_path_name) { - dw_path_size = strlen(psz_path_name) + 1; - spin_lock(&dbdcd_lock); - list_for_each_entry(dcd_key, ®_key_list, link) { - /* See if the name matches. */ - if (!strncmp(dcd_key->name, sz_reg_key, - strlen(sz_reg_key) + 1)) - break; - } - spin_unlock(&dbdcd_lock); - if (&dcd_key->link == ®_key_list) { - /* - * Add new reg value (UUID+obj_type) - * with COFF path info - */ - - dcd_key = kmalloc(sizeof(struct dcd_key_elem), - GFP_KERNEL); - if (!dcd_key) { - status = -ENOMEM; - goto func_end; - } - - dcd_key->path = kmalloc(dw_path_size, GFP_KERNEL); - - if (!dcd_key->path) { - kfree(dcd_key); - status = -ENOMEM; - goto func_end; - } - - strncpy(dcd_key->name, sz_reg_key, - strlen(sz_reg_key) + 1); - strncpy(dcd_key->path, psz_path_name , - dw_path_size); - spin_lock(&dbdcd_lock); - list_add_tail(&dcd_key->link, ®_key_list); - spin_unlock(&dbdcd_lock); - } else { - /* Make sure the new data is the same. */ - if (strncmp(dcd_key->path, psz_path_name, - dw_path_size)) { - /* The caller needs a different data size! */ - kfree(dcd_key->path); - dcd_key->path = kmalloc(dw_path_size, - GFP_KERNEL); - if (dcd_key->path == NULL) { - status = -ENOMEM; - goto func_end; - } - } - - /* We have a match! Copy out the data. */ - memcpy(dcd_key->path, psz_path_name, dw_path_size); - } - dev_dbg(bridge, "%s: psz_path_name=%s, dw_path_size=%d\n", - __func__, psz_path_name, dw_path_size); - } else { - /* Deregister an existing object */ - spin_lock(&dbdcd_lock); - list_for_each_entry(dcd_key, ®_key_list, link) { - if (!strncmp(dcd_key->name, sz_reg_key, - strlen(sz_reg_key) + 1)) { - list_del(&dcd_key->link); - kfree(dcd_key->path); - kfree(dcd_key); - break; - } - } - spin_unlock(&dbdcd_lock); - if (&dcd_key->link == ®_key_list) - status = -EPERM; - } - - if (!status) { - /* - * Because the node database has been updated through a - * successful object registration/de-registration operation, - * we need to reset the object enumeration counter to allow - * current enumerations to reflect this update in the node - * database. - */ - enum_refs = 0; - } -func_end: - return status; -} - -/* - * ======== dcd_unregister_object ======== - * Call DCD_Register object with psz_path_name set to NULL to - * perform actual object de-registration. - */ -int dcd_unregister_object(struct dsp_uuid *uuid_obj, - enum dsp_dcdobjtype obj_type) -{ - int status = 0; - - /* - * When dcd_register_object is called with NULL as pathname, - * it indicates an unregister object operation. - */ - status = dcd_register_object(uuid_obj, obj_type, NULL); - - return status; -} - -/* - ********************************************************************** - * DCD Helper Functions - ********************************************************************** - */ - -/* - * ======== atoi ======== - * Purpose: - * This function converts strings in decimal or hex format to integers. - */ -static s32 atoi(char *psz_buf) -{ - char *pch = psz_buf; - s32 base = 0; - - while (isspace(*pch)) - pch++; - - if (*pch == '-' || *pch == '+') { - base = 10; - pch++; - } else if (*pch && tolower(pch[strlen(pch) - 1]) == 'h') { - base = 16; - } - - return simple_strtoul(pch, NULL, base); -} - -/* - * ======== get_attrs_from_buf ======== - * Purpose: - * Parse the content of a buffer filled with DSP-side data and - * retrieve an object's attributes from it. IMPORTANT: Assume the - * buffer has been converted from DSP format to GPP format. - */ -static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, - enum dsp_dcdobjtype obj_type, - struct dcd_genericobj *gen_obj) -{ - int status = 0; - char seps[] = ", "; - char *psz_cur; - char *token; - s32 token_len = 0; - u32 i = 0; -#ifdef _DB_TIOMAP - s32 entry_id; -#endif - - switch (obj_type) { - case DSP_DCDNODETYPE: - /* - * Parse COFF sect buffer to retrieve individual tokens used - * to fill in object attrs. - */ - psz_cur = psz_buf; - token = strsep(&psz_cur, seps); - - /* u32 cb_struct */ - gen_obj->obj_data.node_obj.ndb_props.cb_struct = - (u32) atoi(token); - token = strsep(&psz_cur, seps); - - /* dsp_uuid ui_node_id */ - status = dcd_uuid_from_string(token, - &gen_obj->obj_data.node_obj. - ndb_props.ui_node_id); - if (status) - break; - - token = strsep(&psz_cur, seps); - - /* ac_name */ - token_len = strlen(token); - if (token_len > DSP_MAXNAMELEN - 1) - token_len = DSP_MAXNAMELEN - 1; - - strncpy(gen_obj->obj_data.node_obj.ndb_props.ac_name, - token, token_len); - gen_obj->obj_data.node_obj.ndb_props.ac_name[token_len] = '\0'; - token = strsep(&psz_cur, seps); - /* u32 ntype */ - gen_obj->obj_data.node_obj.ndb_props.ntype = atoi(token); - token = strsep(&psz_cur, seps); - /* u32 cache_on_gpp */ - gen_obj->obj_data.node_obj.ndb_props.cache_on_gpp = atoi(token); - token = strsep(&psz_cur, seps); - /* dsp_resourcereqmts dsp_resource_reqmts */ - gen_obj->obj_data.node_obj.ndb_props.dsp_resource_reqmts. - cb_struct = (u32) atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.static_data_size = atoi(token); - token = strsep(&psz_cur, seps); - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.global_data_size = atoi(token); - token = strsep(&psz_cur, seps); - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.program_mem_size = atoi(token); - token = strsep(&psz_cur, seps); - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.wc_execution_time = atoi(token); - token = strsep(&psz_cur, seps); - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.wc_period = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.wc_deadline = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.avg_exection_time = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.minimum_period = atoi(token); - token = strsep(&psz_cur, seps); - - /* s32 prio */ - gen_obj->obj_data.node_obj.ndb_props.prio = atoi(token); - token = strsep(&psz_cur, seps); - - /* u32 stack_size */ - gen_obj->obj_data.node_obj.ndb_props.stack_size = atoi(token); - token = strsep(&psz_cur, seps); - - /* u32 sys_stack_size */ - gen_obj->obj_data.node_obj.ndb_props.sys_stack_size = - atoi(token); - token = strsep(&psz_cur, seps); - - /* u32 stack_seg */ - gen_obj->obj_data.node_obj.ndb_props.stack_seg = atoi(token); - token = strsep(&psz_cur, seps); - - /* u32 message_depth */ - gen_obj->obj_data.node_obj.ndb_props.message_depth = - atoi(token); - token = strsep(&psz_cur, seps); - - /* u32 num_input_streams */ - gen_obj->obj_data.node_obj.ndb_props.num_input_streams = - atoi(token); - token = strsep(&psz_cur, seps); - - /* u32 num_output_streams */ - gen_obj->obj_data.node_obj.ndb_props.num_output_streams = - atoi(token); - token = strsep(&psz_cur, seps); - - /* u32 timeout */ - gen_obj->obj_data.node_obj.ndb_props.timeout = atoi(token); - token = strsep(&psz_cur, seps); - - /* char *str_create_phase_fxn */ - token_len = strlen(token); - gen_obj->obj_data.node_obj.str_create_phase_fxn = - kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.str_create_phase_fxn, - token, token_len); - gen_obj->obj_data.node_obj.str_create_phase_fxn[token_len] = - '\0'; - token = strsep(&psz_cur, seps); - - /* char *str_execute_phase_fxn */ - token_len = strlen(token); - gen_obj->obj_data.node_obj.str_execute_phase_fxn = - kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.str_execute_phase_fxn, - token, token_len); - gen_obj->obj_data.node_obj.str_execute_phase_fxn[token_len] = - '\0'; - token = strsep(&psz_cur, seps); - - /* char *str_delete_phase_fxn */ - token_len = strlen(token); - gen_obj->obj_data.node_obj.str_delete_phase_fxn = - kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.str_delete_phase_fxn, - token, token_len); - gen_obj->obj_data.node_obj.str_delete_phase_fxn[token_len] = - '\0'; - token = strsep(&psz_cur, seps); - - /* Segment id for message buffers */ - gen_obj->obj_data.node_obj.msg_segid = atoi(token); - token = strsep(&psz_cur, seps); - - /* Message notification type */ - gen_obj->obj_data.node_obj.msg_notify_type = atoi(token); - token = strsep(&psz_cur, seps); - - /* char *str_i_alg_name */ - if (token) { - token_len = strlen(token); - gen_obj->obj_data.node_obj.str_i_alg_name = - kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.str_i_alg_name, - token, token_len); - gen_obj->obj_data.node_obj.str_i_alg_name[token_len] = - '\0'; - token = strsep(&psz_cur, seps); - } - - /* Load type (static, dynamic, or overlay) */ - if (token) { - gen_obj->obj_data.node_obj.load_type = atoi(token); - token = strsep(&psz_cur, seps); - } - - /* Dynamic load data requirements */ - if (token) { - gen_obj->obj_data.node_obj.data_mem_seg_mask = - atoi(token); - token = strsep(&psz_cur, seps); - } - - /* Dynamic load code requirements */ - if (token) { - gen_obj->obj_data.node_obj.code_mem_seg_mask = - atoi(token); - token = strsep(&psz_cur, seps); - } - - /* Extract node profiles into node properties */ - if (token) { - - gen_obj->obj_data.node_obj.ndb_props.count_profiles = - atoi(token); - for (i = 0; - i < - gen_obj->obj_data.node_obj. - ndb_props.count_profiles; i++) { - token = strsep(&psz_cur, seps); - if (token) { - /* Heap Size for the node */ - gen_obj->obj_data.node_obj. - ndb_props.node_profiles[i]. - heap_size = atoi(token); - } - } - } - token = strsep(&psz_cur, seps); - if (token) { - gen_obj->obj_data.node_obj.ndb_props.stack_seg_name = - (u32) (token); - } - - break; - - case DSP_DCDPROCESSORTYPE: - /* - * Parse COFF sect buffer to retrieve individual tokens used - * to fill in object attrs. - */ - psz_cur = psz_buf; - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.cb_struct = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.processor_family = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.processor_type = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.clock_rate = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.internal_mem_size = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.external_mem_size = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.processor_id = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.ty_running_rtos = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.node_min_priority = atoi(token); - token = strsep(&psz_cur, seps); - - gen_obj->obj_data.proc_info.node_max_priority = atoi(token); - -#ifdef _DB_TIOMAP - /* Proc object may contain additional(extended) attributes. */ - /* attr must match proc.hxx */ - for (entry_id = 0; entry_id < 7; entry_id++) { - token = strsep(&psz_cur, seps); - gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id]. - gpp_phys = atoi(token); - - token = strsep(&psz_cur, seps); - gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id]. - dsp_virt = atoi(token); - } -#endif - - break; - - default: - status = -EPERM; - break; - } - - return status; -} - -/* - * ======== CompressBuffer ======== - * Purpose: - * Compress the DSP buffer, if necessary, to conform to PC format. - */ -static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size) -{ - char *p; - char ch; - char *q; - - p = psz_buf; - if (p == NULL) - return; - - for (q = psz_buf; q < (psz_buf + ul_buf_size);) { - ch = dsp_char2_gpp_char(q, char_size); - if (ch == '\\') { - q += char_size; - ch = dsp_char2_gpp_char(q, char_size); - switch (ch) { - case 't': - *p = '\t'; - break; - - case 'n': - *p = '\n'; - break; - - case 'r': - *p = '\r'; - break; - - case '0': - *p = '\0'; - break; - - default: - *p = ch; - break; - } - } else { - *p = ch; - } - p++; - q += char_size; - } - - /* NULL out remainder of buffer. */ - while (p < q) - *p++ = '\0'; -} - -/* - * ======== dsp_char2_gpp_char ======== - * Purpose: - * Convert DSP char to host GPP char in a portable manner - */ -static char dsp_char2_gpp_char(char *word, s32 dsp_char_size) -{ - char ch = '\0'; - char *ch_src; - s32 i; - - for (ch_src = word, i = dsp_char_size; i > 0; i--) - ch |= *ch_src++; - - return ch; -} - -/* - * ======== get_dep_lib_info ======== - */ -static int get_dep_lib_info(struct dcd_manager *hdcd_mgr, - struct dsp_uuid *uuid_obj, - u16 *num_libs, - u16 *num_pers_libs, - struct dsp_uuid *dep_lib_uuids, - bool *prstnt_dep_libs, - enum nldr_phase phase) -{ - struct dcd_manager *dcd_mgr_obj = hdcd_mgr; - char *psz_coff_buf = NULL; - char *psz_cur; - char *psz_file_name = NULL; - struct cod_libraryobj *lib = NULL; - u32 ul_addr = 0; /* Used by cod_get_section */ - u32 ul_len = 0; /* Used by cod_get_section */ - u32 dw_data_size = COD_MAXPATHLENGTH; - char seps[] = ", "; - char *token = NULL; - bool get_uuids = (dep_lib_uuids != NULL); - u16 dep_libs = 0; - int status = 0; - - /* Initialize to 0 dependent libraries, if only counting number of - * dependent libraries */ - if (!get_uuids) { - *num_libs = 0; - *num_pers_libs = 0; - } - - /* Allocate a buffer for file name */ - psz_file_name = kzalloc(dw_data_size, GFP_KERNEL); - if (psz_file_name == NULL) { - status = -ENOMEM; - } else { - /* Get the name of the library */ - status = dcd_get_library_name(hdcd_mgr, uuid_obj, psz_file_name, - &dw_data_size, phase, NULL); - } - - /* Open the library */ - if (!status) { - status = cod_open(dcd_mgr_obj->cod_mgr, psz_file_name, - COD_NOLOAD, &lib); - } - if (!status) { - /* Get dependent library section information. */ - status = cod_get_section(lib, DEPLIBSECT, &ul_addr, &ul_len); - - if (status) { - /* Ok, no dependent libraries */ - ul_len = 0; - status = 0; - } - } - - if (status || !(ul_len > 0)) - goto func_cont; - - /* Allocate zeroed buffer. */ - psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL); - if (psz_coff_buf == NULL) - status = -ENOMEM; - - /* Read section contents. */ - status = cod_read_section(lib, DEPLIBSECT, psz_coff_buf, ul_len); - if (status) - goto func_cont; - - /* Compress and format DSP buffer to conform to PC format. */ - compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE); - - /* Read from buffer */ - psz_cur = psz_coff_buf; - while ((token = strsep(&psz_cur, seps)) && *token != '\0') { - if (get_uuids) { - if (dep_libs >= *num_libs) { - /* Gone beyond the limit */ - break; - } else { - /* Retrieve UUID string. */ - status = dcd_uuid_from_string(token, - &(dep_lib_uuids - [dep_libs])); - if (status) - break; - - /* Is this library persistent? */ - token = strsep(&psz_cur, seps); - prstnt_dep_libs[dep_libs] = atoi(token); - dep_libs++; - } - } else { - /* Advanc to next token */ - token = strsep(&psz_cur, seps); - if (atoi(token)) - (*num_pers_libs)++; - - /* Just counting number of dependent libraries */ - (*num_libs)++; - } - } -func_cont: - if (lib) - cod_close(lib); - - /* Free previously allocated dynamic buffers. */ - kfree(psz_file_name); - - kfree(psz_coff_buf); - - return status; -} diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c deleted file mode 100644 index 4af51b75aea..00000000000 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * disp.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Node Dispatcher interface. Communicates with Resource Manager Server - * (RMS) on DSP. Access to RMS is synchronized in NODE. - * - * 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. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Link Driver */ -#include <dspbridge/dspdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> -#include <dspbridge/chnldefs.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/nodedefs.h> -#include <dspbridge/nodepriv.h> -#include <dspbridge/rms_sh.h> - -/* ----------------------------------- This */ -#include <dspbridge/disp.h> - -/* Size of a reply from RMS */ -#define REPLYSIZE (3 * sizeof(rms_word)) - -/* Reserved channel offsets for communication with RMS */ -#define CHNLTORMSOFFSET 0 -#define CHNLFROMRMSOFFSET 1 - -#define CHNLIOREQS 1 - -/* - * ======== disp_object ======== - */ -struct disp_object { - struct dev_object *dev_obj; /* Device for this processor */ - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; - struct chnl_mgr *chnl_mgr; /* Channel manager */ - struct chnl_object *chnl_to_dsp; /* Chnl for commands to RMS */ - struct chnl_object *chnl_from_dsp; /* Chnl for replies from RMS */ - u8 *buf; /* Buffer for commands, replies */ - u32 bufsize; /* buf size in bytes */ - u32 bufsize_rms; /* buf size in RMS words */ - u32 char_size; /* Size of DSP character */ - u32 word_size; /* Size of DSP word */ - u32 data_mau_size; /* Size of DSP Data MAU */ -}; - -static void delete_disp(struct disp_object *disp_obj); -static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset, - struct node_strmdef strm_def, u32 max, - u32 chars_in_rms_word); -static int send_message(struct disp_object *disp_obj, u32 timeout, - u32 ul_bytes, u32 *pdw_arg); - -/* - * ======== disp_create ======== - * Create a NODE Dispatcher object. - */ -int disp_create(struct disp_object **dispatch_obj, - struct dev_object *hdev_obj, - const struct disp_attr *disp_attrs) -{ - struct disp_object *disp_obj; - struct bridge_drv_interface *intf_fxns; - u32 ul_chnl_id; - struct chnl_attr chnl_attr_obj; - int status = 0; - u8 dev_type; - - *dispatch_obj = NULL; - - /* Allocate Node Dispatcher object */ - disp_obj = kzalloc(sizeof(struct disp_object), GFP_KERNEL); - if (disp_obj == NULL) - status = -ENOMEM; - else - disp_obj->dev_obj = hdev_obj; - - /* Get Channel manager and Bridge function interface */ - if (!status) { - status = dev_get_chnl_mgr(hdev_obj, &(disp_obj->chnl_mgr)); - if (!status) { - (void)dev_get_intf_fxns(hdev_obj, &intf_fxns); - disp_obj->intf_fxns = intf_fxns; - } - } - - /* check device type and decide if streams or messag'ing is used for - * RMS/EDS */ - if (status) - goto func_cont; - - status = dev_get_dev_type(hdev_obj, &dev_type); - - if (status) - goto func_cont; - - if (dev_type != DSP_UNIT) { - status = -EPERM; - goto func_cont; - } - - disp_obj->char_size = DSPWORDSIZE; - disp_obj->word_size = DSPWORDSIZE; - disp_obj->data_mau_size = DSPWORDSIZE; - /* Open channels for communicating with the RMS */ - chnl_attr_obj.uio_reqs = CHNLIOREQS; - chnl_attr_obj.event_obj = NULL; - ul_chnl_id = disp_attrs->chnl_offset + CHNLTORMSOFFSET; - status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_to_dsp), - disp_obj->chnl_mgr, - CHNL_MODETODSP, ul_chnl_id, - &chnl_attr_obj); - - if (!status) { - ul_chnl_id = disp_attrs->chnl_offset + CHNLFROMRMSOFFSET; - status = - (*intf_fxns->chnl_open) (&(disp_obj->chnl_from_dsp), - disp_obj->chnl_mgr, - CHNL_MODEFROMDSP, ul_chnl_id, - &chnl_attr_obj); - } - if (!status) { - /* Allocate buffer for commands, replies */ - disp_obj->bufsize = disp_attrs->chnl_buf_size; - disp_obj->bufsize_rms = RMS_COMMANDBUFSIZE; - disp_obj->buf = kzalloc(disp_obj->bufsize, GFP_KERNEL); - if (disp_obj->buf == NULL) - status = -ENOMEM; - } -func_cont: - if (!status) - *dispatch_obj = disp_obj; - else - delete_disp(disp_obj); - - return status; -} - -/* - * ======== disp_delete ======== - * Delete the NODE Dispatcher. - */ -void disp_delete(struct disp_object *disp_obj) -{ - delete_disp(disp_obj); -} - -/* - * ======== disp_node_change_priority ======== - * Change the priority of a node currently running on the target. - */ -int disp_node_change_priority(struct disp_object *disp_obj, - struct node_object *hnode, - u32 rms_fxn, nodeenv node_env, s32 prio) -{ - u32 dw_arg; - struct rms_command *rms_cmd; - int status = 0; - - /* Send message to RMS to change priority */ - rms_cmd = (struct rms_command *)(disp_obj->buf); - rms_cmd->fxn = (rms_word) (rms_fxn); - rms_cmd->arg1 = (rms_word) node_env; - rms_cmd->arg2 = prio; - status = send_message(disp_obj, node_get_timeout(hnode), - sizeof(struct rms_command), &dw_arg); - - return status; -} - -/* - * ======== disp_node_create ======== - * Create a node on the DSP by remotely calling the node's create function. - */ -int disp_node_create(struct disp_object *disp_obj, - struct node_object *hnode, u32 rms_fxn, - u32 ul_create_fxn, - const struct node_createargs *pargs, - nodeenv *node_env) -{ - struct node_msgargs node_msg_args; - struct node_taskargs task_arg_obj; - struct rms_command *rms_cmd; - struct rms_msg_args *pmsg_args; - struct rms_more_task_args *more_task_args; - enum node_type node_type; - u32 dw_length; - rms_word *pdw_buf = NULL; - u32 ul_bytes; - u32 i; - u32 total; - u32 chars_in_rms_word; - s32 task_args_offset; - s32 sio_in_def_offset; - s32 sio_out_def_offset; - s32 sio_defs_offset; - s32 args_offset = -1; - s32 offset; - struct node_strmdef strm_def; - u32 max; - int status = 0; - struct dsp_nodeinfo node_info; - u8 dev_type; - - status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); - - if (status) - goto func_end; - - if (dev_type != DSP_UNIT) { - dev_dbg(bridge, "%s: unknown device type = 0x%x\n", - __func__, dev_type); - goto func_end; - } - node_type = node_get_type(hnode); - node_msg_args = pargs->asa.node_msg_args; - max = disp_obj->bufsize_rms; /*Max # of RMS words that can be sent */ - chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size; - /* Number of RMS words needed to hold arg data */ - dw_length = - (node_msg_args.arg_length + chars_in_rms_word - - 1) / chars_in_rms_word; - /* Make sure msg args and command fit in buffer */ - total = sizeof(struct rms_command) / sizeof(rms_word) + - sizeof(struct rms_msg_args) - / sizeof(rms_word) - 1 + dw_length; - if (total >= max) { - status = -EPERM; - dev_dbg(bridge, "%s: Message args too large for buffer! size " - "= %d, max = %d\n", __func__, total, max); - } - /* - * Fill in buffer to send to RMS. - * The buffer will have the following format: - * - * RMS command: - * Address of RMS_CreateNode() - * Address of node's create function - * dummy argument - * node type - * - * Message Args: - * max number of messages - * segid for message buffer allocation - * notification type to use when message is received - * length of message arg data - * message args data - * - * Task Args (if task or socket node): - * priority - * stack size - * system stack size - * stack segment - * misc - * number of input streams - * pSTRMInDef[] - offsets of STRM definitions for input streams - * number of output streams - * pSTRMOutDef[] - offsets of STRM definitions for output - * streams - * STRMInDef[] - array of STRM definitions for input streams - * STRMOutDef[] - array of STRM definitions for output streams - * - * Socket Args (if DAIS socket node): - * - */ - if (!status) { - total = 0; /* Total number of words in buffer so far */ - pdw_buf = (rms_word *) disp_obj->buf; - rms_cmd = (struct rms_command *)pdw_buf; - rms_cmd->fxn = (rms_word) (rms_fxn); - rms_cmd->arg1 = (rms_word) (ul_create_fxn); - if (node_get_load_type(hnode) == NLDR_DYNAMICLOAD) { - /* Flush ICACHE on Load */ - rms_cmd->arg2 = 1; /* dummy argument */ - } else { - /* Do not flush ICACHE */ - rms_cmd->arg2 = 0; /* dummy argument */ - } - rms_cmd->data = node_get_type(hnode); - /* - * args_offset is the offset of the data field in struct - * rms_command structure. We need this to calculate stream - * definition offsets. - */ - args_offset = 3; - total += sizeof(struct rms_command) / sizeof(rms_word); - /* Message args */ - pmsg_args = (struct rms_msg_args *)(pdw_buf + total); - pmsg_args->max_msgs = node_msg_args.max_msgs; - pmsg_args->segid = node_msg_args.seg_id; - pmsg_args->notify_type = node_msg_args.notify_type; - pmsg_args->arg_length = node_msg_args.arg_length; - total += sizeof(struct rms_msg_args) / sizeof(rms_word) - 1; - memcpy(pdw_buf + total, node_msg_args.pdata, - node_msg_args.arg_length); - total += dw_length; - } - if (status) - goto func_end; - - /* If node is a task node, copy task create arguments into buffer */ - if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) { - task_arg_obj = pargs->asa.task_arg_obj; - task_args_offset = total; - total += sizeof(struct rms_more_task_args) / sizeof(rms_word) + - 1 + task_arg_obj.num_inputs + task_arg_obj.num_outputs; - /* Copy task arguments */ - if (total < max) { - total = task_args_offset; - more_task_args = (struct rms_more_task_args *)(pdw_buf + - total); - /* - * Get some important info about the node. Note that we - * don't just reach into the hnode struct because - * that would break the node object's abstraction. - */ - get_node_info(hnode, &node_info); - more_task_args->priority = node_info.execution_priority; - more_task_args->stack_size = task_arg_obj.stack_size; - more_task_args->sysstack_size = - task_arg_obj.sys_stack_size; - more_task_args->stack_seg = task_arg_obj.stack_seg; - more_task_args->heap_addr = task_arg_obj.dsp_heap_addr; - more_task_args->heap_size = task_arg_obj.heap_size; - more_task_args->misc = task_arg_obj.dais_arg; - more_task_args->num_input_streams = - task_arg_obj.num_inputs; - total += - sizeof(struct rms_more_task_args) / - sizeof(rms_word); - dev_dbg(bridge, "%s: dsp_heap_addr %x, heap_size %x\n", - __func__, task_arg_obj.dsp_heap_addr, - task_arg_obj.heap_size); - /* Keep track of pSIOInDef[] and pSIOOutDef[] - * positions in the buffer, since this needs to be - * filled in later. */ - sio_in_def_offset = total; - total += task_arg_obj.num_inputs; - pdw_buf[total++] = task_arg_obj.num_outputs; - sio_out_def_offset = total; - total += task_arg_obj.num_outputs; - sio_defs_offset = total; - /* Fill SIO defs and offsets */ - offset = sio_defs_offset; - for (i = 0; i < task_arg_obj.num_inputs; i++) { - if (status) - break; - - pdw_buf[sio_in_def_offset + i] = - (offset - args_offset) - * (sizeof(rms_word) / DSPWORDSIZE); - strm_def = task_arg_obj.strm_in_def[i]; - status = - fill_stream_def(pdw_buf, &total, offset, - strm_def, max, - chars_in_rms_word); - offset = total; - } - for (i = 0; (i < task_arg_obj.num_outputs) && - (!status); i++) { - pdw_buf[sio_out_def_offset + i] = - (offset - args_offset) - * (sizeof(rms_word) / DSPWORDSIZE); - strm_def = task_arg_obj.strm_out_def[i]; - status = - fill_stream_def(pdw_buf, &total, offset, - strm_def, max, - chars_in_rms_word); - offset = total; - } - } else { - /* Args won't fit */ - status = -EPERM; - } - } - if (!status) { - ul_bytes = total * sizeof(rms_word); - status = send_message(disp_obj, node_get_timeout(hnode), - ul_bytes, node_env); - } -func_end: - return status; -} - -/* - * ======== disp_node_delete ======== - * purpose: - * Delete a node on the DSP by remotely calling the node's delete function. - * - */ -int disp_node_delete(struct disp_object *disp_obj, - struct node_object *hnode, u32 rms_fxn, - u32 ul_delete_fxn, nodeenv node_env) -{ - u32 dw_arg; - struct rms_command *rms_cmd; - int status = 0; - u8 dev_type; - - status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); - - if (!status) { - - if (dev_type == DSP_UNIT) { - - /* - * Fill in buffer to send to RMS - */ - rms_cmd = (struct rms_command *)disp_obj->buf; - rms_cmd->fxn = (rms_word) (rms_fxn); - rms_cmd->arg1 = (rms_word) node_env; - rms_cmd->arg2 = (rms_word) (ul_delete_fxn); - rms_cmd->data = node_get_type(hnode); - - status = send_message(disp_obj, node_get_timeout(hnode), - sizeof(struct rms_command), - &dw_arg); - } - } - return status; -} - -/* - * ======== disp_node_run ======== - * purpose: - * Start execution of a node's execute phase, or resume execution of a node - * that has been suspended (via DISP_NodePause()) on the DSP. - */ -int disp_node_run(struct disp_object *disp_obj, - struct node_object *hnode, u32 rms_fxn, - u32 ul_execute_fxn, nodeenv node_env) -{ - u32 dw_arg; - struct rms_command *rms_cmd; - int status = 0; - u8 dev_type; - - status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); - - if (!status) { - - if (dev_type == DSP_UNIT) { - - /* - * Fill in buffer to send to RMS. - */ - rms_cmd = (struct rms_command *)disp_obj->buf; - rms_cmd->fxn = (rms_word) (rms_fxn); - rms_cmd->arg1 = (rms_word) node_env; - rms_cmd->arg2 = (rms_word) (ul_execute_fxn); - rms_cmd->data = node_get_type(hnode); - - status = send_message(disp_obj, node_get_timeout(hnode), - sizeof(struct rms_command), - &dw_arg); - } - } - - return status; -} - -/* - * ======== delete_disp ======== - * purpose: - * Frees the resources allocated for the dispatcher. - */ -static void delete_disp(struct disp_object *disp_obj) -{ - int status = 0; - struct bridge_drv_interface *intf_fxns; - - if (disp_obj) { - intf_fxns = disp_obj->intf_fxns; - - /* Free Node Dispatcher resources */ - if (disp_obj->chnl_from_dsp) { - /* Channel close can fail only if the channel handle - * is invalid. */ - status = (*intf_fxns->chnl_close) - (disp_obj->chnl_from_dsp); - if (status) { - dev_dbg(bridge, "%s: Failed to close channel " - "from RMS: 0x%x\n", __func__, status); - } - } - if (disp_obj->chnl_to_dsp) { - status = - (*intf_fxns->chnl_close) (disp_obj-> - chnl_to_dsp); - if (status) { - dev_dbg(bridge, "%s: Failed to close channel to" - " RMS: 0x%x\n", __func__, status); - } - } - kfree(disp_obj->buf); - - kfree(disp_obj); - } -} - -/* - * ======== fill_stream_def ======== - * purpose: - * Fills stream definitions. - */ -static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset, - struct node_strmdef strm_def, u32 max, - u32 chars_in_rms_word) -{ - struct rms_strm_def *strm_def_obj; - u32 total = *ptotal; - u32 name_len; - u32 dw_length; - int status = 0; - - if (total + sizeof(struct rms_strm_def) / sizeof(rms_word) >= max) { - status = -EPERM; - } else { - strm_def_obj = (struct rms_strm_def *)(pdw_buf + total); - strm_def_obj->bufsize = strm_def.buf_size; - strm_def_obj->nbufs = strm_def.num_bufs; - strm_def_obj->segid = strm_def.seg_id; - strm_def_obj->align = strm_def.buf_alignment; - strm_def_obj->timeout = strm_def.timeout; - } - - if (!status) { - /* - * Since we haven't added the device name yet, subtract - * 1 from total. - */ - total += sizeof(struct rms_strm_def) / sizeof(rms_word) - 1; - dw_length = strlen(strm_def.sz_device) + 1; - - /* Number of RMS_WORDS needed to hold device name */ - name_len = - (dw_length + chars_in_rms_word - 1) / chars_in_rms_word; - - if (total + name_len >= max) { - status = -EPERM; - } else { - /* - * Zero out last word, since the device name may not - * extend to completely fill this word. - */ - pdw_buf[total + name_len - 1] = 0; - /** TODO USE SERVICES * */ - memcpy(pdw_buf + total, strm_def.sz_device, dw_length); - total += name_len; - *ptotal = total; - } - } - - return status; -} - -/* - * ======== send_message ====== - * Send command message to RMS, get reply from RMS. - */ -static int send_message(struct disp_object *disp_obj, u32 timeout, - u32 ul_bytes, u32 *pdw_arg) -{ - struct bridge_drv_interface *intf_fxns; - struct chnl_object *chnl_obj; - u32 dw_arg = 0; - u8 *pbuf; - struct chnl_ioc chnl_ioc_obj; - int status = 0; - - *pdw_arg = (u32) NULL; - intf_fxns = disp_obj->intf_fxns; - chnl_obj = disp_obj->chnl_to_dsp; - pbuf = disp_obj->buf; - - /* Send the command */ - status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0, - 0L, dw_arg); - if (status) - goto func_end; - - status = - (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj); - if (!status) { - if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { - if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) - status = -ETIME; - else - status = -EPERM; - } - } - /* Get the reply */ - if (status) - goto func_end; - - chnl_obj = disp_obj->chnl_from_dsp; - ul_bytes = REPLYSIZE; - status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, - 0, 0L, dw_arg); - if (status) - goto func_end; - - status = - (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj); - if (!status) { - if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) { - status = -ETIME; - } else if (chnl_ioc_obj.byte_size < ul_bytes) { - /* Did not get all of the reply from the RMS */ - status = -EPERM; - } else { - if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { - if (*((int *)chnl_ioc_obj.buf) < 0) { - /* Translate DSP's to kernel error */ - status = -EREMOTEIO; - dev_dbg(bridge, "%s: DSP-side failed:" - " DSP errcode = 0x%x, Kernel " - "errcode = %d\n", __func__, - *(int *)pbuf, status); - } - *pdw_arg = - (((rms_word *) (chnl_ioc_obj.buf))[1]); - } else { - status = -EPERM; - } - } - } -func_end: - return status; -} diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c deleted file mode 100644 index 757ae20b38e..00000000000 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * drv.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge resource allocation 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. - */ -#include <linux/types.h> -#include <linux/list.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- This */ -#include <dspbridge/drv.h> -#include <dspbridge/dev.h> - -#include <dspbridge/node.h> -#include <dspbridge/proc.h> -#include <dspbridge/strm.h> -#include <dspbridge/nodepriv.h> -#include <dspbridge/dspchnl.h> -#include <dspbridge/resourcecleanup.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -struct drv_object { - struct list_head dev_list; - struct list_head dev_node_string; -}; - -/* - * This is the Device Extension. Named with the Prefix - * DRV_ since it is living in this module - */ -struct drv_ext { - struct list_head link; - char sz_string[MAXREGPATHLENGTH]; -}; - -/* ----------------------------------- Globals */ -static bool ext_phys_mem_pool_enabled; -struct ext_phys_mem_pool { - u32 phys_mem_base; - u32 phys_mem_size; - u32 virt_mem_base; - u32 next_phys_alloc_ptr; -}; -static struct ext_phys_mem_pool ext_mem_pool; - -/* ----------------------------------- Function Prototypes */ -static int request_bridge_resources(struct cfg_hostres *res); - - -/* GPP PROCESS CLEANUP CODE */ - -static int drv_proc_free_node_res(int id, void *p, void *data); - -/* Allocate and add a node resource element -* This function is called from .Node_Allocate. */ -int drv_insert_node_res_element(void *hnode, void *node_resource, - void *process_ctxt) -{ - struct node_res_object **node_res_obj = - (struct node_res_object **)node_resource; - struct process_context *ctxt = (struct process_context *)process_ctxt; - int retval; - - *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL); - if (!*node_res_obj) - return -ENOMEM; - - (*node_res_obj)->node = hnode; - retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL); - if (retval >= 0) { - (*node_res_obj)->id = retval; - return 0; - } - - kfree(*node_res_obj); - - if (retval == -ENOSPC) { - pr_err("%s: FAILED, IDR is FULL\n", __func__); - return -EFAULT; - } else { - pr_err("%s: OUT OF MEMORY\n", __func__); - return -ENOMEM; - } -} - -/* Release all Node resources and its context - * Actual Node De-Allocation */ -static int drv_proc_free_node_res(int id, void *p, void *data) -{ - struct process_context *ctxt = data; - int status; - struct node_res_object *node_res_obj = p; - u32 node_state; - - if (node_res_obj->node_allocated) { - node_state = node_get_state(node_res_obj->node); - if (node_state <= NODE_DELETING) { - if ((node_state == NODE_RUNNING) || - (node_state == NODE_PAUSED) || - (node_state == NODE_TERMINATING)) - node_terminate - (node_res_obj->node, &status); - - node_delete(node_res_obj, ctxt); - } - } - - return 0; -} - -/* Release all Mapped and Reserved DMM resources */ -int drv_remove_all_dmm_res_elements(void *process_ctxt) -{ - struct process_context *ctxt = (struct process_context *)process_ctxt; - int status = 0; - struct dmm_map_object *temp_map, *map_obj; - struct dmm_rsv_object *temp_rsv, *rsv_obj; - - /* Free DMM mapped memory resources */ - list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) { - status = proc_un_map(ctxt->processor, - (void *)map_obj->dsp_addr, ctxt); - if (status) - pr_err("%s: proc_un_map failed!" - " status = 0x%xn", __func__, status); - } - - /* Free DMM reserved memory resources */ - list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) { - status = proc_un_reserve_memory(ctxt->processor, (void *) - rsv_obj->dsp_reserved_addr, - ctxt); - if (status) - pr_err("%s: proc_un_reserve_memory failed!" - " status = 0x%xn", __func__, status); - } - return status; -} - -/* Update Node allocation status */ -void drv_proc_node_update_status(void *node_resource, s32 status) -{ - struct node_res_object *node_res_obj = - (struct node_res_object *)node_resource; - node_res_obj->node_allocated = status; -} - -/* Update Node Heap status */ -void drv_proc_node_update_heap_status(void *node_resource, s32 status) -{ - struct node_res_object *node_res_obj = - (struct node_res_object *)node_resource; - node_res_obj->heap_allocated = status; -} - -/* Release all Node resources and its context -* This is called from .bridge_release. - */ -int drv_remove_all_node_res_elements(void *process_ctxt) -{ - struct process_context *ctxt = process_ctxt; - - idr_for_each(ctxt->node_id, drv_proc_free_node_res, ctxt); - idr_destroy(ctxt->node_id); - - return 0; -} - -/* Allocate the STRM resource element -* This is called after the actual resource is allocated - */ -int drv_proc_insert_strm_res_element(void *stream_obj, - void *strm_res, void *process_ctxt) -{ - struct strm_res_object **pstrm_res = - (struct strm_res_object **)strm_res; - struct process_context *ctxt = (struct process_context *)process_ctxt; - int retval; - - *pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL); - if (*pstrm_res == NULL) - return -EFAULT; - - (*pstrm_res)->stream = stream_obj; - retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL); - if (retval >= 0) { - (*pstrm_res)->id = retval; - return 0; - } - - if (retval == -ENOSPC) { - pr_err("%s: FAILED, IDR is FULL\n", __func__); - return -EPERM; - } else { - pr_err("%s: OUT OF MEMORY\n", __func__); - return -ENOMEM; - } -} - -static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt) -{ - struct process_context *ctxt = process_ctxt; - struct strm_res_object *strm_res = p; - struct stream_info strm_info; - struct dsp_streaminfo user; - u8 **ap_buffer = NULL; - u8 *buf_ptr; - u32 ul_bytes; - u32 dw_arg; - s32 ul_buf_size; - - if (strm_res->num_bufs) { - ap_buffer = kmalloc((strm_res->num_bufs * - sizeof(u8 *)), GFP_KERNEL); - if (ap_buffer) { - strm_free_buffer(strm_res, - ap_buffer, - strm_res->num_bufs, - ctxt); - kfree(ap_buffer); - } - } - strm_info.user_strm = &user; - user.number_bufs_in_stream = 0; - strm_get_info(strm_res->stream, &strm_info, sizeof(strm_info)); - while (user.number_bufs_in_stream--) - strm_reclaim(strm_res->stream, &buf_ptr, &ul_bytes, - (u32 *) &ul_buf_size, &dw_arg); - strm_close(strm_res, ctxt); - return 0; -} - -/* Release all Stream resources and its context -* This is called from .bridge_release. - */ -int drv_remove_all_strm_res_elements(void *process_ctxt) -{ - struct process_context *ctxt = process_ctxt; - - idr_for_each(ctxt->stream_id, drv_proc_free_strm_res, ctxt); - idr_destroy(ctxt->stream_id); - - return 0; -} - -/* Updating the stream resource element */ -int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources) -{ - int status = 0; - struct strm_res_object **strm_res = - (struct strm_res_object **)strm_resources; - - (*strm_res)->num_bufs = num_bufs; - return status; -} - -/* GPP PROCESS CLEANUP CODE END */ - -/* - * ======== = drv_create ======== = - * Purpose: - * DRV Object gets created only once during Driver Loading. - */ -int drv_create(struct drv_object **drv_obj) -{ - int status = 0; - struct drv_object *pdrv_object = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - pdrv_object = kzalloc(sizeof(struct drv_object), GFP_KERNEL); - if (pdrv_object) { - /* Create and Initialize List of device objects */ - INIT_LIST_HEAD(&pdrv_object->dev_list); - INIT_LIST_HEAD(&pdrv_object->dev_node_string); - } else { - status = -ENOMEM; - } - /* Store the DRV Object in the driver data */ - if (!status) { - if (drv_datap) { - drv_datap->drv_object = (void *)pdrv_object; - } else { - status = -EPERM; - pr_err("%s: Failed to store DRV object\n", __func__); - } - } - - if (!status) { - *drv_obj = pdrv_object; - } else { - /* Free the DRV Object */ - kfree(pdrv_object); - } - - return status; -} - -/* - * ======== = drv_destroy ======== = - * purpose: - * Invoked during bridge de-initialization - */ -int drv_destroy(struct drv_object *driver_obj) -{ - int status = 0; - struct drv_object *pdrv_object = (struct drv_object *)driver_obj; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - kfree(pdrv_object); - /* Update the DRV Object in the driver data */ - if (drv_datap) { - drv_datap->drv_object = NULL; - } else { - status = -EPERM; - pr_err("%s: Failed to store DRV object\n", __func__); - } - - return status; -} - -/* - * ======== drv_get_dev_object ======== - * Purpose: - * Given a index, returns a handle to DevObject from the list. - */ -int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj, - struct dev_object **device_obj) -{ - int status = 0; - struct dev_object *dev_obj; - u32 i; - - dev_obj = (struct dev_object *)drv_get_first_dev_object(); - for (i = 0; i < index; i++) { - dev_obj = - (struct dev_object *)drv_get_next_dev_object((u32) dev_obj); - } - if (dev_obj) { - *device_obj = (struct dev_object *)dev_obj; - } else { - *device_obj = NULL; - status = -EPERM; - } - - return status; -} - -/* - * ======== drv_get_first_dev_object ======== - * Purpose: - * Retrieve the first Device Object handle from an internal linked list of - * of DEV_OBJECTs maintained by DRV. - */ -u32 drv_get_first_dev_object(void) -{ - u32 dw_dev_object = 0; - struct drv_object *pdrv_obj; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - if (drv_datap && drv_datap->drv_object) { - pdrv_obj = drv_datap->drv_object; - if (!list_empty(&pdrv_obj->dev_list)) - dw_dev_object = (u32) pdrv_obj->dev_list.next; - } else { - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } - - return dw_dev_object; -} - -/* - * ======== DRV_GetFirstDevNodeString ======== - * Purpose: - * Retrieve the first Device Extension from an internal linked list of - * of Pointer to dev_node Strings maintained by DRV. - */ -u32 drv_get_first_dev_extension(void) -{ - u32 dw_dev_extension = 0; - struct drv_object *pdrv_obj; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - if (drv_datap && drv_datap->drv_object) { - pdrv_obj = drv_datap->drv_object; - if (!list_empty(&pdrv_obj->dev_node_string)) { - dw_dev_extension = - (u32) pdrv_obj->dev_node_string.next; - } - } else { - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } - - return dw_dev_extension; -} - -/* - * ======== drv_get_next_dev_object ======== - * Purpose: - * Retrieve the next Device Object handle from an internal linked list of - * of DEV_OBJECTs maintained by DRV, after having previously called - * drv_get_first_dev_object() and zero or more DRV_GetNext. - */ -u32 drv_get_next_dev_object(u32 hdev_obj) -{ - u32 dw_next_dev_object = 0; - struct drv_object *pdrv_obj; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - struct list_head *curr; - - if (drv_datap && drv_datap->drv_object) { - pdrv_obj = drv_datap->drv_object; - if (!list_empty(&pdrv_obj->dev_list)) { - curr = (struct list_head *)hdev_obj; - if (list_is_last(curr, &pdrv_obj->dev_list)) - return 0; - dw_next_dev_object = (u32) curr->next; - } - } else { - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } - - return dw_next_dev_object; -} - -/* - * ======== drv_get_next_dev_extension ======== - * Purpose: - * Retrieve the next Device Extension from an internal linked list of - * of pointer to DevNodeString maintained by DRV, after having previously - * called drv_get_first_dev_extension() and zero or more - * drv_get_next_dev_extension(). - */ -u32 drv_get_next_dev_extension(u32 dev_extension) -{ - u32 dw_dev_extension = 0; - struct drv_object *pdrv_obj; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - struct list_head *curr; - - if (drv_datap && drv_datap->drv_object) { - pdrv_obj = drv_datap->drv_object; - if (!list_empty(&pdrv_obj->dev_node_string)) { - curr = (struct list_head *)dev_extension; - if (list_is_last(curr, &pdrv_obj->dev_node_string)) - return 0; - dw_dev_extension = (u32) curr->next; - } - } else { - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } - - return dw_dev_extension; -} - -/* - * ======== drv_insert_dev_object ======== - * Purpose: - * Insert a DevObject into the list of Manager object. - */ -int drv_insert_dev_object(struct drv_object *driver_obj, - struct dev_object *hdev_obj) -{ - struct drv_object *pdrv_object = (struct drv_object *)driver_obj; - - list_add_tail((struct list_head *)hdev_obj, &pdrv_object->dev_list); - - return 0; -} - -/* - * ======== drv_remove_dev_object ======== - * Purpose: - * Search for and remove a DeviceObject from the given list of DRV - * objects. - */ -int drv_remove_dev_object(struct drv_object *driver_obj, - struct dev_object *hdev_obj) -{ - int status = -EPERM; - struct drv_object *pdrv_object = (struct drv_object *)driver_obj; - struct list_head *cur_elem; - - /* Search list for p_proc_object: */ - list_for_each(cur_elem, &pdrv_object->dev_list) { - /* If found, remove it. */ - if ((struct dev_object *)cur_elem == hdev_obj) { - list_del(cur_elem); - status = 0; - break; - } - } - - return status; -} - -/* - * ======== drv_request_resources ======== - * Purpose: - * Requests resources from the OS. - */ -int drv_request_resources(u32 dw_context, u32 *dev_node_strg) -{ - int status = 0; - struct drv_object *pdrv_object; - struct drv_ext *pszdev_node; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - /* - * Allocate memory to hold the string. This will live until - * it is freed in the Release resources. Update the driver object - * list. - */ - - if (!drv_datap || !drv_datap->drv_object) - status = -ENODATA; - else - pdrv_object = drv_datap->drv_object; - - if (!status) { - pszdev_node = kzalloc(sizeof(struct drv_ext), GFP_KERNEL); - if (pszdev_node) { - strncpy(pszdev_node->sz_string, - (char *)dw_context, MAXREGPATHLENGTH - 1); - pszdev_node->sz_string[MAXREGPATHLENGTH - 1] = '\0'; - /* Update the Driver Object List */ - *dev_node_strg = (u32) pszdev_node->sz_string; - list_add_tail(&pszdev_node->link, - &pdrv_object->dev_node_string); - } else { - status = -ENOMEM; - *dev_node_strg = 0; - } - } else { - dev_dbg(bridge, "%s: Failed to get Driver Object from Registry", - __func__); - *dev_node_strg = 0; - } - - return status; -} - -/* - * ======== drv_release_resources ======== - * Purpose: - * Releases resources from the OS. - */ -int drv_release_resources(u32 dw_context, struct drv_object *hdrv_obj) -{ - int status = 0; - struct drv_ext *pszdev_node; - - /* - * Irrespective of the status go ahead and clean it - * The following will over write the status. - */ - for (pszdev_node = (struct drv_ext *)drv_get_first_dev_extension(); - pszdev_node != NULL; pszdev_node = (struct drv_ext *) - drv_get_next_dev_extension((u32) pszdev_node)) { - if ((u32) pszdev_node == dw_context) { - /* Found it */ - /* Delete from the Driver object list */ - list_del(&pszdev_node->link); - kfree(pszdev_node); - break; - } - } - return status; -} - -/* - * ======== request_bridge_resources ======== - * Purpose: - * Reserves shared memory for bridge. - */ -static int request_bridge_resources(struct cfg_hostres *res) -{ - struct cfg_hostres *host_res = res; - - /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */ - host_res->num_mem_windows = 2; - - /* First window is for DSP internal memory */ - dev_dbg(bridge, "mem_base[0] 0x%x\n", host_res->mem_base[0]); - dev_dbg(bridge, "mem_base[3] 0x%x\n", host_res->mem_base[3]); - dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base); - - /* for 24xx base port is not mapping the mamory for DSP - * internal memory TODO Do a ioremap here */ - /* Second window is for DSP external memory shared with MPU */ - - /* These are hard-coded values */ - host_res->birq_registers = 0; - host_res->birq_attrib = 0; - host_res->offset_for_monitor = 0; - host_res->chnl_offset = 0; - /* CHNL_MAXCHANNELS */ - host_res->num_chnls = CHNL_MAXCHANNELS; - host_res->chnl_buf_size = 0x400; - - return 0; -} - -/* - * ======== drv_request_bridge_res_dsp ======== - * Purpose: - * Reserves shared memory for bridge. - */ -int drv_request_bridge_res_dsp(void **phost_resources) -{ - int status = 0; - struct cfg_hostres *host_res; - u32 dw_buff_size; - u32 dma_addr; - u32 shm_size; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - dw_buff_size = sizeof(struct cfg_hostres); - - host_res = kzalloc(dw_buff_size, GFP_KERNEL); - - if (host_res != NULL) { - request_bridge_resources(host_res); - /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */ - host_res->num_mem_windows = 4; - - host_res->mem_base[0] = 0; - host_res->mem_base[2] = (u32) ioremap(OMAP_DSP_MEM1_BASE, - OMAP_DSP_MEM1_SIZE); - host_res->mem_base[3] = (u32) ioremap(OMAP_DSP_MEM2_BASE, - OMAP_DSP_MEM2_SIZE); - host_res->mem_base[4] = (u32) ioremap(OMAP_DSP_MEM3_BASE, - OMAP_DSP_MEM3_SIZE); - host_res->per_base = ioremap(OMAP_PER_CM_BASE, - OMAP_PER_CM_SIZE); - host_res->per_pm_base = ioremap(OMAP_PER_PRM_BASE, - OMAP_PER_PRM_SIZE); - host_res->core_pm_base = ioremap(OMAP_CORE_PRM_BASE, - OMAP_CORE_PRM_SIZE); - host_res->dmmu_base = ioremap(OMAP_DMMU_BASE, - OMAP_DMMU_SIZE); - - dev_dbg(bridge, "mem_base[0] 0x%x\n", - host_res->mem_base[0]); - dev_dbg(bridge, "mem_base[1] 0x%x\n", - host_res->mem_base[1]); - dev_dbg(bridge, "mem_base[2] 0x%x\n", - host_res->mem_base[2]); - dev_dbg(bridge, "mem_base[3] 0x%x\n", - host_res->mem_base[3]); - dev_dbg(bridge, "mem_base[4] 0x%x\n", - host_res->mem_base[4]); - dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base); - - shm_size = drv_datap->shm_size; - if (shm_size >= 0x10000) { - /* Allocate Physically contiguous, - * non-cacheable memory */ - host_res->mem_base[1] = - (u32) mem_alloc_phys_mem(shm_size, 0x100000, - &dma_addr); - if (host_res->mem_base[1] == 0) { - status = -ENOMEM; - pr_err("shm reservation Failed\n"); - } else { - host_res->mem_length[1] = shm_size; - host_res->mem_phys[1] = dma_addr; - - dev_dbg(bridge, "%s: Bridge shm address 0x%x " - "dma_addr %x size %x\n", __func__, - host_res->mem_base[1], - dma_addr, shm_size); - } - } - if (!status) { - /* These are hard-coded values */ - host_res->birq_registers = 0; - host_res->birq_attrib = 0; - host_res->offset_for_monitor = 0; - host_res->chnl_offset = 0; - /* CHNL_MAXCHANNELS */ - host_res->num_chnls = CHNL_MAXCHANNELS; - host_res->chnl_buf_size = 0x400; - dw_buff_size = sizeof(struct cfg_hostres); - } - *phost_resources = host_res; - } - /* End Mem alloc */ - return status; -} - -void mem_ext_phys_pool_init(u32 pool_phys_base, u32 pool_size) -{ - u32 pool_virt_base; - - /* get the virtual address for the physical memory pool passed */ - pool_virt_base = (u32) ioremap(pool_phys_base, pool_size); - - if ((void **)pool_virt_base == NULL) { - pr_err("%s: external physical memory map failed\n", __func__); - ext_phys_mem_pool_enabled = false; - } else { - ext_mem_pool.phys_mem_base = pool_phys_base; - ext_mem_pool.phys_mem_size = pool_size; - ext_mem_pool.virt_mem_base = pool_virt_base; - ext_mem_pool.next_phys_alloc_ptr = pool_phys_base; - ext_phys_mem_pool_enabled = true; - } -} - -void mem_ext_phys_pool_release(void) -{ - if (ext_phys_mem_pool_enabled) { - iounmap((void *)(ext_mem_pool.virt_mem_base)); - ext_phys_mem_pool_enabled = false; - } -} - -/* - * ======== mem_ext_phys_mem_alloc ======== - * Purpose: - * Allocate physically contiguous, uncached memory from external memory pool - */ - -static void *mem_ext_phys_mem_alloc(u32 bytes, u32 align, u32 *phys_addr) -{ - u32 new_alloc_ptr; - u32 offset; - u32 virt_addr; - - if (align == 0) - align = 1; - - if (bytes > ((ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size) - - ext_mem_pool.next_phys_alloc_ptr)) { - phys_addr = NULL; - return NULL; - } else { - offset = (ext_mem_pool.next_phys_alloc_ptr & (align - 1)); - if (offset == 0) - new_alloc_ptr = ext_mem_pool.next_phys_alloc_ptr; - else - new_alloc_ptr = (ext_mem_pool.next_phys_alloc_ptr) + - (align - offset); - if ((new_alloc_ptr + bytes) <= - (ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size)) { - /* we can allocate */ - *phys_addr = new_alloc_ptr; - ext_mem_pool.next_phys_alloc_ptr = - new_alloc_ptr + bytes; - virt_addr = - ext_mem_pool.virt_mem_base + (new_alloc_ptr - - ext_mem_pool. - phys_mem_base); - return (void *)virt_addr; - } else { - *phys_addr = 0; - return NULL; - } - } -} - -/* - * ======== mem_alloc_phys_mem ======== - * Purpose: - * Allocate physically contiguous, uncached memory - */ -void *mem_alloc_phys_mem(u32 byte_size, u32 align_mask, - u32 *physical_address) -{ - void *va_mem = NULL; - dma_addr_t pa_mem; - - if (byte_size > 0) { - if (ext_phys_mem_pool_enabled) { - va_mem = mem_ext_phys_mem_alloc(byte_size, align_mask, - (u32 *) &pa_mem); - } else - va_mem = dma_alloc_coherent(NULL, byte_size, &pa_mem, - GFP_KERNEL); - if (va_mem == NULL) - *physical_address = 0; - else - *physical_address = pa_mem; - } - return va_mem; -} - -/* - * ======== mem_free_phys_mem ======== - * Purpose: - * Free the given block of physically contiguous memory. - */ -void mem_free_phys_mem(void *virtual_address, u32 physical_address, - u32 byte_size) -{ - if (!ext_phys_mem_pool_enabled) - dma_free_coherent(NULL, byte_size, virtual_address, - physical_address); -} diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c deleted file mode 100644 index 74d31dabe83..00000000000 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - * drv_interface.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge driver interface. - * - * 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. - */ - -#include <linux/platform_data/dsp-omap.h> - -#include <linux/types.h> -#include <linux/platform_device.h> -#include <linux/pm.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/moduleparam.h> -#include <linux/cdev.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/clk.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dspapi.h> -#include <dspbridge/dspdrv.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/pwr.h> - -#include <dspbridge/resourcecleanup.h> -#include <dspbridge/proc.h> -#include <dspbridge/dev.h> - -#ifdef CONFIG_TIDSPBRIDGE_DVFS -#include <mach-omap2/omap3-opp.h> -#endif - -/* ----------------------------------- Globals */ -#define DSPBRIDGE_VERSION "0.3" -s32 dsp_debug; - -struct platform_device *omap_dspbridge_dev; -struct device *bridge; - -/* This is a test variable used by Bridge to test different sleep states */ -s32 dsp_test_sleepstate; - -static struct cdev bridge_cdev; - -static struct class *bridge_class; - -static u32 driver_context; -static s32 driver_major; -static char *base_img; -static s32 shm_size = 0x500000; /* 5 MB */ -static int tc_wordswapon; /* Default value is always false */ -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY -#define REC_TIMEOUT 5000 /*recovery timeout in msecs */ -static atomic_t bridge_cref; /* number of bridge open handles */ -static struct workqueue_struct *bridge_rec_queue; -static struct work_struct bridge_recovery_work; -static DECLARE_COMPLETION(bridge_comp); -static DECLARE_COMPLETION(bridge_open_comp); -static bool recover; -#endif - -#ifdef CONFIG_PM -struct omap34_xx_bridge_suspend_data { - int suspended; - wait_queue_head_t suspend_wq; -}; - -static struct omap34_xx_bridge_suspend_data bridge_suspend_data; - -static int omap34_xxbridge_suspend_lockout(struct omap34_xx_bridge_suspend_data - *s, struct file *f) -{ - if ((s)->suspended) { - if ((f)->f_flags & O_NONBLOCK) - return -EPERM; - wait_event_interruptible((s)->suspend_wq, (s)->suspended == 0); - } - return 0; -} -#endif - -module_param(dsp_debug, int, 0); -MODULE_PARM_DESC(dsp_debug, "Wait after loading DSP image. default = false"); - -module_param(dsp_test_sleepstate, int, 0); -MODULE_PARM_DESC(dsp_test_sleepstate, "DSP Sleep state = 0"); - -module_param(base_img, charp, 0); -MODULE_PARM_DESC(base_img, "DSP base image, default = NULL"); - -module_param(shm_size, int, 0); -MODULE_PARM_DESC(shm_size, "shm size, default = 4 MB, minimum = 64 KB"); - -module_param(tc_wordswapon, int, 0); -MODULE_PARM_DESC(tc_wordswapon, "TC Word Swap Option. default = 0"); - -MODULE_AUTHOR("Texas Instruments"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DSPBRIDGE_VERSION); - -/* - * This function is called when an application opens handle to the - * bridge driver. - */ -static int bridge_open(struct inode *ip, struct file *filp) -{ - int status = 0; - struct process_context *pr_ctxt = NULL; - - /* - * Allocate a new process context and insert it into global - * process context list. - */ - -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - if (recover) { - if (filp->f_flags & O_NONBLOCK || - wait_for_completion_interruptible(&bridge_open_comp)) - return -EBUSY; - } -#endif - pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL); - if (!pr_ctxt) - return -ENOMEM; - - pr_ctxt->res_state = PROC_RES_ALLOCATED; - spin_lock_init(&pr_ctxt->dmm_map_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); - spin_lock_init(&pr_ctxt->dmm_rsv_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); - - pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); - if (!pr_ctxt->node_id) { - status = -ENOMEM; - goto err1; - } - - idr_init(pr_ctxt->node_id); - - pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL); - if (!pr_ctxt->stream_id) { - status = -ENOMEM; - goto err2; - } - - idr_init(pr_ctxt->stream_id); - - filp->private_data = pr_ctxt; - -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - atomic_inc(&bridge_cref); -#endif - return 0; - -err2: - kfree(pr_ctxt->node_id); -err1: - kfree(pr_ctxt); - return status; -} - -/* - * This function is called when an application closes handle to the bridge - * driver. - */ -static int bridge_release(struct inode *ip, struct file *filp) -{ - int status = 0; - struct process_context *pr_ctxt; - - if (!filp->private_data) { - status = -EIO; - goto err; - } - - pr_ctxt = filp->private_data; - flush_signals(current); - drv_remove_all_resources(pr_ctxt); - proc_detach(pr_ctxt); - kfree(pr_ctxt->node_id); - kfree(pr_ctxt->stream_id); - kfree(pr_ctxt); - - filp->private_data = NULL; - -err: -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - if (!atomic_dec_return(&bridge_cref)) - complete(&bridge_comp); -#endif - return status; -} - -/* This function provides IO interface to the bridge driver. */ -static long bridge_ioctl(struct file *filp, unsigned int code, - unsigned long args) -{ - int status; - u32 retval = 0; - union trapped_args buf_in; - -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - if (recover) { - status = -EIO; - goto err; - } -#endif -#ifdef CONFIG_PM - status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp); - if (status != 0) - return status; -#endif - - if (!filp->private_data) { - status = -EIO; - goto err; - } - - status = copy_from_user(&buf_in, (union trapped_args *)args, - sizeof(union trapped_args)); - - if (!status) { - status = api_call_dev_ioctl(code, &buf_in, &retval, - filp->private_data); - - if (!status) { - status = retval; - } else { - dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x " - "status 0x%x\n", __func__, code, status); - status = -1; - } - - } - -err: - return status; -} - -/* This function maps kernel space memory to user space memory. */ -static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) -{ - unsigned long base_pgoff; - int status; - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - dev_dbg(bridge, "%s: vm filp %p start %lx end %lx page_prot %ulx " - "flags %lx\n", __func__, filp, - vma->vm_start, vma->vm_end, vma->vm_page_prot, - vma->vm_flags); - - /* - * vm_iomap_memory() expects vma->vm_pgoff to be expressed as an offset - * from the start of the physical memory pool, but we're called with - * a pfn (physical page number) stored there instead. - * - * To avoid duplicating lots of tricky overflow checking logic, - * temporarily convert vma->vm_pgoff to the offset vm_iomap_memory() - * expects, but restore the original value once the mapping has been - * created. - */ - base_pgoff = pdata->phys_mempool_base >> PAGE_SHIFT; - - if (vma->vm_pgoff < base_pgoff) - return -EINVAL; - - vma->vm_pgoff -= base_pgoff; - - status = vm_iomap_memory(vma, - pdata->phys_mempool_base, - pdata->phys_mempool_size); - - /* Restore the original value of vma->vm_pgoff */ - vma->vm_pgoff += base_pgoff; - - return status; -} - -static const struct file_operations bridge_fops = { - .open = bridge_open, - .release = bridge_release, - .unlocked_ioctl = bridge_ioctl, - .mmap = bridge_mmap, - .llseek = noop_llseek, -}; - -#ifdef CONFIG_PM -static u32 time_out = 1000; -#ifdef CONFIG_TIDSPBRIDGE_DVFS -s32 dsp_max_opps = VDD1_OPP5; -#endif - -/* Maximum Opps that can be requested by IVA */ -/*vdd1 rate table */ -#ifdef CONFIG_TIDSPBRIDGE_DVFS -const struct omap_opp vdd1_rate_table_bridge[] = { - {0, 0, 0}, - /*OPP1 */ - {S125M, VDD1_OPP1, 0}, - /*OPP2 */ - {S250M, VDD1_OPP2, 0}, - /*OPP3 */ - {S500M, VDD1_OPP3, 0}, - /*OPP4 */ - {S550M, VDD1_OPP4, 0}, - /*OPP5 */ - {S600M, VDD1_OPP5, 0}, -}; -#endif -#endif - -struct omap_dsp_platform_data *omap_dspbridge_pdata; - -u32 vdd1_dsp_freq[6][4] = { - {0, 0, 0, 0}, - /*OPP1 */ - {0, 90000, 0, 86000}, - /*OPP2 */ - {0, 180000, 80000, 170000}, - /*OPP3 */ - {0, 360000, 160000, 340000}, - /*OPP4 */ - {0, 396000, 325000, 376000}, - /*OPP5 */ - {0, 430000, 355000, 430000}, -}; - -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY -static void bridge_recover(struct work_struct *work) -{ - struct dev_object *dev; - struct cfg_devnode *dev_node; - if (atomic_read(&bridge_cref)) { - reinit_completion(&bridge_comp); - while (!wait_for_completion_timeout(&bridge_comp, - msecs_to_jiffies(REC_TIMEOUT))) - pr_info("%s:%d handle(s) still opened\n", - __func__, atomic_read(&bridge_cref)); - } - dev = dev_get_first(); - dev_get_dev_node(dev, &dev_node); - if (!dev_node || proc_auto_start(dev_node, dev)) - pr_err("DSP could not be restarted\n"); - recover = false; - complete_all(&bridge_open_comp); -} - -void bridge_recover_schedule(void) -{ - reinit_completion(&bridge_open_comp); - recover = true; - queue_work(bridge_rec_queue, &bridge_recovery_work); -} -#endif -#ifdef CONFIG_TIDSPBRIDGE_DVFS -static int dspbridge_scale_notification(struct notifier_block *op, - unsigned long val, void *ptr) -{ - struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; - - if (CPUFREQ_POSTCHANGE == val && pdata->dsp_get_opp) - pwr_pm_post_scale(PRCM_VDD1, pdata->dsp_get_opp()); - - return 0; -} - -static struct notifier_block iva_clk_notifier = { - .notifier_call = dspbridge_scale_notification, - NULL, -}; -#endif - -/** - * omap3_bridge_startup() - perform low lever initializations - * @pdev: pointer to platform device - * - * Initializes recovery, PM and DVFS required data, before calling - * clk and memory init routines. - */ -static int omap3_bridge_startup(struct platform_device *pdev) -{ - struct omap_dsp_platform_data *pdata = pdev->dev.platform_data; - struct drv_data *drv_datap = NULL; - u32 phys_membase, phys_memsize; - int err; - -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - bridge_rec_queue = create_workqueue("bridge_rec_queue"); - INIT_WORK(&bridge_recovery_work, bridge_recover); - reinit_completion(&bridge_comp); -#endif - -#ifdef CONFIG_PM - /* Initialize the wait queue */ - bridge_suspend_data.suspended = 0; - init_waitqueue_head(&bridge_suspend_data.suspend_wq); - -#ifdef CONFIG_TIDSPBRIDGE_DVFS - for (i = 0; i < 6; i++) - pdata->mpu_speed[i] = vdd1_rate_table_bridge[i].rate; - - err = cpufreq_register_notifier(&iva_clk_notifier, - CPUFREQ_TRANSITION_NOTIFIER); - if (err) - pr_err("%s: clk_notifier_register failed for iva2_ck\n", - __func__); -#endif -#endif - - dsp_clk_init(); - - drv_datap = kzalloc(sizeof(struct drv_data), GFP_KERNEL); - if (!drv_datap) { - err = -ENOMEM; - goto err1; - } - - drv_datap->shm_size = shm_size; - drv_datap->tc_wordswapon = tc_wordswapon; - - if (base_img) { - drv_datap->base_img = kstrdup(base_img, GFP_KERNEL); - if (!drv_datap->base_img) { - err = -ENOMEM; - goto err2; - } - } - - dev_set_drvdata(bridge, drv_datap); - - if (shm_size < 0x10000) { /* 64 KB */ - err = -EINVAL; - pr_err("%s: shm size must be at least 64 KB\n", __func__); - goto err3; - } - dev_dbg(bridge, "%s: requested shm_size = 0x%x\n", __func__, shm_size); - - phys_membase = pdata->phys_mempool_base; - phys_memsize = pdata->phys_mempool_size; - if (phys_membase > 0 && phys_memsize > 0) - mem_ext_phys_pool_init(phys_membase, phys_memsize); - - if (tc_wordswapon) - dev_dbg(bridge, "%s: TC Word Swap is enabled\n", __func__); - - driver_context = dsp_init(&err); - if (err) { - pr_err("DSP Bridge driver initialization failed\n"); - goto err4; - } - - return 0; - -err4: - mem_ext_phys_pool_release(); -err3: - kfree(drv_datap->base_img); -err2: - kfree(drv_datap); -err1: -#ifdef CONFIG_TIDSPBRIDGE_DVFS - cpufreq_unregister_notifier(&iva_clk_notifier, - CPUFREQ_TRANSITION_NOTIFIER); -#endif - dsp_clk_exit(); - - return err; -} - -static int omap34_xx_bridge_probe(struct platform_device *pdev) -{ - int err; - dev_t dev = 0; -#ifdef CONFIG_TIDSPBRIDGE_DVFS - int i = 0; -#endif - - omap_dspbridge_dev = pdev; - - /* Global bridge device */ - bridge = &omap_dspbridge_dev->dev; - - /* Bridge low level initializations */ - err = omap3_bridge_startup(pdev); - if (err) - goto err1; - - /* use 2.6 device model */ - err = alloc_chrdev_region(&dev, 0, 1, "DspBridge"); - if (err) { - pr_err("%s: Can't get major %d\n", __func__, driver_major); - goto err1; - } - - cdev_init(&bridge_cdev, &bridge_fops); - bridge_cdev.owner = THIS_MODULE; - - err = cdev_add(&bridge_cdev, dev, 1); - if (err) { - pr_err("%s: Failed to add bridge device\n", __func__); - goto err2; - } - - /* udev support */ - bridge_class = class_create(THIS_MODULE, "ti_bridge"); - if (IS_ERR(bridge_class)) { - pr_err("%s: Error creating bridge class\n", __func__); - err = PTR_ERR(bridge_class); - goto err3; - } - - driver_major = MAJOR(dev); - device_create(bridge_class, NULL, MKDEV(driver_major, 0), - NULL, "DspBridge"); - pr_info("DSP Bridge driver loaded\n"); - - return 0; - -err3: - cdev_del(&bridge_cdev); -err2: - unregister_chrdev_region(dev, 1); -err1: - return err; -} - -static int omap34_xx_bridge_remove(struct platform_device *pdev) -{ - dev_t devno; - int status = 0; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - /* Retrieve the Object handle from the driver data */ - if (!drv_datap || !drv_datap->drv_object) { - status = -ENODATA; - pr_err("%s: Failed to retrieve the object handle\n", __func__); - goto func_cont; - } - -#ifdef CONFIG_TIDSPBRIDGE_DVFS - if (cpufreq_unregister_notifier(&iva_clk_notifier, - CPUFREQ_TRANSITION_NOTIFIER)) - pr_err("%s: cpufreq_unregister_notifier failed for iva2_ck\n", - __func__); -#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */ - - if (driver_context) { - /* Put the DSP in reset state */ - dsp_deinit(driver_context); - driver_context = 0; - } - - kfree(drv_datap); - dev_set_drvdata(bridge, NULL); - -func_cont: - mem_ext_phys_pool_release(); - - dsp_clk_exit(); - - devno = MKDEV(driver_major, 0); - cdev_del(&bridge_cdev); - unregister_chrdev_region(devno, 1); - if (bridge_class) { - /* remove the device from sysfs */ - device_destroy(bridge_class, MKDEV(driver_major, 0)); - class_destroy(bridge_class); - - } - return status; -} - -#ifdef CONFIG_PM -static int bridge_suspend(struct platform_device *pdev, pm_message_t state) -{ - u32 status; - u32 command = PWR_EMERGENCYDEEPSLEEP; - - status = pwr_sleep_dsp(command, time_out); - if (status) - return -1; - - bridge_suspend_data.suspended = 1; - return 0; -} - -static int bridge_resume(struct platform_device *pdev) -{ - u32 status; - - status = pwr_wake_dsp(time_out); - if (status) - return -1; - - bridge_suspend_data.suspended = 0; - wake_up(&bridge_suspend_data.suspend_wq); - return 0; -} -#endif - -static struct platform_driver bridge_driver = { - .driver = { - .name = "omap-dsp", - }, - .probe = omap34_xx_bridge_probe, - .remove = omap34_xx_bridge_remove, -#ifdef CONFIG_PM - .suspend = bridge_suspend, - .resume = bridge_resume, -#endif -}; - -/* To remove all process resources before removing the process from the - * process context list */ -int drv_remove_all_resources(void *process_ctxt) -{ - int status = 0; - struct process_context *ctxt = (struct process_context *)process_ctxt; - drv_remove_all_strm_res_elements(ctxt); - drv_remove_all_node_res_elements(ctxt); - drv_remove_all_dmm_res_elements(ctxt); - ctxt->res_state = PROC_RES_FREED; - return status; -} - -module_platform_driver(bridge_driver); diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c deleted file mode 100644 index 012e4a38d2d..00000000000 --- a/drivers/staging/tidspbridge/rmgr/dspdrv.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * dspdrv.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Interface to allocate and free bridge resources. - * - * 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 <linux/types.h> -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/drv.h> -#include <dspbridge/dev.h> -#include <dspbridge/dspapi.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/mgr.h> - -/* ----------------------------------- This */ -#include <dspbridge/dspdrv.h> - -/* - * ======== dsp_init ======== - * Allocates bridge resources. Loads a base image onto DSP, if specified. - */ -u32 dsp_init(u32 *init_status) -{ - char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510"; - int status = -EPERM; - struct drv_object *drv_obj = NULL; - u32 device_node; - u32 device_node_string; - - if (!api_init()) - goto func_cont; - - status = drv_create(&drv_obj); - if (status) { - api_exit(); - goto func_cont; - } - - /* End drv_create */ - /* Request Resources */ - status = drv_request_resources((u32) &dev_node, &device_node_string); - if (!status) { - /* Attempt to Start the Device */ - status = dev_start_device((struct cfg_devnode *) - device_node_string); - if (status) - (void)drv_release_resources - ((u32) device_node_string, drv_obj); - } else { - dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__); - status = -EPERM; - } - - /* Unwind whatever was loaded */ - if (status) { - /* irrespective of the status of dev_remove_device we continue - * unloading. Get the Driver Object iterate through and remove. - * Reset the status to E_FAIL to avoid going through - * api_init_complete2. */ - for (device_node = drv_get_first_dev_extension(); - device_node != 0; - device_node = drv_get_next_dev_extension(device_node)) { - (void)dev_remove_device((struct cfg_devnode *) - device_node); - (void)drv_release_resources((u32) device_node, drv_obj); - } - /* Remove the Driver Object */ - (void)drv_destroy(drv_obj); - drv_obj = NULL; - api_exit(); - dev_dbg(bridge, "%s: Logical device failed init\n", __func__); - } /* Unwinding the loaded drivers */ -func_cont: - /* Attempt to Start the Board */ - if (!status) { - /* BRD_AutoStart could fail if the dsp executable is not the - * correct one. We should not propagate that error - * into the device loader. */ - (void)api_init_complete2(); - } else { - dev_dbg(bridge, "%s: Failed\n", __func__); - } /* End api_init_complete2 */ - *init_status = status; - /* Return the Driver Object */ - return (u32) drv_obj; -} - -/* - * ======== dsp_deinit ======== - * Frees the resources allocated for bridge. - */ -bool dsp_deinit(u32 device_context) -{ - bool ret = true; - u32 device_node; - struct mgr_object *mgr_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - while ((device_node = drv_get_first_dev_extension()) != 0) { - (void)dev_remove_device((struct cfg_devnode *)device_node); - - (void)drv_release_resources((u32) device_node, - (struct drv_object *)device_context); - } - - (void)drv_destroy((struct drv_object *)device_context); - - /* Get the Manager Object from driver data - * MGR Destroy will unload the DCD dll */ - if (drv_datap && drv_datap->mgr_object) { - mgr_obj = drv_datap->mgr_object; - (void)mgr_destroy(mgr_obj); - } else { - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } - - api_exit(); - - return ret; -} diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c deleted file mode 100644 index 93e6282f122..00000000000 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * mgr.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implementation of Manager interface to the device object at the - * driver level. This queries the NDB data base and retrieves the - * data about Node and Processor. - * - * 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. - */ - -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Others */ -#include <dspbridge/dbdcd.h> -#include <dspbridge/drv.h> -#include <dspbridge/dev.h> - -/* ----------------------------------- This */ -#include <dspbridge/mgr.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define ZLDLLNAME "" - -struct mgr_object { - struct dcd_manager *dcd_mgr; /* Proc/Node data manager */ -}; - -/* ----------------------------------- Globals */ -static u32 refs; - -/* - * ========= mgr_create ========= - * Purpose: - * MGR Object gets created only once during driver Loading. - */ -int mgr_create(struct mgr_object **mgr_obj, - struct cfg_devnode *dev_node_obj) -{ - int status = 0; - struct mgr_object *pmgr_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL); - if (pmgr_obj) { - status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->dcd_mgr); - if (!status) { - /* If succeeded store the handle in the MGR Object */ - if (drv_datap) { - drv_datap->mgr_object = (void *)pmgr_obj; - } else { - status = -EPERM; - pr_err("%s: Failed to store MGR object\n", - __func__); - } - - if (!status) { - *mgr_obj = pmgr_obj; - } else { - dcd_destroy_manager(pmgr_obj->dcd_mgr); - kfree(pmgr_obj); - } - } else { - /* failed to Create DCD Manager */ - kfree(pmgr_obj); - } - } else { - status = -ENOMEM; - } - - return status; -} - -/* - * ========= mgr_destroy ========= - * This function is invoked during bridge driver unloading.Frees MGR object. - */ -int mgr_destroy(struct mgr_object *hmgr_obj) -{ - int status = 0; - struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - /* Free resources */ - if (hmgr_obj->dcd_mgr) - dcd_destroy_manager(hmgr_obj->dcd_mgr); - - kfree(pmgr_obj); - /* Update the driver data with NULL for MGR Object */ - if (drv_datap) { - drv_datap->mgr_object = NULL; - } else { - status = -EPERM; - pr_err("%s: Failed to store MGR object\n", __func__); - } - - return status; -} - -/* - * ======== mgr_enum_node_info ======== - * Enumerate and get configuration information about nodes configured - * in the node database. - */ -int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, - u32 undb_props_size, u32 *pu_num_nodes) -{ - int status = 0; - struct dsp_uuid node_uuid; - u32 node_index = 0; - struct dcd_genericobj gen_obj; - struct mgr_object *pmgr_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - *pu_num_nodes = 0; - /* Get the Manager Object from the driver data */ - if (!drv_datap || !drv_datap->mgr_object) { - pr_err("%s: Failed to retrieve the object handle\n", __func__); - return -ENODATA; - } - pmgr_obj = drv_datap->mgr_object; - - /* Forever loop till we hit failed or no more items in the - * Enumeration. We will exit the loop other than 0; */ - while (!status) { - status = dcd_enumerate_object(node_index++, DSP_DCDNODETYPE, - &node_uuid); - if (status) - break; - *pu_num_nodes = node_index; - if (node_id == (node_index - 1)) { - status = dcd_get_object_def(pmgr_obj->dcd_mgr, - &node_uuid, DSP_DCDNODETYPE, &gen_obj); - if (status) - break; - /* Get the Obj def */ - *pndb_props = gen_obj.obj_data.node_obj.ndb_props; - } - } - - /* the last status is not 0, but neither an error */ - if (status > 0) - status = 0; - - return status; -} - -/* - * ======== mgr_enum_processor_info ======== - * Enumerate and get configuration information about available - * DSP processors. - */ -int mgr_enum_processor_info(u32 processor_id, - struct dsp_processorinfo * - processor_info, u32 processor_info_size, - u8 *pu_num_procs) -{ - int status = 0; - int status1 = 0; - int status2 = 0; - struct dsp_uuid temp_uuid; - u32 temp_index = 0; - u32 proc_index = 0; - struct dcd_genericobj gen_obj; - struct mgr_object *pmgr_obj = NULL; - struct mgr_processorextinfo *ext_info; - struct dev_object *hdev_obj; - struct drv_object *hdrv_obj; - u8 dev_type; - struct cfg_devnode *dev_node; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - bool proc_detect = false; - - *pu_num_procs = 0; - - /* Retrieve the Object handle from the driver data */ - if (!drv_datap || !drv_datap->drv_object) { - status = -ENODATA; - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } else { - hdrv_obj = drv_datap->drv_object; - } - - if (!status) { - status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj); - if (!status) { - status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type); - status = dev_get_dev_node(hdev_obj, &dev_node); - if (dev_type != DSP_UNIT) - status = -EPERM; - - if (!status) - processor_info->processor_type = DSPTYPE64; - } - } - if (status) - goto func_end; - - /* Get The Manager Object from the driver data */ - if (drv_datap && drv_datap->mgr_object) { - pmgr_obj = drv_datap->mgr_object; - } else { - dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__); - goto func_end; - } - /* Forever loop till we hit no more items in the - * Enumeration. We will exit the loop other than 0; */ - while (status1 == 0) { - status1 = dcd_enumerate_object(temp_index++, - DSP_DCDPROCESSORTYPE, - &temp_uuid); - if (status1 != 0) - break; - - proc_index++; - /* Get the Object properties to find the Device/Processor - * Type */ - if (proc_detect != false) - continue; - - status2 = dcd_get_object_def(pmgr_obj->dcd_mgr, - (struct dsp_uuid *)&temp_uuid, - DSP_DCDPROCESSORTYPE, &gen_obj); - if (!status2) { - /* Get the Obj def */ - if (processor_info_size < - sizeof(struct mgr_processorextinfo)) { - *processor_info = gen_obj.obj_data.proc_info; - } else { - /* extended info */ - ext_info = (struct mgr_processorextinfo *) - processor_info; - *ext_info = gen_obj.obj_data.ext_proc_obj; - } - dev_dbg(bridge, "%s: Got proctype from DCD %x\n", - __func__, processor_info->processor_type); - /* See if we got the needed processor */ - if (dev_type == DSP_UNIT) { - if (processor_info->processor_type == - DSPPROCTYPE_C64) - proc_detect = true; - } else if (dev_type == IVA_UNIT) { - if (processor_info->processor_type == - IVAPROCTYPE_ARM7) - proc_detect = true; - } - /* User applications only check for chip type, so - * this is a clumsy overwrite */ - processor_info->processor_type = DSPTYPE64; - } else { - dev_dbg(bridge, "%s: Failed to get DCD processor info %x\n", - __func__, status2); - status = -EPERM; - } - } - *pu_num_procs = proc_index; - if (proc_detect == false) { - dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use CFG registry\n", - __func__); - processor_info->processor_type = DSPTYPE64; - } -func_end: - return status; -} - -/* - * ======== mgr_exit ======== - * Decrement reference count, and free resources when reference count is - * 0. - */ -void mgr_exit(void) -{ - refs--; - if (refs == 0) - dcd_exit(); -} - -/* - * ======== mgr_get_dcd_handle ======== - * Retrieves the MGR handle. Accessor Function. - */ -int mgr_get_dcd_handle(struct mgr_object *mgr_handle, - u32 *dcd_handle) -{ - int status = -EPERM; - struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle; - - *dcd_handle = (u32) NULL; - if (pmgr_obj) { - *dcd_handle = (u32) pmgr_obj->dcd_mgr; - status = 0; - } - - return status; -} - -/* - * ======== mgr_init ======== - * Initialize MGR's private state, keeping a reference count on each call. - */ -bool mgr_init(void) -{ - bool ret = true; - - if (refs == 0) - ret = dcd_init(); /* DCD Module */ - - if (ret) - refs++; - - return ret; -} - -/* - * ======== mgr_wait_for_bridge_events ======== - * Block on any Bridge event(s) - */ -int mgr_wait_for_bridge_events(struct dsp_notification **anotifications, - u32 count, u32 *pu_index, - u32 utimeout) -{ - int status; - struct sync_object *sync_events[MAX_EVENTS]; - u32 i; - - for (i = 0; i < count; i++) - sync_events[i] = anotifications[i]->handle; - - status = sync_wait_on_multiple_events(sync_events, count, utimeout, - pu_index); - - return status; - -} diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c deleted file mode 100644 index 5ac507ccd19..00000000000 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ /dev/null @@ -1,1860 +0,0 @@ -/* - * nldr.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge dynamic + overlay Node loader. - * - * 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. - */ - -#include <linux/types.h> - -#include <dspbridge/host_os.h> - -#include <dspbridge/dbdefs.h> - -/* Platform manager */ -#include <dspbridge/cod.h> -#include <dspbridge/dev.h> - -/* Resource manager */ -#include <dspbridge/dbll.h> -#include <dspbridge/dbdcd.h> -#include <dspbridge/rmm.h> -#include <dspbridge/uuidutil.h> - -#include <dspbridge/nldr.h> -#include <linux/lcm.h> - -/* Name of section containing dynamic load mem */ -#define DYNMEMSECT ".dspbridge_mem" - -/* Name of section containing dependent library information */ -#define DEPLIBSECT ".dspbridge_deplibs" - -/* Max depth of recursion for loading node's dependent libraries */ -#define MAXDEPTH 5 - -/* Max number of persistent libraries kept by a node */ -#define MAXLIBS 5 - -/* - * Defines for extracting packed dynamic load memory requirements from two - * masks. - * These defines must match node.cdb and dynm.cdb - * Format of data/code mask is: - * uuuuuuuu|fueeeeee|fudddddd|fucccccc| - * where - * u = unused - * cccccc = preferred/required dynamic mem segid for create phase data/code - * dddddd = preferred/required dynamic mem segid for delete phase data/code - * eeeeee = preferred/req. dynamic mem segid for execute phase data/code - * f = flag indicating if memory is preferred or required: - * f = 1 if required, f = 0 if preferred. - * - * The 6 bits of the segid are interpreted as follows: - * - * If the 6th bit (bit 5) is not set, then this specifies a memory segment - * between 0 and 31 (a maximum of 32 dynamic loading memory segments). - * If the 6th bit (bit 5) is set, segid has the following interpretation: - * segid = 32 - Any internal memory segment can be used. - * segid = 33 - Any external memory segment can be used. - * segid = 63 - Any memory segment can be used (in this case the - * required/preferred flag is irrelevant). - * - */ -/* Maximum allowed dynamic loading memory segments */ -#define MAXMEMSEGS 32 - -#define MAXSEGID 3 /* Largest possible (real) segid */ -#define MEMINTERNALID 32 /* Segid meaning use internal mem */ -#define MEMEXTERNALID 33 /* Segid meaning use external mem */ -#define NULLID 63 /* Segid meaning no memory req/pref */ -#define FLAGBIT 7 /* 7th bit is pref./req. flag */ -#define SEGMASK 0x3f /* Bits 0 - 5 */ - -#define CREATEBIT 0 /* Create segid starts at bit 0 */ -#define DELETEBIT 8 /* Delete segid starts at bit 8 */ -#define EXECUTEBIT 16 /* Execute segid starts at bit 16 */ - -/* - * Masks that define memory type. Must match defines in dynm.cdb. - */ -#define DYNM_CODE 0x2 -#define DYNM_DATA 0x4 -#define DYNM_CODEDATA (DYNM_CODE | DYNM_DATA) -#define DYNM_INTERNAL 0x8 -#define DYNM_EXTERNAL 0x10 - -/* - * Defines for packing memory requirement/preference flags for code and - * data of each of the node's phases into one mask. - * The bit is set if the segid is required for loading code/data of the - * given phase. The bit is not set, if the segid is preferred only. - * - * These defines are also used as indeces into a segid array for the node. - * eg node's segid[CREATEDATAFLAGBIT] is the memory segment id that the - * create phase data is required or preferred to be loaded into. - */ -#define CREATEDATAFLAGBIT 0 -#define CREATECODEFLAGBIT 1 -#define EXECUTEDATAFLAGBIT 2 -#define EXECUTECODEFLAGBIT 3 -#define DELETEDATAFLAGBIT 4 -#define DELETECODEFLAGBIT 5 -#define MAXFLAGS 6 - - /* - * These names may be embedded in overlay sections to identify which - * node phase the section should be overlayed. - */ -#define PCREATE "create" -#define PDELETE "delete" -#define PEXECUTE "execute" - -static inline bool is_equal_uuid(struct dsp_uuid *uuid1, - struct dsp_uuid *uuid2) -{ - return !memcmp(uuid1, uuid2, sizeof(struct dsp_uuid)); -} - - /* - * ======== mem_seg_info ======== - * Format of dynamic loading memory segment info in coff file. - * Must match dynm.h55. - */ -struct mem_seg_info { - u32 segid; /* Dynamic loading memory segment number */ - u32 base; - u32 len; - u32 type; /* Mask of DYNM_CODE, DYNM_INTERNAL, etc. */ -}; - -/* - * ======== lib_node ======== - * For maintaining a tree of library dependencies. - */ -struct lib_node { - struct dbll_library_obj *lib; /* The library */ - u16 dep_libs; /* Number of dependent libraries */ - struct lib_node *dep_libs_tree; /* Dependent libraries of lib */ -}; - -/* - * ======== ovly_sect ======== - * Information needed to overlay a section. - */ -struct ovly_sect { - struct ovly_sect *next_sect; - u32 sect_load_addr; /* Load address of section */ - u32 sect_run_addr; /* Run address of section */ - u32 size; /* Size of section */ - u16 page; /* DBL_CODE, DBL_DATA */ -}; - -/* - * ======== ovly_node ======== - * For maintaining a list of overlay nodes, with sections that need to be - * overlayed for each of the nodes phases. - */ -struct ovly_node { - struct dsp_uuid uuid; - char *node_name; - struct ovly_sect *create_sects_list; - struct ovly_sect *delete_sects_list; - struct ovly_sect *execute_sects_list; - struct ovly_sect *other_sects_list; - u16 create_sects; - u16 delete_sects; - u16 execute_sects; - u16 other_sects; - u16 create_ref; - u16 delete_ref; - u16 execute_ref; - u16 other_ref; -}; - -/* - * ======== nldr_object ======== - * Overlay loader object. - */ -struct nldr_object { - struct dev_object *dev_obj; /* Device object */ - struct dcd_manager *dcd_mgr; /* Proc/Node data manager */ - struct dbll_tar_obj *dbll; /* The DBL loader */ - struct dbll_library_obj *base_lib; /* Base image library */ - struct rmm_target_obj *rmm; /* Remote memory manager for DSP */ - struct dbll_fxns ldr_fxns; /* Loader function table */ - struct dbll_attrs ldr_attrs; /* attrs to pass to loader functions */ - nldr_ovlyfxn ovly_fxn; /* "write" for overlay nodes */ - nldr_writefxn write_fxn; /* "write" for dynamic nodes */ - struct ovly_node *ovly_table; /* Table of overlay nodes */ - u16 ovly_nodes; /* Number of overlay nodes in base */ - u16 ovly_nid; /* Index for tracking overlay nodes */ - u16 dload_segs; /* Number of dynamic load mem segs */ - u32 *seg_table; /* memtypes of dynamic memory segs - * indexed by segid - */ - u16 dsp_mau_size; /* Size of DSP MAU */ - u16 dsp_word_size; /* Size of DSP word */ -}; - -/* - * ======== nldr_nodeobject ======== - * Dynamic node object. This object is created when a node is allocated. - */ -struct nldr_nodeobject { - struct nldr_object *nldr_obj; /* Dynamic loader handle */ - void *priv_ref; /* Handle to pass to dbl_write_fxn */ - struct dsp_uuid uuid; /* Node's UUID */ - bool dynamic; /* Dynamically loaded node? */ - bool overlay; /* Overlay node? */ - bool *phase_split; /* Multiple phase libraries? */ - struct lib_node root; /* Library containing node phase */ - struct lib_node create_lib; /* Library with create phase lib */ - struct lib_node execute_lib; /* Library with execute phase lib */ - struct lib_node delete_lib; /* Library with delete phase lib */ - /* libs remain loaded until Delete */ - struct lib_node pers_lib_table[MAXLIBS]; - s32 pers_libs; /* Number of persistent libraries */ - /* Path in lib dependency tree */ - struct dbll_library_obj *lib_path[MAXDEPTH + 1]; - enum nldr_phase phase; /* Node phase currently being loaded */ - - /* - * Dynamic loading memory segments for data and code of each phase. - */ - u16 seg_id[MAXFLAGS]; - - /* - * Mask indicating whether each mem segment specified in seg_id[] - * is preferred or required. - * For example - * if (code_data_flag_mask & (1 << EXECUTEDATAFLAGBIT)) != 0, - * then it is required to load execute phase data into the memory - * specified by seg_id[EXECUTEDATAFLAGBIT]. - */ - u32 code_data_flag_mask; -}; - -/* Dynamic loader function table */ -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_open_fxn) dbll_open, - (dbll_read_sect_fxn) dbll_read_sect, - (dbll_unload_fxn) dbll_unload, -}; - -static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info, - u32 addr, u32 bytes); -static int add_ovly_node(struct dsp_uuid *uuid_obj, - enum dsp_dcdobjtype obj_type, void *handle); -static int add_ovly_sect(struct nldr_object *nldr_obj, - struct ovly_sect **lst, - struct dbll_sect_info *sect_inf, - bool *exists, u32 addr, u32 bytes); -static s32 fake_ovly_write(void *handle, u32 dsp_address, void *buf, u32 bytes, - s32 mtype); -static void free_sects(struct nldr_object *nldr_obj, - struct ovly_sect *phase_sects, u16 alloc_num); -static bool get_symbol_value(void *handle, void *parg, void *rmm_handle, - char *sym_name, struct dbll_sym_val **sym); -static int load_lib(struct nldr_nodeobject *nldr_node_obj, - struct lib_node *root, struct dsp_uuid uuid, - bool root_prstnt, - struct dbll_library_obj **lib_path, - enum nldr_phase phase, u16 depth); -static int load_ovly(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase); -static int remote_alloc(void **ref, u16 mem_sect, u32 size, - u32 align, u32 *dsp_address, - s32 segmnt_id, - s32 req, bool reserve); -static int remote_free(void **ref, u16 space, u32 dsp_address, u32 size, - bool reserve); - -static void unload_lib(struct nldr_nodeobject *nldr_node_obj, - struct lib_node *root); -static void unload_ovly(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase); -static bool find_in_persistent_lib_array(struct nldr_nodeobject *nldr_node_obj, - struct dbll_library_obj *lib); - -/* - * ======== nldr_allocate ======== - */ -int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref, - const struct dcd_nodeprops *node_props, - struct nldr_nodeobject **nldr_nodeobj, - bool *pf_phase_split) -{ - struct nldr_nodeobject *nldr_node_obj = NULL; - int status = 0; - - /* Initialize handle in case of failure */ - *nldr_nodeobj = NULL; - /* Allocate node object */ - nldr_node_obj = kzalloc(sizeof(struct nldr_nodeobject), GFP_KERNEL); - - if (nldr_node_obj == NULL) { - status = -ENOMEM; - } else { - nldr_node_obj->phase_split = pf_phase_split; - nldr_node_obj->pers_libs = 0; - nldr_node_obj->nldr_obj = nldr_obj; - nldr_node_obj->priv_ref = priv_ref; - /* Save node's UUID. */ - nldr_node_obj->uuid = node_props->ndb_props.ui_node_id; - /* - * Determine if node is a dynamically loaded node from - * ndb_props. - */ - if (node_props->load_type == NLDR_DYNAMICLOAD) { - /* Dynamic node */ - nldr_node_obj->dynamic = true; - /* - * Extract memory requirements from ndb_props masks - */ - /* Create phase */ - nldr_node_obj->seg_id[CREATEDATAFLAGBIT] = (u16) - (node_props->data_mem_seg_mask >> CREATEBIT) & - SEGMASK; - nldr_node_obj->code_data_flag_mask |= - ((node_props->data_mem_seg_mask >> - (CREATEBIT + FLAGBIT)) & 1) << CREATEDATAFLAGBIT; - nldr_node_obj->seg_id[CREATECODEFLAGBIT] = (u16) - (node_props->code_mem_seg_mask >> - CREATEBIT) & SEGMASK; - nldr_node_obj->code_data_flag_mask |= - ((node_props->code_mem_seg_mask >> - (CREATEBIT + FLAGBIT)) & 1) << CREATECODEFLAGBIT; - /* Execute phase */ - nldr_node_obj->seg_id[EXECUTEDATAFLAGBIT] = (u16) - (node_props->data_mem_seg_mask >> - EXECUTEBIT) & SEGMASK; - nldr_node_obj->code_data_flag_mask |= - ((node_props->data_mem_seg_mask >> - (EXECUTEBIT + FLAGBIT)) & 1) << - EXECUTEDATAFLAGBIT; - nldr_node_obj->seg_id[EXECUTECODEFLAGBIT] = (u16) - (node_props->code_mem_seg_mask >> - EXECUTEBIT) & SEGMASK; - nldr_node_obj->code_data_flag_mask |= - ((node_props->code_mem_seg_mask >> - (EXECUTEBIT + FLAGBIT)) & 1) << - EXECUTECODEFLAGBIT; - /* Delete phase */ - nldr_node_obj->seg_id[DELETEDATAFLAGBIT] = (u16) - (node_props->data_mem_seg_mask >> DELETEBIT) & - SEGMASK; - nldr_node_obj->code_data_flag_mask |= - ((node_props->data_mem_seg_mask >> - (DELETEBIT + FLAGBIT)) & 1) << DELETEDATAFLAGBIT; - nldr_node_obj->seg_id[DELETECODEFLAGBIT] = (u16) - (node_props->code_mem_seg_mask >> - DELETEBIT) & SEGMASK; - nldr_node_obj->code_data_flag_mask |= - ((node_props->code_mem_seg_mask >> - (DELETEBIT + FLAGBIT)) & 1) << DELETECODEFLAGBIT; - } else { - /* Non-dynamically loaded nodes are part of the - * base image */ - nldr_node_obj->root.lib = nldr_obj->base_lib; - /* Check for overlay node */ - if (node_props->load_type == NLDR_OVLYLOAD) - nldr_node_obj->overlay = true; - - } - *nldr_nodeobj = (struct nldr_nodeobject *)nldr_node_obj; - } - /* Cleanup on failure */ - if (status && nldr_node_obj) - kfree(nldr_node_obj); - - return status; -} - -/* - * ======== nldr_create ======== - */ -int nldr_create(struct nldr_object **nldr, - struct dev_object *hdev_obj, - const struct nldr_attrs *pattrs) -{ - struct cod_manager *cod_mgr; /* COD manager */ - char *psz_coff_buf = NULL; - char sz_zl_file[COD_MAXPATHLENGTH]; - struct nldr_object *nldr_obj = NULL; - struct dbll_attrs save_attrs; - struct dbll_attrs new_attrs; - dbll_flags flags; - u32 ul_entry; - u16 dload_segs = 0; - struct mem_seg_info *mem_info_obj; - u32 ul_len = 0; - u32 ul_addr; - struct rmm_segment *rmm_segs = NULL; - u16 i; - int status = 0; - - /* Allocate dynamic loader object */ - nldr_obj = kzalloc(sizeof(struct nldr_object), GFP_KERNEL); - if (nldr_obj) { - nldr_obj->dev_obj = hdev_obj; - /* warning, lazy status checking alert! */ - dev_get_cod_mgr(hdev_obj, &cod_mgr); - if (cod_mgr) { - status = cod_get_loader(cod_mgr, &nldr_obj->dbll); - status = cod_get_base_lib(cod_mgr, &nldr_obj->base_lib); - status = - cod_get_base_name(cod_mgr, sz_zl_file, - COD_MAXPATHLENGTH); - } - status = 0; - /* end lazy status checking */ - nldr_obj->dsp_mau_size = pattrs->dsp_mau_size; - nldr_obj->dsp_word_size = pattrs->dsp_word_size; - nldr_obj->ldr_fxns = ldr_fxns; - if (!(nldr_obj->ldr_fxns.init_fxn())) - status = -ENOMEM; - - } else { - status = -ENOMEM; - } - /* Create the DCD Manager */ - if (!status) - status = dcd_create_manager(NULL, &nldr_obj->dcd_mgr); - - /* Get dynamic loading memory sections from base lib */ - if (!status) { - status = - nldr_obj->ldr_fxns.get_sect_fxn(nldr_obj->base_lib, - DYNMEMSECT, &ul_addr, - &ul_len); - if (!status) { - psz_coff_buf = - kzalloc(ul_len * nldr_obj->dsp_mau_size, - GFP_KERNEL); - if (!psz_coff_buf) - status = -ENOMEM; - } else { - /* Ok to not have dynamic loading memory */ - status = 0; - ul_len = 0; - dev_dbg(bridge, "%s: failed - no dynamic loading mem " - "segments: 0x%x\n", __func__, status); - } - } - if (!status && ul_len > 0) { - /* Read section containing dynamic load mem segments */ - status = - nldr_obj->ldr_fxns.read_sect_fxn(nldr_obj->base_lib, - DYNMEMSECT, psz_coff_buf, - ul_len); - } - if (!status && ul_len > 0) { - /* Parse memory segment data */ - dload_segs = (u16) (*((u32 *) psz_coff_buf)); - if (dload_segs > MAXMEMSEGS) - status = -EBADF; - } - /* Parse dynamic load memory segments */ - if (!status && dload_segs > 0) { - rmm_segs = kzalloc(sizeof(struct rmm_segment) * dload_segs, - GFP_KERNEL); - nldr_obj->seg_table = - kzalloc(sizeof(u32) * dload_segs, GFP_KERNEL); - if (rmm_segs == NULL || nldr_obj->seg_table == NULL) { - status = -ENOMEM; - } else { - nldr_obj->dload_segs = dload_segs; - mem_info_obj = (struct mem_seg_info *)(psz_coff_buf + - sizeof(u32)); - for (i = 0; i < dload_segs; i++) { - rmm_segs[i].base = (mem_info_obj + i)->base; - rmm_segs[i].length = (mem_info_obj + i)->len; - rmm_segs[i].space = 0; - nldr_obj->seg_table[i] = - (mem_info_obj + i)->type; - dev_dbg(bridge, - "(proc) DLL MEMSEGMENT: %d, " - "Base: 0x%x, Length: 0x%x\n", i, - rmm_segs[i].base, rmm_segs[i].length); - } - } - } - /* Create Remote memory manager */ - if (!status) - status = rmm_create(&nldr_obj->rmm, rmm_segs, dload_segs); - - if (!status) { - /* set the alloc, free, write functions for loader */ - nldr_obj->ldr_fxns.get_attrs_fxn(nldr_obj->dbll, &save_attrs); - new_attrs = save_attrs; - new_attrs.alloc = (dbll_alloc_fxn) remote_alloc; - new_attrs.free = (dbll_free_fxn) remote_free; - new_attrs.sym_lookup = (dbll_sym_lookup) get_symbol_value; - new_attrs.sym_handle = nldr_obj; - new_attrs.write = (dbll_write_fxn) pattrs->write; - nldr_obj->ovly_fxn = pattrs->ovly; - nldr_obj->write_fxn = pattrs->write; - nldr_obj->ldr_attrs = new_attrs; - } - kfree(rmm_segs); - - kfree(psz_coff_buf); - - /* Get overlay nodes */ - if (!status) { - status = - cod_get_base_name(cod_mgr, sz_zl_file, COD_MAXPATHLENGTH); - /* lazy check */ - /* First count number of overlay nodes */ - status = - dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file, - add_ovly_node, (void *)nldr_obj); - /* Now build table of overlay nodes */ - if (!status && nldr_obj->ovly_nodes > 0) { - /* Allocate table for overlay nodes */ - nldr_obj->ovly_table = - kzalloc(sizeof(struct ovly_node) * - nldr_obj->ovly_nodes, GFP_KERNEL); - /* Put overlay nodes in the table */ - nldr_obj->ovly_nid = 0; - status = dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file, - add_ovly_node, - (void *)nldr_obj); - } - } - /* Do a fake reload of the base image to get overlay section info */ - if (!status && nldr_obj->ovly_nodes > 0) { - save_attrs.write = fake_ovly_write; - save_attrs.log_write = add_ovly_info; - save_attrs.log_write_handle = nldr_obj; - flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB; - status = nldr_obj->ldr_fxns.load_fxn(nldr_obj->base_lib, flags, - &save_attrs, &ul_entry); - } - if (!status) { - *nldr = (struct nldr_object *)nldr_obj; - } else { - if (nldr_obj) - nldr_delete((struct nldr_object *)nldr_obj); - - *nldr = NULL; - } - /* FIXME:Temp. Fix. Must be removed */ - return status; -} - -/* - * ======== nldr_delete ======== - */ -void nldr_delete(struct nldr_object *nldr_obj) -{ - struct ovly_sect *ovly_section; - struct ovly_sect *next; - u16 i; - - nldr_obj->ldr_fxns.exit_fxn(); - if (nldr_obj->rmm) - rmm_delete(nldr_obj->rmm); - - kfree(nldr_obj->seg_table); - - if (nldr_obj->dcd_mgr) - dcd_destroy_manager(nldr_obj->dcd_mgr); - - /* Free overlay node information */ - if (nldr_obj->ovly_table) { - for (i = 0; i < nldr_obj->ovly_nodes; i++) { - ovly_section = - nldr_obj->ovly_table[i].create_sects_list; - while (ovly_section) { - next = ovly_section->next_sect; - kfree(ovly_section); - ovly_section = next; - } - ovly_section = - nldr_obj->ovly_table[i].delete_sects_list; - while (ovly_section) { - next = ovly_section->next_sect; - kfree(ovly_section); - ovly_section = next; - } - ovly_section = - nldr_obj->ovly_table[i].execute_sects_list; - while (ovly_section) { - next = ovly_section->next_sect; - kfree(ovly_section); - ovly_section = next; - } - ovly_section = nldr_obj->ovly_table[i].other_sects_list; - while (ovly_section) { - next = ovly_section->next_sect; - kfree(ovly_section); - ovly_section = next; - } - } - kfree(nldr_obj->ovly_table); - } - kfree(nldr_obj); -} - -/* - * ======== nldr_get_fxn_addr ======== - */ -int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj, - char *str_fxn, u32 *addr) -{ - struct dbll_sym_val *dbll_sym; - struct nldr_object *nldr_obj; - int status = 0; - bool status1 = false; - s32 i = 0; - struct lib_node root = { NULL, 0, NULL }; - - nldr_obj = nldr_node_obj->nldr_obj; - /* Called from node_create(), node_delete(), or node_run(). */ - if (nldr_node_obj->dynamic && *nldr_node_obj->phase_split) { - switch (nldr_node_obj->phase) { - case NLDR_CREATE: - root = nldr_node_obj->create_lib; - break; - case NLDR_EXECUTE: - root = nldr_node_obj->execute_lib; - break; - case NLDR_DELETE: - root = nldr_node_obj->delete_lib; - break; - default: - break; - } - } else { - /* for Overlay nodes or non-split Dynamic nodes */ - root = nldr_node_obj->root; - } - status1 = - nldr_obj->ldr_fxns.get_c_addr_fxn(root.lib, str_fxn, &dbll_sym); - if (!status1) - status1 = - nldr_obj->ldr_fxns.get_addr_fxn(root.lib, str_fxn, - &dbll_sym); - - /* If symbol not found, check dependent libraries */ - if (!status1) { - for (i = 0; i < root.dep_libs; i++) { - status1 = - nldr_obj->ldr_fxns.get_addr_fxn(root.dep_libs_tree - [i].lib, str_fxn, - &dbll_sym); - if (!status1) { - status1 = - nldr_obj->ldr_fxns. - get_c_addr_fxn(root.dep_libs_tree[i].lib, - str_fxn, &dbll_sym); - } - if (status1) { - /* Symbol found */ - break; - } - } - } - /* Check persistent libraries */ - if (!status1) { - for (i = 0; i < nldr_node_obj->pers_libs; i++) { - status1 = - nldr_obj->ldr_fxns. - get_addr_fxn(nldr_node_obj->pers_lib_table[i].lib, - str_fxn, &dbll_sym); - if (!status1) { - status1 = - nldr_obj->ldr_fxns. - get_c_addr_fxn(nldr_node_obj->pers_lib_table - [i].lib, str_fxn, &dbll_sym); - } - if (status1) { - /* Symbol found */ - break; - } - } - } - - if (status1) - *addr = dbll_sym->value; - else - status = -ESPIPE; - - return status; -} - -/* - * ======== nldr_get_rmm_manager ======== - * Given a NLDR object, retrieve RMM Manager Handle - */ -int nldr_get_rmm_manager(struct nldr_object *nldr, - struct rmm_target_obj **rmm_mgr) -{ - int status = 0; - struct nldr_object *nldr_obj = nldr; - - if (nldr) { - *rmm_mgr = nldr_obj->rmm; - } else { - *rmm_mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== nldr_load ======== - */ -int nldr_load(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase) -{ - struct nldr_object *nldr_obj; - struct dsp_uuid lib_uuid; - int status = 0; - - nldr_obj = nldr_node_obj->nldr_obj; - - if (nldr_node_obj->dynamic) { - nldr_node_obj->phase = phase; - - lib_uuid = nldr_node_obj->uuid; - - /* At this point, we may not know if node is split into - * different libraries. So we'll go ahead and load the - * library, and then save the pointer to the appropriate - * location after we know. */ - - status = - load_lib(nldr_node_obj, &nldr_node_obj->root, lib_uuid, - false, nldr_node_obj->lib_path, phase, 0); - - if (!status) { - if (*nldr_node_obj->phase_split) { - switch (phase) { - case NLDR_CREATE: - nldr_node_obj->create_lib = - nldr_node_obj->root; - break; - - case NLDR_EXECUTE: - nldr_node_obj->execute_lib = - nldr_node_obj->root; - break; - - case NLDR_DELETE: - nldr_node_obj->delete_lib = - nldr_node_obj->root; - break; - - default: - break; - } - } - } - } else { - if (nldr_node_obj->overlay) - status = load_ovly(nldr_node_obj, phase); - - } - - return status; -} - -/* - * ======== nldr_unload ======== - */ -int nldr_unload(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase) -{ - int status = 0; - struct lib_node *root_lib = NULL; - s32 i = 0; - - if (nldr_node_obj != NULL) { - if (nldr_node_obj->dynamic) { - if (*nldr_node_obj->phase_split) { - switch (phase) { - case NLDR_CREATE: - root_lib = &nldr_node_obj->create_lib; - break; - case NLDR_EXECUTE: - root_lib = &nldr_node_obj->execute_lib; - break; - case NLDR_DELETE: - root_lib = &nldr_node_obj->delete_lib; - /* Unload persistent libraries */ - for (i = 0; - i < nldr_node_obj->pers_libs; - i++) { - unload_lib(nldr_node_obj, - &nldr_node_obj-> - pers_lib_table[i]); - } - nldr_node_obj->pers_libs = 0; - break; - default: - break; - } - } else { - /* Unload main library */ - root_lib = &nldr_node_obj->root; - } - if (root_lib) - unload_lib(nldr_node_obj, root_lib); - } else { - if (nldr_node_obj->overlay) - unload_ovly(nldr_node_obj, phase); - - } - } - return status; -} - -/* - * ======== add_ovly_info ======== - */ -static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info, - u32 addr, u32 bytes) -{ - char *node_name; - char *sect_name = (char *)sect_info->name; - bool sect_exists = false; - char seps = ':'; - char *pch; - u16 i; - struct nldr_object *nldr_obj = (struct nldr_object *)handle; - int status = 0; - - /* Is this an overlay section (load address != run address)? */ - if (sect_info->sect_load_addr == sect_info->sect_run_addr) - goto func_end; - - /* Find the node it belongs to */ - for (i = 0; i < nldr_obj->ovly_nodes; i++) { - node_name = nldr_obj->ovly_table[i].node_name; - if (strncmp(node_name, sect_name + 1, strlen(node_name)) == 0) { - /* Found the node */ - break; - } - } - if (!(i < nldr_obj->ovly_nodes)) - goto func_end; - - /* Determine which phase this section belongs to */ - for (pch = sect_name + 1; *pch && *pch != seps; pch++) - ; - - if (*pch) { - pch++; /* Skip over the ':' */ - if (strncmp(pch, PCREATE, strlen(PCREATE)) == 0) { - status = - add_ovly_sect(nldr_obj, - &nldr_obj-> - ovly_table[i].create_sects_list, - sect_info, §_exists, addr, bytes); - if (!status && !sect_exists) - nldr_obj->ovly_table[i].create_sects++; - - } else if (strncmp(pch, PDELETE, strlen(PDELETE)) == 0) { - status = - add_ovly_sect(nldr_obj, - &nldr_obj-> - ovly_table[i].delete_sects_list, - sect_info, §_exists, addr, bytes); - if (!status && !sect_exists) - nldr_obj->ovly_table[i].delete_sects++; - - } else if (strncmp(pch, PEXECUTE, strlen(PEXECUTE)) == 0) { - status = - add_ovly_sect(nldr_obj, - &nldr_obj-> - ovly_table[i].execute_sects_list, - sect_info, §_exists, addr, bytes); - if (!status && !sect_exists) - nldr_obj->ovly_table[i].execute_sects++; - - } else { - /* Put in "other" sections */ - status = - add_ovly_sect(nldr_obj, - &nldr_obj-> - ovly_table[i].other_sects_list, - sect_info, §_exists, addr, bytes); - if (!status && !sect_exists) - nldr_obj->ovly_table[i].other_sects++; - - } - } -func_end: - return status; -} - -/* - * ======== add_ovly_node ========= - * Callback function passed to dcd_get_objects. - */ -static int add_ovly_node(struct dsp_uuid *uuid_obj, - enum dsp_dcdobjtype obj_type, void *handle) -{ - struct nldr_object *nldr_obj = (struct nldr_object *)handle; - char *node_name = NULL; - char *pbuf = NULL; - u32 len; - struct dcd_genericobj obj_def; - int status = 0; - - if (obj_type != DSP_DCDNODETYPE) - goto func_end; - - status = - dcd_get_object_def(nldr_obj->dcd_mgr, uuid_obj, obj_type, - &obj_def); - if (status) - goto func_end; - - /* If overlay node, add to the list */ - if (obj_def.obj_data.node_obj.load_type == NLDR_OVLYLOAD) { - if (nldr_obj->ovly_table == NULL) { - nldr_obj->ovly_nodes++; - } else { - /* Add node to table */ - nldr_obj->ovly_table[nldr_obj->ovly_nid].uuid = - *uuid_obj; - len = - strlen(obj_def.obj_data.node_obj.ndb_props.ac_name); - node_name = obj_def.obj_data.node_obj.ndb_props.ac_name; - pbuf = kzalloc(len + 1, GFP_KERNEL); - if (pbuf == NULL) { - status = -ENOMEM; - } else { - strncpy(pbuf, node_name, len); - nldr_obj->ovly_table[nldr_obj->ovly_nid]. - node_name = pbuf; - nldr_obj->ovly_nid++; - } - } - } - /* These were allocated in dcd_get_object_def */ - kfree(obj_def.obj_data.node_obj.str_create_phase_fxn); - - kfree(obj_def.obj_data.node_obj.str_execute_phase_fxn); - - kfree(obj_def.obj_data.node_obj.str_delete_phase_fxn); - - kfree(obj_def.obj_data.node_obj.str_i_alg_name); - -func_end: - return status; -} - -/* - * ======== add_ovly_sect ======== - */ -static int add_ovly_sect(struct nldr_object *nldr_obj, - struct ovly_sect **lst, - struct dbll_sect_info *sect_inf, - bool *exists, u32 addr, u32 bytes) -{ - struct ovly_sect *new_sect = NULL; - struct ovly_sect *last_sect; - struct ovly_sect *ovly_section; - int status = 0; - - ovly_section = last_sect = *lst; - *exists = false; - while (ovly_section) { - /* - * Make sure section has not already been added. Multiple - * 'write' calls may be made to load the section. - */ - if (ovly_section->sect_load_addr == addr) { - /* Already added */ - *exists = true; - break; - } - last_sect = ovly_section; - ovly_section = ovly_section->next_sect; - } - - if (!ovly_section) { - /* New section */ - new_sect = kzalloc(sizeof(struct ovly_sect), GFP_KERNEL); - if (new_sect == NULL) { - status = -ENOMEM; - } else { - new_sect->sect_load_addr = addr; - new_sect->sect_run_addr = sect_inf->sect_run_addr + - (addr - sect_inf->sect_load_addr); - new_sect->size = bytes; - new_sect->page = sect_inf->type; - } - - /* Add to the list */ - if (!status) { - if (*lst == NULL) { - /* First in the list */ - *lst = new_sect; - } else { - last_sect->next_sect = new_sect; - } - } - } - - return status; -} - -/* - * ======== fake_ovly_write ======== - */ -static s32 fake_ovly_write(void *handle, u32 dsp_address, void *buf, u32 bytes, - s32 mtype) -{ - return (s32) bytes; -} - -/* - * ======== free_sects ======== - */ -static void free_sects(struct nldr_object *nldr_obj, - struct ovly_sect *phase_sects, u16 alloc_num) -{ - struct ovly_sect *ovly_section = phase_sects; - u16 i = 0; - bool ret; - - while (ovly_section && i < alloc_num) { - /* 'Deallocate' */ - /* segid - page not supported yet */ - /* Reserved memory */ - ret = - rmm_free(nldr_obj->rmm, 0, ovly_section->sect_run_addr, - ovly_section->size, true); - ovly_section = ovly_section->next_sect; - i++; - } -} - -/* - * ======== get_symbol_value ======== - * Find symbol in library's base image. If not there, check dependent - * libraries. - */ -static bool get_symbol_value(void *handle, void *parg, void *rmm_handle, - char *sym_name, struct dbll_sym_val **sym) -{ - struct nldr_object *nldr_obj = (struct nldr_object *)handle; - struct nldr_nodeobject *nldr_node_obj = - (struct nldr_nodeobject *)rmm_handle; - struct lib_node *root = (struct lib_node *)parg; - u16 i; - bool status = false; - - /* check the base image */ - status = nldr_obj->ldr_fxns.get_addr_fxn(nldr_obj->base_lib, - sym_name, sym); - if (!status) - status = - nldr_obj->ldr_fxns.get_c_addr_fxn(nldr_obj->base_lib, - sym_name, sym); - - /* - * Check in root lib itself. If the library consists of - * multiple object files linked together, some symbols in the - * library may need to be resolved. - */ - if (!status) { - status = nldr_obj->ldr_fxns.get_addr_fxn(root->lib, sym_name, - sym); - if (!status) { - status = - nldr_obj->ldr_fxns.get_c_addr_fxn(root->lib, - sym_name, sym); - } - } - - /* - * Check in root lib's dependent libraries, but not dependent - * libraries' dependents. - */ - if (!status) { - for (i = 0; i < root->dep_libs; i++) { - status = - nldr_obj->ldr_fxns.get_addr_fxn(root-> - dep_libs_tree - [i].lib, - sym_name, sym); - if (!status) { - status = - nldr_obj->ldr_fxns. - get_c_addr_fxn(root->dep_libs_tree[i].lib, - sym_name, sym); - } - if (status) { - /* Symbol found */ - break; - } - } - } - /* - * Check in persistent libraries - */ - if (!status) { - for (i = 0; i < nldr_node_obj->pers_libs; i++) { - status = - nldr_obj->ldr_fxns. - get_addr_fxn(nldr_node_obj->pers_lib_table[i].lib, - sym_name, sym); - if (!status) { - status = nldr_obj->ldr_fxns.get_c_addr_fxn - (nldr_node_obj->pers_lib_table[i].lib, - sym_name, sym); - } - if (status) { - /* Symbol found */ - break; - } - } - } - - return status; -} - -/* - * ======== load_lib ======== - * Recursively load library and all its dependent libraries. The library - * we're loading is specified by a uuid. - */ -static int load_lib(struct nldr_nodeobject *nldr_node_obj, - struct lib_node *root, struct dsp_uuid uuid, - bool root_prstnt, - struct dbll_library_obj **lib_path, - enum nldr_phase phase, u16 depth) -{ - struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj; - u16 nd_libs = 0; /* Number of dependent libraries */ - u16 np_libs = 0; /* Number of persistent libraries */ - u16 nd_libs_loaded = 0; /* Number of dep. libraries loaded */ - u16 i; - u32 entry; - u32 dw_buf_size = NLDR_MAXPATHLENGTH; - dbll_flags flags = DBLL_SYMB | DBLL_CODE | DBLL_DATA | DBLL_DYNAMIC; - struct dbll_attrs new_attrs; - char *psz_file_name = NULL; - struct dsp_uuid *dep_lib_uui_ds = NULL; - bool *persistent_dep_libs = NULL; - int status = 0; - bool lib_status = false; - struct lib_node *dep_lib; - - if (depth > MAXDEPTH) { - /* Error */ - } - root->lib = NULL; - /* Allocate a buffer for library file name of size DBL_MAXPATHLENGTH */ - psz_file_name = kzalloc(DBLL_MAXPATHLENGTH, GFP_KERNEL); - if (psz_file_name == NULL) - status = -ENOMEM; - - if (!status) { - /* Get the name of the library */ - if (depth == 0) { - status = - dcd_get_library_name(nldr_node_obj->nldr_obj-> - dcd_mgr, &uuid, psz_file_name, - &dw_buf_size, phase, - nldr_node_obj->phase_split); - } else { - /* Dependent libraries are registered with a phase */ - status = - dcd_get_library_name(nldr_node_obj->nldr_obj-> - dcd_mgr, &uuid, psz_file_name, - &dw_buf_size, NLDR_NOPHASE, - NULL); - } - } - if (!status) { - /* Open the library, don't load symbols */ - status = - nldr_obj->ldr_fxns.open_fxn(nldr_obj->dbll, psz_file_name, - DBLL_NOLOAD, &root->lib); - } - /* Done with file name */ - kfree(psz_file_name); - - /* Check to see if library not already loaded */ - if (!status && root_prstnt) { - lib_status = - find_in_persistent_lib_array(nldr_node_obj, root->lib); - /* Close library */ - if (lib_status) { - nldr_obj->ldr_fxns.close_fxn(root->lib); - return 0; - } - } - if (!status) { - /* Check for circular dependencies. */ - for (i = 0; i < depth; i++) { - if (root->lib == lib_path[i]) { - /* This condition could be checked by a - * tool at build time. */ - status = -EILSEQ; - } - } - } - if (!status) { - /* Add library to current path in dependency tree */ - lib_path[depth] = root->lib; - depth++; - /* Get number of dependent libraries */ - status = - dcd_get_num_dep_libs(nldr_node_obj->nldr_obj->dcd_mgr, - &uuid, &nd_libs, &np_libs, phase); - } - if (!status) { - if (!(*nldr_node_obj->phase_split)) - np_libs = 0; - - /* nd_libs = #of dependent libraries */ - root->dep_libs = nd_libs - np_libs; - if (nd_libs > 0) { - dep_lib_uui_ds = kzalloc(sizeof(struct dsp_uuid) * - nd_libs, GFP_KERNEL); - persistent_dep_libs = - kzalloc(sizeof(bool) * nd_libs, GFP_KERNEL); - if (!dep_lib_uui_ds || !persistent_dep_libs) - status = -ENOMEM; - - if (root->dep_libs > 0) { - /* Allocate arrays for dependent lib UUIDs, - * lib nodes */ - root->dep_libs_tree = kzalloc - (sizeof(struct lib_node) * - (root->dep_libs), GFP_KERNEL); - if (!(root->dep_libs_tree)) - status = -ENOMEM; - - } - - if (!status) { - /* Get the dependent library UUIDs */ - status = - dcd_get_dep_libs(nldr_node_obj-> - nldr_obj->dcd_mgr, &uuid, - nd_libs, dep_lib_uui_ds, - persistent_dep_libs, - phase); - } - } - } - - /* - * Recursively load dependent libraries. - */ - if (!status) { - for (i = 0; i < nd_libs; i++) { - /* If root library is NOT persistent, and dep library - * is, then record it. If root library IS persistent, - * the deplib is already included */ - if (!root_prstnt && persistent_dep_libs[i] && - *nldr_node_obj->phase_split) { - if ((nldr_node_obj->pers_libs) >= MAXLIBS) { - status = -EILSEQ; - break; - } - - /* Allocate library outside of phase */ - dep_lib = - &nldr_node_obj->pers_lib_table - [nldr_node_obj->pers_libs]; - } else { - if (root_prstnt) - persistent_dep_libs[i] = true; - - /* Allocate library within phase */ - dep_lib = &root->dep_libs_tree[nd_libs_loaded]; - } - - status = load_lib(nldr_node_obj, dep_lib, - dep_lib_uui_ds[i], - persistent_dep_libs[i], lib_path, - phase, depth); - - if (!status) { - if ((status != 0) && - !root_prstnt && persistent_dep_libs[i] && - *nldr_node_obj->phase_split) { - (nldr_node_obj->pers_libs)++; - } else { - if (!persistent_dep_libs[i] || - !(*nldr_node_obj->phase_split)) { - nd_libs_loaded++; - } - } - } else { - break; - } - } - } - - /* Now we can load the root library */ - if (!status) { - new_attrs = nldr_obj->ldr_attrs; - new_attrs.sym_arg = root; - new_attrs.rmm_handle = nldr_node_obj; - new_attrs.input_params = nldr_node_obj->priv_ref; - new_attrs.base_image = false; - - status = - nldr_obj->ldr_fxns.load_fxn(root->lib, flags, &new_attrs, - &entry); - } - - /* - * In case of failure, unload any dependent libraries that - * were loaded, and close the root library. - * (Persistent libraries are unloaded from the very top) - */ - if (status) { - if (phase != NLDR_EXECUTE) { - for (i = 0; i < nldr_node_obj->pers_libs; i++) - unload_lib(nldr_node_obj, - &nldr_node_obj->pers_lib_table[i]); - - nldr_node_obj->pers_libs = 0; - } - for (i = 0; i < nd_libs_loaded; i++) - unload_lib(nldr_node_obj, &root->dep_libs_tree[i]); - - if (root->lib) - nldr_obj->ldr_fxns.close_fxn(root->lib); - - } - - /* Going up one node in the dependency tree */ - depth--; - - kfree(dep_lib_uui_ds); - dep_lib_uui_ds = NULL; - - kfree(persistent_dep_libs); - persistent_dep_libs = NULL; - - return status; -} - -/* - * ======== load_ovly ======== - */ -static int load_ovly(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase) -{ - struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj; - struct ovly_node *po_node = NULL; - struct ovly_sect *phase_sects = NULL; - struct ovly_sect *other_sects_list = NULL; - u16 i; - u16 alloc_num = 0; - u16 other_alloc = 0; - u16 *ref_count = NULL; - u16 *other_ref = NULL; - u32 bytes; - struct ovly_sect *ovly_section; - int status = 0; - - /* Find the node in the table */ - for (i = 0; i < nldr_obj->ovly_nodes; i++) { - if (is_equal_uuid - (&nldr_node_obj->uuid, &nldr_obj->ovly_table[i].uuid)) { - /* Found it */ - po_node = &(nldr_obj->ovly_table[i]); - break; - } - } - - - if (!po_node) { - status = -ENOENT; - goto func_end; - } - - switch (phase) { - case NLDR_CREATE: - ref_count = &(po_node->create_ref); - other_ref = &(po_node->other_ref); - phase_sects = po_node->create_sects_list; - other_sects_list = po_node->other_sects_list; - break; - - case NLDR_EXECUTE: - ref_count = &(po_node->execute_ref); - phase_sects = po_node->execute_sects_list; - break; - - case NLDR_DELETE: - ref_count = &(po_node->delete_ref); - phase_sects = po_node->delete_sects_list; - break; - - default: - break; - } - - if (ref_count == NULL) - goto func_end; - - if (*ref_count != 0) - goto func_end; - - /* 'Allocate' memory for overlay sections of this phase */ - ovly_section = phase_sects; - while (ovly_section) { - /* allocate *//* page not supported yet */ - /* reserve *//* align */ - status = rmm_alloc(nldr_obj->rmm, 0, ovly_section->size, 0, - &(ovly_section->sect_run_addr), true); - if (!status) { - ovly_section = ovly_section->next_sect; - alloc_num++; - } else { - break; - } - } - if (other_ref && *other_ref == 0) { - /* 'Allocate' memory for other overlay sections - * (create phase) */ - if (!status) { - ovly_section = other_sects_list; - while (ovly_section) { - /* page not supported *//* align */ - /* reserve */ - status = - rmm_alloc(nldr_obj->rmm, 0, - ovly_section->size, 0, - &(ovly_section->sect_run_addr), - true); - if (!status) { - ovly_section = ovly_section->next_sect; - other_alloc++; - } else { - break; - } - } - } - } - if (*ref_count == 0) { - if (!status) { - /* Load sections for this phase */ - ovly_section = phase_sects; - while (ovly_section && !status) { - bytes = - (*nldr_obj->ovly_fxn) (nldr_node_obj-> - priv_ref, - ovly_section-> - sect_run_addr, - ovly_section-> - sect_load_addr, - ovly_section->size, - ovly_section->page); - if (bytes != ovly_section->size) - status = -EPERM; - - ovly_section = ovly_section->next_sect; - } - } - } - if (other_ref && *other_ref == 0) { - if (!status) { - /* Load other sections (create phase) */ - ovly_section = other_sects_list; - while (ovly_section && !status) { - bytes = - (*nldr_obj->ovly_fxn) (nldr_node_obj-> - priv_ref, - ovly_section-> - sect_run_addr, - ovly_section-> - sect_load_addr, - ovly_section->size, - ovly_section->page); - if (bytes != ovly_section->size) - status = -EPERM; - - ovly_section = ovly_section->next_sect; - } - } - } - if (status) { - /* 'Deallocate' memory */ - free_sects(nldr_obj, phase_sects, alloc_num); - free_sects(nldr_obj, other_sects_list, other_alloc); - } -func_end: - if (!status && (ref_count != NULL)) { - *ref_count += 1; - if (other_ref) - *other_ref += 1; - - } - - return status; -} - -/* - * ======== remote_alloc ======== - */ -static int remote_alloc(void **ref, u16 mem_sect, u32 size, - u32 align, u32 *dsp_address, - s32 segmnt_id, s32 req, - bool reserve) -{ - struct nldr_nodeobject *hnode = (struct nldr_nodeobject *)ref; - struct nldr_object *nldr_obj; - struct rmm_target_obj *rmm; - u16 mem_phase_bit = MAXFLAGS; - u16 segid = 0; - u16 i; - u16 mem_sect_type; - u32 word_size; - struct rmm_addr *rmm_addr_obj = (struct rmm_addr *)dsp_address; - bool mem_load_req = false; - int status = -ENOMEM; /* Set to fail */ - nldr_obj = hnode->nldr_obj; - rmm = nldr_obj->rmm; - /* Convert size to DSP words */ - word_size = - (size + nldr_obj->dsp_word_size - - 1) / nldr_obj->dsp_word_size; - /* Modify memory 'align' to account for DSP cache line size */ - align = lcm(GEM_CACHE_LINE_SIZE, align); - dev_dbg(bridge, "%s: memory align to 0x%x\n", __func__, align); - if (segmnt_id != -1) { - rmm_addr_obj->segid = segmnt_id; - segid = segmnt_id; - mem_load_req = req; - } else { - switch (hnode->phase) { - case NLDR_CREATE: - mem_phase_bit = CREATEDATAFLAGBIT; - break; - case NLDR_DELETE: - mem_phase_bit = DELETEDATAFLAGBIT; - break; - case NLDR_EXECUTE: - mem_phase_bit = EXECUTEDATAFLAGBIT; - break; - default: - break; - } - if (mem_sect == DBLL_CODE) - mem_phase_bit++; - - if (mem_phase_bit < MAXFLAGS) - segid = hnode->seg_id[mem_phase_bit]; - - /* Determine if there is a memory loading requirement */ - if ((hnode->code_data_flag_mask >> mem_phase_bit) & 0x1) - mem_load_req = true; - - } - mem_sect_type = (mem_sect == DBLL_CODE) ? DYNM_CODE : DYNM_DATA; - - /* Find an appropriate segment based on mem_sect */ - if (segid == NULLID) { - /* No memory requirements of preferences */ - goto func_cont; - } - if (segid <= MAXSEGID) { - /* Attempt to allocate from segid first. */ - rmm_addr_obj->segid = segid; - status = - rmm_alloc(rmm, segid, word_size, align, dsp_address, false); - if (status) { - dev_dbg(bridge, "%s: Unable allocate from segment %d\n", - __func__, segid); - } - } else { - /* segid > MAXSEGID ==> Internal or external memory */ - /* Check for any internal or external memory segment, - * depending on segid. */ - mem_sect_type |= segid == MEMINTERNALID ? - DYNM_INTERNAL : DYNM_EXTERNAL; - for (i = 0; i < nldr_obj->dload_segs; i++) { - if ((nldr_obj->seg_table[i] & mem_sect_type) != - mem_sect_type) - continue; - - status = rmm_alloc(rmm, i, word_size, align, - dsp_address, false); - if (!status) { - /* Save segid for freeing later */ - rmm_addr_obj->segid = i; - break; - } - } - } -func_cont: - /* Haven't found memory yet, attempt to find any segment that works */ - if (status == -ENOMEM && !mem_load_req) { - dev_dbg(bridge, "%s: Preferred segment unavailable, trying " - "another\n", __func__); - for (i = 0; i < nldr_obj->dload_segs; i++) { - /* All bits of mem_sect_type must be set */ - if ((nldr_obj->seg_table[i] & mem_sect_type) != - mem_sect_type) - continue; - - status = rmm_alloc(rmm, i, word_size, align, - dsp_address, false); - if (!status) { - /* Save segid */ - rmm_addr_obj->segid = i; - break; - } - } - } - - return status; -} - -static int remote_free(void **ref, u16 space, u32 dsp_address, - u32 size, bool reserve) -{ - struct nldr_object *nldr_obj = (struct nldr_object *)ref; - struct rmm_target_obj *rmm; - u32 word_size; - int status = -ENOMEM; /* Set to fail */ - - rmm = nldr_obj->rmm; - - /* Convert size to DSP words */ - word_size = - (size + nldr_obj->dsp_word_size - - 1) / nldr_obj->dsp_word_size; - - if (rmm_free(rmm, space, dsp_address, word_size, reserve)) - status = 0; - - return status; -} - -/* - * ======== unload_lib ======== - */ -static void unload_lib(struct nldr_nodeobject *nldr_node_obj, - struct lib_node *root) -{ - struct dbll_attrs new_attrs; - struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj; - u16 i; - - - /* Unload dependent libraries */ - for (i = 0; i < root->dep_libs; i++) - unload_lib(nldr_node_obj, &root->dep_libs_tree[i]); - - root->dep_libs = 0; - - new_attrs = nldr_obj->ldr_attrs; - new_attrs.rmm_handle = nldr_obj->rmm; - new_attrs.input_params = nldr_node_obj->priv_ref; - new_attrs.base_image = false; - new_attrs.sym_arg = root; - - if (root->lib) { - /* Unload the root library */ - nldr_obj->ldr_fxns.unload_fxn(root->lib, &new_attrs); - nldr_obj->ldr_fxns.close_fxn(root->lib); - } - - /* Free dependent library list */ - kfree(root->dep_libs_tree); - root->dep_libs_tree = NULL; -} - -/* - * ======== unload_ovly ======== - */ -static void unload_ovly(struct nldr_nodeobject *nldr_node_obj, - enum nldr_phase phase) -{ - struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj; - struct ovly_node *po_node = NULL; - struct ovly_sect *phase_sects = NULL; - struct ovly_sect *other_sects_list = NULL; - u16 i; - u16 alloc_num = 0; - u16 other_alloc = 0; - u16 *ref_count = NULL; - u16 *other_ref = NULL; - - /* Find the node in the table */ - for (i = 0; i < nldr_obj->ovly_nodes; i++) { - if (is_equal_uuid - (&nldr_node_obj->uuid, &nldr_obj->ovly_table[i].uuid)) { - /* Found it */ - po_node = &(nldr_obj->ovly_table[i]); - break; - } - } - - - if (!po_node) - /* TODO: Should we print warning here? */ - return; - - switch (phase) { - case NLDR_CREATE: - ref_count = &(po_node->create_ref); - phase_sects = po_node->create_sects_list; - alloc_num = po_node->create_sects; - break; - case NLDR_EXECUTE: - ref_count = &(po_node->execute_ref); - phase_sects = po_node->execute_sects_list; - alloc_num = po_node->execute_sects; - break; - case NLDR_DELETE: - ref_count = &(po_node->delete_ref); - other_ref = &(po_node->other_ref); - phase_sects = po_node->delete_sects_list; - /* 'Other' overlay sections are unloaded in the delete phase */ - other_sects_list = po_node->other_sects_list; - alloc_num = po_node->delete_sects; - other_alloc = po_node->other_sects; - break; - default: - break; - } - if (ref_count && (*ref_count > 0)) { - *ref_count -= 1; - if (other_ref) - *other_ref -= 1; - } - - if (ref_count && *ref_count == 0) { - /* 'Deallocate' memory */ - free_sects(nldr_obj, phase_sects, alloc_num); - } - if (other_ref && *other_ref == 0) - free_sects(nldr_obj, other_sects_list, other_alloc); -} - -/* - * ======== find_in_persistent_lib_array ======== - */ -static bool find_in_persistent_lib_array(struct nldr_nodeobject *nldr_node_obj, - struct dbll_library_obj *lib) -{ - s32 i = 0; - - for (i = 0; i < nldr_node_obj->pers_libs; i++) { - if (lib == nldr_node_obj->pers_lib_table[i].lib) - return true; - - } - - return false; -} - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/** - * nldr_find_addr() - Find the closest symbol to the given address based on - * dynamic node object. - * - * @nldr_node: Dynamic node object - * @sym_addr: Given address to find the dsp symbol - * @offset_range: offset range to look for dsp symbol - * @offset_output: Symbol Output address - * @sym_name: String with the dsp symbol - * - * This function finds the node library for a given address and - * retrieves the dsp symbol by calling dbll_find_dsp_symbol. - */ -int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr, - u32 offset_range, void *offset_output, char *sym_name) -{ - int status = 0; - bool status1 = false; - s32 i = 0; - struct lib_node root = { NULL, 0, NULL }; - - if (nldr_node->dynamic && *nldr_node->phase_split) { - switch (nldr_node->phase) { - case NLDR_CREATE: - root = nldr_node->create_lib; - break; - case NLDR_EXECUTE: - root = nldr_node->execute_lib; - break; - case NLDR_DELETE: - root = nldr_node->delete_lib; - break; - default: - break; - } - } else { - /* for Overlay nodes or non-split Dynamic nodes */ - root = nldr_node->root; - } - - status1 = dbll_find_dsp_symbol(root.lib, sym_addr, - offset_range, offset_output, sym_name); - - /* If symbol not found, check dependent libraries */ - if (!status1) - for (i = 0; i < root.dep_libs; i++) { - status1 = dbll_find_dsp_symbol( - root.dep_libs_tree[i].lib, sym_addr, - offset_range, offset_output, sym_name); - if (status1) - /* Symbol found */ - break; - } - /* Check persistent libraries */ - if (!status1) - for (i = 0; i < nldr_node->pers_libs; i++) { - status1 = dbll_find_dsp_symbol( - nldr_node->pers_lib_table[i].lib, sym_addr, - offset_range, offset_output, sym_name); - if (status1) - /* Symbol found */ - break; - } - - if (!status1) { - pr_debug("%s: Address 0x%x not found in range %d.\n", - __func__, sym_addr, offset_range); - status = -ESPIPE; - } else { - pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x, %s)\n", - __func__, (u32) nldr_node, sym_addr, offset_range, - (u32) offset_output, sym_name); - } - - return status; -} -#endif diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c deleted file mode 100644 index 9d3044a384e..00000000000 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ /dev/null @@ -1,3029 +0,0 @@ -/* - * node.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge Node Manager. - * - * 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. - */ - -#include <linux/types.h> -#include <linux/bitmap.h> -#include <linux/list.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/memdefs.h> -#include <dspbridge/proc.h> -#include <dspbridge/strm.h> -#include <dspbridge/sync.h> -#include <dspbridge/ntfy.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/cmm.h> -#include <dspbridge/cod.h> -#include <dspbridge/dev.h> -#include <dspbridge/msg.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/dbdcd.h> -#include <dspbridge/disp.h> -#include <dspbridge/rms_sh.h> - -/* ----------------------------------- Link Driver */ -#include <dspbridge/dspdefs.h> -#include <dspbridge/dspioctl.h> - -/* ----------------------------------- Others */ -#include <dspbridge/uuidutil.h> - -/* ----------------------------------- This */ -#include <dspbridge/nodepriv.h> -#include <dspbridge/node.h> -#include <dspbridge/dmm.h> - -/* Static/Dynamic Loader includes */ -#include <dspbridge/dbll.h> -#include <dspbridge/nldr.h> - -#include <dspbridge/drv.h> -#include <dspbridge/resourcecleanup.h> -#include <_tiomap.h> - -#include <dspbridge/dspdeh.h> - -#define HOSTPREFIX "/host" -#define PIPEPREFIX "/dbpipe" - -#define MAX_INPUTS(h) \ - ((h)->dcd_props.obj_data.node_obj.ndb_props.num_input_streams) -#define MAX_OUTPUTS(h) \ - ((h)->dcd_props.obj_data.node_obj.ndb_props.num_output_streams) - -#define NODE_GET_PRIORITY(h) ((h)->prio) -#define NODE_SET_PRIORITY(hnode, prio) ((hnode)->prio = prio) -#define NODE_SET_STATE(hnode, state) ((hnode)->node_state = state) - -#define MAXPIPES 100 /* Max # of /pipe connections (CSL limit) */ -#define MAXDEVSUFFIXLEN 2 /* Max(Log base 10 of MAXPIPES, MAXSTREAMS) */ - -#define PIPENAMELEN (sizeof(PIPEPREFIX) + MAXDEVSUFFIXLEN) -#define HOSTNAMELEN (sizeof(HOSTPREFIX) + MAXDEVSUFFIXLEN) - -#define MAXDEVNAMELEN 32 /* dsp_ndbprops.ac_name size */ -#define CREATEPHASE 1 -#define EXECUTEPHASE 2 -#define DELETEPHASE 3 - -/* Define default STRM parameters */ -/* - * TBD: Put in header file, make global DSP_STRMATTRS with defaults, - * or make defaults configurable. - */ -#define DEFAULTBUFSIZE 32 -#define DEFAULTNBUFS 2 -#define DEFAULTSEGID 0 -#define DEFAULTALIGNMENT 0 -#define DEFAULTTIMEOUT 10000 - -#define RMSQUERYSERVER 0 -#define RMSCONFIGURESERVER 1 -#define RMSCREATENODE 2 -#define RMSEXECUTENODE 3 -#define RMSDELETENODE 4 -#define RMSCHANGENODEPRIORITY 5 -#define RMSREADMEMORY 6 -#define RMSWRITEMEMORY 7 -#define RMSCOPY 8 -#define MAXTIMEOUT 2000 - -#define NUMRMSFXNS 9 - -#define PWR_TIMEOUT 500 /* default PWR timeout in msec */ - -#define STACKSEGLABEL "L1DSRAM_HEAP" /* Label for DSP Stack Segment Addr */ - -/* - * ======== node_mgr ======== - */ -struct node_mgr { - struct dev_object *dev_obj; /* Device object */ - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; - struct dcd_manager *dcd_mgr; /* Proc/Node data manager */ - struct disp_object *disp_obj; /* Node dispatcher */ - struct list_head node_list; /* List of all allocated nodes */ - u32 num_nodes; /* Number of nodes in node_list */ - u32 num_created; /* Number of nodes *created* on DSP */ - DECLARE_BITMAP(pipe_map, MAXPIPES); /* Pipe connection bitmap */ - DECLARE_BITMAP(pipe_done_map, MAXPIPES); /* Pipes that are half free */ - /* Channel allocation bitmap */ - DECLARE_BITMAP(chnl_map, CHNL_MAXCHANNELS); - /* DMA Channel allocation bitmap */ - DECLARE_BITMAP(dma_chnl_map, CHNL_MAXCHANNELS); - /* Zero-Copy Channel alloc bitmap */ - DECLARE_BITMAP(zc_chnl_map, CHNL_MAXCHANNELS); - struct ntfy_object *ntfy_obj; /* Manages registered notifications */ - struct mutex node_mgr_lock; /* For critical sections */ - u32 fxn_addrs[NUMRMSFXNS]; /* RMS function addresses */ - struct msg_mgr *msg_mgr_obj; - - /* Processor properties needed by Node Dispatcher */ - u32 num_chnls; /* Total number of channels */ - u32 chnl_offset; /* Offset of chnl ids rsvd for RMS */ - u32 chnl_buf_size; /* Buffer size for data to RMS */ - int proc_family; /* eg, 5000 */ - int proc_type; /* eg, 5510 */ - u32 dsp_word_size; /* Size of DSP word on host bytes */ - u32 dsp_data_mau_size; /* Size of DSP data MAU */ - u32 dsp_mau_size; /* Size of MAU */ - s32 min_pri; /* Minimum runtime priority for node */ - s32 max_pri; /* Maximum runtime priority for node */ - - struct strm_mgr *strm_mgr_obj; /* STRM manager */ - - /* Loader properties */ - struct nldr_object *nldr_obj; /* Handle to loader */ - struct node_ldr_fxns nldr_fxns; /* Handle to loader functions */ -}; - -/* - * ======== connecttype ======== - */ -enum connecttype { - NOTCONNECTED = 0, - NODECONNECT, - HOSTCONNECT, - DEVICECONNECT, -}; - -/* - * ======== stream_chnl ======== - */ -struct stream_chnl { - enum connecttype type; /* Type of stream connection */ - u32 dev_id; /* pipe or channel id */ -}; - -/* - * ======== node_object ======== - */ -struct node_object { - struct list_head list_elem; - struct node_mgr *node_mgr; /* The manager of this node */ - struct proc_object *processor; /* Back pointer to processor */ - struct dsp_uuid node_uuid; /* Node's ID */ - s32 prio; /* Node's current priority */ - u32 timeout; /* Timeout for blocking NODE calls */ - u32 heap_size; /* Heap Size */ - u32 dsp_heap_virt_addr; /* Heap Size */ - u32 gpp_heap_virt_addr; /* Heap Size */ - enum node_type ntype; /* Type of node: message, task, etc */ - enum node_state node_state; /* NODE_ALLOCATED, NODE_CREATED, ... */ - u32 num_inputs; /* Current number of inputs */ - u32 num_outputs; /* Current number of outputs */ - u32 max_input_index; /* Current max input stream index */ - u32 max_output_index; /* Current max output stream index */ - struct stream_chnl *inputs; /* Node's input streams */ - struct stream_chnl *outputs; /* Node's output streams */ - struct node_createargs create_args; /* Args for node create func */ - nodeenv node_env; /* Environment returned by RMS */ - struct dcd_genericobj dcd_props; /* Node properties from DCD */ - struct dsp_cbdata *args; /* Optional args to pass to node */ - struct ntfy_object *ntfy_obj; /* Manages registered notifications */ - char *str_dev_name; /* device name, if device node */ - struct sync_object *sync_done; /* Synchronize node_terminate */ - s32 exit_status; /* execute function return status */ - - /* Information needed for node_get_attr() */ - void *device_owner; /* If dev node, task that owns it */ - u32 num_gpp_inputs; /* Current # of from GPP streams */ - u32 num_gpp_outputs; /* Current # of to GPP streams */ - /* Current stream connections */ - struct dsp_streamconnect *stream_connect; - - /* Message queue */ - struct msg_queue *msg_queue_obj; - - /* These fields used for SM messaging */ - struct cmm_xlatorobject *xlator; /* Node's SM addr translator */ - - /* Handle to pass to dynamic loader */ - struct nldr_nodeobject *nldr_node_obj; - bool loaded; /* Code is (dynamically) loaded */ - bool phase_split; /* Phases split in many libs or ovly */ - -}; - -/* Default buffer attributes */ -static struct dsp_bufferattr node_dfltbufattrs = { - .cb_struct = 0, - .segment_id = 1, - .buf_alignment = 0, -}; - -static void delete_node(struct node_object *hnode, - struct process_context *pr_ctxt); -static void delete_node_mgr(struct node_mgr *hnode_mgr); -static void fill_stream_connect(struct node_object *node1, - struct node_object *node2, u32 stream1, - u32 stream2); -static void fill_stream_def(struct node_object *hnode, - struct node_strmdef *pstrm_def, - struct dsp_strmattr *pattrs); -static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream); -static int get_fxn_address(struct node_object *hnode, u32 *fxn_addr, - u32 phase); -static int get_node_props(struct dcd_manager *hdcd_mgr, - struct node_object *hnode, - const struct dsp_uuid *node_uuid, - struct dcd_genericobj *dcd_prop); -static int get_proc_props(struct node_mgr *hnode_mgr, - struct dev_object *hdev_obj); -static int get_rms_fxns(struct node_mgr *hnode_mgr); -static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr, - u32 ul_num_bytes, u32 mem_space); -static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf, - u32 ul_num_bytes, u32 mem_space); - -/* Dynamic loader functions. */ -static struct node_ldr_fxns nldr_fxns = { - nldr_allocate, - nldr_create, - nldr_delete, - nldr_get_fxn_addr, - nldr_load, - nldr_unload, -}; - -enum node_state node_get_state(void *hnode) -{ - struct node_object *pnode = (struct node_object *)hnode; - if (!pnode) - return -1; - return pnode->node_state; -} - -/* - * ======== node_allocate ======== - * Purpose: - * Allocate GPP resources to manage a node on the DSP. - */ -int node_allocate(struct proc_object *hprocessor, - const struct dsp_uuid *node_uuid, - const struct dsp_cbdata *pargs, - const struct dsp_nodeattrin *attr_in, - struct node_res_object **noderes, - struct process_context *pr_ctxt) -{ - struct node_mgr *hnode_mgr; - struct dev_object *hdev_obj; - struct node_object *pnode = NULL; - enum node_type node_type = NODE_TASK; - struct node_msgargs *pmsg_args; - struct node_taskargs *ptask_args; - u32 num_streams; - struct bridge_drv_interface *intf_fxns; - int status = 0; - struct cmm_object *hcmm_mgr = NULL; /* Shared memory manager hndl */ - u32 proc_id; - u32 pul_value; - u32 dynext_base; - u32 off_set = 0; - u32 ul_stack_seg_val; - struct cfg_hostres *host_res; - struct bridge_dev_context *pbridge_context; - u32 mapped_addr = 0; - u32 map_attrs = 0x0; - struct dsp_processorstate proc_state; -#ifdef DSP_DMM_DEBUG - struct dmm_object *dmm_mgr; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; -#endif - - void *node_res; - - *noderes = NULL; - - status = proc_get_processor_id(hprocessor, &proc_id); - - if (proc_id != DSP_UNIT) - goto func_end; - - status = proc_get_dev_object(hprocessor, &hdev_obj); - if (!status) { - status = dev_get_node_manager(hdev_obj, &hnode_mgr); - if (hnode_mgr == NULL) - status = -EPERM; - - } - - if (status) - goto func_end; - - status = dev_get_bridge_context(hdev_obj, &pbridge_context); - if (!pbridge_context) { - status = -EFAULT; - goto func_end; - } - - status = proc_get_state(hprocessor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_end; - /* If processor is in error state then don't attempt - to send the message */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_end; - } - - /* Assuming that 0 is not a valid function address */ - if (hnode_mgr->fxn_addrs[0] == 0) { - /* No RMS on target - we currently can't handle this */ - pr_err("%s: Failed, no RMS in base image\n", __func__); - status = -EPERM; - } else { - /* Validate attr_in fields, if non-NULL */ - if (attr_in) { - /* Check if attr_in->prio is within range */ - if (attr_in->prio < hnode_mgr->min_pri || - attr_in->prio > hnode_mgr->max_pri) - status = -EDOM; - } - } - /* Allocate node object and fill in */ - if (status) - goto func_end; - - pnode = kzalloc(sizeof(struct node_object), GFP_KERNEL); - if (pnode == NULL) { - status = -ENOMEM; - goto func_end; - } - pnode->node_mgr = hnode_mgr; - /* This critical section protects get_node_props */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - /* Get dsp_ndbprops from node database */ - status = get_node_props(hnode_mgr->dcd_mgr, pnode, node_uuid, - &(pnode->dcd_props)); - if (status) - goto func_cont; - - pnode->node_uuid = *node_uuid; - pnode->processor = hprocessor; - pnode->ntype = pnode->dcd_props.obj_data.node_obj.ndb_props.ntype; - pnode->timeout = pnode->dcd_props.obj_data.node_obj.ndb_props.timeout; - pnode->prio = pnode->dcd_props.obj_data.node_obj.ndb_props.prio; - - /* Currently only C64 DSP builds support Node Dynamic * heaps */ - /* Allocate memory for node heap */ - pnode->create_args.asa.task_arg_obj.heap_size = 0; - pnode->create_args.asa.task_arg_obj.dsp_heap_addr = 0; - pnode->create_args.asa.task_arg_obj.dsp_heap_res_addr = 0; - pnode->create_args.asa.task_arg_obj.gpp_heap_addr = 0; - if (!attr_in) - goto func_cont; - - /* Check if we have a user allocated node heap */ - if (!(attr_in->pgpp_virt_addr)) - goto func_cont; - - /* check for page aligned Heap size */ - if (((attr_in->heap_size) & (PG_SIZE4K - 1))) { - pr_err("%s: node heap size not aligned to 4K, size = 0x%x\n", - __func__, attr_in->heap_size); - status = -EINVAL; - } else { - pnode->create_args.asa.task_arg_obj.heap_size = - attr_in->heap_size; - pnode->create_args.asa.task_arg_obj.gpp_heap_addr = - (u32) attr_in->pgpp_virt_addr; - } - if (status) - goto func_cont; - - status = proc_reserve_memory(hprocessor, - pnode->create_args.asa.task_arg_obj. - heap_size + PAGE_SIZE, - (void **)&(pnode->create_args.asa. - task_arg_obj.dsp_heap_res_addr), - pr_ctxt); - if (status) { - pr_err("%s: Failed to reserve memory for heap: 0x%x\n", - __func__, status); - goto func_cont; - } -#ifdef DSP_DMM_DEBUG - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = DSP_EHANDLE; - goto func_cont; - } - - dmm_mem_map_dump(dmm_mgr); -#endif - - map_attrs |= DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPVIRTUALADDR; - status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr, - pnode->create_args.asa.task_arg_obj.heap_size, - (void *)pnode->create_args.asa.task_arg_obj. - dsp_heap_res_addr, (void **)&mapped_addr, map_attrs, - pr_ctxt); - if (status) - pr_err("%s: Failed to map memory for Heap: 0x%x\n", - __func__, status); - else - pnode->create_args.asa.task_arg_obj.dsp_heap_addr = - (u32) mapped_addr; - -func_cont: - mutex_unlock(&hnode_mgr->node_mgr_lock); - if (attr_in != NULL) { - /* Overrides of NBD properties */ - pnode->timeout = attr_in->timeout; - pnode->prio = attr_in->prio; - } - /* Create object to manage notifications */ - if (!status) { - pnode->ntfy_obj = kmalloc(sizeof(struct ntfy_object), - GFP_KERNEL); - if (pnode->ntfy_obj) - ntfy_init(pnode->ntfy_obj); - else - status = -ENOMEM; - } - - if (!status) { - node_type = node_get_type(pnode); - /* Allocate dsp_streamconnect array for device, task, and - * dais socket nodes. */ - if (node_type != NODE_MESSAGE) { - num_streams = MAX_INPUTS(pnode) + MAX_OUTPUTS(pnode); - pnode->stream_connect = kzalloc(num_streams * - sizeof(struct dsp_streamconnect), - GFP_KERNEL); - if (num_streams > 0 && pnode->stream_connect == NULL) - status = -ENOMEM; - - } - if (!status && (node_type == NODE_TASK || - node_type == NODE_DAISSOCKET)) { - /* Allocate arrays for maintainig stream connections */ - pnode->inputs = kzalloc(MAX_INPUTS(pnode) * - sizeof(struct stream_chnl), GFP_KERNEL); - pnode->outputs = kzalloc(MAX_OUTPUTS(pnode) * - sizeof(struct stream_chnl), GFP_KERNEL); - ptask_args = &(pnode->create_args.asa.task_arg_obj); - ptask_args->strm_in_def = kzalloc(MAX_INPUTS(pnode) * - sizeof(struct node_strmdef), - GFP_KERNEL); - ptask_args->strm_out_def = kzalloc(MAX_OUTPUTS(pnode) * - sizeof(struct node_strmdef), - GFP_KERNEL); - if ((MAX_INPUTS(pnode) > 0 && (pnode->inputs == NULL || - ptask_args->strm_in_def - == NULL)) - || (MAX_OUTPUTS(pnode) > 0 - && (pnode->outputs == NULL - || ptask_args->strm_out_def == NULL))) - status = -ENOMEM; - } - } - if (!status && (node_type != NODE_DEVICE)) { - /* Create an event that will be posted when RMS_EXIT is - * received. */ - pnode->sync_done = kzalloc(sizeof(struct sync_object), - GFP_KERNEL); - if (pnode->sync_done) - sync_init_event(pnode->sync_done); - else - status = -ENOMEM; - - if (!status) { - /*Get the shared mem mgr for this nodes dev object */ - status = cmm_get_handle(hprocessor, &hcmm_mgr); - if (!status) { - /* Allocate a SM addr translator for this node - * w/ deflt attr */ - status = cmm_xlator_create(&pnode->xlator, - hcmm_mgr, NULL); - } - } - if (!status) { - /* Fill in message args */ - if ((pargs != NULL) && (pargs->cb_data > 0)) { - pmsg_args = - &(pnode->create_args.asa.node_msg_args); - pmsg_args->pdata = kzalloc(pargs->cb_data, - GFP_KERNEL); - if (pmsg_args->pdata == NULL) { - status = -ENOMEM; - } else { - pmsg_args->arg_length = pargs->cb_data; - memcpy(pmsg_args->pdata, - pargs->node_data, - pargs->cb_data); - } - } - } - } - - if (!status && node_type != NODE_DEVICE) { - /* Create a message queue for this node */ - intf_fxns = hnode_mgr->intf_fxns; - status = - (*intf_fxns->msg_create_queue) (hnode_mgr->msg_mgr_obj, - &pnode->msg_queue_obj, - 0, - pnode->create_args.asa. - node_msg_args.max_msgs, - pnode); - } - - if (!status) { - /* Create object for dynamic loading */ - - status = hnode_mgr->nldr_fxns.allocate(hnode_mgr->nldr_obj, - (void *)pnode, - &pnode->dcd_props. - obj_data.node_obj, - &pnode-> - nldr_node_obj, - &pnode->phase_split); - } - - /* Compare value read from Node Properties and check if it is same as - * STACKSEGLABEL, if yes read the Address of STACKSEGLABEL, calculate - * GPP Address, Read the value in that address and override the - * stack_seg value in task args */ - if (!status && - (char *)pnode->dcd_props.obj_data.node_obj.ndb_props. - stack_seg_name != NULL) { - if (strcmp((char *) - pnode->dcd_props.obj_data.node_obj.ndb_props. - stack_seg_name, STACKSEGLABEL) == 0) { - void __iomem *stack_seg; - u32 stack_seg_pa; - - status = - hnode_mgr->nldr_fxns. - get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG", - &dynext_base); - if (status) - pr_err("%s: Failed to get addr for DYNEXT_BEG" - " status = 0x%x\n", __func__, status); - - status = - hnode_mgr->nldr_fxns. - get_fxn_addr(pnode->nldr_node_obj, - "L1DSRAM_HEAP", &pul_value); - - if (status) - pr_err("%s: Failed to get addr for L1DSRAM_HEAP" - " status = 0x%x\n", __func__, status); - - host_res = pbridge_context->resources; - if (!host_res) - status = -EPERM; - - if (status) { - pr_err("%s: Failed to get host resource, status" - " = 0x%x\n", __func__, status); - goto func_end; - } - - off_set = pul_value - dynext_base; - stack_seg_pa = host_res->mem_phys[1] + off_set; - stack_seg = ioremap(stack_seg_pa, SZ_32); - if (!stack_seg) { - status = -ENOMEM; - goto func_end; - } - - ul_stack_seg_val = readl(stack_seg); - - iounmap(stack_seg); - - dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr =" - " 0x%x\n", __func__, ul_stack_seg_val, - host_res->mem_base[1] + off_set); - - pnode->create_args.asa.task_arg_obj.stack_seg = - ul_stack_seg_val; - - } - } - - if (!status) { - /* Add the node to the node manager's list of allocated - * nodes. */ - NODE_SET_STATE(pnode, NODE_ALLOCATED); - - mutex_lock(&hnode_mgr->node_mgr_lock); - - list_add_tail(&pnode->list_elem, &hnode_mgr->node_list); - ++(hnode_mgr->num_nodes); - - /* Exit critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - - /* Preset this to assume phases are split - * (for overlay and dll) */ - pnode->phase_split = true; - - /* Notify all clients registered for DSP_NODESTATECHANGE. */ - proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE); - } else { - /* Cleanup */ - if (pnode) - delete_node(pnode, pr_ctxt); - - } - - if (!status) { - status = drv_insert_node_res_element(pnode, &node_res, pr_ctxt); - if (status) { - delete_node(pnode, pr_ctxt); - goto func_end; - } - - *noderes = (struct node_res_object *)node_res; - drv_proc_node_update_heap_status(node_res, true); - drv_proc_node_update_status(node_res, true); - } -func_end: - dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p " - "node_res: %p status: 0x%x\n", __func__, hprocessor, - node_uuid, pargs, attr_in, noderes, status); - return status; -} - -/* - * ======== node_alloc_msg_buf ======== - * Purpose: - * Allocates buffer for zero copy messaging. - */ -DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize, - struct dsp_bufferattr *pattr, - u8 **pbuffer) -{ - struct node_object *pnode = (struct node_object *)hnode; - int status = 0; - bool va_flag = false; - bool set_info; - u32 proc_id; - - if (!pnode) - status = -EFAULT; - else if (node_get_type(pnode) == NODE_DEVICE) - status = -EPERM; - - if (status) - goto func_end; - - if (pattr == NULL) - pattr = &node_dfltbufattrs; /* set defaults */ - - status = proc_get_processor_id(pnode->processor, &proc_id); - if (proc_id != DSP_UNIT) - goto func_end; - - /* If segment ID includes MEM_SETVIRTUALSEGID then pbuffer is a - * virt address, so set this info in this node's translator - * object for future ref. If MEM_GETVIRTUALSEGID then retrieve - * virtual address from node's translator. */ - if ((pattr->segment_id & MEM_SETVIRTUALSEGID) || - (pattr->segment_id & MEM_GETVIRTUALSEGID)) { - va_flag = true; - set_info = (pattr->segment_id & MEM_SETVIRTUALSEGID) ? - true : false; - /* Clear mask bits */ - pattr->segment_id &= ~MEM_MASKVIRTUALSEGID; - /* Set/get this node's translators virtual address base/size */ - status = cmm_xlator_info(pnode->xlator, pbuffer, usize, - pattr->segment_id, set_info); - } - if (!status && (!va_flag)) { - if (pattr->segment_id != 1) { - /* Node supports single SM segment only. */ - status = -EBADR; - } - /* Arbitrary SM buffer alignment not supported for host side - * allocs, but guaranteed for the following alignment - * values. */ - switch (pattr->buf_alignment) { - case 0: - case 1: - case 2: - case 4: - break; - default: - /* alignment value not supportted */ - status = -EPERM; - break; - } - if (!status) { - /* allocate physical buffer from seg_id in node's - * translator */ - (void)cmm_xlator_alloc_buf(pnode->xlator, pbuffer, - usize); - if (*pbuffer == NULL) { - pr_err("%s: error - Out of shared memory\n", - __func__); - status = -ENOMEM; - } - } - } -func_end: - return status; -} - -/* - * ======== node_change_priority ======== - * Purpose: - * Change the priority of a node in the allocated state, or that is - * currently running or paused on the target. - */ -int node_change_priority(struct node_object *hnode, s32 prio) -{ - struct node_object *pnode = (struct node_object *)hnode; - struct node_mgr *hnode_mgr = NULL; - enum node_type node_type; - enum node_state state; - int status = 0; - u32 proc_id; - - if (!hnode || !hnode->node_mgr) { - status = -EFAULT; - } else { - hnode_mgr = hnode->node_mgr; - node_type = node_get_type(hnode); - if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) - status = -EPERM; - else if (prio < hnode_mgr->min_pri || prio > hnode_mgr->max_pri) - status = -EDOM; - } - if (status) - goto func_end; - - /* Enter critical section */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - state = node_get_state(hnode); - if (state == NODE_ALLOCATED || state == NODE_PAUSED) { - NODE_SET_PRIORITY(hnode, prio); - } else { - if (state != NODE_RUNNING) { - status = -EBADR; - goto func_cont; - } - status = proc_get_processor_id(pnode->processor, &proc_id); - if (proc_id == DSP_UNIT) { - status = - disp_node_change_priority(hnode_mgr->disp_obj, - hnode, - hnode_mgr->fxn_addrs - [RMSCHANGENODEPRIORITY], - hnode->node_env, prio); - } - if (status >= 0) - NODE_SET_PRIORITY(hnode, prio); - - } -func_cont: - /* Leave critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); -func_end: - return status; -} - -/* - * ======== node_connect ======== - * Purpose: - * Connect two nodes on the DSP, or a node on the DSP to the GPP. - */ -int node_connect(struct node_object *node1, u32 stream1, - struct node_object *node2, - u32 stream2, struct dsp_strmattr *pattrs, - struct dsp_cbdata *conn_param) -{ - struct node_mgr *hnode_mgr; - char *pstr_dev_name = NULL; - enum node_type node1_type = NODE_TASK; - enum node_type node2_type = NODE_TASK; - enum dsp_strmmode strm_mode; - struct node_strmdef *pstrm_def; - struct node_strmdef *input = NULL; - struct node_strmdef *output = NULL; - struct node_object *dev_node_obj; - struct node_object *hnode; - struct stream_chnl *pstream; - u32 pipe_id; - u32 chnl_id; - s8 chnl_mode; - u32 dw_length; - int status = 0; - - if (!node1 || !node2) - return -EFAULT; - - /* The two nodes must be on the same processor */ - if (node1 != (struct node_object *)DSP_HGPPNODE && - node2 != (struct node_object *)DSP_HGPPNODE && - node1->node_mgr != node2->node_mgr) - return -EPERM; - - /* Cannot connect a node to itself */ - if (node1 == node2) - return -EPERM; - - /* node_get_type() will return NODE_GPP if hnode = DSP_HGPPNODE. */ - node1_type = node_get_type(node1); - node2_type = node_get_type(node2); - /* Check stream indices ranges */ - if ((node1_type != NODE_GPP && node1_type != NODE_DEVICE && - stream1 >= MAX_OUTPUTS(node1)) || - (node2_type != NODE_GPP && node2_type != NODE_DEVICE && - stream2 >= MAX_INPUTS(node2))) - return -EINVAL; - - /* - * Only the following types of connections are allowed: - * task/dais socket < == > task/dais socket - * task/dais socket < == > device - * task/dais socket < == > GPP - * - * ie, no message nodes, and at least one task or dais - * socket node. - */ - if (node1_type == NODE_MESSAGE || node2_type == NODE_MESSAGE || - (node1_type != NODE_TASK && - node1_type != NODE_DAISSOCKET && - node2_type != NODE_TASK && - node2_type != NODE_DAISSOCKET)) - return -EPERM; - /* - * Check stream mode. Default is STRMMODE_PROCCOPY. - */ - if (pattrs && pattrs->strm_mode != STRMMODE_PROCCOPY) - return -EPERM; /* illegal stream mode */ - - if (node1_type != NODE_GPP) - hnode_mgr = node1->node_mgr; - else - hnode_mgr = node2->node_mgr; - - /* Enter critical section */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - /* Nodes must be in the allocated state */ - if (node1_type != NODE_GPP && - node_get_state(node1) != NODE_ALLOCATED) { - status = -EBADR; - goto out_unlock; - } - - if (node2_type != NODE_GPP && - node_get_state(node2) != NODE_ALLOCATED) { - status = -EBADR; - goto out_unlock; - } - - /* - * Check that stream indices for task and dais socket nodes - * are not already be used. (Device nodes checked later) - */ - if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) { - output = &(node1->create_args.asa. - task_arg_obj.strm_out_def[stream1]); - if (output->sz_device) { - status = -EISCONN; - goto out_unlock; - } - - } - if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) { - input = &(node2->create_args.asa. - task_arg_obj.strm_in_def[stream2]); - if (input->sz_device) { - status = -EISCONN; - goto out_unlock; - } - - } - /* Connecting two task nodes? */ - if ((node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) && - (node2_type == NODE_TASK || - node2_type == NODE_DAISSOCKET)) { - /* Find available pipe */ - pipe_id = find_first_zero_bit(hnode_mgr->pipe_map, MAXPIPES); - if (pipe_id == MAXPIPES) { - status = -ECONNREFUSED; - goto out_unlock; - } - set_bit(pipe_id, hnode_mgr->pipe_map); - node1->outputs[stream1].type = NODECONNECT; - node2->inputs[stream2].type = NODECONNECT; - node1->outputs[stream1].dev_id = pipe_id; - node2->inputs[stream2].dev_id = pipe_id; - output->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL); - input->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL); - if (!output->sz_device || !input->sz_device) { - /* Undo the connection */ - kfree(output->sz_device); - kfree(input->sz_device); - clear_bit(pipe_id, hnode_mgr->pipe_map); - status = -ENOMEM; - goto out_unlock; - } - /* Copy "/dbpipe<pipId>" name to device names */ - sprintf(output->sz_device, "%s%d", PIPEPREFIX, pipe_id); - strcpy(input->sz_device, output->sz_device); - } - /* Connecting task node to host? */ - if (node1_type == NODE_GPP || node2_type == NODE_GPP) { - pstr_dev_name = kzalloc(HOSTNAMELEN + 1, GFP_KERNEL); - if (!pstr_dev_name) { - status = -ENOMEM; - goto out_unlock; - } - - chnl_mode = (node1_type == NODE_GPP) ? - CHNL_MODETODSP : CHNL_MODEFROMDSP; - - /* - * Reserve a channel id. We need to put the name "/host<id>" - * in the node's create_args, but the host - * side channel will not be opened until DSPStream_Open is - * called for this node. - */ - strm_mode = pattrs ? pattrs->strm_mode : STRMMODE_PROCCOPY; - switch (strm_mode) { - case STRMMODE_RDMA: - chnl_id = find_first_zero_bit(hnode_mgr->dma_chnl_map, - CHNL_MAXCHANNELS); - if (chnl_id < CHNL_MAXCHANNELS) { - set_bit(chnl_id, hnode_mgr->dma_chnl_map); - /* dma chans are 2nd transport chnl set - * ids(e.g. 16-31) */ - chnl_id = chnl_id + hnode_mgr->num_chnls; - } - break; - case STRMMODE_ZEROCOPY: - chnl_id = find_first_zero_bit(hnode_mgr->zc_chnl_map, - CHNL_MAXCHANNELS); - if (chnl_id < CHNL_MAXCHANNELS) { - set_bit(chnl_id, hnode_mgr->zc_chnl_map); - /* zero-copy chans are 3nd transport set - * (e.g. 32-47) */ - chnl_id = chnl_id + - (2 * hnode_mgr->num_chnls); - } - break; - case STRMMODE_PROCCOPY: - chnl_id = find_first_zero_bit(hnode_mgr->chnl_map, - CHNL_MAXCHANNELS); - if (chnl_id < CHNL_MAXCHANNELS) - set_bit(chnl_id, hnode_mgr->chnl_map); - break; - default: - status = -EINVAL; - goto out_unlock; - } - if (chnl_id == CHNL_MAXCHANNELS) { - status = -ECONNREFUSED; - goto out_unlock; - } - - if (node1 == (struct node_object *)DSP_HGPPNODE) { - node2->inputs[stream2].type = HOSTCONNECT; - node2->inputs[stream2].dev_id = chnl_id; - input->sz_device = pstr_dev_name; - } else { - node1->outputs[stream1].type = HOSTCONNECT; - node1->outputs[stream1].dev_id = chnl_id; - output->sz_device = pstr_dev_name; - } - sprintf(pstr_dev_name, "%s%d", HOSTPREFIX, chnl_id); - } - /* Connecting task node to device node? */ - if ((node1_type == NODE_DEVICE) || (node2_type == NODE_DEVICE)) { - if (node2_type == NODE_DEVICE) { - /* node1 == > device */ - dev_node_obj = node2; - hnode = node1; - pstream = &(node1->outputs[stream1]); - pstrm_def = output; - } else { - /* device == > node2 */ - dev_node_obj = node1; - hnode = node2; - pstream = &(node2->inputs[stream2]); - pstrm_def = input; - } - /* Set up create args */ - pstream->type = DEVICECONNECT; - dw_length = strlen(dev_node_obj->str_dev_name); - if (conn_param) - pstrm_def->sz_device = kzalloc(dw_length + 1 + - conn_param->cb_data, - GFP_KERNEL); - else - pstrm_def->sz_device = kzalloc(dw_length + 1, - GFP_KERNEL); - if (!pstrm_def->sz_device) { - status = -ENOMEM; - goto out_unlock; - } - /* Copy device name */ - strncpy(pstrm_def->sz_device, - dev_node_obj->str_dev_name, dw_length); - if (conn_param) - strncat(pstrm_def->sz_device, - (char *)conn_param->node_data, - (u32) conn_param->cb_data); - dev_node_obj->device_owner = hnode; - } - /* Fill in create args */ - if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) { - node1->create_args.asa.task_arg_obj.num_outputs++; - fill_stream_def(node1, output, pattrs); - } - if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) { - node2->create_args.asa.task_arg_obj.num_inputs++; - fill_stream_def(node2, input, pattrs); - } - /* Update node1 and node2 stream_connect */ - if (node1_type != NODE_GPP && node1_type != NODE_DEVICE) { - node1->num_outputs++; - if (stream1 > node1->max_output_index) - node1->max_output_index = stream1; - - } - if (node2_type != NODE_GPP && node2_type != NODE_DEVICE) { - node2->num_inputs++; - if (stream2 > node2->max_input_index) - node2->max_input_index = stream2; - - } - fill_stream_connect(node1, node2, stream1, stream2); - /* end of sync_enter_cs */ - /* Exit critical section */ -out_unlock: - if (status && pstr_dev_name) - kfree(pstr_dev_name); - mutex_unlock(&hnode_mgr->node_mgr_lock); - dev_dbg(bridge, "%s: node1: %p stream1: %d node2: %p stream2: %d" - "pattrs: %p status: 0x%x\n", __func__, node1, - stream1, node2, stream2, pattrs, status); - return status; -} - -/* - * ======== node_create ======== - * Purpose: - * Create a node on the DSP by remotely calling the node's create function. - */ -int node_create(struct node_object *hnode) -{ - struct node_object *pnode = (struct node_object *)hnode; - struct node_mgr *hnode_mgr; - struct bridge_drv_interface *intf_fxns; - u32 ul_create_fxn; - enum node_type node_type; - int status = 0; - int status1 = 0; - struct dsp_cbdata cb_data; - u32 proc_id = 255; - struct dsp_processorstate proc_state; - struct proc_object *hprocessor; -#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) - struct dspbridge_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; -#endif - - if (!pnode) { - status = -EFAULT; - goto func_end; - } - hprocessor = hnode->processor; - status = proc_get_state(hprocessor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_end; - /* If processor is in error state then don't attempt to create - new node */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_end; - } - /* create struct dsp_cbdata struct for PWR calls */ - cb_data.cb_data = PWR_TIMEOUT; - node_type = node_get_type(hnode); - hnode_mgr = hnode->node_mgr; - intf_fxns = hnode_mgr->intf_fxns; - /* Get access to node dispatcher */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - /* Check node state */ - if (node_get_state(hnode) != NODE_ALLOCATED) - status = -EBADR; - - if (!status) - status = proc_get_processor_id(pnode->processor, &proc_id); - - if (status) - goto func_cont2; - - if (proc_id != DSP_UNIT) - goto func_cont2; - - /* Make sure streams are properly connected */ - if ((hnode->num_inputs && hnode->max_input_index > - hnode->num_inputs - 1) || - (hnode->num_outputs && hnode->max_output_index > - hnode->num_outputs - 1)) - status = -ENOTCONN; - - if (!status) { - /* If node's create function is not loaded, load it */ - /* Boost the OPP level to max level that DSP can be requested */ -#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) - if (pdata->cpu_set_freq) - (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP3]); -#endif - status = hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj, - NLDR_CREATE); - /* Get address of node's create function */ - if (!status) { - hnode->loaded = true; - if (node_type != NODE_DEVICE) { - status = get_fxn_address(hnode, &ul_create_fxn, - CREATEPHASE); - } - } else { - pr_err("%s: failed to load create code: 0x%x\n", - __func__, status); - } - /* Request the lowest OPP level */ -#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) - if (pdata->cpu_set_freq) - (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]); -#endif - /* Get address of iAlg functions, if socket node */ - if (!status) { - if (node_type == NODE_DAISSOCKET) { - status = hnode_mgr->nldr_fxns.get_fxn_addr - (hnode->nldr_node_obj, - hnode->dcd_props.obj_data.node_obj. - str_i_alg_name, - &hnode->create_args.asa. - task_arg_obj.dais_arg); - } - } - } - if (!status) { - if (node_type != NODE_DEVICE) { - status = disp_node_create(hnode_mgr->disp_obj, hnode, - hnode_mgr->fxn_addrs - [RMSCREATENODE], - ul_create_fxn, - &(hnode->create_args), - &(hnode->node_env)); - if (status >= 0) { - /* Set the message queue id to the node env - * pointer */ - intf_fxns = hnode_mgr->intf_fxns; - (*intf_fxns->msg_set_queue_id) (hnode-> - msg_queue_obj, - hnode->node_env); - } - } - } - /* Phase II/Overlays: Create, execute, delete phases possibly in - * different files/sections. */ - if (hnode->loaded && hnode->phase_split) { - /* If create code was dynamically loaded, we can now unload - * it. */ - status1 = hnode_mgr->nldr_fxns.unload(hnode->nldr_node_obj, - NLDR_CREATE); - hnode->loaded = false; - } - if (status1) - pr_err("%s: Failed to unload create code: 0x%x\n", - __func__, status1); -func_cont2: - /* Update node state and node manager state */ - if (status >= 0) { - NODE_SET_STATE(hnode, NODE_CREATED); - hnode_mgr->num_created++; - goto func_cont; - } - if (status != -EBADR) { - /* Put back in NODE_ALLOCATED state if error occurred */ - NODE_SET_STATE(hnode, NODE_ALLOCATED); - } -func_cont: - /* Free access to node dispatcher */ - mutex_unlock(&hnode_mgr->node_mgr_lock); -func_end: - if (status >= 0) { - proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE); - ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); - } - - dev_dbg(bridge, "%s: hnode: %p status: 0x%x\n", __func__, - hnode, status); - return status; -} - -/* - * ======== node_create_mgr ======== - * Purpose: - * Create a NODE Manager object. - */ -int node_create_mgr(struct node_mgr **node_man, - struct dev_object *hdev_obj) -{ - u32 i; - struct node_mgr *node_mgr_obj = NULL; - struct disp_attr disp_attr_obj; - char *sz_zl_file = ""; - struct nldr_attrs nldr_attrs_obj; - int status = 0; - u8 dev_type; - - *node_man = NULL; - /* Allocate Node manager object */ - node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL); - if (!node_mgr_obj) - return -ENOMEM; - - node_mgr_obj->dev_obj = hdev_obj; - - node_mgr_obj->ntfy_obj = kmalloc(sizeof(struct ntfy_object), - GFP_KERNEL); - if (!node_mgr_obj->ntfy_obj) { - status = -ENOMEM; - goto out_err; - } - ntfy_init(node_mgr_obj->ntfy_obj); - - INIT_LIST_HEAD(&node_mgr_obj->node_list); - - dev_get_dev_type(hdev_obj, &dev_type); - - status = dcd_create_manager(sz_zl_file, &node_mgr_obj->dcd_mgr); - if (status) - goto out_err; - - status = get_proc_props(node_mgr_obj, hdev_obj); - if (status) - goto out_err; - - /* Create NODE Dispatcher */ - disp_attr_obj.chnl_offset = node_mgr_obj->chnl_offset; - disp_attr_obj.chnl_buf_size = node_mgr_obj->chnl_buf_size; - disp_attr_obj.proc_family = node_mgr_obj->proc_family; - disp_attr_obj.proc_type = node_mgr_obj->proc_type; - - status = disp_create(&node_mgr_obj->disp_obj, hdev_obj, &disp_attr_obj); - if (status) - goto out_err; - - /* Create a STRM Manager */ - status = strm_create(&node_mgr_obj->strm_mgr_obj, hdev_obj); - if (status) - goto out_err; - - dev_get_intf_fxns(hdev_obj, &node_mgr_obj->intf_fxns); - /* Get msg_ctrl queue manager */ - dev_get_msg_mgr(hdev_obj, &node_mgr_obj->msg_mgr_obj); - mutex_init(&node_mgr_obj->node_mgr_lock); - - /* Block out reserved channels */ - for (i = 0; i < node_mgr_obj->chnl_offset; i++) - set_bit(i, node_mgr_obj->chnl_map); - - /* Block out channels reserved for RMS */ - set_bit(node_mgr_obj->chnl_offset, node_mgr_obj->chnl_map); - set_bit(node_mgr_obj->chnl_offset + 1, node_mgr_obj->chnl_map); - - /* NO RM Server on the IVA */ - if (dev_type != IVA_UNIT) { - /* Get addresses of any RMS functions loaded */ - status = get_rms_fxns(node_mgr_obj); - if (status) - goto out_err; - } - - /* Get loader functions and create loader */ - node_mgr_obj->nldr_fxns = nldr_fxns; /* Dyn loader funcs */ - - nldr_attrs_obj.ovly = ovly; - nldr_attrs_obj.write = mem_write; - nldr_attrs_obj.dsp_word_size = node_mgr_obj->dsp_word_size; - nldr_attrs_obj.dsp_mau_size = node_mgr_obj->dsp_mau_size; - status = node_mgr_obj->nldr_fxns.create(&node_mgr_obj->nldr_obj, - hdev_obj, - &nldr_attrs_obj); - if (status) - goto out_err; - - *node_man = node_mgr_obj; - - return status; -out_err: - delete_node_mgr(node_mgr_obj); - return status; -} - -/* - * ======== node_delete ======== - * Purpose: - * Delete a node on the DSP by remotely calling the node's delete function. - * Loads the node's delete function if necessary. Free GPP side resources - * after node's delete function returns. - */ -int node_delete(struct node_res_object *noderes, - struct process_context *pr_ctxt) -{ - struct node_object *pnode = noderes->node; - struct node_mgr *hnode_mgr; - struct proc_object *hprocessor; - struct disp_object *disp_obj; - u32 ul_delete_fxn; - enum node_type node_type; - enum node_state state; - int status = 0; - int status1 = 0; - struct dsp_cbdata cb_data; - u32 proc_id; - struct bridge_drv_interface *intf_fxns; - - void *node_res = noderes; - - struct dsp_processorstate proc_state; - - if (!pnode) { - status = -EFAULT; - goto func_end; - } - /* create struct dsp_cbdata struct for PWR call */ - cb_data.cb_data = PWR_TIMEOUT; - hnode_mgr = pnode->node_mgr; - hprocessor = pnode->processor; - disp_obj = hnode_mgr->disp_obj; - node_type = node_get_type(pnode); - intf_fxns = hnode_mgr->intf_fxns; - /* Enter critical section */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - state = node_get_state(pnode); - /* Execute delete phase code for non-device node in all cases - * except when the node was only allocated. Delete phase must be - * executed even if create phase was executed, but failed. - * If the node environment pointer is non-NULL, the delete phase - * code must be executed. */ - if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) && - node_type != NODE_DEVICE) { - status = proc_get_processor_id(pnode->processor, &proc_id); - if (status) - goto func_cont1; - - if (proc_id == DSP_UNIT || proc_id == IVA_UNIT) { - /* If node has terminated, execute phase code will - * have already been unloaded in node_on_exit(). If the - * node is PAUSED, the execute phase is loaded, and it - * is now ok to unload it. If the node is running, we - * will unload the execute phase only after deleting - * the node. */ - if (state == NODE_PAUSED && pnode->loaded && - pnode->phase_split) { - /* Ok to unload execute code as long as node - * is not * running */ - status1 = - hnode_mgr->nldr_fxns. - unload(pnode->nldr_node_obj, - NLDR_EXECUTE); - pnode->loaded = false; - NODE_SET_STATE(pnode, NODE_DONE); - } - /* Load delete phase code if not loaded or if haven't - * * unloaded EXECUTE phase */ - if ((!(pnode->loaded) || (state == NODE_RUNNING)) && - pnode->phase_split) { - status = - hnode_mgr->nldr_fxns. - load(pnode->nldr_node_obj, NLDR_DELETE); - if (!status) - pnode->loaded = true; - else - pr_err("%s: fail - load delete code:" - " 0x%x\n", __func__, status); - } - } -func_cont1: - if (!status) { - /* Unblock a thread trying to terminate the node */ - (void)sync_set_event(pnode->sync_done); - if (proc_id == DSP_UNIT) { - /* ul_delete_fxn = address of node's delete - * function */ - status = get_fxn_address(pnode, &ul_delete_fxn, - DELETEPHASE); - } else if (proc_id == IVA_UNIT) - ul_delete_fxn = (u32) pnode->node_env; - if (!status) { - status = proc_get_state(hprocessor, - &proc_state, - sizeof(struct - dsp_processorstate)); - if (proc_state.proc_state != PROC_ERROR) { - status = - disp_node_delete(disp_obj, pnode, - hnode_mgr-> - fxn_addrs - [RMSDELETENODE], - ul_delete_fxn, - pnode->node_env); - } else - NODE_SET_STATE(pnode, NODE_DONE); - - /* Unload execute, if not unloaded, and delete - * function */ - if (state == NODE_RUNNING && - pnode->phase_split) { - status1 = - hnode_mgr->nldr_fxns. - unload(pnode->nldr_node_obj, - NLDR_EXECUTE); - } - if (status1) - pr_err("%s: fail - unload execute code:" - " 0x%x\n", __func__, status1); - - status1 = - hnode_mgr->nldr_fxns.unload(pnode-> - nldr_node_obj, - NLDR_DELETE); - pnode->loaded = false; - if (status1) - pr_err("%s: fail - unload delete code: " - "0x%x\n", __func__, status1); - } - } - } - /* Free host side resources even if a failure occurred */ - /* Remove node from hnode_mgr->node_list */ - list_del(&pnode->list_elem); - hnode_mgr->num_nodes--; - /* Decrement count of nodes created on DSP */ - if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) && - (pnode->node_env != (u32) NULL))) - hnode_mgr->num_created--; - /* Free host-side resources allocated by node_create() - * delete_node() fails if SM buffers not freed by client! */ - drv_proc_node_update_status(node_res, false); - delete_node(pnode, pr_ctxt); - - /* - * Release all Node resources and its context - */ - idr_remove(pr_ctxt->node_id, ((struct node_res_object *)node_res)->id); - kfree(node_res); - - /* Exit critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - proc_notify_clients(hprocessor, DSP_NODESTATECHANGE); -func_end: - dev_dbg(bridge, "%s: pnode: %p status 0x%x\n", __func__, pnode, status); - return status; -} - -/* - * ======== node_delete_mgr ======== - * Purpose: - * Delete the NODE Manager. - */ -int node_delete_mgr(struct node_mgr *hnode_mgr) -{ - if (!hnode_mgr) - return -EFAULT; - - delete_node_mgr(hnode_mgr); - - return 0; -} - -/* - * ======== node_enum_nodes ======== - * Purpose: - * Enumerate currently allocated nodes. - */ -int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab, - u32 node_tab_size, u32 *pu_num_nodes, - u32 *pu_allocated) -{ - struct node_object *hnode; - u32 i = 0; - int status = 0; - - if (!hnode_mgr) { - status = -EFAULT; - goto func_end; - } - /* Enter critical section */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - if (hnode_mgr->num_nodes > node_tab_size) { - *pu_allocated = hnode_mgr->num_nodes; - *pu_num_nodes = 0; - status = -EINVAL; - } else { - list_for_each_entry(hnode, &hnode_mgr->node_list, list_elem) - node_tab[i++] = hnode; - *pu_allocated = *pu_num_nodes = hnode_mgr->num_nodes; - } - /* end of sync_enter_cs */ - /* Exit critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); -func_end: - return status; -} - -/* - * ======== node_free_msg_buf ======== - * Purpose: - * Frees the message buffer. - */ -int node_free_msg_buf(struct node_object *hnode, u8 *pbuffer, - struct dsp_bufferattr *pattr) -{ - struct node_object *pnode = (struct node_object *)hnode; - int status = 0; - u32 proc_id; - - if (!hnode) { - status = -EFAULT; - goto func_end; - } - status = proc_get_processor_id(pnode->processor, &proc_id); - if (proc_id == DSP_UNIT) { - if (!status) { - if (pattr == NULL) { - /* set defaults */ - pattr = &node_dfltbufattrs; - } - /* Node supports single SM segment only */ - if (pattr->segment_id != 1) - status = -EBADR; - - /* pbuffer is clients Va. */ - status = cmm_xlator_free_buf(pnode->xlator, pbuffer); - } - } else { - } -func_end: - return status; -} - -/* - * ======== node_get_attr ======== - * Purpose: - * Copy the current attributes of the specified node into a dsp_nodeattr - * structure. - */ -int node_get_attr(struct node_object *hnode, - struct dsp_nodeattr *pattr, u32 attr_size) -{ - struct node_mgr *hnode_mgr; - - if (!hnode) - return -EFAULT; - - hnode_mgr = hnode->node_mgr; - /* Enter hnode_mgr critical section since we're accessing - * data that could be changed by node_change_priority() and - * node_connect(). */ - mutex_lock(&hnode_mgr->node_mgr_lock); - pattr->cb_struct = sizeof(struct dsp_nodeattr); - /* dsp_nodeattrin */ - pattr->in_node_attr_in.cb_struct = - sizeof(struct dsp_nodeattrin); - pattr->in_node_attr_in.prio = hnode->prio; - pattr->in_node_attr_in.timeout = hnode->timeout; - pattr->in_node_attr_in.heap_size = - hnode->create_args.asa.task_arg_obj.heap_size; - pattr->in_node_attr_in.pgpp_virt_addr = (void *) - hnode->create_args.asa.task_arg_obj.gpp_heap_addr; - pattr->node_attr_inputs = hnode->num_gpp_inputs; - pattr->node_attr_outputs = hnode->num_gpp_outputs; - /* dsp_nodeinfo */ - get_node_info(hnode, &(pattr->node_info)); - /* end of sync_enter_cs */ - /* Exit critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - - return 0; -} - -/* - * ======== node_get_channel_id ======== - * Purpose: - * Get the channel index reserved for a stream connection between the - * host and a node. - */ -int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index, - u32 *chan_id) -{ - enum node_type node_type; - int status = -EINVAL; - - if (!hnode) { - status = -EFAULT; - return status; - } - node_type = node_get_type(hnode); - if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) { - status = -EPERM; - return status; - } - if (dir == DSP_TONODE) { - if (index < MAX_INPUTS(hnode)) { - if (hnode->inputs[index].type == HOSTCONNECT) { - *chan_id = hnode->inputs[index].dev_id; - status = 0; - } - } - } else { - if (index < MAX_OUTPUTS(hnode)) { - if (hnode->outputs[index].type == HOSTCONNECT) { - *chan_id = hnode->outputs[index].dev_id; - status = 0; - } - } - } - return status; -} - -/* - * ======== node_get_message ======== - * Purpose: - * Retrieve a message from a node on the DSP. - */ -int node_get_message(struct node_object *hnode, - struct dsp_msg *message, u32 utimeout) -{ - struct node_mgr *hnode_mgr; - enum node_type node_type; - struct bridge_drv_interface *intf_fxns; - int status = 0; - void *tmp_buf; - struct dsp_processorstate proc_state; - struct proc_object *hprocessor; - - if (!hnode) { - status = -EFAULT; - goto func_end; - } - hprocessor = hnode->processor; - status = proc_get_state(hprocessor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_end; - /* If processor is in error state then don't attempt to get the - message */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_end; - } - hnode_mgr = hnode->node_mgr; - node_type = node_get_type(hnode); - if (node_type != NODE_MESSAGE && node_type != NODE_TASK && - node_type != NODE_DAISSOCKET) { - status = -EPERM; - goto func_end; - } - /* This function will block unless a message is available. Since - * DSPNode_RegisterNotify() allows notification when a message - * is available, the system can be designed so that - * DSPNode_GetMessage() is only called when a message is - * available. */ - intf_fxns = hnode_mgr->intf_fxns; - status = - (*intf_fxns->msg_get) (hnode->msg_queue_obj, message, utimeout); - /* Check if message contains SM descriptor */ - if (status || !(message->cmd & DSP_RMSBUFDESC)) - goto func_end; - - /* Translate DSP byte addr to GPP Va. */ - tmp_buf = cmm_xlator_translate(hnode->xlator, - (void *)(message->arg1 * - hnode->node_mgr-> - dsp_word_size), CMM_DSPPA2PA); - if (tmp_buf != NULL) { - /* now convert this GPP Pa to Va */ - tmp_buf = cmm_xlator_translate(hnode->xlator, tmp_buf, - CMM_PA2VA); - if (tmp_buf != NULL) { - /* Adjust SM size in msg */ - message->arg1 = (u32) tmp_buf; - message->arg2 *= hnode->node_mgr->dsp_word_size; - } else { - status = -ESRCH; - } - } else { - status = -ESRCH; - } -func_end: - dev_dbg(bridge, "%s: hnode: %p message: %p utimeout: 0x%x\n", __func__, - hnode, message, utimeout); - return status; -} - -/* - * ======== node_get_nldr_obj ======== - */ -int node_get_nldr_obj(struct node_mgr *hnode_mgr, - struct nldr_object **nldr_ovlyobj) -{ - int status = 0; - struct node_mgr *node_mgr_obj = hnode_mgr; - - if (!hnode_mgr) - status = -EFAULT; - else - *nldr_ovlyobj = node_mgr_obj->nldr_obj; - - return status; -} - -/* - * ======== node_get_strm_mgr ======== - * Purpose: - * Returns the Stream manager. - */ -int node_get_strm_mgr(struct node_object *hnode, - struct strm_mgr **strm_man) -{ - int status = 0; - - if (!hnode) - status = -EFAULT; - else - *strm_man = hnode->node_mgr->strm_mgr_obj; - - return status; -} - -/* - * ======== node_get_load_type ======== - */ -enum nldr_loadtype node_get_load_type(struct node_object *hnode) -{ - if (!hnode) { - dev_dbg(bridge, "%s: Failed. hnode: %p\n", __func__, hnode); - return -1; - } else { - return hnode->dcd_props.obj_data.node_obj.load_type; - } -} - -/* - * ======== node_get_timeout ======== - * Purpose: - * Returns the timeout value for this node. - */ -u32 node_get_timeout(struct node_object *hnode) -{ - if (!hnode) { - dev_dbg(bridge, "%s: failed. hnode: %p\n", __func__, hnode); - return 0; - } else { - return hnode->timeout; - } -} - -/* - * ======== node_get_type ======== - * Purpose: - * Returns the node type. - */ -enum node_type node_get_type(struct node_object *hnode) -{ - enum node_type node_type; - - if (hnode == (struct node_object *)DSP_HGPPNODE) - node_type = NODE_GPP; - else { - if (!hnode) - node_type = -1; - else - node_type = hnode->ntype; - } - return node_type; -} - -/* - * ======== node_on_exit ======== - * Purpose: - * Gets called when RMS_EXIT is received for a node. - */ -void node_on_exit(struct node_object *hnode, s32 node_status) -{ - if (!hnode) - return; - - /* Set node state to done */ - NODE_SET_STATE(hnode, NODE_DONE); - hnode->exit_status = node_status; - if (hnode->loaded && hnode->phase_split) { - (void)hnode->node_mgr->nldr_fxns.unload(hnode-> - nldr_node_obj, - NLDR_EXECUTE); - hnode->loaded = false; - } - /* Unblock call to node_terminate */ - (void)sync_set_event(hnode->sync_done); - /* Notify clients */ - proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE); - ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); -} - -/* - * ======== node_pause ======== - * Purpose: - * Suspend execution of a node currently running on the DSP. - */ -int node_pause(struct node_object *hnode) -{ - struct node_object *pnode = (struct node_object *)hnode; - enum node_type node_type; - enum node_state state; - struct node_mgr *hnode_mgr; - int status = 0; - u32 proc_id; - struct dsp_processorstate proc_state; - struct proc_object *hprocessor; - - if (!hnode) { - status = -EFAULT; - } else { - node_type = node_get_type(hnode); - if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) - status = -EPERM; - } - if (status) - goto func_end; - - status = proc_get_processor_id(pnode->processor, &proc_id); - - if (proc_id == IVA_UNIT) - status = -ENOSYS; - - if (!status) { - hnode_mgr = hnode->node_mgr; - - /* Enter critical section */ - mutex_lock(&hnode_mgr->node_mgr_lock); - state = node_get_state(hnode); - /* Check node state */ - if (state != NODE_RUNNING) - status = -EBADR; - - if (status) - goto func_cont; - hprocessor = hnode->processor; - status = proc_get_state(hprocessor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_cont; - /* If processor is in error state then don't attempt - to send the message */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_cont; - } - - status = disp_node_change_priority(hnode_mgr->disp_obj, hnode, - hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY], - hnode->node_env, NODE_SUSPENDEDPRI); - - /* Update state */ - if (status >= 0) - NODE_SET_STATE(hnode, NODE_PAUSED); - -func_cont: - /* End of sync_enter_cs */ - /* Leave critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - if (status >= 0) { - proc_notify_clients(hnode->processor, - DSP_NODESTATECHANGE); - ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); - } - } -func_end: - dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status); - return status; -} - -/* - * ======== node_put_message ======== - * Purpose: - * Send a message to a message node, task node, or XDAIS socket node. This - * function will block until the message stream can accommodate the - * message, or a timeout occurs. - */ -int node_put_message(struct node_object *hnode, - const struct dsp_msg *pmsg, u32 utimeout) -{ - struct node_mgr *hnode_mgr = NULL; - enum node_type node_type; - struct bridge_drv_interface *intf_fxns; - enum node_state state; - int status = 0; - void *tmp_buf; - struct dsp_msg new_msg; - struct dsp_processorstate proc_state; - struct proc_object *hprocessor; - - if (!hnode) { - status = -EFAULT; - goto func_end; - } - hprocessor = hnode->processor; - status = proc_get_state(hprocessor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_end; - /* If processor is in bad state then don't attempt sending the - message */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_end; - } - hnode_mgr = hnode->node_mgr; - node_type = node_get_type(hnode); - if (node_type != NODE_MESSAGE && node_type != NODE_TASK && - node_type != NODE_DAISSOCKET) - status = -EPERM; - - if (!status) { - /* Check node state. Can't send messages to a node after - * we've sent the RMS_EXIT command. There is still the - * possibility that node_terminate can be called after we've - * checked the state. Could add another SYNC object to - * prevent this (can't use node_mgr_lock, since we don't - * want to block other NODE functions). However, the node may - * still exit on its own, before this message is sent. */ - mutex_lock(&hnode_mgr->node_mgr_lock); - state = node_get_state(hnode); - if (state == NODE_TERMINATING || state == NODE_DONE) - status = -EBADR; - - /* end of sync_enter_cs */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - } - if (status) - goto func_end; - - /* assign pmsg values to new msg */ - new_msg = *pmsg; - /* Now, check if message contains a SM buffer descriptor */ - if (pmsg->cmd & DSP_RMSBUFDESC) { - /* Translate GPP Va to DSP physical buf Ptr. */ - tmp_buf = cmm_xlator_translate(hnode->xlator, - (void *)new_msg.arg1, - CMM_VA2DSPPA); - if (tmp_buf != NULL) { - /* got translation, convert to MAUs in msg */ - if (hnode->node_mgr->dsp_word_size != 0) { - new_msg.arg1 = - (u32) tmp_buf / - hnode->node_mgr->dsp_word_size; - /* MAUs */ - new_msg.arg2 /= hnode->node_mgr-> - dsp_word_size; - } else { - pr_err("%s: dsp_word_size is zero!\n", - __func__); - status = -EPERM; /* bad DSPWordSize */ - } - } else { /* failed to translate buffer address */ - status = -ESRCH; - } - } - if (!status) { - intf_fxns = hnode_mgr->intf_fxns; - status = (*intf_fxns->msg_put) (hnode->msg_queue_obj, - &new_msg, utimeout); - } -func_end: - dev_dbg(bridge, "%s: hnode: %p pmsg: %p utimeout: 0x%x, " - "status 0x%x\n", __func__, hnode, pmsg, utimeout, status); - return status; -} - -/* - * ======== node_register_notify ======== - * Purpose: - * Register to be notified on specific events for this node. - */ -int node_register_notify(struct node_object *hnode, u32 event_mask, - u32 notify_type, - struct dsp_notification *hnotification) -{ - struct bridge_drv_interface *intf_fxns; - int status = 0; - - if (!hnode) { - status = -EFAULT; - } else { - /* Check if event mask is a valid node related event */ - if (event_mask & ~(DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY)) - status = -EINVAL; - - /* Check if notify type is valid */ - if (notify_type != DSP_SIGNALEVENT) - status = -EINVAL; - - /* Only one Notification can be registered at a - * time - Limitation */ - if (event_mask == (DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY)) - status = -EINVAL; - } - if (!status) { - if (event_mask == DSP_NODESTATECHANGE) { - status = ntfy_register(hnode->ntfy_obj, hnotification, - event_mask & DSP_NODESTATECHANGE, - notify_type); - } else { - /* Send Message part of event mask to msg_ctrl */ - intf_fxns = hnode->node_mgr->intf_fxns; - status = (*intf_fxns->msg_register_notify) - (hnode->msg_queue_obj, - event_mask & DSP_NODEMESSAGEREADY, notify_type, - hnotification); - } - - } - dev_dbg(bridge, "%s: hnode: %p event_mask: 0x%x notify_type: 0x%x " - "hnotification: %p status 0x%x\n", __func__, hnode, - event_mask, notify_type, hnotification, status); - return status; -} - -/* - * ======== node_run ======== - * Purpose: - * Start execution of a node's execute phase, or resume execution of a node - * that has been suspended (via NODE_NodePause()) on the DSP. Load the - * node's execute function if necessary. - */ -int node_run(struct node_object *hnode) -{ - struct node_object *pnode = (struct node_object *)hnode; - struct node_mgr *hnode_mgr; - enum node_type node_type; - enum node_state state; - u32 ul_execute_fxn; - u32 ul_fxn_addr; - int status = 0; - u32 proc_id; - struct bridge_drv_interface *intf_fxns; - struct dsp_processorstate proc_state; - struct proc_object *hprocessor; - - if (!hnode) { - status = -EFAULT; - goto func_end; - } - hprocessor = hnode->processor; - status = proc_get_state(hprocessor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_end; - /* If processor is in error state then don't attempt to run the node */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_end; - } - node_type = node_get_type(hnode); - if (node_type == NODE_DEVICE) - status = -EPERM; - if (status) - goto func_end; - - hnode_mgr = hnode->node_mgr; - if (!hnode_mgr) { - status = -EFAULT; - goto func_end; - } - intf_fxns = hnode_mgr->intf_fxns; - /* Enter critical section */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - state = node_get_state(hnode); - if (state != NODE_CREATED && state != NODE_PAUSED) - status = -EBADR; - - if (!status) - status = proc_get_processor_id(pnode->processor, &proc_id); - - if (status) - goto func_cont1; - - if ((proc_id != DSP_UNIT) && (proc_id != IVA_UNIT)) - goto func_cont1; - - if (state == NODE_CREATED) { - /* If node's execute function is not loaded, load it */ - if (!(hnode->loaded) && hnode->phase_split) { - status = - hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj, - NLDR_EXECUTE); - if (!status) { - hnode->loaded = true; - } else { - pr_err("%s: fail - load execute code: 0x%x\n", - __func__, status); - } - } - if (!status) { - /* Get address of node's execute function */ - if (proc_id == IVA_UNIT) - ul_execute_fxn = (u32) hnode->node_env; - else { - status = get_fxn_address(hnode, &ul_execute_fxn, - EXECUTEPHASE); - } - } - if (!status) { - ul_fxn_addr = hnode_mgr->fxn_addrs[RMSEXECUTENODE]; - status = - disp_node_run(hnode_mgr->disp_obj, hnode, - ul_fxn_addr, ul_execute_fxn, - hnode->node_env); - } - } else if (state == NODE_PAUSED) { - ul_fxn_addr = hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY]; - status = disp_node_change_priority(hnode_mgr->disp_obj, hnode, - ul_fxn_addr, hnode->node_env, - NODE_GET_PRIORITY(hnode)); - } else { - /* We should never get here */ - } -func_cont1: - /* Update node state. */ - if (status >= 0) - NODE_SET_STATE(hnode, NODE_RUNNING); - else /* Set state back to previous value */ - NODE_SET_STATE(hnode, state); - /*End of sync_enter_cs */ - /* Exit critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - if (status >= 0) { - proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE); - ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); - } -func_end: - dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status); - return status; -} - -/* - * ======== node_terminate ======== - * Purpose: - * Signal a node running on the DSP that it should exit its execute phase - * function. - */ -int node_terminate(struct node_object *hnode, int *pstatus) -{ - struct node_object *pnode = (struct node_object *)hnode; - struct node_mgr *hnode_mgr = NULL; - enum node_type node_type; - struct bridge_drv_interface *intf_fxns; - enum node_state state; - struct dsp_msg msg, killmsg; - int status = 0; - u32 proc_id, kill_time_out; - struct deh_mgr *hdeh_mgr; - struct dsp_processorstate proc_state; - - if (!hnode || !hnode->node_mgr) { - status = -EFAULT; - goto func_end; - } - if (pnode->processor == NULL) { - status = -EFAULT; - goto func_end; - } - status = proc_get_processor_id(pnode->processor, &proc_id); - - if (!status) { - hnode_mgr = hnode->node_mgr; - node_type = node_get_type(hnode); - if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) - status = -EPERM; - } - if (!status) { - /* Check node state */ - mutex_lock(&hnode_mgr->node_mgr_lock); - state = node_get_state(hnode); - if (state != NODE_RUNNING) { - status = -EBADR; - /* Set the exit status if node terminated on - * its own. */ - if (state == NODE_DONE) - *pstatus = hnode->exit_status; - - } else { - NODE_SET_STATE(hnode, NODE_TERMINATING); - } - /* end of sync_enter_cs */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - } - if (!status) { - /* - * Send exit message. Do not change state to NODE_DONE - * here. That will be done in callback. - */ - status = proc_get_state(pnode->processor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_cont; - /* If processor is in error state then don't attempt to send - * A kill task command */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_cont; - } - - msg.cmd = RMS_EXIT; - msg.arg1 = hnode->node_env; - killmsg.cmd = RMS_KILLTASK; - killmsg.arg1 = hnode->node_env; - intf_fxns = hnode_mgr->intf_fxns; - - if (hnode->timeout > MAXTIMEOUT) - kill_time_out = MAXTIMEOUT; - else - kill_time_out = (hnode->timeout) * 2; - - status = (*intf_fxns->msg_put) (hnode->msg_queue_obj, &msg, - hnode->timeout); - if (status) - goto func_cont; - - /* - * Wait on synchronization object that will be - * posted in the callback on receiving RMS_EXIT - * message, or by node_delete. Check for valid hnode, - * in case posted by node_delete(). - */ - status = sync_wait_on_event(hnode->sync_done, - kill_time_out / 2); - if (status != ETIME) - goto func_cont; - - status = (*intf_fxns->msg_put)(hnode->msg_queue_obj, - &killmsg, hnode->timeout); - if (status) - goto func_cont; - status = sync_wait_on_event(hnode->sync_done, - kill_time_out / 2); - if (status) { - /* - * Here it goes the part of the simulation of - * the DSP exception. - */ - dev_get_deh_mgr(hnode_mgr->dev_obj, &hdeh_mgr); - if (!hdeh_mgr) - goto func_cont; - - bridge_deh_notify(hdeh_mgr, DSP_SYSERROR, - DSP_EXCEPTIONABORT); - } - } -func_cont: - if (!status) { - /* Enter CS before getting exit status, in case node was - * deleted. */ - mutex_lock(&hnode_mgr->node_mgr_lock); - /* Make sure node wasn't deleted while we blocked */ - if (!hnode) { - status = -EPERM; - } else { - *pstatus = hnode->exit_status; - dev_dbg(bridge, "%s: hnode: %p env 0x%x status 0x%x\n", - __func__, hnode, hnode->node_env, status); - } - mutex_unlock(&hnode_mgr->node_mgr_lock); - } /*End of sync_enter_cs */ -func_end: - return status; -} - -/* - * ======== delete_node ======== - * Purpose: - * Free GPP resources allocated in node_allocate() or node_connect(). - */ -static void delete_node(struct node_object *hnode, - struct process_context *pr_ctxt) -{ - struct node_mgr *hnode_mgr; - struct bridge_drv_interface *intf_fxns; - u32 i; - enum node_type node_type; - struct stream_chnl stream; - struct node_msgargs node_msg_args; - struct node_taskargs task_arg_obj; -#ifdef DSP_DMM_DEBUG - struct dmm_object *dmm_mgr; - struct proc_object *p_proc_object = - (struct proc_object *)hnode->processor; -#endif - int status; - if (!hnode) - goto func_end; - hnode_mgr = hnode->node_mgr; - if (!hnode_mgr) - goto func_end; - - node_type = node_get_type(hnode); - if (node_type != NODE_DEVICE) { - node_msg_args = hnode->create_args.asa.node_msg_args; - kfree(node_msg_args.pdata); - - /* Free msg_ctrl queue */ - if (hnode->msg_queue_obj) { - intf_fxns = hnode_mgr->intf_fxns; - (*intf_fxns->msg_delete_queue) (hnode-> - msg_queue_obj); - hnode->msg_queue_obj = NULL; - } - - kfree(hnode->sync_done); - - /* Free all stream info */ - if (hnode->inputs) { - for (i = 0; i < MAX_INPUTS(hnode); i++) { - stream = hnode->inputs[i]; - free_stream(hnode_mgr, stream); - } - kfree(hnode->inputs); - hnode->inputs = NULL; - } - if (hnode->outputs) { - for (i = 0; i < MAX_OUTPUTS(hnode); i++) { - stream = hnode->outputs[i]; - free_stream(hnode_mgr, stream); - } - kfree(hnode->outputs); - hnode->outputs = NULL; - } - task_arg_obj = hnode->create_args.asa.task_arg_obj; - if (task_arg_obj.strm_in_def) { - for (i = 0; i < MAX_INPUTS(hnode); i++) { - kfree(task_arg_obj.strm_in_def[i].sz_device); - task_arg_obj.strm_in_def[i].sz_device = NULL; - } - kfree(task_arg_obj.strm_in_def); - task_arg_obj.strm_in_def = NULL; - } - if (task_arg_obj.strm_out_def) { - for (i = 0; i < MAX_OUTPUTS(hnode); i++) { - kfree(task_arg_obj.strm_out_def[i].sz_device); - task_arg_obj.strm_out_def[i].sz_device = NULL; - } - kfree(task_arg_obj.strm_out_def); - task_arg_obj.strm_out_def = NULL; - } - if (task_arg_obj.dsp_heap_res_addr) { - status = proc_un_map(hnode->processor, (void *) - task_arg_obj.dsp_heap_addr, - pr_ctxt); - - status = proc_un_reserve_memory(hnode->processor, - (void *) - task_arg_obj. - dsp_heap_res_addr, - pr_ctxt); -#ifdef DSP_DMM_DEBUG - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (dmm_mgr) - dmm_mem_map_dump(dmm_mgr); - else - status = DSP_EHANDLE; -#endif - } - } - if (node_type != NODE_MESSAGE) { - kfree(hnode->stream_connect); - hnode->stream_connect = NULL; - } - kfree(hnode->str_dev_name); - hnode->str_dev_name = NULL; - - if (hnode->ntfy_obj) { - ntfy_delete(hnode->ntfy_obj); - kfree(hnode->ntfy_obj); - hnode->ntfy_obj = NULL; - } - - /* These were allocated in dcd_get_object_def (via node_allocate) */ - kfree(hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn); - hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn = NULL; - - kfree(hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn); - hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn = NULL; - - kfree(hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn); - hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn = NULL; - - kfree(hnode->dcd_props.obj_data.node_obj.str_i_alg_name); - hnode->dcd_props.obj_data.node_obj.str_i_alg_name = NULL; - - /* Free all SM address translator resources */ - kfree(hnode->xlator); - kfree(hnode->nldr_node_obj); - hnode->nldr_node_obj = NULL; - hnode->node_mgr = NULL; - kfree(hnode); - hnode = NULL; -func_end: - return; -} - -/* - * ======== delete_node_mgr ======== - * Purpose: - * Frees the node manager. - */ -static void delete_node_mgr(struct node_mgr *hnode_mgr) -{ - struct node_object *hnode, *tmp; - - if (hnode_mgr) { - /* Free resources */ - if (hnode_mgr->dcd_mgr) - dcd_destroy_manager(hnode_mgr->dcd_mgr); - - /* Remove any elements remaining in lists */ - list_for_each_entry_safe(hnode, tmp, &hnode_mgr->node_list, - list_elem) { - list_del(&hnode->list_elem); - delete_node(hnode, NULL); - } - mutex_destroy(&hnode_mgr->node_mgr_lock); - if (hnode_mgr->ntfy_obj) { - ntfy_delete(hnode_mgr->ntfy_obj); - kfree(hnode_mgr->ntfy_obj); - } - - if (hnode_mgr->disp_obj) - disp_delete(hnode_mgr->disp_obj); - - if (hnode_mgr->strm_mgr_obj) - strm_delete(hnode_mgr->strm_mgr_obj); - - /* Delete the loader */ - if (hnode_mgr->nldr_obj) - hnode_mgr->nldr_fxns.delete(hnode_mgr->nldr_obj); - - kfree(hnode_mgr); - } -} - -/* - * ======== fill_stream_connect ======== - * Purpose: - * Fills stream information. - */ -static void fill_stream_connect(struct node_object *node1, - struct node_object *node2, - u32 stream1, u32 stream2) -{ - u32 strm_index; - struct dsp_streamconnect *strm1 = NULL; - struct dsp_streamconnect *strm2 = NULL; - enum node_type node1_type = NODE_TASK; - enum node_type node2_type = NODE_TASK; - - node1_type = node_get_type(node1); - node2_type = node_get_type(node2); - if (node1 != (struct node_object *)DSP_HGPPNODE) { - - if (node1_type != NODE_DEVICE) { - strm_index = node1->num_inputs + - node1->num_outputs - 1; - strm1 = &(node1->stream_connect[strm_index]); - strm1->cb_struct = sizeof(struct dsp_streamconnect); - strm1->this_node_stream_index = stream1; - } - - if (node2 != (struct node_object *)DSP_HGPPNODE) { - /* NODE == > NODE */ - if (node1_type != NODE_DEVICE) { - strm1->connected_node = node2; - strm1->ui_connected_node_id = node2->node_uuid; - strm1->connected_node_stream_index = stream2; - strm1->connect_type = CONNECTTYPE_NODEOUTPUT; - } - if (node2_type != NODE_DEVICE) { - strm_index = node2->num_inputs + - node2->num_outputs - 1; - strm2 = &(node2->stream_connect[strm_index]); - strm2->cb_struct = - sizeof(struct dsp_streamconnect); - strm2->this_node_stream_index = stream2; - strm2->connected_node = node1; - strm2->ui_connected_node_id = node1->node_uuid; - strm2->connected_node_stream_index = stream1; - strm2->connect_type = CONNECTTYPE_NODEINPUT; - } - } else if (node1_type != NODE_DEVICE) - strm1->connect_type = CONNECTTYPE_GPPOUTPUT; - } else { - /* GPP == > NODE */ - strm_index = node2->num_inputs + node2->num_outputs - 1; - strm2 = &(node2->stream_connect[strm_index]); - strm2->cb_struct = sizeof(struct dsp_streamconnect); - strm2->this_node_stream_index = stream2; - strm2->connect_type = CONNECTTYPE_GPPINPUT; - } -} - -/* - * ======== fill_stream_def ======== - * Purpose: - * Fills Stream attributes. - */ -static void fill_stream_def(struct node_object *hnode, - struct node_strmdef *pstrm_def, - struct dsp_strmattr *pattrs) -{ - struct node_mgr *hnode_mgr = hnode->node_mgr; - - if (pattrs != NULL) { - pstrm_def->num_bufs = pattrs->num_bufs; - pstrm_def->buf_size = - pattrs->buf_size / hnode_mgr->dsp_data_mau_size; - pstrm_def->seg_id = pattrs->seg_id; - pstrm_def->buf_alignment = pattrs->buf_alignment; - pstrm_def->timeout = pattrs->timeout; - } else { - pstrm_def->num_bufs = DEFAULTNBUFS; - pstrm_def->buf_size = - DEFAULTBUFSIZE / hnode_mgr->dsp_data_mau_size; - pstrm_def->seg_id = DEFAULTSEGID; - pstrm_def->buf_alignment = DEFAULTALIGNMENT; - pstrm_def->timeout = DEFAULTTIMEOUT; - } -} - -/* - * ======== free_stream ======== - * Purpose: - * Updates the channel mask and frees the pipe id. - */ -static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream) -{ - /* Free up the pipe id unless other node has not yet been deleted. */ - if (stream.type == NODECONNECT) { - if (test_bit(stream.dev_id, hnode_mgr->pipe_done_map)) { - /* The other node has already been deleted */ - clear_bit(stream.dev_id, hnode_mgr->pipe_done_map); - clear_bit(stream.dev_id, hnode_mgr->pipe_map); - } else { - /* The other node has not been deleted yet */ - set_bit(stream.dev_id, hnode_mgr->pipe_done_map); - } - } else if (stream.type == HOSTCONNECT) { - if (stream.dev_id < hnode_mgr->num_chnls) { - clear_bit(stream.dev_id, hnode_mgr->chnl_map); - } else if (stream.dev_id < (2 * hnode_mgr->num_chnls)) { - /* dsp-dma */ - clear_bit(stream.dev_id - (1 * hnode_mgr->num_chnls), - hnode_mgr->dma_chnl_map); - } else if (stream.dev_id < (3 * hnode_mgr->num_chnls)) { - /* zero-copy */ - clear_bit(stream.dev_id - (2 * hnode_mgr->num_chnls), - hnode_mgr->zc_chnl_map); - } - } -} - -/* - * ======== get_fxn_address ======== - * Purpose: - * Retrieves the address for create, execute or delete phase for a node. - */ -static int get_fxn_address(struct node_object *hnode, u32 *fxn_addr, - u32 phase) -{ - char *pstr_fxn_name = NULL; - struct node_mgr *hnode_mgr = hnode->node_mgr; - int status = 0; - - switch (phase) { - case CREATEPHASE: - pstr_fxn_name = - hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn; - break; - case EXECUTEPHASE: - pstr_fxn_name = - hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn; - break; - case DELETEPHASE: - pstr_fxn_name = - hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn; - break; - default: - /* Should never get here */ - break; - } - - status = - hnode_mgr->nldr_fxns.get_fxn_addr(hnode->nldr_node_obj, - pstr_fxn_name, fxn_addr); - - return status; -} - -/* - * ======== get_node_info ======== - * Purpose: - * Retrieves the node information. - */ -void get_node_info(struct node_object *hnode, struct dsp_nodeinfo *node_info) -{ - u32 i; - - node_info->cb_struct = sizeof(struct dsp_nodeinfo); - node_info->nb_node_database_props = - hnode->dcd_props.obj_data.node_obj.ndb_props; - node_info->execution_priority = hnode->prio; - node_info->device_owner = hnode->device_owner; - node_info->number_streams = hnode->num_inputs + hnode->num_outputs; - node_info->node_env = hnode->node_env; - - node_info->ns_execution_state = node_get_state(hnode); - - /* Copy stream connect data */ - for (i = 0; i < hnode->num_inputs + hnode->num_outputs; i++) - node_info->sc_stream_connection[i] = hnode->stream_connect[i]; - -} - -/* - * ======== get_node_props ======== - * Purpose: - * Retrieve node properties. - */ -static int get_node_props(struct dcd_manager *hdcd_mgr, - struct node_object *hnode, - const struct dsp_uuid *node_uuid, - struct dcd_genericobj *dcd_prop) -{ - u32 len; - struct node_msgargs *pmsg_args; - struct node_taskargs *task_arg_obj; - enum node_type node_type = NODE_TASK; - struct dsp_ndbprops *pndb_props = - &(dcd_prop->obj_data.node_obj.ndb_props); - int status = 0; - char sz_uuid[MAXUUIDLEN]; - - status = dcd_get_object_def(hdcd_mgr, (struct dsp_uuid *)node_uuid, - DSP_DCDNODETYPE, dcd_prop); - - if (!status) { - hnode->ntype = node_type = pndb_props->ntype; - - /* Create UUID value to set in registry. */ - snprintf(sz_uuid, MAXUUIDLEN, "%pUL", node_uuid); - dev_dbg(bridge, "(node) UUID: %s\n", sz_uuid); - - /* Fill in message args that come from NDB */ - if (node_type != NODE_DEVICE) { - pmsg_args = &(hnode->create_args.asa.node_msg_args); - pmsg_args->seg_id = - dcd_prop->obj_data.node_obj.msg_segid; - pmsg_args->notify_type = - dcd_prop->obj_data.node_obj.msg_notify_type; - pmsg_args->max_msgs = pndb_props->message_depth; - dev_dbg(bridge, "(node) Max Number of Messages: 0x%x\n", - pmsg_args->max_msgs); - } else { - /* Copy device name */ - len = strlen(pndb_props->ac_name); - hnode->str_dev_name = kzalloc(len + 1, GFP_KERNEL); - if (hnode->str_dev_name == NULL) { - status = -ENOMEM; - } else { - strncpy(hnode->str_dev_name, - pndb_props->ac_name, len); - } - } - } - if (!status) { - /* Fill in create args that come from NDB */ - if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) { - task_arg_obj = &(hnode->create_args.asa.task_arg_obj); - task_arg_obj->prio = pndb_props->prio; - task_arg_obj->stack_size = pndb_props->stack_size; - task_arg_obj->sys_stack_size = - pndb_props->sys_stack_size; - task_arg_obj->stack_seg = pndb_props->stack_seg; - dev_dbg(bridge, "(node) Priority: 0x%x Stack Size: " - "0x%x words System Stack Size: 0x%x words " - "Stack Segment: 0x%x profile count : 0x%x\n", - task_arg_obj->prio, task_arg_obj->stack_size, - task_arg_obj->sys_stack_size, - task_arg_obj->stack_seg, - pndb_props->count_profiles); - } - } - - return status; -} - -/* - * ======== get_proc_props ======== - * Purpose: - * Retrieve the processor properties. - */ -static int get_proc_props(struct node_mgr *hnode_mgr, - struct dev_object *hdev_obj) -{ - struct cfg_hostres *host_res; - struct bridge_dev_context *pbridge_context; - int status = 0; - - status = dev_get_bridge_context(hdev_obj, &pbridge_context); - if (!pbridge_context) - status = -EFAULT; - - if (!status) { - host_res = pbridge_context->resources; - if (!host_res) - return -EPERM; - hnode_mgr->chnl_offset = host_res->chnl_offset; - hnode_mgr->chnl_buf_size = host_res->chnl_buf_size; - hnode_mgr->num_chnls = host_res->num_chnls; - - /* - * PROC will add an API to get dsp_processorinfo. - * Fill in default values for now. - */ - /* TODO -- Instead of hard coding, take from registry */ - hnode_mgr->proc_family = 6000; - hnode_mgr->proc_type = 6410; - hnode_mgr->min_pri = DSP_NODE_MIN_PRIORITY; - hnode_mgr->max_pri = DSP_NODE_MAX_PRIORITY; - hnode_mgr->dsp_word_size = DSPWORDSIZE; - hnode_mgr->dsp_data_mau_size = DSPWORDSIZE; - hnode_mgr->dsp_mau_size = 1; - - } - return status; -} - -/* - * ======== node_get_uuid_props ======== - * Purpose: - * Fetch Node UUID properties from DCD/DOF file. - */ -int node_get_uuid_props(void *hprocessor, - const struct dsp_uuid *node_uuid, - struct dsp_ndbprops *node_props) -{ - struct node_mgr *hnode_mgr = NULL; - struct dev_object *hdev_obj; - int status = 0; - struct dcd_nodeprops dcd_node_props; - struct dsp_processorstate proc_state; - - if (hprocessor == NULL || node_uuid == NULL) { - status = -EFAULT; - goto func_end; - } - status = proc_get_state(hprocessor, &proc_state, - sizeof(struct dsp_processorstate)); - if (status) - goto func_end; - /* If processor is in error state then don't attempt - to send the message */ - if (proc_state.proc_state == PROC_ERROR) { - status = -EPERM; - goto func_end; - } - - status = proc_get_dev_object(hprocessor, &hdev_obj); - if (hdev_obj) { - status = dev_get_node_manager(hdev_obj, &hnode_mgr); - if (hnode_mgr == NULL) { - status = -EFAULT; - goto func_end; - } - } - - /* - * Enter the critical section. This is needed because - * dcd_get_object_def will ultimately end up calling dbll_open/close, - * which needs to be protected in order to not corrupt the zlib manager - * (COD). - */ - mutex_lock(&hnode_mgr->node_mgr_lock); - - dcd_node_props.str_create_phase_fxn = NULL; - dcd_node_props.str_execute_phase_fxn = NULL; - dcd_node_props.str_delete_phase_fxn = NULL; - dcd_node_props.str_i_alg_name = NULL; - - status = dcd_get_object_def(hnode_mgr->dcd_mgr, - (struct dsp_uuid *)node_uuid, DSP_DCDNODETYPE, - (struct dcd_genericobj *)&dcd_node_props); - - if (!status) { - *node_props = dcd_node_props.ndb_props; - kfree(dcd_node_props.str_create_phase_fxn); - - kfree(dcd_node_props.str_execute_phase_fxn); - - kfree(dcd_node_props.str_delete_phase_fxn); - - kfree(dcd_node_props.str_i_alg_name); - } - /* Leave the critical section, we're done. */ - mutex_unlock(&hnode_mgr->node_mgr_lock); -func_end: - return status; -} - -/* - * ======== get_rms_fxns ======== - * Purpose: - * Retrieve the RMS functions. - */ -static int get_rms_fxns(struct node_mgr *hnode_mgr) -{ - s32 i; - struct dev_object *dev_obj = hnode_mgr->dev_obj; - int status = 0; - - static char *psz_fxns[NUMRMSFXNS] = { - "RMS_queryServer", /* RMSQUERYSERVER */ - "RMS_configureServer", /* RMSCONFIGURESERVER */ - "RMS_createNode", /* RMSCREATENODE */ - "RMS_executeNode", /* RMSEXECUTENODE */ - "RMS_deleteNode", /* RMSDELETENODE */ - "RMS_changeNodePriority", /* RMSCHANGENODEPRIORITY */ - "RMS_readMemory", /* RMSREADMEMORY */ - "RMS_writeMemory", /* RMSWRITEMEMORY */ - "RMS_copy", /* RMSCOPY */ - }; - - for (i = 0; i < NUMRMSFXNS; i++) { - status = dev_get_symbol(dev_obj, psz_fxns[i], - &(hnode_mgr->fxn_addrs[i])); - if (status) { - if (status == -ESPIPE) { - /* - * May be loaded dynamically (in the future), - * but return an error for now. - */ - dev_dbg(bridge, "%s: RMS function: %s currently" - " not loaded\n", __func__, psz_fxns[i]); - } else { - dev_dbg(bridge, "%s: Symbol not found: %s " - "status = 0x%x\n", __func__, - psz_fxns[i], status); - break; - } - } - } - - return status; -} - -/* - * ======== ovly ======== - * Purpose: - * Called during overlay.Sends command to RMS to copy a block of data. - */ -static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr, - u32 ul_num_bytes, u32 mem_space) -{ - struct node_object *hnode = (struct node_object *)priv_ref; - struct node_mgr *hnode_mgr; - u32 ul_bytes = 0; - u32 ul_size; - u32 ul_timeout; - int status = 0; - struct bridge_dev_context *hbridge_context; - /* Function interface to Bridge driver*/ - struct bridge_drv_interface *intf_fxns; - - hnode_mgr = hnode->node_mgr; - - ul_size = ul_num_bytes / hnode_mgr->dsp_word_size; - ul_timeout = hnode->timeout; - - /* Call new MemCopy function */ - intf_fxns = hnode_mgr->intf_fxns; - status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context); - if (!status) { - status = - (*intf_fxns->brd_mem_copy) (hbridge_context, - dsp_run_addr, dsp_load_addr, - ul_num_bytes, (u32) mem_space); - if (!status) - ul_bytes = ul_num_bytes; - else - pr_debug("%s: failed to copy brd memory, status 0x%x\n", - __func__, status); - } else { - pr_debug("%s: failed to get Bridge context, status 0x%x\n", - __func__, status); - } - - return ul_bytes; -} - -/* - * ======== mem_write ======== - */ -static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf, - u32 ul_num_bytes, u32 mem_space) -{ - struct node_object *hnode = (struct node_object *)priv_ref; - struct node_mgr *hnode_mgr; - u16 mem_sect_type; - u32 ul_timeout; - int status = 0; - struct bridge_dev_context *hbridge_context; - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; - - hnode_mgr = hnode->node_mgr; - - ul_timeout = hnode->timeout; - mem_sect_type = (mem_space & DBLL_CODE) ? RMS_CODE : RMS_DATA; - - /* Call new MemWrite function */ - intf_fxns = hnode_mgr->intf_fxns; - status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context); - status = (*intf_fxns->brd_mem_write) (hbridge_context, pbuf, - dsp_add, ul_num_bytes, mem_sect_type); - - return ul_num_bytes; -} - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/* - * ======== node_find_addr ======== - */ -int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr, - u32 offset_range, void *sym_addr_output, char *sym_name) -{ - struct node_object *node_obj; - int status = -ENOENT; - - list_for_each_entry(node_obj, &node_mgr->node_list, list_elem) { - status = nldr_find_addr(node_obj->nldr_node_obj, sym_addr, - offset_range, sym_addr_output, sym_name); - if (!status) { - pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x, %s)\n", __func__, - (unsigned int) node_mgr, - sym_addr, offset_range, - (unsigned int) sym_addr_output, sym_name); - break; - } - } - - return status; -} -#endif diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c deleted file mode 100644 index cd5235a4f77..00000000000 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ /dev/null @@ -1,1833 +0,0 @@ -/* - * proc.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Processor interface at the driver level. - * - * 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. - */ - -#include <linux/types.h> -/* ------------------------------------ Host OS */ -#include <linux/dma-mapping.h> -#include <linux/scatterlist.h> -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/ntfy.h> -#include <dspbridge/sync.h> -/* ----------------------------------- Bridge Driver */ -#include <dspbridge/dspdefs.h> -#include <dspbridge/dspdeh.h> -/* ----------------------------------- Platform Manager */ -#include <dspbridge/cod.h> -#include <dspbridge/dev.h> -#include <dspbridge/procpriv.h> -#include <dspbridge/dmm.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/mgr.h> -#include <dspbridge/node.h> -#include <dspbridge/nldr.h> -#include <dspbridge/rmm.h> - -/* ----------------------------------- Others */ -#include <dspbridge/dbdcd.h> -#include <dspbridge/msg.h> -#include <dspbridge/dspioctl.h> -#include <dspbridge/drv.h> - -/* ----------------------------------- This */ -#include <dspbridge/proc.h> -#include <dspbridge/pwr.h> - -#include <dspbridge/resourcecleanup.h> -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define MAXCMDLINELEN 255 -#define PROC_ENVPROCID "PROC_ID=%d" -#define MAXPROCIDLEN (8 + 5) -#define PROC_DFLT_TIMEOUT 10000 /* Time out in milliseconds */ -#define PWR_TIMEOUT 500 /* Sleep/wake timout in msec */ -#define EXTEND "_EXT_END" /* Extmem end addr in DSP binary */ - -#define DSP_CACHE_LINE 128 - -#define BUFMODE_MASK (3 << 14) - -/* Buffer modes from DSP perspective */ -#define RBUF 0x4000 /* Input buffer */ -#define WBUF 0x8000 /* Output Buffer */ - -extern struct device *bridge; - -/* ----------------------------------- Globals */ - -/* The proc_object structure. */ -struct proc_object { - struct list_head link; /* Link to next proc_object */ - struct dev_object *dev_obj; /* Device this PROC represents */ - u32 process; /* Process owning this Processor */ - struct mgr_object *mgr_obj; /* Manager Object Handle */ - u32 attach_count; /* Processor attach count */ - u32 processor_id; /* Processor number */ - u32 timeout; /* Time out count */ - enum dsp_procstate proc_state; /* Processor state */ - u32 unit; /* DDSP unit number */ - bool is_already_attached; /* - * True if the Device below has - * GPP Client attached - */ - struct ntfy_object *ntfy_obj; /* Manages notifications */ - /* Bridge Context Handle */ - struct bridge_dev_context *bridge_context; - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; - char *last_coff; - struct list_head proc_list; -}; - -DEFINE_MUTEX(proc_lock); /* For critical sections */ - -/* ----------------------------------- Function Prototypes */ -static int proc_monitor(struct proc_object *proc_obj); -static s32 get_envp_count(char **envp); -static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems, - s32 cnew_envp, char *sz_var); - -/* remember mapping information */ -static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt, - u32 mpu_addr, u32 dsp_addr, u32 size) -{ - struct dmm_map_object *map_obj; - - u32 num_usr_pgs = size / PG_SIZE4K; - - pr_debug("%s: adding map info: mpu_addr 0x%x virt 0x%x size 0x%x\n", - __func__, mpu_addr, - dsp_addr, size); - - map_obj = kzalloc(sizeof(struct dmm_map_object), GFP_KERNEL); - if (!map_obj) - return NULL; - - INIT_LIST_HEAD(&map_obj->link); - - map_obj->pages = kcalloc(num_usr_pgs, sizeof(struct page *), - GFP_KERNEL); - if (!map_obj->pages) { - kfree(map_obj); - return NULL; - } - - map_obj->mpu_addr = mpu_addr; - map_obj->dsp_addr = dsp_addr; - map_obj->size = size; - map_obj->num_usr_pgs = num_usr_pgs; - - spin_lock(&pr_ctxt->dmm_map_lock); - list_add(&map_obj->link, &pr_ctxt->dmm_map_list); - spin_unlock(&pr_ctxt->dmm_map_lock); - - return map_obj; -} - -static int match_exact_map_obj(struct dmm_map_object *map_obj, - u32 dsp_addr, u32 size) -{ - if (map_obj->dsp_addr == dsp_addr && map_obj->size != size) - pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n", - __func__, dsp_addr, map_obj->size, size); - - return map_obj->dsp_addr == dsp_addr && - map_obj->size == size; -} - -static void remove_mapping_information(struct process_context *pr_ctxt, - u32 dsp_addr, u32 size) -{ - struct dmm_map_object *map_obj; - - pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__, - dsp_addr, size); - - spin_lock(&pr_ctxt->dmm_map_lock); - list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) { - pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n", - __func__, - map_obj->mpu_addr, - map_obj->dsp_addr, - map_obj->size); - - if (match_exact_map_obj(map_obj, dsp_addr, size)) { - pr_debug("%s: match, deleting map info\n", __func__); - list_del(&map_obj->link); - kfree(map_obj->dma_info.sg); - kfree(map_obj->pages); - kfree(map_obj); - goto out; - } - pr_debug("%s: candidate didn't match\n", __func__); - } - - pr_err("%s: failed to find given map info\n", __func__); -out: - spin_unlock(&pr_ctxt->dmm_map_lock); -} - -static int match_containing_map_obj(struct dmm_map_object *map_obj, - u32 mpu_addr, u32 size) -{ - u32 map_obj_end = map_obj->mpu_addr + map_obj->size; - - return mpu_addr >= map_obj->mpu_addr && - mpu_addr + size <= map_obj_end; -} - -static struct dmm_map_object *find_containing_mapping( - struct process_context *pr_ctxt, - u32 mpu_addr, u32 size) -{ - struct dmm_map_object *map_obj; - pr_debug("%s: looking for mpu_addr 0x%x size 0x%x\n", __func__, - mpu_addr, size); - - spin_lock(&pr_ctxt->dmm_map_lock); - list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) { - pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n", - __func__, - map_obj->mpu_addr, - map_obj->dsp_addr, - map_obj->size); - if (match_containing_map_obj(map_obj, mpu_addr, size)) { - pr_debug("%s: match!\n", __func__); - goto out; - } - - pr_debug("%s: no match!\n", __func__); - } - - map_obj = NULL; -out: - spin_unlock(&pr_ctxt->dmm_map_lock); - return map_obj; -} - -static int find_first_page_in_cache(struct dmm_map_object *map_obj, - unsigned long mpu_addr) -{ - u32 mapped_base_page = map_obj->mpu_addr >> PAGE_SHIFT; - u32 requested_base_page = mpu_addr >> PAGE_SHIFT; - int pg_index = requested_base_page - mapped_base_page; - - if (pg_index < 0 || pg_index >= map_obj->num_usr_pgs) { - pr_err("%s: failed (got %d)\n", __func__, pg_index); - return -1; - } - - pr_debug("%s: first page is %d\n", __func__, pg_index); - return pg_index; -} - -static inline struct page *get_mapping_page(struct dmm_map_object *map_obj, - int pg_i) -{ - pr_debug("%s: looking for pg_i %d, num_usr_pgs: %d\n", __func__, - pg_i, map_obj->num_usr_pgs); - - if (pg_i < 0 || pg_i >= map_obj->num_usr_pgs) { - pr_err("%s: requested pg_i %d is out of mapped range\n", - __func__, pg_i); - return NULL; - } - - return map_obj->pages[pg_i]; -} - -/* - * ======== proc_attach ======== - * Purpose: - * Prepare for communication with a particular DSP processor, and return - * a handle to the processor object. - */ -int -proc_attach(u32 processor_id, - const struct dsp_processorattrin *attr_in, - void **ph_processor, struct process_context *pr_ctxt) -{ - int status = 0; - struct dev_object *hdev_obj; - struct proc_object *p_proc_object = NULL; - struct mgr_object *hmgr_obj = NULL; - struct drv_object *hdrv_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - u8 dev_type; - - if (pr_ctxt->processor) { - *ph_processor = pr_ctxt->processor; - return status; - } - - /* Get the Driver and Manager Object Handles */ - if (!drv_datap || !drv_datap->drv_object || !drv_datap->mgr_object) { - status = -ENODATA; - pr_err("%s: Failed to get object handles\n", __func__); - } else { - hdrv_obj = drv_datap->drv_object; - hmgr_obj = drv_datap->mgr_object; - } - - if (!status) { - /* Get the Device Object */ - status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj); - } - if (!status) - status = dev_get_dev_type(hdev_obj, &dev_type); - - if (status) - goto func_end; - - /* If we made it this far, create the Processor object: */ - p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL); - /* Fill out the Processor Object: */ - if (p_proc_object == NULL) { - status = -ENOMEM; - goto func_end; - } - p_proc_object->dev_obj = hdev_obj; - p_proc_object->mgr_obj = hmgr_obj; - p_proc_object->processor_id = dev_type; - /* Store TGID instead of process handle */ - p_proc_object->process = current->tgid; - - INIT_LIST_HEAD(&p_proc_object->proc_list); - - if (attr_in) - p_proc_object->timeout = attr_in->timeout; - else - p_proc_object->timeout = PROC_DFLT_TIMEOUT; - - status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns); - if (!status) { - status = dev_get_bridge_context(hdev_obj, - &p_proc_object->bridge_context); - if (status) - kfree(p_proc_object); - } else - kfree(p_proc_object); - - if (status) - goto func_end; - - /* Create the Notification Object */ - /* This is created with no event mask, no notify mask - * and no valid handle to the notification. They all get - * filled up when proc_register_notify is called */ - p_proc_object->ntfy_obj = kmalloc(sizeof(struct ntfy_object), - GFP_KERNEL); - if (p_proc_object->ntfy_obj) - ntfy_init(p_proc_object->ntfy_obj); - else - status = -ENOMEM; - - if (!status) { - /* Insert the Processor Object into the DEV List. - * Return handle to this Processor Object: - * Find out if the Device is already attached to a - * Processor. If so, return AlreadyAttached status */ - status = dev_insert_proc_object(p_proc_object->dev_obj, - (u32) p_proc_object, - &p_proc_object-> - is_already_attached); - if (!status) { - if (p_proc_object->is_already_attached) - status = 0; - } else { - if (p_proc_object->ntfy_obj) { - ntfy_delete(p_proc_object->ntfy_obj); - kfree(p_proc_object->ntfy_obj); - } - - kfree(p_proc_object); - } - if (!status) { - *ph_processor = (void *)p_proc_object; - pr_ctxt->processor = *ph_processor; - (void)proc_notify_clients(p_proc_object, - DSP_PROCESSORATTACH); - } - } else { - /* Don't leak memory if status is failed */ - kfree(p_proc_object); - } -func_end: - return status; -} - -static int get_exec_file(struct cfg_devnode *dev_node_obj, - struct dev_object *hdev_obj, - u32 size, char *exec_file) -{ - u8 dev_type; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - dev_get_dev_type(hdev_obj, (u8 *) &dev_type); - - if (!exec_file) - return -EFAULT; - - if (dev_type == DSP_UNIT) { - if (!drv_datap || !drv_datap->base_img) - return -EFAULT; - - if (strlen(drv_datap->base_img) >= size) - return -EINVAL; - - strcpy(exec_file, drv_datap->base_img); - } else { - return -ENOENT; - } - - return 0; -} - -/* - * ======== proc_auto_start ======== = - * Purpose: - * A Particular device gets loaded with the default image - * if the AutoStart flag is set. - * Parameters: - * hdev_obj: Handle to the Device - * Returns: - * 0: On Successful Loading - * -EPERM General Failure - * Requires: - * hdev_obj != NULL - * Ensures: - */ -int proc_auto_start(struct cfg_devnode *dev_node_obj, - struct dev_object *hdev_obj) -{ - int status = -EPERM; - struct proc_object *p_proc_object; - char sz_exec_file[MAXCMDLINELEN]; - char *argv[2]; - struct mgr_object *hmgr_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - u8 dev_type; - - /* Create a Dummy PROC Object */ - if (!drv_datap || !drv_datap->mgr_object) { - status = -ENODATA; - pr_err("%s: Failed to retrieve the object handle\n", __func__); - goto func_end; - } else { - hmgr_obj = drv_datap->mgr_object; - } - - p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL); - if (p_proc_object == NULL) { - status = -ENOMEM; - goto func_end; - } - p_proc_object->dev_obj = hdev_obj; - p_proc_object->mgr_obj = hmgr_obj; - status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns); - if (!status) - status = dev_get_bridge_context(hdev_obj, - &p_proc_object->bridge_context); - if (status) - goto func_cont; - - /* Stop the Device, put it into standby mode */ - status = proc_stop(p_proc_object); - - if (status) - goto func_cont; - - /* Get the default executable for this board... */ - dev_get_dev_type(hdev_obj, (u8 *) &dev_type); - p_proc_object->processor_id = dev_type; - status = get_exec_file(dev_node_obj, hdev_obj, sizeof(sz_exec_file), - sz_exec_file); - if (!status) { - argv[0] = sz_exec_file; - argv[1] = NULL; - /* ...and try to load it: */ - status = proc_load(p_proc_object, 1, (const char **)argv, NULL); - if (!status) - status = proc_start(p_proc_object); - } - kfree(p_proc_object->last_coff); - p_proc_object->last_coff = NULL; -func_cont: - kfree(p_proc_object); -func_end: - return status; -} - -/* - * ======== proc_ctrl ======== - * Purpose: - * Pass control information to the GPP device driver managing the - * DSP processor. - * - * This will be an OEM-only function, and not part of the DSP/BIOS Bridge - * application developer's API. - * Call the bridge_dev_ctrl fxn with the Argument. This is a Synchronous - * Operation. arg can be null. - */ -int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata *arg) -{ - int status = 0; - struct proc_object *p_proc_object = hprocessor; - u32 timeout = 0; - - if (p_proc_object) { - /* intercept PWR deep sleep command */ - if (dw_cmd == BRDIOCTL_DEEPSLEEP) { - timeout = arg->cb_data; - status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout); - } - /* intercept PWR emergency sleep command */ - else if (dw_cmd == BRDIOCTL_EMERGENCYSLEEP) { - timeout = arg->cb_data; - status = pwr_sleep_dsp(PWR_EMERGENCYDEEPSLEEP, timeout); - } else if (dw_cmd == PWR_DEEPSLEEP) { - /* timeout = arg->cb_data; */ - status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout); - } - /* intercept PWR wake commands */ - else if (dw_cmd == BRDIOCTL_WAKEUP) { - timeout = arg->cb_data; - status = pwr_wake_dsp(timeout); - } else if (dw_cmd == PWR_WAKEUP) { - /* timeout = arg->cb_data; */ - status = pwr_wake_dsp(timeout); - } else - if (!((*p_proc_object->intf_fxns->dev_cntrl) - (p_proc_object->bridge_context, dw_cmd, - arg))) { - status = 0; - } else { - status = -EPERM; - } - } else { - status = -EFAULT; - } - - return status; -} - -/* - * ======== proc_detach ======== - * Purpose: - * Destroys the Processor Object. Removes the notification from the Dev - * List. - */ -int proc_detach(struct process_context *pr_ctxt) -{ - int status = 0; - struct proc_object *p_proc_object = NULL; - - p_proc_object = (struct proc_object *)pr_ctxt->processor; - - if (p_proc_object) { - /* Notify the Client */ - ntfy_notify(p_proc_object->ntfy_obj, DSP_PROCESSORDETACH); - /* Remove the notification memory */ - if (p_proc_object->ntfy_obj) { - ntfy_delete(p_proc_object->ntfy_obj); - kfree(p_proc_object->ntfy_obj); - } - - kfree(p_proc_object->last_coff); - p_proc_object->last_coff = NULL; - /* Remove the Proc from the DEV List */ - (void)dev_remove_proc_object(p_proc_object->dev_obj, - (u32) p_proc_object); - /* Free the Processor Object */ - kfree(p_proc_object); - pr_ctxt->processor = NULL; - } else { - status = -EFAULT; - } - - return status; -} - -/* - * ======== proc_enum_nodes ======== - * Purpose: - * Enumerate and get configuration information about nodes allocated - * on a DSP processor. - */ -int proc_enum_nodes(void *hprocessor, void **node_tab, - u32 node_tab_size, u32 *pu_num_nodes, - u32 *pu_allocated) -{ - int status = -EPERM; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct node_mgr *hnode_mgr = NULL; - - if (p_proc_object) { - if (!(dev_get_node_manager(p_proc_object->dev_obj, - &hnode_mgr))) { - if (hnode_mgr) { - status = node_enum_nodes(hnode_mgr, node_tab, - node_tab_size, - pu_num_nodes, - pu_allocated); - } - } - } else { - status = -EFAULT; - } - - return status; -} - -/* Cache operation against kernel address instead of users */ -static int build_dma_sg(struct dmm_map_object *map_obj, unsigned long start, - ssize_t len, int pg_i) -{ - struct page *page; - unsigned long offset; - ssize_t rest; - int ret = 0, i = 0; - struct scatterlist *sg = map_obj->dma_info.sg; - - while (len) { - page = get_mapping_page(map_obj, pg_i); - if (!page) { - pr_err("%s: no page for %08lx\n", __func__, start); - ret = -EINVAL; - goto out; - } else if (IS_ERR(page)) { - pr_err("%s: err page for %08lx(%lu)\n", __func__, start, - PTR_ERR(page)); - ret = PTR_ERR(page); - goto out; - } - - offset = start & ~PAGE_MASK; - rest = min_t(ssize_t, PAGE_SIZE - offset, len); - - sg_set_page(&sg[i], page, rest, offset); - - len -= rest; - start += rest; - pg_i++, i++; - } - - if (i != map_obj->dma_info.num_pages) { - pr_err("%s: bad number of sg iterations\n", __func__); - ret = -EFAULT; - goto out; - } - -out: - return ret; -} - -static int memory_regain_ownership(struct dmm_map_object *map_obj, - unsigned long start, ssize_t len, enum dma_data_direction dir) -{ - int ret = 0; - unsigned long first_data_page = start >> PAGE_SHIFT; - unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT); - /* calculating the number of pages this area spans */ - unsigned long num_pages = last_data_page - first_data_page + 1; - struct bridge_dma_map_info *dma_info = &map_obj->dma_info; - - if (!dma_info->sg) - goto out; - - if (dma_info->dir != dir || dma_info->num_pages != num_pages) { - pr_err("%s: dma info doesn't match given params\n", __func__); - return -EINVAL; - } - - dma_unmap_sg(bridge, dma_info->sg, num_pages, dma_info->dir); - - pr_debug("%s: dma_map_sg unmapped\n", __func__); - - kfree(dma_info->sg); - - map_obj->dma_info.sg = NULL; - -out: - return ret; -} - -/* Cache operation against kernel address instead of users */ -static int memory_give_ownership(struct dmm_map_object *map_obj, - unsigned long start, ssize_t len, enum dma_data_direction dir) -{ - int pg_i, ret, sg_num; - struct scatterlist *sg; - unsigned long first_data_page = start >> PAGE_SHIFT; - unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT); - /* calculating the number of pages this area spans */ - unsigned long num_pages = last_data_page - first_data_page + 1; - - pg_i = find_first_page_in_cache(map_obj, start); - if (pg_i < 0) { - pr_err("%s: failed to find first page in cache\n", __func__); - ret = -EINVAL; - goto out; - } - - sg = kcalloc(num_pages, sizeof(*sg), GFP_KERNEL); - if (!sg) { - ret = -ENOMEM; - goto out; - } - - sg_init_table(sg, num_pages); - - /* cleanup a previous sg allocation */ - /* this may happen if application doesn't signal for e/o DMA */ - kfree(map_obj->dma_info.sg); - - map_obj->dma_info.sg = sg; - map_obj->dma_info.dir = dir; - map_obj->dma_info.num_pages = num_pages; - - ret = build_dma_sg(map_obj, start, len, pg_i); - if (ret) - goto kfree_sg; - - sg_num = dma_map_sg(bridge, sg, num_pages, dir); - if (sg_num < 1) { - pr_err("%s: dma_map_sg failed: %d\n", __func__, sg_num); - ret = -EFAULT; - goto kfree_sg; - } - - pr_debug("%s: dma_map_sg mapped %d elements\n", __func__, sg_num); - map_obj->dma_info.sg_num = sg_num; - - return 0; - -kfree_sg: - kfree(sg); - map_obj->dma_info.sg = NULL; -out: - return ret; -} - -int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, - enum dma_data_direction dir) -{ - /* Keep STATUS here for future additions to this function */ - int status = 0; - struct process_context *pr_ctxt = (struct process_context *) hprocessor; - struct dmm_map_object *map_obj; - - if (!pr_ctxt) { - status = -EFAULT; - goto err_out; - } - - pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__, - (u32)pmpu_addr, - ul_size, dir); - - mutex_lock(&proc_lock); - - /* find requested memory are in cached mapping information */ - map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); - if (!map_obj) { - pr_err("%s: find_containing_mapping failed\n", __func__); - status = -EFAULT; - goto no_map; - } - - if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { - pr_err("%s: InValid address parameters %p %x\n", - __func__, pmpu_addr, ul_size); - status = -EFAULT; - } - -no_map: - mutex_unlock(&proc_lock); -err_out: - - return status; -} - -int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, - enum dma_data_direction dir) -{ - /* Keep STATUS here for future additions to this function */ - int status = 0; - struct process_context *pr_ctxt = (struct process_context *) hprocessor; - struct dmm_map_object *map_obj; - - if (!pr_ctxt) { - status = -EFAULT; - goto err_out; - } - - pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__, - (u32)pmpu_addr, - ul_size, dir); - - mutex_lock(&proc_lock); - - /* find requested memory are in cached mapping information */ - map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); - if (!map_obj) { - pr_err("%s: find_containing_mapping failed\n", __func__); - status = -EFAULT; - goto no_map; - } - - if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { - pr_err("%s: InValid address parameters %p %x\n", - __func__, pmpu_addr, ul_size); - status = -EFAULT; - } - -no_map: - mutex_unlock(&proc_lock); -err_out: - return status; -} - -/* - * ======== proc_flush_memory ======== - * Purpose: - * Flush cache - */ -int proc_flush_memory(void *hprocessor, void *pmpu_addr, - u32 ul_size, u32 ul_flags) -{ - enum dma_data_direction dir = DMA_BIDIRECTIONAL; - - return proc_begin_dma(hprocessor, pmpu_addr, ul_size, dir); -} - -/* - * ======== proc_invalidate_memory ======== - * Purpose: - * Invalidates the memory specified - */ -int proc_invalidate_memory(void *hprocessor, void *pmpu_addr, u32 size) -{ - enum dma_data_direction dir = DMA_FROM_DEVICE; - - return proc_begin_dma(hprocessor, pmpu_addr, size, dir); -} - -/* - * ======== proc_get_resource_info ======== - * Purpose: - * Enumerate the resources currently available on a processor. - */ -int proc_get_resource_info(void *hprocessor, u32 resource_type, - struct dsp_resourceinfo *resource_info, - u32 resource_info_size) -{ - int status = -EPERM; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct node_mgr *hnode_mgr = NULL; - struct nldr_object *nldr_obj = NULL; - struct rmm_target_obj *rmm = NULL; - struct io_mgr *hio_mgr = NULL; /* IO manager handle */ - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - switch (resource_type) { - case DSP_RESOURCE_DYNDARAM: - case DSP_RESOURCE_DYNSARAM: - case DSP_RESOURCE_DYNEXTERNAL: - case DSP_RESOURCE_DYNSRAM: - status = dev_get_node_manager(p_proc_object->dev_obj, - &hnode_mgr); - if (!hnode_mgr) { - status = -EFAULT; - goto func_end; - } - - status = node_get_nldr_obj(hnode_mgr, &nldr_obj); - if (!status) { - status = nldr_get_rmm_manager(nldr_obj, &rmm); - if (rmm) { - if (!rmm_stat(rmm, - (enum dsp_memtype)resource_type, - (struct dsp_memstat *) - &(resource_info->result. - mem_stat))) - status = -EINVAL; - } else { - status = -EFAULT; - } - } - break; - case DSP_RESOURCE_PROCLOAD: - status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr); - if (hio_mgr) - status = - p_proc_object->intf_fxns-> - io_get_proc_load(hio_mgr, - (struct dsp_procloadstat *) - &(resource_info->result. - proc_load_stat)); - else - status = -EFAULT; - break; - default: - status = -EPERM; - break; - } -func_end: - return status; -} - -/* - * ======== proc_get_dev_object ======== - * Purpose: - * Return the Dev Object handle for a given Processor. - * - */ -int proc_get_dev_object(void *hprocessor, - struct dev_object **device_obj) -{ - int status = -EPERM; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - - if (p_proc_object) { - *device_obj = p_proc_object->dev_obj; - status = 0; - } else { - *device_obj = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== proc_get_state ======== - * Purpose: - * Report the state of the specified DSP processor. - */ -int proc_get_state(void *hprocessor, - struct dsp_processorstate *proc_state_obj, - u32 state_info_size) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - int brd_status; - - if (p_proc_object) { - /* First, retrieve BRD state information */ - status = (*p_proc_object->intf_fxns->brd_status) - (p_proc_object->bridge_context, &brd_status); - if (!status) { - switch (brd_status) { - case BRD_STOPPED: - proc_state_obj->proc_state = PROC_STOPPED; - break; - case BRD_SLEEP_TRANSITION: - case BRD_DSP_HIBERNATION: - /* Fall through */ - case BRD_RUNNING: - proc_state_obj->proc_state = PROC_RUNNING; - break; - case BRD_LOADED: - proc_state_obj->proc_state = PROC_LOADED; - break; - case BRD_ERROR: - proc_state_obj->proc_state = PROC_ERROR; - break; - default: - proc_state_obj->proc_state = 0xFF; - status = -EPERM; - break; - } - } - } else { - status = -EFAULT; - } - dev_dbg(bridge, "%s, results: status: 0x%x proc_state_obj: 0x%x\n", - __func__, status, proc_state_obj->proc_state); - return status; -} - -/* - * ======== proc_get_trace ======== - * Purpose: - * Retrieve the current contents of the trace buffer, located on the - * Processor. Predefined symbols for the trace buffer must have been - * configured into the DSP executable. - * Details: - * We support using the symbols SYS_PUTCBEG and SYS_PUTCEND to define a - * trace buffer, only. Treat it as an undocumented feature. - * This call is destructive, meaning the processor is placed in the monitor - * state as a result of this function. - */ -int proc_get_trace(void *hprocessor, u8 *pbuf, u32 max_size) -{ - int status; - status = -ENOSYS; - return status; -} - -/* - * ======== proc_load ======== - * Purpose: - * Reset a processor and load a new base program image. - * This will be an OEM-only function, and not part of the DSP/BIOS Bridge - * application developer's API. - */ -int proc_load(void *hprocessor, const s32 argc_index, - const char **user_args, const char **user_envp) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct io_mgr *hio_mgr; /* IO manager handle */ - struct msg_mgr *hmsg_mgr; - struct cod_manager *cod_mgr; /* Code manager handle */ - char *pargv0; /* temp argv[0] ptr */ - char **new_envp; /* Updated envp[] array. */ - char sz_proc_id[MAXPROCIDLEN]; /* Size of "PROC_ID=<n>" */ - s32 envp_elems; /* Num elements in envp[]. */ - s32 cnew_envp; /* " " in new_envp[] */ - s32 nproc_id = 0; /* Anticipate MP version. */ - struct dcd_manager *hdcd_handle; - struct dmm_object *dmm_mgr; - u32 dw_ext_end; - u32 proc_id; - int brd_state; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - -#ifdef OPT_LOAD_TIME_INSTRUMENTATION - struct timeval tv1; - struct timeval tv2; -#endif - -#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) - struct dspbridge_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; -#endif - -#ifdef OPT_LOAD_TIME_INSTRUMENTATION - do_gettimeofday(&tv1); -#endif - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr); - if (!cod_mgr) { - status = -EPERM; - goto func_end; - } - status = proc_stop(hprocessor); - if (status) - goto func_end; - - /* Place the board in the monitor state. */ - status = proc_monitor(hprocessor); - if (status) - goto func_end; - - /* Save ptr to original argv[0]. */ - pargv0 = (char *)user_args[0]; - /*Prepend "PROC_ID=<nproc_id>"to envp array for target. */ - envp_elems = get_envp_count((char **)user_envp); - cnew_envp = (envp_elems ? (envp_elems + 1) : (envp_elems + 2)); - new_envp = kzalloc(cnew_envp * sizeof(char **), GFP_KERNEL); - if (new_envp) { - status = snprintf(sz_proc_id, MAXPROCIDLEN, PROC_ENVPROCID, - nproc_id); - if (status == -1) { - dev_dbg(bridge, "%s: Proc ID string overflow\n", - __func__); - status = -EPERM; - } else { - new_envp = - prepend_envp(new_envp, (char **)user_envp, - envp_elems, cnew_envp, sz_proc_id); - /* Get the DCD Handle */ - status = mgr_get_dcd_handle(p_proc_object->mgr_obj, - (u32 *) &hdcd_handle); - if (!status) { - /* Before proceeding with new load, - * check if a previously registered COFF - * exists. - * If yes, unregister nodes in previously - * registered COFF. If any error occurred, - * set previously registered COFF to NULL. */ - if (p_proc_object->last_coff != NULL) { - status = - dcd_auto_unregister(hdcd_handle, - p_proc_object-> - last_coff); - /* Regardless of auto unregister status, - * free previously allocated - * memory. */ - kfree(p_proc_object->last_coff); - p_proc_object->last_coff = NULL; - } - } - /* On success, do cod_open_base() */ - status = cod_open_base(cod_mgr, (char *)user_args[0], - COD_SYMB); - } - } else { - status = -ENOMEM; - } - if (!status) { - /* Auto-register data base */ - /* Get the DCD Handle */ - status = mgr_get_dcd_handle(p_proc_object->mgr_obj, - (u32 *) &hdcd_handle); - if (!status) { - /* Auto register nodes in specified COFF - * file. If registration did not fail, - * (status = 0 or -EACCES) - * save the name of the COFF file for - * de-registration in the future. */ - status = - dcd_auto_register(hdcd_handle, - (char *)user_args[0]); - if (status == -EACCES) - status = 0; - - if (status) { - status = -EPERM; - } else { - /* Allocate memory for pszLastCoff */ - p_proc_object->last_coff = - kzalloc((strlen(user_args[0]) + - 1), GFP_KERNEL); - /* If memory allocated, save COFF file name */ - if (p_proc_object->last_coff) { - strncpy(p_proc_object->last_coff, - (char *)user_args[0], - (strlen((char *)user_args[0]) + - 1)); - } - } - } - } - /* Update shared memory address and size */ - if (!status) { - /* Create the message manager. This must be done - * before calling the IOOnLoaded function. */ - dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr); - if (!hmsg_mgr) { - status = msg_create(&hmsg_mgr, p_proc_object->dev_obj, - (msg_onexit) node_on_exit); - dev_set_msg_mgr(p_proc_object->dev_obj, hmsg_mgr); - } - } - if (!status) { - /* Set the Device object's message manager */ - status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr); - if (hio_mgr) - status = (*p_proc_object->intf_fxns->io_on_loaded) - (hio_mgr); - else - status = -EFAULT; - } - if (!status) { - /* Now, attempt to load an exec: */ - - /* Boost the OPP level to Maximum level supported by baseport */ -#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) - if (pdata->cpu_set_freq) - (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP5]); -#endif - status = cod_load_base(cod_mgr, argc_index, (char **)user_args, - dev_brd_write_fxn, - p_proc_object->dev_obj, NULL); - if (status) { - if (status == -EBADF) { - dev_dbg(bridge, "%s: Failure to Load the EXE\n", - __func__); - } - if (status == -ESPIPE) { - pr_err("%s: Couldn't parse the file\n", - __func__); - } - } - /* Requesting the lowest opp supported */ -#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) - if (pdata->cpu_set_freq) - (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]); -#endif - - } - if (!status) { - /* Update the Processor status to loaded */ - status = (*p_proc_object->intf_fxns->brd_set_state) - (p_proc_object->bridge_context, BRD_LOADED); - if (!status) { - p_proc_object->proc_state = PROC_LOADED; - if (p_proc_object->ntfy_obj) - proc_notify_clients(p_proc_object, - DSP_PROCESSORSTATECHANGE); - } - } - if (!status) { - status = proc_get_processor_id(hprocessor, &proc_id); - if (proc_id == DSP_UNIT) { - /* Use all available DSP address space after EXTMEM - * for DMM */ - if (!status) - status = cod_get_sym_value(cod_mgr, EXTEND, - &dw_ext_end); - - /* Reset DMM structs and add an initial free chunk */ - if (!status) { - status = - dev_get_dmm_mgr(p_proc_object->dev_obj, - &dmm_mgr); - if (dmm_mgr) { - /* Set dw_ext_end to DMM START u8 - * address */ - dw_ext_end = - (dw_ext_end + 1) * DSPWORDSIZE; - /* DMM memory is from EXT_END */ - status = dmm_create_tables(dmm_mgr, - dw_ext_end, - DMMPOOLSIZE); - } else { - status = -EFAULT; - } - } - } - } - /* Restore the original argv[0] */ - kfree(new_envp); - user_args[0] = pargv0; - if (!status) { - if (!((*p_proc_object->intf_fxns->brd_status) - (p_proc_object->bridge_context, &brd_state))) { - pr_info("%s: Processor Loaded %s\n", __func__, pargv0); - kfree(drv_datap->base_img); - drv_datap->base_img = kstrdup(pargv0, GFP_KERNEL); - if (!drv_datap->base_img) - status = -ENOMEM; - } - } - -func_end: - if (status) { - pr_err("%s: Processor failed to load\n", __func__); - proc_stop(p_proc_object); - } -#ifdef OPT_LOAD_TIME_INSTRUMENTATION - do_gettimeofday(&tv2); - if (tv2.tv_usec < tv1.tv_usec) { - tv2.tv_usec += 1000000; - tv2.tv_sec--; - } - dev_dbg(bridge, "%s: time to load %d sec and %d usec\n", __func__, - tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec); -#endif - return status; -} - -/* - * ======== proc_map ======== - * Purpose: - * Maps a MPU buffer to DSP address space. - */ -int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, - void *req_addr, void **pp_map_addr, u32 ul_map_attr, - struct process_context *pr_ctxt) -{ - u32 va_align; - u32 pa_align; - struct dmm_object *dmm_mgr; - u32 size_align; - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_map_object *map_obj; - u32 tmp_addr = 0; - -#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK - if ((ul_map_attr & BUFMODE_MASK) != RBUF) { - if (!IS_ALIGNED((u32)pmpu_addr, DSP_CACHE_LINE) || - !IS_ALIGNED(ul_size, DSP_CACHE_LINE)) { - pr_err("%s: not aligned: 0x%x (%d)\n", __func__, - (u32)pmpu_addr, ul_size); - return -EFAULT; - } - } -#endif - - /* Calculate the page-aligned PA, VA and size */ - va_align = PG_ALIGN_LOW((u32) req_addr, PG_SIZE4K); - pa_align = PG_ALIGN_LOW((u32) pmpu_addr, PG_SIZE4K); - size_align = PG_ALIGN_HIGH(ul_size + (u32) pmpu_addr - pa_align, - PG_SIZE4K); - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - /* Critical section */ - mutex_lock(&proc_lock); - dmm_get_handle(p_proc_object, &dmm_mgr); - if (dmm_mgr) - status = dmm_map_memory(dmm_mgr, va_align, size_align); - else - status = -EFAULT; - - /* Add mapping to the page tables. */ - if (!status) { - - /* Mapped address = MSB of VA | LSB of PA */ - tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1))); - /* mapped memory resource tracking */ - map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr, - size_align); - if (!map_obj) - status = -ENOMEM; - else - status = (*p_proc_object->intf_fxns->brd_mem_map) - (p_proc_object->bridge_context, pa_align, va_align, - size_align, ul_map_attr, map_obj->pages); - } - if (!status) { - /* Mapped address = MSB of VA | LSB of PA */ - *pp_map_addr = (void *) tmp_addr; - } else { - remove_mapping_information(pr_ctxt, tmp_addr, size_align); - dmm_un_map_memory(dmm_mgr, va_align, &size_align); - } - mutex_unlock(&proc_lock); - - if (status) - goto func_end; - -func_end: - dev_dbg(bridge, "%s: hprocessor %p, pmpu_addr %p, ul_size %x, " - "req_addr %p, ul_map_attr %x, pp_map_addr %p, va_align %x, " - "pa_align %x, size_align %x status 0x%x\n", __func__, - hprocessor, pmpu_addr, ul_size, req_addr, ul_map_attr, - pp_map_addr, va_align, pa_align, size_align, status); - - return status; -} - -/* - * ======== proc_register_notify ======== - * Purpose: - * Register to be notified of specific processor events. - */ -int proc_register_notify(void *hprocessor, u32 event_mask, - u32 notify_type, struct dsp_notification - *hnotification) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct deh_mgr *hdeh_mgr; - - /* Check processor handle */ - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - /* Check if event mask is a valid processor related event */ - if (event_mask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH | - DSP_PROCESSORDETACH | DSP_PROCESSORRESTART | - DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR | - DSP_WDTOVERFLOW)) - status = -EINVAL; - - /* Check if notify type is valid */ - if (notify_type != DSP_SIGNALEVENT) - status = -EINVAL; - - if (!status) { - /* If event mask is not DSP_SYSERROR, DSP_MMUFAULT, - * or DSP_PWRERROR then register event immediately. */ - if (event_mask & - ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR | - DSP_WDTOVERFLOW)) { - status = ntfy_register(p_proc_object->ntfy_obj, - hnotification, event_mask, - notify_type); - /* Special case alert, special case alert! - * If we're trying to *deregister* (i.e. event_mask - * is 0), a DSP_SYSERROR or DSP_MMUFAULT notification, - * we have to deregister with the DEH manager. - * There's no way to know, based on event_mask which - * manager the notification event was registered with, - * so if we're trying to deregister and ntfy_register - * failed, we'll give the deh manager a shot. - */ - if ((event_mask == 0) && status) { - status = - dev_get_deh_mgr(p_proc_object->dev_obj, - &hdeh_mgr); - status = - bridge_deh_register_notify(hdeh_mgr, - event_mask, - notify_type, - hnotification); - } - } else { - status = dev_get_deh_mgr(p_proc_object->dev_obj, - &hdeh_mgr); - status = - bridge_deh_register_notify(hdeh_mgr, - event_mask, - notify_type, - hnotification); - - } - } -func_end: - return status; -} - -/* - * ======== proc_reserve_memory ======== - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - */ -int proc_reserve_memory(void *hprocessor, u32 ul_size, - void **pp_rsv_addr, - struct process_context *pr_ctxt) -{ - struct dmm_object *dmm_mgr; - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - - status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr); - if (status != 0) - goto func_end; - - /* - * A successful reserve should be followed by insertion of rsv_obj - * into dmm_rsv_list, so that reserved memory resource tracking - * remains uptodate - */ - rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL); - if (rsv_obj) { - rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr; - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list); - spin_unlock(&pr_ctxt->dmm_rsv_lock); - } - -func_end: - dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p " - "status 0x%x\n", __func__, hprocessor, - ul_size, pp_rsv_addr, status); - return status; -} - -/* - * ======== proc_start ======== - * Purpose: - * Start a processor running. - */ -int proc_start(void *hprocessor) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct cod_manager *cod_mgr; /* Code manager handle */ - u32 dw_dsp_addr; /* Loaded code's entry point. */ - int brd_state; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - /* Call the bridge_brd_start */ - if (p_proc_object->proc_state != PROC_LOADED) { - status = -EBADR; - goto func_end; - } - status = dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr); - if (!cod_mgr) { - status = -EFAULT; - goto func_cont; - } - - status = cod_get_entry(cod_mgr, &dw_dsp_addr); - if (status) - goto func_cont; - - status = (*p_proc_object->intf_fxns->brd_start) - (p_proc_object->bridge_context, dw_dsp_addr); - if (status) - goto func_cont; - - /* Call dev_create2 */ - status = dev_create2(p_proc_object->dev_obj); - if (!status) { - p_proc_object->proc_state = PROC_RUNNING; - /* Deep sleep switces off the peripheral clocks. - * we just put the DSP CPU in idle in the idle loop. - * so there is no need to send a command to DSP */ - - if (p_proc_object->ntfy_obj) { - proc_notify_clients(p_proc_object, - DSP_PROCESSORSTATECHANGE); - } - } else { - /* Failed to Create Node Manager and DISP Object - * Stop the Processor from running. Put it in STOPPED State */ - (void)(*p_proc_object->intf_fxns-> - brd_stop) (p_proc_object->bridge_context); - p_proc_object->proc_state = PROC_STOPPED; - } -func_cont: - if (!status) { - if (!((*p_proc_object->intf_fxns->brd_status) - (p_proc_object->bridge_context, &brd_state))) { - pr_info("%s: dsp in running state\n", __func__); - } - } else { - pr_err("%s: Failed to start the dsp\n", __func__); - proc_stop(p_proc_object); - } - -func_end: - return status; -} - -/* - * ======== proc_stop ======== - * Purpose: - * Stop a processor running. - */ -int proc_stop(void *hprocessor) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct msg_mgr *hmsg_mgr; - struct node_mgr *hnode_mgr; - void *hnode; - u32 node_tab_size = 1; - u32 num_nodes = 0; - u32 nodes_allocated = 0; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - /* check if there are any running nodes */ - status = dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr); - if (!status && hnode_mgr) { - status = node_enum_nodes(hnode_mgr, &hnode, node_tab_size, - &num_nodes, &nodes_allocated); - if ((status == -EINVAL) || (nodes_allocated > 0)) { - pr_err("%s: Can't stop device, active nodes = %d\n", - __func__, nodes_allocated); - return -EBADR; - } - } - /* Call the bridge_brd_stop */ - /* It is OK to stop a device that does n't have nodes OR not started */ - status = - (*p_proc_object->intf_fxns-> - brd_stop) (p_proc_object->bridge_context); - if (!status) { - dev_dbg(bridge, "%s: processor in standby mode\n", __func__); - p_proc_object->proc_state = PROC_STOPPED; - /* Destroy the Node Manager, msg_ctrl Manager */ - if (!(dev_destroy2(p_proc_object->dev_obj))) { - /* Destroy the msg_ctrl by calling msg_delete */ - dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr); - if (hmsg_mgr) { - msg_delete(hmsg_mgr); - dev_set_msg_mgr(p_proc_object->dev_obj, NULL); - } - } - } else { - pr_err("%s: Failed to stop the processor\n", __func__); - } -func_end: - - return status; -} - -/* - * ======== proc_un_map ======== - * Purpose: - * Removes a MPU buffer mapping from the DSP address space. - */ -int proc_un_map(void *hprocessor, void *map_addr, - struct process_context *pr_ctxt) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_object *dmm_mgr; - u32 va_align; - u32 size_align; - - va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K); - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - status = dmm_get_handle(hprocessor, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - - /* Critical section */ - mutex_lock(&proc_lock); - /* - * Update DMM structures. Get the size to unmap. - * This function returns error if the VA is not mapped - */ - status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align); - /* Remove mapping from the page tables. */ - if (!status) { - status = (*p_proc_object->intf_fxns->brd_mem_un_map) - (p_proc_object->bridge_context, va_align, size_align); - } - - if (status) - goto unmap_failed; - - /* - * A successful unmap should be followed by removal of map_obj - * from dmm_map_list, so that mapped memory resource tracking - * remains uptodate - */ - remove_mapping_information(pr_ctxt, (u32) map_addr, size_align); - -unmap_failed: - mutex_unlock(&proc_lock); - -func_end: - dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", - __func__, hprocessor, map_addr, status); - return status; -} - -/* - * ======== proc_un_reserve_memory ======== - * Purpose: - * Frees a previously reserved region of DSP address space. - */ -int proc_un_reserve_memory(void *hprocessor, void *prsv_addr, - struct process_context *pr_ctxt) -{ - struct dmm_object *dmm_mgr; - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - - status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr); - if (status != 0) - goto func_end; - - /* - * A successful unreserve should be followed by removal of rsv_obj - * from dmm_rsv_list, so that reserved memory resource tracking - * remains uptodate - */ - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) { - if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) { - list_del(&rsv_obj->link); - kfree(rsv_obj); - break; - } - } - spin_unlock(&pr_ctxt->dmm_rsv_lock); - -func_end: - dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n", - __func__, hprocessor, prsv_addr, status); - return status; -} - -/* - * ======== = proc_monitor ======== == - * Purpose: - * Place the Processor in Monitor State. This is an internal - * function and a requirement before Processor is loaded. - * This does a bridge_brd_stop, dev_destroy2 and bridge_brd_monitor. - * In dev_destroy2 we delete the node manager. - * Parameters: - * p_proc_object: Pointer to Processor Object - * Returns: - * 0: Processor placed in monitor mode. - * !0: Failed to place processor in monitor mode. - * Requires: - * Valid Processor Handle - * Ensures: - * Success: ProcObject state is PROC_IDLE - */ -static int proc_monitor(struct proc_object *proc_obj) -{ - int status = -EPERM; - struct msg_mgr *hmsg_mgr; - - /* This is needed only when Device is loaded when it is - * already 'ACTIVE' */ - /* Destroy the Node Manager, msg_ctrl Manager */ - if (!dev_destroy2(proc_obj->dev_obj)) { - /* Destroy the msg_ctrl by calling msg_delete */ - dev_get_msg_mgr(proc_obj->dev_obj, &hmsg_mgr); - if (hmsg_mgr) { - msg_delete(hmsg_mgr); - dev_set_msg_mgr(proc_obj->dev_obj, NULL); - } - } - /* Place the Board in the Monitor State */ - if (!((*proc_obj->intf_fxns->brd_monitor) - (proc_obj->bridge_context))) { - status = 0; - } - - return status; -} - -/* - * ======== get_envp_count ======== - * Purpose: - * Return the number of elements in the envp array, including the - * terminating NULL element. - */ -static s32 get_envp_count(char **envp) -{ - s32 ret = 0; - if (envp) { - while (*envp++) - ret++; - - ret += 1; /* Include the terminating NULL in the count. */ - } - - return ret; -} - -/* - * ======== prepend_envp ======== - * Purpose: - * Prepend an environment variable=value pair to the new envp array, and - * copy in the existing var=value pairs in the old envp array. - */ -static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems, - s32 cnew_envp, char *sz_var) -{ - char **pp_envp = new_envp; - - /* Prepend new environ var=value string */ - *new_envp++ = sz_var; - - /* Copy user's environment into our own. */ - while (envp_elems--) - *new_envp++ = *envp++; - - /* Ensure NULL terminates the new environment strings array. */ - if (envp_elems == 0) - *new_envp = NULL; - - return pp_envp; -} - -/* - * ======== proc_notify_clients ======== - * Purpose: - * Notify the processor the events. - */ -int proc_notify_clients(void *proc, u32 events) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)proc; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - ntfy_notify(p_proc_object->ntfy_obj, events); -func_end: - return status; -} - -/* - * ======== proc_notify_all_clients ======== - * Purpose: - * Notify the processor the events. This includes notifying all clients - * attached to a particulat DSP. - */ -int proc_notify_all_clients(void *proc, u32 events) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)proc; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - dev_notify_clients(p_proc_object->dev_obj, events); - -func_end: - return status; -} - -/* - * ======== proc_get_processor_id ======== - * Purpose: - * Retrieves the processor ID. - */ -int proc_get_processor_id(void *proc, u32 *proc_id) -{ - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)proc; - - if (p_proc_object) - *proc_id = p_proc_object->processor_id; - else - status = -EFAULT; - - return status; -} diff --git a/drivers/staging/tidspbridge/rmgr/pwr.c b/drivers/staging/tidspbridge/rmgr/pwr.c deleted file mode 100644 index 17748df351b..00000000000 --- a/drivers/staging/tidspbridge/rmgr/pwr.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * pwr.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * PWR API for controlling DSP power states. - * - * 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> - -/* ----------------------------------- This */ -#include <dspbridge/pwr.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/devdefs.h> -#include <dspbridge/drv.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> - -/* ----------------------------------- Link Driver */ -#include <dspbridge/dspioctl.h> - -/* - * ======== pwr_sleep_dsp ======== - * Send command to DSP to enter sleep state. - */ -int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout) -{ - struct bridge_drv_interface *intf_fxns; - struct bridge_dev_context *dw_context; - int status = -EPERM; - struct dev_object *hdev_obj = NULL; - u32 ioctlcode = 0; - u32 arg = timeout; - - for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); - hdev_obj != NULL; - hdev_obj = - (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) { - if (dev_get_bridge_context(hdev_obj, - (struct bridge_dev_context **) - &dw_context)) { - continue; - } - if (dev_get_intf_fxns(hdev_obj, - (struct bridge_drv_interface **) - &intf_fxns)) { - continue; - } - if (sleep_code == PWR_DEEPSLEEP) - ioctlcode = BRDIOCTL_DEEPSLEEP; - else if (sleep_code == PWR_EMERGENCYDEEPSLEEP) - ioctlcode = BRDIOCTL_EMERGENCYSLEEP; - else - status = -EINVAL; - - if (status != -EINVAL) { - status = (*intf_fxns->dev_cntrl) (dw_context, - ioctlcode, - (void *)&arg); - } - } - return status; -} - -/* - * ======== pwr_wake_dsp ======== - * Send command to DSP to wake it from sleep. - */ -int pwr_wake_dsp(const u32 timeout) -{ - struct bridge_drv_interface *intf_fxns; - struct bridge_dev_context *dw_context; - int status = -EPERM; - struct dev_object *hdev_obj = NULL; - u32 arg = timeout; - - for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); - hdev_obj != NULL; - hdev_obj = (struct dev_object *)drv_get_next_dev_object - ((u32) hdev_obj)) { - if (!(dev_get_bridge_context(hdev_obj, - (struct bridge_dev_context - **)&dw_context))) { - if (!(dev_get_intf_fxns(hdev_obj, - (struct bridge_drv_interface **)&intf_fxns))) { - status = - (*intf_fxns->dev_cntrl) (dw_context, - BRDIOCTL_WAKEUP, - (void *)&arg); - } - } - } - return status; -} - -/* - * ======== pwr_pm_pre_scale======== - * Sends pre-notification message to DSP. - */ -int pwr_pm_pre_scale(u16 voltage_domain, u32 level) -{ - struct bridge_drv_interface *intf_fxns; - struct bridge_dev_context *dw_context; - int status = -EPERM; - struct dev_object *hdev_obj = NULL; - u32 arg[2]; - - arg[0] = voltage_domain; - arg[1] = level; - - for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); - hdev_obj != NULL; - hdev_obj = (struct dev_object *)drv_get_next_dev_object - ((u32) hdev_obj)) { - if (!(dev_get_bridge_context(hdev_obj, - (struct bridge_dev_context - **)&dw_context))) { - if (!(dev_get_intf_fxns(hdev_obj, - (struct bridge_drv_interface **)&intf_fxns))) { - status = - (*intf_fxns->dev_cntrl) (dw_context, - BRDIOCTL_PRESCALE_NOTIFY, - (void *)&arg); - } - } - } - return status; -} - -/* - * ======== pwr_pm_post_scale======== - * Sends post-notification message to DSP. - */ -int pwr_pm_post_scale(u16 voltage_domain, u32 level) -{ - struct bridge_drv_interface *intf_fxns; - struct bridge_dev_context *dw_context; - int status = -EPERM; - struct dev_object *hdev_obj = NULL; - u32 arg[2]; - - arg[0] = voltage_domain; - arg[1] = level; - - for (hdev_obj = (struct dev_object *)drv_get_first_dev_object(); - hdev_obj != NULL; - hdev_obj = (struct dev_object *)drv_get_next_dev_object - ((u32) hdev_obj)) { - if (!(dev_get_bridge_context(hdev_obj, - (struct bridge_dev_context - **)&dw_context))) { - if (!(dev_get_intf_fxns(hdev_obj, - (struct bridge_drv_interface **)&intf_fxns))) { - status = - (*intf_fxns->dev_cntrl) (dw_context, - BRDIOCTL_POSTSCALE_NOTIFY, - (void *)&arg); - } - } - } - return status; - -} diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c deleted file mode 100644 index 52187bd9772..00000000000 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * rmm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * 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. - */ - -/* - * This memory manager provides general heap management and arbitrary - * alignment for any number of memory segments. - * - * Notes: - * - * Memory blocks are allocated from the end of the first free memory - * block large enough to satisfy the request. Alignment requirements - * are satisfied by "sliding" the block forward until its base satisfies - * the alignment specification; if this is not possible then the next - * free block large enough to hold the request is tried. - * - * Since alignment can cause the creation of a new free block - the - * unused memory formed between the start of the original free block - * and the start of the allocated block - the memory manager must free - * this memory to prevent a memory leak. - * - * Overlay memory is managed by reserving through rmm_alloc, and freeing - * it through rmm_free. The memory manager prevents DSP code/data that is - * overlayed from being overwritten as long as the memory it runs at has - * been allocated, and not yet freed. - */ - -#include <linux/types.h> -#include <linux/list.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- This */ -#include <dspbridge/rmm.h> - -/* - * ======== rmm_header ======== - * This header is used to maintain a list of free memory blocks. - */ -struct rmm_header { - struct rmm_header *next; /* form a free memory link list */ - u32 size; /* size of the free memory */ - u32 addr; /* DSP address of memory block */ -}; - -/* - * ======== rmm_ovly_sect ======== - * Keeps track of memory occupied by overlay section. - */ -struct rmm_ovly_sect { - struct list_head list_elem; - u32 addr; /* Start of memory section */ - u32 size; /* Length (target MAUs) of section */ - s32 page; /* Memory page */ -}; - -/* - * ======== rmm_target_obj ======== - */ -struct rmm_target_obj { - struct rmm_segment *seg_tab; - struct rmm_header **free_list; - u32 num_segs; - struct list_head ovly_list; /* List of overlay memory in use */ -}; - -static bool alloc_block(struct rmm_target_obj *target, u32 segid, u32 size, - u32 align, u32 *dsp_address); -static bool free_block(struct rmm_target_obj *target, u32 segid, u32 addr, - u32 size); - -/* - * ======== rmm_alloc ======== - */ -int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, - u32 align, u32 *dsp_address, bool reserve) -{ - struct rmm_ovly_sect *sect, *prev_sect = NULL; - struct rmm_ovly_sect *new_sect; - u32 addr; - int status = 0; - - if (!reserve) { - if (!alloc_block(target, segid, size, align, dsp_address)) { - status = -ENOMEM; - } else { - /* Increment the number of allocated blocks in this - * segment */ - target->seg_tab[segid].number++; - } - goto func_end; - } - /* An overlay section - See if block is already in use. If not, - * insert into the list in ascending address size. */ - addr = *dsp_address; - /* Find place to insert new list element. List is sorted from - * smallest to largest address. */ - list_for_each_entry(sect, &target->ovly_list, list_elem) { - if (addr <= sect->addr) { - /* Check for overlap with sect */ - if ((addr + size > sect->addr) || (prev_sect && - (prev_sect->addr + - prev_sect->size > - addr))) { - status = -ENXIO; - } - break; - } - prev_sect = sect; - } - if (!status) { - /* No overlap - allocate list element for new section. */ - new_sect = kzalloc(sizeof(struct rmm_ovly_sect), GFP_KERNEL); - if (new_sect == NULL) { - status = -ENOMEM; - } else { - new_sect->addr = addr; - new_sect->size = size; - new_sect->page = segid; - if (list_is_last(§->list_elem, &target->ovly_list)) - /* Put new section at the end of the list */ - list_add_tail(&new_sect->list_elem, - &target->ovly_list); - else - /* Put new section just before sect */ - list_add_tail(&new_sect->list_elem, - §->list_elem); - } - } -func_end: - return status; -} - -/* - * ======== rmm_create ======== - */ -int rmm_create(struct rmm_target_obj **target_obj, - struct rmm_segment seg_tab[], u32 num_segs) -{ - struct rmm_header *hptr; - struct rmm_segment *sptr, *tmp; - struct rmm_target_obj *target; - s32 i; - int status = 0; - - /* Allocate DBL target object */ - target = kzalloc(sizeof(struct rmm_target_obj), GFP_KERNEL); - - if (target == NULL) - status = -ENOMEM; - - if (status) - goto func_cont; - - target->num_segs = num_segs; - if (!(num_segs > 0)) - goto func_cont; - - /* Allocate the memory for freelist from host's memory */ - target->free_list = kzalloc(num_segs * sizeof(struct rmm_header *), - GFP_KERNEL); - if (target->free_list == NULL) { - status = -ENOMEM; - } else { - /* Allocate headers for each element on the free list */ - for (i = 0; i < (s32) num_segs; i++) { - target->free_list[i] = - kzalloc(sizeof(struct rmm_header), GFP_KERNEL); - if (target->free_list[i] == NULL) { - status = -ENOMEM; - break; - } - } - /* Allocate memory for initial segment table */ - target->seg_tab = kzalloc(num_segs * sizeof(struct rmm_segment), - GFP_KERNEL); - if (target->seg_tab == NULL) { - status = -ENOMEM; - } else { - /* Initialize segment table and free list */ - sptr = target->seg_tab; - for (i = 0, tmp = seg_tab; num_segs > 0; - num_segs--, i++) { - *sptr = *tmp; - hptr = target->free_list[i]; - hptr->addr = tmp->base; - hptr->size = tmp->length; - hptr->next = NULL; - tmp++; - sptr++; - } - } - } -func_cont: - /* Initialize overlay memory list */ - if (!status) - INIT_LIST_HEAD(&target->ovly_list); - - if (!status) { - *target_obj = target; - } else { - *target_obj = NULL; - if (target) - rmm_delete(target); - - } - - return status; -} - -/* - * ======== rmm_delete ======== - */ -void rmm_delete(struct rmm_target_obj *target) -{ - struct rmm_ovly_sect *sect, *tmp; - struct rmm_header *hptr; - struct rmm_header *next; - u32 i; - - kfree(target->seg_tab); - - list_for_each_entry_safe(sect, tmp, &target->ovly_list, list_elem) { - list_del(§->list_elem); - kfree(sect); - } - - if (target->free_list != NULL) { - /* Free elements on freelist */ - for (i = 0; i < target->num_segs; i++) { - hptr = next = target->free_list[i]; - while (next) { - hptr = next; - next = hptr->next; - kfree(hptr); - } - } - kfree(target->free_list); - } - - kfree(target); -} - -/* - * ======== rmm_free ======== - */ -bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size, - bool reserved) -{ - struct rmm_ovly_sect *sect, *tmp; - bool ret = false; - - /* - * Free or unreserve memory. - */ - if (!reserved) { - ret = free_block(target, segid, dsp_addr, size); - if (ret) - target->seg_tab[segid].number--; - - } else { - /* Unreserve memory */ - list_for_each_entry_safe(sect, tmp, &target->ovly_list, - list_elem) { - if (dsp_addr == sect->addr) { - /* Remove from list */ - list_del(§->list_elem); - kfree(sect); - return true; - } - } - } - return ret; -} - -/* - * ======== rmm_stat ======== - */ -bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid, - struct dsp_memstat *mem_stat_buf) -{ - struct rmm_header *head; - bool ret = false; - u32 max_free_size = 0; - u32 total_free_size = 0; - u32 free_blocks = 0; - - if ((u32) segid < target->num_segs) { - head = target->free_list[segid]; - - /* Collect data from free_list */ - while (head != NULL) { - max_free_size = max(max_free_size, head->size); - total_free_size += head->size; - free_blocks++; - head = head->next; - } - - /* ul_size */ - mem_stat_buf->size = target->seg_tab[segid].length; - - /* num_free_blocks */ - mem_stat_buf->num_free_blocks = free_blocks; - - /* total_free_size */ - mem_stat_buf->total_free_size = total_free_size; - - /* len_max_free_block */ - mem_stat_buf->len_max_free_block = max_free_size; - - /* num_alloc_blocks */ - mem_stat_buf->num_alloc_blocks = - target->seg_tab[segid].number; - - ret = true; - } - - return ret; -} - -/* - * ======== balloc ======== - * This allocation function allocates memory from the lowest addresses - * first. - */ -static bool alloc_block(struct rmm_target_obj *target, u32 segid, u32 size, - u32 align, u32 *dsp_address) -{ - struct rmm_header *head; - struct rmm_header *prevhead = NULL; - struct rmm_header *next; - u32 tmpalign; - u32 alignbytes; - u32 hsize; - u32 allocsize; - u32 addr; - - alignbytes = (align == 0) ? 1 : align; - prevhead = NULL; - head = target->free_list[segid]; - - do { - hsize = head->size; - next = head->next; - - addr = head->addr; /* alloc from the bottom */ - - /* align allocation */ - (tmpalign = (u32) addr % alignbytes); - if (tmpalign != 0) - tmpalign = alignbytes - tmpalign; - - allocsize = size + tmpalign; - - if (hsize >= allocsize) { /* big enough */ - if (hsize == allocsize && prevhead != NULL) { - prevhead->next = next; - kfree(head); - } else { - head->size = hsize - allocsize; - head->addr += allocsize; - } - - /* free up any hole created by alignment */ - if (tmpalign) - free_block(target, segid, addr, tmpalign); - - *dsp_address = addr + tmpalign; - return true; - } - - prevhead = head; - head = next; - - } while (head != NULL); - - return false; -} - -/* - * ======== free_block ======== - * TO DO: free_block() allocates memory, which could result in failure. - * Could allocate an rmm_header in rmm_alloc(), to be kept in a pool. - * free_block() could use an rmm_header from the pool, freeing as blocks - * are coalesced. - */ -static bool free_block(struct rmm_target_obj *target, u32 segid, u32 addr, - u32 size) -{ - struct rmm_header *head; - struct rmm_header *thead; - struct rmm_header *rhead; - bool ret = true; - - /* Create a memory header to hold the newly free'd block. */ - rhead = kzalloc(sizeof(struct rmm_header), GFP_KERNEL); - if (rhead == NULL) { - ret = false; - } else { - /* search down the free list to find the right place for addr */ - head = target->free_list[segid]; - - if (addr >= head->addr) { - while (head->next != NULL && addr > head->next->addr) - head = head->next; - - thead = head->next; - - head->next = rhead; - rhead->next = thead; - rhead->addr = addr; - rhead->size = size; - } else { - *rhead = *head; - head->next = rhead; - head->addr = addr; - head->size = size; - thead = rhead->next; - } - - /* join with upper block, if possible */ - if (thead != NULL && (rhead->addr + rhead->size) == - thead->addr) { - head->next = rhead->next; - thead->size = size + thead->size; - thead->addr = addr; - kfree(rhead); - rhead = thead; - } - - /* join with the lower block, if possible */ - if ((head->addr + head->size) == rhead->addr) { - head->next = rhead->next; - head->size = head->size + rhead->size; - kfree(rhead); - } - } - - return ret; -} diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c deleted file mode 100644 index b88b27bbe2e..00000000000 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ /dev/null @@ -1,733 +0,0 @@ -/* - * strm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge Stream Manager. - * - * 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. - */ - -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Bridge Driver */ -#include <dspbridge/dspdefs.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/nodepriv.h> - -/* ----------------------------------- Others */ -#include <dspbridge/cmm.h> - -/* ----------------------------------- This */ -#include <dspbridge/strm.h> - -#include <dspbridge/resourcecleanup.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define DEFAULTTIMEOUT 10000 -#define DEFAULTNUMBUFS 2 - -/* - * ======== strm_mgr ======== - * The strm_mgr contains device information needed to open the underlying - * channels of a stream. - */ -struct strm_mgr { - struct dev_object *dev_obj; /* Device for this processor */ - struct chnl_mgr *chnl_mgr; /* Channel manager */ - /* Function interface to Bridge driver */ - struct bridge_drv_interface *intf_fxns; -}; - -/* - * ======== strm_object ======== - * This object is allocated in strm_open(). - */ -struct strm_object { - struct strm_mgr *strm_mgr_obj; - struct chnl_object *chnl_obj; - u32 dir; /* DSP_TONODE or DSP_FROMNODE */ - u32 timeout; - u32 num_bufs; /* Max # of bufs allowed in stream */ - u32 bufs_in_strm; /* Current # of bufs in stream */ - u32 bytes; /* bytes transferred since idled */ - /* STREAM_IDLE, STREAM_READY, ... */ - enum dsp_streamstate strm_state; - void *user_event; /* Saved for strm_get_info() */ - enum dsp_strmmode strm_mode; /* STRMMODE_[PROCCOPY][ZEROCOPY]... */ - u32 dma_chnl_id; /* DMA chnl id */ - u32 dma_priority; /* DMA priority:DMAPRI_[LOW][HIGH] */ - u32 segment_id; /* >0 is SM segment.=0 is local heap */ - u32 buf_alignment; /* Alignment for stream bufs */ - /* Stream's SM address translator */ - struct cmm_xlatorobject *xlator; -}; - -/* ----------------------------------- Function Prototypes */ -static int delete_strm(struct strm_object *stream_obj); - -/* - * ======== strm_allocate_buffer ======== - * Purpose: - * Allocates buffers for a stream. - */ -int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize, - u8 **ap_buffer, u32 num_bufs, - struct process_context *pr_ctxt) -{ - int status = 0; - u32 alloc_cnt = 0; - u32 i; - struct strm_object *stream_obj = strmres->stream; - - if (stream_obj) { - /* - * Allocate from segment specified at time of stream open. - */ - if (usize == 0) - status = -EINVAL; - - } else { - status = -EFAULT; - } - - if (status) - goto func_end; - - for (i = 0; i < num_bufs; i++) { - (void)cmm_xlator_alloc_buf(stream_obj->xlator, &ap_buffer[i], - usize); - if (ap_buffer[i] == NULL) { - status = -ENOMEM; - alloc_cnt = i; - break; - } - } - if (status) - strm_free_buffer(strmres, ap_buffer, alloc_cnt, pr_ctxt); - - if (status) - goto func_end; - - drv_proc_update_strm_res(num_bufs, strmres); - -func_end: - return status; -} - -/* - * ======== strm_close ======== - * Purpose: - * Close a stream opened with strm_open(). - */ -int strm_close(struct strm_res_object *strmres, - struct process_context *pr_ctxt) -{ - struct bridge_drv_interface *intf_fxns; - struct chnl_info chnl_info_obj; - int status = 0; - struct strm_object *stream_obj = strmres->stream; - - if (!stream_obj) { - status = -EFAULT; - } else { - /* Have all buffers been reclaimed? If not, return - * -EPIPE */ - intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - status = - (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj, - &chnl_info_obj); - - if (chnl_info_obj.cio_cs > 0 || chnl_info_obj.cio_reqs > 0) - status = -EPIPE; - else - status = delete_strm(stream_obj); - } - - if (status) - goto func_end; - - idr_remove(pr_ctxt->stream_id, strmres->id); -func_end: - dev_dbg(bridge, "%s: stream_obj: %p, status 0x%x\n", __func__, - stream_obj, status); - return status; -} - -/* - * ======== strm_create ======== - * Purpose: - * Create a STRM manager object. - */ -int strm_create(struct strm_mgr **strm_man, - struct dev_object *dev_obj) -{ - struct strm_mgr *strm_mgr_obj; - int status = 0; - - *strm_man = NULL; - /* Allocate STRM manager object */ - strm_mgr_obj = kzalloc(sizeof(struct strm_mgr), GFP_KERNEL); - if (strm_mgr_obj == NULL) - status = -ENOMEM; - else - strm_mgr_obj->dev_obj = dev_obj; - - /* Get Channel manager and Bridge function interface */ - if (!status) { - status = dev_get_chnl_mgr(dev_obj, &(strm_mgr_obj->chnl_mgr)); - if (!status) { - (void)dev_get_intf_fxns(dev_obj, - &(strm_mgr_obj->intf_fxns)); - } - } - - if (!status) - *strm_man = strm_mgr_obj; - else - kfree(strm_mgr_obj); - - return status; -} - -/* - * ======== strm_delete ======== - * Purpose: - * Delete the STRM Manager Object. - */ -void strm_delete(struct strm_mgr *strm_mgr_obj) -{ - kfree(strm_mgr_obj); -} - -/* - * ======== strm_free_buffer ======== - * Purpose: - * Frees the buffers allocated for a stream. - */ -int strm_free_buffer(struct strm_res_object *strmres, u8 **ap_buffer, - u32 num_bufs, struct process_context *pr_ctxt) -{ - int status = 0; - u32 i = 0; - struct strm_object *stream_obj = strmres->stream; - - if (!stream_obj) - status = -EFAULT; - - if (!status) { - for (i = 0; i < num_bufs; i++) { - status = - cmm_xlator_free_buf(stream_obj->xlator, - ap_buffer[i]); - if (status) - break; - ap_buffer[i] = NULL; - } - } - drv_proc_update_strm_res(num_bufs - i, strmres); - - return status; -} - -/* - * ======== strm_get_info ======== - * Purpose: - * Retrieves information about a stream. - */ -int strm_get_info(struct strm_object *stream_obj, - struct stream_info *stream_info, - u32 stream_info_size) -{ - struct bridge_drv_interface *intf_fxns; - struct chnl_info chnl_info_obj; - int status = 0; - void *virt_base = NULL; /* NULL if no SM used */ - - if (!stream_obj) { - status = -EFAULT; - } else { - if (stream_info_size < sizeof(struct stream_info)) { - /* size of users info */ - status = -EINVAL; - } - } - if (status) - goto func_end; - - intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - status = - (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj, - &chnl_info_obj); - if (status) - goto func_end; - - if (stream_obj->xlator) { - /* We have a translator */ - cmm_xlator_info(stream_obj->xlator, (u8 **) &virt_base, 0, - stream_obj->segment_id, false); - } - stream_info->segment_id = stream_obj->segment_id; - stream_info->strm_mode = stream_obj->strm_mode; - stream_info->virt_base = virt_base; - stream_info->user_strm->number_bufs_allowed = stream_obj->num_bufs; - stream_info->user_strm->number_bufs_in_stream = chnl_info_obj.cio_cs + - chnl_info_obj.cio_reqs; - /* # of bytes transferred since last call to DSPStream_Idle() */ - stream_info->user_strm->number_bytes = chnl_info_obj.bytes_tx; - stream_info->user_strm->sync_object_handle = chnl_info_obj.event_obj; - /* Determine stream state based on channel state and info */ - if (chnl_info_obj.state & CHNL_STATEEOS) { - stream_info->user_strm->ss_stream_state = STREAM_DONE; - } else { - if (chnl_info_obj.cio_cs > 0) - stream_info->user_strm->ss_stream_state = STREAM_READY; - else if (chnl_info_obj.cio_reqs > 0) - stream_info->user_strm->ss_stream_state = - STREAM_PENDING; - else - stream_info->user_strm->ss_stream_state = STREAM_IDLE; - - } -func_end: - return status; -} - -/* - * ======== strm_idle ======== - * Purpose: - * Idles a particular stream. - */ -int strm_idle(struct strm_object *stream_obj, bool flush_data) -{ - struct bridge_drv_interface *intf_fxns; - int status = 0; - - if (!stream_obj) { - status = -EFAULT; - } else { - intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - - status = (*intf_fxns->chnl_idle) (stream_obj->chnl_obj, - stream_obj->timeout, - flush_data); - } - - dev_dbg(bridge, "%s: stream_obj: %p flush_data: 0x%x status: 0x%x\n", - __func__, stream_obj, flush_data, status); - return status; -} - -/* - * ======== strm_issue ======== - * Purpose: - * Issues a buffer on a stream - */ -int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes, - u32 ul_buf_size, u32 dw_arg) -{ - struct bridge_drv_interface *intf_fxns; - int status = 0; - void *tmp_buf = NULL; - - if (!stream_obj) { - status = -EFAULT; - } else { - intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - - if (stream_obj->segment_id != 0) { - tmp_buf = cmm_xlator_translate(stream_obj->xlator, - (void *)pbuf, - CMM_VA2DSPPA); - if (tmp_buf == NULL) - status = -ESRCH; - - } - if (!status) { - status = (*intf_fxns->chnl_add_io_req) - (stream_obj->chnl_obj, pbuf, ul_bytes, ul_buf_size, - (u32) tmp_buf, dw_arg); - } - if (status == -EIO) - status = -ENOSR; - } - - dev_dbg(bridge, "%s: stream_obj: %p pbuf: %p ul_bytes: 0x%x dw_arg:" - " 0x%x status: 0x%x\n", __func__, stream_obj, pbuf, - ul_bytes, dw_arg, status); - return status; -} - -/* - * ======== strm_open ======== - * Purpose: - * Open a stream for sending/receiving data buffers to/from a task or - * XDAIS socket node on the DSP. - */ -int strm_open(struct node_object *hnode, u32 dir, u32 index, - struct strm_attr *pattr, - struct strm_res_object **strmres, - struct process_context *pr_ctxt) -{ - struct strm_mgr *strm_mgr_obj; - struct bridge_drv_interface *intf_fxns; - u32 ul_chnl_id; - struct strm_object *strm_obj = NULL; - s8 chnl_mode; - struct chnl_attr chnl_attr_obj; - int status = 0; - struct cmm_object *hcmm_mgr = NULL; /* Shared memory manager hndl */ - - void *stream_res; - - *strmres = NULL; - if (dir != DSP_TONODE && dir != DSP_FROMNODE) { - status = -EPERM; - } else { - /* Get the channel id from the node (set in node_connect()) */ - status = node_get_channel_id(hnode, dir, index, &ul_chnl_id); - } - if (!status) - status = node_get_strm_mgr(hnode, &strm_mgr_obj); - - if (!status) { - strm_obj = kzalloc(sizeof(struct strm_object), GFP_KERNEL); - if (strm_obj == NULL) { - status = -ENOMEM; - } else { - strm_obj->strm_mgr_obj = strm_mgr_obj; - strm_obj->dir = dir; - strm_obj->strm_state = STREAM_IDLE; - strm_obj->user_event = pattr->user_event; - if (pattr->stream_attr_in != NULL) { - strm_obj->timeout = - pattr->stream_attr_in->timeout; - strm_obj->num_bufs = - pattr->stream_attr_in->num_bufs; - strm_obj->strm_mode = - pattr->stream_attr_in->strm_mode; - strm_obj->segment_id = - pattr->stream_attr_in->segment_id; - strm_obj->buf_alignment = - pattr->stream_attr_in->buf_alignment; - strm_obj->dma_chnl_id = - pattr->stream_attr_in->dma_chnl_id; - strm_obj->dma_priority = - pattr->stream_attr_in->dma_priority; - chnl_attr_obj.uio_reqs = - pattr->stream_attr_in->num_bufs; - } else { - strm_obj->timeout = DEFAULTTIMEOUT; - strm_obj->num_bufs = DEFAULTNUMBUFS; - strm_obj->strm_mode = STRMMODE_PROCCOPY; - strm_obj->segment_id = 0; /* local mem */ - strm_obj->buf_alignment = 0; - strm_obj->dma_chnl_id = 0; - strm_obj->dma_priority = 0; - chnl_attr_obj.uio_reqs = DEFAULTNUMBUFS; - } - chnl_attr_obj.reserved1 = NULL; - /* DMA chnl flush timeout */ - chnl_attr_obj.reserved2 = strm_obj->timeout; - chnl_attr_obj.event_obj = NULL; - if (pattr->user_event != NULL) - chnl_attr_obj.event_obj = pattr->user_event; - - } - } - if (status) - goto func_cont; - - if ((pattr->virt_base == NULL) || !(pattr->virt_size > 0)) - goto func_cont; - - /* No System DMA */ - /* Get the shared mem mgr for this streams dev object */ - status = dev_get_cmm_mgr(strm_mgr_obj->dev_obj, &hcmm_mgr); - if (!status) { - /*Allocate a SM addr translator for this strm. */ - status = cmm_xlator_create(&strm_obj->xlator, hcmm_mgr, NULL); - if (!status) { - /* Set translators Virt Addr attributes */ - status = cmm_xlator_info(strm_obj->xlator, - (u8 **) &pattr->virt_base, - pattr->virt_size, - strm_obj->segment_id, true); - } - } -func_cont: - if (!status) { - /* Open channel */ - chnl_mode = (dir == DSP_TONODE) ? - CHNL_MODETODSP : CHNL_MODEFROMDSP; - intf_fxns = strm_mgr_obj->intf_fxns; - status = (*intf_fxns->chnl_open) (&(strm_obj->chnl_obj), - strm_mgr_obj->chnl_mgr, - chnl_mode, ul_chnl_id, - &chnl_attr_obj); - if (status) { - /* - * over-ride non-returnable status codes so we return - * something documented - */ - if (status != -ENOMEM && status != - -EINVAL && status != -EPERM) { - /* - * We got a status that's not return-able. - * Assert that we got something we were - * expecting (-EFAULT isn't acceptable, - * strm_mgr_obj->chnl_mgr better be valid or we - * assert here), and then return -EPERM. - */ - status = -EPERM; - } - } - } - if (!status) { - status = drv_proc_insert_strm_res_element(strm_obj, - &stream_res, pr_ctxt); - if (status) - delete_strm(strm_obj); - else - *strmres = (struct strm_res_object *)stream_res; - } else { - (void)delete_strm(strm_obj); - } - - dev_dbg(bridge, "%s: hnode: %p dir: 0x%x index: 0x%x pattr: %p " - "strmres: %p status: 0x%x\n", __func__, - hnode, dir, index, pattr, strmres, status); - return status; -} - -/* - * ======== strm_reclaim ======== - * Purpose: - * Relcaims a buffer from a stream. - */ -int strm_reclaim(struct strm_object *stream_obj, u8 **buf_ptr, - u32 *nbytes, u32 *buff_size, u32 *pdw_arg) -{ - struct bridge_drv_interface *intf_fxns; - struct chnl_ioc chnl_ioc_obj; - int status = 0; - void *tmp_buf = NULL; - - if (!stream_obj) { - status = -EFAULT; - goto func_end; - } - intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - - status = - (*intf_fxns->chnl_get_ioc) (stream_obj->chnl_obj, - stream_obj->timeout, - &chnl_ioc_obj); - if (!status) { - *nbytes = chnl_ioc_obj.byte_size; - if (buff_size) - *buff_size = chnl_ioc_obj.buf_size; - - *pdw_arg = chnl_ioc_obj.arg; - if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { - if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) { - status = -ETIME; - } else { - /* Allow reclaims after idle to succeed */ - if (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj)) - status = -EPERM; - - } - } - /* Translate zerocopy buffer if channel not canceled. */ - if (!status - && (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj)) - && (stream_obj->strm_mode == STRMMODE_ZEROCOPY)) { - /* - * This is a zero-copy channel so chnl_ioc_obj.buf - * contains the DSP address of SM. We need to - * translate it to a virtual address for the user - * thread to access. - * Note: Could add CMM_DSPPA2VA to CMM in the future. - */ - tmp_buf = cmm_xlator_translate(stream_obj->xlator, - chnl_ioc_obj.buf, - CMM_DSPPA2PA); - if (tmp_buf != NULL) { - /* now convert this GPP Pa to Va */ - tmp_buf = cmm_xlator_translate(stream_obj-> - xlator, - tmp_buf, - CMM_PA2VA); - } - if (tmp_buf == NULL) - status = -ESRCH; - - chnl_ioc_obj.buf = tmp_buf; - } - *buf_ptr = chnl_ioc_obj.buf; - } -func_end: - dev_dbg(bridge, "%s: stream_obj: %p buf_ptr: %p nbytes: %p " - "pdw_arg: %p status 0x%x\n", __func__, stream_obj, - buf_ptr, nbytes, pdw_arg, status); - return status; -} - -/* - * ======== strm_register_notify ======== - * Purpose: - * Register to be notified on specific events for this stream. - */ -int strm_register_notify(struct strm_object *stream_obj, u32 event_mask, - u32 notify_type, struct dsp_notification - *hnotification) -{ - struct bridge_drv_interface *intf_fxns; - int status = 0; - - if (!stream_obj) { - status = -EFAULT; - } else if ((event_mask & ~((DSP_STREAMIOCOMPLETION) | - DSP_STREAMDONE)) != 0) { - status = -EINVAL; - } else { - if (notify_type != DSP_SIGNALEVENT) - status = -ENOSYS; - - } - if (!status) { - intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - - status = - (*intf_fxns->chnl_register_notify) (stream_obj-> - chnl_obj, - event_mask, - notify_type, - hnotification); - } - - return status; -} - -/* - * ======== strm_select ======== - * Purpose: - * Selects a ready stream. - */ -int strm_select(struct strm_object **strm_tab, u32 strms, - u32 *pmask, u32 utimeout) -{ - u32 index; - struct chnl_info chnl_info_obj; - struct bridge_drv_interface *intf_fxns; - struct sync_object **sync_events = NULL; - u32 i; - int status = 0; - - *pmask = 0; - for (i = 0; i < strms; i++) { - if (!strm_tab[i]) { - status = -EFAULT; - break; - } - } - if (status) - goto func_end; - - /* Determine which channels have IO ready */ - for (i = 0; i < strms; i++) { - intf_fxns = strm_tab[i]->strm_mgr_obj->intf_fxns; - status = (*intf_fxns->chnl_get_info) (strm_tab[i]->chnl_obj, - &chnl_info_obj); - if (status) { - break; - } else { - if (chnl_info_obj.cio_cs > 0) - *pmask |= (1 << i); - - } - } - if (!status && utimeout > 0 && *pmask == 0) { - /* Non-zero timeout */ - sync_events = kmalloc(strms * sizeof(struct sync_object *), - GFP_KERNEL); - - if (sync_events == NULL) { - status = -ENOMEM; - } else { - for (i = 0; i < strms; i++) { - intf_fxns = - strm_tab[i]->strm_mgr_obj->intf_fxns; - status = (*intf_fxns->chnl_get_info) - (strm_tab[i]->chnl_obj, &chnl_info_obj); - if (status) - break; - else - sync_events[i] = - chnl_info_obj.sync_event; - - } - } - if (!status) { - status = - sync_wait_on_multiple_events(sync_events, strms, - utimeout, &index); - if (!status) { - /* Since we waited on the event, we have to - * reset it */ - sync_set_event(sync_events[index]); - *pmask = 1 << index; - } - } - } -func_end: - kfree(sync_events); - - return status; -} - -/* - * ======== delete_strm ======== - * Purpose: - * Frees the resources allocated for a stream. - */ -static int delete_strm(struct strm_object *stream_obj) -{ - struct bridge_drv_interface *intf_fxns; - int status = 0; - - if (stream_obj) { - if (stream_obj->chnl_obj) { - intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - /* Channel close can fail only if the channel handle - * is invalid. */ - status = (*intf_fxns->chnl_close) - (stream_obj->chnl_obj); - } - /* Free all SM address translator resources */ - kfree(stream_obj->xlator); - kfree(stream_obj); - } else { - status = -EFAULT; - } - return status; -} |