Initial import into "quilt"
[bridge-dev.git] / 0006-TI-DSP-BRIDGE-Platform-Manager.patch
blobb2cf762042b31a6063df2552c520fc45d3d50bd0
1 From 3e100ade5acf2c8c570c74976d83709119075a51 Mon Sep 17 00:00:00 2001
2 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
3 Date: Fri, 15 Aug 2008 01:55:54 +0300
4 Subject: [PATCH 06/10] TI DSP BRIDGE: Platform Manager
6 Initial port from omapzoom
7 http://omapzoom.org/gf/project/omapbridge
9 For details,
10 http://omapzoom.org/gf/project/omapbridge/docman/?subdir=3
12 Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
13 ---
14 drivers/dsp/bridge/pmgr/chnl.c | 517 ++++++++++++
15 drivers/dsp/bridge/pmgr/chnlobj.h | 71 ++
16 drivers/dsp/bridge/pmgr/cmm.c | 1290 +++++++++++++++++++++++++++++
17 drivers/dsp/bridge/pmgr/cod.c | 683 +++++++++++++++
18 drivers/dsp/bridge/pmgr/dbl.c | 1385 +++++++++++++++++++++++++++++++
19 drivers/dsp/bridge/pmgr/dbll.c | 1565 +++++++++++++++++++++++++++++++++++
20 drivers/dsp/bridge/pmgr/dev.c | 1475 +++++++++++++++++++++++++++++++++
21 drivers/dsp/bridge/pmgr/dmm.c | 646 +++++++++++++++
22 drivers/dsp/bridge/pmgr/io.c | 204 +++++
23 drivers/dsp/bridge/pmgr/ioobj.h | 52 ++
24 drivers/dsp/bridge/pmgr/msg.c | 173 ++++
25 drivers/dsp/bridge/pmgr/msgobj.h | 52 ++
26 drivers/dsp/bridge/pmgr/wcd.c | 1641 +++++++++++++++++++++++++++++++++++++
27 13 files changed, 9754 insertions(+), 0 deletions(-)
28 create mode 100644 drivers/dsp/bridge/pmgr/chnl.c
29 create mode 100644 drivers/dsp/bridge/pmgr/chnlobj.h
30 create mode 100644 drivers/dsp/bridge/pmgr/cmm.c
31 create mode 100644 drivers/dsp/bridge/pmgr/cod.c
32 create mode 100644 drivers/dsp/bridge/pmgr/dbl.c
33 create mode 100644 drivers/dsp/bridge/pmgr/dbll.c
34 create mode 100644 drivers/dsp/bridge/pmgr/dev.c
35 create mode 100644 drivers/dsp/bridge/pmgr/dmm.c
36 create mode 100644 drivers/dsp/bridge/pmgr/io.c
37 create mode 100644 drivers/dsp/bridge/pmgr/ioobj.h
38 create mode 100644 drivers/dsp/bridge/pmgr/msg.c
39 create mode 100644 drivers/dsp/bridge/pmgr/msgobj.h
40 create mode 100644 drivers/dsp/bridge/pmgr/wcd.c
42 diff --git a/drivers/dsp/bridge/pmgr/chnl.c b/drivers/dsp/bridge/pmgr/chnl.c
43 new file mode 100644
44 index 0000000..9742dac
45 --- /dev/null
46 +++ b/drivers/dsp/bridge/pmgr/chnl.c
47 @@ -0,0 +1,517 @@
48 +/*
49 + * linux/drivers/dsp/bridge/pmgr/chnl.c
50 + *
51 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
52 + *
53 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
54 + *
55 + * This package is free software; you can redistribute it and/or modify
56 + * it under the terms of the GNU General Public License version 2 as
57 + * published by the Free Software Foundation.
58 + *
59 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
60 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
61 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
62 + */
65 +/*
66 + * ======== chnl.c ========
67 + * Description:
68 + * WCD channel interface: multiplexes data streams through the single
69 + * physical link managed by a 'Bridge mini-driver.
70 + *
71 + * Public Functions:
72 + * CHNL_Close
73 + * CHNL_CloseOrphans
74 + * CHNL_Create
75 + * CHNL_Destroy
76 + * CHNL_Exit
77 + * CHNL_GetHandle
78 + * CHNL_GetProcessHandle
79 + * CHNL_Init
80 + * CHNL_Open
81 + *
82 + * Notes:
83 + * This interface is basically a pass through to the WMD CHNL functions,
84 + * except for the CHNL_Get() accessor functions which call
85 + * WMD_CHNL_GetInfo().
86 + *
87 + *! Revision History:
88 + *! ================
89 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
90 + *! 07-Jan-2002 ag CHNL_CloseOrphans() now closes supported # of channels.
91 + *! 17-Nov-2000 jeh Removed IRQ, shared memory stuff from CHNL_Create.
92 + *! 28-Feb-2000 rr: New GT USage Implementation
93 + *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from
94 + *! SERVICES)
95 + *! 21-Jan-2000 ag: Added code review comments.
96 + *! 13-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject.
97 + *! 08-Dec-1999 ag: CHNL_[Alloc|Free]Buffer bufs taken from client process heap.
98 + *! 02-Dec-1999 ag: Implemented CHNL_GetEventHandle().
99 + *! 17-Nov-1999 ag: CHNL_AllocBuffer() allocs extra word for process mapping.
100 + *! 28-Oct-1999 ag: WinCE port. Search for "WinCE" for changes(TBR).
101 + *! 07-Jan-1998 gp: CHNL_[Alloc|Free]Buffer now call MEM_UMB functions.
102 + *! 22-Oct-1997 gp: Removed requirement in CHNL_Open that hReserved1 != NULL.
103 + *! 30-Aug-1997 cr: Renamed cfg.h wbwcd.h b/c of WINNT file name collision.
104 + *! 10-Mar-1997 gp: Added GT trace.
105 + *! 14-Jan-1997 gp: Updated based on code review feedback.
106 + *! 03-Jan-1997 gp: Moved CHNL_AllocBuffer/CHNL_FreeBuffer code from udspsys.
107 + *! 14-Dec-1996 gp: Added uChnlId parameter to CHNL_Open().
108 + *! 09-Sep-1996 gp: Added CHNL_GetProcessHandle().
109 + *! 15-Jul-1996 gp: Created.
110 + */
112 +/* ----------------------------------- Host OS */
113 +#include <host_os.h>
115 +/* ----------------------------------- DSP/BIOS Bridge */
116 +#include <std.h>
117 +#include <dbdefs.h>
118 +#include <errbase.h>
120 +/* ----------------------------------- Trace & Debug */
121 +#include <dbc.h>
122 +#include <gt.h>
124 +/* ----------------------------------- OS Adaptation Layer */
125 +#include <cfg.h>
126 +#include <csl.h>
127 +#include <dpc.h>
128 +#include <isr.h>
129 +#include <list.h>
130 +#include <mem.h>
131 +#include <sync.h>
133 +/* ----------------------------------- Platform Manager */
134 +#include <proc.h>
135 +#include <dev.h>
137 +/* ----------------------------------- Others */
138 +#include <chnlpriv.h>
139 +#include <chnlobj.h>
141 +/* ----------------------------------- This */
142 +#include <chnl.h>
144 +/* ----------------------------------- Globals */
145 +static u32 cRefs;
146 +#if GT_TRACE
147 +static struct GT_Mask CHNL_DebugMask = { NULL, NULL }; /* WCD CHNL Mask */
148 +#endif
150 +/* ----------------------------------- Function Prototypes */
151 +static DSP_STATUS GetNumOpenChannels(struct CHNL_MGR *hChnlMgr,
152 + OUT u32 *pcOpenChannels);
154 +static DSP_STATUS GetNumChannels(struct CHNL_MGR *hChnlMgr,
155 + OUT u32 *pcChannels);
158 + * ======== CHNL_Close ========
159 + * Purpose:
160 + * Ensures all pending I/O on this channel is cancelled, discards all
161 + * queued I/O completion notifications, then frees the resources
162 + * allocated for this channel, and makes the corresponding logical
163 + * channel id available for subsequent use.
164 + */
165 +DSP_STATUS CHNL_Close(struct CHNL_OBJECT *hChnl)
167 + DSP_STATUS status;
168 + struct CHNL_OBJECT_ *pChnl = (struct CHNL_OBJECT_ *)hChnl;
169 + struct WMD_DRV_INTERFACE *pIntfFxns;
171 + DBC_Require(cRefs > 0);
173 + GT_1trace(CHNL_DebugMask, GT_ENTER,
174 + "Entered CHNL_Close:hChnl: 0x%x\n",
175 + hChnl);
177 + if (CHNL_IsValidChnl(pChnl)) {
178 + pIntfFxns = pChnl->pChnlMgr->pIntfFxns;
179 + status = (*pIntfFxns->pfnChnlClose) (hChnl);
180 + } else {
181 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
182 + "CHNL_Close:Invalid Handle\n");
183 + status = DSP_EHANDLE;
185 + GT_2trace(CHNL_DebugMask, GT_ENTER,
186 + "Exiting CHNL_Close:hChnl: 0x%x, status:"
187 + " 0x%x\n", hChnl, status);
188 + return status;
192 + * ======== CHNL_CloseOrphans ========
193 + * Purpose:
194 + * Close open channels orphaned by a closing process.
195 + */
196 +DSP_STATUS CHNL_CloseOrphans(struct CHNL_MGR *hChnlMgr, HANDLE hProcess)
198 + u32 uChnlID;
199 + DSP_STATUS status = DSP_SFALSE;
200 + HANDLE hProc;
201 + u32 cOpenChannels;
202 + u32 cTotalChnls;
203 + struct CHNL_OBJECT *hChnl;
205 + DBC_Require(cRefs > 0);
207 + GT_2trace(CHNL_DebugMask, GT_ENTER,
208 + "Enter CHNL_CloseOrphans hChnlMgr "
209 + "0x%x\t\nhProcess: 0x%x\n", hChnlMgr, hProcess);
210 + if (!CHNL_IsValidMgr((struct CHNL_MGR_ *)hChnlMgr)) {
211 + status = DSP_EHANDLE;
212 + goto func_end;
214 + if (DSP_SUCCEEDED(GetNumOpenChannels(hChnlMgr, &cOpenChannels)) &&
215 + (cOpenChannels > 0)) {
216 + if (DSP_FAILED(GetNumChannels(hChnlMgr, &cTotalChnls)))
217 + goto func_end;
219 + /* For each channel (except for RMS), get process handle: */
220 + for (uChnlID = 2; uChnlID < cTotalChnls; uChnlID++) {
221 + if (DSP_FAILED(CHNL_GetHandle(hChnlMgr, uChnlID,
222 + &hChnl))) {
223 + continue;
225 + if (DSP_FAILED(CHNL_GetProcessHandle(hChnl,
226 + &hProc))) {
227 + continue;
229 + /* See if channel owned by this process: */
230 + if (hProc == hProcess) {
231 + /* If so, close it now. */
232 + CHNL_Close(hChnl);
233 + status = DSP_SOK;
237 +func_end:
238 + GT_1trace(CHNL_DebugMask, GT_ENTER, "CHNL_CloseOrphans status 0x%x\n",
239 + status);
241 + return status;
245 + * ======== CHNL_Create ========
246 + * Purpose:
247 + * Create a channel manager object, responsible for opening new channels
248 + * and closing old ones for a given 'Bridge board.
249 + */
250 +DSP_STATUS CHNL_Create(OUT struct CHNL_MGR **phChnlMgr,
251 + struct DEV_OBJECT *hDevObject,
252 + IN CONST struct CHNL_MGRATTRS *pMgrAttrs)
254 + DSP_STATUS status;
255 + struct CHNL_MGR *hChnlMgr;
256 + struct CHNL_MGR_ *pChnlMgr = NULL;
258 + DBC_Require(cRefs > 0);
259 + DBC_Require(phChnlMgr != NULL);
260 + DBC_Require(pMgrAttrs != NULL);
262 + GT_3trace(CHNL_DebugMask, GT_ENTER,
263 + "Entered CHNL_Create: phChnlMgr: 0x%x\t"
264 + "hDevObject: 0x%x\tpMgrAttrs:0x%x\n",
265 + phChnlMgr, hDevObject, pMgrAttrs);
267 + *phChnlMgr = NULL;
269 + /* Validate args: */
270 + if ((0 < pMgrAttrs->cChannels) &&
271 + (pMgrAttrs->cChannels <= CHNL_MAXCHANNELS)) {
272 + status = DSP_SOK;
273 + } else if (pMgrAttrs->cChannels == 0) {
274 + status = DSP_EINVALIDARG;
275 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
276 + "CHNL_Create:Invalid Args\n");
277 + } else {
278 + status = CHNL_E_MAXCHANNELS;
279 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
280 + "CHNL_Create:Error Max Channels\n");
282 + if (pMgrAttrs->uWordSize == 0) {
283 + status = CHNL_E_INVALIDWORDSIZE;
284 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
285 + "CHNL_Create:Invalid Word size\n");
287 + if (DSP_SUCCEEDED(status)) {
288 + status = DEV_GetChnlMgr(hDevObject, &hChnlMgr);
289 + if (DSP_SUCCEEDED(status) && hChnlMgr != NULL)
290 + status = CHNL_E_MGREXISTS;
294 + if (DSP_SUCCEEDED(status)) {
295 + struct WMD_DRV_INTERFACE *pIntfFxns;
296 + DEV_GetIntfFxns(hDevObject, &pIntfFxns);
297 + /* Let WMD channel module finish the create: */
298 + status = (*pIntfFxns->pfnChnlCreate)(&hChnlMgr, hDevObject,
299 + pMgrAttrs);
300 + if (DSP_SUCCEEDED(status)) {
301 + /* Fill in WCD channel module's fields of the
302 + * CHNL_MGR structure */
303 + pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
304 + pChnlMgr->pIntfFxns = pIntfFxns;
305 + /* Finally, return the new channel manager handle: */
306 + *phChnlMgr = hChnlMgr;
307 + GT_1trace(CHNL_DebugMask, GT_1CLASS,
308 + "CHNL_Create: Success pChnlMgr:"
309 + "0x%x\n", pChnlMgr);
313 + GT_2trace(CHNL_DebugMask, GT_ENTER,
314 + "Exiting CHNL_Create: pChnlMgr: 0x%x,"
315 + "status: 0x%x\n", pChnlMgr, status);
316 + DBC_Ensure(DSP_FAILED(status) || CHNL_IsValidMgr(pChnlMgr));
318 + return status;
322 + * ======== CHNL_Destroy ========
323 + * Purpose:
324 + * Close all open channels, and destroy the channel manager.
325 + */
326 +DSP_STATUS CHNL_Destroy(struct CHNL_MGR *hChnlMgr)
328 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
329 + struct WMD_DRV_INTERFACE *pIntfFxns;
330 + DSP_STATUS status;
332 + DBC_Require(cRefs > 0);
334 + GT_1trace(CHNL_DebugMask, GT_ENTER,
335 + "Entered CHNL_Destroy: hChnlMgr: 0x%x\n", hChnlMgr);
336 + if (CHNL_IsValidMgr(pChnlMgr)) {
337 + pIntfFxns = pChnlMgr->pIntfFxns;
338 + /* Let WMD channel module destroy the CHNL_MGR: */
339 + status = (*pIntfFxns->pfnChnlDestroy)(hChnlMgr);
340 + } else {
341 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
342 + "CHNL_Destroy:Invalid Handle\n");
343 + status = DSP_EHANDLE;
346 + GT_2trace(CHNL_DebugMask, GT_ENTER,
347 + "Exiting CHNL_Destroy: pChnlMgr: 0x%x,"
348 + " status:0x%x\n", pChnlMgr, status);
349 + DBC_Ensure(DSP_FAILED(status) || !CHNL_IsValidMgr(pChnlMgr));
351 + return status;
355 + * ======== CHNL_Exit ========
356 + * Purpose:
357 + * Discontinue usage of the CHNL module.
358 + */
359 +void CHNL_Exit(void)
361 + DBC_Require(cRefs > 0);
363 + cRefs--;
365 + GT_1trace(CHNL_DebugMask, GT_5CLASS,
366 + "Entered CHNL_Exit, ref count: 0x%x\n", cRefs);
368 + DBC_Ensure(cRefs >= 0);
372 + * ======== CHNL_GetHandle ========
373 + * Purpose:
374 + * Retrieve the channel handle given the logical ID and channel manager.
375 + */
376 +DSP_STATUS CHNL_GetHandle(struct CHNL_MGR *hChnlMgr, u32 uChnlID,
377 + OUT struct CHNL_OBJECT **phChnl)
379 + DSP_STATUS status = DSP_SOK;
380 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
381 + struct WMD_DRV_INTERFACE *pIntfFxns;
382 + struct CHNL_MGRINFO chnlMgrInfo;
384 + DBC_Require(cRefs > 0);
386 + GT_3trace(CHNL_DebugMask, GT_ENTER, "Entered CHNL_GetHandle: hChnlMgr: "
387 + "0x%x\tuChnlID: 0x%x\t\nphChnl: 0x%x\n", hChnlMgr, uChnlID,
388 + phChnl);
389 + if (phChnl) {
390 + *phChnl = NULL;
391 + if (CHNL_IsValidMgr(pChnlMgr)) {
392 + pIntfFxns = pChnlMgr->pIntfFxns;
393 + status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr,
394 + uChnlID, &chnlMgrInfo);
395 + if (DSP_SUCCEEDED(status))
396 + *phChnl = chnlMgrInfo.hChnl;
398 + } else {
399 + status = DSP_EHANDLE;
400 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
401 + "CHNL_GetHandle:Invalid Handle\n");
403 + } else {
404 + status = DSP_EPOINTER;
406 + GT_2trace(CHNL_DebugMask, GT_ENTER,
407 + "Exit CHNL_GetHandle: status: 0x%x\t\n"
408 + "hChnl: 0x%x\n", status, *phChnl);
409 + return status;
413 + * ======== CHNL_GetProcessHandle ========
414 + * Purpose:
415 + * Retrieve the handle of the process owning this channel.
416 + */
417 +DSP_STATUS CHNL_GetProcessHandle(struct CHNL_OBJECT *hChnl,
418 + OUT HANDLE *phProcess)
420 + DSP_STATUS status = DSP_SOK;
421 + struct CHNL_OBJECT_ *pChnl = (struct CHNL_OBJECT_ *)hChnl;
422 + struct WMD_DRV_INTERFACE *pIntfFxns;
423 + struct CHNL_INFO chnlInfo;
425 + DBC_Require(cRefs > 0);
427 + GT_2trace(CHNL_DebugMask, GT_ENTER,
428 + "Enter CHNL_GetProcessHandle: hChnl: "
429 + "0x%x\t\n phProcess: 0x%x\n", hChnl, phProcess);
430 + if (phProcess) {
431 + *phProcess = NULL;
432 + if (CHNL_IsValidChnl(pChnl)) {
433 + pIntfFxns = pChnl->pChnlMgr->pIntfFxns;
434 + status = (*pIntfFxns->pfnChnlGetInfo)(hChnl, &chnlInfo);
435 + if (DSP_SUCCEEDED(status))
436 + *phProcess = chnlInfo.hProcess;
438 + } else {
439 + status = DSP_EHANDLE;
441 + } else {
442 + status = DSP_EPOINTER;
444 + GT_2trace(CHNL_DebugMask, GT_ENTER,
445 + "Exit CHNL_GetProcessHandle: status: "
446 + "0x%x\t\n phProcess: 0x%x\n", status, *phProcess);
447 + return status;
451 + * ======== CHNL_Init ========
452 + * Purpose:
453 + * Initialize the CHNL module's private state.
454 + */
455 +bool CHNL_Init(void)
457 + bool fRetval = true;
459 + DBC_Require(cRefs >= 0);
461 + if (cRefs == 0) {
462 + DBC_Assert(!CHNL_DebugMask.flags);
463 + GT_create(&CHNL_DebugMask, "CH"); /* "CH" for CHannel */
466 + if (fRetval)
467 + cRefs++;
469 + GT_1trace(CHNL_DebugMask, GT_5CLASS,
470 + "Entered CHNL_Init, ref count: 0x%x\n",
471 + cRefs);
473 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
475 + return fRetval;
479 + * ======== GetNumOpenChannels ========
480 + * Purpose:
481 + * Retrieve number of open channels
482 + * Parameters:
483 + * hChnlMgr: Handle to a valid channel manager, or NULL.
484 + * pcOpenChannels: Location to store number of open channels.
485 + * Returns:
486 + * DSP_SOK: Success;
487 + * DSP_EHANDLE: Invalid hChnlMgr.
488 + * E_POINTER: pcOpenChannels == NULL.
489 + * Requires:
490 + * Ensures:
491 + * DSP_SOK: *pcOpenChannels points to a valid number
492 + * if pcOpenChannels != NULL.
493 + */
494 +static DSP_STATUS GetNumOpenChannels(struct CHNL_MGR *hChnlMgr,
495 + OUT u32 *pcOpenChannels)
497 + DSP_STATUS status = DSP_SOK;
498 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
499 + struct WMD_DRV_INTERFACE *pIntfFxns;
500 + struct CHNL_MGRINFO chnlMgrInfo;
502 + DBC_Require(cRefs > 0);
503 + if (pcOpenChannels) {
504 + *pcOpenChannels = 0;
505 + if (CHNL_IsValidMgr(pChnlMgr)) {
506 + pIntfFxns = pChnlMgr->pIntfFxns;
507 + status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr, 0,
508 + &chnlMgrInfo);
509 + if (DSP_SUCCEEDED(status))
510 + *pcOpenChannels = chnlMgrInfo.cOpenChannels;
512 + } else {
513 + status = DSP_EHANDLE;
515 + } else {
516 + status = DSP_EPOINTER;
518 + return status;
522 + * ======== GetNumOpenChannels ========
523 + * Purpose:
524 + * Retrieve number of total channels supported.
525 + * Parameters:
526 + * hChnlMgr: Handle to a valid channel manager, or NULL.
527 + * pcChannels: Location to store number of channels.
528 + * Returns:
529 + * DSP_SOK: Success;
530 + * DSP_EHANDLE: Invalid hChnlMgr.
531 + * E_POINTER: pcOpenChannels == NULL.
532 + * Requires:
533 + * Ensures:
534 + * DSP_SOK: *pcChannels points to a valid number
535 + * if pcOpenChannels != NULL.
536 + */
537 +static DSP_STATUS GetNumChannels(struct CHNL_MGR *hChnlMgr,
538 + OUT u32 *pcChannels)
540 + DSP_STATUS status = DSP_SOK;
541 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
542 + struct WMD_DRV_INTERFACE *pIntfFxns;
543 + struct CHNL_MGRINFO chnlMgrInfo;
545 + DBC_Require(cRefs > 0);
547 + if (pcChannels) {
548 + *pcChannels = 0;
549 + if (CHNL_IsValidMgr(pChnlMgr)) {
550 + pIntfFxns = pChnlMgr->pIntfFxns;
551 + status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr, 0,
552 + &chnlMgrInfo);
553 + if (DSP_SUCCEEDED(status))
554 + *pcChannels = chnlMgrInfo.cChannels;
556 + } else {
557 + status = DSP_EHANDLE;
559 + } else {
560 + status = DSP_EPOINTER;
562 + return status;
565 diff --git a/drivers/dsp/bridge/pmgr/chnlobj.h b/drivers/dsp/bridge/pmgr/chnlobj.h
566 new file mode 100644
567 index 0000000..267d5d9
568 --- /dev/null
569 +++ b/drivers/dsp/bridge/pmgr/chnlobj.h
570 @@ -0,0 +1,71 @@
572 + * linux/drivers/dsp/bridge/pmgr/chnlobj.h
574 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
576 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
578 + * This package is free software; you can redistribute it and/or modify
579 + * it under the terms of the GNU General Public License version 2 as
580 + * published by the Free Software Foundation.
582 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
583 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
584 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
585 + */
589 + * ======== chnlobj.h ========
590 + * Description:
591 + * Structure subcomponents of channel class library channel objects which
592 + * are exposed to class driver from mini-driver.
594 + * Public Functions:
595 + * None.
597 + *! Revision History:
598 + *! ================
599 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
600 + *! 17-Nov-2000 jeh Removed some fields from CHNL_MGR_ to match CHNL_MGR
601 + *! structure defined in _chnl_sm.h.
602 + *! 16-Jan-1997 gp: Created from chnlpriv.h
603 + */
605 +#ifndef CHNLOBJ_
606 +#define CHNLOBJ_
608 +#include <chnldefs.h>
609 +#include <wmd.h>
611 +/* Object validateion macros: */
612 +#define CHNL_IsValidMgr(h) \
613 + ((h != NULL) && ((h)->dwSignature == CHNL_MGRSIGNATURE))
615 +#define CHNL_IsValidChnl(h)\
616 + ((h != NULL) && ((h)->dwSignature == CHNL_SIGNATURE))
619 + * This struct is the first field in a CHNL_MGR struct, as implemented in
620 + * a WMD channel class library. Other, implementation specific fields
621 + * follow this structure in memory.
622 + */
623 +struct CHNL_MGR_ {
624 + /* These must be the first fields in a CHNL_MGR struct: */
625 + u32 dwSignature; /* Used for object validation. */
626 + struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */
627 +} ;
630 + * This struct is the first field in a CHNL_OBJECT struct, as implemented in
631 + * a WMD channel class library. Other, implementation specific fields
632 + * follow this structure in memory.
633 + */
634 +struct CHNL_OBJECT_ {
635 + /* These must be the first fields in a CHNL_OBJECT struct: */
636 + u32 dwSignature; /* Used for object validation. */
637 + struct CHNL_MGR_ *pChnlMgr; /* Pointer back to channel manager. */
638 +} ;
640 +#endif /* CHNLOBJ_ */
642 diff --git a/drivers/dsp/bridge/pmgr/cmm.c b/drivers/dsp/bridge/pmgr/cmm.c
643 new file mode 100644
644 index 0000000..56d3c29
645 --- /dev/null
646 +++ b/drivers/dsp/bridge/pmgr/cmm.c
647 @@ -0,0 +1,1290 @@
649 + * linux/drivers/dsp/bridge/pmgr/cmm.c
651 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
653 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
655 + * This package is free software; you can redistribute it and/or modify
656 + * it under the terms of the GNU General Public License version 2 as
657 + * published by the Free Software Foundation.
659 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
660 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
661 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
662 + */
666 + * ======== cmm.c ========
667 + * Purpose:
668 + * The Communication(Shared) Memory Management(CMM) module provides
669 + * shared memory management services for DSP/BIOS Bridge data streaming
670 + * and messaging.
672 + * Multiple shared memory segments can be registered with CMM.
673 + * Each registered SM segment is represented by a SM "allocator" that
674 + * describes a block of physically contiguous shared memory used for
675 + * future allocations by CMM.
677 + * Memory is coelesced back to the appropriate heap when a buffer is
678 + * freed.
680 + * Public Functions:
681 + * CMM_CallocBuf
682 + * CMM_Create
683 + * CMM_Destroy
684 + * CMM_Exit
685 + * CMM_FreeBuf
686 + * CMM_GetHandle
687 + * CMM_GetInfo
688 + * CMM_Init
689 + * CMM_RegisterGPPSMSeg
690 + * CMM_UnRegisterGPPSMSeg
692 + * The CMM_Xlator[xxx] routines below are used by Node and Stream
693 + * to perform SM address translation to the client process address space.
694 + * A "translator" object is created by a node/stream for each SM seg used.
696 + * Translator Routines:
697 + * CMM_XlatorAllocBuf
698 + * CMM_XlatorCreate
699 + * CMM_XlatorDelete
700 + * CMM_XlatorFreeBuf
701 + * CMM_XlatorInfo
702 + * CMM_XlatorTranslate
704 + * Private Functions:
705 + * AddToFreeList
706 + * GetAllocator
707 + * GetFreeBlock
708 + * GetNode
709 + * GetSlot
710 + * UnRegisterGPPSMSeg
712 + * Notes:
713 + * Va: Virtual address.
714 + * Pa: Physical or kernel system address.
716 + *! Revision History:
717 + *! ================
718 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
719 + *! 16-Feb-2002 ag Code review cleanup.
720 + *! PreOMAP address translation no longner supported.
721 + *! 30-Jan-2002 ag Updates to CMM_XlatorTranslate() per TII, ANSI C++
722 + *! warnings.
723 + *! 27-Jan-2002 ag Removed unused CMM_[Alloc][Free]Desc() & #ifdef USELOOKUP,
724 + *! & unused VALIDATECMM and VaPaConvert().
725 + *! Removed bFastXlate from CMM_XLATOR. Always fast lookup.
726 + *! 03-Jan-2002 ag Clear SM in CMM_AllocBuf(). Renamed to CMM_CallocBuf().
727 + *! 13-Nov-2001 ag Now delete pNodeFreeListHead and nodes in CMM_Destroy().
728 + *! 28-Aug-2001 ag CMM_GetHandle() returns CMM Mgr hndle given HPROCESSOR.
729 + *! Removed unused CMM_[Un]RegisterDSPSMSeg() &
730 + * CMM_[Un}ReserveVirtSpace fxns. Some cleanup.
731 + *! 12-Aug-2001 ag Exposed CMM_UnRegisterGPP[DSP]SMSeg.
732 + *! 13-Feb-2001 kc DSP/BIOS Bridge name update.
733 + *! 21-Dec-2000 rr GetFreeBlock checks for pAllocator.
734 + *! 09-Dec-2000 ag Added GPPPA2DSPPA, DSPPA2GPPPA macros.
735 + *! 05-Dec-2000 ag CMM_XlatorDelete() optionally frees SM bufs and descriptors.
736 + *! 30-Oct-2000 ag Buf size bug fixed in CMM_AllocBuf() causing leak.
737 + *! Revamped XlatorTranslate() routine.
738 + *! 10-Oct-2000 ag Added CMM_Xlator[xxx] functions.
739 + *! 02-Aug-2000 ag Created.
740 + *!
741 + */
743 +/* ----------------------------------- DSP/BIOS Bridge */
744 +#include <std.h>
745 +#include <dbdefs.h>
747 +/* ----------------------------------- Trace & Debug */
748 +#include <dbc.h>
749 +#include <errbase.h>
750 +#include <gt.h>
752 +/* ----------------------------------- OS Adaptation Layer */
753 +#include <cfg.h>
754 +#include <list.h>
755 +#include <mem.h>
756 +#include <prcs.h>
757 +#include <sync.h>
758 +#include <util.h>
760 +/* ----------------------------------- Platform Manager */
761 +#include <dev.h>
762 +#include <proc.h>
764 +/* ----------------------------------- This */
765 +#include <cmm.h>
767 +/* ----------------------------------- Defines, Data Structures, Typedefs */
768 +/* Object signatures */
769 +#define CMMSIGNATURE 0x004d4d43 /* "CMM" (in reverse) */
770 +#define SMEMSIGNATURE 0x4D454D53 /* "SMEM" SM space */
771 +#define CMMXLATESIGNATURE 0x584d4d43 /* "CMMX" CMM Xlator */
773 +#define NEXT_PA(pNode) (pNode->dwPA + pNode->ulSize)
775 +/* Other bus/platform translations */
776 +#define DSPPA2GPPPA(base, x, y) ((x)+(y))
777 +#define GPPPA2DSPPA(base, x, y) ((x)-(y))
780 + * Allocators define a block of contiguous memory used for future allocations.
782 + * sma - shared memory allocator.
783 + * vma - virtual memory allocator.(not used).
784 + */
785 +struct CMM_ALLOCATOR { /* sma */
786 + u32 dwSignature; /* SMA allocator signature SMEMSIGNATURE */
787 + unsigned int dwSmBase; /* Start of physical SM block */
788 + u32 ulSmSize; /* Size of SM block in bytes */
789 + unsigned int dwVmBase; /* Start of VM block. (Dev driver
790 + * context for 'sma') */
791 + u32 dwDSPPhysAddrOffset; /* DSP PA to GPP PA offset for this
792 + * SM space */
793 + /* CMM_ADDTO[SUBFROM]DSPPA, _POMAPEMIF2DSPBUS */
794 + enum CMM_CNVTTYPE cFactor;
795 + unsigned int dwDSPBase; /* DSP virt base byte address */
796 + u32 ulDSPSize; /* DSP seg size in bytes */
797 + struct CMM_OBJECT *hCmmMgr; /* back ref to parent mgr */
798 + struct LST_LIST *pFreeListHead; /* node list of available memory */
799 + struct LST_LIST *pInUseListHead; /* node list of memory in use */
800 +} ;
802 +struct CMM_XLATOR { /* Pa<->Va translator object */
803 + u32 dwSignature; /* "CMMX" */
804 + struct CMM_OBJECT *hCmmMgr; /* CMM object this translator associated */
805 + /*
806 + * Client process virtual base address that corresponds to phys SM
807 + * base address for translator's ulSegId.
808 + * Only 1 segment ID currently supported.
809 + */
810 + unsigned int dwVirtBase; /* virtual base address */
811 + u32 ulVirtSize; /* size of virt space in bytes */
812 + u32 ulSegId; /* Segment Id */
813 +} ;
815 +/* CMM Mgr */
816 +struct CMM_OBJECT {
817 + u32 dwSignature; /* Used for object validation */
818 + /*
819 + * Cmm Lock is used to serialize access mem manager for multi-threads.
820 + */
821 + struct SYNC_CSOBJECT *hCmmLock; /* Lock to access cmm mgr */
822 + struct LST_LIST *pNodeFreeListHead; /* Free list of memory nodes */
823 + u32 ulMinBlockSize; /* Min SM block; default 16 bytes */
824 + u32 dwPageSize; /* Memory Page size (1k/4k) */
825 + /* GPP SM segment ptrs */
826 + struct CMM_ALLOCATOR *paGPPSMSegTab[CMM_MAXGPPSEGS];
827 +} ;
829 +/* Default CMM Mgr attributes */
830 +static struct CMM_MGRATTRS CMM_DFLTMGRATTRS = {
831 + 16 /* ulMinBlockSize, min block size(bytes) allocated by cmm mgr */
834 +/* Default allocation attributes */
835 +static struct CMM_ATTRS CMM_DFLTALCTATTRS = {
836 + 1 /* ulSegId, default segment Id for allocator */
839 +/* Address translator default attrs */
840 +struct CMM_XLATORATTRS CMM_DFLTXLATORATTRS = {
841 + 1, /* ulSegId, does not have to match CMM_DFLTALCTATTRS ulSegId */
842 + 0, /* dwDSPBufs */
843 + 0, /* dwDSPBufSize */
844 + NULL, /* pVmBase */
845 + 0, /* dwVmSize */
848 +/* SM node representing a block of memory. */
849 +struct CMM_MNODE {
850 + struct LST_ELEM link; /* must be 1st element */
851 + u32 dwPA; /* Phys addr */
852 + u32 dwVA; /* Virtual address in device process context */
853 + u32 ulSize; /* SM block size in bytes */
854 + HANDLE hClientProc; /* Process that allocated this mem block */
855 +} ;
858 +/* ----------------------------------- Globals */
859 +#if GT_TRACE
860 +static struct GT_Mask CMM_debugMask = { NULL, NULL }; /* GT trace variable */
861 +#endif
863 +static u32 cRefs; /* module reference count */
865 +/* ----------------------------------- Function Prototypes */
866 +static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator,
867 + struct CMM_MNODE *pNode);
868 +static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr,
869 + u32 ulSegId);
870 +static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator,
871 + u32 uSize);
872 +static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA,
873 + u32 dwVA, u32 ulSize);
874 +/* get available slot for new allocator */
875 +static s32 GetSlot(struct CMM_OBJECT *hCmmMgr);
876 +static void UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA);
879 + * ======== CMM_CallocBuf ========
880 + * Purpose:
881 + * Allocate a SM buffer, zero contents, and return the physical address
882 + * and optional driver context virtual address(ppBufVA).
884 + * The freelist is sorted in increasing size order. Get the first
885 + * block that satifies the request and sort the remaining back on
886 + * the freelist; if large enough. The kept block is placed on the
887 + * inUseList.
888 + */
889 +void *CMM_CallocBuf(struct CMM_OBJECT *hCmmMgr, u32 uSize,
890 + struct CMM_ATTRS *pAttrs, OUT void **ppBufVA)
892 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
893 + void *pBufPA = NULL;
894 + struct CMM_MNODE *pNode = NULL;
895 + struct CMM_MNODE *pNewNode = NULL;
896 + struct CMM_ALLOCATOR *pAllocator = NULL;
897 + u32 uDeltaSize;
898 + u8 *pByte = NULL;
899 + s32 cnt;
901 + if (pAttrs == NULL)
902 + pAttrs = &CMM_DFLTALCTATTRS;
904 + if (ppBufVA != NULL)
905 + *ppBufVA = NULL;
907 + if ((MEM_IsValidHandle(pCmmMgr, CMMSIGNATURE)) && (uSize != 0)) {
908 + if (pAttrs->ulSegId > 0) {
909 + /* SegId > 0 is SM */
910 + /* get the allocator object for this segment id */
911 + pAllocator = GetAllocator(pCmmMgr, pAttrs->ulSegId);
912 + /* keep block size a multiple of ulMinBlockSize */
913 + uSize = ((uSize - 1) & ~(pCmmMgr->ulMinBlockSize - 1))
914 + + pCmmMgr->ulMinBlockSize;
915 + SYNC_EnterCS(pCmmMgr->hCmmLock);
916 + pNode = GetFreeBlock(pAllocator, uSize);
918 + if (pNode) {
919 + uDeltaSize = (pNode->ulSize - uSize);
920 + if (uDeltaSize >= pCmmMgr->ulMinBlockSize) {
921 + /* create a new block with the leftovers and
922 + * add to freelist */
923 + pNewNode = GetNode(pCmmMgr, pNode->dwPA + uSize,
924 + pNode->dwVA + uSize,
925 + (u32)uDeltaSize);
926 + /* leftovers go free */
927 + AddToFreeList(pAllocator, pNewNode);
928 + /* adjust our node's size */
929 + pNode->ulSize = uSize;
931 + /* Tag node with client process requesting allocation
932 + * We'll need to free up a process's alloc'd SM if the
933 + * client process goes away.
934 + */
935 + (void)PRCS_GetCurrentHandle(&pNode->hClientProc);
936 + /* put our node on InUse list */
937 + LST_PutTail(pAllocator->pInUseListHead,
938 + (struct LST_ELEM *)pNode);
939 + pBufPA = (void *)pNode->dwPA; /* physical address */
940 + /* clear mem */
941 + pByte = (u8 *)pNode->dwVA;
942 + for (cnt = 0; cnt < (s32) uSize; cnt++, pByte++)
943 + *pByte = 0;
945 + if (ppBufVA != NULL) {
946 + /* Virtual address */
947 + *ppBufVA = (void *)pNode->dwVA;
950 + GT_3trace(CMM_debugMask, GT_3CLASS,
951 + "CMM_CallocBuf dwPA %x, dwVA %x uSize"
952 + "%x\n", pNode->dwPA, pNode->dwVA, uSize);
953 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
955 + return pBufPA;
959 + * ======== CMM_Create ========
960 + * Purpose:
961 + * Create a communication memory manager object.
962 + */
963 +DSP_STATUS CMM_Create(OUT struct CMM_OBJECT **phCmmMgr,
964 + struct DEV_OBJECT *hDevObject,
965 + IN CONST struct CMM_MGRATTRS *pMgrAttrs)
967 + struct CMM_OBJECT *pCmmObject = NULL;
968 + DSP_STATUS status = DSP_SOK;
969 + struct UTIL_SYSINFO sysInfo;
971 + DBC_Require(cRefs > 0);
972 + DBC_Require(phCmmMgr != NULL);
974 + GT_3trace(CMM_debugMask, GT_ENTER,
975 + "CMM_Create: phCmmMgr: 0x%x\thDevObject: "
976 + "0x%x\tpMgrAttrs: 0x%x\n", phCmmMgr, hDevObject, pMgrAttrs);
977 + *phCmmMgr = NULL;
978 + /* create, zero, and tag a cmm mgr object */
979 + MEM_AllocObject(pCmmObject, struct CMM_OBJECT, CMMSIGNATURE);
980 + if (pCmmObject != NULL) {
981 + if (pMgrAttrs == NULL)
982 + pMgrAttrs = &CMM_DFLTMGRATTRS; /* set defaults */
984 + /* 4 bytes minimum */
985 + DBC_Assert(pMgrAttrs->ulMinBlockSize >= 4);
986 + /* save away smallest block allocation for this cmm mgr */
987 + pCmmObject->ulMinBlockSize = pMgrAttrs->ulMinBlockSize;
988 + /* save away the systems memory page size */
989 + sysInfo.dwPageSize = PAGE_SIZE;
990 + sysInfo.dwAllocationGranularity = PAGE_SIZE;
991 + sysInfo.dwNumberOfProcessors = 1;
992 + if (DSP_SUCCEEDED(status)) {
993 + GT_1trace(CMM_debugMask, GT_5CLASS,
994 + "CMM_Create: Got system page size"
995 + "= 0x%x\t\n", sysInfo.dwPageSize);
996 + pCmmObject->dwPageSize = sysInfo.dwPageSize;
997 + } else {
998 + GT_0trace(CMM_debugMask, GT_7CLASS,
999 + "CMM_Create: failed to get system"
1000 + "page size\n");
1001 + pCmmObject->dwPageSize = 0;
1002 + status = DSP_EFAIL;
1004 + /* Note: DSP SM seg table(aDSPSMSegTab[]) zero'd by
1005 + * MEM_AllocObject */
1006 + if (DSP_SUCCEEDED(status)) {
1007 + /* create node free list */
1008 + pCmmObject->pNodeFreeListHead = LST_Create();
1009 + if (pCmmObject->pNodeFreeListHead == NULL) {
1010 + GT_0trace(CMM_debugMask, GT_7CLASS,
1011 + "CMM_Create: LST_Create() "
1012 + "failed \n");
1013 + status = DSP_EMEMORY;
1016 + if (DSP_SUCCEEDED(status))
1017 + status = SYNC_InitializeCS(&pCmmObject->hCmmLock);
1019 + if (DSP_SUCCEEDED(status))
1020 + *phCmmMgr = pCmmObject;
1021 + else
1022 + CMM_Destroy(pCmmObject, true);
1024 + } else {
1025 + GT_0trace(CMM_debugMask, GT_6CLASS,
1026 + "CMM_Create: Object Allocation "
1027 + "Failure(CMM Object)\n");
1028 + status = DSP_EMEMORY;
1030 + return status;
1034 + * ======== CMM_Destroy ========
1035 + * Purpose:
1036 + * Release the communication memory manager resources.
1037 + */
1038 +DSP_STATUS CMM_Destroy(struct CMM_OBJECT *hCmmMgr, bool bForce)
1040 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1041 + struct CMM_INFO tempInfo;
1042 + DSP_STATUS status = DSP_SOK;
1043 + s32 nSlot;
1044 + struct CMM_MNODE *pNode;
1046 + DBC_Require(cRefs > 0);
1047 + if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1048 + status = DSP_EHANDLE;
1049 + return status;
1051 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1052 + /* If not force then fail if outstanding allocations exist */
1053 + if (!bForce) {
1054 + /* Check for outstanding memory allocations */
1055 + status = CMM_GetInfo(hCmmMgr, &tempInfo);
1056 + if (DSP_SUCCEEDED(status)) {
1057 + if (tempInfo.ulTotalInUseCnt > 0) {
1058 + /* outstanding allocations */
1059 + status = DSP_EFAIL;
1063 + if (DSP_SUCCEEDED(status)) {
1064 + /* UnRegister SM allocator */
1065 + for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) {
1066 + if (pCmmMgr->paGPPSMSegTab[nSlot] != NULL) {
1067 + UnRegisterGPPSMSeg(pCmmMgr->
1068 + paGPPSMSegTab[nSlot]);
1069 + /* Set slot to NULL for future reuse */
1070 + pCmmMgr->paGPPSMSegTab[nSlot] = NULL;
1074 + if (pCmmMgr->pNodeFreeListHead != NULL) {
1075 + /* Free the free nodes */
1076 + while (!LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) {
1077 + /* (struct LST_ELEM*) pNode =
1078 + * LST_GetHead(pCmmMgr->pNodeFreeListHead);*/
1079 + pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr->
1080 + pNodeFreeListHead);
1081 + MEM_Free(pNode);
1083 + /* delete NodeFreeList list */
1084 + LST_Delete(pCmmMgr->pNodeFreeListHead);
1086 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1087 + if (DSP_SUCCEEDED(status)) {
1088 + /* delete CS & cmm mgr object */
1089 + SYNC_DeleteCS(pCmmMgr->hCmmLock);
1090 + MEM_FreeObject(pCmmMgr);
1092 + return status;
1096 + * ======== CMM_Exit ========
1097 + * Purpose:
1098 + * Discontinue usage of module; free resources when reference count
1099 + * reaches 0.
1100 + */
1101 +void CMM_Exit(void)
1103 + DBC_Require(cRefs > 0);
1105 + cRefs--;
1107 + GT_1trace(CMM_debugMask, GT_ENTER,
1108 + "exiting CMM_Exit,ref count:0x%x\n", cRefs);
1112 + * ======== CMM_FreeBuf ========
1113 + * Purpose:
1114 + * Free the given buffer.
1115 + */
1116 +DSP_STATUS CMM_FreeBuf(struct CMM_OBJECT *hCmmMgr, void *pBufPA, u32 ulSegId)
1118 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1119 + DSP_STATUS status = DSP_EPOINTER;
1120 + struct CMM_MNODE *pCurNode = NULL;
1121 + struct CMM_ALLOCATOR *pAllocator = NULL;
1122 + struct CMM_ATTRS *pAttrs;
1124 + DBC_Require(cRefs > 0);
1125 + DBC_Require(pBufPA != NULL);
1126 + GT_1trace(CMM_debugMask, GT_ENTER, "CMM_FreeBuf pBufPA %x\n", pBufPA);
1127 + if (ulSegId == 0) {
1128 + pAttrs = &CMM_DFLTALCTATTRS;
1129 + ulSegId = pAttrs->ulSegId;
1131 + if (!(MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) || !(ulSegId > 0)) {
1132 + status = DSP_EHANDLE;
1133 + return status;
1135 + /* get the allocator for this segment id */
1136 + pAllocator = GetAllocator(pCmmMgr, ulSegId);
1137 + if (pAllocator != NULL) {
1138 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1139 + pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->
1140 + pInUseListHead);
1141 + while (pCurNode) {
1142 + if ((u32)pBufPA == pCurNode->dwPA) {
1143 + /* Found it */
1144 + LST_RemoveElem(pAllocator->pInUseListHead,
1145 + (struct LST_ELEM *)pCurNode);
1146 + /* back to freelist */
1147 + AddToFreeList(pAllocator, pCurNode);
1148 + status = DSP_SOK; /* all right! */
1149 + break;
1151 + /* next node. */
1152 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1153 + pInUseListHead, (struct LST_ELEM *)pCurNode);
1155 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1157 + return status;
1161 + * ======== CMM_GetHandle ========
1162 + * Purpose:
1163 + * Return the communication memory manager object for this device.
1164 + * This is typically called from the client process.
1165 + */
1166 +DSP_STATUS CMM_GetHandle(DSP_HPROCESSOR hProcessor,
1167 + OUT struct CMM_OBJECT **phCmmMgr)
1169 + DSP_STATUS status = DSP_SOK;
1170 + struct DEV_OBJECT *hDevObject;
1172 + DBC_Require(cRefs > 0);
1173 + DBC_Require(phCmmMgr != NULL);
1174 + if (hProcessor != NULL)
1175 + status = PROC_GetDevObject(hProcessor, &hDevObject);
1176 + else
1177 + hDevObject = DEV_GetFirst(); /* default */
1179 + if (DSP_SUCCEEDED(status))
1180 + status = DEV_GetCmmMgr(hDevObject, phCmmMgr);
1182 + return status;
1186 + * ======== CMM_GetInfo ========
1187 + * Purpose:
1188 + * Return the current memory utilization information.
1189 + */
1190 +DSP_STATUS CMM_GetInfo(struct CMM_OBJECT *hCmmMgr,
1191 + OUT struct CMM_INFO *pCmmInfo)
1193 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1194 + u32 ulSeg;
1195 + DSP_STATUS status = DSP_SOK;
1196 + struct CMM_ALLOCATOR *pAltr;
1197 + struct CMM_MNODE *pCurNode = NULL;
1199 + DBC_Require(pCmmInfo != NULL);
1201 + if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1202 + status = DSP_EHANDLE;
1203 + return status;
1205 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1206 + pCmmInfo->ulNumGPPSMSegs = 0; /* # of SM segments */
1207 + pCmmInfo->ulTotalInUseCnt = 0; /* Total # of outstanding alloc */
1208 + pCmmInfo->ulMinBlockSize = pCmmMgr->ulMinBlockSize; /* min block size */
1209 + /* check SM memory segments */
1210 + for (ulSeg = 1; ulSeg <= CMM_MAXGPPSEGS; ulSeg++) {
1211 + /* get the allocator object for this segment id */
1212 + pAltr = GetAllocator(pCmmMgr, ulSeg);
1213 + if (pAltr != NULL) {
1214 + pCmmInfo->ulNumGPPSMSegs++;
1215 + pCmmInfo->segInfo[ulSeg - 1].dwSegBasePa =
1216 + pAltr->dwSmBase - pAltr->ulDSPSize;
1217 + pCmmInfo->segInfo[ulSeg - 1].ulTotalSegSize =
1218 + pAltr->ulDSPSize + pAltr->ulSmSize;
1219 + pCmmInfo->segInfo[ulSeg - 1].dwGPPBasePA =
1220 + pAltr->dwSmBase;
1221 + pCmmInfo->segInfo[ulSeg - 1].ulGPPSize =
1222 + pAltr->ulSmSize;
1223 + pCmmInfo->segInfo[ulSeg - 1].dwDSPBaseVA =
1224 + pAltr->dwDSPBase;
1225 + pCmmInfo->segInfo[ulSeg - 1].ulDSPSize =
1226 + pAltr->ulDSPSize;
1227 + pCmmInfo->segInfo[ulSeg - 1].dwSegBaseVa =
1228 + pAltr->dwVmBase - pAltr->ulDSPSize;
1229 + pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt = 0;
1230 + pCurNode = (struct CMM_MNODE *)LST_First(pAltr->
1231 + pInUseListHead);
1232 + /* Count inUse blocks */
1233 + while (pCurNode) {
1234 + pCmmInfo->ulTotalInUseCnt++;
1235 + pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt++;
1236 + /* next node. */
1237 + pCurNode = (struct CMM_MNODE *)LST_Next(pAltr->
1238 + pInUseListHead,
1239 + (struct LST_ELEM *)pCurNode);
1242 + } /* end for */
1243 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1244 + return status;
1248 + * ======== CMM_Init ========
1249 + * Purpose:
1250 + * Initializes private state of CMM module.
1251 + */
1252 +bool CMM_Init(void)
1254 + bool fRetval = true;
1256 + DBC_Require(cRefs >= 0);
1257 + if (cRefs == 0) {
1258 + /* Set the Trace mask */
1259 + /* "CM" for Comm Memory manager */
1260 + GT_create(&CMM_debugMask, "CM");
1262 + if (fRetval)
1263 + cRefs++;
1265 + GT_1trace(CMM_debugMask, GT_ENTER,
1266 + "Entered CMM_Init,ref count:0x%x\n", cRefs);
1268 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
1270 + return fRetval;
1274 + * ======== CMM_RegisterGPPSMSeg ========
1275 + * Purpose:
1276 + * Register a block of SM with the CMM to be used for later GPP SM
1277 + * allocations.
1278 + */
1279 +DSP_STATUS CMM_RegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 dwGPPBasePA,
1280 + u32 ulSize, u32 dwDSPAddrOffset,
1281 + enum CMM_CNVTTYPE cFactor, u32 dwDSPBase,
1282 + u32 ulDSPSize, u32 *pulSegId,
1283 + u32 dwGPPBaseVA)
1285 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1286 + struct CMM_ALLOCATOR *pSMA = NULL;
1287 + DSP_STATUS status = DSP_SOK;
1288 + struct CMM_MNODE *pNewNode;
1289 + s32 nSlot;
1291 + DBC_Require(ulSize > 0);
1292 + DBC_Require(pulSegId != NULL);
1293 + DBC_Require(dwGPPBasePA != 0);
1294 + DBC_Require(dwGPPBaseVA != 0);
1295 + DBC_Require((cFactor <= CMM_ADDTODSPPA) &&
1296 + (cFactor >= CMM_SUBFROMDSPPA));
1297 + GT_6trace(CMM_debugMask, GT_ENTER,
1298 + "CMM_RegisterGPPSMSeg dwGPPBasePA %x "
1299 + "ulSize %x dwDSPAddrOffset %x dwDSPBase %x ulDSPSize %x "
1300 + "dwGPPBaseVA %x\n", dwGPPBasePA, ulSize, dwDSPAddrOffset,
1301 + dwDSPBase, ulDSPSize, dwGPPBaseVA);
1302 + if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1303 + status = DSP_EHANDLE;
1304 + return status;
1306 + /* make sure we have room for another allocator */
1307 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1308 + nSlot = GetSlot(pCmmMgr);
1309 + if (nSlot < 0) {
1310 + /* get a slot number */
1311 + status = DSP_EFAIL;
1312 + goto func_end;
1314 + /* Check if input ulSize is big enough to alloc at least one block */
1315 + if (DSP_SUCCEEDED(status)) {
1316 + if (ulSize < pCmmMgr->ulMinBlockSize) {
1317 + GT_0trace(CMM_debugMask, GT_7CLASS,
1318 + "CMM_RegisterGPPSMSeg: "
1319 + "ulSize too small\n");
1320 + status = DSP_EINVALIDARG;
1321 + goto func_end;
1324 + if (DSP_SUCCEEDED(status)) {
1325 + /* create, zero, and tag an SM allocator object */
1326 + MEM_AllocObject(pSMA, struct CMM_ALLOCATOR, SMEMSIGNATURE);
1328 + if (pSMA != NULL) {
1329 + pSMA->hCmmMgr = hCmmMgr; /* ref to parent */
1330 + pSMA->dwSmBase = dwGPPBasePA; /* SM Base phys */
1331 + pSMA->ulSmSize = ulSize; /* SM segment size in bytes */
1332 + pSMA->dwVmBase = dwGPPBaseVA;
1333 + pSMA->dwDSPPhysAddrOffset = dwDSPAddrOffset;
1334 + pSMA->cFactor = cFactor;
1335 + pSMA->dwDSPBase = dwDSPBase;
1336 + pSMA->ulDSPSize = ulDSPSize;
1337 + if (pSMA->dwVmBase == 0) {
1338 + GT_0trace(CMM_debugMask, GT_7CLASS,
1339 + "CMM_RegisterGPPSMSeg: Error"
1340 + "MEM_LinearAddress()\n");
1341 + status = DSP_EFAIL;
1342 + goto func_end;
1344 + if (DSP_SUCCEEDED(status)) {
1345 + /* return the actual segment identifier */
1346 + *pulSegId = (u32) nSlot + 1;
1347 + /* create memory free list */
1348 + pSMA->pFreeListHead = LST_Create();
1349 + if (pSMA->pFreeListHead == NULL) {
1350 + GT_0trace(CMM_debugMask, GT_7CLASS,
1351 + "CMM_RegisterGPPSMSeg: "
1352 + "Out Of Memory \n");
1353 + status = DSP_EMEMORY;
1354 + goto func_end;
1357 + if (DSP_SUCCEEDED(status)) {
1358 + /* create memory in-use list */
1359 + pSMA->pInUseListHead = LST_Create();
1360 + if (pSMA->pInUseListHead == NULL) {
1361 + GT_0trace(CMM_debugMask, GT_7CLASS,
1362 + "CMM_RegisterGPPSMSeg: "
1363 + "LST_Create failed\n");
1364 + status = DSP_EMEMORY;
1365 + goto func_end;
1368 + if (DSP_SUCCEEDED(status)) {
1369 + /* Get a mem node for this hunk-o-memory */
1370 + pNewNode = GetNode(pCmmMgr, dwGPPBasePA,
1371 + pSMA->dwVmBase, ulSize);
1372 + /* Place node on the SM allocator's free list */
1373 + if (pNewNode) {
1374 + LST_PutTail(pSMA->pFreeListHead,
1375 + (struct LST_ELEM *)pNewNode);
1376 + } else {
1377 + status = DSP_EMEMORY;
1378 + goto func_end;
1381 + if (DSP_FAILED(status)) {
1382 + /* Cleanup allocator */
1383 + UnRegisterGPPSMSeg(pSMA);
1385 + } else {
1386 + GT_0trace(CMM_debugMask, GT_6CLASS,
1387 + "CMM_RegisterGPPSMSeg: SMA Object "
1388 + "Allocation Failure\n");
1389 + status = DSP_EMEMORY;
1390 + goto func_end;
1392 + /* make entry */
1393 + if (DSP_SUCCEEDED(status))
1394 + pCmmMgr->paGPPSMSegTab[nSlot] = pSMA;
1396 +func_end:
1397 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1398 + return status;
1402 + * ======== CMM_UnRegisterGPPSMSeg ========
1403 + * Purpose:
1404 + * UnRegister GPP SM segments with the CMM.
1405 + */
1406 +DSP_STATUS CMM_UnRegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 ulSegId)
1408 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1409 + DSP_STATUS status = DSP_SOK;
1410 + struct CMM_ALLOCATOR *pSMA;
1411 + u32 ulId = ulSegId;
1413 + DBC_Require(ulSegId > 0);
1414 + if (MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1415 + if (ulSegId == CMM_ALLSEGMENTS)
1416 + ulId = 1;
1418 + if ((ulId > 0) && (ulId <= CMM_MAXGPPSEGS)) {
1419 + while (ulId <= CMM_MAXGPPSEGS) {
1420 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1421 + /* slot = segId-1 */
1422 + pSMA = pCmmMgr->paGPPSMSegTab[ulId - 1];
1423 + if (pSMA != NULL) {
1424 + UnRegisterGPPSMSeg(pSMA);
1425 + /* Set alctr ptr to NULL for future
1426 + * reuse */
1427 + pCmmMgr->paGPPSMSegTab[ulId - 1] = NULL;
1428 + } else if (ulSegId != CMM_ALLSEGMENTS) {
1429 + status = DSP_EFAIL;
1431 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1432 + if (ulSegId != CMM_ALLSEGMENTS)
1433 + break;
1435 + ulId++;
1436 + } /* end while */
1437 + } else {
1438 + status = DSP_EINVALIDARG;
1439 + GT_0trace(CMM_debugMask, GT_7CLASS,
1440 + "CMM_UnRegisterGPPSMSeg: Bad "
1441 + "segment Id\n");
1443 + } else {
1444 + status = DSP_EHANDLE;
1446 + return status;
1450 + * ======== UnRegisterGPPSMSeg ========
1451 + * Purpose:
1452 + * UnRegister the SM allocator by freeing all its resources and
1453 + * nulling cmm mgr table entry.
1454 + * Note:
1455 + * This routine is always called within cmm lock crit sect.
1456 + */
1457 +static void UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA)
1459 + struct CMM_MNODE *pCurNode = NULL;
1460 + struct CMM_MNODE *pNextNode = NULL;
1462 + DBC_Require(pSMA != NULL);
1463 + if (pSMA->pFreeListHead != NULL) {
1464 + /* free nodes on free list */
1465 + pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pFreeListHead);
1466 + while (pCurNode) {
1467 + pNextNode = (struct CMM_MNODE *)LST_Next(pSMA->
1468 + pFreeListHead,
1469 + (struct LST_ELEM *)pCurNode);
1470 + LST_RemoveElem(pSMA->pFreeListHead,
1471 + (struct LST_ELEM *)pCurNode);
1472 + MEM_Free((void *) pCurNode);
1473 + /* next node. */
1474 + pCurNode = pNextNode;
1476 + LST_Delete(pSMA->pFreeListHead); /* delete freelist */
1477 + /* free nodes on InUse list */
1478 + pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pInUseListHead);
1479 + while (pCurNode) {
1480 + pNextNode = (struct CMM_MNODE *)LST_Next(pSMA->
1481 + pInUseListHead,
1482 + (struct LST_ELEM *)pCurNode);
1483 + LST_RemoveElem(pSMA->pInUseListHead,
1484 + (struct LST_ELEM *)pCurNode);
1485 + MEM_Free((void *) pCurNode);
1486 + /* next node. */
1487 + pCurNode = pNextNode;
1489 + LST_Delete(pSMA->pInUseListHead); /* delete InUse list */
1491 + if ((void *) pSMA->dwVmBase != NULL)
1492 + MEM_UnmapLinearAddress((void *) pSMA->dwVmBase);
1494 + /* Free allocator itself */
1495 + MEM_FreeObject(pSMA);
1499 + * ======== GetSlot ========
1500 + * Purpose:
1501 + * An available slot # is returned. Returns negative on failure.
1502 + */
1503 +static s32 GetSlot(struct CMM_OBJECT *pCmmMgr)
1505 + s32 nSlot = -1; /* neg on failure */
1506 + DBC_Require(pCmmMgr != NULL);
1507 + /* get first available slot in cmm mgr SMSegTab[] */
1508 + for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) {
1509 + if (pCmmMgr->paGPPSMSegTab[nSlot] == NULL)
1510 + break;
1513 + if (nSlot == CMM_MAXGPPSEGS) {
1514 + GT_0trace(CMM_debugMask, GT_7CLASS,
1515 + "CMM_RegisterGPPSMSeg: Allocator "
1516 + "entry failure, max exceeded\n");
1517 + nSlot = -1; /* failed */
1519 + return nSlot;
1523 + * ======== GetNode ========
1524 + * Purpose:
1525 + * Get a memory node from freelist or create a new one.
1526 + */
1527 +static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA,
1528 + u32 dwVA, u32 ulSize)
1530 + struct CMM_MNODE *pNode = NULL;
1532 + DBC_Require(pCmmMgr != NULL);
1533 + DBC_Require(dwPA != 0);
1534 + DBC_Require(dwVA != 0);
1535 + DBC_Require(ulSize != 0);
1536 + /* Check cmm mgr's node freelist */
1537 + if (LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) {
1538 + pNode = (struct CMM_MNODE *)MEM_Calloc(sizeof(struct CMM_MNODE),
1539 + MEM_PAGED);
1540 + } else {
1541 + /* surely a valid element */
1542 + /* (struct LST_ELEM*) pNode = LST_GetHead(pCmmMgr->
1543 + * pNodeFreeListHead);*/
1544 + pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr->
1545 + pNodeFreeListHead);
1547 + if (pNode == NULL) {
1548 + GT_0trace(CMM_debugMask, GT_7CLASS, "GetNode: Out Of Memory\n");
1549 + } else {
1550 + LST_InitElem((struct LST_ELEM *) pNode); /* set self */
1551 + pNode->dwPA = dwPA; /* Physical addr of start of block */
1552 + pNode->dwVA = dwVA; /* Virtual " " */
1553 + pNode->ulSize = ulSize; /* Size of block */
1555 + return pNode;
1559 + * ======== DeleteNode ========
1560 + * Purpose:
1561 + * Put a memory node on the cmm nodelist for later use.
1562 + * Doesn't actually delete the node. Heap thrashing friendly.
1563 + */
1564 +static void DeleteNode(struct CMM_OBJECT *pCmmMgr, struct CMM_MNODE *pNode)
1566 + DBC_Require(pNode != NULL);
1567 + LST_InitElem((struct LST_ELEM *) pNode); /* init .self ptr */
1568 + LST_PutTail(pCmmMgr->pNodeFreeListHead, (struct LST_ELEM *) pNode);
1572 + * ====== GetFreeBlock ========
1573 + * Purpose:
1574 + * Scan the free block list and return the first block that satisfies
1575 + * the size.
1576 + */
1577 +static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator,
1578 + u32 uSize)
1580 + if (pAllocator) {
1581 + struct CMM_MNODE *pCurNode = (struct CMM_MNODE *)
1582 + LST_First(pAllocator->pFreeListHead);
1583 + while (pCurNode) {
1584 + if (uSize <= (u32) pCurNode->ulSize) {
1585 + LST_RemoveElem(pAllocator->pFreeListHead,
1586 + (struct LST_ELEM *)pCurNode);
1587 + return pCurNode;
1589 + /* next node. */
1590 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1591 + pFreeListHead, (struct LST_ELEM *)pCurNode);
1594 + return NULL;
1598 + * ======== AddToFreeList ========
1599 + * Purpose:
1600 + * Coelesce node into the freelist in ascending size order.
1601 + */
1602 +static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator,
1603 + struct CMM_MNODE *pNode)
1605 + struct CMM_MNODE *pNodePrev = NULL;
1606 + struct CMM_MNODE *pNodeNext = NULL;
1607 + struct CMM_MNODE *pCurNode;
1608 + u32 dwThisPA;
1609 + u32 dwNextPA;
1611 + DBC_Require(pNode != NULL);
1612 + DBC_Require(pAllocator != NULL);
1613 + dwThisPA = pNode->dwPA;
1614 + dwNextPA = NEXT_PA(pNode);
1615 + pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead);
1616 + while (pCurNode) {
1617 + if (dwThisPA == NEXT_PA(pCurNode)) {
1618 + /* found the block ahead of this one */
1619 + pNodePrev = pCurNode;
1620 + } else if (dwNextPA == pCurNode->dwPA) {
1621 + pNodeNext = pCurNode;
1623 + if ((pNodePrev == NULL) || (pNodeNext == NULL)) {
1624 + /* next node. */
1625 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1626 + pFreeListHead, (struct LST_ELEM *)pCurNode);
1627 + } else {
1628 + /* got 'em */
1629 + break;
1631 + } /* while */
1632 + if (pNodePrev != NULL) {
1633 + /* combine with previous block */
1634 + LST_RemoveElem(pAllocator->pFreeListHead,
1635 + (struct LST_ELEM *)pNodePrev);
1636 + /* grow node to hold both */
1637 + pNode->ulSize += pNodePrev->ulSize;
1638 + pNode->dwPA = pNodePrev->dwPA;
1639 + pNode->dwVA = pNodePrev->dwVA;
1640 + /* place node on mgr nodeFreeList */
1641 + DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodePrev);
1643 + if (pNodeNext != NULL) {
1644 + /* combine with next block */
1645 + LST_RemoveElem(pAllocator->pFreeListHead,
1646 + (struct LST_ELEM *)pNodeNext);
1647 + /* grow da node */
1648 + pNode->ulSize += pNodeNext->ulSize;
1649 + /* place node on mgr nodeFreeList */
1650 + DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodeNext);
1652 + /* Now, let's add to freelist in increasing size order */
1653 + pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead);
1654 + while (pCurNode) {
1655 + if (pNode->ulSize <= pCurNode->ulSize)
1656 + break;
1658 + /* next node. */
1659 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1660 + pFreeListHead, (struct LST_ELEM *)pCurNode);
1662 + /* if pCurNode is NULL then add our pNode to the end of the freelist */
1663 + if (pCurNode == NULL) {
1664 + LST_PutTail(pAllocator->pFreeListHead,
1665 + (struct LST_ELEM *)pNode);
1666 + } else {
1667 + /* insert our node before the current traversed node */
1668 + LST_InsertBefore(pAllocator->pFreeListHead,
1669 + (struct LST_ELEM *)pNode,
1670 + (struct LST_ELEM *)pCurNode);
1675 + * ======== GetAllocator ========
1676 + * Purpose:
1677 + * Return the allocator for the given SM Segid.
1678 + * SegIds: 1,2,3..max.
1679 + */
1680 +static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr,
1681 + u32 ulSegId)
1683 + struct CMM_ALLOCATOR *pAllocator = NULL;
1685 + DBC_Require(pCmmMgr != NULL);
1686 + DBC_Require((ulSegId > 0) && (ulSegId <= CMM_MAXGPPSEGS));
1687 + pAllocator = pCmmMgr->paGPPSMSegTab[ulSegId - 1];
1688 + if (pAllocator != NULL) {
1689 + /* make sure it's for real */
1690 + if (!MEM_IsValidHandle(pAllocator, SMEMSIGNATURE)) {
1691 + pAllocator = NULL;
1692 + DBC_Assert(false);
1695 + return pAllocator;
1699 + * ======== CMM_XlatorCreate ========
1700 + * Purpose:
1701 + * Create an address translator object.
1702 + */
1703 +DSP_STATUS CMM_XlatorCreate(OUT struct CMM_XLATOROBJECT **phXlator,
1704 + struct CMM_OBJECT *hCmmMgr,
1705 + struct CMM_XLATORATTRS *pXlatorAttrs)
1707 + struct CMM_XLATOR *pXlatorObject = NULL;
1708 + DSP_STATUS status = DSP_SOK;
1710 + DBC_Require(cRefs > 0);
1711 + DBC_Require(phXlator != NULL);
1712 + DBC_Require(hCmmMgr != NULL);
1713 + GT_3trace(CMM_debugMask, GT_ENTER,
1714 + "CMM_XlatorCreate: phXlator: 0x%x\t"
1715 + "phCmmMgr: 0x%x\tpXlAttrs: 0x%x\n", phXlator,
1716 + hCmmMgr, pXlatorAttrs);
1717 + *phXlator = NULL;
1718 + if (pXlatorAttrs == NULL)
1719 + pXlatorAttrs = &CMM_DFLTXLATORATTRS; /* set defaults */
1721 + MEM_AllocObject(pXlatorObject, struct CMM_XLATOR, CMMXLATESIGNATURE);
1722 + if (pXlatorObject != NULL) {
1723 + pXlatorObject->hCmmMgr = hCmmMgr; /* ref back to CMM */
1724 + pXlatorObject->ulSegId = pXlatorAttrs->ulSegId; /* SM segId */
1725 + } else {
1726 + GT_0trace(CMM_debugMask, GT_6CLASS,
1727 + "CMM_XlatorCreate: Object Allocation"
1728 + "Failure(CMM Xlator)\n");
1729 + status = DSP_EMEMORY;
1731 + if (DSP_SUCCEEDED(status))
1732 + *phXlator = (struct CMM_XLATOROBJECT *) pXlatorObject;
1734 + return status;
1738 + * ======== CMM_XlatorDelete ========
1739 + * Purpose:
1740 + * Free the Xlator resources.
1741 + * VM gets freed later.
1742 + */
1743 +DSP_STATUS CMM_XlatorDelete(struct CMM_XLATOROBJECT *hXlator, bool bForce)
1745 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1746 + DSP_STATUS status = DSP_SOK;
1748 + DBC_Require(cRefs > 0);
1750 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1751 + MEM_FreeObject(pXlator);
1752 + } else {
1753 + status = DSP_EHANDLE;
1756 + return status;
1760 + * ======== CMM_XlatorAllocBuf ========
1761 + */
1762 +void *CMM_XlatorAllocBuf(struct CMM_XLATOROBJECT *hXlator, void *pVaBuf,
1763 + u32 uPaSize)
1765 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1766 + void *pBuf = NULL;
1767 + struct CMM_ATTRS attrs;
1769 + DBC_Require(cRefs > 0);
1770 + DBC_Require(hXlator != NULL);
1771 + DBC_Require(pXlator->hCmmMgr != NULL);
1772 + DBC_Require(pVaBuf != NULL);
1773 + DBC_Require(uPaSize > 0);
1774 + DBC_Require(pXlator->ulSegId > 0);
1776 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1777 + attrs.ulSegId = pXlator->ulSegId;
1778 + *(volatile u32 *)pVaBuf = 0;
1779 + /* Alloc SM */
1780 + pBuf = CMM_CallocBuf(pXlator->hCmmMgr, uPaSize, &attrs, NULL);
1781 + if (pBuf) {
1782 + /* convert to translator(node/strm) process Virtual
1783 + * address */
1784 + *(volatile u32 **)pVaBuf =
1785 + (u32 *)CMM_XlatorTranslate(hXlator,
1786 + pBuf, CMM_PA2VA);
1789 + return pBuf;
1793 + * ======== CMM_XlatorFreeBuf ========
1794 + * Purpose:
1795 + * Free the given SM buffer and descriptor.
1796 + * Does not free virtual memory.
1797 + */
1798 +DSP_STATUS CMM_XlatorFreeBuf(struct CMM_XLATOROBJECT *hXlator, void *pBufVa)
1800 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1801 + DSP_STATUS status = DSP_EFAIL;
1802 + void *pBufPa = NULL;
1804 + DBC_Require(cRefs > 0);
1805 + DBC_Require(pBufVa != NULL);
1806 + DBC_Require(pXlator->ulSegId > 0);
1808 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1809 + /* convert Va to Pa so we can free it. */
1810 + pBufPa = CMM_XlatorTranslate(hXlator, pBufVa, CMM_VA2PA);
1811 + if (pBufPa) {
1812 + status = CMM_FreeBuf(pXlator->hCmmMgr, pBufPa,
1813 + pXlator->ulSegId);
1814 + if (DSP_FAILED(status)) {
1815 + /* Uh oh, this shouldn't happen. Descriptor
1816 + * gone! */
1817 + GT_2trace(CMM_debugMask, GT_7CLASS,
1818 + "Cannot free DMA/ZCPY buffer"
1819 + "not allocated by MPU. PA %x, VA %x\n",
1820 + pBufPa, pBufVa);
1821 + DBC_Assert(false); /* CMM is leaking mem! */
1825 + return status;
1829 + * ======== CMM_XlatorInfo ========
1830 + * Purpose:
1831 + * Set/Get translator info.
1832 + */
1833 +DSP_STATUS CMM_XlatorInfo(struct CMM_XLATOROBJECT *hXlator, IN OUT u8 **pAddr,
1834 + u32 ulSize, u32 uSegId, bool bSetInfo)
1836 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1837 + DSP_STATUS status = DSP_SOK;
1839 + DBC_Require(cRefs > 0);
1840 + DBC_Require(pAddr != NULL);
1841 + DBC_Require((uSegId > 0) && (uSegId <= CMM_MAXGPPSEGS));
1843 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1844 + if (bSetInfo) {
1845 + /* set translators virtual address range */
1846 + pXlator->dwVirtBase = (u32)*pAddr;
1847 + pXlator->ulVirtSize = ulSize;
1848 + GT_2trace(CMM_debugMask, GT_3CLASS,
1849 + "pXlator->dwVirtBase %x, "
1850 + "ulVirtSize %x\n", pXlator->dwVirtBase,
1851 + pXlator->ulVirtSize);
1852 + } else { /* return virt base address */
1853 + *pAddr = (u8 *)pXlator->dwVirtBase;
1855 + } else {
1856 + status = DSP_EHANDLE;
1858 + return status;
1862 + * ======== CMM_XlatorTranslate ========
1863 + */
1864 +void *CMM_XlatorTranslate(struct CMM_XLATOROBJECT *hXlator, void *pAddr,
1865 + enum CMM_XLATETYPE xType)
1867 + u32 dwAddrXlate = 0;
1868 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1869 + struct CMM_OBJECT *pCmmMgr = NULL;
1870 + struct CMM_ALLOCATOR *pAlctr = NULL;
1871 + u32 dwOffset = 0;
1873 + DBC_Require(cRefs > 0);
1874 + DBC_Require(pAddr != NULL);
1875 + DBC_Require((xType >= CMM_VA2PA) && (xType <= CMM_DSPPA2PA));
1877 + if (!MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE))
1878 + goto loop_cont;
1880 + pCmmMgr = (struct CMM_OBJECT *)pXlator->hCmmMgr;
1881 + /* get this translator's default SM allocator */
1882 + DBC_Assert(pXlator->ulSegId > 0);
1883 + pAlctr = pCmmMgr->paGPPSMSegTab[pXlator->ulSegId - 1];
1884 + if (!MEM_IsValidHandle(pAlctr, SMEMSIGNATURE))
1885 + goto loop_cont;
1887 + if ((xType == CMM_VA2DSPPA) || (xType == CMM_VA2PA) ||
1888 + (xType == CMM_PA2VA)) {
1889 + if (xType == CMM_PA2VA) {
1890 + /* Gpp Va = Va Base + offset */
1891 + dwOffset = (u8 *)pAddr - (u8 *)(pAlctr->dwSmBase -
1892 + pAlctr->ulDSPSize);
1893 + dwAddrXlate = pXlator->dwVirtBase + dwOffset;
1894 + /* Check if translated Va base is in range */
1895 + if ((dwAddrXlate < pXlator->dwVirtBase) ||
1896 + (dwAddrXlate >=
1897 + (pXlator->dwVirtBase + pXlator->ulVirtSize))) {
1898 + dwAddrXlate = 0; /* bad address */
1899 + GT_0trace(CMM_debugMask, GT_7CLASS,
1900 + "CMM_XlatorTranslate: "
1901 + "Virt addr out of range\n");
1903 + } else {
1904 + /* Gpp PA = Gpp Base + offset */
1905 + dwOffset = (u8 *)pAddr - (u8 *)pXlator->dwVirtBase;
1906 + dwAddrXlate = pAlctr->dwSmBase - pAlctr->ulDSPSize +
1907 + dwOffset;
1909 + } else {
1910 + dwAddrXlate = (u32)pAddr;
1912 + /*Now convert address to proper target physical address if needed*/
1913 + if ((xType == CMM_VA2DSPPA) || (xType == CMM_PA2DSPPA)) {
1914 + /* Got Gpp Pa now, convert to DSP Pa */
1915 + dwAddrXlate = GPPPA2DSPPA((pAlctr->dwSmBase - pAlctr->
1916 + ulDSPSize), dwAddrXlate,
1917 + pAlctr->dwDSPPhysAddrOffset *
1918 + pAlctr->cFactor);
1919 + } else if (xType == CMM_DSPPA2PA) {
1920 + /* Got DSP Pa, convert to GPP Pa */
1921 + dwAddrXlate = DSPPA2GPPPA(pAlctr->dwSmBase - pAlctr->ulDSPSize,
1922 + dwAddrXlate,
1923 + pAlctr->dwDSPPhysAddrOffset *
1924 + pAlctr->cFactor);
1926 +loop_cont:
1927 + if (!dwAddrXlate) {
1928 + GT_2trace(CMM_debugMask, GT_7CLASS,
1929 + "CMM_XlatorTranslate: Can't translate"
1930 + " address: 0x%x xType %x\n", pAddr, xType);
1931 + } else {
1932 + GT_3trace(CMM_debugMask, GT_3CLASS,
1933 + "CMM_XlatorTranslate: pAddr %x, xType"
1934 + " %x, dwAddrXlate %x\n", pAddr, xType, dwAddrXlate);
1936 + return (void *)dwAddrXlate;
1938 diff --git a/drivers/dsp/bridge/pmgr/cod.c b/drivers/dsp/bridge/pmgr/cod.c
1939 new file mode 100644
1940 index 0000000..d1065e2
1941 --- /dev/null
1942 +++ b/drivers/dsp/bridge/pmgr/cod.c
1943 @@ -0,0 +1,683 @@
1945 + * linux/drivers/dsp/bridge/pmgr/cod.c
1947 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1949 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1951 + * This package is free software; you can redistribute it and/or modify
1952 + * it under the terms of the GNU General Public License version 2 as
1953 + * published by the Free Software Foundation.
1955 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1956 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1957 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1958 + */
1962 + * ======== cod.c ========
1963 + * This module implements DSP code management for the DSP/BIOS Bridge
1964 + * environment. It is mostly a thin wrapper.
1966 + * This module provides an interface for loading both static and
1967 + * dynamic code objects onto DSP systems.
1969 + *! Revision History
1970 + *! ================
1971 + *! 08-Apr-2003 map: Consolidated DBL to DBLL loader name
1972 + *! 24-Feb-2003 swa: PMGR Code review comments incorporated.
1973 + *! 18-Apr-2002 jeh: Added DBL function tables.
1974 + *! 20-Nov-2001 jeh: Removed call to ZL_loadArgs function.
1975 + *! 19-Oct-2001 jeh: Access DBL as a static library. Added COD_GetBaseLib,
1976 + *! COD_GetLoader, removed COD_LoadSection, COD_UnloadSection.
1977 + *! 07-Sep-2001 jeh: Added COD_LoadSection(), COD_UnloadSection().
1978 + *! 07-Aug-2001 rr: hMgr->baseLib is updated after zlopen in COD_LoadBase.
1979 + *! 18-Apr-2001 jeh: Check for fLoaded flag before ZL_unload, to allow
1980 + *! COD_OpenBase to be used.
1981 + *! 11-Jan-2001 jeh: Added COD_OpenBase (not used yet, since there is an
1982 + *! occasional crash).
1983 + *! 02-Aug-2000 kc: Added COD_ReadSection to COD module. Incorporates use
1984 + *! of ZL_readSect (new function in ZL module).
1985 + *! 28-Feb-2000 rr: New GT Usage Implementation
1986 + *! 08-Dec-1999 ag: Removed x86 specific __asm int 3.
1987 + *! 02-Oct-1999 ag: Added #ifdef DEBUGINT3COD for debug.
1988 + *! 20-Sep-1999 ag: Removed call to GT_set().
1989 + *! 04-Jun-1997 cr: Added validation of argc/argv pair in COD_LoadBase, as it
1990 + *! is a requirement to ZL_loadArgs.
1991 + *! 31-May-1997 cr: Changed COD_LoadBase argc value from u32 to int, added
1992 + *! DSP_ENOTIMPL return value to COD_Create when attrs != NULL.
1993 + *! 29-May-1997 cr: Added debugging support.
1994 + *! 24-Oct-1996 gp: Added COD_GetSection().
1995 + *! 18-Jun-1996 gp: Updated GetSymValue() to check for lib; updated E_ codes.
1996 + *! 12-Jun-1996 gp: Imported CSL_ services for strcpyn(); Added ref counting.
1997 + *! 20-May-1996 mg: Adapted for new MEM and LDR modules.
1998 + *! 08-May-1996 mg: Created.
1999 + */
2001 +/* ----------------------------------- Host OS */
2002 +#include <host_os.h>
2004 +/* ----------------------------------- DSP/BIOS Bridge */
2005 +#include <std.h>
2006 +#include <dbdefs.h>
2007 +#include <errbase.h>
2009 +/* ----------------------------------- Trace & Debug */
2010 +#include <dbc.h>
2011 +#include <gt.h>
2013 +/* ----------------------------------- OS Adaptation Layer */
2014 +#include <csl.h>
2015 +#include <kfile.h>
2016 +#include <ldr.h>
2017 +#include <mem.h>
2019 +/* ----------------------------------- Platform Manager */
2020 +/* Include appropriate loader header file */
2021 +#include <dbll.h>
2023 +/* ----------------------------------- This */
2024 +#include <cod.h>
2026 +/* magic number for handle validation */
2027 +#define MAGIC 0xc001beef
2029 +/* macro to validate COD manager handles */
2030 +#define IsValid(h) ((h) != NULL && (h)->ulMagic == MAGIC)
2033 + * ======== COD_MANAGER ========
2034 + */
2035 +struct COD_MANAGER {
2036 + struct DBLL_TarObj *target;
2037 + struct DBLL_LibraryObj *baseLib;
2038 + bool fLoaded; /* Base library loaded? */
2039 + u32 ulEntry;
2040 + struct LDR_MODULE *hDll;
2041 + struct DBLL_Fxns fxns;
2042 + struct DBLL_Attrs attrs;
2043 + char szZLFile[COD_MAXPATHLENGTH];
2044 + u32 ulMagic;
2045 +} ;
2048 + * ======== COD_LIBRARYOBJ ========
2049 + */
2050 +struct COD_LIBRARYOBJ {
2051 + struct DBLL_LibraryObj *dbllLib;
2052 + struct COD_MANAGER *hCodMgr;
2053 +} ;
2055 +static u32 cRefs = 0L;
2057 +#if GT_TRACE
2058 +static struct GT_Mask COD_debugMask = { NULL, NULL };
2059 +#endif
2061 +static struct DBLL_Fxns dbllFxns = {
2062 + (DBLL_CloseFxn) DBLL_close,
2063 + (DBLL_CreateFxn) DBLL_create,
2064 + (DBLL_DeleteFxn) DBLL_delete,
2065 + (DBLL_ExitFxn) DBLL_exit,
2066 + (DBLL_GetAttrsFxn) DBLL_getAttrs,
2067 + (DBLL_GetAddrFxn) DBLL_getAddr,
2068 + (DBLL_GetCAddrFxn) DBLL_getCAddr,
2069 + (DBLL_GetSectFxn) DBLL_getSect,
2070 + (DBLL_InitFxn) DBLL_init,
2071 + (DBLL_LoadFxn) DBLL_load,
2072 + (DBLL_LoadSectFxn) DBLL_loadSect,
2073 + (DBLL_OpenFxn) DBLL_open,
2074 + (DBLL_ReadSectFxn) DBLL_readSect,
2075 + (DBLL_SetAttrsFxn) DBLL_setAttrs,
2076 + (DBLL_UnloadFxn) DBLL_unload,
2077 + (DBLL_UnloadSectFxn) DBLL_unloadSect,
2080 +static bool NoOp();
2083 + * ======== COD_Close ========
2084 + */
2085 +void CDECL COD_Close(struct COD_LIBRARYOBJ *lib)
2087 + struct COD_MANAGER *hMgr;
2089 + DBC_Require(cRefs > 0);
2090 + DBC_Require(lib != NULL);
2091 + DBC_Require(IsValid(((struct COD_LIBRARYOBJ *)lib)->hCodMgr));
2093 + hMgr = lib->hCodMgr;
2094 + hMgr->fxns.closeFxn(lib->dbllLib);
2096 + MEM_Free(lib);
2100 + * ======== COD_Create ========
2101 + * Purpose:
2102 + * Create an object to manage code on a DSP system.
2103 + * This object can be used to load an initial program image with
2104 + * arguments that can later be expanded with
2105 + * dynamically loaded object files.
2107 + */
2108 +DSP_STATUS COD_Create(OUT struct COD_MANAGER **phMgr, char *pstrDummyFile,
2109 + IN OPTIONAL CONST struct COD_ATTRS *attrs)
2111 + struct COD_MANAGER *hMgrNew;
2112 + struct DBLL_Attrs zlAttrs;
2113 + DSP_STATUS status = DSP_SOK;
2115 + DBC_Require(cRefs > 0);
2116 + DBC_Require(phMgr != NULL);
2118 + GT_3trace(COD_debugMask, GT_ENTER,
2119 + "Entered COD_Create, Args: \t\nphMgr: "
2120 + "0x%x\t\npstrDummyFile: 0x%x\t\nattr: 0x%x\n",
2121 + phMgr, pstrDummyFile, attrs);
2122 + /* assume failure */
2123 + *phMgr = NULL;
2125 + /* we don't support non-default attrs yet */
2126 + if (attrs != NULL)
2127 + return DSP_ENOTIMPL;
2129 + hMgrNew = MEM_Calloc(sizeof(struct COD_MANAGER), MEM_NONPAGED);
2130 + if (hMgrNew == NULL) {
2131 + GT_0trace(COD_debugMask, GT_7CLASS,
2132 + "COD_Create: Out Of Memory\n");
2133 + return DSP_EMEMORY;
2136 + hMgrNew->ulMagic = MAGIC;
2138 + /* Set up loader functions */
2139 + hMgrNew->fxns = dbllFxns;
2141 + /* initialize the ZL module */
2142 + hMgrNew->fxns.initFxn();
2144 + zlAttrs.alloc = (DBLL_AllocFxn)NoOp;
2145 + zlAttrs.free = (DBLL_FreeFxn)NoOp;
2146 + zlAttrs.fread = (DBLL_ReadFxn)KFILE_Read;
2147 + zlAttrs.fseek = (DBLL_SeekFxn)KFILE_Seek;
2148 + zlAttrs.ftell = (DBLL_TellFxn)KFILE_Tell;
2149 + zlAttrs.fclose = (DBLL_FCloseFxn)KFILE_Close;
2150 + zlAttrs.fopen = (DBLL_FOpenFxn)KFILE_Open;
2151 + zlAttrs.symLookup = NULL;
2152 + zlAttrs.baseImage = true;
2153 + zlAttrs.logWrite = NULL;
2154 + zlAttrs.logWriteHandle = NULL;
2155 + zlAttrs.write = 0;
2156 + zlAttrs.rmmHandle = 0;
2157 + zlAttrs.wHandle = 0;
2158 + zlAttrs.symHandle = 0;
2159 + zlAttrs.symArg = 0;
2161 + hMgrNew->attrs = zlAttrs;
2163 + status = hMgrNew->fxns.createFxn(&hMgrNew->target, &zlAttrs);
2165 + if (DSP_FAILED(status)) {
2166 + COD_Delete(hMgrNew);
2167 + GT_1trace(COD_debugMask, GT_7CLASS,
2168 + "COD_Create:ZL Create Failed: 0x%x\n", status);
2169 + return COD_E_ZLCREATEFAILED;
2172 + /* return the new manager */
2173 + *phMgr = hMgrNew;
2174 + GT_1trace(COD_debugMask, GT_1CLASS,
2175 + "COD_Create: Success CodMgr: 0x%x\n", *phMgr);
2176 + return DSP_SOK;
2180 + * ======== COD_Delete ========
2181 + * Purpose:
2182 + * Delete a code manager object.
2183 + */
2184 +void COD_Delete(struct COD_MANAGER *hMgr)
2186 + DBC_Require(cRefs > 0);
2187 + DBC_Require(IsValid(hMgr));
2189 + GT_1trace(COD_debugMask, GT_ENTER, "COD_Delete:hMgr 0x%x\n", hMgr);
2190 + if (hMgr->baseLib) {
2191 + if (hMgr->fLoaded)
2192 + hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs);
2194 + hMgr->fxns.closeFxn(hMgr->baseLib);
2196 + if (hMgr->target) {
2197 + hMgr->fxns.deleteFxn(hMgr->target);
2198 + hMgr->fxns.exitFxn();
2200 + hMgr->ulMagic = ~MAGIC;
2201 + MEM_Free(hMgr);
2205 + * ======== COD_Exit ========
2206 + * Purpose:
2207 + * Discontinue usage of the COD module.
2209 + */
2210 +void COD_Exit(void)
2212 + DBC_Require(cRefs > 0);
2214 + cRefs--;
2216 + GT_1trace(COD_debugMask, GT_ENTER,
2217 + "Entered COD_Exit, ref count: 0x%x\n", cRefs);
2219 + DBC_Ensure(cRefs >= 0);
2223 + * ======== COD_GetBaseLib ========
2224 + * Purpose:
2225 + * Get handle to the base image DBL library.
2226 + */
2227 +DSP_STATUS CDECL COD_GetBaseLib(struct COD_MANAGER *hManager,
2228 + struct DBLL_LibraryObj **plib)
2230 + DSP_STATUS status = DSP_SOK;
2232 + DBC_Require(cRefs > 0);
2233 + DBC_Require(IsValid(hManager));
2234 + DBC_Require(plib != NULL);
2236 + *plib = (struct DBLL_LibraryObj *) hManager->baseLib;
2238 + return status;
2242 + * ======== COD_GetBaseName ========
2243 + */
2244 +DSP_STATUS CDECL COD_GetBaseName(struct COD_MANAGER *hManager, char *pszName,
2245 + u32 uSize)
2247 + DSP_STATUS status = DSP_SOK;
2249 + DBC_Require(cRefs > 0);
2250 + DBC_Require(IsValid(hManager));
2251 + DBC_Require(pszName != NULL);
2253 + if (uSize <= COD_MAXPATHLENGTH)
2254 + CSL_Strcpyn(pszName, hManager->szZLFile, uSize);
2255 + else
2256 + status = DSP_EFAIL;
2258 + return status;
2262 + * ======== COD_GetEntry ========
2263 + * Purpose:
2264 + * Retrieve the entry point of a loaded DSP program image
2266 + */
2267 +DSP_STATUS COD_GetEntry(struct COD_MANAGER *hManager, u32 *pulEntry)
2269 + DBC_Require(cRefs > 0);
2270 + DBC_Require(IsValid(hManager));
2271 + DBC_Require(pulEntry != NULL);
2273 + *pulEntry = hManager->ulEntry;
2275 + GT_1trace(COD_debugMask, GT_ENTER, "COD_GetEntry:ulEntr 0x%x\n",
2276 + *pulEntry);
2278 + return DSP_SOK;
2282 + * ======== COD_GetLoader ========
2283 + * Purpose:
2284 + * Get handle to the DBLL loader.
2285 + */
2286 +DSP_STATUS CDECL COD_GetLoader(struct COD_MANAGER *hManager,
2287 + struct DBLL_TarObj **phLoader)
2289 + DSP_STATUS status = DSP_SOK;
2291 + DBC_Require(cRefs > 0);
2292 + DBC_Require(IsValid(hManager));
2293 + DBC_Require(phLoader != NULL);
2295 + *phLoader = (struct DBLL_TarObj *)hManager->target;
2297 + return status;
2301 + * ======== COD_GetSection ========
2302 + * Purpose:
2303 + * Retrieve the starting address and length of a section in the COFF file
2304 + * given the section name.
2305 + */
2306 +DSP_STATUS COD_GetSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect,
2307 + OUT u32 *puAddr, OUT u32 *puLen)
2309 + struct COD_MANAGER *hManager;
2310 + DSP_STATUS status = DSP_SOK;
2312 + DBC_Require(cRefs > 0);
2313 + DBC_Require(lib != NULL);
2314 + DBC_Require(IsValid(lib->hCodMgr));
2315 + DBC_Require(pstrSect != NULL);
2316 + DBC_Require(puAddr != NULL);
2317 + DBC_Require(puLen != NULL);
2319 + GT_4trace(COD_debugMask, GT_ENTER,
2320 + "Entered COD_GetSection Args \t\n lib: "
2321 + "0x%x\t\npstrsect: 0x%x\t\npuAddr: 0x%x\t\npuLen: 0x%x\n",
2322 + lib, pstrSect, puAddr, puLen);
2323 + *puAddr = 0;
2324 + *puLen = 0;
2325 + if (lib != NULL) {
2326 + hManager = lib->hCodMgr;
2327 + status = hManager->fxns.getSectFxn(lib->dbllLib, pstrSect,
2328 + puAddr, puLen);
2329 + if (DSP_FAILED(status)) {
2330 + GT_1trace(COD_debugMask, GT_7CLASS,
2331 + "COD_GetSection: Section %s not"
2332 + "found\n", pstrSect);
2334 + } else {
2335 + status = COD_E_NOSYMBOLSLOADED;
2336 + GT_0trace(COD_debugMask, GT_7CLASS,
2337 + "COD_GetSection:No Symbols loaded\n");
2340 + DBC_Ensure(DSP_SUCCEEDED(status) || ((*puAddr == 0) && (*puLen == 0)));
2342 + return status;
2346 + * ======== COD_GetSymValue ========
2347 + * Purpose:
2348 + * Retrieve the value for the specified symbol. The symbol is first
2349 + * searched for literally and then, if not found, searched for as a
2350 + * C symbol.
2352 + */
2353 +DSP_STATUS COD_GetSymValue(struct COD_MANAGER *hMgr, char *pstrSym,
2354 + u32 *pulValue)
2356 + struct DBLL_Symbol *pSym;
2358 + DBC_Require(cRefs > 0);
2359 + DBC_Require(IsValid(hMgr));
2360 + DBC_Require(pstrSym != NULL);
2361 + DBC_Require(pulValue != NULL);
2363 + GT_3trace(COD_debugMask, GT_ENTER, "Entered COD_GetSymValue Args \t\n"
2364 + "hMgr: 0x%x\t\npstrSym: 0x%x\t\npulValue: 0x%x\n",
2365 + hMgr, pstrSym, pulValue);
2366 + if (hMgr->baseLib) {
2367 + if (!hMgr->fxns.getAddrFxn(hMgr->baseLib, pstrSym, &pSym)) {
2368 + if (!hMgr->fxns.getCAddrFxn(hMgr->baseLib, pstrSym,
2369 + &pSym)) {
2370 + GT_0trace(COD_debugMask, GT_7CLASS,
2371 + "COD_GetSymValue: "
2372 + "Symbols not found\n");
2373 + return COD_E_SYMBOLNOTFOUND;
2376 + } else {
2377 + GT_0trace(COD_debugMask, GT_7CLASS, "COD_GetSymValue: "
2378 + "No Symbols loaded\n");
2379 + return COD_E_NOSYMBOLSLOADED;
2382 + *pulValue = pSym->value;
2384 + return DSP_SOK;
2388 + * ======== COD_Init ========
2389 + * Purpose:
2390 + * Initialize the COD module's private state.
2392 + */
2393 +bool COD_Init(void)
2395 + bool fRetVal = true;
2397 + DBC_Require(cRefs >= 0);
2399 + if (cRefs == 0) {
2400 + DBC_Assert(!COD_debugMask.flags);
2401 + GT_create(&COD_debugMask, "CO");
2404 + if (fRetVal)
2405 + cRefs++;
2408 + GT_1trace(COD_debugMask, GT_1CLASS,
2409 + "Entered COD_Init, ref count: 0x%x\n", cRefs);
2410 + DBC_Ensure((fRetVal && cRefs > 0) || (!fRetVal && cRefs >= 0));
2411 + return fRetVal;
2415 + * ======== COD_LoadBase ========
2416 + * Purpose:
2417 + * Load the initial program image, optionally with command-line arguments,
2418 + * on the DSP system managed by the supplied handle. The program to be
2419 + * loaded must be the first element of the args array and must be a fully
2420 + * qualified pathname.
2421 + * Details:
2422 + * if nArgc doesn't match the number of arguments in the aArgs array, the
2423 + * aArgs array is searched for a NULL terminating entry, and argc is
2424 + * recalculated to reflect this. In this way, we can support NULL
2425 + * terminating aArgs arrays, if nArgc is very large.
2426 + */
2427 +DSP_STATUS COD_LoadBase(struct COD_MANAGER *hMgr, u32 nArgc, char *aArgs[],
2428 + COD_WRITEFXN pfnWrite, void *pArb, char *envp[])
2430 + DBLL_Flags flags;
2431 + struct DBLL_Attrs saveAttrs;
2432 + struct DBLL_Attrs newAttrs;
2433 + DSP_STATUS status;
2434 + u32 i;
2436 + DBC_Require(cRefs > 0);
2437 + DBC_Require(IsValid(hMgr));
2438 + DBC_Require(nArgc > 0);
2439 + DBC_Require(aArgs != NULL);
2440 + DBC_Require(aArgs[0] != NULL);
2441 + DBC_Require(pfnWrite != NULL);
2442 + DBC_Require(hMgr->baseLib != NULL);
2444 + GT_6trace(COD_debugMask, GT_ENTER,
2445 + "Entered COD_LoadBase, hMgr: 0x%x\n \t"
2446 + "nArgc: 0x%x\n\taArgs: 0x%x\n\tpfnWrite: 0x%x\n\tpArb:"
2447 + " 0x%x\n \tenvp: 0x%x\n", hMgr, nArgc, aArgs, pfnWrite,
2448 + pArb, envp);
2449 + /*
2450 + * Make sure every argv[] stated in argc has a value, or change argc to
2451 + * reflect true number in NULL terminated argv array.
2452 + */
2453 + for (i = 0; i < nArgc; i++) {
2454 + if (aArgs[i] == NULL) {
2455 + nArgc = i;
2456 + break;
2460 + /* set the write function for this operation */
2461 + hMgr->fxns.getAttrsFxn(hMgr->target, &saveAttrs);
2463 + newAttrs = saveAttrs;
2464 + newAttrs.write = (DBLL_WriteFxn)pfnWrite;
2465 + newAttrs.wHandle = pArb;
2466 + newAttrs.alloc = (DBLL_AllocFxn)NoOp;
2467 + newAttrs.free = (DBLL_FreeFxn)NoOp;
2468 + newAttrs.logWrite = NULL;
2469 + newAttrs.logWriteHandle = NULL;
2471 + /* Load the image */
2472 + flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
2473 + status = hMgr->fxns.loadFxn(hMgr->baseLib, flags, &newAttrs,
2474 + &hMgr->ulEntry);
2475 + if (DSP_FAILED(status)) {
2476 + hMgr->fxns.closeFxn(hMgr->baseLib);
2477 + GT_1trace(COD_debugMask, GT_7CLASS,
2478 + "COD_LoadBase: COD Load failed: "
2479 + "0x%x\n", status);
2481 + if (DSP_SUCCEEDED(status))
2482 + hMgr->fLoaded = true;
2483 + else
2484 + hMgr->baseLib = NULL;
2486 + return status;
2490 + * ======== COD_Open ========
2491 + * Open library for reading sections.
2492 + */
2493 +DSP_STATUS COD_Open(struct COD_MANAGER *hMgr, IN char *pszCoffPath,
2494 + COD_FLAGS flags, struct COD_LIBRARYOBJ **pLib)
2496 + DSP_STATUS status = DSP_SOK;
2497 + struct COD_LIBRARYOBJ *lib = NULL;
2499 + DBC_Require(cRefs > 0);
2500 + DBC_Require(IsValid(hMgr));
2501 + DBC_Require(pszCoffPath != NULL);
2502 + DBC_Require(flags == COD_NOLOAD || flags == COD_SYMB);
2503 + DBC_Require(pLib != NULL);
2505 + GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_Open, hMgr: 0x%x\n\t "
2506 + "pszCoffPath: 0x%x\tflags: 0x%x\tlib: 0x%x\n", hMgr,
2507 + pszCoffPath, flags, pLib);
2509 + *pLib = NULL;
2511 + lib = MEM_Calloc(sizeof(struct COD_LIBRARYOBJ), MEM_NONPAGED);
2512 + if (lib == NULL) {
2513 + GT_0trace(COD_debugMask, GT_7CLASS,
2514 + "COD_Open: Out Of Memory\n");
2515 + status = DSP_EMEMORY;
2518 + if (DSP_SUCCEEDED(status)) {
2519 + lib->hCodMgr = hMgr;
2520 + status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags,
2521 + &lib->dbllLib);
2522 + if (DSP_FAILED(status)) {
2523 + GT_1trace(COD_debugMask, GT_7CLASS,
2524 + "COD_Open failed: 0x%x\n", status);
2525 + } else {
2526 + *pLib = lib;
2530 + return status;
2534 + * ======== COD_OpenBase ========
2535 + * Purpose:
2536 + * Open base image for reading sections.
2537 + */
2538 +DSP_STATUS COD_OpenBase(struct COD_MANAGER *hMgr, IN char *pszCoffPath,
2539 + DBLL_Flags flags)
2541 + DSP_STATUS status = DSP_SOK;
2542 + struct DBLL_LibraryObj *lib;
2544 + DBC_Require(cRefs > 0);
2545 + DBC_Require(IsValid(hMgr));
2546 + DBC_Require(pszCoffPath != NULL);
2548 + GT_2trace(COD_debugMask, GT_ENTER,
2549 + "Entered COD_OpenBase, hMgr: 0x%x\n\t"
2550 + "pszCoffPath: 0x%x\n", hMgr, pszCoffPath);
2552 + /* if we previously opened a base image, close it now */
2553 + if (hMgr->baseLib) {
2554 + if (hMgr->fLoaded) {
2555 + GT_0trace(COD_debugMask, GT_7CLASS,
2556 + "Base Image is already loaded. "
2557 + "Unloading it...\n");
2558 + hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs);
2559 + hMgr->fLoaded = false;
2561 + hMgr->fxns.closeFxn(hMgr->baseLib);
2562 + hMgr->baseLib = NULL;
2563 + } else {
2564 + GT_0trace(COD_debugMask, GT_1CLASS,
2565 + "COD_OpenBase: Opening the base image ...\n");
2567 + status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags, &lib);
2568 + if (DSP_FAILED(status)) {
2569 + GT_0trace(COD_debugMask, GT_7CLASS,
2570 + "COD_OpenBase: COD Open failed\n");
2571 + } else {
2572 + /* hang onto the library for subsequent sym table usage */
2573 + hMgr->baseLib = lib;
2574 + CSL_Strcpyn(hMgr->szZLFile, pszCoffPath, COD_MAXPATHLENGTH);
2577 + return status;
2581 + * ======== COD_ReadSection ========
2582 + * Purpose:
2583 + * Retrieve the content of a code section given the section name.
2584 + */
2585 +DSP_STATUS COD_ReadSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect,
2586 + OUT char *pstrContent, IN u32 cContentSize)
2588 + DSP_STATUS status = DSP_SOK;
2590 + DBC_Require(cRefs > 0);
2591 + DBC_Require(lib != NULL);
2592 + DBC_Require(IsValid(lib->hCodMgr));
2593 + DBC_Require(pstrSect != NULL);
2594 + DBC_Require(pstrContent != NULL);
2596 + GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_ReadSection Args: 0x%x,"
2597 + " 0x%x, 0x%x, 0x%x\n", lib, pstrSect, pstrContent,
2598 + cContentSize);
2600 + if (lib != NULL) {
2601 + status = lib->hCodMgr->fxns.readSectFxn(lib->dbllLib, pstrSect,
2602 + pstrContent,
2603 + cContentSize);
2604 + if (DSP_FAILED(status)) {
2605 + GT_1trace(COD_debugMask, GT_7CLASS,
2606 + "COD_ReadSection failed: 0x%lx\n", status);
2608 + } else {
2609 + status = COD_E_NOSYMBOLSLOADED;
2610 + GT_0trace(COD_debugMask, GT_7CLASS,
2611 + "COD_ReadSection: No Symbols loaded\n");
2613 + return status;
2617 + * ======== NoOp ========
2618 + * Purpose:
2619 + * No Operation.
2621 + */
2622 +static bool NoOp(void)
2624 + return true;
2627 diff --git a/drivers/dsp/bridge/pmgr/dbl.c b/drivers/dsp/bridge/pmgr/dbl.c
2628 new file mode 100644
2629 index 0000000..d4c68c0
2630 --- /dev/null
2631 +++ b/drivers/dsp/bridge/pmgr/dbl.c
2632 @@ -0,0 +1,1385 @@
2634 + * linux/drivers/dsp/bridge/pmgr/linux/dbl/dbl.c
2636 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
2638 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
2640 + * This package is free software; you can redistribute it and/or modify
2641 + * it under the terms of the GNU General Public License version 2 as
2642 + * published by the Free Software Foundation.
2644 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2645 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2646 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2647 + */
2651 + * ======== dbl.c ========
2652 + * Dynamic BOF Loader library. Contains functions related to
2653 + * loading and unloading symbols/code/data on DSP.
2654 + * Also contains other support functions.
2656 + *! Revision History
2657 + *! ================
2658 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
2659 + *! 24-May-2002 jeh Free DCD sects in DBL_close().
2660 + *! 19-Mar-2002 jeh Changes made to match dynamic loader (dbll.c): Pass
2661 + *! DBL_Library to DBL_getAddr() instead of DBL_Target,
2662 + *! eliminate scope param, use DBL_Symbol. Pass attrs to
2663 + *! DBL_load(), DBL_unload().
2664 + *! 20-Nov-2001 jeh Removed DBL_loadArgs().
2665 + *! 07-Sep-2001 jeh Added overlay support.
2666 + *! 31-Jul-2001 jeh Include windows.h.
2667 + *! 06-Jun-2001 jeh Created.
2668 + */
2670 +/* ----------------------------------- Host OS */
2671 +#include <host_os.h>
2673 +/* ----------------------------------- DSP/BIOS Bridge */
2674 +#include <std.h>
2675 +#include <dbdefs.h>
2676 +#include <errbase.h>
2678 +/* ----------------------------------- Trace & Debug */
2679 +#include <dbc.h>
2680 +#include <gt.h>
2682 +/* ----------------------------------- OS Adaptation Layer */
2683 +#include <csl.h>
2684 +#include <mem.h>
2685 +#include <kfile.h>
2687 +/* ----------------------------------- This */
2688 +#include <dbof.h>
2689 +#include <dbl.h>
2691 +#define DBL_TARGSIGNATURE 0x544c4244 /* "TLBD" */
2692 +#define DBL_LIBSIGNATURE 0x4c4c4244 /* "LLBD" */
2694 +#define C54TARG 0
2695 +#define C55TARG 1
2696 +#define NUMTARGS 2
2698 +#define C54MAGIC 0x98 /* Magic number for TI C54 COF */
2699 +#define C55MAGIC 0x9c /* Magic number for LEAD3 (C55) COF */
2701 +/* Three task phases */
2702 +#define CREATEPHASE 0
2703 +#define DELETEPHASE 1
2704 +#define EXECUTEPHASE 2
2705 +#define NONE 3 /* For overlay section with phase not specified */
2707 +/* Default load buffer size */
2708 +#define LOADBUFSIZE 0x800
2710 +#define SWAPLONG(x) ((((x) << 24) & 0xFF000000) | (((x) << 8) & 0xFF0000L) | \
2711 + (((x) >> 8) & 0xFF00L) | (((x) >> 24) & 0xFF))
2713 +#define SWAPWORD(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0xFF))
2716 + * Macros for accessing the following types of overlay data within a
2717 + * structure of type OvlyData:
2718 + * - Overlay data not associated with a particular phase
2719 + * - Create phase overlay data
2720 + * - Delete phase overlay data
2721 + * - Execute phase overlay data
2722 + */
2723 +#define numOtherSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numOtherSects)
2724 +#define numCreateSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numCreateSects)
2725 +#define numDeleteSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numDeleteSects)
2726 +#define numExecuteSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numExecuteSects)
2727 +#define otherOffset(pOvlyData) 0
2728 +#define createOffset(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numOtherSects)
2729 +#define deleteOffset(pOvlyData) (createOffset(pOvlyData) + \
2730 + (pOvlyData->hdr.dbofHdr.numCreateSects))
2731 +#define executeOffset(pOvlyData) (deleteOffset(pOvlyData) + \
2732 + (pOvlyData->hdr.dbofHdr.numDeleteSects))
2734 + * ======== OvlyHdr ========
2735 + */
2736 +struct OvlyHdr {
2737 + struct DBOF_OvlySectHdr dbofHdr;
2738 + char *pName; /* Name of overlay section */
2739 + u16 createRef; /* Reference count for create phase */
2740 + u16 deleteRef; /* Reference count for delete phase */
2741 + u16 executeRef; /* Execute phase ref count */
2742 + u16 otherRef; /* Unspecified phase ref count */
2743 +} ;
2746 + * ======== OvlyData ========
2747 + */
2748 +struct OvlyData {
2749 + struct OvlyHdr hdr;
2750 + struct DBOF_OvlySectData data[1];
2751 +} ;
2754 + * ======== Symbol ========
2755 + */
2756 +struct Symbol {
2757 + struct DBL_Symbol sym;
2758 + char *pSymName;
2762 + * ======== DCDSect ========
2763 + */
2764 +struct DCDSect {
2765 + struct DBOF_DCDSectHdr sectHdr;
2766 + char *pData;
2767 +} ;
2770 + * ======== DBL_TargetObj ========
2771 + */
2772 +struct DBL_TargetObj {
2773 + u32 dwSignature; /* For object validation */
2774 + struct DBL_Attrs dblAttrs; /* file read, write, etc. functions */
2775 + char *pBuf; /* Load buffer */
2779 + * ======== TargetInfo ========
2780 + */
2781 +struct TargetInfo {
2782 + u16 dspType; /* eg, C54TARG, C55TARG */
2783 + u32 magic; /* COFF magic number, identifies target type */
2784 + u16 wordSize; /* Size of a DSP word */
2785 + u16 mauSize; /* Size of minimum addressable unit */
2786 + u16 charSize; /* For C55x, mausize = 1, but charsize = 2 */
2787 +} ;
2790 + * ======== DBL_LibraryObj ========
2791 + * Represents a library loaded on a target.
2792 + */
2793 +struct DBL_LibraryObj {
2794 + u32 dwSignature; /* For object validation */
2795 + struct DBL_TargetObj *pTarget; /* Target for this library */
2796 + struct KFILE_FileObj *file; /* DBOF file handle */
2797 + bool byteSwapped; /* Are bytes swapped? */
2798 + struct DBOF_FileHdr fileHdr; /* Header of DBOF file */
2799 + u16 nSymbols; /* Number of DSP/Bridge symbols */
2800 + struct Symbol *symbols; /* Table of DSP/Bridge symbols */
2801 + u16 nDCDSects; /* Number of DCD sections */
2802 + u16 nOvlySects; /* Number of overlay nodes */
2803 + struct DCDSect *dcdSects; /* DCD section data */
2804 + struct OvlyData **ppOvlyData; /* Array of overlay section data */
2805 + struct TargetInfo *pTargetInfo; /* Entry in targetTab[] below */
2806 +} ;
2808 +#if GT_TRACE
2809 +static struct GT_Mask DBL_debugMask = { NULL, NULL }; /* GT trace variable */
2810 +#endif
2812 +static u32 cRefs; /* module reference count */
2814 +static u32 magicTab[NUMTARGS] = { C54MAGIC, C55MAGIC };
2816 +static struct TargetInfo targetTab[] = {
2817 + /* targ magic wordsize mausize charsize */
2818 + {C54TARG, C54MAGIC, 2, 2, 2}, /* C54 */
2819 + {C55TARG, C55MAGIC, 2, 1, 2}, /* C55 */
2822 +static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData,
2823 + s32 offset, s32 nSects);
2824 +static DSP_STATUS loadSect(struct DBL_TargetObj *dbl,
2825 + struct DBL_LibraryObj *pdblLib);
2826 +static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl,
2827 + struct DBL_LibraryObj *pdblLib);
2828 +static DSP_STATUS readHeader(struct DBL_TargetObj *dbl,
2829 + struct DBL_LibraryObj *pdblLib);
2830 +static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl,
2831 + struct DBL_LibraryObj *pdblLib);
2832 +static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl,
2833 + struct DBL_LibraryObj *pdblLib);
2836 + * ======== DBL_close ========
2837 + * Purpose:
2838 + * Close library opened with DBL_open.
2839 + */
2840 +void DBL_close(struct DBL_LibraryObj *lib)
2842 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
2843 + u16 i;
2845 + DBC_Require(cRefs > 0);
2846 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
2848 + GT_1trace(DBL_debugMask, GT_ENTER, "DBL_close: lib: 0x%x\n", lib);
2850 + /* Free symbols */
2851 + if (pdblLib->symbols) {
2852 + for (i = 0; i < pdblLib->nSymbols; i++) {
2853 + if (pdblLib->symbols[i].pSymName)
2854 + MEM_Free(pdblLib->symbols[i].pSymName);
2857 + MEM_Free(pdblLib->symbols);
2860 + /* Free DCD sects */
2861 + if (pdblLib->dcdSects) {
2862 + for (i = 0; i < pdblLib->nDCDSects; i++) {
2863 + if (pdblLib->dcdSects[i].pData)
2864 + MEM_Free(pdblLib->dcdSects[i].pData);
2867 + MEM_Free(pdblLib->dcdSects);
2870 + /* Free overlay sects */
2871 + if (pdblLib->ppOvlyData) {
2872 + for (i = 0; i < pdblLib->nOvlySects; i++) {
2873 + if (pdblLib->ppOvlyData[i]) {
2874 + if (pdblLib->ppOvlyData[i]->hdr.pName) {
2875 + MEM_Free(pdblLib->ppOvlyData[i]->
2876 + hdr.pName);
2878 + MEM_Free(pdblLib->ppOvlyData[i]);
2881 + MEM_Free(pdblLib->ppOvlyData);
2884 + /* Close the file */
2885 + if (pdblLib->file)
2886 + (*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file);
2889 + MEM_FreeObject(pdblLib);
2893 + * ======== DBL_create ========
2894 + * Purpose:
2895 + * Create a target object by specifying the alloc, free, and
2896 + * write functions for the target.
2897 + */
2898 +DSP_STATUS DBL_create(struct DBL_TargetObj **pTarget, struct DBL_Attrs *pAttrs)
2900 + struct DBL_TargetObj *pdblTarget = NULL;
2901 + DSP_STATUS status = DSP_SOK;
2903 + DBC_Require(cRefs > 0);
2904 + DBC_Require(pAttrs != NULL);
2905 + DBC_Require(pTarget != NULL);
2907 + GT_2trace(DBL_debugMask, GT_ENTER,
2908 + "DBL_create: pTarget: 0x%x pAttrs: 0x%x\n",
2909 + pTarget, pAttrs);
2910 + /* Allocate DBL target object */
2911 + MEM_AllocObject(pdblTarget, struct DBL_TargetObj, DBL_TARGSIGNATURE);
2912 + if (pdblTarget == NULL) {
2913 + GT_0trace(DBL_debugMask, GT_6CLASS,
2914 + "DBL_create: Memory allocation failed\n");
2915 + status = DSP_EMEMORY;
2916 + } else {
2917 + pdblTarget->dblAttrs = *pAttrs;
2918 + /* Allocate buffer for loading target */
2919 + pdblTarget->pBuf = MEM_Calloc(LOADBUFSIZE, MEM_PAGED);
2920 + if (pdblTarget->pBuf == NULL)
2921 + status = DSP_EMEMORY;
2924 + if (DSP_SUCCEEDED(status)) {
2925 + *pTarget = pdblTarget;
2926 + } else {
2927 + *pTarget = NULL;
2928 + if (pdblTarget)
2929 + DBL_delete(pdblTarget);
2932 + DBC_Ensure(DSP_SUCCEEDED(status) &&
2933 + ((MEM_IsValidHandle((*pTarget), DBL_TARGSIGNATURE)) ||
2934 + (DSP_FAILED(status) && *pTarget == NULL)));
2935 + return status;
2939 + * ======== DBL_delete ========
2940 + * Purpose:
2941 + * Delete target object and free resources for any loaded libraries.
2942 + */
2943 +void DBL_delete(struct DBL_TargetObj *target)
2945 + DBC_Require(cRefs > 0);
2946 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
2948 + GT_1trace(DBL_debugMask, GT_ENTER,
2949 + "DBL_delete: target: 0x%x\n", target);
2951 + if (target->pBuf)
2952 + MEM_Free(target->pBuf);
2954 + MEM_FreeObject(target);
2958 + * ======== DBL_exit ========
2959 + * Purpose
2960 + * Discontinue usage of DBL module.
2961 + */
2962 +void DBL_exit()
2964 + DBC_Require(cRefs > 0);
2965 + cRefs--;
2966 + GT_1trace(DBL_debugMask, GT_5CLASS,
2967 + "DBL_exit() ref count: 0x%x\n", cRefs);
2968 + DBC_Ensure(cRefs >= 0);
2972 + * ======== DBL_getAddr ========
2973 + * Purpose:
2974 + * Get address of name in the specified library.
2975 + */
2976 +bool DBL_getAddr(struct DBL_LibraryObj *lib, char *name,
2977 + struct DBL_Symbol **ppSym)
2979 + bool retVal = false;
2980 + struct Symbol *symbol;
2981 + u16 i;
2983 + DBC_Require(cRefs > 0);
2984 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
2985 + DBC_Require(name != NULL);
2986 + DBC_Require(ppSym != NULL);
2988 + GT_3trace(DBL_debugMask, GT_ENTER,
2989 + "DBL_getAddr: libt: 0x%x name: %s pAddr: "
2990 + "0x%x\n", lib, name, ppSym);
2991 + for (i = 0; i < lib->nSymbols; i++) {
2992 + symbol = &lib->symbols[i];
2993 + if (CSL_Strcmp(name, symbol->pSymName) == 0) {
2994 + /* Found it */
2995 + *ppSym = &lib->symbols[i].sym;
2996 + retVal = true;
2997 + break;
3000 + return retVal;
3004 + * ======== DBL_getAttrs ========
3005 + * Purpose:
3006 + * Retrieve the attributes of the target.
3007 + */
3008 +void DBL_getAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs)
3010 + DBC_Require(cRefs > 0);
3011 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
3012 + DBC_Require(pAttrs != NULL);
3013 + GT_2trace(DBL_debugMask, GT_ENTER, "DBL_getAttrs: target: 0x%x pAttrs: "
3014 + "0x%x\n", target, pAttrs);
3015 + *pAttrs = target->dblAttrs;
3019 + * ======== DBL_getCAddr ========
3020 + * Purpose:
3021 + * Get address of "C" name in the specified library.
3022 + */
3023 +bool DBL_getCAddr(struct DBL_LibraryObj *lib, char *name,
3024 + struct DBL_Symbol **ppSym)
3026 + bool retVal = false;
3027 + struct Symbol *symbol;
3028 + u16 i;
3030 + DBC_Require(cRefs > 0);
3031 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3032 + DBC_Require(name != NULL);
3033 + DBC_Require(ppSym != NULL);
3035 + GT_3trace(DBL_debugMask, GT_ENTER,
3036 + "DBL_getCAddr: target: 0x%x name:%s pAddr:"
3037 + " 0x%x\n", lib, name, ppSym);
3038 + for (i = 0; i < lib->nSymbols; i++) {
3039 + symbol = &lib->symbols[i];
3040 + if ((CSL_Strcmp(name, symbol->pSymName) == 0) ||
3041 + (CSL_Strcmp(name, symbol->pSymName + 1) == 0 &&
3042 + symbol->pSymName[0] == '_')) {
3043 + /* Found it */
3044 + *ppSym = &lib->symbols[i].sym;
3045 + retVal = true;
3046 + break;
3049 + return retVal;
3053 + * ======== DBL_getEntry ========
3054 + * Purpose:
3055 + * Get program entry point.
3057 + */
3058 +bool DBL_getEntry(struct DBL_LibraryObj *lib, u32 *pEntry)
3060 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3062 + DBC_Require(cRefs > 0);
3063 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3064 + DBC_Require(pEntry != NULL);
3066 + GT_2trace(DBL_debugMask, GT_ENTER,
3067 + "DBL_getEntry: lib: 0x%x pEntry: 0x%x\n", lib, pEntry);
3068 + *pEntry = pdblLib->fileHdr.entry;
3070 + return true;
3074 + * ======== DBL_getSect ========
3075 + * Purpose:
3076 + * Get address and size of a named section.
3077 + */
3078 +DSP_STATUS DBL_getSect(struct DBL_LibraryObj *lib, char *name, u32 *pAddr,
3079 + u32 *pSize)
3081 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3082 + u16 i;
3083 + DSP_STATUS status = DSP_ENOSECT;
3085 + DBC_Require(cRefs > 0);
3086 + DBC_Require(name != NULL);
3087 + DBC_Require(pAddr != NULL);
3088 + DBC_Require(pSize != NULL);
3089 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3091 + GT_4trace(DBL_debugMask, GT_ENTER,
3092 + "DBL_getSect: lib: 0x%x name: %s pAddr:"
3093 + " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize);
3095 + /*
3096 + * Check for DCD and overlay sections. Overlay loader uses DBL_getSect
3097 + * to determine whether or not a node has overlay sections.
3098 + * DCD section names begin with '.'
3099 + */
3100 + if (name[0] == '.') {
3101 + /* Get DCD section size (address is 0, since it's a NOLOAD). */
3102 + for (i = 0; i < pdblLib->nDCDSects; i++) {
3103 + if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name,
3104 + name) == 0) {
3105 + *pAddr = 0;
3106 + *pSize = pdblLib->dcdSects[i].sectHdr.size *
3107 + pdblLib->pTargetInfo->mauSize;
3108 + status = DSP_SOK;
3109 + break;
3112 + } else {
3113 + /* Check for overlay section */
3114 + for (i = 0; i < pdblLib->nOvlySects; i++) {
3115 + if (CSL_Strcmp(pdblLib->ppOvlyData[i]->hdr.pName,
3116 + name) == 0) {
3117 + /* Address and size are meaningless */
3118 + *pAddr = 0;
3119 + *pSize = 0;
3120 + status = DSP_SOK;
3121 + break;
3126 + return status;
3130 + * ======== DBL_init ========
3131 + * Purpose:
3132 + * Initialize DBL module.
3133 + */
3134 +bool DBL_init(void)
3136 + bool retVal = true;
3138 + DBC_Require(cRefs >= 0);
3140 + if (cRefs == 0) {
3141 + DBC_Assert(!DBL_debugMask.flags);
3142 + GT_create(&DBL_debugMask, "BL"); /* "BL" for dBL */
3146 + if (retVal)
3147 + cRefs++;
3150 + GT_1trace(DBL_debugMask, GT_5CLASS, "DBL_init(), ref count: 0x%x\n",
3151 + cRefs);
3153 + DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0)));
3155 + return retVal;
3159 + * ======== DBL_load ========
3160 + * Purpose:
3161 + * Add symbols/code/data defined in file to that already present
3162 + * on the target.
3163 + */
3164 +DSP_STATUS DBL_load(struct DBL_LibraryObj *lib, DBL_Flags flags,
3165 + struct DBL_Attrs *attrs, u32 *pEntry)
3167 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3168 + struct DBL_TargetObj *dbl;
3169 + u16 i;
3170 + u16 nSects;
3171 + DSP_STATUS status = DSP_EFAIL;
3173 + DBC_Require(cRefs > 0);
3174 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3175 + DBC_Require(pEntry != NULL);
3176 + DBC_Require(attrs != NULL);
3178 + GT_4trace(DBL_debugMask, GT_ENTER, "DBL_load: lib: 0x%x flags: "
3179 + "0x%x attrs: 0x%x pEntry: 0x%x\n", lib, flags, attrs, pEntry);
3181 + dbl = pdblLib->pTarget;
3182 + *pEntry = pdblLib->fileHdr.entry;
3183 + nSects = pdblLib->fileHdr.numSects;
3184 + dbl->dblAttrs = *attrs;
3186 + for (i = 0; i < nSects; i++) {
3187 + /* Load the section at the current file offset */
3188 + status = loadSect(dbl, lib);
3189 + if (DSP_FAILED(status))
3190 + break;
3194 + /* Done with file, we can close it */
3195 + if (pdblLib->file) {
3196 + (*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file);
3197 + pdblLib->file = NULL;
3199 + return status;
3203 + * ======== DBL_loadSect ========
3204 + * Purpose:
3205 + * Load a named section from an library (for overlay support).
3206 + */
3207 +DSP_STATUS DBL_loadSect(struct DBL_LibraryObj *lib, char *sectName,
3208 + struct DBL_Attrs *attrs)
3210 + struct DBL_TargetObj *dbl;
3211 + s32 i;
3212 + s32 phase;
3213 + s32 offset = -1;
3214 + s32 nSects = -1;
3215 + s32 allocdSects = 0;
3216 + u32 loadAddr;
3217 + u32 runAddr;
3218 + u32 size;
3219 + u32 space;
3220 + u32 ulBytes;
3221 + u16 mauSize;
3222 + u16 wordSize;
3223 + u16 *phaseRef = NULL;
3224 + u16 *otherRef = NULL;
3225 + char *name = NULL;
3226 + struct OvlyData *pOvlyData;
3227 + DSP_STATUS status = DSP_ENOSECT;
3229 + DBC_Require(cRefs > 0);
3230 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3231 + DBC_Require(sectName != NULL);
3232 + DBC_Require(attrs != NULL);
3233 + DBC_Require(attrs->write != NULL);
3234 + GT_3trace(DBL_debugMask, GT_ENTER,
3235 + "DBL_loadSect: lib: 0x%x sectName: %s "
3236 + "attrs: 0x%x\n", lib, sectName, attrs);
3237 + dbl = lib->pTarget;
3238 + mauSize = lib->pTargetInfo->mauSize;
3239 + wordSize = lib->pTargetInfo->wordSize;
3240 + /* Check for match of sect name in overlay table */
3241 + for (i = 0; i < lib->nOvlySects; i++) {
3242 + name = lib->ppOvlyData[i]->hdr.pName;
3243 + if (!CSL_Strncmp(name, sectName, CSL_Strlen(name))) {
3244 + /* Match found */
3245 + status = DSP_SOK;
3246 + break;
3249 + if (DSP_SUCCEEDED(status)) {
3250 + DBC_Assert(i < lib->nOvlySects);
3251 + pOvlyData = lib->ppOvlyData[i];
3252 + /*
3253 + * If node overlay, phase will be encoded in name. If not node
3254 + * overlay, set phase to NONE.
3255 + */
3256 + phase = (CSL_Strcmp(name, sectName)) ?
3257 + CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE;
3258 + /* Get reference count of node phase to be loaded, offset into
3259 + * overlay data array, and number of sections to overlay. */
3260 + switch (phase) {
3261 + case NONE:
3262 + /* Not a node overlay */
3263 + phaseRef = &pOvlyData->hdr.otherRef;
3264 + nSects = numOtherSects(pOvlyData);
3265 + offset = otherOffset(pOvlyData);
3266 + break;
3267 + case CREATEPHASE:
3268 + phaseRef = &pOvlyData->hdr.createRef;
3269 + otherRef = &pOvlyData->hdr.otherRef;
3270 + if (*otherRef) {
3271 + /* The overlay sections where node phase was
3272 + * not specified, have already been loaded. */
3273 + nSects = numCreateSects(pOvlyData);
3274 + offset = createOffset(pOvlyData);
3275 + } else {
3276 + /* Overlay sections where node phase was not
3277 + * specified get loaded at create time, along
3278 + * with create sects. */
3279 + nSects = numCreateSects(pOvlyData) +
3280 + numOtherSects(pOvlyData);
3281 + offset = otherOffset(pOvlyData);
3283 + break;
3284 + case DELETEPHASE:
3285 + phaseRef = &pOvlyData->hdr.deleteRef;
3286 + nSects = numDeleteSects(pOvlyData);
3287 + offset = deleteOffset(pOvlyData);
3288 + break;
3289 + case EXECUTEPHASE:
3290 + phaseRef = &pOvlyData->hdr.executeRef;
3291 + nSects = numExecuteSects(pOvlyData);
3292 + offset = executeOffset(pOvlyData);
3293 + break;
3294 + default:
3295 + /* ERROR */
3296 + DBC_Assert(false);
3297 + break;
3299 + /* Do overlay if reference count is 0 */
3300 + if (!(*phaseRef)) {
3301 + /* "Allocate" all sections */
3302 + for (i = 0; i < nSects; i++) {
3303 + runAddr = pOvlyData->data[offset + i].runAddr;
3304 + size = pOvlyData->data[offset + i].size;
3305 + space = pOvlyData->data[offset + i].page;
3306 + status = (dbl->dblAttrs.alloc)(dbl->dblAttrs.
3307 + rmmHandle, space, size, 0,
3308 + &runAddr, true);
3309 + if (DSP_FAILED(status))
3310 + break;
3312 + allocdSects++;
3314 + if (DSP_SUCCEEDED(status)) {
3315 + /* Load sections */
3316 + for (i = 0; i < nSects; i++) {
3317 + loadAddr = pOvlyData->data[offset + i].
3318 + loadAddr;
3319 + runAddr = pOvlyData->data[offset + i].
3320 + runAddr;
3321 + size = pOvlyData->data[offset + i].
3322 + size;
3323 + space = pOvlyData->data[offset + i].
3324 + page;
3325 + /* Convert to word address, call
3326 + * write function */
3327 + loadAddr /= (wordSize / mauSize);
3328 + runAddr /= (wordSize / mauSize);
3329 + ulBytes = size * mauSize;
3330 + if ((*attrs->write)(attrs->wHandle,
3331 + runAddr, (void *)loadAddr, ulBytes,
3332 + space) != ulBytes) {
3333 + GT_0trace(DBL_debugMask,
3334 + GT_6CLASS,
3335 + "DBL_loadSect: write"
3336 + " failed\n");
3337 + status = DSP_EFWRITE;
3338 + break;
3342 + /* Free sections on failure */
3343 + if (DSP_FAILED(status))
3344 + freeSects(dbl, pOvlyData, offset, allocdSects);
3348 + if (DSP_SUCCEEDED(status)) {
3349 + /* Increment reference counts */
3350 + if (otherRef)
3351 + *otherRef = *otherRef + 1;
3353 + *phaseRef = *phaseRef + 1;
3355 + return status;
3359 + * ======== DBL_open ========
3360 + * Purpose:
3361 + * DBL_open() returns a library handle that can be used to
3362 + * load/unload the symbols/code/data via DBL_load()/DBL_unload().
3363 + */
3364 +DSP_STATUS DBL_open(struct DBL_TargetObj *target, char *file, DBL_Flags flags,
3365 + struct DBL_LibraryObj **pLib)
3367 + struct DBL_LibraryObj *pdblLib = NULL;
3368 + u16 nSymbols;
3369 + u16 nDCDSects;
3370 + DSP_STATUS status = DSP_SOK;
3371 + DBC_Require(cRefs > 0);
3372 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
3373 + DBC_Require(target->dblAttrs.fopen != NULL);
3374 + DBC_Require(file != NULL);
3375 + DBC_Require(pLib != NULL);
3377 + GT_3trace(DBL_debugMask, GT_ENTER, "DBL_open: target: 0x%x file: %s "
3378 + "pLib: 0x%x\n", target, file, pLib);
3379 + /* Allocate DBL library object */
3380 + MEM_AllocObject(pdblLib, struct DBL_LibraryObj, DBL_LIBSIGNATURE);
3381 + if (pdblLib == NULL)
3382 + status = DSP_EMEMORY;
3384 + /* Open the file */
3385 + if (DSP_SUCCEEDED(status)) {
3386 + pdblLib->pTarget = target;
3387 + pdblLib->file = (*target->dblAttrs.fopen)(file, "rb");
3388 + if (pdblLib->file == NULL)
3389 + status = DSP_EFOPEN;
3392 + /* Read file header */
3393 + if (DSP_SUCCEEDED(status)) {
3394 + status = readHeader(target, pdblLib);
3395 + if (DSP_FAILED(status)) {
3396 + GT_0trace(DBL_debugMask, GT_6CLASS,
3397 + "DBL_open(): Failed to read file header\n");
3400 + /* Allocate symbol table */
3401 + if (DSP_SUCCEEDED(status)) {
3402 + nSymbols = pdblLib->nSymbols = pdblLib->fileHdr.numSymbols;
3403 + pdblLib->symbols = MEM_Calloc(nSymbols * sizeof(struct Symbol),
3404 + MEM_PAGED);
3405 + if (pdblLib->symbols == NULL)
3406 + status = DSP_EMEMORY;
3409 + /* Read all the symbols */
3410 + if (DSP_SUCCEEDED(status)) {
3411 + status = readSymbols(target, pdblLib);
3412 + if (DSP_FAILED(status)) {
3413 + GT_0trace(DBL_debugMask, GT_6CLASS,
3414 + "DBL_open(): Failed to read symbols\n");
3417 + /* Allocate DCD sect table */
3418 + if (DSP_SUCCEEDED(status)) {
3419 + nDCDSects = pdblLib->nDCDSects = pdblLib->fileHdr.numDCDSects;
3420 + pdblLib->dcdSects = MEM_Calloc(nDCDSects *
3421 + sizeof(struct DCDSect), MEM_PAGED);
3422 + if (pdblLib->dcdSects == NULL)
3423 + status = DSP_EMEMORY;
3426 + /* Read DCD sections */
3427 + if (DSP_SUCCEEDED(status)) {
3428 + status = readDCDSects(target, pdblLib);
3429 + if (DSP_FAILED(status)) {
3430 + GT_0trace(DBL_debugMask, GT_6CLASS,
3431 + "DBL_open(): Failed to read DCD sections\n");
3434 + /* Read overlay sections */
3435 + if (DSP_SUCCEEDED(status)) {
3436 + status = readOvlySects(target, pdblLib);
3437 + if (DSP_FAILED(status)) {
3438 + GT_0trace(DBL_debugMask, GT_6CLASS,
3439 + "DBL_open(): Failed to read "
3440 + "overlay sections\n");
3443 + if (DSP_FAILED(status)) {
3444 + *pLib = NULL;
3445 + if (pdblLib != NULL)
3446 + DBL_close((struct DBL_LibraryObj *) pdblLib);
3448 + } else {
3449 + *pLib = pdblLib;
3451 + DBC_Ensure((DSP_SUCCEEDED(status) &&
3452 + (MEM_IsValidHandle((*pLib), DBL_LIBSIGNATURE))) ||
3453 + (DSP_FAILED(status) && *pLib == NULL));
3454 + return status;
3458 + * ======== DBL_readSect ========
3459 + * Purpose:
3460 + * Read COFF section into a character buffer.
3461 + */
3462 +DSP_STATUS DBL_readSect(struct DBL_LibraryObj *lib, char *name, char *pContent,
3463 + u32 size)
3465 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3466 + u16 i;
3467 + u32 mauSize;
3468 + u32 max;
3469 + DSP_STATUS status = DSP_ENOSECT;
3471 + DBC_Require(cRefs > 0);
3472 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3473 + DBC_Require(name != NULL);
3474 + DBC_Require(pContent != NULL);
3475 + DBC_Require(size != 0);
3476 + GT_4trace(DBL_debugMask, GT_ENTER, "DBL_readSect: lib: 0x%x name: %s "
3477 + "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size);
3479 + mauSize = pdblLib->pTargetInfo->mauSize;
3481 + /* Attempt to find match with DCD section names. */
3482 + for (i = 0; i < pdblLib->nDCDSects; i++) {
3483 + if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name, name) == 0) {
3484 + /* Match found */
3485 + max = pdblLib->dcdSects[i].sectHdr.size * mauSize;
3486 + max = (max > size) ? size : max;
3487 + memcpy(pContent, pdblLib->dcdSects[i].pData, max);
3488 + status = DSP_SOK;
3489 + break;
3493 + return status;
3497 + * ======== DBL_setAttrs ========
3498 + * Purpose:
3499 + * Set the attributes of the target.
3500 + */
3501 +void DBL_setAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs)
3503 + DBC_Require(cRefs > 0);
3504 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
3505 + DBC_Require(pAttrs != NULL);
3507 + GT_2trace(DBL_debugMask, GT_ENTER, "DBL_setAttrs: target: 0x%x pAttrs: "
3508 + "0x%x\n", target, pAttrs);
3510 + target->dblAttrs = *pAttrs;
3514 + * ======== DBL_unload ========
3515 + * Purpose:
3516 + * Remove the symbols/code/data corresponding to the library lib.
3517 + */
3518 +void DBL_unload(struct DBL_LibraryObj *lib, struct DBL_Attrs *attrs)
3520 + DBC_Require(cRefs > 0);
3521 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3523 + GT_1trace(DBL_debugMask, GT_ENTER, "DBL_unload: lib: 0x%x\n", lib);
3525 + /* Nothing to do for static loading */
3529 + * ======== DBL_unloadSect ========
3530 + * Purpose:
3531 + * Unload a named section from an library (for overlay support).
3532 + */
3533 +DSP_STATUS DBL_unloadSect(struct DBL_LibraryObj *lib, char *sectName,
3534 + struct DBL_Attrs *attrs)
3536 + struct DBL_TargetObj *dbl;
3537 + s32 i;
3538 + s32 phase;
3539 + s32 offset = -1;
3540 + s32 nSects = -1;
3541 + u16 *phaseRef = NULL;
3542 + u16 *otherRef = NULL;
3543 + char *pName = NULL;
3544 + struct OvlyData *pOvlyData;
3545 + DSP_STATUS status = DSP_ENOSECT;
3547 + DBC_Require(cRefs > 0);
3548 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3549 + DBC_Require(sectName != NULL);
3551 + GT_2trace(DBL_debugMask, GT_ENTER,
3552 + "DBL_unloadSect: lib: 0x%x sectName: %s\n", lib, sectName);
3553 + dbl = lib->pTarget;
3554 + /* Check for match of sect name in overlay table */
3555 + for (i = 0; i < lib->nOvlySects; i++) {
3556 + pName = lib->ppOvlyData[i]->hdr.pName;
3557 + if (!CSL_Strncmp(pName, sectName, CSL_Strlen(pName))) {
3558 + /* Match found */
3559 + status = DSP_SOK;
3560 + break;
3563 + if (DSP_SUCCEEDED(status)) {
3564 + DBC_Assert(i < lib->nOvlySects);
3565 + pOvlyData = lib->ppOvlyData[i];
3566 + /* If node overlay, phase will be encoded in name. */
3567 + phase = (CSL_Strcmp(pName, sectName)) ?
3568 + CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE;
3569 + switch (phase) {
3570 + case NONE:
3571 + nSects = numOtherSects(pOvlyData);
3572 + phaseRef = &pOvlyData->hdr.otherRef;
3573 + offset = otherOffset(pOvlyData);
3574 + break;
3575 + case CREATEPHASE:
3576 + nSects = numCreateSects(pOvlyData);
3577 + offset = createOffset(pOvlyData);
3578 + phaseRef = &pOvlyData->hdr.createRef;
3579 + break;
3580 + case DELETEPHASE:
3581 + nSects = numDeleteSects(pOvlyData);
3582 + offset = deleteOffset(pOvlyData);
3583 + phaseRef = &pOvlyData->hdr.deleteRef;
3584 + otherRef = &pOvlyData->hdr.otherRef;
3585 + break;
3586 + case EXECUTEPHASE:
3587 + nSects = numExecuteSects(pOvlyData);
3588 + offset = executeOffset(pOvlyData);
3589 + phaseRef = &pOvlyData->hdr.executeRef;
3590 + break;
3591 + default:
3592 + /* ERROR */
3593 + DBC_Assert(false);
3594 + break;
3596 + if (*phaseRef) {
3597 + *phaseRef = *phaseRef - 1;
3598 + if (*phaseRef == 0) {
3599 + /* Unload overlay sections for phase */
3600 + freeSects(dbl, pOvlyData, offset, nSects);
3602 + if (phase == DELETEPHASE) {
3603 + DBC_Assert(*otherRef);
3604 + *otherRef = *otherRef - 1;
3605 + if (*otherRef == 0) {
3606 + /* Unload other overlay sections */
3607 + nSects = numOtherSects(pOvlyData);
3608 + offset = otherOffset(pOvlyData);
3609 + freeSects(dbl, pOvlyData, offset,
3610 + nSects);
3616 + return status;
3620 + * ======== freeSects ========
3621 + * Purpose:
3622 + * Free section
3623 + */
3624 +static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData,
3625 + s32 offset, s32 nSects)
3627 + u32 runAddr;
3628 + u32 size;
3629 + u32 space;
3630 + s32 i;
3632 + for (i = 0; i < nSects; i++) {
3633 + runAddr = pOvlyData->data[offset + i].runAddr;
3634 + size = pOvlyData->data[offset + i].size;
3635 + space = pOvlyData->data[offset + i].page;
3636 + if (!(dbl->dblAttrs.free)
3637 + (dbl->dblAttrs.rmmHandle, space, runAddr, size, true)) {
3638 + /*
3639 + * Free function will not fail for overlay, unless
3640 + * address passed in is bad.
3641 + */
3642 + DBC_Assert(false);
3648 + * ======== loadSect ========
3649 + * Purpose:
3650 + * Load section to target
3651 + */
3652 +static DSP_STATUS loadSect(struct DBL_TargetObj *dbl,
3653 + struct DBL_LibraryObj *pdblLib)
3655 + struct DBOF_SectHdr sectHdr;
3656 + char *pBuf;
3657 + struct KFILE_FileObj *file;
3658 + u32 space;
3659 + u32 addr;
3660 + u32 total;
3661 + u32 nWords = 0;
3662 + u32 nBytes = 0;
3663 + u16 mauSize;
3664 + u32 bufSize;
3665 + DSP_STATUS status = DSP_SOK;
3667 + file = pdblLib->file;
3668 + mauSize = pdblLib->pTargetInfo->mauSize;
3669 + bufSize = LOADBUFSIZE / mauSize;
3670 + pBuf = dbl->pBuf;
3672 + /* Read the section header */
3673 + if ((*dbl->dblAttrs.fread)(&sectHdr, sizeof(struct DBOF_SectHdr),
3674 + 1, file) != 1) {
3675 + GT_0trace(DBL_debugMask, GT_6CLASS,
3676 + "Failed to read DCD sect header\n");
3677 + status = DSP_EFREAD;
3678 + } else {
3679 + if (pdblLib->byteSwapped) {
3680 + sectHdr.size = SWAPLONG(sectHdr.size);
3681 + sectHdr.addr = SWAPLONG(sectHdr.addr);
3682 + sectHdr.page = SWAPWORD(sectHdr.page);
3685 + if (DSP_SUCCEEDED(status)) {
3686 + addr = sectHdr.addr;
3687 + space = sectHdr.page;
3688 + for (total = sectHdr.size; total > 0; total -= nWords) {
3689 + nWords = min(total, bufSize);
3690 + nBytes = nWords * mauSize;
3691 + /* Read section data */
3692 + if ((*dbl->dblAttrs.fread)(pBuf, nBytes, 1,
3693 + file) != 1) {
3694 + GT_0trace(DBL_debugMask, GT_6CLASS,
3695 + "Failed to read DCD sect header\n");
3696 + status = DSP_EFREAD;
3697 + break;
3699 + /* Write section to target */
3700 + if (!(*dbl->dblAttrs.write)(dbl->dblAttrs.wHandle,
3701 + addr, pBuf, nBytes, space)) {
3702 + GT_0trace(DBL_debugMask, GT_6CLASS,
3703 + "Failed to write section data\n");
3704 + status = DSP_EFWRITE;
3705 + break;
3707 + addr += nWords;
3710 + return status;
3714 + * ======== readDCDSects ========
3715 + * Purpose:
3716 + * Read DCD sections.
3717 + */
3718 +static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl,
3719 + struct DBL_LibraryObj *pdblLib)
3721 + struct DBOF_DCDSectHdr *pSectHdr;
3722 + struct DCDSect *pSect;
3723 + struct KFILE_FileObj *file;
3724 + u16 nSects;
3725 + u16 i;
3726 + u16 mauSize;
3727 + DSP_STATUS status = DSP_SOK;
3729 + file = pdblLib->file;
3730 + mauSize = pdblLib->pTargetInfo->mauSize;
3731 + nSects = pdblLib->fileHdr.numDCDSects;
3732 + for (i = 0; i < nSects; i++) {
3733 + pSect = &pdblLib->dcdSects[i];
3734 + pSectHdr = &pdblLib->dcdSects[i].sectHdr;
3735 + /* Read sect header */
3736 + if ((*dbl->dblAttrs.fread)(pSectHdr,
3737 + sizeof(struct DBOF_DCDSectHdr), 1, file) != 1) {
3738 + GT_0trace(DBL_debugMask, GT_6CLASS,
3739 + "Failed to read DCD sect header\n");
3740 + status = DSP_EFREAD;
3741 + break;
3743 + if (pdblLib->byteSwapped)
3744 + pSectHdr->size = SWAPLONG(pSectHdr->size);
3746 + pSect->pData = (char *)MEM_Calloc(pSectHdr->size *
3747 + mauSize, MEM_PAGED);
3748 + if (pSect->pData == NULL) {
3749 + GT_2trace(DBL_debugMask, GT_6CLASS,
3750 + "Memory allocation for sect %s "
3751 + "data failed: Size: 0x%lx\n", pSectHdr->name,
3752 + pSectHdr->size);
3753 + status = DSP_EMEMORY;
3754 + break;
3756 + /* Read DCD sect data */
3757 + if ((*dbl->dblAttrs.fread)(pSect->pData, mauSize,
3758 + pSectHdr->size, file) != pSectHdr->size) {
3759 + GT_0trace(DBL_debugMask, GT_6CLASS,
3760 + "Failed to read DCD sect data\n");
3761 + status = DSP_EFREAD;
3762 + break;
3766 + return status;
3770 + * ======== readHeader ========
3771 + * Purpose:
3772 + * Read Header.
3773 + */
3774 +static DSP_STATUS readHeader(struct DBL_TargetObj *dbl,
3775 + struct DBL_LibraryObj *pdblLib)
3777 + struct KFILE_FileObj *file;
3778 + s32 i;
3779 + struct DBOF_FileHdr *pHdr;
3780 + u32 swapMagic;
3781 + DSP_STATUS status = DSP_SOK;
3783 + pdblLib->byteSwapped = false;
3784 + file = pdblLib->file;
3785 + pHdr = &pdblLib->fileHdr;
3786 + if ((*dbl->dblAttrs.fread)(pHdr, sizeof(struct DBOF_FileHdr), 1,
3787 + file) != 1) {
3788 + GT_0trace(DBL_debugMask, GT_6CLASS,
3789 + "readHeader: Failed to read file header\n");
3790 + status = DSP_EFREAD;
3793 + if (DSP_SUCCEEDED(status)) {
3794 + /* Determine if byte swapped */
3795 + for (i = 0; i < NUMTARGS; i++) {
3796 + swapMagic = SWAPLONG(pHdr->magic);
3797 + if (pHdr->magic == magicTab[i] || swapMagic ==
3798 + magicTab[i]) {
3799 + if (swapMagic == magicTab[i]) {
3800 + pdblLib->byteSwapped = true;
3801 + pHdr->magic = SWAPLONG(pHdr->magic);
3802 + pHdr->entry = SWAPLONG(pHdr->entry);
3803 + pHdr->symOffset = SWAPLONG(pHdr->
3804 + symOffset);
3805 + pHdr->dcdSectOffset = SWAPLONG(pHdr->
3806 + dcdSectOffset);
3807 + pHdr->loadSectOffset = SWAPLONG(pHdr->
3808 + loadSectOffset);
3809 + pHdr->ovlySectOffset = SWAPLONG(pHdr->
3810 + ovlySectOffset);
3811 + pHdr->numSymbols = SWAPWORD(pHdr->
3812 + numSymbols);
3813 + pHdr->numDCDSects = SWAPWORD(pHdr->
3814 + numDCDSects);
3815 + pHdr->numSects = SWAPWORD(pHdr->
3816 + numSects);
3817 + pHdr->numOvlySects = SWAPWORD(pHdr->
3818 + numOvlySects);
3820 + break;
3823 + if (i == NUMTARGS) {
3824 + GT_0trace(DBL_debugMask, GT_6CLASS,
3825 + "readHeader: Failed to determine"
3826 + " target type\n");
3827 + status = DSP_ECORRUPTFILE;
3828 + } else {
3829 + pdblLib->pTargetInfo = &targetTab[i];
3830 + GT_1trace(DBL_debugMask, GT_ENTER,
3831 + "COF type: 0x%lx\n", pHdr->magic);
3832 + GT_1trace(DBL_debugMask, GT_ENTER,
3833 + "Entry point:0x%lx\n", pHdr->entry);
3836 + return status;
3840 + * ======== readOvlySects ========
3841 + * Purpose:
3842 + * Read Overlay Sections
3843 + */
3844 +static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl,
3845 + struct DBL_LibraryObj *pdblLib)
3847 + struct DBOF_OvlySectHdr hdr;
3848 + struct DBOF_OvlySectData *pData;
3849 + struct OvlyData *pOvlyData;
3850 + char *pName;
3851 + struct KFILE_FileObj *file;
3852 + u16 i, j;
3853 + u16 nSects;
3854 + u16 n;
3855 + DSP_STATUS status = DSP_SOK;
3857 + pdblLib->nOvlySects = nSects = pdblLib->fileHdr.numOvlySects;
3858 + file = pdblLib->file;
3859 + if (nSects > 0) {
3860 + pdblLib->ppOvlyData = MEM_Calloc(nSects * sizeof(OvlyData *),
3861 + MEM_PAGED);
3862 + if (pdblLib->ppOvlyData == NULL) {
3863 + GT_0trace(DBL_debugMask, GT_7CLASS,
3864 + "Failed to allocatate overlay "
3865 + "data memory\n");
3866 + status = DSP_EMEMORY;
3869 + if (DSP_SUCCEEDED(status)) {
3870 + /* Read overlay data for each node */
3871 + for (i = 0; i < nSects; i++) {
3872 + /* Read overlay section header */
3873 + if ((*dbl->dblAttrs.fread)(&hdr,
3874 + sizeof(struct DBOF_OvlySectHdr), 1, file) != 1) {
3875 + GT_0trace(DBL_debugMask, GT_6CLASS,
3876 + "Failed to read overlay sect"
3877 + " header\n");
3878 + status = DSP_EFREAD;
3879 + break;
3881 + if (pdblLib->byteSwapped) {
3882 + hdr.nameLen = SWAPWORD(hdr.nameLen);
3883 + hdr.numCreateSects =
3884 + SWAPWORD(hdr.numCreateSects);
3885 + hdr.numDeleteSects =
3886 + SWAPWORD(hdr.numDeleteSects);
3887 + hdr.numExecuteSects =
3888 + SWAPWORD(hdr.numExecuteSects);
3889 + hdr.numOtherSects =
3890 + SWAPWORD(hdr.numOtherSects);
3891 + hdr.resvd = SWAPWORD(hdr.resvd);
3893 + n = hdr.numCreateSects + hdr.numDeleteSects +
3894 + hdr.numExecuteSects + hdr.numOtherSects;
3896 + /* Allocate memory for node's overlay data */
3897 + pOvlyData = (struct OvlyData *)MEM_Calloc
3898 + (sizeof(struct OvlyHdr) +
3899 + n * sizeof(struct DBOF_OvlySectData),
3900 + MEM_PAGED);
3901 + if (pOvlyData == NULL) {
3902 + GT_0trace(DBL_debugMask, GT_7CLASS,
3903 + "Failed to allocatate ovlyay"
3904 + " data memory\n");
3905 + status = DSP_EMEMORY;
3906 + break;
3908 + pOvlyData->hdr.dbofHdr = hdr;
3909 + pdblLib->ppOvlyData[i] = pOvlyData;
3910 + /* Allocate memory for section name */
3911 + pName = (char *)MEM_Calloc(hdr.nameLen + 1, MEM_PAGED);
3912 + if (pName == NULL) {
3913 + GT_0trace(DBL_debugMask, GT_7CLASS,
3914 + "Failed to allocatate ovlyay"
3915 + " section name\n");
3916 + status = DSP_EMEMORY;
3917 + break;
3919 + pOvlyData->hdr.pName = pName;
3920 + /* Read the overlay section name */
3921 + if ((*dbl->dblAttrs.fread)(pName, sizeof(char),
3922 + hdr.nameLen, file) != hdr.nameLen) {
3923 + GT_0trace(DBL_debugMask, GT_7CLASS,
3924 + "readOvlySects: Unable to "
3925 + "read overlay name.\n");
3926 + status = DSP_EFREAD;
3927 + break;
3929 + /* Read the overlay section data */
3930 + pData = pOvlyData->data;
3931 + if ((*dbl->dblAttrs.fread)(pData,
3932 + sizeof(struct DBOF_OvlySectData), n, file) != n) {
3933 + GT_0trace(DBL_debugMask, GT_7CLASS,
3934 + "readOvlySects: Unable to "
3935 + "read overlay data.\n");
3936 + status = DSP_EFREAD;
3937 + break;
3939 + /* Swap overlay data, if necessary */
3940 + if (pdblLib->byteSwapped) {
3941 + for (j = 0; j < n; j++) {
3942 + pData[j].loadAddr =
3943 + SWAPLONG(pData[j].loadAddr);
3944 + pData[j].runAddr =
3945 + SWAPLONG(pData[j].runAddr);
3946 + pData[j].size =
3947 + SWAPLONG(pData[j].size);
3948 + pData[j].page =
3949 + SWAPWORD(pData[j].page);
3954 + return status;
3958 + * ======== readSymbols ========
3959 + * Purpose:
3960 + * Read Symbols
3961 + */
3962 +static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl,
3963 + struct DBL_LibraryObj *pdblLib)
3965 + struct DBOF_SymbolHdr symHdr;
3966 + struct KFILE_FileObj *file;
3967 + u16 i;
3968 + u16 nSymbols;
3969 + u16 len;
3970 + char *pName = NULL;
3971 + DSP_STATUS status = DSP_SOK;
3973 + file = pdblLib->file;
3975 + nSymbols = pdblLib->fileHdr.numSymbols;
3977 + for (i = 0; i < nSymbols; i++) {
3978 + /* Read symbol value */
3979 + if ((*dbl->dblAttrs.fread)(&symHdr,
3980 + sizeof(struct DBOF_SymbolHdr), 1, file) != 1) {
3981 + GT_0trace(DBL_debugMask, GT_6CLASS,
3982 + "Failed to read symbol value\n");
3983 + status = DSP_EFREAD;
3984 + break;
3986 + if (pdblLib->byteSwapped) {
3987 + symHdr.nameLen = SWAPWORD(symHdr.nameLen);
3988 + symHdr.value = SWAPLONG(symHdr.value);
3990 + /* Allocate buffer for symbol name */
3991 + len = symHdr.nameLen;
3992 + pName = (char *)MEM_Calloc(len + 1, MEM_PAGED);
3993 + if (pName == NULL) {
3994 + GT_0trace(DBL_debugMask, GT_6CLASS,
3995 + "Memory allocation failed\n");
3996 + status = DSP_EMEMORY;
3997 + break;
3999 + pdblLib->symbols[i].pSymName = pName;
4000 + pdblLib->symbols[i].sym.value = symHdr.value;
4001 + /* Read symbol name */
4002 + if ((*dbl->dblAttrs.fread) (pName, sizeof(char), len, file) !=
4003 + len) {
4004 + GT_0trace(DBL_debugMask, GT_6CLASS,
4005 + "Failed to read symbol value\n");
4006 + status = DSP_EFREAD;
4007 + break;
4008 + } else {
4009 + pName[len] = '\0';
4010 + GT_2trace(DBL_debugMask, GT_ENTER,
4011 + "Symbol: %s Value: 0x%lx\n",
4012 + pName, symHdr.value);
4015 + return status;
4018 diff --git a/drivers/dsp/bridge/pmgr/dbll.c b/drivers/dsp/bridge/pmgr/dbll.c
4019 new file mode 100644
4020 index 0000000..d4c365f
4021 --- /dev/null
4022 +++ b/drivers/dsp/bridge/pmgr/dbll.c
4023 @@ -0,0 +1,1565 @@
4025 + * linux/drivers/dsp/bridge/pmgr/linux/dbll/dbll.c
4027 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
4029 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
4031 + * This package is free software; you can redistribute it and/or modify
4032 + * it under the terms of the GNU General Public License version 2 as
4033 + * published by the Free Software Foundation.
4035 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
4036 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
4037 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
4038 + */
4041 + * ======== dbll.c ========
4043 + *! Revision History
4044 + *! ================
4045 + *! 25-Apr-2030 map: Fixed symbol redefinition bug + unload and return error
4046 + *! 08-Apr-2003 map: Consolidated DBL with DBLL loader name
4047 + *! 24-Mar-2003 map: Updated findSymbol to support dllview update
4048 + *! 23-Jan-2003 map: Updated rmmAlloc to support memory granularity
4049 + *! 21-Nov-2002 map: Combine fopen and DLOAD_module_open to increase
4050 + *! performance on start.
4051 + *! 04-Oct-2002 map: Integrated new TIP dynamic loader w/ DOF api.
4052 + *! 27-Sep-2002 map: Changed handle passed to RemoteFree, instead of
4053 + *! RMM_free; added GT_trace to rmmDealloc
4054 + *! 20-Sep-2002 map: Updated from Code Review
4055 + *! 08-Aug-2002 jeh: Updated to support overlays.
4056 + *! 25-Jun-2002 jeh: Pass RMM_Addr object to alloc function in rmmAlloc().
4057 + *! 20-Mar-2002 jeh: Created.
4058 + */
4060 +/* ----------------------------------- Host OS */
4061 +#include <host_os.h>
4063 +/* ----------------------------------- DSP/BIOS Bridge */
4064 +#include <std.h>
4065 +#include <dbdefs.h>
4066 +#include <errbase.h>
4068 +/* ----------------------------------- Trace & Debug */
4069 +#include <gt.h>
4070 +#include <dbc.h>
4071 +#include <gh.h>
4073 +/* ----------------------------------- OS Adaptation Layer */
4074 +#include <csl.h>
4075 +#include <mem.h>
4077 +/* Dynamic loader library interface */
4078 +#include <dynamic_loader.h>
4079 +#include <getsection.h>
4081 +/* ----------------------------------- This */
4082 +#include <dbll.h>
4083 +#include <rmm.h>
4085 +#define DBLL_TARGSIGNATURE 0x544c4c44 /* "TLLD" */
4086 +#define DBLL_LIBSIGNATURE 0x4c4c4c44 /* "LLLD" */
4088 +/* Number of buckets for symbol hash table */
4089 +#define MAXBUCKETS 211
4091 +/* Max buffer length */
4092 +#define MAXEXPR 128
4094 +#ifndef UINT32_C
4095 +#define UINT32_C(zzz) ((uint32_t)zzz)
4096 +#endif
4097 +#define DOFF_ALIGN(x) (((x) + 3) & ~UINT32_C(3))
4100 + * ======== struct DBLL_TarObj* ========
4101 + * A target may have one or more libraries of symbols/code/data loaded
4102 + * onto it, where a library is simply the symbols/code/data contained
4103 + * in a DOFF file.
4104 + */
4106 + * ======== DBLL_TarObj ========
4107 + */
4108 +struct DBLL_TarObj {
4109 + u32 dwSignature; /* For object validation */
4110 + struct DBLL_Attrs attrs;
4111 + struct DBLL_LibraryObj *head; /* List of all opened libraries */
4112 +} ;
4115 + * The following 4 typedefs are "super classes" of the dynamic loader
4116 + * library types used in dynamic loader functions (dynamic_loader.h).
4117 + */
4119 + * ======== DBLLStream ========
4120 + * Contains Dynamic_Loader_Stream
4121 + */
4122 +struct DBLLStream {
4123 + struct Dynamic_Loader_Stream dlStream;
4124 + struct DBLL_LibraryObj *lib;
4125 +} ;
4128 + * ======== DBLLSymbol ========
4129 + */
4130 +struct DBLLSymbol {
4131 + struct Dynamic_Loader_Sym dlSymbol;
4132 + struct DBLL_LibraryObj *lib;
4133 +} ;
4136 + * ======== DBLLAlloc ========
4137 + */
4138 + struct DBLLAlloc {
4139 + struct Dynamic_Loader_Allocate dlAlloc;
4140 + struct DBLL_LibraryObj *lib;
4141 +} ;
4144 + * ======== DBLLInit ========
4145 + */
4146 +struct DBLLInit {
4147 + struct Dynamic_Loader_Initialize dlInit;
4148 + struct DBLL_LibraryObj *lib;
4152 + * ======== DBLL_Library ========
4153 + * A library handle is returned by DBLL_Open() and is passed to DBLL_load()
4154 + * to load symbols/code/data, and to DBLL_unload(), to remove the
4155 + * symbols/code/data loaded by DBLL_load().
4156 + */
4159 + * ======== DBLL_LibraryObj ========
4160 + */
4161 + struct DBLL_LibraryObj {
4162 + u32 dwSignature; /* For object validation */
4163 + struct DBLL_LibraryObj *next; /* Next library in target's list */
4164 + struct DBLL_LibraryObj *prev; /* Previous in the list */
4165 + struct DBLL_TarObj *pTarget; /* target for this library */
4167 + /* Objects needed by dynamic loader */
4168 + struct DBLLStream stream;
4169 + struct DBLLSymbol symbol;
4170 + struct DBLLAlloc allocate;
4171 + struct DBLLInit init;
4172 + DLOAD_mhandle mHandle;
4174 + char *fileName; /* COFF file name */
4175 + void *fp; /* Opaque file handle */
4176 + u32 entry; /* Entry point */
4177 + DLOAD_mhandle desc; /* desc of DOFF file loaded */
4178 + u32 openRef; /* Number of times opened */
4179 + u32 loadRef; /* Number of times loaded */
4180 + struct GH_THashTab *symTab; /* Hash table of symbols */
4181 + u32 ulPos;
4182 +} ;
4185 + * ======== Symbol ========
4186 + */
4187 +struct Symbol {
4188 + struct DBLL_Symbol value;
4189 + char *name;
4190 +} ;
4191 +extern bool bSymbolsReloaded;
4193 +static void dofClose(struct DBLL_LibraryObj *zlLib);
4194 +static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib);
4195 +static s32 NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr,
4196 + LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsiz);
4199 + * Functions called by dynamic loader
4201 + */
4202 +/* Dynamic_Loader_Stream */
4203 +static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer,
4204 + unsigned bufsize);
4205 +static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos);
4206 +/* Dynamic_Loader_Sym */
4207 +static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this,
4208 + const char *name);
4209 +static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this,
4210 + const char *name,
4211 + unsigned moduleId);
4212 +static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this,
4213 + const char *name,
4214 + unsigned moduleid);
4215 +static void purgeSymbolTable(struct Dynamic_Loader_Sym *this,
4216 + unsigned moduleId);
4217 +static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize);
4218 +static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr);
4219 +static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr,
4220 + va_list args);
4221 +/* Dynamic_Loader_Allocate */
4222 +static int rmmAlloc(struct Dynamic_Loader_Allocate *this,
4223 + struct LDR_SECTION_INFO *info, unsigned align);
4224 +static void rmmDealloc(struct Dynamic_Loader_Allocate *this,
4225 + struct LDR_SECTION_INFO *info);
4227 +/* Dynamic_Loader_Initialize */
4228 +static int connect(struct Dynamic_Loader_Initialize *this);
4229 +static int readMem(struct Dynamic_Loader_Initialize *this, void *buf,
4230 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
4231 + unsigned nbytes);
4232 +static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf,
4233 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
4234 + unsigned nbytes);
4235 +static int fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr,
4236 + struct LDR_SECTION_INFO *info, unsigned nbytes,
4237 + unsigned val);
4238 +static int execute(struct Dynamic_Loader_Initialize *this, LDR_ADDR start);
4239 +static void release(struct Dynamic_Loader_Initialize *this);
4241 +/* symbol table hash functions */
4242 +static u16 nameHash(void *name, u16 maxBucket);
4243 +static bool nameMatch(void *name, void *sp);
4244 +static void symDelete(void *sp);
4246 +#if GT_TRACE
4247 +static struct GT_Mask DBLL_debugMask = { NULL, NULL }; /* GT trace variable */
4248 +#endif
4250 +static u32 cRefs; /* module reference count */
4252 +/* Symbol Redefinition */
4253 +static int bRedefinedSymbol = 0;
4254 +static int bGblSearch = 1;
4257 + * ======== DBLL_close ========
4258 + */
4259 +void DBLL_close(struct DBLL_LibraryObj *zlLib)
4261 + struct DBLL_TarObj *zlTarget;
4263 + DBC_Require(cRefs > 0);
4264 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4265 + DBC_Require(zlLib->openRef > 0);
4266 + zlTarget = zlLib->pTarget;
4267 + GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_close: lib: 0x%x\n", zlLib);
4268 + zlLib->openRef--;
4269 + if (zlLib->openRef == 0) {
4270 + /* Remove library from list */
4271 + if (zlTarget->head == zlLib)
4272 + zlTarget->head = zlLib->next;
4274 + if (zlLib->prev)
4275 + (zlLib->prev)->next = zlLib->next;
4277 + if (zlLib->next)
4278 + (zlLib->next)->prev = zlLib->prev;
4280 + /* Free DOF resources */
4281 + dofClose(zlLib);
4282 + if (zlLib->fileName)
4283 + MEM_Free(zlLib->fileName);
4285 + /* remove symbols from symbol table */
4286 + if (zlLib->symTab)
4287 + GH_delete(zlLib->symTab);
4289 + /* remove the library object itself */
4290 + MEM_FreeObject(zlLib);
4291 + zlLib = NULL;
4296 + * ======== DBLL_create ========
4297 + */
4298 +DSP_STATUS DBLL_create(struct DBLL_TarObj **pTarget, struct DBLL_Attrs *pAttrs)
4300 + struct DBLL_TarObj *pzlTarget;
4301 + DSP_STATUS status = DSP_SOK;
4303 + DBC_Require(cRefs > 0);
4304 + DBC_Require(pAttrs != NULL);
4305 + DBC_Require(pTarget != NULL);
4307 + GT_2trace(DBLL_debugMask, GT_ENTER,
4308 + "DBLL_create: pTarget: 0x%x pAttrs: "
4309 + "0x%x\n", pTarget, pAttrs);
4310 + /* Allocate DBL target object */
4311 + MEM_AllocObject(pzlTarget, struct DBLL_TarObj, DBLL_TARGSIGNATURE);
4312 + if (pTarget != NULL) {
4313 + if (pzlTarget == NULL) {
4314 + GT_0trace(DBLL_debugMask, GT_6CLASS,
4315 + "DBLL_create: Memory allocation"
4316 + " failed\n");
4317 + *pTarget = NULL;
4318 + status = DSP_EMEMORY;
4319 + } else {
4320 + pzlTarget->attrs = *pAttrs;
4321 + *pTarget = (struct DBLL_TarObj *)pzlTarget;
4323 + DBC_Ensure((DSP_SUCCEEDED(status) &&
4324 + MEM_IsValidHandle(((struct DBLL_TarObj *)(*pTarget)),
4325 + DBLL_TARGSIGNATURE)) || (DSP_FAILED(status) &&
4326 + *pTarget == NULL));
4329 + return status;
4333 + * ======== DBLL_delete ========
4334 + */
4335 +void DBLL_delete(struct DBLL_TarObj *target)
4337 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4339 + DBC_Require(cRefs > 0);
4340 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4342 + GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_delete: target: 0x%x\n",
4343 + target);
4345 + if (zlTarget != NULL)
4346 + MEM_FreeObject(zlTarget);
4351 + * ======== DBLL_exit ========
4352 + * Discontinue usage of DBL module.
4353 + */
4354 +void DBLL_exit(void)
4356 + DBC_Require(cRefs > 0);
4358 + cRefs--;
4360 + GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_exit() ref count: 0x%x\n",
4361 + cRefs);
4363 + if (cRefs == 0) {
4364 + MEM_Exit();
4365 + CSL_Exit();
4366 + GH_exit();
4367 +#if GT_TRACE
4368 + DBLL_debugMask.flags = 0;
4369 +#endif
4372 + DBC_Ensure(cRefs >= 0);
4376 + * ======== DBLL_getAddr ========
4377 + * Get address of name in the specified library.
4378 + */
4379 +bool DBLL_getAddr(struct DBLL_LibraryObj *zlLib, char *name,
4380 + struct DBLL_Symbol **ppSym)
4382 + struct Symbol *sym;
4383 + bool status = false;
4385 + DBC_Require(cRefs > 0);
4386 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4387 + DBC_Require(name != NULL);
4388 + DBC_Require(ppSym != NULL);
4389 + DBC_Require(zlLib->symTab != NULL);
4391 + GT_3trace(DBLL_debugMask, GT_ENTER,
4392 + "DBLL_getAddr: lib: 0x%x name: %s pAddr:"
4393 + " 0x%x\n", zlLib, name, ppSym);
4394 + sym = (struct Symbol *)GH_find(zlLib->symTab, name);
4395 + if (sym != NULL) {
4396 + *ppSym = &sym->value;
4397 + status = true;
4399 + return status;
4403 + * ======== DBLL_getAttrs ========
4404 + * Retrieve the attributes of the target.
4405 + */
4406 +void DBLL_getAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs)
4408 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4410 + DBC_Require(cRefs > 0);
4411 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4412 + DBC_Require(pAttrs != NULL);
4414 + if ((pAttrs != NULL) && (zlTarget != NULL))
4415 + *pAttrs = zlTarget->attrs;
4420 + * ======== DBLL_getCAddr ========
4421 + * Get address of a "C" name in the specified library.
4422 + */
4423 +bool DBLL_getCAddr(struct DBLL_LibraryObj *zlLib, char *name,
4424 + struct DBLL_Symbol **ppSym)
4426 + struct Symbol *sym;
4427 + char cname[MAXEXPR + 1];
4428 + bool status = false;
4430 + DBC_Require(cRefs > 0);
4431 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4432 + DBC_Require(ppSym != NULL);
4433 + DBC_Require(zlLib->symTab != NULL);
4434 + DBC_Require(name != NULL);
4436 + cname[0] = '_';
4438 + CSL_Strcpyn(cname + 1, name, sizeof(cname) - 2);
4439 + cname[MAXEXPR] = '\0'; /* insure '\0' string termination */
4441 + /* Check for C name, if not found */
4442 + sym = (struct Symbol *)GH_find(zlLib->symTab, cname);
4444 + if (sym != NULL) {
4445 + *ppSym = &sym->value;
4446 + status = true;
4449 + return status;
4453 + * ======== DBLL_getSect ========
4454 + * Get the base address and size (in bytes) of a COFF section.
4455 + */
4456 +DSP_STATUS DBLL_getSect(struct DBLL_LibraryObj *lib, char *name, u32 *pAddr,
4457 + u32 *pSize)
4459 + u32 uByteSize;
4460 + bool fOpenedDoff = false;
4461 + const struct LDR_SECTION_INFO *sect = NULL;
4462 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4463 + DSP_STATUS status = DSP_SOK;
4465 + DBC_Require(cRefs > 0);
4466 + DBC_Require(name != NULL);
4467 + DBC_Require(pAddr != NULL);
4468 + DBC_Require(pSize != NULL);
4469 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4471 + GT_4trace(DBLL_debugMask, GT_ENTER,
4472 + "DBLL_getSect: lib: 0x%x name: %s pAddr:"
4473 + " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize);
4474 + /* If DOFF file is not open, we open it. */
4475 + if (zlLib != NULL) {
4476 + if (zlLib->fp == NULL) {
4477 + status = dofOpen(zlLib);
4478 + if (DSP_SUCCEEDED(status))
4479 + fOpenedDoff = true;
4481 + } else {
4482 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp,
4483 + zlLib->ulPos, SEEK_SET);
4486 + if (DSP_SUCCEEDED(status)) {
4487 + uByteSize = 1;
4488 + if (DLOAD_GetSectionInfo(zlLib->desc, name, &sect)) {
4489 + *pAddr = sect->load_addr;
4490 + *pSize = sect->size * uByteSize;
4491 + /* Make sure size is even for good swap */
4492 + if (*pSize % 2)
4493 + (*pSize)++;
4495 + /* Align size */
4496 + *pSize = DOFF_ALIGN(*pSize);
4497 + } else {
4498 + status = DSP_ENOSECT;
4501 + if (fOpenedDoff) {
4502 + dofClose(zlLib);
4503 + fOpenedDoff = false;
4506 + return status;
4510 + * ======== DBLL_init ========
4511 + */
4512 +bool DBLL_init(void)
4514 + bool retVal = true;
4516 + DBC_Require(cRefs >= 0);
4518 + if (cRefs == 0) {
4519 + DBC_Assert(!DBLL_debugMask.flags);
4520 + GT_create(&DBLL_debugMask, "DL"); /* "DL" for dbDL */
4521 + GH_init();
4522 + CSL_Init();
4523 + retVal = MEM_Init();
4524 + if (!retVal)
4525 + MEM_Exit();
4529 + if (retVal)
4530 + cRefs++;
4533 + GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_init(), ref count: 0x%x\n",
4534 + cRefs);
4536 + DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0)));
4538 + return retVal;
4542 + * ======== DBLL_load ========
4543 + */
4544 +DSP_STATUS DBLL_load(struct DBLL_LibraryObj *lib, DBLL_Flags flags,
4545 + struct DBLL_Attrs *attrs, u32 *pEntry)
4547 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4548 + struct DBLL_TarObj *dbzl;
4549 + bool gotSymbols = true;
4550 + s32 err;
4551 + DSP_STATUS status = DSP_SOK;
4552 + bool fOpenedDoff = false;
4553 + DBC_Require(cRefs > 0);
4554 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4555 + DBC_Require(pEntry != NULL);
4556 + DBC_Require(attrs != NULL);
4558 + GT_4trace(DBLL_debugMask, GT_ENTER,
4559 + "DBLL_load: lib: 0x%x flags: 0x%x pEntry:"
4560 + " 0x%x\n", lib, flags, attrs, pEntry);
4561 + /*
4562 + * Load if not already loaded.
4563 + */
4564 + if (zlLib->loadRef == 0 || !(flags & DBLL_DYNAMIC)) {
4565 + dbzl = zlLib->pTarget;
4566 + dbzl->attrs = *attrs;
4567 + /* Create a hash table for symbols if not already created */
4568 + if (zlLib->symTab == NULL) {
4569 + gotSymbols = false;
4570 + zlLib->symTab = GH_create(MAXBUCKETS,
4571 + sizeof(struct Symbol),
4572 + nameHash,
4573 + nameMatch, symDelete);
4574 + if (zlLib->symTab == NULL)
4575 + status = DSP_EMEMORY;
4578 + /*
4579 + * Set up objects needed by the dynamic loader
4580 + */
4581 + /* Stream */
4582 + zlLib->stream.dlStream.read_buffer = readBuffer;
4583 + zlLib->stream.dlStream.set_file_posn = setFilePosn;
4584 + zlLib->stream.lib = zlLib;
4585 + /* Symbol */
4586 + zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol;
4587 + if (gotSymbols) {
4588 + zlLib->symbol.dlSymbol.Add_To_Symbol_Table =
4589 + findInSymbolTable;
4590 + } else {
4591 + zlLib->symbol.dlSymbol.Add_To_Symbol_Table =
4592 + addToSymbolTable;
4594 + zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable;
4595 + zlLib->symbol.dlSymbol.Allocate = allocate;
4596 + zlLib->symbol.dlSymbol.Deallocate = deallocate;
4597 + zlLib->symbol.dlSymbol.Error_Report = errorReport;
4598 + zlLib->symbol.lib = zlLib;
4599 + /* Allocate */
4600 + zlLib->allocate.dlAlloc.Allocate = rmmAlloc;
4601 + zlLib->allocate.dlAlloc.Deallocate = rmmDealloc;
4602 + zlLib->allocate.lib = zlLib;
4603 + /* Init */
4604 + zlLib->init.dlInit.connect = connect;
4605 + zlLib->init.dlInit.readmem = readMem;
4606 + zlLib->init.dlInit.writemem = writeMem;
4607 + zlLib->init.dlInit.fillmem = fillMem;
4608 + zlLib->init.dlInit.execute = execute;
4609 + zlLib->init.dlInit.release = release;
4610 + zlLib->init.lib = zlLib;
4611 + /* If COFF file is not open, we open it. */
4612 + if (zlLib->fp == NULL) {
4613 + status = dofOpen(zlLib);
4614 + if (DSP_SUCCEEDED(status))
4615 + fOpenedDoff = true;
4618 + if (DSP_SUCCEEDED(status)) {
4619 + zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell))
4620 + (zlLib->fp);
4621 + /* Reset file cursor */
4622 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0,
4623 + SEEK_SET);
4624 + bSymbolsReloaded = true;
4625 + /* The 5th argument, DLOAD_INITBSS, tells the DLL
4626 + * module to zero-init all BSS sections. In general,
4627 + * this is not necessary and also increases load time.
4628 + * We may want to make this configurable by the user */
4629 + err = Dynamic_Load_Module(&zlLib->stream.dlStream,
4630 + &zlLib->symbol.dlSymbol, &zlLib->allocate.dlAlloc,
4631 + &zlLib->init.dlInit, DLOAD_INITBSS,
4632 + &zlLib->mHandle);
4634 + if (err != 0) {
4635 + GT_1trace(DBLL_debugMask, GT_6CLASS,
4636 + "DBLL_load: "
4637 + "Dynamic_Load_Module failed: 0x%lx\n",
4638 + err);
4639 + status = DSP_EDYNLOAD;
4640 + } else if (bRedefinedSymbol) {
4641 + zlLib->loadRef++;
4642 + DBLL_unload(zlLib, (struct DBLL_Attrs *) attrs);
4643 + bRedefinedSymbol = false;
4644 + status = DSP_EDYNLOAD;
4645 + } else {
4646 + *pEntry = zlLib->entry;
4650 + if (DSP_SUCCEEDED(status))
4651 + zlLib->loadRef++;
4653 + /* Clean up DOFF resources */
4654 + if (fOpenedDoff)
4655 + dofClose(zlLib);
4657 + DBC_Ensure(DSP_FAILED(status) || zlLib->loadRef > 0);
4658 + return status;
4662 + * ======== DBLL_loadSect ========
4663 + * Not supported for COFF.
4664 + */
4665 +DSP_STATUS DBLL_loadSect(struct DBLL_LibraryObj *zlLib, char *sectName,
4666 + struct DBLL_Attrs *attrs)
4668 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4670 + return DSP_ENOTIMPL;
4674 + * ======== DBLL_open ========
4675 + */
4676 +DSP_STATUS DBLL_open(struct DBLL_TarObj *target, char *file, DBLL_Flags flags,
4677 + struct DBLL_LibraryObj **pLib)
4679 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4680 + struct DBLL_LibraryObj *zlLib = NULL;
4681 + s32 err;
4682 + DSP_STATUS status = DSP_SOK;
4684 + DBC_Require(cRefs > 0);
4685 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4686 + DBC_Require(zlTarget->attrs.fopen != NULL);
4687 + DBC_Require(file != NULL);
4688 + DBC_Require(pLib != NULL);
4690 + GT_3trace(DBLL_debugMask, GT_ENTER,
4691 + "DBLL_open: target: 0x%x file: %s pLib:"
4692 + " 0x%x\n", target, file, pLib);
4693 + zlLib = zlTarget->head;
4694 + while (zlLib != NULL) {
4695 + if (CSL_Strcmp(zlLib->fileName, file) == 0) {
4696 + /* Library is already opened */
4697 + zlLib->openRef++;
4698 + break;
4700 + zlLib = zlLib->next;
4702 + if (zlLib == NULL) {
4703 + /* Allocate DBL library object */
4704 + MEM_AllocObject(zlLib, struct DBLL_LibraryObj,
4705 + DBLL_LIBSIGNATURE);
4706 + if (zlLib == NULL) {
4707 + GT_0trace(DBLL_debugMask, GT_6CLASS,
4708 + "DBLL_open: Memory allocation failed\n");
4709 + status = DSP_EMEMORY;
4710 + } else {
4711 + zlLib->ulPos = 0;
4712 + /* Increment ref count to allow close on failure
4713 + * later on */
4714 + zlLib->openRef++;
4715 + zlLib->pTarget = zlTarget;
4716 + /* Keep a copy of the file name */
4717 + zlLib->fileName = MEM_Calloc(CSL_Strlen(file) + 1,
4718 + MEM_PAGED);
4719 + if (zlLib->fileName == NULL) {
4720 + GT_0trace(DBLL_debugMask, GT_6CLASS,
4721 + "DBLL_open: Memory "
4722 + "allocation failed\n");
4723 + status = DSP_EMEMORY;
4724 + } else {
4725 + CSL_Strcpyn(zlLib->fileName, file,
4726 + CSL_Strlen(file) + 1);
4728 + zlLib->symTab = NULL;
4731 + /*
4732 + * Set up objects needed by the dynamic loader
4733 + */
4734 + if (DSP_FAILED(status))
4735 + goto func_cont;
4737 + /* Stream */
4738 + zlLib->stream.dlStream.read_buffer = readBuffer;
4739 + zlLib->stream.dlStream.set_file_posn = setFilePosn;
4740 + zlLib->stream.lib = zlLib;
4741 + /* Symbol */
4742 + zlLib->symbol.dlSymbol.Add_To_Symbol_Table = addToSymbolTable;
4743 + zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol;
4744 + zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable;
4745 + zlLib->symbol.dlSymbol.Allocate = allocate;
4746 + zlLib->symbol.dlSymbol.Deallocate = deallocate;
4747 + zlLib->symbol.dlSymbol.Error_Report = errorReport;
4748 + zlLib->symbol.lib = zlLib;
4749 + /* Allocate */
4750 + zlLib->allocate.dlAlloc.Allocate = rmmAlloc;
4751 + zlLib->allocate.dlAlloc.Deallocate = rmmDealloc;
4752 + zlLib->allocate.lib = zlLib;
4753 + /* Init */
4754 + zlLib->init.dlInit.connect = connect;
4755 + zlLib->init.dlInit.readmem = readMem;
4756 + zlLib->init.dlInit.writemem = writeMem;
4757 + zlLib->init.dlInit.fillmem = fillMem;
4758 + zlLib->init.dlInit.execute = execute;
4759 + zlLib->init.dlInit.release = release;
4760 + zlLib->init.lib = zlLib;
4761 + if (DSP_SUCCEEDED(status) && zlLib->fp == NULL)
4762 + status = dofOpen(zlLib);
4764 + zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell)) (zlLib->fp);
4765 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long) 0, SEEK_SET);
4766 + /* Create a hash table for symbols if flag is set */
4767 + if (zlLib->symTab != NULL || !(flags & DBLL_SYMB))
4768 + goto func_cont;
4770 + zlLib->symTab = GH_create(MAXBUCKETS, sizeof(struct Symbol), nameHash,
4771 + nameMatch, symDelete);
4772 + if (zlLib->symTab == NULL) {
4773 + status = DSP_EMEMORY;
4774 + } else {
4775 + /* Do a fake load to get symbols - set write function to NoOp */
4776 + zlLib->init.dlInit.writemem = NoOp;
4777 + err = Dynamic_Open_Module(&zlLib->stream.dlStream,
4778 + &zlLib->symbol.dlSymbol,
4779 + &zlLib->allocate.dlAlloc,
4780 + &zlLib->init.dlInit, 0,
4781 + &zlLib->mHandle);
4782 + if (err != 0) {
4783 + GT_1trace(DBLL_debugMask, GT_6CLASS, "DBLL_open: "
4784 + "Dynamic_Load_Module failed: 0x%lx\n", err);
4785 + status = DSP_EDYNLOAD;
4786 + } else {
4787 + /* Now that we have the symbol table, we can unload */
4788 + err = Dynamic_Unload_Module(zlLib->mHandle,
4789 + &zlLib->symbol.dlSymbol,
4790 + &zlLib->allocate.dlAlloc,
4791 + &zlLib->init.dlInit);
4792 + if (err != 0) {
4793 + GT_1trace(DBLL_debugMask, GT_6CLASS,
4794 + "DBLL_open: "
4795 + "Dynamic_Unload_Module failed: 0x%lx\n",
4796 + err);
4797 + status = DSP_EDYNLOAD;
4799 + zlLib->mHandle = NULL;
4802 +func_cont:
4803 + if (DSP_SUCCEEDED(status)) {
4804 + if (zlLib->openRef == 1) {
4805 + /* First time opened - insert in list */
4806 + if (zlTarget->head)
4807 + (zlTarget->head)->prev = zlLib;
4809 + zlLib->prev = NULL;
4810 + zlLib->next = zlTarget->head;
4811 + zlTarget->head = zlLib;
4813 + *pLib = (struct DBLL_LibraryObj *)zlLib;
4814 + } else {
4815 + *pLib = NULL;
4816 + if (zlLib != NULL)
4817 + DBLL_close((struct DBLL_LibraryObj *)zlLib);
4820 + DBC_Ensure((DSP_SUCCEEDED(status) && (zlLib->openRef > 0) &&
4821 + MEM_IsValidHandle(((struct DBLL_LibraryObj *)(*pLib)),
4822 + DBLL_LIBSIGNATURE)) || (DSP_FAILED(status) && *pLib == NULL));
4823 + return status;
4827 + * ======== DBLL_readSect ========
4828 + * Get the content of a COFF section.
4829 + */
4830 +DSP_STATUS DBLL_readSect(struct DBLL_LibraryObj *lib, char *name,
4831 + char *pContent, u32 size)
4833 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4834 + bool fOpenedDoff = false;
4835 + u32 uByteSize; /* size of bytes */
4836 + u32 ulSectSize; /* size of section */
4837 + const struct LDR_SECTION_INFO *sect = NULL;
4838 + DSP_STATUS status = DSP_SOK;
4840 + DBC_Require(cRefs > 0);
4841 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4842 + DBC_Require(name != NULL);
4843 + DBC_Require(pContent != NULL);
4844 + DBC_Require(size != 0);
4846 + GT_4trace(DBLL_debugMask, GT_ENTER,
4847 + "DBLL_readSect: lib: 0x%x name: %s "
4848 + "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size);
4849 + /* If DOFF file is not open, we open it. */
4850 + if (zlLib != NULL) {
4851 + if (zlLib->fp == NULL) {
4852 + status = dofOpen(zlLib);
4853 + if (DSP_SUCCEEDED(status))
4854 + fOpenedDoff = true;
4856 + } else {
4857 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp,
4858 + zlLib->ulPos, SEEK_SET);
4862 + if (DSP_FAILED(status))
4863 + goto func_cont;
4865 + uByteSize = 1;
4866 + if (!DLOAD_GetSectionInfo(zlLib->desc, name, &sect)) {
4867 + status = DSP_ENOSECT;
4868 + goto func_cont;
4870 + /*
4871 + * Ensure the supplied buffer size is sufficient to store
4872 + * the section content to be read.
4873 + */
4874 + ulSectSize = sect->size * uByteSize;
4875 + /* Make sure size is even for good swap */
4876 + if (ulSectSize % 2)
4877 + ulSectSize++;
4879 + /* Align size */
4880 + ulSectSize = DOFF_ALIGN(ulSectSize);
4881 + if (ulSectSize > size) {
4882 + status = DSP_EFAIL;
4883 + } else {
4884 + if (!DLOAD_GetSection(zlLib->desc, sect, pContent))
4885 + status = DSP_EFREAD;
4888 +func_cont:
4889 + if (fOpenedDoff) {
4890 + dofClose(zlLib);
4891 + fOpenedDoff = false;
4893 + return status;
4897 + * ======== DBLL_setAttrs ========
4898 + * Set the attributes of the target.
4899 + */
4900 +void DBLL_setAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs)
4902 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4903 + DBC_Require(cRefs > 0);
4904 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4905 + DBC_Require(pAttrs != NULL);
4906 + GT_2trace(DBLL_debugMask, GT_ENTER,
4907 + "DBLL_setAttrs: target: 0x%x pAttrs: "
4908 + "0x%x\n", target, pAttrs);
4909 + if ((pAttrs != NULL) && (zlTarget != NULL))
4910 + zlTarget->attrs = *pAttrs;
4915 + * ======== DBLL_unload ========
4916 + */
4917 +void DBLL_unload(struct DBLL_LibraryObj *lib, struct DBLL_Attrs *attrs)
4919 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4920 + s32 err = 0;
4922 + DBC_Require(cRefs > 0);
4923 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4924 + DBC_Require(zlLib->loadRef > 0);
4925 + GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_unload: lib: 0x%x\n", lib);
4926 + zlLib->loadRef--;
4927 + /* Unload only if reference count is 0 */
4928 + if (zlLib->loadRef != 0)
4929 + goto func_end;
4931 + zlLib->pTarget->attrs = *attrs;
4932 + if (zlLib != NULL) {
4933 + if (zlLib->mHandle) {
4934 + err = Dynamic_Unload_Module(zlLib->mHandle,
4935 + &zlLib->symbol.dlSymbol,
4936 + &zlLib->allocate.dlAlloc, &zlLib->init.dlInit);
4937 + if (err != 0) {
4938 + GT_1trace(DBLL_debugMask, GT_5CLASS,
4939 + "Dynamic_Unload_Module "
4940 + "failed: 0x%x\n", err);
4943 + /* remove symbols from symbol table */
4944 + if (zlLib->symTab != NULL) {
4945 + GH_delete(zlLib->symTab);
4946 + zlLib->symTab = NULL;
4948 + /* delete DOFF desc since it holds *lots* of host OS
4949 + * resources */
4950 + dofClose(zlLib);
4952 +func_end:
4953 + DBC_Ensure(zlLib->loadRef >= 0);
4957 + * ======== DBLL_unloadSect ========
4958 + * Not supported for COFF.
4959 + */
4960 +DSP_STATUS DBLL_unloadSect(struct DBLL_LibraryObj *lib, char *sectName,
4961 + struct DBLL_Attrs *attrs)
4963 + DBC_Require(cRefs > 0);
4964 + DBC_Require(sectName != NULL);
4965 + GT_2trace(DBLL_debugMask, GT_ENTER,
4966 + "DBLL_unloadSect: lib: 0x%x sectName: "
4967 + "%s\n", lib, sectName);
4968 + return DSP_ENOTIMPL;
4972 + * ======== dofClose ========
4973 + */
4974 +static void dofClose(struct DBLL_LibraryObj *zlLib)
4976 + if (zlLib->desc) {
4977 + DLOAD_module_close(zlLib->desc);
4978 + zlLib->desc = NULL;
4980 + /* close file */
4981 + if (zlLib->fp) {
4982 + (zlLib->pTarget->attrs.fclose) (zlLib->fp);
4983 + zlLib->fp = NULL;
4988 + * ======== dofOpen ========
4989 + */
4990 +static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib)
4992 + void *open = *(zlLib->pTarget->attrs.fopen);
4993 + DSP_STATUS status = DSP_SOK;
4995 + /* First open the file for the dynamic loader, then open COF */
4996 + zlLib->fp = (void *)((Fxn)(open))(zlLib->fileName, "rb");
4998 + /* Open DOFF module */
4999 + if (zlLib->fp && zlLib->desc == NULL) {
5000 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0, SEEK_SET);
5001 + zlLib->desc = DLOAD_module_open(&zlLib->stream.dlStream,
5002 + &zlLib->symbol.dlSymbol);
5003 + if (zlLib->desc == NULL) {
5004 + (zlLib->pTarget->attrs.fclose)(zlLib->fp);
5005 + zlLib->fp = NULL;
5006 + status = DSP_EFOPEN;
5008 + } else {
5009 + status = DSP_EFOPEN;
5012 + return status;
5016 + * ======== nameHash ========
5017 + */
5018 +static u16 nameHash(void *key, u16 maxBucket)
5020 + u16 ret;
5021 + u16 hash;
5022 + char *name = (char *)key;
5024 + DBC_Require(name != NULL);
5026 + hash = 0;
5028 + while (*name) {
5029 + hash <<= 1;
5030 + hash ^= *name++;
5033 + ret = hash % maxBucket;
5035 + return ret;
5039 + * ======== nameMatch ========
5040 + */
5041 +static bool nameMatch(void *key, void *value)
5043 + DBC_Require(key != NULL);
5044 + DBC_Require(value != NULL);
5046 + if ((key != NULL) && (value != NULL)) {
5047 + if (CSL_Strcmp((char *)key, ((struct Symbol *)value)->
5048 + name) == 0) {
5049 + return true;
5052 + return false;
5056 + * ======== NoOp ========
5057 + */
5058 +static int NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr,
5059 + LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsize)
5061 + return 1;
5065 + * ======== symDelete ========
5066 + */
5067 +static void symDelete(void *value)
5069 + struct Symbol *sp = (struct Symbol *)value;
5071 + MEM_Free(sp->name);
5075 + * Dynamic Loader Functions
5076 + */
5078 +/* Dynamic_Loader_Stream */
5080 + * ======== readBuffer ========
5081 + */
5082 +static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer,
5083 + unsigned bufsize)
5085 + struct DBLLStream *pStream = (struct DBLLStream *)this;
5086 + struct DBLL_LibraryObj *lib;
5087 + int bytesRead = 0;
5089 + DBC_Require(this != NULL);
5090 + lib = pStream->lib;
5091 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5093 + if (lib != NULL) {
5094 + bytesRead = (*(lib->pTarget->attrs.fread))(buffer, 1, bufsize,
5095 + lib->fp);
5097 + return bytesRead;
5101 + * ======== setFilePosn ========
5102 + */
5103 +static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos)
5105 + struct DBLLStream *pStream = (struct DBLLStream *)this;
5106 + struct DBLL_LibraryObj *lib;
5107 + int status = 0; /* Success */
5109 + DBC_Require(this != NULL);
5110 + lib = pStream->lib;
5111 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5113 + if (lib != NULL) {
5114 + status = (*(lib->pTarget->attrs.fseek))(lib->fp, (long)pos,
5115 + SEEK_SET);
5118 + return status;
5121 +/* Dynamic_Loader_Sym */
5124 + * ======== findSymbol ========
5125 + */
5126 +static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this,
5127 + const char *name)
5129 + struct dynload_symbol *retSym;
5130 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5131 + struct DBLL_LibraryObj *lib;
5132 + struct DBLL_Symbol *pSym = NULL;
5133 + bool status = false; /* Symbol not found yet */
5135 + DBC_Require(this != NULL);
5136 + lib = pSymbol->lib;
5137 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5139 + if (lib != NULL) {
5140 + if (lib->pTarget->attrs.symLookup) {
5141 + /* Check current lib + base lib + dep lib +
5142 + * persistent lib */
5143 + status = (*(lib->pTarget->attrs.symLookup))
5144 + (lib->pTarget->attrs.symHandle,
5145 + lib->pTarget->attrs.symArg,
5146 + lib->pTarget->attrs.rmmHandle, name, &pSym);
5147 + } else {
5148 + /* Just check current lib for symbol */
5149 + status = DBLL_getAddr((struct DBLL_LibraryObj *)lib,
5150 + (char *)name, &pSym);
5151 + if (!status) {
5152 + status =
5153 + DBLL_getCAddr((struct DBLL_LibraryObj *)lib,
5154 + (char *)name, &pSym);
5159 + if (!status && bGblSearch) {
5160 + GT_1trace(DBLL_debugMask, GT_6CLASS,
5161 + "findSymbol: Symbol not found: %s\n", name);
5164 + DBC_Assert((status && (pSym != NULL)) || (!status && (pSym == NULL)));
5166 + retSym = (struct dynload_symbol *)pSym;
5167 + return retSym;
5171 + * ======== findInSymbolTable ========
5172 + */
5173 +static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this,
5174 + const char *name,
5175 + unsigned moduleid)
5177 + struct dynload_symbol *retSym;
5178 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5179 + struct DBLL_LibraryObj *lib;
5180 + struct Symbol *sym;
5182 + DBC_Require(this != NULL);
5183 + lib = pSymbol->lib;
5184 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5185 + DBC_Require(lib->symTab != NULL);
5187 + sym = (struct Symbol *)GH_find(lib->symTab, (char *) name);
5189 + retSym = (struct dynload_symbol *)&sym->value;
5190 + return retSym;
5194 + * ======== addToSymbolTable ========
5195 + */
5196 +static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this,
5197 + const char *name,
5198 + unsigned moduleId)
5200 + struct Symbol *symPtr = NULL;
5201 + struct Symbol symbol;
5202 + struct dynload_symbol *pSym = NULL;
5203 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5204 + struct DBLL_LibraryObj *lib;
5205 + struct dynload_symbol *retVal;
5207 + DBC_Require(this != NULL);
5208 + lib = pSymbol->lib;
5209 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5211 + /* Check to see if symbol is already defined in symbol table */
5212 + if (!(lib->pTarget->attrs.baseImage)) {
5213 + bGblSearch = false;
5214 + pSym = findSymbol(this, name);
5215 + bGblSearch = true;
5216 + if (pSym) {
5217 + bRedefinedSymbol = true;
5218 + GT_1trace(DBLL_debugMask, GT_6CLASS,
5219 + "Symbol already defined in "
5220 + "symbol table: %s\n", name);
5221 + return NULL;
5224 + /* Allocate string to copy symbol name */
5225 + symbol.name = (char *)MEM_Calloc(CSL_Strlen((char *const)name) + 1,
5226 + MEM_PAGED);
5227 + if (symbol.name == NULL)
5228 + return NULL;
5230 + if (symbol.name != NULL) {
5231 + /* Just copy name (value will be filled in by dynamic loader) */
5232 + CSL_Strcpyn(symbol.name, (char *const)name,
5233 + CSL_Strlen((char *const)name) + 1);
5235 + /* Add symbol to symbol table */
5236 + symPtr = (struct Symbol *)GH_insert(lib->symTab, (void *)name,
5237 + (void *)&symbol);
5238 + if (symPtr == NULL)
5239 + MEM_Free(symbol.name);
5242 + if (symPtr != NULL)
5243 + retVal = (struct dynload_symbol *)&symPtr->value;
5244 + else
5245 + retVal = NULL;
5247 + return retVal;
5251 + * ======== purgeSymbolTable ========
5252 + */
5253 +static void purgeSymbolTable(struct Dynamic_Loader_Sym *this, unsigned moduleId)
5255 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5256 + struct DBLL_LibraryObj *lib;
5258 + DBC_Require(this != NULL);
5259 + lib = pSymbol->lib;
5260 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5262 + /* May not need to do anything */
5266 + * ======== allocate ========
5267 + */
5268 +static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize)
5270 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5271 + struct DBLL_LibraryObj *lib;
5272 + void *buf;
5274 + DBC_Require(this != NULL);
5275 + lib = pSymbol->lib;
5276 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5278 + buf = MEM_Calloc(memsize, MEM_PAGED);
5280 + return buf;
5284 + * ======== deallocate ========
5285 + */
5286 +static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr)
5288 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5289 + struct DBLL_LibraryObj *lib;
5291 + DBC_Require(this != NULL);
5292 + lib = pSymbol->lib;
5293 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5295 + MEM_Free(memPtr);
5299 + * ======== errorReport ========
5300 + */
5301 +static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr,
5302 + va_list args)
5304 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5305 + struct DBLL_LibraryObj *lib;
5306 + char tempBuf[MAXEXPR];
5308 + DBC_Require(this != NULL);
5309 + lib = pSymbol->lib;
5310 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5311 + vsnprintf((char *)tempBuf, MAXEXPR, (char *)errstr, args);
5312 + GT_1trace(DBLL_debugMask, GT_5CLASS, "%s\n", tempBuf);
5315 +/* Dynamic_Loader_Allocate */
5318 + * ======== rmmAlloc ========
5319 + */
5320 +static int rmmAlloc(struct Dynamic_Loader_Allocate *this,
5321 + struct LDR_SECTION_INFO *info, unsigned align)
5323 + struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this;
5324 + struct DBLL_LibraryObj *lib;
5325 + DSP_STATUS status = DSP_SOK;
5326 + u32 memType;
5327 + struct RMM_Addr rmmAddr;
5328 + s32 retVal = TRUE;
5329 + unsigned stype = DLOAD_SECTION_TYPE(info->type);
5330 + char *pToken = NULL;
5331 + char *szSecLastToken = NULL;
5332 + char *szLastToken = NULL;
5333 + char *szSectName = NULL;
5334 + char *pszCur;
5335 + s32 tokenLen = 0;
5336 + s32 segId = -1;
5337 + s32 req = -1;
5338 + s32 count = 0;
5339 + u32 allocSize = 0;
5341 + DBC_Require(this != NULL);
5342 + lib = pAlloc->lib;
5343 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5345 + memType = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ?
5346 + DBLL_BSS : DBLL_DATA;
5348 + /* Attempt to extract the segment ID and requirement information from
5349 + the name of the section */
5350 + tokenLen = CSL_Strlen((char *)(info->name)) + 1;
5352 + szSectName = MEM_Calloc(tokenLen, MEM_PAGED);
5353 + szLastToken = MEM_Calloc(tokenLen, MEM_PAGED);
5354 + szSecLastToken = MEM_Calloc(tokenLen, MEM_PAGED);
5356 + if (szSectName == NULL || szSecLastToken == NULL ||
5357 + szLastToken == NULL) {
5358 + status = DSP_EMEMORY;
5359 + goto func_cont;
5361 + CSL_Strcpyn(szSectName, (char *)(info->name), tokenLen);
5362 + pToken = CSL_Strtokr(szSectName, ":", &pszCur);
5363 + while (pToken) {
5364 + CSL_Strcpyn(szSecLastToken, szLastToken,
5365 + CSL_Strlen(szLastToken) + 1);
5366 + CSL_Strcpyn(szLastToken, pToken, CSL_Strlen(pToken) + 1);
5367 + pToken = CSL_Strtokr(NULL, ":", &pszCur);
5368 + count++; /* optimizes processing*/
5370 + /* If pToken is 0 or 1, and szSecLastToken is DYN_DARAM or DYN_SARAM,
5371 + or DYN_EXTERNAL, then mem granularity information is present
5372 + within the section name - only process if there are at least three
5373 + tokens within the section name (just a minor optimization)*/
5374 + if (count >= 3)
5375 + req = CSL_Atoi(szLastToken);
5377 + if ((req == 0) || (req == 1)) {
5378 + if (CSL_Strcmp(szSecLastToken, "DYN_DARAM") == 0) {
5379 + segId = 0;
5380 + } else {
5381 + if (CSL_Strcmp(szSecLastToken, "DYN_SARAM") == 0) {
5382 + segId = 1;
5383 + } else {
5384 + if (CSL_Strcmp(szSecLastToken,
5385 + "DYN_EXTERNAL") == 0) {
5386 + segId = 2;
5390 + if (segId != -1) {
5391 + GT_2trace(DBLL_debugMask, GT_5CLASS,
5392 + "Extracted values for memory"
5393 + " granularity req [%d] segId [%d]\n",
5394 + req, segId);
5397 + MEM_Free(szSectName);
5398 + szSectName = NULL;
5399 + MEM_Free(szLastToken);
5400 + szLastToken = NULL;
5401 + MEM_Free(szSecLastToken);
5402 + szSecLastToken = NULL;
5403 +func_cont:
5404 + if (memType == DBLL_CODE)
5405 + allocSize = info->size + GEM_L1P_PREFETCH_SIZE;
5406 + else
5407 + allocSize = info->size;
5408 + /* TODO - ideally, we can pass the alignment requirement also
5409 + * from here */
5410 + if (lib != NULL) {
5411 + status = (lib->pTarget->attrs.alloc)(lib->pTarget->
5412 + attrs.rmmHandle, memType, allocSize, align,
5413 + (u32 *)&rmmAddr, segId, req, FALSE);
5415 + if (DSP_FAILED(status)) {
5416 + retVal = false;
5417 + } else {
5418 + /* RMM gives word address. Need to convert to byte address */
5419 + info->load_addr = rmmAddr.addr * DSPWORDSIZE;
5420 + info->run_addr = info->load_addr;
5421 + info->context = (u32)rmmAddr.segid;
5422 + GT_3trace(DBLL_debugMask, GT_5CLASS,
5423 + "Remote alloc: %s base = 0x%lx len"
5424 + "= 0x%lx\n", info->name, info->load_addr / DSPWORDSIZE,
5425 + info->size / DSPWORDSIZE);
5427 + return retVal;
5431 + * ======== rmmDealloc ========
5432 + */
5433 +static void rmmDealloc(struct Dynamic_Loader_Allocate *this,
5434 + struct LDR_SECTION_INFO *info)
5436 + struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this;
5437 + struct DBLL_LibraryObj *lib;
5438 + u32 segid;
5439 + DSP_STATUS status = DSP_SOK;
5440 + unsigned stype = DLOAD_SECTION_TYPE(info->type);
5441 + u32 memType;
5442 + u32 freeSize = 0;
5444 + memType = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ?
5445 + DBLL_BSS : DBLL_DATA;
5446 + DBC_Require(this != NULL);
5447 + lib = pAlloc->lib;
5448 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5449 + /* segid was set by alloc function */
5450 + segid = (u32)info->context;
5451 + if (memType == DBLL_CODE)
5452 + freeSize = info->size + GEM_L1P_PREFETCH_SIZE;
5453 + else
5454 + freeSize = info->size;
5455 + if (lib != NULL) {
5456 + status = (lib->pTarget->attrs.free)(lib->pTarget->
5457 + attrs.symHandle, segid, info->load_addr / DSPWORDSIZE,
5458 + freeSize, false);
5460 + if (DSP_SUCCEEDED(status)) {
5461 + GT_2trace(DBLL_debugMask, GT_5CLASS,
5462 + "Remote dealloc: base = 0x%lx len ="
5463 + "0x%lx\n", info->load_addr / DSPWORDSIZE,
5464 + freeSize / DSPWORDSIZE);
5468 +/* Dynamic_Loader_Initialize */
5470 + * ======== connect ========
5471 + */
5472 +static int connect(struct Dynamic_Loader_Initialize *this)
5474 + return true;
5478 + * ======== readMem ========
5479 + * This function does not need to be implemented.
5480 + */
5481 +static int readMem(struct Dynamic_Loader_Initialize *this, void *buf,
5482 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
5483 + unsigned nbytes)
5485 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5486 + struct DBLL_LibraryObj *lib;
5487 + int bytesRead = 0;
5489 + DBC_Require(this != NULL);
5490 + lib = pInit->lib;
5491 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5492 + /* Need WMD_BRD_Read function */
5493 + return bytesRead;
5497 + * ======== writeMem ========
5498 + */
5499 +static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf,
5500 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
5501 + unsigned nBytes)
5503 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5504 + struct DBLL_LibraryObj *lib;
5505 + struct DBLL_SectInfo sectInfo;
5506 + u32 memType;
5507 + bool retVal = true;
5509 + DBC_Require(this != NULL);
5510 + lib = pInit->lib;
5511 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5513 + memType = (DLOAD_SECTION_TYPE(info->type) == DLOAD_TEXT) ? DBLL_CODE :
5514 + DBLL_DATA;
5515 + if (lib != NULL) {
5516 + retVal = (*lib->pTarget->attrs.write)(lib->pTarget->
5517 + attrs.wHandle, addr, buf, nBytes, memType);
5519 + if (lib->pTarget->attrs.logWrite) {
5520 + sectInfo.name = info->name;
5521 + sectInfo.runAddr = info->run_addr;
5522 + sectInfo.loadAddr = info->load_addr;
5523 + sectInfo.size = info->size;
5524 + sectInfo.type = memType;
5525 + /* Pass the information about what we've written to
5526 + * another module */
5527 + (*lib->pTarget->attrs.logWrite)(lib->pTarget->
5528 + attrs.logWriteHandle, &sectInfo, addr, nBytes);
5530 + return retVal;
5534 + * ======== fillMem ========
5535 + * Fill nBytes of memory at a given address with a given value by
5536 + * writing from a buffer containing the given value. Write in
5537 + * sets of MAXEXPR (128) bytes to avoid large stack buffer issues.
5538 + */
5539 +static int fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr,
5540 + struct LDR_SECTION_INFO *info, unsigned nBytes,
5541 + unsigned val)
5543 + bool retVal = true;
5544 + char *pBuf;
5545 + struct DBLL_LibraryObj *lib;
5546 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5548 + DBC_Require(this != NULL);
5549 + lib = pInit->lib;
5550 + pBuf = NULL;
5551 + /* Pass the NULL pointer to writeMem to get the start address of Shared
5552 + memory. This is a trick to just get the start address, there is no
5553 + writing taking place with this Writemem
5554 + */
5555 + if ((lib->pTarget->attrs.write) != (DBLL_WriteFxn)NoOp)
5556 + writeMem(this, &pBuf, addr, info, 0);
5557 + if (pBuf)
5558 + memset(pBuf, val, nBytes);
5560 + return retVal;
5564 + * ======== execute ========
5565 + */
5566 +static int execute(struct Dynamic_Loader_Initialize *this, LDR_ADDR start)
5568 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5569 + struct DBLL_LibraryObj *lib;
5570 + bool retVal = true;
5572 + DBC_Require(this != NULL);
5573 + lib = pInit->lib;
5574 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5575 + /* Save entry point */
5576 + if (lib != NULL)
5577 + lib->entry = (u32)start;
5579 + return retVal;
5583 + * ======== release ========
5584 + */
5585 +static void release(struct Dynamic_Loader_Initialize *this)
5589 diff --git a/drivers/dsp/bridge/pmgr/dev.c b/drivers/dsp/bridge/pmgr/dev.c
5590 new file mode 100644
5591 index 0000000..7d80947
5592 --- /dev/null
5593 +++ b/drivers/dsp/bridge/pmgr/dev.c
5594 @@ -0,0 +1,1475 @@
5596 + * linux/drivers/dsp/bridge/pmgr/dev.c
5598 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5600 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
5602 + * This package is free software; you can redistribute it and/or modify
5603 + * it under the terms of the GNU General Public License version 2 as
5604 + * published by the Free Software Foundation.
5606 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
5607 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
5608 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
5609 + */
5613 + * ======== dev.c ========
5614 + * Description:
5615 + * Implementation of 'Bridge Mini-driver device operations.
5617 + * Public Functions:
5618 + * DEV_BrdWriteFxn
5619 + * DEV_CreateDevice
5620 + * DEV_Create2
5621 + * DEV_Destroy2
5622 + * DEV_DestroyDevice
5623 + * DEV_GetChnlMgr
5624 + * DEV_GetCmmMgr
5625 + * DEV_GetCodMgr
5626 + * DEV_GetDehMgr
5627 + * DEV_GetDevNode
5628 + * DEV_GetDSPWordSize
5629 + * DEV_GetFirst
5630 + * DEV_GetIntfFxns
5631 + * DEV_GetIOMgr
5632 + * DEV_GetNext
5633 + * DEV_GetNodeManager
5634 + * DEV_GetSymbol
5635 + * DEV_GetWMDContext
5636 + * DEV_Exit
5637 + * DEV_Init
5638 + * DEV_InsertProcObject
5639 + * DEV_IsLocked
5640 + * DEV_NotifyClient
5641 + * DEV_RegisterNotify
5642 + * DEV_ReleaseCodMgr
5643 + * DEV_RemoveDevice
5644 + * DEV_RemoveProcObject
5645 + * DEV_SetChnlMgr
5646 + * DEV_SetMsgMgr
5647 + * DEV_SetLockOwner
5648 + * DEV_StartDevice
5650 + * Private Functions:
5651 + * FxnNotImplemented
5652 + * InitCodMgr
5653 + * InsertDevObject
5654 + * IsValidHandle
5655 + * RemoveDevObject
5656 + * StoreInterfaceFxns
5658 + *! Revision History:
5659 + *! ================
5660 + *! 03-Jan-2005 hn Support for IVA DEH
5661 + *! 08-Mar-2004 sb Added the Dynamic Memory Mapping feature
5662 + *! 09-Feb-2004 vp Updated to support IVA.
5663 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
5664 + *! 29-Nov-2001 jeh Check for DSP_ENOTIMPL status of DEH create function.
5665 + *! 05-Nov-2001 kc Added support for DEH module.
5666 + *! 05-Aug-2001 ag Shared memory registration moved to WMD_IO_OnLoaded().
5667 + *! 11-Jul-2001 jeh Moved MGR_Create() from DSP_Init() to DEV_StartDevice().
5668 + *! 11-Apr-2001 rr: Removed CMM_RegisterGPPSMSeg.
5669 + *! 02-Apr-2001 rr: CHNL_Create failure is printed out.
5670 + *! 15-Jan-2001 jeh Removed call to IO_OnLoaded() from DEV_Create2().
5671 + *! 13-Feb-2001 kc: DSP/BIOS Bridge name update.
5672 + *! 15-Dec-2000 rr: Dev_Create2 returns error if NODE_CreateMgr fails.
5673 + *! 05-Dec-2000 jeh Moved IO_OnLoaded() to PROC_Load. Added DEV_SetMsgMgr.
5674 + *! 05-Dev-2000 ag SM Heap for messaging registered via CMM_RegisterGPPSMSeg().
5675 + *! SM heap base and size currently taken from registry.
5676 + *! 29-Nov-2000 rr: Incorporated code review changes.
5677 + *! 17-Nov-2000 jeh Added calls to get IO manager (IO_Create), IO_OnLoaded().
5678 + *! 06-Oct-2000 rr: DEV_Destroy2 and DEV_Create2 added.
5679 + *! 02-Oct-2000 rr: DEV_GetNodeManager added.
5680 + *! 11-Aug-2000 ag: Added DEV_GetCmmMgr(), CMM_Init() & CMM_Exit().
5681 + *! Removed <std.h> & <stdwin.h>, added <dbtype.h>
5682 + *! 10-Aug-2000 rr: DEV_InsertProcObject/RemoveProcObject added.
5683 + *! DEV_Cleanup calls PROC_Detach if it is a matching process.
5684 + *! 27-Jul-2000 rr: DEV is in new directoy DEV and produces devlib.lib
5685 + *! 17-Jul-2000 rr: DRV Object holds the list of Dev Objects. DEV gets
5686 + *! the List and Next devices through DRV.
5687 + *! DEV object has a back pointer to DRV Object.
5688 + *! 06-Jun-2000 jeh Added DEV_GetSymbol().
5689 + *! 09-May-2000 rr: dwMemBase has index for multiple windows need.
5690 + *! 28-Feb-2000 rr: New GT Usage implemented.
5691 + *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from
5692 + *! SERVICES)
5693 + *! 31-Jan-2000 rr: Comments changed after code review.
5694 + *! 21-Jan-2000 rr: windows.h, tchar.h, HMODULE removed. FreeLibrary replaced
5695 + *! with LDR_FreeModule
5696 + *! 17-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject.
5697 + *! StoreInterfaceFxns stores the new fxn WMD_BRD_SETSTATE.
5698 + *! 20-Nov-1999 ag: Actual uSMLength = total - monitor offset.
5699 + *! 12-Nov-1999 rr: bIRQ and IRQAttrib taken from the struct CFG_HOSTRES.
5700 + *! dMemBase is added with offset for monitor taken from
5701 + *! registry.
5702 + *! 31-Oct-1999 ag: Added CHNL support.
5703 + *! 10-Sep-1999 rr: GT Enabled. DEV_Create will Load the Mini Driver and will
5704 + *! find its fxn table. Right now lot of things are hardcoded
5705 + *! as the REG is not ready.
5706 + *! 10-Jun-1996 rr: Created from WSX
5707 + */
5709 +/* ----------------------------------- Host OS */
5710 +#include <host_os.h>
5712 +/* ----------------------------------- DSP/BIOS Bridge */
5713 +#include <std.h>
5714 +#include <dbdefs.h>
5715 +#include <errbase.h>
5717 +/* ----------------------------------- Trace & Debug */
5718 +#include <dbc.h>
5719 +#include <dbg.h>
5720 +#include <gt.h>
5722 +/* ----------------------------------- OS Adaptation Layer */
5723 +#include <cfg.h>
5724 +#include <ldr.h>
5725 +#include <list.h>
5726 +#include <mem.h>
5727 +#include <util.h>
5729 +/* ----------------------------------- Platform Manager */
5730 +#include <cod.h>
5731 +#include <drv.h>
5732 +#include <proc.h>
5733 +#include <dmm.h>
5735 +/* ----------------------------------- Resource Manager */
5736 +#include <mgr.h>
5737 +#include <node.h>
5739 +/* ----------------------------------- Others */
5740 +#include <dbreg.h>
5741 +#include <wcd.h> /* WCD version info. */
5743 +#include <chnl.h>
5744 +#include <io.h>
5745 +#include <msg.h>
5746 +#include <cmm.h>
5748 +/* ----------------------------------- This */
5749 +#include <dev.h>
5751 +/* ----------------------------------- Defines, Data Structures, Typedefs */
5753 +#define SIGNATURE 0x5f564544 /* "DEV_" (in reverse) */
5754 +#define MAKEVERSION(major, minor) (major * 10 + minor)
5755 +#define WCDVERSION MAKEVERSION(WCD_MAJOR_VERSION, WCD_MINOR_VERSION)
5757 +/* The WMD device object: */
5758 +struct DEV_OBJECT {
5759 + /* LST requires "link" to be first field! */
5760 + struct LST_ELEM link; /* Link to next DEV_OBJECT. */
5761 + u32 devType; /* Device Type */
5762 + u32 dwSignature; /* Used for object validation. */
5763 + struct CFG_DEVNODE *hDevNode; /* Platform specific device id */
5764 + struct WMD_DEV_CONTEXT *hWmdContext; /* WMD Context Handle */
5765 + struct WMD_DRV_INTERFACE intfFxns; /* Function interface to WMD. */
5766 + struct BRD_OBJECT *lockOwner; /* Client with exclusive access. */
5767 + struct COD_MANAGER *hCodMgr; /* Code manager handle. */
5768 + struct CHNL_MGR *hChnlMgr; /* Channel manager. */
5769 + struct DEH_MGR *hDehMgr; /* DEH manager. */
5770 + struct MSG_MGR *hMsgMgr; /* Message manager. */
5771 + struct IO_MGR *hIOMgr; /* IO manager (CHNL, MSG) */
5772 + struct CMM_OBJECT *hCmmMgr; /* SM memory manager. */
5773 + struct DMM_OBJECT *hDmmMgr; /* Dynamic memory manager. */
5774 + struct LDR_MODULE *hModule; /* WMD Module handle. */
5775 + u32 uWordSize; /* DSP word size: quick access. */
5776 + struct DRV_OBJECT *hDrvObject; /* Driver Object */
5777 + struct LST_LIST *procList; /* List of Proceeosr attached to
5778 + * this device */
5779 + struct NODE_MGR *hNodeMgr;
5780 +} ;
5782 +/* ----------------------------------- Globals */
5783 +static u32 cRefs; /* Module reference count */
5784 +#if GT_TRACE
5785 +static struct GT_Mask debugMask = { NULL, NULL }; /* For debugging */
5786 +#endif
5788 +/* ----------------------------------- Function Prototypes */
5789 +static DSP_STATUS FxnNotImplemented(int arg, ...);
5790 +static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject);
5791 +static bool IsValidHandle(struct DEV_OBJECT *hObj);
5792 +static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns,
5793 + OUT struct WMD_DRV_INTERFACE *pIntfFxns);
5795 + * ======== DEV_BrdWriteFxn ========
5796 + * Purpose:
5797 + * Exported function to be used as the COD write function. This function
5798 + * is passed a handle to a DEV_hObject, then calls the
5799 + * device's WMD_BRD_Write() function.
5800 + */
5801 +u32 DEV_BrdWriteFxn(void *pArb, u32 ulDspAddr, void *pHostBuf,
5802 + u32 ulNumBytes, u32 nMemSpace)
5804 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)pArb;
5805 + u32 ulWritten = 0;
5806 + DSP_STATUS status;
5808 + DBC_Require(cRefs > 0);
5809 + DBC_Require(pHostBuf != NULL); /* Required of BrdWrite(). */
5810 + GT_5trace(debugMask, GT_ENTER,
5811 + "Entered DEV_BrdWriteFxn, pArb: 0x%x\n\t\t"
5812 + "ulDspAddr: 0x%x\n\t\tpHostBuf: 0x%x\n \t\tulNumBytes: 0x%x\n"
5813 + "\t\tnMemSpace: 0x%x\n", pArb, ulDspAddr, pHostBuf,
5814 + ulNumBytes, nMemSpace);
5815 + if (IsValidHandle(pDevObject)) {
5816 + /* Require of BrdWrite() */
5817 + DBC_Assert(pDevObject->hWmdContext != NULL);
5818 + status = (*pDevObject->intfFxns.pfnBrdWrite)(pDevObject->
5819 + hWmdContext, pHostBuf, ulDspAddr, ulNumBytes,
5820 + nMemSpace);
5821 + /* Special case of getting the address only */
5822 + if (ulNumBytes == 0)
5823 + ulNumBytes = 1;
5824 + if (DSP_SUCCEEDED(status))
5825 + ulWritten = ulNumBytes;
5828 + GT_1trace(debugMask, GT_ENTER, "Exit DEV_BrdWriteFxn ulWritten: 0x%x\n",
5829 + ulWritten);
5830 + return ulWritten;
5834 + * ======== DEV_CreateDevice ========
5835 + * Purpose:
5836 + * Called by the operating system to load the PM Mini Driver for a
5837 + * PM board (device).
5838 + */
5839 +DSP_STATUS DEV_CreateDevice(OUT struct DEV_OBJECT **phDevObject,
5840 + IN CONST char *pstrWMDFileName,
5841 + IN CONST struct CFG_HOSTRES *pHostConfig,
5842 + IN CONST struct CFG_DSPRES *pDspConfig,
5843 + struct CFG_DEVNODE *hDevNode)
5845 + struct LDR_MODULE *hModule = NULL;
5846 + struct WMD_DRV_INTERFACE *pDrvFxns = NULL;
5847 + struct DEV_OBJECT *pDevObject = NULL;
5848 + struct CHNL_MGRATTRS mgrAttrs;
5849 + struct IO_ATTRS ioMgrAttrs;
5850 + u32 uNumWindows;
5851 + struct DRV_OBJECT *hDrvObject = NULL;
5852 + DSP_STATUS status = DSP_SOK;
5853 + DBC_Require(cRefs > 0);
5854 + DBC_Require(phDevObject != NULL);
5855 + DBC_Require(pstrWMDFileName != NULL);
5856 + DBC_Require(pHostConfig != NULL);
5857 + DBC_Require(pDspConfig != NULL);
5859 + GT_5trace(debugMask, GT_ENTER,
5860 + "Entered DEV_CreateDevice, phDevObject: 0x%x\n"
5861 + "\t\tpstrWMDFileName: 0x%x\n\t\tpHostConfig:0x%x\n\t\t"
5862 + "pDspConfig: 0x%x\n\t\tnhDevNode: 0x%x\n", phDevObject,
5863 + pstrWMDFileName, pHostConfig, pDspConfig, hDevNode);
5864 + /* Get the WMD interface functions*/
5865 + WMD_DRV_Entry(&pDrvFxns, pstrWMDFileName);
5866 + if (DSP_FAILED(CFG_GetObject((u32 *) &hDrvObject, REG_DRV_OBJECT))) {
5867 + /* don't propogate CFG errors from this PROC function */
5868 + GT_0trace(debugMask, GT_7CLASS,
5869 + "Failed to get the DRV Object \n");
5870 + status = DSP_EFAIL;
5872 + /* Create the device object, and pass a handle to the WMD for
5873 + * storage. */
5874 + if (DSP_SUCCEEDED(status)) {
5875 + DBC_Assert(pDrvFxns);
5876 + MEM_AllocObject(pDevObject, struct DEV_OBJECT, SIGNATURE);
5877 + if (pDevObject) {
5878 + /* Fill out the rest of the Dev Object structure: */
5879 + pDevObject->hDevNode = hDevNode;
5880 + pDevObject->hModule = hModule;
5881 + pDevObject->hCodMgr = NULL;
5882 + pDevObject->hChnlMgr = NULL;
5883 + pDevObject->hDehMgr = NULL;
5884 + pDevObject->lockOwner = NULL;
5885 + pDevObject->uWordSize = pDspConfig->uWordSize;
5886 + pDevObject->hDrvObject = hDrvObject;
5887 + pDevObject->devType = DSP_UNIT;
5888 + /* Store this WMD's interface functions, based on its
5889 + * version. */
5890 + StoreInterfaceFxns(pDrvFxns, &pDevObject->intfFxns);
5891 + /* Call WMD_DEV_CREATE() to get the WMD's device
5892 + * context handle. */
5893 + status = (pDevObject->intfFxns.pfnDevCreate)
5894 + (&pDevObject->hWmdContext, pDevObject,
5895 + pHostConfig, pDspConfig);
5896 + /* Assert WMD_DEV_Create()'s ensure clause: */
5897 + DBC_Assert(DSP_FAILED(status) || (pDevObject->
5898 + hWmdContext != NULL));
5899 + } else {
5900 + GT_0trace(debugMask, GT_7CLASS,
5901 + "DEV_Create: Out Of Memory");
5902 + status = DSP_EMEMORY;
5905 + /* Attempt to create the COD manager for this device: */
5906 + if (DSP_SUCCEEDED(status))
5907 + status = InitCodMgr(pDevObject);
5909 + /* Attempt to create the channel manager for this device: */
5910 + if (DSP_SUCCEEDED(status)) {
5911 + mgrAttrs.cChannels = CHNL_MAXCHANNELS;
5912 + ioMgrAttrs.bIRQ = pHostConfig->bIRQRegisters;
5913 + ioMgrAttrs.fShared = (pHostConfig->bIRQAttrib & CFG_IRQSHARED);
5914 + ioMgrAttrs.uWordSize = pDspConfig->uWordSize;
5915 + mgrAttrs.uWordSize = pDspConfig->uWordSize;
5916 + uNumWindows = pHostConfig->wNumMemWindows;
5917 + if (uNumWindows) {
5918 + /* Assume last memory window is for CHNL */
5919 + ioMgrAttrs.dwSMBase = pHostConfig->dwMemBase[1] +
5920 + pHostConfig->dwOffsetForMonitor;
5921 + ioMgrAttrs.uSMLength = pHostConfig->dwMemLength[1] -
5922 + pHostConfig->dwOffsetForMonitor;
5923 + } else {
5924 + ioMgrAttrs.dwSMBase = 0;
5925 + ioMgrAttrs.uSMLength = 0;
5926 + GT_0trace(debugMask, GT_7CLASS,
5927 + "**There is no memory reserved for "
5928 + "shared structures**\n");
5930 + status = CHNL_Create(&pDevObject->hChnlMgr, pDevObject,
5931 + &mgrAttrs);
5932 + if (status == DSP_ENOTIMPL) {
5933 + /* It's OK for a device not to have a channel
5934 + * manager: */
5935 + status = DSP_SOK;
5937 + /* Create CMM mgr even if Msg Mgr not impl. */
5938 + status = CMM_Create(&pDevObject->hCmmMgr,
5939 + (struct DEV_OBJECT *)pDevObject, NULL);
5940 + if (DSP_FAILED(status)) {
5941 + GT_0trace(debugMask, GT_7CLASS,
5942 + "DEV_Create: Failed to Create SM "
5943 + "Manager\n");
5945 + /* Only create IO manager if we have a channel manager */
5946 + if (DSP_SUCCEEDED(status) && pDevObject->hChnlMgr) {
5947 + status = IO_Create(&pDevObject->hIOMgr, pDevObject,
5948 + &ioMgrAttrs);
5950 + /* Only create DEH manager if we have an IO manager */
5951 + if (DSP_SUCCEEDED(status)) {
5952 + /* Instantiate the DEH module */
5953 + status = (*pDevObject->intfFxns.pfnDehCreate)
5954 + (&pDevObject->hDehMgr, pDevObject);
5956 + /* Create DMM mgr . */
5957 + status = DMM_Create(&pDevObject->hDmmMgr,
5958 + (struct DEV_OBJECT *)pDevObject, NULL);
5959 + if (DSP_FAILED(status)) {
5960 + GT_0trace(debugMask, GT_7CLASS,
5961 + "DEV_Create: Failed to Create DMM "
5962 + "Manager\n");
5965 + /* Add the new DEV_Object to the global list: */
5966 + if (DSP_SUCCEEDED(status)) {
5967 + LST_InitElem(&pDevObject->link);
5968 + status = DRV_InsertDevObject(hDrvObject, pDevObject);
5970 + /* Create the Processor List */
5971 + if (DSP_SUCCEEDED(status)) {
5972 + pDevObject->procList = LST_Create();
5973 + if (!(pDevObject->procList)) {
5974 + status = DSP_EFAIL;
5975 + GT_0trace(debugMask, GT_7CLASS, "DEV_Create: "
5976 + "Failed to Create Proc List");
5979 + /* If all went well, return a handle to the dev object;
5980 + * else, cleanup and return NULL in the OUT parameter. */
5981 + if (DSP_SUCCEEDED(status)) {
5982 + *phDevObject = pDevObject;
5983 + GT_1trace(debugMask, GT_1CLASS,
5984 + "DEV_CreateDevice Succeeded \nDevObject "
5985 + "0x%x\n", pDevObject);
5986 + } else {
5987 + if (pDevObject && pDevObject->procList)
5988 + LST_Delete(pDevObject->procList);
5990 + if (pDevObject && pDevObject->hCodMgr)
5991 + COD_Delete(pDevObject->hCodMgr);
5993 + if (pDevObject && pDevObject->hDmmMgr)
5994 + DMM_Destroy(pDevObject->hDmmMgr);
5996 + if (pDevObject)
5997 + MEM_FreeObject(pDevObject);
5999 + *phDevObject = NULL;
6000 + GT_0trace(debugMask, GT_7CLASS, "DEV_CreateDevice Failed\n");
6002 + GT_1trace(debugMask, GT_1CLASS, "Exiting DEV_Create: DevObject 0x%x\n",
6003 + *phDevObject);
6004 + DBC_Ensure((DSP_SUCCEEDED(status) && IsValidHandle(*phDevObject)) ||
6005 + (DSP_FAILED(status) && !*phDevObject));
6006 + return status;
6010 + * ======== DEV_Create2 ========
6011 + * Purpose:
6012 + * After successful loading of the image from WCD_InitComplete2
6013 + * (PROC Auto_Start) or PROC_Load this fxn is called. This creates
6014 + * the Node Manager and updates the DEV Object.
6015 + */
6016 +DSP_STATUS CDECL DEV_Create2(struct DEV_OBJECT *hDevObject)
6018 + DSP_STATUS status = DSP_SOK;
6019 + struct DEV_OBJECT *pDevObject = hDevObject;
6021 + DBC_Require(cRefs > 0);
6022 + DBC_Require(IsValidHandle(hDevObject));
6024 + GT_1trace(debugMask, GT_ENTER,
6025 + "Entered DEV_Create2, hDevObject: 0x%x\n", hDevObject);
6026 + /* There can be only one Node Manager per DEV object */
6027 + DBC_Assert(!pDevObject->hNodeMgr);
6028 + status = NODE_CreateMgr(&pDevObject->hNodeMgr, hDevObject);
6029 + if (DSP_FAILED(status)) {
6030 + GT_1trace(debugMask, GT_7CLASS,
6031 + "DEV_Create2: NODE_CreateMgr failed, "
6032 + "0x%x!\n", status);
6033 + pDevObject->hNodeMgr = NULL;
6034 + GT_0trace(debugMask, GT_7CLASS, "DEV_Create2: Failed!!\n");
6036 + DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr != NULL)
6037 + || (DSP_FAILED(status) && pDevObject->hNodeMgr == NULL));
6038 + GT_2trace(debugMask, GT_ENTER,
6039 + "Exiting DEV_Create2, hNodeMgr: 0x%x, status:"
6040 + " 0x%x\n", pDevObject->hNodeMgr, status);
6041 + return status;
6045 + * ======== DEV_Destroy2 ========
6046 + * Purpose:
6047 + * Destroys the Node manager for this device.
6048 + */
6049 +DSP_STATUS CDECL DEV_Destroy2(struct DEV_OBJECT *hDevObject)
6051 + DSP_STATUS status = DSP_SOK;
6052 + struct DEV_OBJECT *pDevObject = hDevObject;
6054 + DBC_Require(cRefs > 0);
6055 + DBC_Require(IsValidHandle(hDevObject));
6057 + GT_1trace(debugMask, GT_ENTER,
6058 + "Entered DEV_Destroy2, hDevObject: 0x%x\n",
6059 + hDevObject);
6060 + if (pDevObject->hNodeMgr) {
6061 + if (DSP_FAILED(NODE_DeleteMgr(pDevObject->hNodeMgr)))
6062 + status = DSP_EFAIL;
6063 + else
6064 + pDevObject->hNodeMgr = NULL;
6067 + if (DSP_FAILED(status))
6068 + GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy2 failed!!\n");
6070 + DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr == NULL) ||
6071 + DSP_FAILED(status));
6072 + GT_2trace(debugMask, GT_ENTER,
6073 + "Exiting DEV_Destroy2, hNodeMgr: 0x%x, status"
6074 + " = 0x%x\n", pDevObject->hNodeMgr, status);
6075 + return status;
6079 + * ======== DEV_DestroyDevice ========
6080 + * Purpose:
6081 + * Destroys the channel manager for this device, if any, calls
6082 + * WMD_DEV_Destroy(), and then attempts to unload the WMD module.
6083 + */
6084 +DSP_STATUS DEV_DestroyDevice(struct DEV_OBJECT *hDevObject)
6086 + DSP_STATUS status = DSP_SOK;
6087 + struct DEV_OBJECT *pDevObject = hDevObject;
6089 + DBC_Require(cRefs > 0);
6091 + GT_1trace(debugMask, GT_ENTER, "Entered DEV_DestroyDevice, hDevObject: "
6092 + "0x%x\n", hDevObject);
6093 + if (IsValidHandle(hDevObject)) {
6094 + if (pDevObject->hCodMgr)
6095 + COD_Delete(pDevObject->hCodMgr);
6097 + if (pDevObject->hNodeMgr)
6098 + NODE_DeleteMgr(pDevObject->hNodeMgr);
6100 + /* Free the io, channel, and message managers for this board: */
6101 + if (pDevObject->hIOMgr) {
6102 + IO_Destroy(pDevObject->hIOMgr);
6103 + pDevObject->hIOMgr = NULL;
6105 + if (pDevObject->hChnlMgr) {
6106 + CHNL_Destroy(pDevObject->hChnlMgr);
6107 + pDevObject->hChnlMgr = NULL;
6109 + if (pDevObject->hMsgMgr)
6110 + MSG_Delete(pDevObject->hMsgMgr);
6112 + if (pDevObject->hDehMgr) {
6113 + /* Uninitialize DEH module. */
6114 + (*pDevObject->intfFxns.pfnDehDestroy)
6115 + (pDevObject->hDehMgr);
6117 + if (pDevObject->hCmmMgr)
6118 + CMM_Destroy(pDevObject->hCmmMgr, true);
6120 + if (pDevObject->hDmmMgr)
6121 + DMM_Destroy(pDevObject->hDmmMgr);
6123 + /* Call the driver's WMD_DEV_Destroy() function: */
6124 + /* Require of DevDestroy */
6125 + DBC_Assert(pDevObject->hWmdContext != NULL);
6126 + status = (*pDevObject->intfFxns.pfnDevDestroy)
6127 + (pDevObject->hWmdContext);
6128 + if (DSP_SUCCEEDED(status)) {
6129 + if (pDevObject->procList)
6130 + LST_Delete(pDevObject->procList);
6132 + /* Remove this DEV_Object from the global list: */
6133 + DRV_RemoveDevObject(pDevObject->hDrvObject, pDevObject);
6134 + /* Free The library * LDR_FreeModule
6135 + * (pDevObject->hModule);*/
6136 + /* Free this dev object: */
6137 + MEM_FreeObject(pDevObject);
6139 + } else {
6140 + GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy: Invlaid handle");
6141 + status = DSP_EHANDLE;
6143 + GT_1trace(debugMask, GT_ENTER, "Exit DEV_destroy: status 0x%x\n",
6144 + status);
6145 + return status;
6149 + * ======== DEV_GetChnlMgr ========
6150 + * Purpose:
6151 + * Retrieve the handle to the channel manager handle created for this
6152 + * device.
6153 + */
6154 +DSP_STATUS DEV_GetChnlMgr(struct DEV_OBJECT *hDevObject,
6155 + OUT struct CHNL_MGR **phMgr)
6157 + DSP_STATUS status = DSP_SOK;
6158 + struct DEV_OBJECT *pDevObject = hDevObject;
6160 + DBC_Require(cRefs > 0);
6161 + DBC_Require(phMgr != NULL);
6163 + GT_2trace(debugMask, GT_ENTER,
6164 + "Entered DEV_GetChnlMgr, hDevObject: 0x%x\n\t"
6165 + "\tphMgr: 0x%x\n", hDevObject, phMgr);
6166 + if (IsValidHandle(hDevObject)) {
6167 + *phMgr = pDevObject->hChnlMgr;
6168 + } else {
6169 + *phMgr = NULL;
6170 + status = DSP_EHANDLE;
6171 + GT_0trace(debugMask, GT_7CLASS,
6172 + "DEV_GetChnlMgr: Invalid handle");
6174 + GT_2trace(debugMask, GT_ENTER,
6175 + "Exit DEV_GetChnlMgr: status 0x%x\t\n hMgr: "
6176 + "0x%x\n", status, *phMgr);
6177 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
6178 + (*phMgr == NULL)));
6179 + return status;
6183 + * ======== DEV_GetCmmMgr ========
6184 + * Purpose:
6185 + * Retrieve the handle to the shared memory manager created for this
6186 + * device.
6187 + */
6188 +DSP_STATUS DEV_GetCmmMgr(struct DEV_OBJECT *hDevObject,
6189 + OUT struct CMM_OBJECT **phMgr)
6191 + DSP_STATUS status = DSP_SOK;
6192 + struct DEV_OBJECT *pDevObject = hDevObject;
6194 + DBC_Require(cRefs > 0);
6195 + DBC_Require(phMgr != NULL);
6196 + GT_2trace(debugMask, GT_ENTER,
6197 + "Entered DEV_GetCmmMgr, hDevObject: 0x%x\n\t"
6198 + "\tphMgr: 0x%x\n", hDevObject, phMgr);
6199 + if (IsValidHandle(hDevObject)) {
6200 + *phMgr = pDevObject->hCmmMgr;
6201 + } else {
6202 + *phMgr = NULL;
6203 + status = DSP_EHANDLE;
6204 + GT_0trace(debugMask, GT_7CLASS,
6205 + "DEV_GetCmmMgr: Invalid handle");
6207 + GT_2trace(debugMask, GT_ENTER,
6208 + "Exit DEV_GetCmmMgr: status 0x%x\t\nhMgr: "
6209 + "0x%x\n", status, *phMgr);
6210 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
6211 + (*phMgr == NULL)));
6212 + return status;
6216 + * ======== DEV_GetDmmMgr ========
6217 + * Purpose:
6218 + * Retrieve the handle to the dynamic memory manager created for this
6219 + * device.
6220 + */
6221 +DSP_STATUS DEV_GetDmmMgr(struct DEV_OBJECT *hDevObject,
6222 + OUT struct DMM_OBJECT **phMgr)
6224 + DSP_STATUS status = DSP_SOK;
6225 + struct DEV_OBJECT *pDevObject = hDevObject;
6227 + DBC_Require(cRefs > 0);
6228 + DBC_Require(phMgr != NULL);
6230 + GT_2trace(debugMask, GT_ENTER, "Entered DEV_GetDmmMgr, hDevObject: "
6231 + "0x%x\n\t\tphMgr: 0x%x\n", hDevObject, phMgr);
6232 + if (IsValidHandle(hDevObject)) {
6233 + *phMgr = pDevObject->hDmmMgr;
6234 + } else {
6235 + *phMgr = NULL;
6236 + status = DSP_EHANDLE;
6237 + GT_0trace(debugMask, GT_7CLASS,
6238 + "DEV_GetDmmMgr: Invalid handle");
6240 + GT_2trace(debugMask, GT_ENTER,
6241 + "Exit DEV_GetDmmMgr: status 0x%x\t\n hMgr: "
6242 + "0x%x\n", status, *phMgr);
6243 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
6244 + (*phMgr == NULL)));
6245 + return status;
6249 + * ======== DEV_GetCodMgr ========
6250 + * Purpose:
6251 + * Retrieve the COD manager create for this device.
6252 + */
6253 +DSP_STATUS DEV_GetCodMgr(struct DEV_OBJECT *hDevObject,
6254 + OUT struct COD_MANAGER **phCodMgr)
6256 + DSP_STATUS status = DSP_SOK;
6257 + struct DEV_OBJECT *pDevObject = hDevObject;
6259 + DBC_Require(cRefs > 0);
6260 + DBC_Require(phCodMgr != NULL);
6262 + GT_2trace(debugMask, GT_ENTER,
6263 + "Entered DEV_GetCodMgr, hDevObject: 0x%x\n\t\t"
6264 + "phCodMgr: 0x%x\n", hDevObject, phCodMgr);
6265 + if (IsValidHandle(hDevObject)) {
6266 + *phCodMgr = pDevObject->hCodMgr;
6267 + } else {
6268 + *phCodMgr = NULL;
6269 + status = DSP_EHANDLE;
6270 + GT_1trace(debugMask, GT_7CLASS,
6271 + "DEV_GetCodMgr, invalid handle: 0x%x\n",
6272 + hDevObject);
6274 + GT_2trace(debugMask, GT_ENTER,
6275 + "Exit DEV_GetCodMgr: status 0x%x\t\n hCodMgr:"
6276 + " 0x%x\n", status, *phCodMgr);
6277 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phCodMgr != NULL) &&
6278 + (*phCodMgr == NULL)));
6279 + return status;
6283 + * ========= DEV_GetDehMgr ========
6284 + */
6285 +DSP_STATUS DEV_GetDehMgr(struct DEV_OBJECT *hDevObject,
6286 + OUT struct DEH_MGR **phDehMgr)
6288 + DSP_STATUS status = DSP_SOK;
6290 + DBC_Require(cRefs > 0);
6291 + DBC_Require(phDehMgr != NULL);
6292 + DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
6293 + if (IsValidHandle(hDevObject)) {
6294 + *phDehMgr = hDevObject->hDehMgr;
6295 + } else {
6296 + *phDehMgr = NULL;
6297 + status = DSP_EHANDLE;
6298 + GT_0trace(debugMask, GT_7CLASS,
6299 + "DEV_GetDehMgr: Invalid handle");
6301 + return status;
6305 + * ======== DEV_GetDevNode ========
6306 + * Purpose:
6307 + * Retrieve the platform specific device ID for this device.
6308 + */
6309 +DSP_STATUS DEV_GetDevNode(struct DEV_OBJECT *hDevObject,
6310 + OUT struct CFG_DEVNODE **phDevNode)
6312 + DSP_STATUS status = DSP_SOK;
6313 + struct DEV_OBJECT *pDevObject = hDevObject;
6315 + DBC_Require(cRefs > 0);
6316 + DBC_Require(phDevNode != NULL);
6318 + GT_2trace(debugMask, GT_ENTER,
6319 + "Entered DEV_GetDevNode, hDevObject: 0x%x\n\t"
6320 + "\tphDevNode: 0x%x\n", hDevObject, phDevNode);
6321 + if (IsValidHandle(hDevObject)) {
6322 + *phDevNode = pDevObject->hDevNode;
6323 + } else {
6324 + *phDevNode = NULL;
6325 + status = DSP_EHANDLE;
6326 + GT_0trace(debugMask, GT_7CLASS,
6327 + "DEV_GetDevNode: Invalid handle");
6329 + GT_2trace(debugMask, GT_ENTER,
6330 + "Exit DEV_GetDevNode: status 0x%x\t\nhDevNode:"
6331 + "0x%x\n", status, *phDevNode);
6332 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phDevNode != NULL) &&
6333 + (*phDevNode == NULL)));
6334 + return status;
6338 + * ======== DEV_GetFirst ========
6339 + * Purpose:
6340 + * Retrieve the first Device Object handle from an internal linked list
6341 + * DEV_OBJECTs maintained by DEV.
6342 + */
6343 +struct DEV_OBJECT *DEV_GetFirst(void)
6345 + struct DEV_OBJECT *pDevObject = NULL;
6347 + pDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject();
6349 + DBC_Ensure((pDevObject == NULL) || IsValidHandle(pDevObject));
6351 + return pDevObject;
6355 + * ======== DEV_GetIntfFxns ========
6356 + * Purpose:
6357 + * Retrieve the WMD interface function structure for the loaded WMD.
6358 + * ppIntfFxns != NULL.
6359 + */
6360 +DSP_STATUS DEV_GetIntfFxns(struct DEV_OBJECT *hDevObject,
6361 + OUT struct WMD_DRV_INTERFACE **ppIntfFxns)
6363 + DSP_STATUS status = DSP_SOK;
6364 + struct DEV_OBJECT *pDevObject = hDevObject;
6366 + DBC_Require(cRefs > 0);
6367 + DBC_Require(ppIntfFxns != NULL);
6369 + GT_2trace(debugMask, GT_ENTER,
6370 + "Entered DEV_GetIntfFxns, hDevObject: 0x%x\n\t"
6371 + "\tppIntfFxns: 0x%x\n", hDevObject, ppIntfFxns);
6372 + if (IsValidHandle(hDevObject)) {
6373 + *ppIntfFxns = &pDevObject->intfFxns;
6374 + } else {
6375 + *ppIntfFxns = NULL;
6376 + status = DSP_EHANDLE;
6377 + GT_0trace(debugMask, GT_7CLASS,
6378 + "DEV_GetIntDxns: Invalid handle");
6380 + GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetIntFxns: status 0x%x\t\n"
6381 + "ppIntFxns: 0x%x\n", status, *ppIntfFxns);
6382 + DBC_Ensure(DSP_SUCCEEDED(status) || ((ppIntfFxns != NULL) &&
6383 + (*ppIntfFxns == NULL)));
6384 + return status;
6388 + * ========= DEV_GetIOMgr ========
6389 + */
6390 +DSP_STATUS DEV_GetIOMgr(struct DEV_OBJECT *hDevObject,
6391 + OUT struct IO_MGR **phIOMgr)
6393 + DSP_STATUS status = DSP_SOK;
6395 + DBC_Require(cRefs > 0);
6396 + DBC_Require(phIOMgr != NULL);
6397 + DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
6399 + if (IsValidHandle(hDevObject)) {
6400 + *phIOMgr = hDevObject->hIOMgr;
6401 + } else {
6402 + *phIOMgr = NULL;
6403 + status = DSP_EHANDLE;
6404 + GT_0trace(debugMask, GT_7CLASS, "DEV_GetIOMgr: Invalid handle");
6407 + return status;
6411 + * ======== DEV_GetNext ========
6412 + * Purpose:
6413 + * Retrieve the next Device Object handle from an internal linked list
6414 + * of DEV_OBJECTs maintained by DEV, after having previously called
6415 + * DEV_GetFirst() and zero or more DEV_GetNext
6416 + */
6417 +struct DEV_OBJECT *DEV_GetNext(struct DEV_OBJECT *hDevObject)
6419 + struct DEV_OBJECT *pNextDevObject = NULL;
6421 + if (IsValidHandle(hDevObject)) {
6422 + pNextDevObject = (struct DEV_OBJECT *)
6423 + DRV_GetNextDevObject((u32)hDevObject);
6425 + DBC_Ensure((pNextDevObject == NULL) || IsValidHandle(pNextDevObject));
6426 + return pNextDevObject;
6430 + * ========= DEV_GetMsgMgr ========
6431 + */
6432 +void CDECL DEV_GetMsgMgr(struct DEV_OBJECT *hDevObject,
6433 + OUT struct MSG_MGR **phMsgMgr)
6435 + DBC_Require(cRefs > 0);
6436 + DBC_Require(phMsgMgr != NULL);
6437 + DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
6439 + *phMsgMgr = hDevObject->hMsgMgr;
6443 + * ======== DEV_GetNodeManager ========
6444 + * Purpose:
6445 + * Retrieve the Node Manager Handle
6446 + */
6447 +DSP_STATUS CDECL DEV_GetNodeManager(struct DEV_OBJECT *hDevObject,
6448 + OUT struct NODE_MGR **phNodeMgr)
6450 + DSP_STATUS status = DSP_SOK;
6451 + struct DEV_OBJECT *pDevObject = hDevObject;
6453 + DBC_Require(cRefs > 0);
6454 + DBC_Require(phNodeMgr != NULL);
6456 + GT_2trace(debugMask, GT_ENTER,
6457 + "Entered DEV_GetNodeManager, hDevObject: 0x%x"
6458 + "\n\t\tphNodeMgr: 0x%x\n", hDevObject, phNodeMgr);
6459 + if (IsValidHandle(hDevObject)) {
6460 + *phNodeMgr = pDevObject->hNodeMgr;
6461 + } else {
6462 + *phNodeMgr = NULL;
6463 + status = DSP_EHANDLE;
6464 + GT_1trace(debugMask, GT_7CLASS,
6465 + "DEV_GetNodeManager, invalid handle: 0x"
6466 + "%x\n", hDevObject);
6468 + GT_2trace(debugMask, GT_ENTER,
6469 + "Exit DEV_GetNodeManager: status 0x%x\t\nhMgr:"
6470 + " 0x%x\n", status, *phNodeMgr);
6471 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phNodeMgr != NULL) &&
6472 + (*phNodeMgr == NULL)));
6473 + return status;
6477 + * ======== DEV_GetSymbol ========
6478 + */
6479 +DSP_STATUS CDECL DEV_GetSymbol(struct DEV_OBJECT *hDevObject,
6480 + IN CONST char *pstrSym, OUT u32 *pulValue)
6482 + DSP_STATUS status = DSP_SOK;
6483 + struct COD_MANAGER *hCodMgr;
6485 + DBC_Require(cRefs > 0);
6486 + DBC_Require(pstrSym != NULL && pulValue != NULL);
6488 + GT_3trace(debugMask, GT_ENTER,
6489 + "Entered DEV_GetSymbol, hDevObject: 0x%x\n\t\t"
6490 + "pstrSym: 0x%x\n\t\tpulValue: 0x%x\n", hDevObject, pstrSym,
6491 + pulValue);
6492 + if (IsValidHandle(hDevObject)) {
6493 + status = DEV_GetCodMgr(hDevObject, &hCodMgr);
6494 + if (DSP_SUCCEEDED(status)) {
6495 + DBC_Assert(hCodMgr != NULL);
6496 + status = COD_GetSymValue(hCodMgr, (char *)pstrSym, pulValue);
6498 + } else {
6499 + status = DSP_EHANDLE;
6500 + GT_0trace(debugMask, GT_7CLASS,
6501 + "DEV_GetSymbol: Invalid handle");
6503 + GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetSymbol: status 0x%x\t\n"
6504 + "hWmdContext: 0x%x\n", status, *pulValue);
6505 + return status;
6509 + * ======== DEV_GetWMDContext ========
6510 + * Purpose:
6511 + * Retrieve the WMD Context handle, as returned by the WMD_Create fxn.
6512 + */
6513 +DSP_STATUS DEV_GetWMDContext(struct DEV_OBJECT *hDevObject,
6514 + OUT struct WMD_DEV_CONTEXT **phWmdContext)
6516 + DSP_STATUS status = DSP_SOK;
6517 + struct DEV_OBJECT *pDevObject = hDevObject;
6519 + DBC_Require(cRefs > 0);
6520 + DBC_Require(phWmdContext != NULL);
6521 + GT_2trace(debugMask, GT_ENTER,
6522 + "Entered DEV_GetWMDContext, hDevObject: 0x%x\n"
6523 + "\t\tphWmdContext: 0x%x\n", hDevObject, phWmdContext);
6524 + if (IsValidHandle(hDevObject)) {
6525 + *phWmdContext = pDevObject->hWmdContext;
6526 + } else {
6527 + *phWmdContext = NULL;
6528 + status = DSP_EHANDLE;
6529 + GT_0trace(debugMask, GT_7CLASS,
6530 + "DEV_GetWMDContext: Invalid handle");
6533 + GT_2trace(debugMask, GT_ENTER,
6534 + "Exit DEV_GetWMDContext: status 0x%x\t\n"
6535 + "hWmdContext: 0x%x\n", status, *phWmdContext);
6536 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phWmdContext != NULL) &&
6537 + (*phWmdContext == NULL)));
6538 + return status;
6542 + * ======== DEV_Exit ========
6543 + * Purpose:
6544 + * Decrement reference count, and free resources when reference count is
6545 + * 0.
6546 + */
6547 +void CDECL DEV_Exit(void)
6549 + DBC_Require(cRefs > 0);
6551 + cRefs--;
6553 + if (cRefs == 0) {
6554 + CMM_Exit();
6555 + DMM_Exit();
6558 + GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Exit, ref count: 0x%x\n",
6559 + cRefs);
6561 + DBC_Ensure(cRefs >= 0);
6565 + * ======== DEV_Init ========
6566 + * Purpose:
6567 + * Initialize DEV's private state, keeping a reference count on each call.
6568 + */
6569 +bool CDECL DEV_Init(void)
6571 + bool fCmm, fDmm, fRetval = true;
6573 + DBC_Require(cRefs >= 0);
6575 + if (cRefs == 0) {
6576 + /* Set the Trace mask */
6577 + DBC_Assert(!debugMask.flags);
6578 + GT_create(&debugMask, "DV"); /* "DV" for DeVice */
6579 + fCmm = CMM_Init();
6580 + fDmm = DMM_Init();
6582 + fRetval = fCmm && fDmm;
6584 + if (!fRetval) {
6585 + if (fCmm)
6586 + CMM_Exit();
6589 + if (fDmm)
6590 + DMM_Exit();
6595 + if (fRetval)
6596 + cRefs++;
6599 + GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Init, ref count: 0x%x\n",
6600 + cRefs);
6602 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
6604 + return fRetval;
6608 + * ======== DEV_NotifyClients ========
6609 + * Purpose:
6610 + * Notify all clients of this device of a change in device status.
6611 + */
6612 +DSP_STATUS DEV_NotifyClients(struct DEV_OBJECT *hDevObject, u32 ulStatus)
6614 + DSP_STATUS status = DSP_SOK;
6616 + struct DEV_OBJECT *pDevObject = hDevObject;
6617 + DSP_HPROCESSOR hProcObject;
6619 + GT_2trace(debugMask, GT_ENTER,
6620 + "Entered DEV_NotifyClients, hDevObject: 0x%x\n"
6621 + "\t\tulStatus: 0x%x\n", hDevObject, ulStatus);
6622 + for (hProcObject = (DSP_HPROCESSOR)LST_First(pDevObject->procList);
6623 + hProcObject != NULL;
6624 + hProcObject = (DSP_HPROCESSOR)LST_Next(pDevObject->procList,
6625 + (struct LST_ELEM *)hProcObject))
6626 + PROC_NotifyClients(hProcObject, (u32) ulStatus);
6628 + return status;
6632 + * ======== DEV_RemoveDevice ========
6633 + */
6634 +DSP_STATUS CDECL DEV_RemoveDevice(struct CFG_DEVNODE *hDevNode)
6636 + struct DEV_OBJECT *hDevObject; /* handle to device object */
6637 + DSP_STATUS status = DSP_SOK;
6638 + struct DEV_OBJECT *pDevObject;
6640 + GT_1trace(debugMask, GT_ENTER,
6641 + "Entered DEV_RemoveDevice, hDevNode: 0x%x\n", hDevNode);
6642 + /* Retrieve the device object handle originaly stored with
6643 + * the DevNode: */
6644 + status = CFG_GetDevObject(hDevNode, (u32 *)&hDevObject);
6645 + if (DSP_SUCCEEDED(status)) {
6646 + /* Remove the Processor List */
6647 + pDevObject = (struct DEV_OBJECT *)hDevObject;
6648 + /* Destroy the device object. */
6649 + status = DEV_DestroyDevice(hDevObject);
6650 + if (DSP_SUCCEEDED(status)) {
6651 + /* Null out the handle stored with the DevNode. */
6652 + GT_0trace(debugMask, GT_1CLASS,
6653 + "DEV_RemoveDevice, success");
6656 + GT_1trace(debugMask, GT_ENTER, "Exit DEV_RemoveDevice, status: 0x%x\n",
6657 + status);
6658 + return status;
6662 + * ======== DEV_SetChnlMgr ========
6663 + * Purpose:
6664 + * Set the channel manager for this device.
6665 + */
6666 +DSP_STATUS DEV_SetChnlMgr(struct DEV_OBJECT *hDevObject, struct CHNL_MGR *hMgr)
6668 + DSP_STATUS status = DSP_SOK;
6669 + struct DEV_OBJECT *pDevObject = hDevObject;
6671 + DBC_Require(cRefs > 0);
6673 + GT_2trace(debugMask, GT_ENTER,
6674 + "Entered DEV_SetChnlMgr, hDevObject: 0x%x\n\t"
6675 + "\thMgr:0x%x\n", hDevObject, hMgr);
6676 + if (IsValidHandle(hDevObject)) {
6677 + pDevObject->hChnlMgr = hMgr;
6678 + } else {
6679 + status = DSP_EHANDLE;
6680 + GT_0trace(debugMask, GT_7CLASS,
6681 + "DEV_SetChnlMgr, Invalid handle\n");
6683 + DBC_Ensure(DSP_FAILED(status) || (pDevObject->hChnlMgr == hMgr));
6684 + return status;
6688 + * ======== DEV_SetMsgMgr ========
6689 + * Purpose:
6690 + * Set the message manager for this device.
6691 + */
6692 +void DEV_SetMsgMgr(struct DEV_OBJECT *hDevObject, struct MSG_MGR *hMgr)
6694 + DBC_Require(cRefs > 0);
6695 + DBC_Require(IsValidHandle(hDevObject));
6696 + GT_2trace(debugMask, GT_ENTER,
6697 + "Entered DEV_SetMsgMgr, hDevObject: 0x%x\n\t\t"
6698 + "hMgr: 0x%x\n", hDevObject, hMgr);
6699 + hDevObject->hMsgMgr = hMgr;
6703 + * ======== DEV_StartDevice ========
6704 + * Purpose:
6705 + * Initializes the new device with the BRIDGE environment.
6706 + */
6707 +DSP_STATUS CDECL DEV_StartDevice(struct CFG_DEVNODE *hDevNode)
6709 + struct DEV_OBJECT *hDevObject = NULL; /* handle to 'Bridge Device */
6710 + struct CFG_HOSTRES hostRes; /* resources struct. */
6711 + struct CFG_DSPRES dspRes; /* DSP resources struct */
6712 + char szWMDFileName[CFG_MAXSEARCHPATHLEN] = "UMA"; /* wmd filename */
6713 + DSP_STATUS status;
6714 + struct MGR_OBJECT *hMgrObject = NULL;
6716 + DBC_Require(cRefs > 0);
6718 + GT_1trace(debugMask, GT_ENTER,
6719 + "Entered DEV_StartDevice, hDevObject: 0x%x\n", hDevNode);
6720 + status = CFG_GetHostResources(hDevNode, &hostRes);
6721 + if (DSP_SUCCEEDED(status)) {
6722 + /* Get DSP resources of device from Registry: */
6723 + status = CFG_GetDSPResources(hDevNode, &dspRes);
6724 + if (DSP_FAILED(status)) {
6725 + GT_1trace(debugMask, GT_7CLASS,
6726 + "Failed to get WMD DSP resources"
6727 + " from registry: 0x%x ", status);
6729 + } else {
6730 + GT_1trace(debugMask, GT_7CLASS,
6731 + "Failed to get WMD Host resources "
6732 + "from registry: 0x%x ", status);
6734 + if (DSP_SUCCEEDED(status)) {
6735 + /* Given all resources, create a device object. */
6736 + status = DEV_CreateDevice(&hDevObject, szWMDFileName, &hostRes,
6737 + &dspRes, hDevNode);
6738 + if (DSP_SUCCEEDED(status)) {
6739 + /* Store away the hDevObject with the DEVNODE */
6740 + status = CFG_SetDevObject(hDevNode, (u32)hDevObject);
6741 + if (DSP_FAILED(status)) {
6742 + /* Clean up */
6743 + GT_1trace(debugMask, GT_7CLASS,
6744 + "Failed to set DevObject in the "
6745 + "Registry: 0x%x", status);
6746 + DEV_DestroyDevice(hDevObject);
6747 + hDevObject = NULL;
6749 + } else {
6750 + GT_1trace(debugMask, GT_7CLASS,
6751 + "Failed to Create Device: 0x%x",
6752 + status);
6755 + if (DSP_SUCCEEDED(status)) {
6756 + /* Create the Manager Object */
6757 + status = MGR_Create(&hMgrObject, hDevNode);
6759 + if (DSP_FAILED(status)) {
6760 + GT_1trace(debugMask, GT_7CLASS, "Failed to MGR object: 0x%x",
6761 + status);
6762 + status = DSP_EFAIL;
6764 + if (DSP_FAILED(status)) {
6765 + if (hDevObject)
6766 + DEV_DestroyDevice(hDevObject);
6768 + /* Ensure the device extension is NULL */
6769 + CFG_SetDevObject(hDevNode, 0L);
6771 + GT_1trace(debugMask, GT_ENTER, "Exiting DEV_StartDevice status 0x%x\n",
6772 + status);
6773 + return status;
6777 + * ======== FxnNotImplemented ========
6778 + * Purpose:
6779 + * Takes the place of a WMD Null Function.
6780 + * Parameters:
6781 + * Multiple, optional.
6782 + * Returns:
6783 + * DSP_ENOTIMPL: Always.
6784 + */
6785 +static DSP_STATUS FxnNotImplemented(int arg, ...)
6787 + DBG_Trace(DBG_LEVEL1,
6788 + "WARNING: Calling a non-implemented WMD function.\n");
6790 + return DSP_ENOTIMPL;
6794 + * ======== IsValidHandle ========
6795 + * Purpose:
6796 + * Validate the device object handle.
6797 + * Parameters:
6798 + * hDevObject: Handle to device object created with
6799 + * DEV_CreateDevice().
6800 + * Returns:
6801 + * true if handle is valid; false otherwise.
6802 + * Requires:
6803 + * Ensures:
6804 + */
6805 +static bool IsValidHandle(struct DEV_OBJECT *hObj)
6807 + bool retVal;
6809 + retVal = (hObj != NULL) && (hObj->dwSignature == SIGNATURE);
6811 + return retVal;
6815 + * ======== InitCodMgr ========
6816 + * Purpose:
6817 + * Create a COD manager for this device.
6818 + * Parameters:
6819 + * pDevObject: Pointer to device object created with
6820 + * DEV_CreateDevice()
6821 + * Returns:
6822 + * DSP_SOK: Success.
6823 + * DSP_EHANDLE: Invalid hDevObject.
6824 + * Requires:
6825 + * Should only be called once by DEV_CreateDevice() for a given DevObject.
6826 + * Ensures:
6827 + */
6828 +static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject)
6830 + DSP_STATUS status = DSP_SOK;
6831 + char *szDummyFile = "dummy";
6833 + DBC_Require(cRefs > 0);
6834 + DBC_Require(!IsValidHandle(pDevObject) ||
6835 + (pDevObject->hCodMgr == NULL));
6836 + GT_1trace(debugMask, GT_ENTER, "Entering InitCodMgr pDevObject: 0x%x",
6837 + pDevObject);
6838 + status = COD_Create(&pDevObject->hCodMgr, szDummyFile, NULL);
6839 + GT_1trace(debugMask, GT_ENTER, "Exiting InitCodMgr status 0x%x\n ",
6840 + status);
6841 + return status;
6845 + * ======== DEV_InsertProcObject ========
6846 + * Purpose:
6847 + * Insert a ProcObject into the list maintained by DEV.
6848 + * Parameters:
6849 + * pProcObject: Ptr to ProcObject to insert.
6850 + * pDevObject: Ptr to Dev Object where the list is.
6851 + * pbAlreadyAttached: Ptr to return the bool
6852 + * Returns:
6853 + * DSP_SOK: If successful.
6854 + * Requires:
6855 + * List Exists
6856 + * hDevObject is Valid handle
6857 + * DEV Initialized
6858 + * pbAlreadyAttached != NULL
6859 + * hProcObject != 0
6860 + * Ensures:
6861 + * DSP_SOK and List is not Empty.
6862 + */
6863 +DSP_STATUS CDECL DEV_InsertProcObject(struct DEV_OBJECT *hDevObject,
6864 + u32 hProcObject,
6865 + OUT bool *pbAlreadyAttached)
6867 + DSP_STATUS status = DSP_SOK;
6868 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject;
6870 + GT_2trace(debugMask, GT_ENTER,
6871 + "Entering DEV_InsetProcObject pProcObject 0x%x"
6872 + "pDevObject 0x%x\n", hProcObject, hDevObject);
6873 + DBC_Require(cRefs > 0);
6874 + DBC_Require(IsValidHandle(pDevObject));
6875 + DBC_Require(hProcObject != 0);
6876 + DBC_Require(pDevObject->procList != NULL);
6877 + DBC_Require(pbAlreadyAttached != NULL);
6878 + if (!LST_IsEmpty(pDevObject->procList))
6879 + *pbAlreadyAttached = true;
6881 + /* Add DevObject to tail. */
6882 + LST_PutTail(pDevObject->procList, (struct LST_ELEM *)hProcObject);
6884 + GT_1trace(debugMask, GT_ENTER,
6885 + "Exiting DEV_InsetProcObject status 0x%x\n", status);
6886 + DBC_Ensure(DSP_SUCCEEDED(status) && !LST_IsEmpty(pDevObject->procList));
6888 + return status;
6892 + * ======== DEV_RemoveProcObject ========
6893 + * Purpose:
6894 + * Search for and remove a Proc object from the given list maintained
6895 + * by the DEV
6896 + * Parameters:
6897 + * pProcObject: Ptr to ProcObject to insert.
6898 + * pDevObject Ptr to Dev Object where the list is.
6899 + * Returns:
6900 + * DSP_SOK: If successful.
6901 + * Requires:
6902 + * List exists and is not empty
6903 + * hProcObject != 0
6904 + * hDevObject is a valid Dev handle.
6905 + * Ensures:
6906 + * Details:
6907 + * List will be deleted when the DEV is destroyed.
6908 + */
6909 +DSP_STATUS CDECL DEV_RemoveProcObject(struct DEV_OBJECT *hDevObject,
6910 + u32 hProcObject)
6912 + DSP_STATUS status = DSP_EFAIL;
6913 + struct LST_ELEM *pCurElem;
6914 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject;
6916 + DBC_Require(IsValidHandle(pDevObject));
6917 + DBC_Require(hProcObject != 0);
6918 + DBC_Require(pDevObject->procList != NULL);
6919 + DBC_Require(!LST_IsEmpty(pDevObject->procList));
6921 + GT_1trace(debugMask, GT_ENTER,
6922 + "Entering DEV_RemoveProcObject hDevObject "
6923 + "0x%x\n", hDevObject);
6924 + /* Search list for pDevObject: */
6925 + for (pCurElem = LST_First(pDevObject->procList); pCurElem != NULL;
6926 + pCurElem = LST_Next(pDevObject->procList, pCurElem)) {
6927 + /* If found, remove it. */
6928 + if ((u32)pCurElem == hProcObject) {
6929 + LST_RemoveElem(pDevObject->procList, pCurElem);
6930 + status = DSP_SOK;
6931 + break;
6934 + GT_1trace(debugMask, GT_ENTER, "DEV_RemoveProcObject returning 0x%x\n",
6935 + status);
6936 + return status;
6939 +DSP_STATUS CDECL DEV_GetDevType(struct DEV_OBJECT *hdevObject, u32 *devType)
6941 + DSP_STATUS status = DSP_SOK;
6942 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hdevObject;
6944 + *devType = pDevObject->devType;
6946 + return status;
6950 + * ======== StoreInterfaceFxns ========
6951 + * Purpose:
6952 + * Copy the WMD's interface functions into the device object,
6953 + * ensuring that FxnNotImplemented() is set for:
6955 + * 1. All WMD function pointers which are NULL; and
6956 + * 2. All function slots in the struct DEV_OBJECT structure which have no
6957 + * corresponding slots in the the WMD's interface, because the WMD
6958 + * is of an *older* version.
6959 + * Parameters:
6960 + * pIntfFxns: Interface Fxn Structure of the WCD's Dev Object.
6961 + * pDrvFxns: Interface Fxns offered by the WMD during DEV_Create().
6962 + * Returns:
6963 + * Requires:
6964 + * Input pointers are valid.
6965 + * WMD is *not* written for a newer WCD.
6966 + * Ensures:
6967 + * All function pointers in the dev object's Fxn interface are not NULL.
6968 + */
6969 +static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns,
6970 + OUT struct WMD_DRV_INTERFACE *pIntfFxns)
6972 + u32 dwWMDVersion;
6974 + /* Local helper macro: */
6975 +#define StoreFxn(cast, pfn) \
6976 + (pIntfFxns->pfn = ((pDrvFxns->pfn != NULL) ? pDrvFxns->pfn : \
6977 + (cast)FxnNotImplemented))
6979 + DBC_Require(pIntfFxns != NULL);
6980 + DBC_Require(pDrvFxns != NULL);
6981 + DBC_Require(MAKEVERSION(pDrvFxns->dwWCDMajorVersion,
6982 + pDrvFxns->dwWCDMinorVersion) <= WCDVERSION);
6983 + dwWMDVersion = MAKEVERSION(pDrvFxns->dwWCDMajorVersion,
6984 + pDrvFxns->dwWCDMinorVersion);
6985 + pIntfFxns->dwWCDMajorVersion = pDrvFxns->dwWCDMajorVersion;
6986 + pIntfFxns->dwWCDMinorVersion = pDrvFxns->dwWCDMinorVersion;
6987 + /* Install functions up to WCD version .80 (first alpha): */
6988 + if (dwWMDVersion > 0) {
6989 + StoreFxn(WMD_DEV_CREATE, pfnDevCreate);
6990 + StoreFxn(WMD_DEV_DESTROY, pfnDevDestroy);
6991 + StoreFxn(WMD_DEV_CTRL, pfnDevCntrl);
6992 + StoreFxn(WMD_BRD_MONITOR, pfnBrdMonitor);
6993 + StoreFxn(WMD_BRD_START, pfnBrdStart);
6994 + StoreFxn(WMD_BRD_STOP, pfnBrdStop);
6995 + StoreFxn(WMD_BRD_STATUS, pfnBrdStatus);
6996 + StoreFxn(WMD_BRD_READ, pfnBrdRead);
6997 + StoreFxn(WMD_BRD_WRITE, pfnBrdWrite);
6998 + StoreFxn(WMD_BRD_SETSTATE, pfnBrdSetState);
6999 + StoreFxn(WMD_BRD_MEMCOPY, pfnBrdMemCopy);
7000 + StoreFxn(WMD_BRD_MEMWRITE, pfnBrdMemWrite);
7001 + StoreFxn(WMD_BRD_MEMMAP, pfnBrdMemMap);
7002 + StoreFxn(WMD_BRD_MEMUNMAP, pfnBrdMemUnMap);
7003 + StoreFxn(WMD_CHNL_CREATE, pfnChnlCreate);
7004 + StoreFxn(WMD_CHNL_DESTROY, pfnChnlDestroy);
7005 + StoreFxn(WMD_CHNL_OPEN, pfnChnlOpen);
7006 + StoreFxn(WMD_CHNL_CLOSE, pfnChnlClose);
7007 + StoreFxn(WMD_CHNL_ADDIOREQ, pfnChnlAddIOReq);
7008 + StoreFxn(WMD_CHNL_GETIOC, pfnChnlGetIOC);
7009 + StoreFxn(WMD_CHNL_CANCELIO, pfnChnlCancelIO);
7010 + StoreFxn(WMD_CHNL_FLUSHIO, pfnChnlFlushIO);
7011 + StoreFxn(WMD_CHNL_GETINFO, pfnChnlGetInfo);
7012 + StoreFxn(WMD_CHNL_GETMGRINFO, pfnChnlGetMgrInfo);
7013 + StoreFxn(WMD_CHNL_IDLE, pfnChnlIdle);
7014 + StoreFxn(WMD_CHNL_REGISTERNOTIFY, pfnChnlRegisterNotify);
7015 + StoreFxn(WMD_DEH_CREATE, pfnDehCreate);
7016 + StoreFxn(WMD_DEH_DESTROY, pfnDehDestroy);
7017 + StoreFxn(WMD_DEH_NOTIFY, pfnDehNotify);
7018 + StoreFxn(WMD_DEH_REGISTERNOTIFY, pfnDehRegisterNotify);
7019 + StoreFxn(WMD_DEH_GETINFO, pfnDehGetInfo);
7020 + StoreFxn(WMD_IO_CREATE, pfnIOCreate);
7021 + StoreFxn(WMD_IO_DESTROY, pfnIODestroy);
7022 + StoreFxn(WMD_IO_ONLOADED, pfnIOOnLoaded);
7023 + StoreFxn(WMD_IO_GETPROCLOAD, pfnIOGetProcLoad);
7024 + StoreFxn(WMD_MSG_CREATE, pfnMsgCreate);
7025 + StoreFxn(WMD_MSG_CREATEQUEUE, pfnMsgCreateQueue);
7026 + StoreFxn(WMD_MSG_DELETE, pfnMsgDelete);
7027 + StoreFxn(WMD_MSG_DELETEQUEUE, pfnMsgDeleteQueue);
7028 + StoreFxn(WMD_MSG_GET, pfnMsgGet);
7029 + StoreFxn(WMD_MSG_PUT, pfnMsgPut);
7030 + StoreFxn(WMD_MSG_REGISTERNOTIFY, pfnMsgRegisterNotify);
7031 + StoreFxn(WMD_MSG_SETQUEUEID, pfnMsgSetQueueId);
7033 + /* Add code for any additional functions in newer WMD versions here: */
7034 + /* Ensure postcondition: */
7035 + DBC_Ensure(pIntfFxns->pfnDevCreate != NULL);
7036 + DBC_Ensure(pIntfFxns->pfnDevDestroy != NULL);
7037 + DBC_Ensure(pIntfFxns->pfnDevCntrl != NULL);
7038 + DBC_Ensure(pIntfFxns->pfnBrdMonitor != NULL);
7039 + DBC_Ensure(pIntfFxns->pfnBrdStart != NULL);
7040 + DBC_Ensure(pIntfFxns->pfnBrdStop != NULL);
7041 + DBC_Ensure(pIntfFxns->pfnBrdStatus != NULL);
7042 + DBC_Ensure(pIntfFxns->pfnBrdRead != NULL);
7043 + DBC_Ensure(pIntfFxns->pfnBrdWrite != NULL);
7044 + DBC_Ensure(pIntfFxns->pfnChnlCreate != NULL);
7045 + DBC_Ensure(pIntfFxns->pfnChnlDestroy != NULL);
7046 + DBC_Ensure(pIntfFxns->pfnChnlOpen != NULL);
7047 + DBC_Ensure(pIntfFxns->pfnChnlClose != NULL);
7048 + DBC_Ensure(pIntfFxns->pfnChnlAddIOReq != NULL);
7049 + DBC_Ensure(pIntfFxns->pfnChnlGetIOC != NULL);
7050 + DBC_Ensure(pIntfFxns->pfnChnlCancelIO != NULL);
7051 + DBC_Ensure(pIntfFxns->pfnChnlFlushIO != NULL);
7052 + DBC_Ensure(pIntfFxns->pfnChnlGetInfo != NULL);
7053 + DBC_Ensure(pIntfFxns->pfnChnlGetMgrInfo != NULL);
7054 + DBC_Ensure(pIntfFxns->pfnChnlIdle != NULL);
7055 + DBC_Ensure(pIntfFxns->pfnChnlRegisterNotify != NULL);
7056 + DBC_Ensure(pIntfFxns->pfnDehCreate != NULL);
7057 + DBC_Ensure(pIntfFxns->pfnDehDestroy != NULL);
7058 + DBC_Ensure(pIntfFxns->pfnDehNotify != NULL);
7059 + DBC_Ensure(pIntfFxns->pfnDehRegisterNotify != NULL);
7060 + DBC_Ensure(pIntfFxns->pfnDehGetInfo != NULL);
7061 + DBC_Ensure(pIntfFxns->pfnIOCreate != NULL);
7062 + DBC_Ensure(pIntfFxns->pfnIODestroy != NULL);
7063 + DBC_Ensure(pIntfFxns->pfnIOOnLoaded != NULL);
7064 + DBC_Ensure(pIntfFxns->pfnIOGetProcLoad != NULL);
7065 + DBC_Ensure(pIntfFxns->pfnMsgSetQueueId != NULL);
7067 +#undef StoreFxn
7070 diff --git a/drivers/dsp/bridge/pmgr/dmm.c b/drivers/dsp/bridge/pmgr/dmm.c
7071 new file mode 100644
7072 index 0000000..a1baed3
7073 --- /dev/null
7074 +++ b/drivers/dsp/bridge/pmgr/dmm.c
7075 @@ -0,0 +1,646 @@
7077 + * linux/drivers/dsp/bridge/pmgr/dmm.c
7079 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
7081 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
7083 + * This package is free software; you can redistribute it and/or modify
7084 + * it under the terms of the GNU General Public License version 2 as
7085 + * published by the Free Software Foundation.
7087 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
7088 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7089 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
7090 + */
7093 + * ======== dmm.c ========
7094 + * Purpose:
7095 + * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
7096 + * space that can be directly mapped to any MPU buffer or memory region
7098 + * Public Functions:
7099 + * DMM_CreateTables
7100 + * DMM_Create
7101 + * DMM_Destroy
7102 + * DMM_Exit
7103 + * DMM_Init
7104 + * DMM_MapMemory
7105 + * DMM_Reset
7106 + * DMM_ReserveMemory
7107 + * DMM_UnMapMemory
7108 + * DMM_UnReserveMemory
7110 + * Private Functions:
7111 + * AddRegion
7112 + * CreateRegion
7113 + * GetRegion
7114 + * GetFreeRegion
7115 + * GetMappedRegion
7117 + * Notes:
7118 + * Region: Generic memory entitiy having a start address and a size
7119 + * Chunk: Reserved region
7122 + *! Revision History:
7123 + *! ================
7124 + *! 04-Jun-2008 Hari K : Optimized DMM implementation. Removed linked list
7125 + *! and instead used Table approach.
7126 + *! 19-Apr-2004 sb: Integrated Alan's code review updates.
7127 + *! 17-Mar-2004 ap: Fixed GetRegion for size=0 using tighter bound.
7128 + *! 20-Feb-2004 sb: Created.
7129 + *!
7130 + */
7132 +/* ----------------------------------- Host OS */
7133 +#include <host_os.h>
7135 +/* ----------------------------------- DSP/BIOS Bridge */
7136 +#include <std.h>
7137 +#include <dbdefs.h>
7139 +/* ----------------------------------- Trace & Debug */
7140 +#include <dbc.h>
7141 +#include <errbase.h>
7142 +#include <gt.h>
7144 +/* ----------------------------------- OS Adaptation Layer */
7145 +#include <list.h>
7146 +#include <mem.h>
7147 +#include <sync.h>
7149 +/* ----------------------------------- Platform Manager */
7150 +#include <dev.h>
7151 +#include <proc.h>
7153 +/* ----------------------------------- This */
7154 +#include <dmm.h>
7156 +/* ----------------------------------- Defines, Data Structures, Typedefs */
7157 +/* Object signatures */
7158 +#define DMMSIGNATURE 0x004d4d44 /* "DMM" (in reverse) */
7160 +#define DMM_ADDR_VIRTUAL(a) \
7161 + (((struct MapPage *)(a) - pVirtualMappingTable) * PG_SIZE_4K +\
7162 + dynMemMapBeg)
7163 +#define DMM_ADDR_TO_INDEX(a) (((a) - dynMemMapBeg) / PG_SIZE_4K)
7165 +/* DMM Mgr */
7166 +struct DMM_OBJECT {
7167 + u32 dwSignature; /* Used for object validation */
7168 + /* Dmm Lock is used to serialize access mem manager for
7169 + * multi-threads. */
7170 + struct SYNC_CSOBJECT *hDmmLock; /* Lock to access dmm mgr */
7174 +/* ----------------------------------- Globals */
7175 +#if GT_TRACE
7176 +static struct GT_Mask DMM_debugMask = { NULL, NULL }; /* GT trace variable */
7177 +#endif
7179 +static u32 cRefs; /* module reference count */
7180 +struct MapPage {
7181 + u32 RegionSize:15;
7182 + u32 MappedSize:15;
7183 + u32 bReserved:1;
7184 + u32 bMapped:1;
7187 +/* Create the free list */
7188 +static struct MapPage *pVirtualMappingTable;
7189 +static u32 iFreeRegion; /* The index of free region */
7190 +static u32 iFreeSize;
7191 +static u32 *pPhysicalAddrTable; /* Physical address of MPU buffer */
7192 +static u32 dynMemMapBeg; /* The Beginning of dynamic memory mapping */
7193 +static u32 TableSize;/* The size of virtual and physical pages tables */
7195 +/* ----------------------------------- Function Prototypes */
7196 +static struct MapPage *GetRegion(u32 addr);
7197 +static struct MapPage *GetFreeRegion(u32 aSize);
7198 +static struct MapPage *GetMappedRegion(u32 aAddr);
7200 +/* ======== DMM_CreateTables ========
7201 + * Purpose:
7202 + * Create table to hold the information of physical address
7203 + * the buffer pages that is passed by the user, and the table
7204 + * to hold the information of the virtual memory that is reserved
7205 + * for DSP.
7206 + */
7207 +DSP_STATUS DMM_CreateTables(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size)
7209 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7210 + DSP_STATUS status = DSP_SOK;
7212 + GT_3trace(DMM_debugMask, GT_ENTER,
7213 + "Entered DMM_CreateTables () hDmmMgr %x, addr"
7214 + " %x, size %x\n", hDmmMgr, addr, size);
7215 + status = DMM_DeleteTables(pDmmObj);
7216 + if (DSP_SUCCEEDED(status)) {
7217 + SYNC_EnterCS(pDmmObj->hDmmLock);
7218 + dynMemMapBeg = addr;
7219 + TableSize = (size/PG_SIZE_4K) + 1;
7220 + /* Create the free list */
7221 + pVirtualMappingTable = (struct MapPage *) MEM_Calloc
7222 + (TableSize*sizeof(struct MapPage), MEM_NONPAGED);
7223 + if (pVirtualMappingTable == NULL)
7224 + status = DSP_EMEMORY;
7225 + else {
7226 + /* This table will be used
7227 + * to store the virtual to physical
7228 + * address translations
7229 + */
7230 + pPhysicalAddrTable = (u32 *)MEM_Calloc
7231 + (TableSize*sizeof(u32), MEM_NONPAGED);
7232 + GT_1trace(DMM_debugMask, GT_4CLASS,
7233 + "DMM_CreateTables: Allocate"
7234 + "memory for pPhysicalAddrTable=%d entries\n",
7235 + TableSize);
7236 + if (pPhysicalAddrTable == NULL) {
7237 + status = DSP_EMEMORY;
7238 + GT_0trace(DMM_debugMask, GT_7CLASS,
7239 + "DMM_CreateTables: Memory allocation for "
7240 + "pPhysicalAddrTable failed\n");
7241 + } else {
7242 + /* On successful allocation,
7243 + * all entries are zero ('free') */
7244 + iFreeRegion = 0;
7245 + iFreeSize = TableSize*PG_SIZE_4K;
7246 + pVirtualMappingTable[0].RegionSize = TableSize;
7249 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7250 + } else
7251 + GT_0trace(DMM_debugMask, GT_7CLASS,
7252 + "DMM_CreateTables: DMM_DeleteTables"
7253 + "Failure\n");
7255 + GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_CreateTables status"
7256 + "0x%x\n", status);
7257 + return status;
7261 + * ======== DMM_Create ========
7262 + * Purpose:
7263 + * Create a dynamic memory manager object.
7264 + */
7265 +DSP_STATUS DMM_Create(OUT struct DMM_OBJECT **phDmmMgr,
7266 + struct DEV_OBJECT *hDevObject,
7267 + IN CONST struct DMM_MGRATTRS *pMgrAttrs)
7269 + struct DMM_OBJECT *pDmmObject = NULL;
7270 + DSP_STATUS status = DSP_SOK;
7271 + DBC_Require(cRefs > 0);
7272 + DBC_Require(phDmmMgr != NULL);
7274 + GT_3trace(DMM_debugMask, GT_ENTER,
7275 + "DMM_Create: phDmmMgr: 0x%x hDevObject: "
7276 + "0x%x pMgrAttrs: 0x%x\n", phDmmMgr, hDevObject, pMgrAttrs);
7277 + *phDmmMgr = NULL;
7278 + /* create, zero, and tag a cmm mgr object */
7279 + MEM_AllocObject(pDmmObject, struct DMM_OBJECT, DMMSIGNATURE);
7280 + if (pDmmObject != NULL) {
7281 + status = SYNC_InitializeCS(&pDmmObject->hDmmLock);
7282 + if (DSP_SUCCEEDED(status))
7283 + *phDmmMgr = pDmmObject;
7284 + else
7285 + DMM_Destroy(pDmmObject);
7286 + } else {
7287 + GT_0trace(DMM_debugMask, GT_7CLASS,
7288 + "DMM_Create: Object Allocation "
7289 + "Failure(DMM Object)\n");
7290 + status = DSP_EMEMORY;
7292 + GT_2trace(DMM_debugMask, GT_4CLASS,
7293 + "Leaving DMM_Create status %x pDmmObject %x\n",
7294 + status, pDmmObject);
7296 + return status;
7300 + * ======== DMM_Destroy ========
7301 + * Purpose:
7302 + * Release the communication memory manager resources.
7303 + */
7304 +DSP_STATUS DMM_Destroy(struct DMM_OBJECT *hDmmMgr)
7306 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7307 + DSP_STATUS status = DSP_SOK;
7309 + GT_1trace(DMM_debugMask, GT_ENTER,
7310 + "Entered DMM_Destroy () hDmmMgr %x\n", hDmmMgr);
7311 + DBC_Require(cRefs > 0);
7312 + if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) {
7313 + status = DMM_DeleteTables(pDmmObj);
7314 + if (DSP_SUCCEEDED(status)) {
7315 + /* Delete CS & dmm mgr object */
7316 + SYNC_DeleteCS(pDmmObj->hDmmLock);
7317 + MEM_FreeObject(pDmmObj);
7318 + } else
7319 + GT_0trace(DMM_debugMask, GT_7CLASS,
7320 + "DMM_Destroy: DMM_DeleteTables "
7321 + "Failure\n");
7322 + } else
7323 + status = DSP_EHANDLE;
7324 + GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_Destroy status %x\n",
7325 + status);
7326 + return status;
7331 + * ======== DMM_DeleteTables ========
7332 + * Purpose:
7333 + * Delete DMM Tables.
7334 + */
7335 +DSP_STATUS DMM_DeleteTables(struct DMM_OBJECT *hDmmMgr)
7337 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7338 + DSP_STATUS status = DSP_SOK;
7340 + GT_1trace(DMM_debugMask, GT_ENTER,
7341 + "Entered DMM_DeleteTables () hDmmMgr %x\n", hDmmMgr);
7342 + DBC_Require(cRefs > 0);
7343 + if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) {
7344 + /* Delete all DMM tables */
7345 + SYNC_EnterCS(pDmmObj->hDmmLock);
7347 + if (pVirtualMappingTable != NULL)
7348 + MEM_Free(pVirtualMappingTable);
7350 + if (pPhysicalAddrTable != NULL)
7351 + MEM_Free(pPhysicalAddrTable);
7353 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7354 + } else
7355 + status = DSP_EHANDLE;
7356 + GT_1trace(DMM_debugMask, GT_4CLASS,
7357 + "Leaving DMM_DeleteTables status %x\n", status);
7358 + return status;
7365 + * ======== DMM_Exit ========
7366 + * Purpose:
7367 + * Discontinue usage of module; free resources when reference count
7368 + * reaches 0.
7369 + */
7370 +void DMM_Exit(void)
7372 + DBC_Require(cRefs > 0);
7374 + cRefs--;
7376 + GT_1trace(DMM_debugMask, GT_ENTER,
7377 + "exiting DMM_Exit, ref count:0x%x\n", cRefs);
7381 + * ======== DMM_GetHandle ========
7382 + * Purpose:
7383 + * Return the dynamic memory manager object for this device.
7384 + * This is typically called from the client process.
7385 + */
7386 +DSP_STATUS DMM_GetHandle(DSP_HPROCESSOR hProcessor,
7387 + OUT struct DMM_OBJECT **phDmmMgr)
7389 + DSP_STATUS status = DSP_SOK;
7390 + struct DEV_OBJECT *hDevObject;
7392 + GT_2trace(DMM_debugMask, GT_ENTER,
7393 + "DMM_GetHandle: hProcessor %x, phDmmMgr"
7394 + "%x\n", hProcessor, phDmmMgr);
7395 + DBC_Require(cRefs > 0);
7396 + DBC_Require(phDmmMgr != NULL);
7397 + if (hProcessor != NULL)
7398 + status = PROC_GetDevObject(hProcessor, &hDevObject);
7399 + else
7400 + hDevObject = DEV_GetFirst(); /* default */
7402 + if (DSP_SUCCEEDED(status))
7403 + status = DEV_GetDmmMgr(hDevObject, phDmmMgr);
7405 + GT_2trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_GetHandle status %x, "
7406 + "*phDmmMgr %x\n", status, phDmmMgr ? *phDmmMgr : 0);
7407 + return status;
7411 + * ======== DMM_Init ========
7412 + * Purpose:
7413 + * Initializes private state of DMM module.
7414 + */
7415 +bool DMM_Init(void)
7417 + bool fRetval = true;
7419 + DBC_Require(cRefs >= 0);
7421 + if (cRefs == 0) {
7422 + /* Set the Trace mask */
7423 + /*"DM" for Dymanic Memory Manager */
7424 + GT_create(&DMM_debugMask, "DM");
7427 + if (fRetval)
7428 + cRefs++;
7430 + GT_1trace(DMM_debugMask, GT_ENTER,
7431 + "Entered DMM_Init, ref count:0x%x\n", cRefs);
7433 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
7435 + pVirtualMappingTable = NULL ;
7436 + pPhysicalAddrTable = NULL ;
7437 + TableSize = 0;
7439 + return fRetval;
7443 + * ======== DMM_MapMemory ========
7444 + * Purpose:
7445 + * Add a mapping block to the reserved chunk. DMM assumes that this block
7446 + * will be mapped in the DSP/IVA's address space. DMM returns an error if a
7447 + * mapping overlaps another one. This function stores the info that will be
7448 + * required later while unmapping the block.
7449 + */
7450 +DSP_STATUS DMM_MapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size)
7452 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7453 + struct MapPage *chunk;
7454 + DSP_STATUS status = DSP_SOK;
7456 + GT_3trace(DMM_debugMask, GT_ENTER,
7457 + "Entered DMM_MapMemory () hDmmMgr %x, "
7458 + "addr %x, size %x\n", hDmmMgr, addr, size);
7459 + SYNC_EnterCS(pDmmObj->hDmmLock);
7460 + /* Find the Reserved memory chunk containing the DSP block to
7461 + * be mapped */
7462 + chunk = (struct MapPage *)GetRegion(addr);
7463 + if (chunk != NULL) {
7464 + /* Mark the region 'mapped', leave the 'reserved' info as-is */
7465 + chunk->bMapped = true;
7466 + chunk->MappedSize = (size/PG_SIZE_4K);
7467 + } else
7468 + status = DSP_ENOTFOUND;
7469 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7470 + GT_2trace(DMM_debugMask, GT_4CLASS,
7471 + "Leaving DMM_MapMemory status %x, chunk %x\n",
7472 + status, chunk);
7473 + return status;
7477 + * ======== DMM_ReserveMemory ========
7478 + * Purpose:
7479 + * Reserve a chunk of virtually contiguous DSP/IVA address space.
7480 + */
7481 +DSP_STATUS DMM_ReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 size,
7482 + u32 *pRsvAddr)
7484 + DSP_STATUS status = DSP_SOK;
7485 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7486 + struct MapPage *node;
7487 + u32 rsvAddr = 0;
7488 + u32 rsvSize = 0;
7490 + GT_3trace(DMM_debugMask, GT_ENTER,
7491 + "Entered DMM_ReserveMemory () hDmmMgr %x, "
7492 + "size %x, pRsvAddr %x\n", hDmmMgr, size, pRsvAddr);
7493 + SYNC_EnterCS(pDmmObj->hDmmLock);
7495 + /* Try to get a DSP chunk from the free list */
7496 + node = GetFreeRegion(size);
7497 + if (node != NULL) {
7498 + /* DSP chunk of given size is available. */
7499 + rsvAddr = DMM_ADDR_VIRTUAL(node);
7500 + /* Calculate the number entries to use */
7501 + rsvSize = size/PG_SIZE_4K;
7502 + if (rsvSize < node->RegionSize) {
7503 + /* Mark remainder of free region */
7504 + node[rsvSize].bMapped = false;
7505 + node[rsvSize].bReserved = false;
7506 + node[rsvSize].RegionSize = node->RegionSize - rsvSize;
7507 + node[rsvSize].MappedSize = 0;
7509 + /* GetRegion will return first fit chunk. But we only use what
7510 + is requested. */
7511 + node->bMapped = false;
7512 + node->bReserved = true;
7513 + node->RegionSize = rsvSize;
7514 + node->MappedSize = 0;
7515 + /* Return the chunk's starting address */
7516 + *pRsvAddr = rsvAddr;
7517 + } else
7518 + /*dSP chunk of given size is not available */
7519 + status = DSP_EMEMORY;
7521 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7522 + GT_3trace(DMM_debugMask, GT_4CLASS,
7523 + "Leaving ReserveMemory status %x, rsvAddr"
7524 + " %x, rsvSize %x\n", status, rsvAddr, rsvSize);
7525 + return status;
7530 + * ======== DMM_UnMapMemory ========
7531 + * Purpose:
7532 + * Remove the mapped block from the reserved chunk.
7533 + */
7534 +DSP_STATUS DMM_UnMapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 *pSize)
7536 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7537 + struct MapPage *chunk;
7538 + DSP_STATUS status = DSP_SOK;
7540 + GT_3trace(DMM_debugMask, GT_ENTER,
7541 + "Entered DMM_UnMapMemory () hDmmMgr %x, "
7542 + "addr %x, pSize %x\n", hDmmMgr, addr, pSize);
7543 + SYNC_EnterCS(pDmmObj->hDmmLock);
7544 + chunk = GetMappedRegion(addr) ;
7545 + if (chunk == NULL)
7546 + status = DSP_ENOTFOUND ;
7548 + if (DSP_SUCCEEDED(status)) {
7549 + /* Unmap the region */
7550 + *pSize = chunk->MappedSize * PG_SIZE_4K;
7551 + chunk->bMapped = false;
7552 + chunk->MappedSize = 0;
7554 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7555 + GT_3trace(DMM_debugMask, GT_ENTER,
7556 + "Leaving DMM_UnMapMemory status %x, chunk"
7557 + " %x, *pSize %x\n", status, chunk, *pSize);
7559 + return status;
7563 + * ======== DMM_UnReserveMemory ========
7564 + * Purpose:
7565 + * Free a chunk of reserved DSP/IVA address space.
7566 + */
7567 +DSP_STATUS DMM_UnReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 rsvAddr)
7569 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7570 + struct MapPage *chunk;
7571 + u32 i;
7572 + DSP_STATUS status = DSP_SOK;
7573 + u32 chunkSize;
7575 + GT_2trace(DMM_debugMask, GT_ENTER,
7576 + "Entered DMM_UnReserveMemory () hDmmMgr "
7577 + "%x, rsvAddr %x\n", hDmmMgr, rsvAddr);
7579 + SYNC_EnterCS(pDmmObj->hDmmLock);
7581 + /* Find the chunk containing the reserved address */
7582 + chunk = GetMappedRegion(rsvAddr);
7583 + if (chunk == NULL)
7584 + status = DSP_ENOTFOUND;
7586 + if (DSP_SUCCEEDED(status)) {
7587 + /* Free all the mapped pages for this reserved region */
7588 + i = 0;
7589 + while (i < chunk->RegionSize) {
7590 + if (chunk[i].bMapped) {
7591 + /* Remove mapping from the page tables. */
7592 + chunkSize = chunk[i].MappedSize;
7593 + /* Clear the mapping flags */
7594 + chunk[i].bMapped = false;
7595 + chunk[i].MappedSize = 0;
7596 + i += chunkSize;
7597 + } else
7598 + i++;
7600 + /* Clear the flags (mark the region 'free') */
7601 + chunk->bReserved = false;
7602 + /* NOTE: We do NOT coalesce free regions here.
7603 + * Free regions are coalesced in GetRegion(), as it traverses
7604 + *the whole mapping table
7605 + */
7607 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7608 + GT_2trace(DMM_debugMask, GT_ENTER,
7609 + "Leaving DMM_UnReserveMemory status %x"
7610 + " chunk %x\n", status, chunk);
7611 + return status;
7616 + * ======== GetRegion ========
7617 + * Purpose:
7618 + * Returns a region containing the specified memory region
7619 + */
7620 +struct MapPage *GetRegion(u32 aAddr)
7622 + struct MapPage *currRegion = NULL;
7623 + u32 i = 0;
7625 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetRegion () "
7626 + " aAddr %x\n", aAddr);
7628 + if (pVirtualMappingTable != NULL) {
7629 + /* find page mapped by this address */
7630 + i = DMM_ADDR_TO_INDEX(aAddr);
7631 + if (i < TableSize)
7632 + currRegion = pVirtualMappingTable + i;
7634 + GT_3trace(DMM_debugMask, GT_4CLASS,
7635 + "Leaving GetRegion currRegion %x, iFreeRegion %d\n,"
7636 + "iFreeSize %d\n", currRegion, iFreeRegion, iFreeSize) ;
7637 + return currRegion;
7641 + * ======== GetFreeRegion ========
7642 + * Purpose:
7643 + * Returns the requested free region
7644 + */
7645 +struct MapPage *GetFreeRegion(u32 aSize)
7647 + struct MapPage *currRegion = NULL;
7648 + u32 i = 0;
7649 + u32 RegionSize = 0;
7650 + u32 nextI = 0;
7651 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetFreeRegion () "
7652 + "aSize 0x%x\n", aSize);
7654 + if (pVirtualMappingTable == NULL)
7655 + return currRegion;
7656 + if (aSize > iFreeSize) {
7657 + /* Find the largest free region
7658 + * (coalesce during the traversal) */
7659 + while (i < TableSize) {
7660 + RegionSize = pVirtualMappingTable[i].RegionSize;
7661 + nextI = i+RegionSize;
7662 + if (pVirtualMappingTable[i].bReserved == false) {
7663 + /* Coalesce, if possible */
7664 + if (nextI < TableSize &&
7665 + pVirtualMappingTable[nextI].bReserved
7666 + == false) {
7667 + pVirtualMappingTable[i].RegionSize +=
7668 + pVirtualMappingTable[nextI].RegionSize;
7669 + continue;
7671 + RegionSize *= PG_SIZE_4K;
7672 + if (RegionSize > iFreeSize) {
7673 + iFreeRegion = i;
7674 + iFreeSize = RegionSize;
7677 + i = nextI;
7680 + if (aSize <= iFreeSize) {
7681 + currRegion = pVirtualMappingTable + iFreeRegion;
7682 + iFreeRegion += (aSize / PG_SIZE_4K);
7683 + iFreeSize -= aSize;
7685 + return currRegion;
7689 + * ======== GetMappedRegion ========
7690 + * Purpose:
7691 + * Returns the requestedmapped region
7692 + */
7693 +struct MapPage *GetMappedRegion(u32 aAddr)
7695 + u32 i = 0;
7696 + struct MapPage *currRegion = NULL;
7697 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetMappedRegion () "
7698 + "aAddr 0x%x\n", aAddr);
7700 + if (pVirtualMappingTable == NULL)
7701 + return currRegion;
7703 + i = DMM_ADDR_TO_INDEX(aAddr);
7704 + if (i < TableSize && (pVirtualMappingTable[i].bMapped ||
7705 + pVirtualMappingTable[i].bReserved))
7706 + currRegion = pVirtualMappingTable + i;
7707 + return currRegion;
7711 + * ======== DMM_GetPhysicalAddrTable ========
7712 + * Purpose:
7713 + * Returns the physical table address
7714 + */
7715 +u32 *DMM_GetPhysicalAddrTable(void)
7717 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered "
7718 + "DMM_GetPhysicalAddrTable()- pPhysicalAddrTable 0x%x\n",
7719 + pPhysicalAddrTable);
7720 + return pPhysicalAddrTable;
7722 diff --git a/drivers/dsp/bridge/pmgr/io.c b/drivers/dsp/bridge/pmgr/io.c
7723 new file mode 100644
7724 index 0000000..5b32210
7725 --- /dev/null
7726 +++ b/drivers/dsp/bridge/pmgr/io.c
7727 @@ -0,0 +1,204 @@
7729 + * linux/drivers/dsp/bridge/pmgr/io.c
7731 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
7733 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
7735 + * This package is free software; you can redistribute it and/or modify
7736 + * it under the terms of the GNU General Public License version 2 as
7737 + * published by the Free Software Foundation.
7739 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
7740 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7741 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
7742 + */
7746 + * ======== io.c ========
7747 + * Description:
7748 + * IO manager interface: Manages IO between CHNL and MSG.
7750 + * Public Functions:
7751 + * IO_Create
7752 + * IO_Destroy
7753 + * IO_Exit
7754 + * IO_Init
7755 + * IO_OnLoaded
7757 + * Notes:
7758 + * This interface is basically a pass through to the WMD IO functions.
7760 + *! Revision History:
7761 + *! ================
7762 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
7763 + *! 04-Apr-2001 rr WSX_STATUS initialized in IO_Create.
7764 + *! 07-Nov-2000 jeh Created.
7765 + */
7767 +/* ----------------------------------- Host OS */
7768 +#include <host_os.h>
7770 +/* ----------------------------------- DSP/BIOS Bridge */
7771 +#include <std.h>
7772 +#include <dbdefs.h>
7773 +#include <errbase.h>
7775 +/* ----------------------------------- Trace & Debug */
7776 +#include <dbc.h>
7777 +#include <gt.h>
7779 +/* ----------------------------------- OS Adaptation Layer */
7780 +#include <cfg.h>
7781 +#include <mem.h>
7783 +/* ----------------------------------- Platform Manager */
7784 +#include <dev.h>
7786 +/* ----------------------------------- This */
7787 +#include <ioobj.h>
7788 +#include <iodefs.h>
7790 +/* ----------------------------------- Globals */
7791 +static u32 cRefs;
7793 +#if GT_TRACE
7794 +static struct GT_Mask IO_DebugMask = { NULL, NULL }; /* WCD IO Mask */
7795 +#endif
7798 + * ======== IO_Create ========
7799 + * Purpose:
7800 + * Create an IO manager object, responsible for managing IO between
7801 + * CHNL and MSG
7802 + */
7803 +DSP_STATUS IO_Create(OUT struct IO_MGR **phIOMgr, struct DEV_OBJECT *hDevObject,
7804 + IN CONST struct IO_ATTRS *pMgrAttrs)
7806 + struct WMD_DRV_INTERFACE *pIntfFxns;
7807 + struct IO_MGR *hIOMgr = NULL;
7808 + struct IO_MGR_ *pIOMgr = NULL;
7809 + DSP_STATUS status = DSP_SOK;
7811 + DBC_Require(cRefs > 0);
7812 + DBC_Require(phIOMgr != NULL);
7813 + DBC_Require(pMgrAttrs != NULL);
7815 + GT_3trace(IO_DebugMask, GT_ENTER, "Entered IO_Create: phIOMgr: 0x%x\t "
7816 + "hDevObject: 0x%x\tpMgrAttrs: 0x%x\n",
7817 + phIOMgr, hDevObject, pMgrAttrs);
7819 + *phIOMgr = NULL;
7821 + /* A memory base of 0 implies no memory base: */
7822 + if ((pMgrAttrs->dwSMBase != 0) && (pMgrAttrs->uSMLength == 0)) {
7823 + status = CHNL_E_INVALIDMEMBASE;
7824 + GT_0trace(IO_DebugMask, GT_7CLASS,
7825 + "IO_Create:Invalid Mem Base\n");
7828 + if (pMgrAttrs->uWordSize == 0) {
7829 + status = CHNL_E_INVALIDWORDSIZE;
7830 + GT_0trace(IO_DebugMask, GT_7CLASS,
7831 + "IO_Create:Invalid Word size\n");
7834 + if (DSP_SUCCEEDED(status)) {
7835 + DEV_GetIntfFxns(hDevObject, &pIntfFxns);
7837 + /* Let WMD channel module finish the create: */
7838 + status = (*pIntfFxns->pfnIOCreate)(&hIOMgr, hDevObject,
7839 + pMgrAttrs);
7841 + if (DSP_SUCCEEDED(status)) {
7842 + pIOMgr = (struct IO_MGR_ *) hIOMgr;
7843 + pIOMgr->pIntfFxns = pIntfFxns;
7844 + pIOMgr->hDevObject = hDevObject;
7846 + /* Return the new channel manager handle: */
7847 + *phIOMgr = hIOMgr;
7848 + GT_1trace(IO_DebugMask, GT_1CLASS,
7849 + "IO_Create: Success hIOMgr: 0x%x\n",
7850 + hIOMgr);
7854 + GT_2trace(IO_DebugMask, GT_ENTER,
7855 + "Exiting IO_Create: hIOMgr: 0x%x, status:"
7856 + " 0x%x\n", hIOMgr, status);
7858 + return status;
7862 + * ======== IO_Destroy ========
7863 + * Purpose:
7864 + * Delete IO manager.
7865 + */
7866 +DSP_STATUS IO_Destroy(struct IO_MGR *hIOMgr)
7868 + struct WMD_DRV_INTERFACE *pIntfFxns;
7869 + struct IO_MGR_ *pIOMgr = (struct IO_MGR_ *)hIOMgr;
7870 + DSP_STATUS status;
7872 + DBC_Require(cRefs > 0);
7874 + GT_1trace(IO_DebugMask, GT_ENTER, "Entered IO_Destroy: hIOMgr: 0x%x\n",
7875 + hIOMgr);
7877 + pIntfFxns = pIOMgr->pIntfFxns;
7879 + /* Let WMD channel module destroy the IO_MGR: */
7880 + status = (*pIntfFxns->pfnIODestroy) (hIOMgr);
7882 + GT_2trace(IO_DebugMask, GT_ENTER,
7883 + "Exiting IO_Destroy: pIOMgr: 0x%x, status:"
7884 + " 0x%x\n", pIOMgr, status);
7885 + return status;
7889 + * ======== IO_Exit ========
7890 + * Purpose:
7891 + * Discontinue usage of the IO module.
7892 + */
7893 +void IO_Exit(void)
7895 + DBC_Require(cRefs > 0);
7897 + cRefs--;
7899 + GT_1trace(IO_DebugMask, GT_5CLASS,
7900 + "Entered IO_Exit, ref count: 0x%x\n", cRefs);
7902 + DBC_Ensure(cRefs >= 0);
7906 + * ======== IO_Init ========
7907 + * Purpose:
7908 + * Initialize the IO module's private state.
7909 + */
7910 +bool IO_Init(void)
7912 + bool fRetval = true;
7914 + DBC_Require(cRefs >= 0);
7916 + if (cRefs == 0) {
7917 + DBC_Assert(!IO_DebugMask.flags);
7918 + GT_create(&IO_DebugMask, "IO"); /* "IO" for IO */
7921 + if (fRetval)
7922 + cRefs++;
7925 + GT_1trace(IO_DebugMask, GT_5CLASS,
7926 + "Entered IO_Init, ref count: 0x%x\n", cRefs);
7928 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
7930 + return fRetval;
7932 diff --git a/drivers/dsp/bridge/pmgr/ioobj.h b/drivers/dsp/bridge/pmgr/ioobj.h
7933 new file mode 100644
7934 index 0000000..9dc4ac1
7935 --- /dev/null
7936 +++ b/drivers/dsp/bridge/pmgr/ioobj.h
7937 @@ -0,0 +1,52 @@
7939 + * linux/drivers/dsp/bridge/pmgr/ioobj.h
7941 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
7943 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
7945 + * This package is free software; you can redistribute it and/or modify
7946 + * it under the terms of the GNU General Public License version 2 as
7947 + * published by the Free Software Foundation.
7949 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
7950 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7951 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
7952 + */
7956 + * ======== ioobj.h ========
7957 + * Description:
7958 + * Structure subcomponents of channel class library IO objects which
7959 + * are exposed to class driver from mini-driver.
7961 + * Public Functions:
7962 + * None.
7964 + *! Revision History:
7965 + *! ================
7966 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
7967 + *! 01/16/97 gp: Created from chnlpriv.h
7968 + */
7970 +#ifndef IOOBJ_
7971 +#define IOOBJ_
7973 +#include <devdefs.h>
7974 +#include <wmd.h>
7977 + * This struct is the first field in a IO_MGR struct, as implemented in
7978 + * a WMD channel class library. Other, implementation specific fields
7979 + * follow this structure in memory.
7980 + */
7981 +struct IO_MGR_ {
7982 + /* These must be the first fields in a IO_MGR struct: */
7983 + u32 dwSignature; /* Used for object validation. */
7984 + struct WMD_DEV_CONTEXT *hWmdContext; /* WMD device context. */
7985 + struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */
7986 + struct DEV_OBJECT *hDevObject; /* Device this board represents. */
7987 +} ;
7989 +#endif /* IOOBJ_ */
7990 diff --git a/drivers/dsp/bridge/pmgr/msg.c b/drivers/dsp/bridge/pmgr/msg.c
7991 new file mode 100644
7992 index 0000000..56f28c1
7993 --- /dev/null
7994 +++ b/drivers/dsp/bridge/pmgr/msg.c
7995 @@ -0,0 +1,173 @@
7997 + * linux/drivers/dsp/bridge/pmgr/msg.c
7999 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
8001 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
8003 + * This package is free software; you can redistribute it and/or modify
8004 + * it under the terms of the GNU General Public License version 2 as
8005 + * published by the Free Software Foundation.
8007 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
8008 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
8009 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8010 + */
8014 + * ======== msg.c ========
8015 + * Description:
8016 + * DSP/BIOS Bridge MSG Module.
8018 + * Public Functions:
8019 + * MSG_Create
8020 + * MSG_Delete
8021 + * MSG_Exit
8022 + * MSG_Init
8024 + *! Revision History:
8025 + *! =================
8026 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
8027 + *! 15-May-2001 ag Changed SUCCEEDED to DSP_SUCCEEDED.
8028 + *! 16-Feb-2001 jeh Fixed some comments.
8029 + *! 15-Dec-2000 rr MSG_Create returns DSP_EFAIL if pfnMsgCreate fails.
8030 + *! 12-Sep-2000 jeh Created.
8031 + */
8033 +/* ----------------------------------- Host OS */
8034 +#include <host_os.h>
8036 +/* ----------------------------------- DSP/BIOS Bridge */
8037 +#include <std.h>
8038 +#include <dbdefs.h>
8039 +#include <errbase.h>
8041 +/* ----------------------------------- Trace & Debug */
8042 +#include <dbc.h>
8043 +#include <gt.h>
8045 +/* ----------------------------------- OS Adaptation Layer */
8046 +#include <list.h>
8047 +#include <mem.h>
8049 +/* ----------------------------------- Mini Driver */
8050 +#include <wmd.h>
8052 +/* ----------------------------------- Platform Manager */
8053 +#include <dev.h>
8055 +/* ----------------------------------- This */
8056 +#include <msgobj.h>
8057 +#include <msg.h>
8059 +/* ----------------------------------- Globals */
8060 +#if GT_TRACE
8061 +static struct GT_Mask MSG_debugMask = { NULL, NULL }; /* GT trace variable */
8062 +#endif
8063 +static u32 cRefs; /* module reference count */
8066 + * ======== MSG_Create ========
8067 + * Purpose:
8068 + * Create an object to manage message queues. Only one of these objects
8069 + * can exist per device object.
8070 + */
8071 +DSP_STATUS MSG_Create(OUT struct MSG_MGR **phMsgMgr,
8072 + struct DEV_OBJECT *hDevObject, MSG_ONEXIT msgCallback)
8074 + struct WMD_DRV_INTERFACE *pIntfFxns;
8075 + struct MSG_MGR_ *pMsgMgr;
8076 + struct MSG_MGR *hMsgMgr;
8077 + DSP_STATUS status = DSP_SOK;
8079 + DBC_Require(cRefs > 0);
8080 + DBC_Require(phMsgMgr != NULL);
8081 + DBC_Require(msgCallback != NULL);
8082 + DBC_Require(hDevObject != NULL);
8084 + GT_3trace(MSG_debugMask, GT_ENTER, "MSG_Create: phMsgMgr: 0x%x\t"
8085 + "hDevObject: 0x%x\tmsgCallback: 0x%x\n",
8086 + phMsgMgr, hDevObject, msgCallback);
8088 + *phMsgMgr = NULL;
8090 + DEV_GetIntfFxns(hDevObject, &pIntfFxns);
8092 + /* Let WMD message module finish the create: */
8093 + status = (*pIntfFxns->pfnMsgCreate)(&hMsgMgr, hDevObject, msgCallback);
8095 + if (DSP_SUCCEEDED(status)) {
8096 + /* Fill in WCD message module's fields of the MSG_MGR
8097 + * structure */
8098 + pMsgMgr = (struct MSG_MGR_ *)hMsgMgr;
8099 + pMsgMgr->pIntfFxns = pIntfFxns;
8101 + /* Finally, return the new message manager handle: */
8102 + *phMsgMgr = hMsgMgr;
8103 + GT_1trace(MSG_debugMask, GT_1CLASS,
8104 + "MSG_Create: Success pMsgMgr: 0x%x\n", pMsgMgr);
8105 + } else {
8106 + status = DSP_EFAIL;
8108 + return status;
8112 + * ======== MSG_Delete ========
8113 + * Purpose:
8114 + * Delete a MSG manager allocated in MSG_Create().
8115 + */
8116 +void MSG_Delete(struct MSG_MGR *hMsgMgr)
8118 + struct MSG_MGR_ *pMsgMgr = (struct MSG_MGR_ *)hMsgMgr;
8119 + struct WMD_DRV_INTERFACE *pIntfFxns;
8121 + DBC_Require(cRefs > 0);
8122 + DBC_Require(MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE));
8124 + GT_1trace(MSG_debugMask, GT_ENTER, "MSG_Delete: hMsgMgr: 0x%x\n",
8125 + hMsgMgr);
8127 + pIntfFxns = pMsgMgr->pIntfFxns;
8129 + /* Let WMD message module destroy the MSG_MGR: */
8130 + (*pIntfFxns->pfnMsgDelete)(hMsgMgr);
8132 + DBC_Ensure(!MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE));
8136 + * ======== MSG_Exit ========
8137 + */
8138 +void MSG_Exit(void)
8140 + DBC_Require(cRefs > 0);
8141 + cRefs--;
8142 + GT_1trace(MSG_debugMask, GT_5CLASS,
8143 + "Entered MSG_Exit, ref count: 0x%x\n", cRefs);
8144 + DBC_Ensure(cRefs >= 0);
8148 + * ======== MSG_Init ========
8149 + */
8150 +bool MSG_Init(void)
8152 + DBC_Require(cRefs >= 0);
8154 + if (cRefs == 0) {
8155 + DBC_Assert(!MSG_debugMask.flags);
8156 + GT_create(&MSG_debugMask, "MG"); /* "MG" for MsG */
8159 + cRefs++;
8161 + GT_1trace(MSG_debugMask, GT_5CLASS, "MSG_Init(), ref count: 0x%x\n",
8162 + cRefs);
8164 + DBC_Ensure(cRefs >= 0);
8166 + return true;
8169 diff --git a/drivers/dsp/bridge/pmgr/msgobj.h b/drivers/dsp/bridge/pmgr/msgobj.h
8170 new file mode 100644
8171 index 0000000..14da8da
8172 --- /dev/null
8173 +++ b/drivers/dsp/bridge/pmgr/msgobj.h
8174 @@ -0,0 +1,52 @@
8176 + * linux/drivers/dsp/bridge/pmgr/msgobj.h
8178 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
8180 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
8182 + * This package is free software; you can redistribute it and/or modify
8183 + * it under the terms of the GNU General Public License version 2 as
8184 + * published by the Free Software Foundation.
8186 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
8187 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
8188 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8189 + */
8193 + * ======== msgobj.h ========
8194 + * Description:
8195 + * Structure subcomponents of channel class library MSG objects which
8196 + * are exposed to class driver from mini-driver.
8198 + * Public Functions:
8199 + * None.
8201 + *! Revision History:
8202 + *! ================
8203 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
8204 + *! 17-Nov-2000 jeh Created.
8205 + */
8207 +#ifndef MSGOBJ_
8208 +#define MSGOBJ_
8210 +#include <wmd.h>
8212 +#include <msgdefs.h>
8215 + * This struct is the first field in a MSG_MGR struct, as implemented in
8216 + * a WMD channel class library. Other, implementation specific fields
8217 + * follow this structure in memory.
8218 + */
8219 +struct MSG_MGR_ {
8220 + /* The first two fields must match those in msgobj.h */
8221 + u32 dwSignature;
8222 + struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */
8225 +#endif /* MSGOBJ_ */
8227 diff --git a/drivers/dsp/bridge/pmgr/wcd.c b/drivers/dsp/bridge/pmgr/wcd.c
8228 new file mode 100644
8229 index 0000000..7a6eb1a
8230 --- /dev/null
8231 +++ b/drivers/dsp/bridge/pmgr/wcd.c
8232 @@ -0,0 +1,1641 @@
8234 + * linux/drivers/dsp/bridge/pmgr/wcd.c
8236 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
8238 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
8240 + * This package is free software; you can redistribute it and/or modify
8241 + * it under the terms of the GNU General Public License version 2 as
8242 + * published by the Free Software Foundation.
8244 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
8245 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
8246 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8247 + */
8250 + * ======== wcd.c ========
8251 + * Description:
8252 + * Common WCD functions, also includes the wrapper
8253 + * functions called directly by the DeviceIOControl interface.
8255 + * Public Functions:
8256 + * WCD_CallDevIOCtl
8257 + * WCD_Init
8258 + * WCD_InitComplete2
8259 + * WCD_Exit
8260 + * <MOD>WRAP_*
8262 + *! Revision History:
8263 + *! ================
8264 + *! 29-Apr-2004 hp Call PROC_AutoStart only for DSP device
8265 + *! 19-Apr-2004 sb Aligned DMM definitions with Symbian
8266 + *! 08-Mar-2004 sb Added the Dynamic Memory Mapping APIs
8267 + *! 03-Apr-2003 sb Process environment pointer in PROCWRAP_Load
8268 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
8269 + *! 30-Jan-2002 ag CMMWRAP_AllocBuf name changed to CMMWRAP_CallocBuf
8270 + *! 15-Jan-2002 ag Added actual bufSize param to STRMWRAP_Reclaim[issue].
8271 + *! 14-Dec-2001 rr ARGS_NODE_CONNECT maps the pAttr.
8272 + *! 03-Oct-2001 rr ARGS_NODE_ALLOCMSGBUF/FREEMSGBUF maps the pAttr.
8273 + *! 10-Sep-2001 ag Added CMD_CMM_GETHANDLE.
8274 + *! 23-Apr-2001 jeh Pass pStatus to NODE_Terminate.
8275 + *! 11-Apr-2001 jeh STRMWRAP_Reclaim embedded pointer is mapped and unmapped.
8276 + *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates.
8277 + *! 06-Dec-2000 jeh WRAP_MAP2CALLER pointers in RegisterNotify calls.
8278 + *! 05-Dec-2000 ag: Removed MAP2CALLER in NODEWRAP_FreeMsgBuf().
8279 + *! 22-Nov-2000 kc: Added MGRWRAP_GetPerf_Data().
8280 + *! 20-Nov-2000 jeh Added MSG_Init()/MSG_Exit(), IO_Init()/IO_Exit().
8281 + *! WRAP pointers to handles for PROC_Attach, NODE_Allocate.
8282 + *! 27-Oct-2000 jeh Added NODEWRAP_AllocMsgBuf, NODEWRAP_FreeMsgBuf. Removed
8283 + *! NODEWRAP_GetMessageStream.
8284 + *! 12-Oct-2000 ag: Added user CMM wrappers.
8285 + *! 05-Oct-2000 rr: WcdInitComplete2 will fail even if one BRD or PROC
8286 + *! AutoStart fails.
8287 + *! 25-Sep-2000 rr: Updated to Version 0.9
8288 + *! 13-Sep-2000 jeh Pass ARGS_NODE_CONNECT.pAttrs to NODE_Connect().
8289 + *! 11-Aug-2000 rr: Part of node enabled.
8290 + *! 31-Jul-2000 rr: UTIL_Wrap and MEM_Wrap added to RM.
8291 + *! 27-Jul-2000 rr: PROCWRAP, NODEWRAP and STRMWRAP implemented.
8292 + *! STRM and some NODE Wrappers are not implemented.
8293 + *! 27-Jun-2000 rr: MGRWRAP fxns added.IFDEF to build for PM or DSP/BIOS Bridge
8294 + *! 08-Feb-2000 rr File name changed to wcd.c
8295 + *! 03-Feb-2000 rr: Module initialization are done by SERVICES init. GT Class
8296 + *! changes for module init/exit fxns.
8297 + *! 24-Jan-2000 rr: Merged with Scott's code.
8298 + *! 21-Jan-1999 sg: Changed ARGS_CHNL_GETMODE field name from pdwMode to pMode.
8299 + *! 17-Jan-2000 rr: BRD_GetStatus does WRAP_MAP2CALLER for state.
8300 + *! 14-Dec-1999 ag: Removed _MAP2CALLER in CHNL_GetMgr().
8301 + *! 13-Dec-1999 rr: BRDWRAP_GetSymbol, BRDWRAP_GetTrace uses WRAP_MAP2CALLER
8302 + *! macros.BRDWRAP_Load maps and unmaps embedded pointers.
8303 + *! 10-Dec-1999 ag: User CHNL bufs mapped in _AddIOReq & _GetIOCompletion.
8304 + *! 09-Dec-1999 rr: BRDWRAP_Open and CHNLWRAP_GetMgr does not map
8305 + *! pointer as there was a change in config.c
8306 + *! 06-Dec-1999 rr: BRD_Read and Write Maps the buf pointers.
8307 + *! 03-Dec-1999 rr: CHNLWRAP_GetMgr and BRDWRAP_Open maps hDevNode pointer.
8308 + *! WCD_InitComplete2 Included for BRD_AutoStart.
8309 + *! 16-Nov-1999 ag: Map buf to process in CHNLWRAP_AllocBuffer().
8310 + *! CHNL_GetMgr() Mapping Fix.
8311 + *! 10-Nov-1999 ag: Removed unnecessary calls to WRAP_MAP2CALLER.
8312 + *! 08-Nov-1999 kc: Added MEMRY & enabled BRD_IOCtl for tests.
8313 + *! 29-Oct-1999 ag: Added CHNL.
8314 + *! 29-Oct-1999 kc: Added trace statements; added ptr mapping; updated
8315 + *! use of UTIL module API.
8316 + *! 29-Oct-1999 rr: Wrapper functions does the Mapping of the Pointers.
8317 + *! in WinCE all the explicit pointers will be converted
8318 + *! by the OS during interprocess but not the embedded pointers.
8319 + *! 16-Oct-1999 kc: Code review cleanup.
8320 + *! 07-Oct-1999 kc: Added UTILWRAP_TestDll() to run PM test harness. See
8321 + *! /src/doc/pmtest.doc for more detail.
8322 + *! 09-Sep-1999 rr: After exactly two years(!). Adopted for WinCE. GT Enabled.
8323 + *! 09-Sep-1997 gp: Created.
8324 + */
8326 +/* ----------------------------------- Host OS */
8327 +#include <host_os.h>
8329 +/* ----------------------------------- DSP/BIOS Bridge */
8330 +#include <std.h>
8331 +#include <dbdefs.h>
8332 +#include <errbase.h>
8334 +/* ----------------------------------- Trace & Debug */
8335 +#include <dbc.h>
8336 +#include <gt.h>
8338 +/* ----------------------------------- OS Adaptation Layer */
8339 +#include <cfg.h>
8340 +#include <mem.h>
8341 +#include <ntfy.h>
8342 +#include <services.h>
8343 +#include <util.h>
8345 +/* ----------------------------------- Platform Manager */
8346 +#include <chnl.h>
8347 +#include <dev.h>
8348 +#include <drv.h>
8350 +#include <proc.h>
8351 +#include <strm.h>
8353 +/* ----------------------------------- Resource Manager */
8354 +#include <disp.h>
8355 +#include <mgr.h>
8356 +#include <node.h>
8357 +#include <rmm.h>
8360 +/* ----------------------------------- Others */
8361 +#include <msg.h>
8362 +#include <cmm.h>
8363 +#include <io.h>
8365 +/* ----------------------------------- This */
8366 +#include <_dcd.h>
8367 +#include <dbdcd.h>
8369 +#ifndef RES_CLEANUP_DISABLE
8370 +#include <resourcecleanup.h>
8371 +#endif
8373 +/* ----------------------------------- Defines, Data Structures, Typedefs */
8374 +#define MAX_TRACEBUFLEN 255
8375 +#define MAX_LOADARGS 16
8376 +#define MAX_NODES 64
8377 +#define MAX_STREAMS 16
8378 +#define MAX_BUFS 64
8380 +/* Following two macros should ideally have do{}while(0) */
8382 +#define cp_fm_usr(dest, src, status, elements) \
8383 + if (DSP_SUCCEEDED(status)) {\
8384 + if (unlikely(src == NULL) || \
8385 + unlikely(copy_from_user(dest, src, elements * sizeof(*(dest))))) { \
8386 + GT_1trace(WCD_debugMask, GT_7CLASS, \
8387 + "copy_from_user failed, src=0x%x\n", src); \
8388 + status = DSP_EPOINTER ; \
8389 + } \
8392 +#define cp_to_usr(dest, src, status, elements) \
8393 + if (DSP_SUCCEEDED(status)) {\
8394 + if (unlikely(dest == NULL) || \
8395 + unlikely(copy_to_user(dest, src, elements * sizeof(*(src))))) { \
8396 + GT_1trace(WCD_debugMask, GT_7CLASS, \
8397 + "copy_to_user failed, dest=0x%x\n", dest); \
8398 + status = DSP_EPOINTER ;\
8399 + } \
8402 +/* Device IOCtl function pointer */
8403 +struct WCD_Cmd {
8404 + u32(*fxn)(union Trapped_Args *args);
8405 + u32 dwIndex;
8406 +} ;
8408 +/* ----------------------------------- Globals */
8409 +struct GT_Mask WCD_debugMask = { NULL, NULL }; /* Core VxD Mask */
8410 +u32 WCD_cRefs;
8413 + * Function table.
8414 + * The order of these functions MUST be the same as the order of the command
8415 + * numbers defined in wcdioctl.h This is how an IOCTL number in user mode
8416 + * turns into a function call in kernel mode.
8417 + */
8418 +struct WCD_Cmd WCD_cmdTable[] = {
8419 + /* MGR module */
8420 + {MGRWRAP_EnumNode_Info, CMD_MGR_ENUMNODE_INFO_OFFSET},
8421 + {MGRWRAP_EnumProc_Info, CMD_MGR_ENUMPROC_INFO_OFFSET},
8422 + {MGRWRAP_RegisterObject, CMD_MGR_REGISTEROBJECT_OFFSET},
8423 + {MGRWRAP_UnregisterObject, CMD_MGR_UNREGISTEROBJECT_OFFSET},
8424 + {MGRWRAP_WaitForBridgeEvents, CMD_MGR_WAIT_OFFSET},
8425 +#ifndef RES_CLEANUP_DISABLE
8426 + {MGRWRAP_GetProcessResourcesInfo, CMD_MGR_RESOUCES_OFFSET},
8427 +#endif
8428 + /* PROC Module */
8429 + {PROCWRAP_Attach, CMD_PROC_ATTACH_OFFSET},
8430 + {PROCWRAP_Ctrl, CMD_PROC_CTRL_OFFSET},
8431 + {PROCWRAP_Detach, CMD_PROC_DETACH_OFFSET},
8432 + {PROCWRAP_EnumNode_Info, CMD_PROC_ENUMNODE_OFFSET},
8433 + {PROCWRAP_EnumResources, CMD_PROC_ENUMRESOURCES_OFFSET},
8434 + {PROCWRAP_GetState, CMD_PROC_GETSTATE_OFFSET},
8435 + {PROCWRAP_GetTrace, CMD_PROC_GETTRACE_OFFSET},
8436 + {PROCWRAP_Load, CMD_PROC_LOAD_OFFSET},
8437 + {PROCWRAP_RegisterNotify, CMD_PROC_REGISTERNOTIFY_OFFSET},
8438 + {PROCWRAP_Start, CMD_PROC_START_OFFSET},
8439 + {PROCWRAP_ReserveMemory, CMD_PROC_RSVMEM_OFFSET},
8440 + {PROCWRAP_UnReserveMemory, CMD_PROC_UNRSVMEM_OFFSET},
8441 + {PROCWRAP_Map, CMD_PROC_MAPMEM_OFFSET},
8442 + {PROCWRAP_UnMap, CMD_PROC_UNMAPMEM_OFFSET},
8443 + {PROCWRAP_FlushMemory, CMD_PROC_FLUSHMEMORY_OFFSET},
8444 + {PROCWRAP_Stop, CMD_PROC_STOP_OFFSET},
8445 + {PROCWRAP_InvalidateMemory, CMD_PROC_INVALIDATEMEMORY_OFFSET},
8446 + /* NODE Module */
8447 + {NODEWRAP_Allocate, CMD_NODE_ALLOCATE_OFFSET},
8448 + {NODEWRAP_AllocMsgBuf, CMD_NODE_ALLOCMSGBUF_OFFSET},
8449 + {NODEWRAP_ChangePriority, CMD_NODE_CHANGEPRIORITY_OFFSET},
8450 + {NODEWRAP_Connect, CMD_NODE_CONNECT_OFFSET},
8451 + {NODEWRAP_Create, CMD_NODE_CREATE_OFFSET},
8452 + {NODEWRAP_Delete, CMD_NODE_DELETE_OFFSET},
8453 + {NODEWRAP_FreeMsgBuf, CMD_NODE_FREEMSGBUF_OFFSET},
8454 + {NODEWRAP_GetAttr, CMD_NODE_GETATTR_OFFSET},
8455 + {NODEWRAP_GetMessage, CMD_NODE_GETMESSAGE_OFFSET},
8456 + {NODEWRAP_Pause, CMD_NODE_PAUSE_OFFSET},
8457 + {NODEWRAP_PutMessage, CMD_NODE_PUTMESSAGE_OFFSET},
8458 + {NODEWRAP_RegisterNotify, CMD_NODE_REGISTERNOTIFY_OFFSET},
8459 + {NODEWRAP_Run, CMD_NODE_RUN_OFFSET},
8460 + {NODEWRAP_Terminate, CMD_NODE_TERMINATE_OFFSET},
8461 + {NODEWRAP_GetUUIDProps, CMD_NODE_GETUUIDPROPS_OFFSET},
8462 + /* STRM wrapper functions */
8463 + {STRMWRAP_AllocateBuffer, CMD_STRM_ALLOCATEBUFFER_OFFSET},
8464 + {STRMWRAP_Close, CMD_STRM_CLOSE_OFFSET},
8465 + {STRMWRAP_FreeBuffer, CMD_STRM_FREEBUFFER_OFFSET},
8466 + {STRMWRAP_GetEventHandle, CMD_STRM_GETEVENTHANDLE_OFFSET},
8467 + {STRMWRAP_GetInfo, CMD_STRM_GETINFO_OFFSET},
8468 + {STRMWRAP_Idle, CMD_STRM_IDLE_OFFSET},
8469 + {STRMWRAP_Issue, CMD_STRM_ISSUE_OFFSET},
8470 + {STRMWRAP_Open, CMD_STRM_OPEN_OFFSET},
8471 + {STRMWRAP_Reclaim, CMD_STRM_RECLAIM_OFFSET},
8472 + {STRMWRAP_RegisterNotify, CMD_STRM_REGISTERNOTIFY_OFFSET},
8473 + {STRMWRAP_Select, CMD_STRM_SELECT_OFFSET},
8474 + /* CMM module */
8475 + {CMMWRAP_CallocBuf, CMD_CMM_ALLOCBUF_OFFSET},
8476 + {CMMWRAP_FreeBuf, CMD_CMM_FREEBUF_OFFSET},
8477 + {CMMWRAP_GetHandle, CMD_CMM_GETHANDLE_OFFSET},
8478 + {CMMWRAP_GetInfo, CMD_CMM_GETINFO_OFFSET}
8482 + * ======== WCD_CallDevIOCtl ========
8483 + * Purpose:
8484 + * Call the (wrapper) function for the corresponding WCD IOCTL.
8485 + */
8486 +inline DSP_STATUS WCD_CallDevIOCtl(u32 cmd, union Trapped_Args *args,
8487 + u32 *pResult)
8489 + if ((cmd < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)))) {
8490 + /* make the fxn call via the cmd table */
8491 + *pResult = (*WCD_cmdTable[cmd].fxn) (args);
8492 + return DSP_SOK;
8493 + } else {
8494 + return DSP_EINVALIDARG;
8499 + * ======== WCD_Exit ========
8500 + */
8501 +void WCD_Exit(void)
8503 + DBC_Require(WCD_cRefs > 0);
8504 + WCD_cRefs--;
8505 + GT_1trace(WCD_debugMask, GT_5CLASS,
8506 + "Entered WCD_Exit, ref count: 0x%x\n", WCD_cRefs);
8507 + if (WCD_cRefs == 0) {
8508 + /* Release all WCD modules initialized in WCD_Init(). */
8509 + COD_Exit();
8510 + DEV_Exit();
8511 + CHNL_Exit();
8512 + MSG_Exit();
8513 + IO_Exit();
8514 + STRM_Exit();
8515 + NTFY_Exit();
8516 + DISP_Exit();
8517 + NODE_Exit();
8518 + PROC_Exit();
8519 + MGR_Exit();
8520 + RMM_exit();
8521 + DRV_Exit();
8522 + SERVICES_Exit();
8524 + DBC_Ensure(WCD_cRefs >= 0);
8528 + * ======== WCD_Init ========
8529 + * Purpose:
8530 + * Module initialization is done by SERVICES Init.
8531 + */
8532 +bool WCD_Init(void)
8534 + bool fInit = true;
8535 + bool fDRV, fDEV, fCOD, fSERVICES, fCHNL, fMSG, fIO;
8536 + bool fMGR, fPROC, fNODE, fDISP, fNTFY, fSTRM, fRMM;
8537 +#ifdef DEBUG
8538 + /* runtime check of Device IOCtl array. */
8539 + u32 i;
8540 + for (i = 1; i < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)); i++)
8541 + DBC_Assert(WCD_cmdTable[i - 1].dwIndex == i);
8543 +#endif
8544 + if (WCD_cRefs == 0) {
8545 + /* initialize all SERVICES modules */
8546 + fSERVICES = SERVICES_Init();
8547 + /* initialize debugging module */
8548 + DBC_Assert(!WCD_debugMask.flags);
8549 + GT_create(&WCD_debugMask, "CD"); /* CD for class driver */
8550 + /* initialize class driver and other modules */
8551 + fDRV = DRV_Init();
8552 + fMGR = MGR_Init();
8553 + fPROC = PROC_Init();
8554 + fNODE = NODE_Init();
8555 + fDISP = DISP_Init();
8556 + fNTFY = NTFY_Init();
8557 + fSTRM = STRM_Init();
8558 + fRMM = RMM_init();
8559 + fCHNL = CHNL_Init();
8560 + fMSG = MSG_Init();
8561 + fIO = IO_Init();
8562 + fDEV = DEV_Init();
8563 + fCOD = COD_Init();
8564 + fInit = fSERVICES && fDRV && fDEV && fCHNL && fCOD &&
8565 + fMSG && fIO;
8566 + fInit = fInit && fMGR && fPROC && fRMM;
8567 + if (!fInit) {
8568 + if (fSERVICES)
8569 + SERVICES_Exit();
8571 + if (fDRV)
8572 + DRV_Exit();
8574 + if (fMGR)
8575 + MGR_Exit();
8577 + if (fSTRM)
8578 + STRM_Exit();
8580 + if (fPROC)
8581 + PROC_Exit();
8583 + if (fNODE)
8584 + NODE_Exit();
8586 + if (fDISP)
8587 + DISP_Exit();
8589 + if (fNTFY)
8590 + NTFY_Exit();
8592 + if (fCHNL)
8593 + CHNL_Exit();
8595 + if (fMSG)
8596 + MSG_Exit();
8598 + if (fIO)
8599 + IO_Exit();
8601 + if (fDEV)
8602 + DEV_Exit();
8604 + if (fCOD)
8605 + COD_Exit();
8607 + if (fRMM)
8608 + RMM_exit();
8612 + if (fInit)
8613 + WCD_cRefs++;
8615 + GT_1trace(WCD_debugMask, GT_5CLASS,
8616 + "Entered WCD_Init, ref count: 0x%x\n", WCD_cRefs);
8617 + return fInit;
8621 + * ======== WCD_InitComplete2 ========
8622 + * Purpose:
8623 + * Perform any required WCD, and WMD initialization which
8624 + * cannot not be performed in WCD_Init() or DEV_StartDevice() due
8625 + * to the fact that some services are not yet
8626 + * completely initialized.
8627 + * Parameters:
8628 + * Returns:
8629 + * DSP_SOK: Allow this device to load
8630 + * DSP_EFAIL: Failure.
8631 + * Requires:
8632 + * WCD initialized.
8633 + * Ensures:
8634 + */
8635 +DSP_STATUS WCD_InitComplete2(void)
8637 + DSP_STATUS status = DSP_SOK;
8638 + struct CFG_DEVNODE *DevNode;
8639 + struct DEV_OBJECT *hDevObject;
8640 + u32 devType;
8642 + DBC_Require(WCD_cRefs > 0);
8643 + GT_0trace(WCD_debugMask, GT_ENTER, "Entered WCD_InitComplete\n");
8644 + /* Walk the list of DevObjects, get each devnode, and attempting to
8645 + * autostart the board. Note that this requires COF loading, which
8646 + * requires KFILE. */
8647 + for (hDevObject = DEV_GetFirst(); hDevObject != NULL;
8648 + hDevObject = DEV_GetNext(hDevObject)) {
8649 + if (DSP_FAILED(DEV_GetDevNode(hDevObject, &DevNode)))
8650 + continue;
8652 + if (DSP_FAILED(DEV_GetDevType(hDevObject, &devType)))
8653 + continue;
8655 + if ((devType == DSP_UNIT) || (devType == IVA_UNIT)) {
8656 + if (DSP_FAILED(PROC_AutoStart(DevNode, hDevObject))) {
8657 + GT_0trace(WCD_debugMask, GT_1CLASS,
8658 + "WCD_InitComplete2 Failed\n");
8659 + status = DSP_EFAIL;
8660 + /* break; */
8662 + } else
8663 + GT_1trace(WCD_debugMask, GT_ENTER,
8664 + "Ignoring PROC_AutoStart "
8665 + "for Device Type = 0x%x \n", devType);
8666 + } /* End For Loop */
8667 + GT_1trace(WCD_debugMask, GT_ENTER,
8668 + "Exiting WCD_InitComplete status 0x%x\n", status);
8669 + return status;
8673 + * ======== MGRWRAP_EnumNode_Info ========
8674 + */
8675 +u32 MGRWRAP_EnumNode_Info(union Trapped_Args *args)
8677 + u8 *pNDBProps;
8678 + u32 uNumNodes;
8679 + DSP_STATUS status = DSP_SOK;
8680 + u32 size = args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize;
8682 + GT_4trace(WCD_debugMask, GT_ENTER,
8683 + "MGR_EnumNodeInfo: entered args:\n0x%x"
8684 + " uNode: 0x%x\tpNDBProps: 0x%x\tuNDBPropsSize: "
8685 + "0x%x\tpuNumNodes\n", args->ARGS_MGR_ENUMNODE_INFO.uNode,
8686 + args->ARGS_MGR_ENUMNODE_INFO.pNDBProps,
8687 + args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize,
8688 + args->ARGS_MGR_ENUMNODE_INFO.puNumNodes);
8689 + pNDBProps = MEM_Alloc(size, MEM_NONPAGED);
8690 + if (pNDBProps == NULL)
8691 + status = DSP_EMEMORY;
8693 + if (DSP_SUCCEEDED(status)) {
8694 + status = MGR_EnumNodeInfo(args->ARGS_MGR_ENUMNODE_INFO.uNode,
8695 + (struct DSP_NDBPROPS *)pNDBProps,
8696 + size, &uNumNodes);
8698 + cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.pNDBProps, pNDBProps, status,
8699 + size);
8700 + cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.puNumNodes, &uNumNodes, status,
8701 + 1);
8702 + if (pNDBProps)
8703 + MEM_Free(pNDBProps);
8705 + return status;
8709 + * ======== MGRWRAP_EnumProc_Info ========
8710 + */
8711 +u32 MGRWRAP_EnumProc_Info(union Trapped_Args *args)
8713 + u8 *pProcessorInfo;
8714 + u32 uNumProcs;
8715 + DSP_STATUS status = DSP_SOK;
8716 + u32 size = args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize;
8718 + GT_4trace(WCD_debugMask, GT_ENTER,
8719 + "MGRWRAP_EnumProc_Info: entered args:\n"
8720 + "0x%x uProcessor: 0x%x\tpProcessorInfo: 0x%x\t"
8721 + "uProcessorInfoSize: 0x%x\tpuNumProcs \n",
8722 + args->ARGS_MGR_ENUMPROC_INFO.uProcessor,
8723 + args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo,
8724 + args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize,
8725 + args->ARGS_MGR_ENUMPROC_INFO.puNumProcs);
8726 + pProcessorInfo = MEM_Alloc(size, MEM_NONPAGED);
8727 + if (pProcessorInfo == NULL)
8728 + status = DSP_EMEMORY;
8730 + if (DSP_SUCCEEDED(status)) {
8731 + status = MGR_EnumProcessorInfo(args->
8732 + ARGS_MGR_ENUMPROC_INFO.uProcessor,
8733 + (struct DSP_PROCESSORINFO *)pProcessorInfo,
8734 + size, &uNumProcs);
8736 + cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo, pProcessorInfo,
8737 + status, size);
8738 + cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.puNumProcs, &uNumProcs,
8739 + status, 1);
8740 + if (pProcessorInfo)
8741 + MEM_Free(pProcessorInfo);
8743 + return status;
8746 +#define WRAP_MAP2CALLER(x) x
8748 + * ======== MGRWRAP_RegisterObject ========
8749 + */
8750 +u32 MGRWRAP_RegisterObject(union Trapped_Args *args)
8752 + u32 retVal;
8754 + GT_1trace(WCD_debugMask, GT_ENTER,
8755 + "MGRWRAP_RegisterObject: entered pg2hMsg "
8756 + "0x%x\n", args->ARGS_MGR_REGISTEROBJECT.pUuid);
8757 + retVal = DCD_RegisterObject(WRAP_MAP2CALLER
8758 + (args->ARGS_MGR_REGISTEROBJECT.pUuid),
8759 + args->ARGS_MGR_REGISTEROBJECT.objType,
8760 + WRAP_MAP2CALLER(args->ARGS_MGR_REGISTEROBJECT.pszPathName));
8761 + return retVal;
8765 + * ======== MGRWRAP_UnregisterObject ========
8766 + */
8767 +u32 MGRWRAP_UnregisterObject(union Trapped_Args *args)
8769 + u32 retVal;
8771 + GT_1trace(WCD_debugMask, GT_ENTER,
8772 + "MGRWRAP_UnregisterObject: entered pg2hMsg"
8773 + " 0x%x\n", args->ARGS_MGR_UNREGISTEROBJECT.pUuid);
8774 + retVal = DCD_UnregisterObject(WRAP_MAP2CALLER
8775 + (args->ARGS_MGR_UNREGISTEROBJECT.pUuid),
8776 + args->ARGS_MGR_UNREGISTEROBJECT.objType);
8778 + return retVal;
8782 + * ======== MGRWRAP_WaitForBridgeEvents ========
8783 + */
8784 +u32 MGRWRAP_WaitForBridgeEvents(union Trapped_Args *args)
8786 + DSP_STATUS status = DSP_SOK;
8787 + struct DSP_NOTIFICATION *aNotifications[MAX_EVENTS];
8788 + struct DSP_NOTIFICATION notifications[MAX_EVENTS];
8789 + u32 uIndex, i;
8790 + u32 uCount = args->ARGS_MGR_WAIT.uCount;
8792 + GT_0trace(WCD_debugMask, GT_ENTER,
8793 + "MGRWRAP_WaitForBridgeEvents: entered\n");
8795 + if (uCount > MAX_EVENTS)
8796 + status = DSP_EINVALIDARG;
8798 + /* get the array of pointers to user structures */
8799 + cp_fm_usr(aNotifications, args->ARGS_MGR_WAIT.aNotifications,
8800 + status, uCount);
8801 + /* get the events */
8802 + for (i = 0; i < uCount; i++) {
8803 + cp_fm_usr(&notifications[i], aNotifications[i], status, 1);
8804 + if (DSP_SUCCEEDED(status)) {
8805 + /* set the array of pointers to kernel structures*/
8806 + aNotifications[i] = &notifications[i];
8809 + if (DSP_SUCCEEDED(status)) {
8810 + status = MGR_WaitForBridgeEvents(aNotifications, uCount,
8811 + &uIndex, args->ARGS_MGR_WAIT.uTimeout);
8813 + cp_to_usr(args->ARGS_MGR_WAIT.puIndex, &uIndex, status, 1);
8814 + return status;
8818 +#ifndef RES_CLEANUP_DISABLE
8820 + * ======== MGRWRAP_GetProcessResourceInfo ========
8821 + */
8822 +u32 MGRWRAP_GetProcessResourcesInfo(union Trapped_Args *args)
8824 + DSP_STATUS status = DSP_SOK;
8825 + u32 uSize = 0;
8826 + u8 *pBuf = MEM_Alloc(8092, MEM_NONPAGED);
8827 + status = DRV_ProcDisplayResInfo(pBuf, &uSize);
8828 + GT_1trace(WCD_debugMask, GT_ENTER,
8829 + "MGRWRAP_GetProcessResourcesInfo:uSize=%d :\n", uSize);
8830 + cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status, uSize);
8831 + GT_0trace(WCD_debugMask, GT_ENTER, "\n***********"
8832 + "123MGRWRAP_GetProcessResourcesInfo:**************\n");
8833 + GT_0trace(WCD_debugMask, GT_ENTER, "\n***********"
8834 + "456MGRWRAP_GetProcessResourcesInfo:**************\n");
8835 + cp_to_usr(args->ARGS_PROC_GETTRACE.pSize, &uSize, status, 1);
8836 + MEM_Free(pBuf);
8837 + return status;
8839 +#endif
8843 + * ======== PROCWRAP_Attach ========
8844 + */
8845 +u32 PROCWRAP_Attach(union Trapped_Args *args)
8847 + DSP_HPROCESSOR processor;
8848 + DSP_STATUS status = DSP_SOK;
8849 + struct DSP_PROCESSORATTRIN attrIn, *pAttrIn = NULL;
8851 + GT_3trace(WCD_debugMask, GT_ENTER,
8852 + "PROCWRAP_Attach: entered args:\n" "0x%x"
8853 + " uProcessor: 0x%x\tpAttrIn: 0x%x\tphProcessor \n",
8854 + args->ARGS_PROC_ATTACH.uProcessor,
8855 + args->ARGS_PROC_ATTACH.pAttrIn,
8856 + args->ARGS_PROC_ATTACH.phProcessor);
8857 + /* Optional argument */
8858 + if (args->ARGS_PROC_ATTACH.pAttrIn) {
8859 + cp_fm_usr(&attrIn, args->ARGS_PROC_ATTACH.pAttrIn, status, 1);
8860 + if (DSP_SUCCEEDED(status))
8861 + pAttrIn = &attrIn;
8864 + status = PROC_Attach(args->ARGS_PROC_ATTACH.uProcessor, pAttrIn,
8865 + &processor);
8866 + cp_to_usr(args->ARGS_PROC_ATTACH.phProcessor, &processor, status, 1);
8867 + return status;
8871 + * ======== PROCWRAP_Ctrl ========
8872 + */
8873 +u32 PROCWRAP_Ctrl(union Trapped_Args *args)
8875 + u32 cbDataSize, *pSize = (u32 *)args->ARGS_PROC_CTRL.pArgs;
8876 + u8 *pArgs = NULL;
8877 + DSP_STATUS status = DSP_SOK;
8879 + GT_3trace(WCD_debugMask, GT_ENTER,
8880 + "PROCWRAP_Ctrl: entered args:\n 0x%x"
8881 + " uProcessor: 0x%x\tdwCmd: 0x%x\tpArgs \n",
8882 + args->ARGS_PROC_CTRL.hProcessor,
8883 + args->ARGS_PROC_CTRL.dwCmd,
8884 + args->ARGS_PROC_CTRL.pArgs);
8885 + if (pSize) {
8886 + if (get_user(cbDataSize, pSize))
8887 + status = DSP_EFAIL;
8889 + cbDataSize += sizeof(u32);
8890 + if (DSP_SUCCEEDED(status)) {
8891 + pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
8892 + if (pArgs == NULL)
8893 + status = DSP_EMEMORY;
8896 + cp_fm_usr(pArgs, args->ARGS_PROC_CTRL.pArgs, status,
8897 + cbDataSize);
8899 + if (DSP_SUCCEEDED(status)) {
8900 + status = PROC_Ctrl(args->ARGS_PROC_CTRL.hProcessor,
8901 + args->ARGS_PROC_CTRL.dwCmd,
8902 + (struct DSP_CBDATA *)pArgs);
8905 + /* cp_to_usr(args->ARGS_PROC_CTRL.pArgs, pArgs, status, 1);*/
8906 + if (pArgs)
8907 + MEM_Free(pArgs);
8909 + return status;
8913 + * ======== PROCWRAP_Detach ========
8914 + */
8915 +u32 PROCWRAP_Detach(union Trapped_Args *args)
8917 + u32 retVal;
8919 + GT_1trace(WCD_debugMask, GT_ENTER,
8920 + "PROCWRAP_Detach: entered args\n0x%x "
8921 + "hProceesor \n", args->ARGS_PROC_DETACH.hProcessor);
8922 + retVal = PROC_Detach(args->ARGS_PROC_DETACH.hProcessor);
8924 + return retVal;
8928 + * ======== PROCWRAP_EnumNode_Info ========
8929 + */
8930 +u32 PROCWRAP_EnumNode_Info(union Trapped_Args *args)
8932 + DSP_STATUS status;
8933 + DSP_HNODE aNodeTab[MAX_NODES];
8934 + u32 uNumNodes;
8935 + u32 uAllocated;
8937 + GT_5trace(WCD_debugMask, GT_ENTER,
8938 + "PROCWRAP_EnumNode_Info:entered args:\n0x"
8939 + "%xhProcessor:0x%x\taNodeTab:0x%x\tuNodeTabSize:"
8940 + "%0x%x\tpuNumNodes%\n0x%x puAllocated: \n",
8941 + args->ARGS_PROC_ENUMNODE_INFO.hProcessor,
8942 + args->ARGS_PROC_ENUMNODE_INFO.aNodeTab,
8943 + args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize,
8944 + args->ARGS_PROC_ENUMNODE_INFO.puNumNodes,
8945 + args->ARGS_PROC_ENUMNODE_INFO.puAllocated);
8946 + DBC_Require(args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize <= MAX_NODES);
8947 + status = PROC_EnumNodes(args->ARGS_PROC_ENUMNODE_INFO.hProcessor,
8948 + aNodeTab,
8949 + args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize,
8950 + &uNumNodes, &uAllocated);
8951 + cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.aNodeTab, aNodeTab, status,
8952 + uNumNodes);
8953 + cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puNumNodes, &uNumNodes,
8954 + status, 1);
8955 + cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puAllocated, &uAllocated,
8956 + status, 1);
8957 + return status;
8961 + * ======== PROCWRAP_FlushMemory ========
8962 + */
8963 +u32 PROCWRAP_FlushMemory(union Trapped_Args *args)
8965 + DSP_STATUS status;
8967 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_FlushMemory: entered\n");
8969 + status = PROC_FlushMemory(args->ARGS_PROC_FLUSHMEMORY.hProcessor,
8970 + args->ARGS_PROC_FLUSHMEMORY.pMpuAddr,
8971 + args->ARGS_PROC_FLUSHMEMORY.ulSize,
8972 + args->ARGS_PROC_FLUSHMEMORY.ulFlags);
8973 + return status;
8978 + * ======== PROCWRAP_InvalidateMemory ========
8979 + */
8980 +u32 PROCWRAP_InvalidateMemory(union Trapped_Args *args)
8982 + DSP_STATUS status;
8984 + GT_0trace(WCD_debugMask, GT_ENTER,
8985 + "PROCWRAP_InvalidateMemory:entered\n");
8987 + status = PROC_InvalidateMemory(
8988 + args->ARGS_PROC_INVALIDATEMEMORY.hProcessor,
8989 + args->ARGS_PROC_INVALIDATEMEMORY.pMpuAddr,
8990 + args->ARGS_PROC_INVALIDATEMEMORY.ulSize);
8991 + return status;
8996 + * ======== PROCWRAP_EnumResources ========
8997 + */
8998 +u32 PROCWRAP_EnumResources(union Trapped_Args *args)
9000 + u32 retVal;
9002 + GT_4trace(WCD_debugMask, GT_ENTER,
9003 + "PROCWRAP_EnumResources: entered args:\n"
9004 + "0x%x hProcessor: 0x%x\tuResourceMask: 0x%x\tpResourceInfo"
9005 + " 0x%x\tuResourceInfoSixe \n",
9006 + args->ARGS_PROC_ENUMRESOURCES.hProcessor,
9007 + args->ARGS_PROC_ENUMRESOURCES.uResourceType,
9008 + args->ARGS_PROC_ENUMRESOURCES.pResourceInfo,
9009 + args->ARGS_PROC_ENUMRESOURCES.uResourceInfoSize);
9010 + retVal = PROC_GetResourceInfo(args->ARGS_PROC_ENUMRESOURCES.hProcessor,
9011 + args->ARGS_PROC_ENUMRESOURCES.uResourceType,
9012 + WRAP_MAP2CALLER(args->ARGS_PROC_ENUMRESOURCES.
9013 + pResourceInfo), args->ARGS_PROC_ENUMRESOURCES.
9014 + uResourceInfoSize);
9016 + return retVal;
9020 + * ======== PROCWRAP_GetState ========
9021 + */
9022 +u32 PROCWRAP_GetState(union Trapped_Args *args)
9024 + DSP_STATUS status;
9025 + struct DSP_PROCESSORSTATE procStatus;
9026 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetState: entered\n");
9027 + status = PROC_GetState(args->ARGS_PROC_GETSTATE.hProcessor, &procStatus,
9028 + args->ARGS_PROC_GETSTATE.uStateInfoSize);
9029 + cp_to_usr(args->ARGS_PROC_GETSTATE.pProcStatus, &procStatus, status, 1);
9030 + return status;
9035 + * ======== PROCWRAP_GetTrace ========
9036 + */
9037 +u32 PROCWRAP_GetTrace(union Trapped_Args *args)
9039 + DSP_STATUS status;
9040 + u8 *pBuf;
9042 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetTrace: entered\n");
9044 + DBC_Require(args->ARGS_PROC_GETTRACE.uMaxSize <= MAX_TRACEBUFLEN);
9046 + pBuf = MEM_Calloc(args->ARGS_PROC_GETTRACE.uMaxSize, MEM_NONPAGED);
9047 + if (pBuf != NULL) {
9048 + status = PROC_GetTrace(args->ARGS_PROC_GETTRACE.hProcessor,
9049 + pBuf, args->ARGS_PROC_GETTRACE.uMaxSize);
9050 + } else {
9051 + status = DSP_EMEMORY;
9053 + cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status,
9054 + args->ARGS_PROC_GETTRACE.uMaxSize);
9055 + if (pBuf)
9056 + MEM_Free(pBuf);
9058 + return status;
9062 + * ======== PROCWRAP_Load ========
9063 + */
9064 +u32 PROCWRAP_Load(union Trapped_Args *args)
9066 + s32 i, len;
9067 + DSP_STATUS status = DSP_SOK;
9068 + u8 *temp;
9069 + s32 argc = args->ARGS_PROC_LOAD.iArgc;
9070 + u8 **argv, **envp = NULL;
9072 + DBC_Require(argc > 0);
9073 + DBC_Require(argc <= MAX_LOADARGS);
9075 + argv = MEM_Alloc(argc * sizeof(u8 *), MEM_NONPAGED);
9076 + if (argv == NULL)
9077 + status = DSP_EMEMORY;
9079 + cp_fm_usr(argv, args->ARGS_PROC_LOAD.aArgv, status, argc);
9080 + for (i = 0; DSP_SUCCEEDED(status) && (i < argc); i++) {
9081 + if (argv[i] != NULL) {
9082 + temp = argv[i]; /* User space pointer to argument */
9083 + len = strlen_user((char *)temp);
9084 + /* Kernel space pointer to argument */
9085 + argv[i] = MEM_Alloc(len, MEM_NONPAGED);
9086 + if (argv[i] == NULL) {
9087 + status = DSP_EMEMORY;
9088 + break;
9090 + cp_fm_usr(argv[i], temp, status, len);
9093 + /* TODO: validate this */
9094 + if (args->ARGS_PROC_LOAD.aEnvp != NULL) {
9095 + /* number of elements in the envp array including NULL */
9096 + len = 0;
9097 + do {
9098 + len++;
9099 + get_user(temp, args->ARGS_PROC_LOAD.aEnvp);
9100 + } while (temp);
9101 + envp = MEM_Alloc(len * sizeof(u8 *), MEM_NONPAGED);
9102 + if (envp == NULL)
9103 + status = DSP_EMEMORY;
9105 + cp_fm_usr(envp, args->ARGS_PROC_LOAD.aEnvp, status, len);
9106 + for (i = 0; DSP_SUCCEEDED(status) && (envp[i] != NULL); i++) {
9107 + temp = envp[i]; /* User space pointer to argument */
9108 + len = strlen_user((char *)temp);
9109 + /* Kernel space pointer to argument */
9110 + envp[i] = MEM_Alloc(len, MEM_NONPAGED);
9111 + if (envp[i] == NULL) {
9112 + status = DSP_EMEMORY;
9113 + break;
9115 + cp_fm_usr(envp[i], temp, status, len);
9118 + GT_5trace(WCD_debugMask, GT_ENTER,
9119 + "PROCWRAP_Load, hProcessor: 0x%x\n\tiArgc:"
9120 + "0x%x\n\taArgv: 0x%x\n\taArgv[0]: %s\n\taEnvp: 0x%0x\n",
9121 + args->ARGS_PROC_LOAD.hProcessor,
9122 + args->ARGS_PROC_LOAD.iArgc, args->ARGS_PROC_LOAD.aArgv,
9123 + argv[0], args->ARGS_PROC_LOAD.aEnvp);
9124 + if (DSP_SUCCEEDED(status)) {
9125 + status = PROC_Load(args->ARGS_PROC_LOAD.hProcessor,
9126 + args->ARGS_PROC_LOAD.iArgc,
9127 + (CONST char **)argv, (CONST char **)envp);
9129 + if (envp != NULL) {
9130 + i = 0;
9131 + while (envp[i] != NULL)
9132 + MEM_Free(envp[i++]);
9134 + MEM_Free(envp);
9136 + if (argv != NULL) {
9137 + for (i = 0; i < argc; i++) {
9138 + if (argv[i] != NULL)
9139 + MEM_Free(argv[i]);
9142 + MEM_Free(argv);
9144 + return status;
9148 + * ======== PROCWRAP_Map ========
9149 + */
9150 +u32 PROCWRAP_Map(union Trapped_Args *args)
9152 + DSP_STATUS status;
9153 + void *pMapAddr;
9155 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Map: entered\n");
9156 + status = PROC_Map(args->ARGS_PROC_MAPMEM.hProcessor,
9157 + args->ARGS_PROC_MAPMEM.pMpuAddr,
9158 + args->ARGS_PROC_MAPMEM.ulSize,
9159 + args->ARGS_PROC_MAPMEM.pReqAddr, &pMapAddr,
9160 + args->ARGS_PROC_MAPMEM.ulMapAttr);
9161 + if (DSP_SUCCEEDED(status)) {
9162 + if (put_user(pMapAddr, args->ARGS_PROC_MAPMEM.ppMapAddr))
9163 + status = DSP_EINVALIDARG;
9166 + return status;
9170 + * ======== PROCWRAP_RegisterNotify ========
9171 + */
9172 +u32 PROCWRAP_RegisterNotify(union Trapped_Args *args)
9174 + DSP_STATUS status;
9175 + struct DSP_NOTIFICATION notification;
9177 + GT_0trace(WCD_debugMask, GT_ENTER,
9178 + "PROCWRAP_RegisterNotify: entered\n");
9180 + /* Initialize the notification data structure */
9181 + notification.psName = NULL;
9182 + notification.handle = NULL;
9184 + status = PROC_RegisterNotify(args->ARGS_PROC_REGISTER_NOTIFY.hProcessor,
9185 + args->ARGS_PROC_REGISTER_NOTIFY.uEventMask,
9186 + args->ARGS_PROC_REGISTER_NOTIFY.uNotifyType,
9187 + &notification);
9188 + cp_to_usr(args->ARGS_PROC_REGISTER_NOTIFY.hNotification, &notification,
9189 + status, 1);
9190 + return status;
9194 + * ======== PROCWRAP_ReserveMemory ========
9195 + */
9196 +u32 PROCWRAP_ReserveMemory(union Trapped_Args *args)
9198 + DSP_STATUS status;
9199 + void *pRsvAddr;
9201 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_ReserveMemory: entered\n");
9202 + status = PROC_ReserveMemory(args->ARGS_PROC_RSVMEM.hProcessor,
9203 + args->ARGS_PROC_RSVMEM.ulSize, &pRsvAddr);
9204 + if (put_user(pRsvAddr, args->ARGS_PROC_RSVMEM.ppRsvAddr))
9205 + status = DSP_EINVALIDARG;
9207 + return status;
9211 + * ======== PROCWRAP_Start ========
9212 + */
9213 +u32 PROCWRAP_Start(union Trapped_Args *args)
9215 + u32 retVal;
9217 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Start: entered\n");
9218 + retVal = PROC_Start(args->ARGS_PROC_START.hProcessor);
9219 + return retVal;
9223 + * ======== PROCWRAP_UnMap ========
9224 + */
9225 +u32 PROCWRAP_UnMap(union Trapped_Args *args)
9227 + DSP_STATUS status;
9229 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_UnMap: entered\n");
9230 + status = PROC_UnMap(args->ARGS_PROC_UNMAPMEM.hProcessor,
9231 + args->ARGS_PROC_UNMAPMEM.pMapAddr);
9232 + return status;
9236 + * ======== PROCWRAP_UnReserveMemory ========
9237 + */
9238 +u32 PROCWRAP_UnReserveMemory(union Trapped_Args *args)
9240 + DSP_STATUS status;
9242 + GT_0trace(WCD_debugMask, GT_ENTER,
9243 + "PROCWRAP_UnReserveMemory: entered\n");
9244 + status = PROC_UnReserveMemory(args->ARGS_PROC_UNRSVMEM.hProcessor,
9245 + args->ARGS_PROC_UNRSVMEM.pRsvAddr);
9246 + return status;
9250 + * ======== PROCWRAP_Stop ========
9251 + */
9252 +u32 PROCWRAP_Stop(union Trapped_Args *args)
9254 + u32 retVal;
9256 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Stop: entered\n");
9257 + retVal = PROC_Stop(args->ARGS_PROC_STOP.hProcessor);
9259 + return retVal;
9263 + * ======== NODEWRAP_Allocate ========
9264 + */
9265 +u32 NODEWRAP_Allocate(union Trapped_Args *args)
9267 + DSP_STATUS status = DSP_SOK;
9268 + struct DSP_UUID nodeId;
9269 + u32 cbDataSize;
9270 + u32 *pSize = (u32 *)args->ARGS_NODE_ALLOCATE.pArgs;
9271 + u8 *pArgs = NULL;
9272 + struct DSP_NODEATTRIN attrIn, *pAttrIn = NULL;
9273 + struct NODE_OBJECT *hNode;
9275 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Allocate: entered\n");
9277 + /* Optional argument */
9278 + if (pSize) {
9279 + if (get_user(cbDataSize, pSize))
9280 + status = DSP_EFAIL;
9282 + cbDataSize += sizeof(u32);
9283 + if (DSP_SUCCEEDED(status)) {
9284 + pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
9285 + if (pArgs == NULL)
9286 + status = DSP_EMEMORY;
9289 + cp_fm_usr(pArgs, args->ARGS_NODE_ALLOCATE.pArgs, status,
9290 + cbDataSize);
9292 + cp_fm_usr(&nodeId, args->ARGS_NODE_ALLOCATE.pNodeID, status, 1);
9293 + /* Optional argument */
9294 + if (args->ARGS_NODE_ALLOCATE.pAttrIn) {
9295 + cp_fm_usr(&attrIn, args->ARGS_NODE_ALLOCATE.pAttrIn, status, 1);
9296 + if (DSP_SUCCEEDED(status))
9297 + pAttrIn = &attrIn;
9300 + if (DSP_SUCCEEDED(status)) {
9301 + status = NODE_Allocate(args->ARGS_NODE_ALLOCATE.hProcessor,
9302 + &nodeId, (struct DSP_CBDATA *)pArgs,
9303 + pAttrIn, &hNode);
9305 + cp_to_usr(args->ARGS_NODE_ALLOCATE.phNode, &hNode, status, 1);
9306 + if (pArgs)
9307 + MEM_Free(pArgs);
9309 + return status;
9313 + * ======== NODEWRAP_AllocMsgBuf ========
9314 + */
9315 +u32 NODEWRAP_AllocMsgBuf(union Trapped_Args *args)
9317 + DSP_STATUS status = DSP_SOK;
9318 + struct DSP_BUFFERATTR *pAttr = NULL;
9319 + struct DSP_BUFFERATTR attr;
9320 + u8 *pBuffer = NULL;
9322 + if (args->ARGS_NODE_ALLOCMSGBUF.pAttr) { /* Optional argument */
9323 + cp_fm_usr(&attr, args->ARGS_NODE_ALLOCMSGBUF.pAttr, status, 1);
9324 + if (DSP_SUCCEEDED(status))
9325 + pAttr = &attr;
9328 + /* IN OUT argument */
9329 + cp_fm_usr(&pBuffer, args->ARGS_NODE_ALLOCMSGBUF.pBuffer, status, 1);
9330 + if (DSP_SUCCEEDED(status)) {
9331 + status = NODE_AllocMsgBuf(args->ARGS_NODE_ALLOCMSGBUF.hNode,
9332 + args->ARGS_NODE_ALLOCMSGBUF.uSize,
9333 + pAttr, &pBuffer);
9335 + cp_to_usr(args->ARGS_NODE_ALLOCMSGBUF.pBuffer, &pBuffer, status, 1)
9336 + return status;
9340 + * ======== NODEWRAP_ChangePriority ========
9341 + */
9342 +u32 NODEWRAP_ChangePriority(union Trapped_Args *args)
9344 + u32 retVal;
9346 + GT_0trace(WCD_debugMask, GT_ENTER,
9347 + "NODEWRAP_ChangePriority: entered\n");
9348 + retVal = NODE_ChangePriority(args->ARGS_NODE_CHANGEPRIORITY.hNode,
9349 + args->ARGS_NODE_CHANGEPRIORITY.iPriority);
9351 + return retVal;
9355 + * ======== NODEWRAP_Connect ========
9356 + */
9357 +u32 NODEWRAP_Connect(union Trapped_Args *args)
9359 + DSP_STATUS status = DSP_SOK;
9360 + struct DSP_STRMATTR attrs;
9361 + struct DSP_STRMATTR *pAttrs = NULL;
9362 + u32 cbDataSize;
9363 + u32 *pSize = (u32 *)args->ARGS_NODE_CONNECT.pConnParam;
9364 + u8 *pArgs = NULL;
9366 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Connect: entered\n");
9368 + /* Optional argument */
9369 + if (pSize) {
9370 + if (get_user(cbDataSize, pSize))
9371 + status = DSP_EFAIL;
9373 + cbDataSize += sizeof(u32);
9374 + if (DSP_SUCCEEDED(status)) {
9375 + pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
9376 + if (pArgs == NULL)
9377 + status = DSP_EMEMORY;
9380 + cp_fm_usr(pArgs, args->ARGS_NODE_CONNECT.pConnParam, status,
9381 + cbDataSize);
9383 + if (args->ARGS_NODE_CONNECT.pAttrs) { /* Optional argument */
9384 + cp_fm_usr(&attrs, args->ARGS_NODE_CONNECT.pAttrs, status, 1);
9385 + if (DSP_SUCCEEDED(status))
9386 + pAttrs = &attrs;
9389 + if (DSP_SUCCEEDED(status)) {
9390 + status = NODE_Connect(args->ARGS_NODE_CONNECT.hNode,
9391 + args->ARGS_NODE_CONNECT.uStream,
9392 + args->ARGS_NODE_CONNECT.hOtherNode,
9393 + args->ARGS_NODE_CONNECT.uOtherStream,
9394 + pAttrs, (struct DSP_CBDATA *)pArgs);
9396 + if (pArgs)
9397 + MEM_Free(pArgs);
9399 + return status;
9403 + * ======== NODEWRAP_Create ========
9404 + */
9405 +u32 NODEWRAP_Create(union Trapped_Args *args)
9407 + u32 retVal;
9409 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Create: entered\n");
9410 + retVal = NODE_Create(args->ARGS_NODE_CREATE.hNode);
9412 + return retVal;
9416 + * ======== NODEWRAP_Delete ========
9417 + */
9418 +u32 NODEWRAP_Delete(union Trapped_Args *args)
9420 + u32 retVal;
9422 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Delete: entered\n");
9423 + retVal = NODE_Delete(args->ARGS_NODE_DELETE.hNode);
9425 + return retVal;
9429 + * ======== NODEWRAP_FreeMsgBuf ========
9430 + */
9431 +u32 NODEWRAP_FreeMsgBuf(union Trapped_Args *args)
9433 + DSP_STATUS status = DSP_SOK;
9434 + struct DSP_BUFFERATTR *pAttr = NULL;
9435 + struct DSP_BUFFERATTR attr;
9436 + if (args->ARGS_NODE_FREEMSGBUF.pAttr) { /* Optional argument */
9437 + cp_fm_usr(&attr, args->ARGS_NODE_FREEMSGBUF.pAttr, status, 1);
9438 + if (DSP_SUCCEEDED(status))
9439 + pAttr = &attr;
9442 + if (DSP_SUCCEEDED(status)) {
9443 + status = NODE_FreeMsgBuf(args->ARGS_NODE_FREEMSGBUF.hNode,
9444 + args->ARGS_NODE_FREEMSGBUF.pBuffer,
9445 + pAttr);
9448 + return status;
9452 + * ======== NODEWRAP_GetAttr ========
9453 + */
9454 +u32 NODEWRAP_GetAttr(union Trapped_Args *args)
9456 + DSP_STATUS status = DSP_SOK;
9457 + struct DSP_NODEATTR attr;
9459 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetAttr: entered\n");
9461 + status = NODE_GetAttr(args->ARGS_NODE_GETATTR.hNode, &attr,
9462 + args->ARGS_NODE_GETATTR.uAttrSize);
9463 + cp_to_usr(args->ARGS_NODE_GETATTR.pAttr, &attr, status, 1);
9465 + return status;
9469 + * ======== NODEWRAP_GetMessage ========
9470 + */
9471 +u32 NODEWRAP_GetMessage(union Trapped_Args *args)
9473 + DSP_STATUS status;
9474 + struct DSP_MSG msg;
9476 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetMessage: entered\n");
9478 + status = NODE_GetMessage(args->ARGS_NODE_GETMESSAGE.hNode, &msg,
9479 + args->ARGS_NODE_GETMESSAGE.uTimeout);
9481 + cp_to_usr(args->ARGS_NODE_GETMESSAGE.pMessage, &msg, status, 1);
9483 + return status;
9487 + * ======== NODEWRAP_Pause ========
9488 + */
9489 +u32 NODEWRAP_Pause(union Trapped_Args *args)
9491 + u32 retVal;
9493 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Pause: entered\n");
9494 + retVal = NODE_Pause(args->ARGS_NODE_PAUSE.hNode);
9496 + return retVal;
9500 + * ======== NODEWRAP_PutMessage ========
9501 + */
9502 +u32 NODEWRAP_PutMessage(union Trapped_Args *args)
9504 + DSP_STATUS status = DSP_SOK;
9505 + struct DSP_MSG msg;
9507 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_PutMessage: entered\n");
9509 + cp_fm_usr(&msg, args->ARGS_NODE_PUTMESSAGE.pMessage, status, 1);
9511 + if (DSP_SUCCEEDED(status)) {
9512 + status = NODE_PutMessage(args->ARGS_NODE_PUTMESSAGE.hNode, &msg,
9513 + args->ARGS_NODE_PUTMESSAGE.uTimeout);
9516 + return status;
9520 + * ======== NODEWRAP_RegisterNotify ========
9521 + */
9522 +u32 NODEWRAP_RegisterNotify(union Trapped_Args *args)
9524 + DSP_STATUS status = DSP_SOK;
9525 + struct DSP_NOTIFICATION notification;
9527 + GT_0trace(WCD_debugMask, GT_ENTER,
9528 + "NODEWRAP_RegisterNotify: entered\n");
9530 + /* Initialize the notification data structure */
9531 + notification.psName = NULL;
9532 + notification.handle = NULL;
9534 + status = NODE_RegisterNotify(args->ARGS_NODE_REGISTERNOTIFY.hNode,
9535 + args->ARGS_NODE_REGISTERNOTIFY.uEventMask,
9536 + args->ARGS_NODE_REGISTERNOTIFY.uNotifyType,
9537 + &notification);
9538 + cp_to_usr(args->ARGS_NODE_REGISTERNOTIFY.hNotification, &notification,
9539 + status, 1);
9540 + return status;
9544 + * ======== NODEWRAP_Run ========
9545 + */
9546 +u32 NODEWRAP_Run(union Trapped_Args *args)
9548 + u32 retVal;
9550 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Run: entered\n");
9551 + retVal = NODE_Run(args->ARGS_NODE_RUN.hNode);
9553 + return retVal;
9557 + * ======== NODEWRAP_Terminate ========
9558 + */
9559 +u32 NODEWRAP_Terminate(union Trapped_Args *args)
9561 + DSP_STATUS status;
9562 + DSP_STATUS tempstatus;
9564 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Terminate: entered\n");
9566 + status = NODE_Terminate(args->ARGS_NODE_TERMINATE.hNode, &tempstatus);
9568 + cp_to_usr(args->ARGS_NODE_TERMINATE.pStatus, &tempstatus, status, 1);
9570 + return status;
9575 + * ======== NODEWRAP_GetUUIDProps ========
9576 + */
9577 +u32 NODEWRAP_GetUUIDProps(union Trapped_Args *args)
9579 + DSP_STATUS status = DSP_SOK;
9580 + struct DSP_UUID nodeId;
9581 + struct DSP_NDBPROPS *pnodeProps = NULL;
9583 + GT_0trace(WCD_debugMask, GT_ENTER,
9584 + "NODEWRAP_GetUUIDPropste: entered\n");
9587 + cp_fm_usr(&nodeId, args->ARGS_NODE_GETUUIDPROPS.pNodeID, status, 1);
9588 + pnodeProps = MEM_Alloc(sizeof(struct DSP_NDBPROPS), MEM_NONPAGED);
9589 + if (pnodeProps != NULL) {
9590 + status = NODE_GetUUIDProps(args->
9591 + ARGS_NODE_GETUUIDPROPS.hProcessor,
9592 + &nodeId, pnodeProps);
9593 + cp_to_usr(args->ARGS_NODE_GETUUIDPROPS.pNodeProps, pnodeProps,
9594 + status, 1);
9595 + } else
9596 + status = DSP_EMEMORY;
9597 + if (pnodeProps)
9598 + MEM_Free(pnodeProps);
9599 + return status;
9603 + * ======== STRMWRAP_AllocateBuffer ========
9604 + */
9605 +u32 STRMWRAP_AllocateBuffer(union Trapped_Args *args)
9607 + DSP_STATUS status;
9608 + u8 **apBuffer = NULL;
9609 + u32 uNumBufs = args->ARGS_STRM_ALLOCATEBUFFER.uNumBufs;
9611 + DBC_Require(uNumBufs <= MAX_BUFS);
9613 + apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED);
9615 + status = STRM_AllocateBuffer(args->ARGS_STRM_ALLOCATEBUFFER.hStream,
9616 + args->ARGS_STRM_ALLOCATEBUFFER.uSize,
9617 + apBuffer, uNumBufs);
9618 + cp_to_usr(args->ARGS_STRM_ALLOCATEBUFFER.apBuffer, apBuffer, status,
9619 + uNumBufs);
9620 + if (apBuffer)
9621 + MEM_Free(apBuffer);
9623 + return status;
9627 + * ======== STRMWRAP_Close ========
9628 + */
9629 +u32 STRMWRAP_Close(union Trapped_Args *args)
9631 + u32 retVal;
9633 + retVal = STRM_Close(args->ARGS_STRM_CLOSE.hStream);
9635 + return retVal;
9639 + * ======== STRMWRAP_FreeBuffer ========
9640 + */
9641 +u32 STRMWRAP_FreeBuffer(union Trapped_Args *args)
9643 + DSP_STATUS status = DSP_SOK;
9644 + u8 **apBuffer = NULL;
9645 + u32 uNumBufs = args->ARGS_STRM_FREEBUFFER.uNumBufs;
9647 + DBC_Require(uNumBufs <= MAX_BUFS);
9649 + apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED);
9651 + cp_fm_usr(apBuffer, args->ARGS_STRM_FREEBUFFER.apBuffer, status,
9652 + uNumBufs);
9654 + if (DSP_SUCCEEDED(status)) {
9655 + status = STRM_FreeBuffer(args->ARGS_STRM_FREEBUFFER.hStream,
9656 + apBuffer, uNumBufs);
9658 + cp_to_usr(args->ARGS_STRM_FREEBUFFER.apBuffer, apBuffer, status,
9659 + uNumBufs);
9660 + if (apBuffer)
9661 + MEM_Free(apBuffer);
9663 + return status;
9667 + * ======== STRMWRAP_GetEventHandle ========
9668 + */
9669 +u32 STRMWRAP_GetEventHandle(union Trapped_Args *args)
9671 + return DSP_ENOTIMPL;
9675 + * ======== STRMWRAP_GetInfo ========
9676 + */
9677 +u32 STRMWRAP_GetInfo(union Trapped_Args *args)
9679 + DSP_STATUS status = DSP_SOK;
9680 + struct STRM_INFO strmInfo;
9681 + struct DSP_STREAMINFO user;
9682 + struct DSP_STREAMINFO *temp;
9684 + cp_fm_usr(&strmInfo, args->ARGS_STRM_GETINFO.pStreamInfo, status, 1);
9685 + temp = strmInfo.pUser;
9687 + strmInfo.pUser = &user;
9689 + if (DSP_SUCCEEDED(status)) {
9690 + status = STRM_GetInfo(args->ARGS_STRM_GETINFO.hStream,
9691 + &strmInfo, args->ARGS_STRM_GETINFO.uStreamInfoSize);
9693 + cp_to_usr(temp, strmInfo.pUser, status, 1);
9694 + strmInfo.pUser = temp;
9695 + cp_to_usr(args->ARGS_STRM_GETINFO.pStreamInfo, &strmInfo, status, 1);
9696 + return status;
9700 + * ======== STRMWRAP_Idle ========
9701 + */
9702 +u32 STRMWRAP_Idle(union Trapped_Args *args)
9704 + u32 retVal;
9706 + retVal = STRM_Idle(args->ARGS_STRM_IDLE.hStream,
9707 + args->ARGS_STRM_IDLE.bFlush);
9709 + return retVal;
9713 + * ======== STRMWRAP_Issue ========
9714 + */
9715 +u32 STRMWRAP_Issue(union Trapped_Args *args)
9717 + u32 retVal;
9719 + retVal = STRM_Issue(args->ARGS_STRM_ISSUE.hStream,
9720 + args->ARGS_STRM_ISSUE.pBuffer,
9721 + args->ARGS_STRM_ISSUE.dwBytes,
9722 + args->ARGS_STRM_ISSUE.dwBufSize,
9723 + args->ARGS_STRM_ISSUE.dwArg);
9725 + /* This is a user space pointer */
9726 + return retVal;
9730 + * ======== STRMWRAP_Open ========
9731 + */
9732 +u32 STRMWRAP_Open(union Trapped_Args *args)
9734 + DSP_STATUS status = DSP_SOK;
9735 + struct STRM_ATTR attr;
9736 + struct STRM_OBJECT *pStrm;
9737 + struct DSP_STREAMATTRIN strmAttrIn;
9739 + cp_fm_usr(&attr, args->ARGS_STRM_OPEN.pAttrIn, status, 1);
9741 + if (attr.pStreamAttrIn != NULL) { /* Optional argument */
9742 + cp_fm_usr(&strmAttrIn, attr.pStreamAttrIn, status, 1);
9743 + if (DSP_SUCCEEDED(status))
9744 + attr.pStreamAttrIn = &strmAttrIn;
9747 + status = STRM_Open(args->ARGS_STRM_OPEN.hNode,
9748 + args->ARGS_STRM_OPEN.uDirection,
9749 + args->ARGS_STRM_OPEN.uIndex, &attr, &pStrm);
9750 + cp_to_usr(args->ARGS_STRM_OPEN.phStream, &pStrm, status, 1);
9751 + return status;
9755 + * ======== STRMWRAP_Reclaim ========
9756 + */
9757 +u32 STRMWRAP_Reclaim(union Trapped_Args *args)
9759 + DSP_STATUS status = DSP_SOK;
9760 + u8 *pBufPtr;
9761 + u32 ulBytes;
9762 + u32 dwArg;
9763 + u32 ulBufSize;
9765 + status = STRM_Reclaim(args->ARGS_STRM_RECLAIM.hStream, &pBufPtr,
9766 + &ulBytes, &ulBufSize, &dwArg);
9767 + cp_to_usr(args->ARGS_STRM_RECLAIM.pBufPtr, &pBufPtr, status, 1);
9768 + cp_to_usr(args->ARGS_STRM_RECLAIM.pBytes, &ulBytes, status, 1);
9769 + cp_to_usr(args->ARGS_STRM_RECLAIM.pdwArg, &dwArg, status, 1);
9771 + if (args->ARGS_STRM_RECLAIM.pBufSize != NULL) {
9772 + cp_to_usr(args->ARGS_STRM_RECLAIM.pBufSize, &ulBufSize,
9773 + status, 1);
9776 + return status;
9780 + * ======== STRMWRAP_RegisterNotify ========
9781 + */
9782 +u32 STRMWRAP_RegisterNotify(union Trapped_Args *args)
9784 + DSP_STATUS status = DSP_SOK;
9785 + struct DSP_NOTIFICATION notification;
9787 + GT_0trace(WCD_debugMask, GT_ENTER,
9788 + "NODEWRAP_RegisterNotify: entered\n");
9790 + /* Initialize the notification data structure */
9791 + notification.psName = NULL;
9792 + notification.handle = NULL;
9794 + status = STRM_RegisterNotify(args->ARGS_STRM_REGISTERNOTIFY.hStream,
9795 + args->ARGS_STRM_REGISTERNOTIFY.uEventMask,
9796 + args->ARGS_STRM_REGISTERNOTIFY.uNotifyType,
9797 + &notification);
9798 + cp_to_usr(args->ARGS_STRM_REGISTERNOTIFY.hNotification, &notification,
9799 + status, 1);
9801 + return status;
9805 + * ======== STRMWRAP_Select ========
9806 + */
9807 +u32 STRMWRAP_Select(union Trapped_Args *args)
9809 + u32 mask;
9810 + struct STRM_OBJECT *aStrmTab[MAX_STREAMS];
9811 + DSP_STATUS status = DSP_SOK;
9813 + DBC_Require(args->ARGS_STRM_SELECT.nStreams <= MAX_STREAMS);
9815 + cp_fm_usr(aStrmTab, args->ARGS_STRM_SELECT.aStreamTab, status,
9816 + args->ARGS_STRM_SELECT.nStreams);
9817 + if (DSP_SUCCEEDED(status)) {
9818 + status = STRM_Select(aStrmTab, args->ARGS_STRM_SELECT.nStreams,
9819 + &mask, args->ARGS_STRM_SELECT.uTimeout);
9821 + cp_to_usr(args->ARGS_STRM_SELECT.pMask, &mask, status, 1);
9822 + return status;
9825 +/* CMM */
9828 + * ======== CMMWRAP_CallocBuf ========
9829 + */
9830 +u32 CMMWRAP_CallocBuf(union Trapped_Args *args)
9832 + /* This operation is done in kernel */
9833 + return DSP_ENOTIMPL;
9837 + * ======== CMMWRAP_FreeBuf ========
9838 + */
9839 +u32 CMMWRAP_FreeBuf(union Trapped_Args *args)
9841 + /* This operation is done in kernel */
9842 + return DSP_ENOTIMPL;
9846 + * ======== CMMWRAP_GetHandle ========
9847 + */
9848 +u32 CMMWRAP_GetHandle(union Trapped_Args *args)
9850 + DSP_STATUS status = DSP_SOK;
9851 + struct CMM_OBJECT *hCmmMgr;
9853 + status = CMM_GetHandle(args->ARGS_CMM_GETHANDLE.hProcessor, &hCmmMgr);
9855 + cp_to_usr(args->ARGS_CMM_GETHANDLE.phCmmMgr, &hCmmMgr, status, 1);
9857 + return status;
9861 + * ======== CMMWRAP_GetInfo ========
9862 + */
9863 +u32 CMMWRAP_GetInfo(union Trapped_Args *args)
9865 + DSP_STATUS status = DSP_SOK;
9866 + struct CMM_INFO cmmInfo;
9868 + status = CMM_GetInfo(args->ARGS_CMM_GETINFO.hCmmMgr, &cmmInfo);
9870 + cp_to_usr(args->ARGS_CMM_GETINFO.pCmmInfo, &cmmInfo, status, 1);
9872 + return status;
9875 1.5.5.1.357.g1af8b