Update from omapzoom 18-Aug-2008
[bridge-dev.git] / 0006-TI-DSP-BRIDGE-Platform-Manager.patch
blob89eb0779c2c479f2b50426e4d78ca07164ac2e77
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 Index: lk/drivers/dsp/bridge/pmgr/chnl.c
43 ===================================================================
44 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
45 +++ lk/drivers/dsp/bridge/pmgr/chnl.c 2008-08-18 10:38:37.000000000 +0300
46 @@ -0,0 +1,517 @@
47 +/*
48 + * linux/drivers/dsp/bridge/pmgr/chnl.c
49 + *
50 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
51 + *
52 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
53 + *
54 + * This package is free software; you can redistribute it and/or modify
55 + * it under the terms of the GNU General Public License version 2 as
56 + * published by the Free Software Foundation.
57 + *
58 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
59 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
60 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
61 + */
64 +/*
65 + * ======== chnl.c ========
66 + * Description:
67 + * WCD channel interface: multiplexes data streams through the single
68 + * physical link managed by a 'Bridge mini-driver.
69 + *
70 + * Public Functions:
71 + * CHNL_Close
72 + * CHNL_CloseOrphans
73 + * CHNL_Create
74 + * CHNL_Destroy
75 + * CHNL_Exit
76 + * CHNL_GetHandle
77 + * CHNL_GetProcessHandle
78 + * CHNL_Init
79 + * CHNL_Open
80 + *
81 + * Notes:
82 + * This interface is basically a pass through to the WMD CHNL functions,
83 + * except for the CHNL_Get() accessor functions which call
84 + * WMD_CHNL_GetInfo().
85 + *
86 + *! Revision History:
87 + *! ================
88 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
89 + *! 07-Jan-2002 ag CHNL_CloseOrphans() now closes supported # of channels.
90 + *! 17-Nov-2000 jeh Removed IRQ, shared memory stuff from CHNL_Create.
91 + *! 28-Feb-2000 rr: New GT USage Implementation
92 + *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from
93 + *! SERVICES)
94 + *! 21-Jan-2000 ag: Added code review comments.
95 + *! 13-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject.
96 + *! 08-Dec-1999 ag: CHNL_[Alloc|Free]Buffer bufs taken from client process heap.
97 + *! 02-Dec-1999 ag: Implemented CHNL_GetEventHandle().
98 + *! 17-Nov-1999 ag: CHNL_AllocBuffer() allocs extra word for process mapping.
99 + *! 28-Oct-1999 ag: WinCE port. Search for "WinCE" for changes(TBR).
100 + *! 07-Jan-1998 gp: CHNL_[Alloc|Free]Buffer now call MEM_UMB functions.
101 + *! 22-Oct-1997 gp: Removed requirement in CHNL_Open that hReserved1 != NULL.
102 + *! 30-Aug-1997 cr: Renamed cfg.h wbwcd.h b/c of WINNT file name collision.
103 + *! 10-Mar-1997 gp: Added GT trace.
104 + *! 14-Jan-1997 gp: Updated based on code review feedback.
105 + *! 03-Jan-1997 gp: Moved CHNL_AllocBuffer/CHNL_FreeBuffer code from udspsys.
106 + *! 14-Dec-1996 gp: Added uChnlId parameter to CHNL_Open().
107 + *! 09-Sep-1996 gp: Added CHNL_GetProcessHandle().
108 + *! 15-Jul-1996 gp: Created.
109 + */
111 +/* ----------------------------------- Host OS */
112 +#include <host_os.h>
114 +/* ----------------------------------- DSP/BIOS Bridge */
115 +#include <std.h>
116 +#include <dbdefs.h>
117 +#include <errbase.h>
119 +/* ----------------------------------- Trace & Debug */
120 +#include <dbc.h>
121 +#include <gt.h>
123 +/* ----------------------------------- OS Adaptation Layer */
124 +#include <cfg.h>
125 +#include <csl.h>
126 +#include <dpc.h>
127 +#include <isr.h>
128 +#include <list.h>
129 +#include <mem.h>
130 +#include <sync.h>
132 +/* ----------------------------------- Platform Manager */
133 +#include <proc.h>
134 +#include <dev.h>
136 +/* ----------------------------------- Others */
137 +#include <chnlpriv.h>
138 +#include <chnlobj.h>
140 +/* ----------------------------------- This */
141 +#include <chnl.h>
143 +/* ----------------------------------- Globals */
144 +static u32 cRefs;
145 +#if GT_TRACE
146 +static struct GT_Mask CHNL_DebugMask = { NULL, NULL }; /* WCD CHNL Mask */
147 +#endif
149 +/* ----------------------------------- Function Prototypes */
150 +static DSP_STATUS GetNumOpenChannels(struct CHNL_MGR *hChnlMgr,
151 + OUT u32 *pcOpenChannels);
153 +static DSP_STATUS GetNumChannels(struct CHNL_MGR *hChnlMgr,
154 + OUT u32 *pcChannels);
157 + * ======== CHNL_Close ========
158 + * Purpose:
159 + * Ensures all pending I/O on this channel is cancelled, discards all
160 + * queued I/O completion notifications, then frees the resources
161 + * allocated for this channel, and makes the corresponding logical
162 + * channel id available for subsequent use.
163 + */
164 +DSP_STATUS CHNL_Close(struct CHNL_OBJECT *hChnl)
166 + DSP_STATUS status;
167 + struct CHNL_OBJECT_ *pChnl = (struct CHNL_OBJECT_ *)hChnl;
168 + struct WMD_DRV_INTERFACE *pIntfFxns;
170 + DBC_Require(cRefs > 0);
172 + GT_1trace(CHNL_DebugMask, GT_ENTER,
173 + "Entered CHNL_Close:hChnl: 0x%x\n",
174 + hChnl);
176 + if (CHNL_IsValidChnl(pChnl)) {
177 + pIntfFxns = pChnl->pChnlMgr->pIntfFxns;
178 + status = (*pIntfFxns->pfnChnlClose) (hChnl);
179 + } else {
180 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
181 + "CHNL_Close:Invalid Handle\n");
182 + status = DSP_EHANDLE;
184 + GT_2trace(CHNL_DebugMask, GT_ENTER,
185 + "Exiting CHNL_Close:hChnl: 0x%x, status:"
186 + " 0x%x\n", hChnl, status);
187 + return status;
191 + * ======== CHNL_CloseOrphans ========
192 + * Purpose:
193 + * Close open channels orphaned by a closing process.
194 + */
195 +DSP_STATUS CHNL_CloseOrphans(struct CHNL_MGR *hChnlMgr, HANDLE hProcess)
197 + u32 uChnlID;
198 + DSP_STATUS status = DSP_SFALSE;
199 + HANDLE hProc;
200 + u32 cOpenChannels;
201 + u32 cTotalChnls;
202 + struct CHNL_OBJECT *hChnl;
204 + DBC_Require(cRefs > 0);
206 + GT_2trace(CHNL_DebugMask, GT_ENTER,
207 + "Enter CHNL_CloseOrphans hChnlMgr "
208 + "0x%x\t\nhProcess: 0x%x\n", hChnlMgr, hProcess);
209 + if (!CHNL_IsValidMgr((struct CHNL_MGR_ *)hChnlMgr)) {
210 + status = DSP_EHANDLE;
211 + goto func_end;
213 + if (DSP_SUCCEEDED(GetNumOpenChannels(hChnlMgr, &cOpenChannels)) &&
214 + (cOpenChannels > 0)) {
215 + if (DSP_FAILED(GetNumChannels(hChnlMgr, &cTotalChnls)))
216 + goto func_end;
218 + /* For each channel (except for RMS), get process handle: */
219 + for (uChnlID = 2; uChnlID < cTotalChnls; uChnlID++) {
220 + if (DSP_FAILED(CHNL_GetHandle(hChnlMgr, uChnlID,
221 + &hChnl))) {
222 + continue;
224 + if (DSP_FAILED(CHNL_GetProcessHandle(hChnl,
225 + &hProc))) {
226 + continue;
228 + /* See if channel owned by this process: */
229 + if (hProc == hProcess) {
230 + /* If so, close it now. */
231 + CHNL_Close(hChnl);
232 + status = DSP_SOK;
236 +func_end:
237 + GT_1trace(CHNL_DebugMask, GT_ENTER, "CHNL_CloseOrphans status 0x%x\n",
238 + status);
240 + return status;
244 + * ======== CHNL_Create ========
245 + * Purpose:
246 + * Create a channel manager object, responsible for opening new channels
247 + * and closing old ones for a given 'Bridge board.
248 + */
249 +DSP_STATUS CHNL_Create(OUT struct CHNL_MGR **phChnlMgr,
250 + struct DEV_OBJECT *hDevObject,
251 + IN CONST struct CHNL_MGRATTRS *pMgrAttrs)
253 + DSP_STATUS status;
254 + struct CHNL_MGR *hChnlMgr;
255 + struct CHNL_MGR_ *pChnlMgr = NULL;
257 + DBC_Require(cRefs > 0);
258 + DBC_Require(phChnlMgr != NULL);
259 + DBC_Require(pMgrAttrs != NULL);
261 + GT_3trace(CHNL_DebugMask, GT_ENTER,
262 + "Entered CHNL_Create: phChnlMgr: 0x%x\t"
263 + "hDevObject: 0x%x\tpMgrAttrs:0x%x\n",
264 + phChnlMgr, hDevObject, pMgrAttrs);
266 + *phChnlMgr = NULL;
268 + /* Validate args: */
269 + if ((0 < pMgrAttrs->cChannels) &&
270 + (pMgrAttrs->cChannels <= CHNL_MAXCHANNELS)) {
271 + status = DSP_SOK;
272 + } else if (pMgrAttrs->cChannels == 0) {
273 + status = DSP_EINVALIDARG;
274 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
275 + "CHNL_Create:Invalid Args\n");
276 + } else {
277 + status = CHNL_E_MAXCHANNELS;
278 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
279 + "CHNL_Create:Error Max Channels\n");
281 + if (pMgrAttrs->uWordSize == 0) {
282 + status = CHNL_E_INVALIDWORDSIZE;
283 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
284 + "CHNL_Create:Invalid Word size\n");
286 + if (DSP_SUCCEEDED(status)) {
287 + status = DEV_GetChnlMgr(hDevObject, &hChnlMgr);
288 + if (DSP_SUCCEEDED(status) && hChnlMgr != NULL)
289 + status = CHNL_E_MGREXISTS;
293 + if (DSP_SUCCEEDED(status)) {
294 + struct WMD_DRV_INTERFACE *pIntfFxns;
295 + DEV_GetIntfFxns(hDevObject, &pIntfFxns);
296 + /* Let WMD channel module finish the create: */
297 + status = (*pIntfFxns->pfnChnlCreate)(&hChnlMgr, hDevObject,
298 + pMgrAttrs);
299 + if (DSP_SUCCEEDED(status)) {
300 + /* Fill in WCD channel module's fields of the
301 + * CHNL_MGR structure */
302 + pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
303 + pChnlMgr->pIntfFxns = pIntfFxns;
304 + /* Finally, return the new channel manager handle: */
305 + *phChnlMgr = hChnlMgr;
306 + GT_1trace(CHNL_DebugMask, GT_1CLASS,
307 + "CHNL_Create: Success pChnlMgr:"
308 + "0x%x\n", pChnlMgr);
312 + GT_2trace(CHNL_DebugMask, GT_ENTER,
313 + "Exiting CHNL_Create: pChnlMgr: 0x%x,"
314 + "status: 0x%x\n", pChnlMgr, status);
315 + DBC_Ensure(DSP_FAILED(status) || CHNL_IsValidMgr(pChnlMgr));
317 + return status;
321 + * ======== CHNL_Destroy ========
322 + * Purpose:
323 + * Close all open channels, and destroy the channel manager.
324 + */
325 +DSP_STATUS CHNL_Destroy(struct CHNL_MGR *hChnlMgr)
327 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
328 + struct WMD_DRV_INTERFACE *pIntfFxns;
329 + DSP_STATUS status;
331 + DBC_Require(cRefs > 0);
333 + GT_1trace(CHNL_DebugMask, GT_ENTER,
334 + "Entered CHNL_Destroy: hChnlMgr: 0x%x\n", hChnlMgr);
335 + if (CHNL_IsValidMgr(pChnlMgr)) {
336 + pIntfFxns = pChnlMgr->pIntfFxns;
337 + /* Let WMD channel module destroy the CHNL_MGR: */
338 + status = (*pIntfFxns->pfnChnlDestroy)(hChnlMgr);
339 + } else {
340 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
341 + "CHNL_Destroy:Invalid Handle\n");
342 + status = DSP_EHANDLE;
345 + GT_2trace(CHNL_DebugMask, GT_ENTER,
346 + "Exiting CHNL_Destroy: pChnlMgr: 0x%x,"
347 + " status:0x%x\n", pChnlMgr, status);
348 + DBC_Ensure(DSP_FAILED(status) || !CHNL_IsValidMgr(pChnlMgr));
350 + return status;
354 + * ======== CHNL_Exit ========
355 + * Purpose:
356 + * Discontinue usage of the CHNL module.
357 + */
358 +void CHNL_Exit(void)
360 + DBC_Require(cRefs > 0);
362 + cRefs--;
364 + GT_1trace(CHNL_DebugMask, GT_5CLASS,
365 + "Entered CHNL_Exit, ref count: 0x%x\n", cRefs);
367 + DBC_Ensure(cRefs >= 0);
371 + * ======== CHNL_GetHandle ========
372 + * Purpose:
373 + * Retrieve the channel handle given the logical ID and channel manager.
374 + */
375 +DSP_STATUS CHNL_GetHandle(struct CHNL_MGR *hChnlMgr, u32 uChnlID,
376 + OUT struct CHNL_OBJECT **phChnl)
378 + DSP_STATUS status = DSP_SOK;
379 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
380 + struct WMD_DRV_INTERFACE *pIntfFxns;
381 + struct CHNL_MGRINFO chnlMgrInfo;
383 + DBC_Require(cRefs > 0);
385 + GT_3trace(CHNL_DebugMask, GT_ENTER, "Entered CHNL_GetHandle: hChnlMgr: "
386 + "0x%x\tuChnlID: 0x%x\t\nphChnl: 0x%x\n", hChnlMgr, uChnlID,
387 + phChnl);
388 + if (phChnl) {
389 + *phChnl = NULL;
390 + if (CHNL_IsValidMgr(pChnlMgr)) {
391 + pIntfFxns = pChnlMgr->pIntfFxns;
392 + status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr,
393 + uChnlID, &chnlMgrInfo);
394 + if (DSP_SUCCEEDED(status))
395 + *phChnl = chnlMgrInfo.hChnl;
397 + } else {
398 + status = DSP_EHANDLE;
399 + GT_0trace(CHNL_DebugMask, GT_7CLASS,
400 + "CHNL_GetHandle:Invalid Handle\n");
402 + } else {
403 + status = DSP_EPOINTER;
405 + GT_2trace(CHNL_DebugMask, GT_ENTER,
406 + "Exit CHNL_GetHandle: status: 0x%x\t\n"
407 + "hChnl: 0x%x\n", status, *phChnl);
408 + return status;
412 + * ======== CHNL_GetProcessHandle ========
413 + * Purpose:
414 + * Retrieve the handle of the process owning this channel.
415 + */
416 +DSP_STATUS CHNL_GetProcessHandle(struct CHNL_OBJECT *hChnl,
417 + OUT HANDLE *phProcess)
419 + DSP_STATUS status = DSP_SOK;
420 + struct CHNL_OBJECT_ *pChnl = (struct CHNL_OBJECT_ *)hChnl;
421 + struct WMD_DRV_INTERFACE *pIntfFxns;
422 + struct CHNL_INFO chnlInfo;
424 + DBC_Require(cRefs > 0);
426 + GT_2trace(CHNL_DebugMask, GT_ENTER,
427 + "Enter CHNL_GetProcessHandle: hChnl: "
428 + "0x%x\t\n phProcess: 0x%x\n", hChnl, phProcess);
429 + if (phProcess) {
430 + *phProcess = NULL;
431 + if (CHNL_IsValidChnl(pChnl)) {
432 + pIntfFxns = pChnl->pChnlMgr->pIntfFxns;
433 + status = (*pIntfFxns->pfnChnlGetInfo)(hChnl, &chnlInfo);
434 + if (DSP_SUCCEEDED(status))
435 + *phProcess = chnlInfo.hProcess;
437 + } else {
438 + status = DSP_EHANDLE;
440 + } else {
441 + status = DSP_EPOINTER;
443 + GT_2trace(CHNL_DebugMask, GT_ENTER,
444 + "Exit CHNL_GetProcessHandle: status: "
445 + "0x%x\t\n phProcess: 0x%x\n", status, *phProcess);
446 + return status;
450 + * ======== CHNL_Init ========
451 + * Purpose:
452 + * Initialize the CHNL module's private state.
453 + */
454 +bool CHNL_Init(void)
456 + bool fRetval = true;
458 + DBC_Require(cRefs >= 0);
460 + if (cRefs == 0) {
461 + DBC_Assert(!CHNL_DebugMask.flags);
462 + GT_create(&CHNL_DebugMask, "CH"); /* "CH" for CHannel */
465 + if (fRetval)
466 + cRefs++;
468 + GT_1trace(CHNL_DebugMask, GT_5CLASS,
469 + "Entered CHNL_Init, ref count: 0x%x\n",
470 + cRefs);
472 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
474 + return fRetval;
478 + * ======== GetNumOpenChannels ========
479 + * Purpose:
480 + * Retrieve number of open channels
481 + * Parameters:
482 + * hChnlMgr: Handle to a valid channel manager, or NULL.
483 + * pcOpenChannels: Location to store number of open channels.
484 + * Returns:
485 + * DSP_SOK: Success;
486 + * DSP_EHANDLE: Invalid hChnlMgr.
487 + * E_POINTER: pcOpenChannels == NULL.
488 + * Requires:
489 + * Ensures:
490 + * DSP_SOK: *pcOpenChannels points to a valid number
491 + * if pcOpenChannels != NULL.
492 + */
493 +static DSP_STATUS GetNumOpenChannels(struct CHNL_MGR *hChnlMgr,
494 + OUT u32 *pcOpenChannels)
496 + DSP_STATUS status = DSP_SOK;
497 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
498 + struct WMD_DRV_INTERFACE *pIntfFxns;
499 + struct CHNL_MGRINFO chnlMgrInfo;
501 + DBC_Require(cRefs > 0);
502 + if (pcOpenChannels) {
503 + *pcOpenChannels = 0;
504 + if (CHNL_IsValidMgr(pChnlMgr)) {
505 + pIntfFxns = pChnlMgr->pIntfFxns;
506 + status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr, 0,
507 + &chnlMgrInfo);
508 + if (DSP_SUCCEEDED(status))
509 + *pcOpenChannels = chnlMgrInfo.cOpenChannels;
511 + } else {
512 + status = DSP_EHANDLE;
514 + } else {
515 + status = DSP_EPOINTER;
517 + return status;
521 + * ======== GetNumOpenChannels ========
522 + * Purpose:
523 + * Retrieve number of total channels supported.
524 + * Parameters:
525 + * hChnlMgr: Handle to a valid channel manager, or NULL.
526 + * pcChannels: Location to store number of channels.
527 + * Returns:
528 + * DSP_SOK: Success;
529 + * DSP_EHANDLE: Invalid hChnlMgr.
530 + * E_POINTER: pcOpenChannels == NULL.
531 + * Requires:
532 + * Ensures:
533 + * DSP_SOK: *pcChannels points to a valid number
534 + * if pcOpenChannels != NULL.
535 + */
536 +static DSP_STATUS GetNumChannels(struct CHNL_MGR *hChnlMgr,
537 + OUT u32 *pcChannels)
539 + DSP_STATUS status = DSP_SOK;
540 + struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
541 + struct WMD_DRV_INTERFACE *pIntfFxns;
542 + struct CHNL_MGRINFO chnlMgrInfo;
544 + DBC_Require(cRefs > 0);
546 + if (pcChannels) {
547 + *pcChannels = 0;
548 + if (CHNL_IsValidMgr(pChnlMgr)) {
549 + pIntfFxns = pChnlMgr->pIntfFxns;
550 + status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr, 0,
551 + &chnlMgrInfo);
552 + if (DSP_SUCCEEDED(status))
553 + *pcChannels = chnlMgrInfo.cChannels;
555 + } else {
556 + status = DSP_EHANDLE;
558 + } else {
559 + status = DSP_EPOINTER;
561 + return status;
564 Index: lk/drivers/dsp/bridge/pmgr/chnlobj.h
565 ===================================================================
566 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
567 +++ lk/drivers/dsp/bridge/pmgr/chnlobj.h 2008-08-18 10:38:37.000000000 +0300
568 @@ -0,0 +1,71 @@
570 + * linux/drivers/dsp/bridge/pmgr/chnlobj.h
572 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
574 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
576 + * This package is free software; you can redistribute it and/or modify
577 + * it under the terms of the GNU General Public License version 2 as
578 + * published by the Free Software Foundation.
580 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
581 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
582 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
583 + */
587 + * ======== chnlobj.h ========
588 + * Description:
589 + * Structure subcomponents of channel class library channel objects which
590 + * are exposed to class driver from mini-driver.
592 + * Public Functions:
593 + * None.
595 + *! Revision History:
596 + *! ================
597 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
598 + *! 17-Nov-2000 jeh Removed some fields from CHNL_MGR_ to match CHNL_MGR
599 + *! structure defined in _chnl_sm.h.
600 + *! 16-Jan-1997 gp: Created from chnlpriv.h
601 + */
603 +#ifndef CHNLOBJ_
604 +#define CHNLOBJ_
606 +#include <chnldefs.h>
607 +#include <wmd.h>
609 +/* Object validateion macros: */
610 +#define CHNL_IsValidMgr(h) \
611 + ((h != NULL) && ((h)->dwSignature == CHNL_MGRSIGNATURE))
613 +#define CHNL_IsValidChnl(h)\
614 + ((h != NULL) && ((h)->dwSignature == CHNL_SIGNATURE))
617 + * This struct is the first field in a CHNL_MGR struct, as implemented in
618 + * a WMD channel class library. Other, implementation specific fields
619 + * follow this structure in memory.
620 + */
621 +struct CHNL_MGR_ {
622 + /* These must be the first fields in a CHNL_MGR struct: */
623 + u32 dwSignature; /* Used for object validation. */
624 + struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */
625 +} ;
628 + * This struct is the first field in a CHNL_OBJECT struct, as implemented in
629 + * a WMD channel class library. Other, implementation specific fields
630 + * follow this structure in memory.
631 + */
632 +struct CHNL_OBJECT_ {
633 + /* These must be the first fields in a CHNL_OBJECT struct: */
634 + u32 dwSignature; /* Used for object validation. */
635 + struct CHNL_MGR_ *pChnlMgr; /* Pointer back to channel manager. */
636 +} ;
638 +#endif /* CHNLOBJ_ */
640 Index: lk/drivers/dsp/bridge/pmgr/cmm.c
641 ===================================================================
642 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
643 +++ lk/drivers/dsp/bridge/pmgr/cmm.c 2008-08-18 10:38:37.000000000 +0300
644 @@ -0,0 +1,1290 @@
646 + * linux/drivers/dsp/bridge/pmgr/cmm.c
648 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
650 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
652 + * This package is free software; you can redistribute it and/or modify
653 + * it under the terms of the GNU General Public License version 2 as
654 + * published by the Free Software Foundation.
656 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
657 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
658 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
659 + */
663 + * ======== cmm.c ========
664 + * Purpose:
665 + * The Communication(Shared) Memory Management(CMM) module provides
666 + * shared memory management services for DSP/BIOS Bridge data streaming
667 + * and messaging.
669 + * Multiple shared memory segments can be registered with CMM.
670 + * Each registered SM segment is represented by a SM "allocator" that
671 + * describes a block of physically contiguous shared memory used for
672 + * future allocations by CMM.
674 + * Memory is coelesced back to the appropriate heap when a buffer is
675 + * freed.
677 + * Public Functions:
678 + * CMM_CallocBuf
679 + * CMM_Create
680 + * CMM_Destroy
681 + * CMM_Exit
682 + * CMM_FreeBuf
683 + * CMM_GetHandle
684 + * CMM_GetInfo
685 + * CMM_Init
686 + * CMM_RegisterGPPSMSeg
687 + * CMM_UnRegisterGPPSMSeg
689 + * The CMM_Xlator[xxx] routines below are used by Node and Stream
690 + * to perform SM address translation to the client process address space.
691 + * A "translator" object is created by a node/stream for each SM seg used.
693 + * Translator Routines:
694 + * CMM_XlatorAllocBuf
695 + * CMM_XlatorCreate
696 + * CMM_XlatorDelete
697 + * CMM_XlatorFreeBuf
698 + * CMM_XlatorInfo
699 + * CMM_XlatorTranslate
701 + * Private Functions:
702 + * AddToFreeList
703 + * GetAllocator
704 + * GetFreeBlock
705 + * GetNode
706 + * GetSlot
707 + * UnRegisterGPPSMSeg
709 + * Notes:
710 + * Va: Virtual address.
711 + * Pa: Physical or kernel system address.
713 + *! Revision History:
714 + *! ================
715 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
716 + *! 16-Feb-2002 ag Code review cleanup.
717 + *! PreOMAP address translation no longner supported.
718 + *! 30-Jan-2002 ag Updates to CMM_XlatorTranslate() per TII, ANSI C++
719 + *! warnings.
720 + *! 27-Jan-2002 ag Removed unused CMM_[Alloc][Free]Desc() & #ifdef USELOOKUP,
721 + *! & unused VALIDATECMM and VaPaConvert().
722 + *! Removed bFastXlate from CMM_XLATOR. Always fast lookup.
723 + *! 03-Jan-2002 ag Clear SM in CMM_AllocBuf(). Renamed to CMM_CallocBuf().
724 + *! 13-Nov-2001 ag Now delete pNodeFreeListHead and nodes in CMM_Destroy().
725 + *! 28-Aug-2001 ag CMM_GetHandle() returns CMM Mgr hndle given HPROCESSOR.
726 + *! Removed unused CMM_[Un]RegisterDSPSMSeg() &
727 + * CMM_[Un}ReserveVirtSpace fxns. Some cleanup.
728 + *! 12-Aug-2001 ag Exposed CMM_UnRegisterGPP[DSP]SMSeg.
729 + *! 13-Feb-2001 kc DSP/BIOS Bridge name update.
730 + *! 21-Dec-2000 rr GetFreeBlock checks for pAllocator.
731 + *! 09-Dec-2000 ag Added GPPPA2DSPPA, DSPPA2GPPPA macros.
732 + *! 05-Dec-2000 ag CMM_XlatorDelete() optionally frees SM bufs and descriptors.
733 + *! 30-Oct-2000 ag Buf size bug fixed in CMM_AllocBuf() causing leak.
734 + *! Revamped XlatorTranslate() routine.
735 + *! 10-Oct-2000 ag Added CMM_Xlator[xxx] functions.
736 + *! 02-Aug-2000 ag Created.
737 + *!
738 + */
740 +/* ----------------------------------- DSP/BIOS Bridge */
741 +#include <std.h>
742 +#include <dbdefs.h>
744 +/* ----------------------------------- Trace & Debug */
745 +#include <dbc.h>
746 +#include <errbase.h>
747 +#include <gt.h>
749 +/* ----------------------------------- OS Adaptation Layer */
750 +#include <cfg.h>
751 +#include <list.h>
752 +#include <mem.h>
753 +#include <prcs.h>
754 +#include <sync.h>
755 +#include <util.h>
757 +/* ----------------------------------- Platform Manager */
758 +#include <dev.h>
759 +#include <proc.h>
761 +/* ----------------------------------- This */
762 +#include <cmm.h>
764 +/* ----------------------------------- Defines, Data Structures, Typedefs */
765 +/* Object signatures */
766 +#define CMMSIGNATURE 0x004d4d43 /* "CMM" (in reverse) */
767 +#define SMEMSIGNATURE 0x4D454D53 /* "SMEM" SM space */
768 +#define CMMXLATESIGNATURE 0x584d4d43 /* "CMMX" CMM Xlator */
770 +#define NEXT_PA(pNode) (pNode->dwPA + pNode->ulSize)
772 +/* Other bus/platform translations */
773 +#define DSPPA2GPPPA(base, x, y) ((x)+(y))
774 +#define GPPPA2DSPPA(base, x, y) ((x)-(y))
777 + * Allocators define a block of contiguous memory used for future allocations.
779 + * sma - shared memory allocator.
780 + * vma - virtual memory allocator.(not used).
781 + */
782 +struct CMM_ALLOCATOR { /* sma */
783 + u32 dwSignature; /* SMA allocator signature SMEMSIGNATURE */
784 + unsigned int dwSmBase; /* Start of physical SM block */
785 + u32 ulSmSize; /* Size of SM block in bytes */
786 + unsigned int dwVmBase; /* Start of VM block. (Dev driver
787 + * context for 'sma') */
788 + u32 dwDSPPhysAddrOffset; /* DSP PA to GPP PA offset for this
789 + * SM space */
790 + /* CMM_ADDTO[SUBFROM]DSPPA, _POMAPEMIF2DSPBUS */
791 + enum CMM_CNVTTYPE cFactor;
792 + unsigned int dwDSPBase; /* DSP virt base byte address */
793 + u32 ulDSPSize; /* DSP seg size in bytes */
794 + struct CMM_OBJECT *hCmmMgr; /* back ref to parent mgr */
795 + struct LST_LIST *pFreeListHead; /* node list of available memory */
796 + struct LST_LIST *pInUseListHead; /* node list of memory in use */
797 +} ;
799 +struct CMM_XLATOR { /* Pa<->Va translator object */
800 + u32 dwSignature; /* "CMMX" */
801 + struct CMM_OBJECT *hCmmMgr; /* CMM object this translator associated */
802 + /*
803 + * Client process virtual base address that corresponds to phys SM
804 + * base address for translator's ulSegId.
805 + * Only 1 segment ID currently supported.
806 + */
807 + unsigned int dwVirtBase; /* virtual base address */
808 + u32 ulVirtSize; /* size of virt space in bytes */
809 + u32 ulSegId; /* Segment Id */
810 +} ;
812 +/* CMM Mgr */
813 +struct CMM_OBJECT {
814 + u32 dwSignature; /* Used for object validation */
815 + /*
816 + * Cmm Lock is used to serialize access mem manager for multi-threads.
817 + */
818 + struct SYNC_CSOBJECT *hCmmLock; /* Lock to access cmm mgr */
819 + struct LST_LIST *pNodeFreeListHead; /* Free list of memory nodes */
820 + u32 ulMinBlockSize; /* Min SM block; default 16 bytes */
821 + u32 dwPageSize; /* Memory Page size (1k/4k) */
822 + /* GPP SM segment ptrs */
823 + struct CMM_ALLOCATOR *paGPPSMSegTab[CMM_MAXGPPSEGS];
824 +} ;
826 +/* Default CMM Mgr attributes */
827 +static struct CMM_MGRATTRS CMM_DFLTMGRATTRS = {
828 + 16 /* ulMinBlockSize, min block size(bytes) allocated by cmm mgr */
831 +/* Default allocation attributes */
832 +static struct CMM_ATTRS CMM_DFLTALCTATTRS = {
833 + 1 /* ulSegId, default segment Id for allocator */
836 +/* Address translator default attrs */
837 +struct CMM_XLATORATTRS CMM_DFLTXLATORATTRS = {
838 + 1, /* ulSegId, does not have to match CMM_DFLTALCTATTRS ulSegId */
839 + 0, /* dwDSPBufs */
840 + 0, /* dwDSPBufSize */
841 + NULL, /* pVmBase */
842 + 0, /* dwVmSize */
845 +/* SM node representing a block of memory. */
846 +struct CMM_MNODE {
847 + struct LST_ELEM link; /* must be 1st element */
848 + u32 dwPA; /* Phys addr */
849 + u32 dwVA; /* Virtual address in device process context */
850 + u32 ulSize; /* SM block size in bytes */
851 + HANDLE hClientProc; /* Process that allocated this mem block */
852 +} ;
855 +/* ----------------------------------- Globals */
856 +#if GT_TRACE
857 +static struct GT_Mask CMM_debugMask = { NULL, NULL }; /* GT trace variable */
858 +#endif
860 +static u32 cRefs; /* module reference count */
862 +/* ----------------------------------- Function Prototypes */
863 +static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator,
864 + struct CMM_MNODE *pNode);
865 +static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr,
866 + u32 ulSegId);
867 +static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator,
868 + u32 uSize);
869 +static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA,
870 + u32 dwVA, u32 ulSize);
871 +/* get available slot for new allocator */
872 +static s32 GetSlot(struct CMM_OBJECT *hCmmMgr);
873 +static void UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA);
876 + * ======== CMM_CallocBuf ========
877 + * Purpose:
878 + * Allocate a SM buffer, zero contents, and return the physical address
879 + * and optional driver context virtual address(ppBufVA).
881 + * The freelist is sorted in increasing size order. Get the first
882 + * block that satifies the request and sort the remaining back on
883 + * the freelist; if large enough. The kept block is placed on the
884 + * inUseList.
885 + */
886 +void *CMM_CallocBuf(struct CMM_OBJECT *hCmmMgr, u32 uSize,
887 + struct CMM_ATTRS *pAttrs, OUT void **ppBufVA)
889 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
890 + void *pBufPA = NULL;
891 + struct CMM_MNODE *pNode = NULL;
892 + struct CMM_MNODE *pNewNode = NULL;
893 + struct CMM_ALLOCATOR *pAllocator = NULL;
894 + u32 uDeltaSize;
895 + u8 *pByte = NULL;
896 + s32 cnt;
898 + if (pAttrs == NULL)
899 + pAttrs = &CMM_DFLTALCTATTRS;
901 + if (ppBufVA != NULL)
902 + *ppBufVA = NULL;
904 + if ((MEM_IsValidHandle(pCmmMgr, CMMSIGNATURE)) && (uSize != 0)) {
905 + if (pAttrs->ulSegId > 0) {
906 + /* SegId > 0 is SM */
907 + /* get the allocator object for this segment id */
908 + pAllocator = GetAllocator(pCmmMgr, pAttrs->ulSegId);
909 + /* keep block size a multiple of ulMinBlockSize */
910 + uSize = ((uSize - 1) & ~(pCmmMgr->ulMinBlockSize - 1))
911 + + pCmmMgr->ulMinBlockSize;
912 + SYNC_EnterCS(pCmmMgr->hCmmLock);
913 + pNode = GetFreeBlock(pAllocator, uSize);
915 + if (pNode) {
916 + uDeltaSize = (pNode->ulSize - uSize);
917 + if (uDeltaSize >= pCmmMgr->ulMinBlockSize) {
918 + /* create a new block with the leftovers and
919 + * add to freelist */
920 + pNewNode = GetNode(pCmmMgr, pNode->dwPA + uSize,
921 + pNode->dwVA + uSize,
922 + (u32)uDeltaSize);
923 + /* leftovers go free */
924 + AddToFreeList(pAllocator, pNewNode);
925 + /* adjust our node's size */
926 + pNode->ulSize = uSize;
928 + /* Tag node with client process requesting allocation
929 + * We'll need to free up a process's alloc'd SM if the
930 + * client process goes away.
931 + */
932 + (void)PRCS_GetCurrentHandle(&pNode->hClientProc);
933 + /* put our node on InUse list */
934 + LST_PutTail(pAllocator->pInUseListHead,
935 + (struct LST_ELEM *)pNode);
936 + pBufPA = (void *)pNode->dwPA; /* physical address */
937 + /* clear mem */
938 + pByte = (u8 *)pNode->dwVA;
939 + for (cnt = 0; cnt < (s32) uSize; cnt++, pByte++)
940 + *pByte = 0;
942 + if (ppBufVA != NULL) {
943 + /* Virtual address */
944 + *ppBufVA = (void *)pNode->dwVA;
947 + GT_3trace(CMM_debugMask, GT_3CLASS,
948 + "CMM_CallocBuf dwPA %x, dwVA %x uSize"
949 + "%x\n", pNode->dwPA, pNode->dwVA, uSize);
950 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
952 + return pBufPA;
956 + * ======== CMM_Create ========
957 + * Purpose:
958 + * Create a communication memory manager object.
959 + */
960 +DSP_STATUS CMM_Create(OUT struct CMM_OBJECT **phCmmMgr,
961 + struct DEV_OBJECT *hDevObject,
962 + IN CONST struct CMM_MGRATTRS *pMgrAttrs)
964 + struct CMM_OBJECT *pCmmObject = NULL;
965 + DSP_STATUS status = DSP_SOK;
966 + struct UTIL_SYSINFO sysInfo;
968 + DBC_Require(cRefs > 0);
969 + DBC_Require(phCmmMgr != NULL);
971 + GT_3trace(CMM_debugMask, GT_ENTER,
972 + "CMM_Create: phCmmMgr: 0x%x\thDevObject: "
973 + "0x%x\tpMgrAttrs: 0x%x\n", phCmmMgr, hDevObject, pMgrAttrs);
974 + *phCmmMgr = NULL;
975 + /* create, zero, and tag a cmm mgr object */
976 + MEM_AllocObject(pCmmObject, struct CMM_OBJECT, CMMSIGNATURE);
977 + if (pCmmObject != NULL) {
978 + if (pMgrAttrs == NULL)
979 + pMgrAttrs = &CMM_DFLTMGRATTRS; /* set defaults */
981 + /* 4 bytes minimum */
982 + DBC_Assert(pMgrAttrs->ulMinBlockSize >= 4);
983 + /* save away smallest block allocation for this cmm mgr */
984 + pCmmObject->ulMinBlockSize = pMgrAttrs->ulMinBlockSize;
985 + /* save away the systems memory page size */
986 + sysInfo.dwPageSize = PAGE_SIZE;
987 + sysInfo.dwAllocationGranularity = PAGE_SIZE;
988 + sysInfo.dwNumberOfProcessors = 1;
989 + if (DSP_SUCCEEDED(status)) {
990 + GT_1trace(CMM_debugMask, GT_5CLASS,
991 + "CMM_Create: Got system page size"
992 + "= 0x%x\t\n", sysInfo.dwPageSize);
993 + pCmmObject->dwPageSize = sysInfo.dwPageSize;
994 + } else {
995 + GT_0trace(CMM_debugMask, GT_7CLASS,
996 + "CMM_Create: failed to get system"
997 + "page size\n");
998 + pCmmObject->dwPageSize = 0;
999 + status = DSP_EFAIL;
1001 + /* Note: DSP SM seg table(aDSPSMSegTab[]) zero'd by
1002 + * MEM_AllocObject */
1003 + if (DSP_SUCCEEDED(status)) {
1004 + /* create node free list */
1005 + pCmmObject->pNodeFreeListHead = LST_Create();
1006 + if (pCmmObject->pNodeFreeListHead == NULL) {
1007 + GT_0trace(CMM_debugMask, GT_7CLASS,
1008 + "CMM_Create: LST_Create() "
1009 + "failed \n");
1010 + status = DSP_EMEMORY;
1013 + if (DSP_SUCCEEDED(status))
1014 + status = SYNC_InitializeCS(&pCmmObject->hCmmLock);
1016 + if (DSP_SUCCEEDED(status))
1017 + *phCmmMgr = pCmmObject;
1018 + else
1019 + CMM_Destroy(pCmmObject, true);
1021 + } else {
1022 + GT_0trace(CMM_debugMask, GT_6CLASS,
1023 + "CMM_Create: Object Allocation "
1024 + "Failure(CMM Object)\n");
1025 + status = DSP_EMEMORY;
1027 + return status;
1031 + * ======== CMM_Destroy ========
1032 + * Purpose:
1033 + * Release the communication memory manager resources.
1034 + */
1035 +DSP_STATUS CMM_Destroy(struct CMM_OBJECT *hCmmMgr, bool bForce)
1037 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1038 + struct CMM_INFO tempInfo;
1039 + DSP_STATUS status = DSP_SOK;
1040 + s32 nSlot;
1041 + struct CMM_MNODE *pNode;
1043 + DBC_Require(cRefs > 0);
1044 + if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1045 + status = DSP_EHANDLE;
1046 + return status;
1048 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1049 + /* If not force then fail if outstanding allocations exist */
1050 + if (!bForce) {
1051 + /* Check for outstanding memory allocations */
1052 + status = CMM_GetInfo(hCmmMgr, &tempInfo);
1053 + if (DSP_SUCCEEDED(status)) {
1054 + if (tempInfo.ulTotalInUseCnt > 0) {
1055 + /* outstanding allocations */
1056 + status = DSP_EFAIL;
1060 + if (DSP_SUCCEEDED(status)) {
1061 + /* UnRegister SM allocator */
1062 + for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) {
1063 + if (pCmmMgr->paGPPSMSegTab[nSlot] != NULL) {
1064 + UnRegisterGPPSMSeg(pCmmMgr->
1065 + paGPPSMSegTab[nSlot]);
1066 + /* Set slot to NULL for future reuse */
1067 + pCmmMgr->paGPPSMSegTab[nSlot] = NULL;
1071 + if (pCmmMgr->pNodeFreeListHead != NULL) {
1072 + /* Free the free nodes */
1073 + while (!LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) {
1074 + /* (struct LST_ELEM*) pNode =
1075 + * LST_GetHead(pCmmMgr->pNodeFreeListHead);*/
1076 + pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr->
1077 + pNodeFreeListHead);
1078 + MEM_Free(pNode);
1080 + /* delete NodeFreeList list */
1081 + LST_Delete(pCmmMgr->pNodeFreeListHead);
1083 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1084 + if (DSP_SUCCEEDED(status)) {
1085 + /* delete CS & cmm mgr object */
1086 + SYNC_DeleteCS(pCmmMgr->hCmmLock);
1087 + MEM_FreeObject(pCmmMgr);
1089 + return status;
1093 + * ======== CMM_Exit ========
1094 + * Purpose:
1095 + * Discontinue usage of module; free resources when reference count
1096 + * reaches 0.
1097 + */
1098 +void CMM_Exit(void)
1100 + DBC_Require(cRefs > 0);
1102 + cRefs--;
1104 + GT_1trace(CMM_debugMask, GT_ENTER,
1105 + "exiting CMM_Exit,ref count:0x%x\n", cRefs);
1109 + * ======== CMM_FreeBuf ========
1110 + * Purpose:
1111 + * Free the given buffer.
1112 + */
1113 +DSP_STATUS CMM_FreeBuf(struct CMM_OBJECT *hCmmMgr, void *pBufPA, u32 ulSegId)
1115 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1116 + DSP_STATUS status = DSP_EPOINTER;
1117 + struct CMM_MNODE *pCurNode = NULL;
1118 + struct CMM_ALLOCATOR *pAllocator = NULL;
1119 + struct CMM_ATTRS *pAttrs;
1121 + DBC_Require(cRefs > 0);
1122 + DBC_Require(pBufPA != NULL);
1123 + GT_1trace(CMM_debugMask, GT_ENTER, "CMM_FreeBuf pBufPA %x\n", pBufPA);
1124 + if (ulSegId == 0) {
1125 + pAttrs = &CMM_DFLTALCTATTRS;
1126 + ulSegId = pAttrs->ulSegId;
1128 + if (!(MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) || !(ulSegId > 0)) {
1129 + status = DSP_EHANDLE;
1130 + return status;
1132 + /* get the allocator for this segment id */
1133 + pAllocator = GetAllocator(pCmmMgr, ulSegId);
1134 + if (pAllocator != NULL) {
1135 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1136 + pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->
1137 + pInUseListHead);
1138 + while (pCurNode) {
1139 + if ((u32)pBufPA == pCurNode->dwPA) {
1140 + /* Found it */
1141 + LST_RemoveElem(pAllocator->pInUseListHead,
1142 + (struct LST_ELEM *)pCurNode);
1143 + /* back to freelist */
1144 + AddToFreeList(pAllocator, pCurNode);
1145 + status = DSP_SOK; /* all right! */
1146 + break;
1148 + /* next node. */
1149 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1150 + pInUseListHead, (struct LST_ELEM *)pCurNode);
1152 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1154 + return status;
1158 + * ======== CMM_GetHandle ========
1159 + * Purpose:
1160 + * Return the communication memory manager object for this device.
1161 + * This is typically called from the client process.
1162 + */
1163 +DSP_STATUS CMM_GetHandle(DSP_HPROCESSOR hProcessor,
1164 + OUT struct CMM_OBJECT **phCmmMgr)
1166 + DSP_STATUS status = DSP_SOK;
1167 + struct DEV_OBJECT *hDevObject;
1169 + DBC_Require(cRefs > 0);
1170 + DBC_Require(phCmmMgr != NULL);
1171 + if (hProcessor != NULL)
1172 + status = PROC_GetDevObject(hProcessor, &hDevObject);
1173 + else
1174 + hDevObject = DEV_GetFirst(); /* default */
1176 + if (DSP_SUCCEEDED(status))
1177 + status = DEV_GetCmmMgr(hDevObject, phCmmMgr);
1179 + return status;
1183 + * ======== CMM_GetInfo ========
1184 + * Purpose:
1185 + * Return the current memory utilization information.
1186 + */
1187 +DSP_STATUS CMM_GetInfo(struct CMM_OBJECT *hCmmMgr,
1188 + OUT struct CMM_INFO *pCmmInfo)
1190 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1191 + u32 ulSeg;
1192 + DSP_STATUS status = DSP_SOK;
1193 + struct CMM_ALLOCATOR *pAltr;
1194 + struct CMM_MNODE *pCurNode = NULL;
1196 + DBC_Require(pCmmInfo != NULL);
1198 + if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1199 + status = DSP_EHANDLE;
1200 + return status;
1202 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1203 + pCmmInfo->ulNumGPPSMSegs = 0; /* # of SM segments */
1204 + pCmmInfo->ulTotalInUseCnt = 0; /* Total # of outstanding alloc */
1205 + pCmmInfo->ulMinBlockSize = pCmmMgr->ulMinBlockSize; /* min block size */
1206 + /* check SM memory segments */
1207 + for (ulSeg = 1; ulSeg <= CMM_MAXGPPSEGS; ulSeg++) {
1208 + /* get the allocator object for this segment id */
1209 + pAltr = GetAllocator(pCmmMgr, ulSeg);
1210 + if (pAltr != NULL) {
1211 + pCmmInfo->ulNumGPPSMSegs++;
1212 + pCmmInfo->segInfo[ulSeg - 1].dwSegBasePa =
1213 + pAltr->dwSmBase - pAltr->ulDSPSize;
1214 + pCmmInfo->segInfo[ulSeg - 1].ulTotalSegSize =
1215 + pAltr->ulDSPSize + pAltr->ulSmSize;
1216 + pCmmInfo->segInfo[ulSeg - 1].dwGPPBasePA =
1217 + pAltr->dwSmBase;
1218 + pCmmInfo->segInfo[ulSeg - 1].ulGPPSize =
1219 + pAltr->ulSmSize;
1220 + pCmmInfo->segInfo[ulSeg - 1].dwDSPBaseVA =
1221 + pAltr->dwDSPBase;
1222 + pCmmInfo->segInfo[ulSeg - 1].ulDSPSize =
1223 + pAltr->ulDSPSize;
1224 + pCmmInfo->segInfo[ulSeg - 1].dwSegBaseVa =
1225 + pAltr->dwVmBase - pAltr->ulDSPSize;
1226 + pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt = 0;
1227 + pCurNode = (struct CMM_MNODE *)LST_First(pAltr->
1228 + pInUseListHead);
1229 + /* Count inUse blocks */
1230 + while (pCurNode) {
1231 + pCmmInfo->ulTotalInUseCnt++;
1232 + pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt++;
1233 + /* next node. */
1234 + pCurNode = (struct CMM_MNODE *)LST_Next(pAltr->
1235 + pInUseListHead,
1236 + (struct LST_ELEM *)pCurNode);
1239 + } /* end for */
1240 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1241 + return status;
1245 + * ======== CMM_Init ========
1246 + * Purpose:
1247 + * Initializes private state of CMM module.
1248 + */
1249 +bool CMM_Init(void)
1251 + bool fRetval = true;
1253 + DBC_Require(cRefs >= 0);
1254 + if (cRefs == 0) {
1255 + /* Set the Trace mask */
1256 + /* "CM" for Comm Memory manager */
1257 + GT_create(&CMM_debugMask, "CM");
1259 + if (fRetval)
1260 + cRefs++;
1262 + GT_1trace(CMM_debugMask, GT_ENTER,
1263 + "Entered CMM_Init,ref count:0x%x\n", cRefs);
1265 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
1267 + return fRetval;
1271 + * ======== CMM_RegisterGPPSMSeg ========
1272 + * Purpose:
1273 + * Register a block of SM with the CMM to be used for later GPP SM
1274 + * allocations.
1275 + */
1276 +DSP_STATUS CMM_RegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 dwGPPBasePA,
1277 + u32 ulSize, u32 dwDSPAddrOffset,
1278 + enum CMM_CNVTTYPE cFactor, u32 dwDSPBase,
1279 + u32 ulDSPSize, u32 *pulSegId,
1280 + u32 dwGPPBaseVA)
1282 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1283 + struct CMM_ALLOCATOR *pSMA = NULL;
1284 + DSP_STATUS status = DSP_SOK;
1285 + struct CMM_MNODE *pNewNode;
1286 + s32 nSlot;
1288 + DBC_Require(ulSize > 0);
1289 + DBC_Require(pulSegId != NULL);
1290 + DBC_Require(dwGPPBasePA != 0);
1291 + DBC_Require(dwGPPBaseVA != 0);
1292 + DBC_Require((cFactor <= CMM_ADDTODSPPA) &&
1293 + (cFactor >= CMM_SUBFROMDSPPA));
1294 + GT_6trace(CMM_debugMask, GT_ENTER,
1295 + "CMM_RegisterGPPSMSeg dwGPPBasePA %x "
1296 + "ulSize %x dwDSPAddrOffset %x dwDSPBase %x ulDSPSize %x "
1297 + "dwGPPBaseVA %x\n", dwGPPBasePA, ulSize, dwDSPAddrOffset,
1298 + dwDSPBase, ulDSPSize, dwGPPBaseVA);
1299 + if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1300 + status = DSP_EHANDLE;
1301 + return status;
1303 + /* make sure we have room for another allocator */
1304 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1305 + nSlot = GetSlot(pCmmMgr);
1306 + if (nSlot < 0) {
1307 + /* get a slot number */
1308 + status = DSP_EFAIL;
1309 + goto func_end;
1311 + /* Check if input ulSize is big enough to alloc at least one block */
1312 + if (DSP_SUCCEEDED(status)) {
1313 + if (ulSize < pCmmMgr->ulMinBlockSize) {
1314 + GT_0trace(CMM_debugMask, GT_7CLASS,
1315 + "CMM_RegisterGPPSMSeg: "
1316 + "ulSize too small\n");
1317 + status = DSP_EINVALIDARG;
1318 + goto func_end;
1321 + if (DSP_SUCCEEDED(status)) {
1322 + /* create, zero, and tag an SM allocator object */
1323 + MEM_AllocObject(pSMA, struct CMM_ALLOCATOR, SMEMSIGNATURE);
1325 + if (pSMA != NULL) {
1326 + pSMA->hCmmMgr = hCmmMgr; /* ref to parent */
1327 + pSMA->dwSmBase = dwGPPBasePA; /* SM Base phys */
1328 + pSMA->ulSmSize = ulSize; /* SM segment size in bytes */
1329 + pSMA->dwVmBase = dwGPPBaseVA;
1330 + pSMA->dwDSPPhysAddrOffset = dwDSPAddrOffset;
1331 + pSMA->cFactor = cFactor;
1332 + pSMA->dwDSPBase = dwDSPBase;
1333 + pSMA->ulDSPSize = ulDSPSize;
1334 + if (pSMA->dwVmBase == 0) {
1335 + GT_0trace(CMM_debugMask, GT_7CLASS,
1336 + "CMM_RegisterGPPSMSeg: Error"
1337 + "MEM_LinearAddress()\n");
1338 + status = DSP_EFAIL;
1339 + goto func_end;
1341 + if (DSP_SUCCEEDED(status)) {
1342 + /* return the actual segment identifier */
1343 + *pulSegId = (u32) nSlot + 1;
1344 + /* create memory free list */
1345 + pSMA->pFreeListHead = LST_Create();
1346 + if (pSMA->pFreeListHead == NULL) {
1347 + GT_0trace(CMM_debugMask, GT_7CLASS,
1348 + "CMM_RegisterGPPSMSeg: "
1349 + "Out Of Memory \n");
1350 + status = DSP_EMEMORY;
1351 + goto func_end;
1354 + if (DSP_SUCCEEDED(status)) {
1355 + /* create memory in-use list */
1356 + pSMA->pInUseListHead = LST_Create();
1357 + if (pSMA->pInUseListHead == NULL) {
1358 + GT_0trace(CMM_debugMask, GT_7CLASS,
1359 + "CMM_RegisterGPPSMSeg: "
1360 + "LST_Create failed\n");
1361 + status = DSP_EMEMORY;
1362 + goto func_end;
1365 + if (DSP_SUCCEEDED(status)) {
1366 + /* Get a mem node for this hunk-o-memory */
1367 + pNewNode = GetNode(pCmmMgr, dwGPPBasePA,
1368 + pSMA->dwVmBase, ulSize);
1369 + /* Place node on the SM allocator's free list */
1370 + if (pNewNode) {
1371 + LST_PutTail(pSMA->pFreeListHead,
1372 + (struct LST_ELEM *)pNewNode);
1373 + } else {
1374 + status = DSP_EMEMORY;
1375 + goto func_end;
1378 + if (DSP_FAILED(status)) {
1379 + /* Cleanup allocator */
1380 + UnRegisterGPPSMSeg(pSMA);
1382 + } else {
1383 + GT_0trace(CMM_debugMask, GT_6CLASS,
1384 + "CMM_RegisterGPPSMSeg: SMA Object "
1385 + "Allocation Failure\n");
1386 + status = DSP_EMEMORY;
1387 + goto func_end;
1389 + /* make entry */
1390 + if (DSP_SUCCEEDED(status))
1391 + pCmmMgr->paGPPSMSegTab[nSlot] = pSMA;
1393 +func_end:
1394 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1395 + return status;
1399 + * ======== CMM_UnRegisterGPPSMSeg ========
1400 + * Purpose:
1401 + * UnRegister GPP SM segments with the CMM.
1402 + */
1403 +DSP_STATUS CMM_UnRegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 ulSegId)
1405 + struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
1406 + DSP_STATUS status = DSP_SOK;
1407 + struct CMM_ALLOCATOR *pSMA;
1408 + u32 ulId = ulSegId;
1410 + DBC_Require(ulSegId > 0);
1411 + if (MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
1412 + if (ulSegId == CMM_ALLSEGMENTS)
1413 + ulId = 1;
1415 + if ((ulId > 0) && (ulId <= CMM_MAXGPPSEGS)) {
1416 + while (ulId <= CMM_MAXGPPSEGS) {
1417 + SYNC_EnterCS(pCmmMgr->hCmmLock);
1418 + /* slot = segId-1 */
1419 + pSMA = pCmmMgr->paGPPSMSegTab[ulId - 1];
1420 + if (pSMA != NULL) {
1421 + UnRegisterGPPSMSeg(pSMA);
1422 + /* Set alctr ptr to NULL for future
1423 + * reuse */
1424 + pCmmMgr->paGPPSMSegTab[ulId - 1] = NULL;
1425 + } else if (ulSegId != CMM_ALLSEGMENTS) {
1426 + status = DSP_EFAIL;
1428 + SYNC_LeaveCS(pCmmMgr->hCmmLock);
1429 + if (ulSegId != CMM_ALLSEGMENTS)
1430 + break;
1432 + ulId++;
1433 + } /* end while */
1434 + } else {
1435 + status = DSP_EINVALIDARG;
1436 + GT_0trace(CMM_debugMask, GT_7CLASS,
1437 + "CMM_UnRegisterGPPSMSeg: Bad "
1438 + "segment Id\n");
1440 + } else {
1441 + status = DSP_EHANDLE;
1443 + return status;
1447 + * ======== UnRegisterGPPSMSeg ========
1448 + * Purpose:
1449 + * UnRegister the SM allocator by freeing all its resources and
1450 + * nulling cmm mgr table entry.
1451 + * Note:
1452 + * This routine is always called within cmm lock crit sect.
1453 + */
1454 +static void UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA)
1456 + struct CMM_MNODE *pCurNode = NULL;
1457 + struct CMM_MNODE *pNextNode = NULL;
1459 + DBC_Require(pSMA != NULL);
1460 + if (pSMA->pFreeListHead != NULL) {
1461 + /* free nodes on free list */
1462 + pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pFreeListHead);
1463 + while (pCurNode) {
1464 + pNextNode = (struct CMM_MNODE *)LST_Next(pSMA->
1465 + pFreeListHead,
1466 + (struct LST_ELEM *)pCurNode);
1467 + LST_RemoveElem(pSMA->pFreeListHead,
1468 + (struct LST_ELEM *)pCurNode);
1469 + MEM_Free((void *) pCurNode);
1470 + /* next node. */
1471 + pCurNode = pNextNode;
1473 + LST_Delete(pSMA->pFreeListHead); /* delete freelist */
1474 + /* free nodes on InUse list */
1475 + pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pInUseListHead);
1476 + while (pCurNode) {
1477 + pNextNode = (struct CMM_MNODE *)LST_Next(pSMA->
1478 + pInUseListHead,
1479 + (struct LST_ELEM *)pCurNode);
1480 + LST_RemoveElem(pSMA->pInUseListHead,
1481 + (struct LST_ELEM *)pCurNode);
1482 + MEM_Free((void *) pCurNode);
1483 + /* next node. */
1484 + pCurNode = pNextNode;
1486 + LST_Delete(pSMA->pInUseListHead); /* delete InUse list */
1488 + if ((void *) pSMA->dwVmBase != NULL)
1489 + MEM_UnmapLinearAddress((void *) pSMA->dwVmBase);
1491 + /* Free allocator itself */
1492 + MEM_FreeObject(pSMA);
1496 + * ======== GetSlot ========
1497 + * Purpose:
1498 + * An available slot # is returned. Returns negative on failure.
1499 + */
1500 +static s32 GetSlot(struct CMM_OBJECT *pCmmMgr)
1502 + s32 nSlot = -1; /* neg on failure */
1503 + DBC_Require(pCmmMgr != NULL);
1504 + /* get first available slot in cmm mgr SMSegTab[] */
1505 + for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) {
1506 + if (pCmmMgr->paGPPSMSegTab[nSlot] == NULL)
1507 + break;
1510 + if (nSlot == CMM_MAXGPPSEGS) {
1511 + GT_0trace(CMM_debugMask, GT_7CLASS,
1512 + "CMM_RegisterGPPSMSeg: Allocator "
1513 + "entry failure, max exceeded\n");
1514 + nSlot = -1; /* failed */
1516 + return nSlot;
1520 + * ======== GetNode ========
1521 + * Purpose:
1522 + * Get a memory node from freelist or create a new one.
1523 + */
1524 +static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA,
1525 + u32 dwVA, u32 ulSize)
1527 + struct CMM_MNODE *pNode = NULL;
1529 + DBC_Require(pCmmMgr != NULL);
1530 + DBC_Require(dwPA != 0);
1531 + DBC_Require(dwVA != 0);
1532 + DBC_Require(ulSize != 0);
1533 + /* Check cmm mgr's node freelist */
1534 + if (LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) {
1535 + pNode = (struct CMM_MNODE *)MEM_Calloc(sizeof(struct CMM_MNODE),
1536 + MEM_PAGED);
1537 + } else {
1538 + /* surely a valid element */
1539 + /* (struct LST_ELEM*) pNode = LST_GetHead(pCmmMgr->
1540 + * pNodeFreeListHead);*/
1541 + pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr->
1542 + pNodeFreeListHead);
1544 + if (pNode == NULL) {
1545 + GT_0trace(CMM_debugMask, GT_7CLASS, "GetNode: Out Of Memory\n");
1546 + } else {
1547 + LST_InitElem((struct LST_ELEM *) pNode); /* set self */
1548 + pNode->dwPA = dwPA; /* Physical addr of start of block */
1549 + pNode->dwVA = dwVA; /* Virtual " " */
1550 + pNode->ulSize = ulSize; /* Size of block */
1552 + return pNode;
1556 + * ======== DeleteNode ========
1557 + * Purpose:
1558 + * Put a memory node on the cmm nodelist for later use.
1559 + * Doesn't actually delete the node. Heap thrashing friendly.
1560 + */
1561 +static void DeleteNode(struct CMM_OBJECT *pCmmMgr, struct CMM_MNODE *pNode)
1563 + DBC_Require(pNode != NULL);
1564 + LST_InitElem((struct LST_ELEM *) pNode); /* init .self ptr */
1565 + LST_PutTail(pCmmMgr->pNodeFreeListHead, (struct LST_ELEM *) pNode);
1569 + * ====== GetFreeBlock ========
1570 + * Purpose:
1571 + * Scan the free block list and return the first block that satisfies
1572 + * the size.
1573 + */
1574 +static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator,
1575 + u32 uSize)
1577 + if (pAllocator) {
1578 + struct CMM_MNODE *pCurNode = (struct CMM_MNODE *)
1579 + LST_First(pAllocator->pFreeListHead);
1580 + while (pCurNode) {
1581 + if (uSize <= (u32) pCurNode->ulSize) {
1582 + LST_RemoveElem(pAllocator->pFreeListHead,
1583 + (struct LST_ELEM *)pCurNode);
1584 + return pCurNode;
1586 + /* next node. */
1587 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1588 + pFreeListHead, (struct LST_ELEM *)pCurNode);
1591 + return NULL;
1595 + * ======== AddToFreeList ========
1596 + * Purpose:
1597 + * Coelesce node into the freelist in ascending size order.
1598 + */
1599 +static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator,
1600 + struct CMM_MNODE *pNode)
1602 + struct CMM_MNODE *pNodePrev = NULL;
1603 + struct CMM_MNODE *pNodeNext = NULL;
1604 + struct CMM_MNODE *pCurNode;
1605 + u32 dwThisPA;
1606 + u32 dwNextPA;
1608 + DBC_Require(pNode != NULL);
1609 + DBC_Require(pAllocator != NULL);
1610 + dwThisPA = pNode->dwPA;
1611 + dwNextPA = NEXT_PA(pNode);
1612 + pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead);
1613 + while (pCurNode) {
1614 + if (dwThisPA == NEXT_PA(pCurNode)) {
1615 + /* found the block ahead of this one */
1616 + pNodePrev = pCurNode;
1617 + } else if (dwNextPA == pCurNode->dwPA) {
1618 + pNodeNext = pCurNode;
1620 + if ((pNodePrev == NULL) || (pNodeNext == NULL)) {
1621 + /* next node. */
1622 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1623 + pFreeListHead, (struct LST_ELEM *)pCurNode);
1624 + } else {
1625 + /* got 'em */
1626 + break;
1628 + } /* while */
1629 + if (pNodePrev != NULL) {
1630 + /* combine with previous block */
1631 + LST_RemoveElem(pAllocator->pFreeListHead,
1632 + (struct LST_ELEM *)pNodePrev);
1633 + /* grow node to hold both */
1634 + pNode->ulSize += pNodePrev->ulSize;
1635 + pNode->dwPA = pNodePrev->dwPA;
1636 + pNode->dwVA = pNodePrev->dwVA;
1637 + /* place node on mgr nodeFreeList */
1638 + DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodePrev);
1640 + if (pNodeNext != NULL) {
1641 + /* combine with next block */
1642 + LST_RemoveElem(pAllocator->pFreeListHead,
1643 + (struct LST_ELEM *)pNodeNext);
1644 + /* grow da node */
1645 + pNode->ulSize += pNodeNext->ulSize;
1646 + /* place node on mgr nodeFreeList */
1647 + DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodeNext);
1649 + /* Now, let's add to freelist in increasing size order */
1650 + pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead);
1651 + while (pCurNode) {
1652 + if (pNode->ulSize <= pCurNode->ulSize)
1653 + break;
1655 + /* next node. */
1656 + pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
1657 + pFreeListHead, (struct LST_ELEM *)pCurNode);
1659 + /* if pCurNode is NULL then add our pNode to the end of the freelist */
1660 + if (pCurNode == NULL) {
1661 + LST_PutTail(pAllocator->pFreeListHead,
1662 + (struct LST_ELEM *)pNode);
1663 + } else {
1664 + /* insert our node before the current traversed node */
1665 + LST_InsertBefore(pAllocator->pFreeListHead,
1666 + (struct LST_ELEM *)pNode,
1667 + (struct LST_ELEM *)pCurNode);
1672 + * ======== GetAllocator ========
1673 + * Purpose:
1674 + * Return the allocator for the given SM Segid.
1675 + * SegIds: 1,2,3..max.
1676 + */
1677 +static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr,
1678 + u32 ulSegId)
1680 + struct CMM_ALLOCATOR *pAllocator = NULL;
1682 + DBC_Require(pCmmMgr != NULL);
1683 + DBC_Require((ulSegId > 0) && (ulSegId <= CMM_MAXGPPSEGS));
1684 + pAllocator = pCmmMgr->paGPPSMSegTab[ulSegId - 1];
1685 + if (pAllocator != NULL) {
1686 + /* make sure it's for real */
1687 + if (!MEM_IsValidHandle(pAllocator, SMEMSIGNATURE)) {
1688 + pAllocator = NULL;
1689 + DBC_Assert(false);
1692 + return pAllocator;
1696 + * ======== CMM_XlatorCreate ========
1697 + * Purpose:
1698 + * Create an address translator object.
1699 + */
1700 +DSP_STATUS CMM_XlatorCreate(OUT struct CMM_XLATOROBJECT **phXlator,
1701 + struct CMM_OBJECT *hCmmMgr,
1702 + struct CMM_XLATORATTRS *pXlatorAttrs)
1704 + struct CMM_XLATOR *pXlatorObject = NULL;
1705 + DSP_STATUS status = DSP_SOK;
1707 + DBC_Require(cRefs > 0);
1708 + DBC_Require(phXlator != NULL);
1709 + DBC_Require(hCmmMgr != NULL);
1710 + GT_3trace(CMM_debugMask, GT_ENTER,
1711 + "CMM_XlatorCreate: phXlator: 0x%x\t"
1712 + "phCmmMgr: 0x%x\tpXlAttrs: 0x%x\n", phXlator,
1713 + hCmmMgr, pXlatorAttrs);
1714 + *phXlator = NULL;
1715 + if (pXlatorAttrs == NULL)
1716 + pXlatorAttrs = &CMM_DFLTXLATORATTRS; /* set defaults */
1718 + MEM_AllocObject(pXlatorObject, struct CMM_XLATOR, CMMXLATESIGNATURE);
1719 + if (pXlatorObject != NULL) {
1720 + pXlatorObject->hCmmMgr = hCmmMgr; /* ref back to CMM */
1721 + pXlatorObject->ulSegId = pXlatorAttrs->ulSegId; /* SM segId */
1722 + } else {
1723 + GT_0trace(CMM_debugMask, GT_6CLASS,
1724 + "CMM_XlatorCreate: Object Allocation"
1725 + "Failure(CMM Xlator)\n");
1726 + status = DSP_EMEMORY;
1728 + if (DSP_SUCCEEDED(status))
1729 + *phXlator = (struct CMM_XLATOROBJECT *) pXlatorObject;
1731 + return status;
1735 + * ======== CMM_XlatorDelete ========
1736 + * Purpose:
1737 + * Free the Xlator resources.
1738 + * VM gets freed later.
1739 + */
1740 +DSP_STATUS CMM_XlatorDelete(struct CMM_XLATOROBJECT *hXlator, bool bForce)
1742 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1743 + DSP_STATUS status = DSP_SOK;
1745 + DBC_Require(cRefs > 0);
1747 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1748 + MEM_FreeObject(pXlator);
1749 + } else {
1750 + status = DSP_EHANDLE;
1753 + return status;
1757 + * ======== CMM_XlatorAllocBuf ========
1758 + */
1759 +void *CMM_XlatorAllocBuf(struct CMM_XLATOROBJECT *hXlator, void *pVaBuf,
1760 + u32 uPaSize)
1762 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1763 + void *pBuf = NULL;
1764 + struct CMM_ATTRS attrs;
1766 + DBC_Require(cRefs > 0);
1767 + DBC_Require(hXlator != NULL);
1768 + DBC_Require(pXlator->hCmmMgr != NULL);
1769 + DBC_Require(pVaBuf != NULL);
1770 + DBC_Require(uPaSize > 0);
1771 + DBC_Require(pXlator->ulSegId > 0);
1773 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1774 + attrs.ulSegId = pXlator->ulSegId;
1775 + *(volatile u32 *)pVaBuf = 0;
1776 + /* Alloc SM */
1777 + pBuf = CMM_CallocBuf(pXlator->hCmmMgr, uPaSize, &attrs, NULL);
1778 + if (pBuf) {
1779 + /* convert to translator(node/strm) process Virtual
1780 + * address */
1781 + *(volatile u32 **)pVaBuf =
1782 + (u32 *)CMM_XlatorTranslate(hXlator,
1783 + pBuf, CMM_PA2VA);
1786 + return pBuf;
1790 + * ======== CMM_XlatorFreeBuf ========
1791 + * Purpose:
1792 + * Free the given SM buffer and descriptor.
1793 + * Does not free virtual memory.
1794 + */
1795 +DSP_STATUS CMM_XlatorFreeBuf(struct CMM_XLATOROBJECT *hXlator, void *pBufVa)
1797 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1798 + DSP_STATUS status = DSP_EFAIL;
1799 + void *pBufPa = NULL;
1801 + DBC_Require(cRefs > 0);
1802 + DBC_Require(pBufVa != NULL);
1803 + DBC_Require(pXlator->ulSegId > 0);
1805 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1806 + /* convert Va to Pa so we can free it. */
1807 + pBufPa = CMM_XlatorTranslate(hXlator, pBufVa, CMM_VA2PA);
1808 + if (pBufPa) {
1809 + status = CMM_FreeBuf(pXlator->hCmmMgr, pBufPa,
1810 + pXlator->ulSegId);
1811 + if (DSP_FAILED(status)) {
1812 + /* Uh oh, this shouldn't happen. Descriptor
1813 + * gone! */
1814 + GT_2trace(CMM_debugMask, GT_7CLASS,
1815 + "Cannot free DMA/ZCPY buffer"
1816 + "not allocated by MPU. PA %x, VA %x\n",
1817 + pBufPa, pBufVa);
1818 + DBC_Assert(false); /* CMM is leaking mem! */
1822 + return status;
1826 + * ======== CMM_XlatorInfo ========
1827 + * Purpose:
1828 + * Set/Get translator info.
1829 + */
1830 +DSP_STATUS CMM_XlatorInfo(struct CMM_XLATOROBJECT *hXlator, IN OUT u8 **pAddr,
1831 + u32 ulSize, u32 uSegId, bool bSetInfo)
1833 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1834 + DSP_STATUS status = DSP_SOK;
1836 + DBC_Require(cRefs > 0);
1837 + DBC_Require(pAddr != NULL);
1838 + DBC_Require((uSegId > 0) && (uSegId <= CMM_MAXGPPSEGS));
1840 + if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
1841 + if (bSetInfo) {
1842 + /* set translators virtual address range */
1843 + pXlator->dwVirtBase = (u32)*pAddr;
1844 + pXlator->ulVirtSize = ulSize;
1845 + GT_2trace(CMM_debugMask, GT_3CLASS,
1846 + "pXlator->dwVirtBase %x, "
1847 + "ulVirtSize %x\n", pXlator->dwVirtBase,
1848 + pXlator->ulVirtSize);
1849 + } else { /* return virt base address */
1850 + *pAddr = (u8 *)pXlator->dwVirtBase;
1852 + } else {
1853 + status = DSP_EHANDLE;
1855 + return status;
1859 + * ======== CMM_XlatorTranslate ========
1860 + */
1861 +void *CMM_XlatorTranslate(struct CMM_XLATOROBJECT *hXlator, void *pAddr,
1862 + enum CMM_XLATETYPE xType)
1864 + u32 dwAddrXlate = 0;
1865 + struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
1866 + struct CMM_OBJECT *pCmmMgr = NULL;
1867 + struct CMM_ALLOCATOR *pAlctr = NULL;
1868 + u32 dwOffset = 0;
1870 + DBC_Require(cRefs > 0);
1871 + DBC_Require(pAddr != NULL);
1872 + DBC_Require((xType >= CMM_VA2PA) && (xType <= CMM_DSPPA2PA));
1874 + if (!MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE))
1875 + goto loop_cont;
1877 + pCmmMgr = (struct CMM_OBJECT *)pXlator->hCmmMgr;
1878 + /* get this translator's default SM allocator */
1879 + DBC_Assert(pXlator->ulSegId > 0);
1880 + pAlctr = pCmmMgr->paGPPSMSegTab[pXlator->ulSegId - 1];
1881 + if (!MEM_IsValidHandle(pAlctr, SMEMSIGNATURE))
1882 + goto loop_cont;
1884 + if ((xType == CMM_VA2DSPPA) || (xType == CMM_VA2PA) ||
1885 + (xType == CMM_PA2VA)) {
1886 + if (xType == CMM_PA2VA) {
1887 + /* Gpp Va = Va Base + offset */
1888 + dwOffset = (u8 *)pAddr - (u8 *)(pAlctr->dwSmBase -
1889 + pAlctr->ulDSPSize);
1890 + dwAddrXlate = pXlator->dwVirtBase + dwOffset;
1891 + /* Check if translated Va base is in range */
1892 + if ((dwAddrXlate < pXlator->dwVirtBase) ||
1893 + (dwAddrXlate >=
1894 + (pXlator->dwVirtBase + pXlator->ulVirtSize))) {
1895 + dwAddrXlate = 0; /* bad address */
1896 + GT_0trace(CMM_debugMask, GT_7CLASS,
1897 + "CMM_XlatorTranslate: "
1898 + "Virt addr out of range\n");
1900 + } else {
1901 + /* Gpp PA = Gpp Base + offset */
1902 + dwOffset = (u8 *)pAddr - (u8 *)pXlator->dwVirtBase;
1903 + dwAddrXlate = pAlctr->dwSmBase - pAlctr->ulDSPSize +
1904 + dwOffset;
1906 + } else {
1907 + dwAddrXlate = (u32)pAddr;
1909 + /*Now convert address to proper target physical address if needed*/
1910 + if ((xType == CMM_VA2DSPPA) || (xType == CMM_PA2DSPPA)) {
1911 + /* Got Gpp Pa now, convert to DSP Pa */
1912 + dwAddrXlate = GPPPA2DSPPA((pAlctr->dwSmBase - pAlctr->
1913 + ulDSPSize), dwAddrXlate,
1914 + pAlctr->dwDSPPhysAddrOffset *
1915 + pAlctr->cFactor);
1916 + } else if (xType == CMM_DSPPA2PA) {
1917 + /* Got DSP Pa, convert to GPP Pa */
1918 + dwAddrXlate = DSPPA2GPPPA(pAlctr->dwSmBase - pAlctr->ulDSPSize,
1919 + dwAddrXlate,
1920 + pAlctr->dwDSPPhysAddrOffset *
1921 + pAlctr->cFactor);
1923 +loop_cont:
1924 + if (!dwAddrXlate) {
1925 + GT_2trace(CMM_debugMask, GT_7CLASS,
1926 + "CMM_XlatorTranslate: Can't translate"
1927 + " address: 0x%x xType %x\n", pAddr, xType);
1928 + } else {
1929 + GT_3trace(CMM_debugMask, GT_3CLASS,
1930 + "CMM_XlatorTranslate: pAddr %x, xType"
1931 + " %x, dwAddrXlate %x\n", pAddr, xType, dwAddrXlate);
1933 + return (void *)dwAddrXlate;
1935 Index: lk/drivers/dsp/bridge/pmgr/cod.c
1936 ===================================================================
1937 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1938 +++ lk/drivers/dsp/bridge/pmgr/cod.c 2008-08-18 10:38:37.000000000 +0300
1939 @@ -0,0 +1,683 @@
1941 + * linux/drivers/dsp/bridge/pmgr/cod.c
1943 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1945 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1947 + * This package is free software; you can redistribute it and/or modify
1948 + * it under the terms of the GNU General Public License version 2 as
1949 + * published by the Free Software Foundation.
1951 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1952 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1953 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1954 + */
1958 + * ======== cod.c ========
1959 + * This module implements DSP code management for the DSP/BIOS Bridge
1960 + * environment. It is mostly a thin wrapper.
1962 + * This module provides an interface for loading both static and
1963 + * dynamic code objects onto DSP systems.
1965 + *! Revision History
1966 + *! ================
1967 + *! 08-Apr-2003 map: Consolidated DBL to DBLL loader name
1968 + *! 24-Feb-2003 swa: PMGR Code review comments incorporated.
1969 + *! 18-Apr-2002 jeh: Added DBL function tables.
1970 + *! 20-Nov-2001 jeh: Removed call to ZL_loadArgs function.
1971 + *! 19-Oct-2001 jeh: Access DBL as a static library. Added COD_GetBaseLib,
1972 + *! COD_GetLoader, removed COD_LoadSection, COD_UnloadSection.
1973 + *! 07-Sep-2001 jeh: Added COD_LoadSection(), COD_UnloadSection().
1974 + *! 07-Aug-2001 rr: hMgr->baseLib is updated after zlopen in COD_LoadBase.
1975 + *! 18-Apr-2001 jeh: Check for fLoaded flag before ZL_unload, to allow
1976 + *! COD_OpenBase to be used.
1977 + *! 11-Jan-2001 jeh: Added COD_OpenBase (not used yet, since there is an
1978 + *! occasional crash).
1979 + *! 02-Aug-2000 kc: Added COD_ReadSection to COD module. Incorporates use
1980 + *! of ZL_readSect (new function in ZL module).
1981 + *! 28-Feb-2000 rr: New GT Usage Implementation
1982 + *! 08-Dec-1999 ag: Removed x86 specific __asm int 3.
1983 + *! 02-Oct-1999 ag: Added #ifdef DEBUGINT3COD for debug.
1984 + *! 20-Sep-1999 ag: Removed call to GT_set().
1985 + *! 04-Jun-1997 cr: Added validation of argc/argv pair in COD_LoadBase, as it
1986 + *! is a requirement to ZL_loadArgs.
1987 + *! 31-May-1997 cr: Changed COD_LoadBase argc value from u32 to int, added
1988 + *! DSP_ENOTIMPL return value to COD_Create when attrs != NULL.
1989 + *! 29-May-1997 cr: Added debugging support.
1990 + *! 24-Oct-1996 gp: Added COD_GetSection().
1991 + *! 18-Jun-1996 gp: Updated GetSymValue() to check for lib; updated E_ codes.
1992 + *! 12-Jun-1996 gp: Imported CSL_ services for strcpyn(); Added ref counting.
1993 + *! 20-May-1996 mg: Adapted for new MEM and LDR modules.
1994 + *! 08-May-1996 mg: Created.
1995 + */
1997 +/* ----------------------------------- Host OS */
1998 +#include <host_os.h>
2000 +/* ----------------------------------- DSP/BIOS Bridge */
2001 +#include <std.h>
2002 +#include <dbdefs.h>
2003 +#include <errbase.h>
2005 +/* ----------------------------------- Trace & Debug */
2006 +#include <dbc.h>
2007 +#include <gt.h>
2009 +/* ----------------------------------- OS Adaptation Layer */
2010 +#include <csl.h>
2011 +#include <kfile.h>
2012 +#include <ldr.h>
2013 +#include <mem.h>
2015 +/* ----------------------------------- Platform Manager */
2016 +/* Include appropriate loader header file */
2017 +#include <dbll.h>
2019 +/* ----------------------------------- This */
2020 +#include <cod.h>
2022 +/* magic number for handle validation */
2023 +#define MAGIC 0xc001beef
2025 +/* macro to validate COD manager handles */
2026 +#define IsValid(h) ((h) != NULL && (h)->ulMagic == MAGIC)
2029 + * ======== COD_MANAGER ========
2030 + */
2031 +struct COD_MANAGER {
2032 + struct DBLL_TarObj *target;
2033 + struct DBLL_LibraryObj *baseLib;
2034 + bool fLoaded; /* Base library loaded? */
2035 + u32 ulEntry;
2036 + struct LDR_MODULE *hDll;
2037 + struct DBLL_Fxns fxns;
2038 + struct DBLL_Attrs attrs;
2039 + char szZLFile[COD_MAXPATHLENGTH];
2040 + u32 ulMagic;
2041 +} ;
2044 + * ======== COD_LIBRARYOBJ ========
2045 + */
2046 +struct COD_LIBRARYOBJ {
2047 + struct DBLL_LibraryObj *dbllLib;
2048 + struct COD_MANAGER *hCodMgr;
2049 +} ;
2051 +static u32 cRefs = 0L;
2053 +#if GT_TRACE
2054 +static struct GT_Mask COD_debugMask = { NULL, NULL };
2055 +#endif
2057 +static struct DBLL_Fxns dbllFxns = {
2058 + (DBLL_CloseFxn) DBLL_close,
2059 + (DBLL_CreateFxn) DBLL_create,
2060 + (DBLL_DeleteFxn) DBLL_delete,
2061 + (DBLL_ExitFxn) DBLL_exit,
2062 + (DBLL_GetAttrsFxn) DBLL_getAttrs,
2063 + (DBLL_GetAddrFxn) DBLL_getAddr,
2064 + (DBLL_GetCAddrFxn) DBLL_getCAddr,
2065 + (DBLL_GetSectFxn) DBLL_getSect,
2066 + (DBLL_InitFxn) DBLL_init,
2067 + (DBLL_LoadFxn) DBLL_load,
2068 + (DBLL_LoadSectFxn) DBLL_loadSect,
2069 + (DBLL_OpenFxn) DBLL_open,
2070 + (DBLL_ReadSectFxn) DBLL_readSect,
2071 + (DBLL_SetAttrsFxn) DBLL_setAttrs,
2072 + (DBLL_UnloadFxn) DBLL_unload,
2073 + (DBLL_UnloadSectFxn) DBLL_unloadSect,
2076 +static bool NoOp();
2079 + * ======== COD_Close ========
2080 + */
2081 +void CDECL COD_Close(struct COD_LIBRARYOBJ *lib)
2083 + struct COD_MANAGER *hMgr;
2085 + DBC_Require(cRefs > 0);
2086 + DBC_Require(lib != NULL);
2087 + DBC_Require(IsValid(((struct COD_LIBRARYOBJ *)lib)->hCodMgr));
2089 + hMgr = lib->hCodMgr;
2090 + hMgr->fxns.closeFxn(lib->dbllLib);
2092 + MEM_Free(lib);
2096 + * ======== COD_Create ========
2097 + * Purpose:
2098 + * Create an object to manage code on a DSP system.
2099 + * This object can be used to load an initial program image with
2100 + * arguments that can later be expanded with
2101 + * dynamically loaded object files.
2103 + */
2104 +DSP_STATUS COD_Create(OUT struct COD_MANAGER **phMgr, char *pstrDummyFile,
2105 + IN OPTIONAL CONST struct COD_ATTRS *attrs)
2107 + struct COD_MANAGER *hMgrNew;
2108 + struct DBLL_Attrs zlAttrs;
2109 + DSP_STATUS status = DSP_SOK;
2111 + DBC_Require(cRefs > 0);
2112 + DBC_Require(phMgr != NULL);
2114 + GT_3trace(COD_debugMask, GT_ENTER,
2115 + "Entered COD_Create, Args: \t\nphMgr: "
2116 + "0x%x\t\npstrDummyFile: 0x%x\t\nattr: 0x%x\n",
2117 + phMgr, pstrDummyFile, attrs);
2118 + /* assume failure */
2119 + *phMgr = NULL;
2121 + /* we don't support non-default attrs yet */
2122 + if (attrs != NULL)
2123 + return DSP_ENOTIMPL;
2125 + hMgrNew = MEM_Calloc(sizeof(struct COD_MANAGER), MEM_NONPAGED);
2126 + if (hMgrNew == NULL) {
2127 + GT_0trace(COD_debugMask, GT_7CLASS,
2128 + "COD_Create: Out Of Memory\n");
2129 + return DSP_EMEMORY;
2132 + hMgrNew->ulMagic = MAGIC;
2134 + /* Set up loader functions */
2135 + hMgrNew->fxns = dbllFxns;
2137 + /* initialize the ZL module */
2138 + hMgrNew->fxns.initFxn();
2140 + zlAttrs.alloc = (DBLL_AllocFxn)NoOp;
2141 + zlAttrs.free = (DBLL_FreeFxn)NoOp;
2142 + zlAttrs.fread = (DBLL_ReadFxn)KFILE_Read;
2143 + zlAttrs.fseek = (DBLL_SeekFxn)KFILE_Seek;
2144 + zlAttrs.ftell = (DBLL_TellFxn)KFILE_Tell;
2145 + zlAttrs.fclose = (DBLL_FCloseFxn)KFILE_Close;
2146 + zlAttrs.fopen = (DBLL_FOpenFxn)KFILE_Open;
2147 + zlAttrs.symLookup = NULL;
2148 + zlAttrs.baseImage = true;
2149 + zlAttrs.logWrite = NULL;
2150 + zlAttrs.logWriteHandle = NULL;
2151 + zlAttrs.write = 0;
2152 + zlAttrs.rmmHandle = 0;
2153 + zlAttrs.wHandle = 0;
2154 + zlAttrs.symHandle = 0;
2155 + zlAttrs.symArg = 0;
2157 + hMgrNew->attrs = zlAttrs;
2159 + status = hMgrNew->fxns.createFxn(&hMgrNew->target, &zlAttrs);
2161 + if (DSP_FAILED(status)) {
2162 + COD_Delete(hMgrNew);
2163 + GT_1trace(COD_debugMask, GT_7CLASS,
2164 + "COD_Create:ZL Create Failed: 0x%x\n", status);
2165 + return COD_E_ZLCREATEFAILED;
2168 + /* return the new manager */
2169 + *phMgr = hMgrNew;
2170 + GT_1trace(COD_debugMask, GT_1CLASS,
2171 + "COD_Create: Success CodMgr: 0x%x\n", *phMgr);
2172 + return DSP_SOK;
2176 + * ======== COD_Delete ========
2177 + * Purpose:
2178 + * Delete a code manager object.
2179 + */
2180 +void COD_Delete(struct COD_MANAGER *hMgr)
2182 + DBC_Require(cRefs > 0);
2183 + DBC_Require(IsValid(hMgr));
2185 + GT_1trace(COD_debugMask, GT_ENTER, "COD_Delete:hMgr 0x%x\n", hMgr);
2186 + if (hMgr->baseLib) {
2187 + if (hMgr->fLoaded)
2188 + hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs);
2190 + hMgr->fxns.closeFxn(hMgr->baseLib);
2192 + if (hMgr->target) {
2193 + hMgr->fxns.deleteFxn(hMgr->target);
2194 + hMgr->fxns.exitFxn();
2196 + hMgr->ulMagic = ~MAGIC;
2197 + MEM_Free(hMgr);
2201 + * ======== COD_Exit ========
2202 + * Purpose:
2203 + * Discontinue usage of the COD module.
2205 + */
2206 +void COD_Exit(void)
2208 + DBC_Require(cRefs > 0);
2210 + cRefs--;
2212 + GT_1trace(COD_debugMask, GT_ENTER,
2213 + "Entered COD_Exit, ref count: 0x%x\n", cRefs);
2215 + DBC_Ensure(cRefs >= 0);
2219 + * ======== COD_GetBaseLib ========
2220 + * Purpose:
2221 + * Get handle to the base image DBL library.
2222 + */
2223 +DSP_STATUS CDECL COD_GetBaseLib(struct COD_MANAGER *hManager,
2224 + struct DBLL_LibraryObj **plib)
2226 + DSP_STATUS status = DSP_SOK;
2228 + DBC_Require(cRefs > 0);
2229 + DBC_Require(IsValid(hManager));
2230 + DBC_Require(plib != NULL);
2232 + *plib = (struct DBLL_LibraryObj *) hManager->baseLib;
2234 + return status;
2238 + * ======== COD_GetBaseName ========
2239 + */
2240 +DSP_STATUS CDECL COD_GetBaseName(struct COD_MANAGER *hManager, char *pszName,
2241 + u32 uSize)
2243 + DSP_STATUS status = DSP_SOK;
2245 + DBC_Require(cRefs > 0);
2246 + DBC_Require(IsValid(hManager));
2247 + DBC_Require(pszName != NULL);
2249 + if (uSize <= COD_MAXPATHLENGTH)
2250 + CSL_Strcpyn(pszName, hManager->szZLFile, uSize);
2251 + else
2252 + status = DSP_EFAIL;
2254 + return status;
2258 + * ======== COD_GetEntry ========
2259 + * Purpose:
2260 + * Retrieve the entry point of a loaded DSP program image
2262 + */
2263 +DSP_STATUS COD_GetEntry(struct COD_MANAGER *hManager, u32 *pulEntry)
2265 + DBC_Require(cRefs > 0);
2266 + DBC_Require(IsValid(hManager));
2267 + DBC_Require(pulEntry != NULL);
2269 + *pulEntry = hManager->ulEntry;
2271 + GT_1trace(COD_debugMask, GT_ENTER, "COD_GetEntry:ulEntr 0x%x\n",
2272 + *pulEntry);
2274 + return DSP_SOK;
2278 + * ======== COD_GetLoader ========
2279 + * Purpose:
2280 + * Get handle to the DBLL loader.
2281 + */
2282 +DSP_STATUS CDECL COD_GetLoader(struct COD_MANAGER *hManager,
2283 + struct DBLL_TarObj **phLoader)
2285 + DSP_STATUS status = DSP_SOK;
2287 + DBC_Require(cRefs > 0);
2288 + DBC_Require(IsValid(hManager));
2289 + DBC_Require(phLoader != NULL);
2291 + *phLoader = (struct DBLL_TarObj *)hManager->target;
2293 + return status;
2297 + * ======== COD_GetSection ========
2298 + * Purpose:
2299 + * Retrieve the starting address and length of a section in the COFF file
2300 + * given the section name.
2301 + */
2302 +DSP_STATUS COD_GetSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect,
2303 + OUT u32 *puAddr, OUT u32 *puLen)
2305 + struct COD_MANAGER *hManager;
2306 + DSP_STATUS status = DSP_SOK;
2308 + DBC_Require(cRefs > 0);
2309 + DBC_Require(lib != NULL);
2310 + DBC_Require(IsValid(lib->hCodMgr));
2311 + DBC_Require(pstrSect != NULL);
2312 + DBC_Require(puAddr != NULL);
2313 + DBC_Require(puLen != NULL);
2315 + GT_4trace(COD_debugMask, GT_ENTER,
2316 + "Entered COD_GetSection Args \t\n lib: "
2317 + "0x%x\t\npstrsect: 0x%x\t\npuAddr: 0x%x\t\npuLen: 0x%x\n",
2318 + lib, pstrSect, puAddr, puLen);
2319 + *puAddr = 0;
2320 + *puLen = 0;
2321 + if (lib != NULL) {
2322 + hManager = lib->hCodMgr;
2323 + status = hManager->fxns.getSectFxn(lib->dbllLib, pstrSect,
2324 + puAddr, puLen);
2325 + if (DSP_FAILED(status)) {
2326 + GT_1trace(COD_debugMask, GT_7CLASS,
2327 + "COD_GetSection: Section %s not"
2328 + "found\n", pstrSect);
2330 + } else {
2331 + status = COD_E_NOSYMBOLSLOADED;
2332 + GT_0trace(COD_debugMask, GT_7CLASS,
2333 + "COD_GetSection:No Symbols loaded\n");
2336 + DBC_Ensure(DSP_SUCCEEDED(status) || ((*puAddr == 0) && (*puLen == 0)));
2338 + return status;
2342 + * ======== COD_GetSymValue ========
2343 + * Purpose:
2344 + * Retrieve the value for the specified symbol. The symbol is first
2345 + * searched for literally and then, if not found, searched for as a
2346 + * C symbol.
2348 + */
2349 +DSP_STATUS COD_GetSymValue(struct COD_MANAGER *hMgr, char *pstrSym,
2350 + u32 *pulValue)
2352 + struct DBLL_Symbol *pSym;
2354 + DBC_Require(cRefs > 0);
2355 + DBC_Require(IsValid(hMgr));
2356 + DBC_Require(pstrSym != NULL);
2357 + DBC_Require(pulValue != NULL);
2359 + GT_3trace(COD_debugMask, GT_ENTER, "Entered COD_GetSymValue Args \t\n"
2360 + "hMgr: 0x%x\t\npstrSym: 0x%x\t\npulValue: 0x%x\n",
2361 + hMgr, pstrSym, pulValue);
2362 + if (hMgr->baseLib) {
2363 + if (!hMgr->fxns.getAddrFxn(hMgr->baseLib, pstrSym, &pSym)) {
2364 + if (!hMgr->fxns.getCAddrFxn(hMgr->baseLib, pstrSym,
2365 + &pSym)) {
2366 + GT_0trace(COD_debugMask, GT_7CLASS,
2367 + "COD_GetSymValue: "
2368 + "Symbols not found\n");
2369 + return COD_E_SYMBOLNOTFOUND;
2372 + } else {
2373 + GT_0trace(COD_debugMask, GT_7CLASS, "COD_GetSymValue: "
2374 + "No Symbols loaded\n");
2375 + return COD_E_NOSYMBOLSLOADED;
2378 + *pulValue = pSym->value;
2380 + return DSP_SOK;
2384 + * ======== COD_Init ========
2385 + * Purpose:
2386 + * Initialize the COD module's private state.
2388 + */
2389 +bool COD_Init(void)
2391 + bool fRetVal = true;
2393 + DBC_Require(cRefs >= 0);
2395 + if (cRefs == 0) {
2396 + DBC_Assert(!COD_debugMask.flags);
2397 + GT_create(&COD_debugMask, "CO");
2400 + if (fRetVal)
2401 + cRefs++;
2404 + GT_1trace(COD_debugMask, GT_1CLASS,
2405 + "Entered COD_Init, ref count: 0x%x\n", cRefs);
2406 + DBC_Ensure((fRetVal && cRefs > 0) || (!fRetVal && cRefs >= 0));
2407 + return fRetVal;
2411 + * ======== COD_LoadBase ========
2412 + * Purpose:
2413 + * Load the initial program image, optionally with command-line arguments,
2414 + * on the DSP system managed by the supplied handle. The program to be
2415 + * loaded must be the first element of the args array and must be a fully
2416 + * qualified pathname.
2417 + * Details:
2418 + * if nArgc doesn't match the number of arguments in the aArgs array, the
2419 + * aArgs array is searched for a NULL terminating entry, and argc is
2420 + * recalculated to reflect this. In this way, we can support NULL
2421 + * terminating aArgs arrays, if nArgc is very large.
2422 + */
2423 +DSP_STATUS COD_LoadBase(struct COD_MANAGER *hMgr, u32 nArgc, char *aArgs[],
2424 + COD_WRITEFXN pfnWrite, void *pArb, char *envp[])
2426 + DBLL_Flags flags;
2427 + struct DBLL_Attrs saveAttrs;
2428 + struct DBLL_Attrs newAttrs;
2429 + DSP_STATUS status;
2430 + u32 i;
2432 + DBC_Require(cRefs > 0);
2433 + DBC_Require(IsValid(hMgr));
2434 + DBC_Require(nArgc > 0);
2435 + DBC_Require(aArgs != NULL);
2436 + DBC_Require(aArgs[0] != NULL);
2437 + DBC_Require(pfnWrite != NULL);
2438 + DBC_Require(hMgr->baseLib != NULL);
2440 + GT_6trace(COD_debugMask, GT_ENTER,
2441 + "Entered COD_LoadBase, hMgr: 0x%x\n \t"
2442 + "nArgc: 0x%x\n\taArgs: 0x%x\n\tpfnWrite: 0x%x\n\tpArb:"
2443 + " 0x%x\n \tenvp: 0x%x\n", hMgr, nArgc, aArgs, pfnWrite,
2444 + pArb, envp);
2445 + /*
2446 + * Make sure every argv[] stated in argc has a value, or change argc to
2447 + * reflect true number in NULL terminated argv array.
2448 + */
2449 + for (i = 0; i < nArgc; i++) {
2450 + if (aArgs[i] == NULL) {
2451 + nArgc = i;
2452 + break;
2456 + /* set the write function for this operation */
2457 + hMgr->fxns.getAttrsFxn(hMgr->target, &saveAttrs);
2459 + newAttrs = saveAttrs;
2460 + newAttrs.write = (DBLL_WriteFxn)pfnWrite;
2461 + newAttrs.wHandle = pArb;
2462 + newAttrs.alloc = (DBLL_AllocFxn)NoOp;
2463 + newAttrs.free = (DBLL_FreeFxn)NoOp;
2464 + newAttrs.logWrite = NULL;
2465 + newAttrs.logWriteHandle = NULL;
2467 + /* Load the image */
2468 + flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
2469 + status = hMgr->fxns.loadFxn(hMgr->baseLib, flags, &newAttrs,
2470 + &hMgr->ulEntry);
2471 + if (DSP_FAILED(status)) {
2472 + hMgr->fxns.closeFxn(hMgr->baseLib);
2473 + GT_1trace(COD_debugMask, GT_7CLASS,
2474 + "COD_LoadBase: COD Load failed: "
2475 + "0x%x\n", status);
2477 + if (DSP_SUCCEEDED(status))
2478 + hMgr->fLoaded = true;
2479 + else
2480 + hMgr->baseLib = NULL;
2482 + return status;
2486 + * ======== COD_Open ========
2487 + * Open library for reading sections.
2488 + */
2489 +DSP_STATUS COD_Open(struct COD_MANAGER *hMgr, IN char *pszCoffPath,
2490 + COD_FLAGS flags, struct COD_LIBRARYOBJ **pLib)
2492 + DSP_STATUS status = DSP_SOK;
2493 + struct COD_LIBRARYOBJ *lib = NULL;
2495 + DBC_Require(cRefs > 0);
2496 + DBC_Require(IsValid(hMgr));
2497 + DBC_Require(pszCoffPath != NULL);
2498 + DBC_Require(flags == COD_NOLOAD || flags == COD_SYMB);
2499 + DBC_Require(pLib != NULL);
2501 + GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_Open, hMgr: 0x%x\n\t "
2502 + "pszCoffPath: 0x%x\tflags: 0x%x\tlib: 0x%x\n", hMgr,
2503 + pszCoffPath, flags, pLib);
2505 + *pLib = NULL;
2507 + lib = MEM_Calloc(sizeof(struct COD_LIBRARYOBJ), MEM_NONPAGED);
2508 + if (lib == NULL) {
2509 + GT_0trace(COD_debugMask, GT_7CLASS,
2510 + "COD_Open: Out Of Memory\n");
2511 + status = DSP_EMEMORY;
2514 + if (DSP_SUCCEEDED(status)) {
2515 + lib->hCodMgr = hMgr;
2516 + status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags,
2517 + &lib->dbllLib);
2518 + if (DSP_FAILED(status)) {
2519 + GT_1trace(COD_debugMask, GT_7CLASS,
2520 + "COD_Open failed: 0x%x\n", status);
2521 + } else {
2522 + *pLib = lib;
2526 + return status;
2530 + * ======== COD_OpenBase ========
2531 + * Purpose:
2532 + * Open base image for reading sections.
2533 + */
2534 +DSP_STATUS COD_OpenBase(struct COD_MANAGER *hMgr, IN char *pszCoffPath,
2535 + DBLL_Flags flags)
2537 + DSP_STATUS status = DSP_SOK;
2538 + struct DBLL_LibraryObj *lib;
2540 + DBC_Require(cRefs > 0);
2541 + DBC_Require(IsValid(hMgr));
2542 + DBC_Require(pszCoffPath != NULL);
2544 + GT_2trace(COD_debugMask, GT_ENTER,
2545 + "Entered COD_OpenBase, hMgr: 0x%x\n\t"
2546 + "pszCoffPath: 0x%x\n", hMgr, pszCoffPath);
2548 + /* if we previously opened a base image, close it now */
2549 + if (hMgr->baseLib) {
2550 + if (hMgr->fLoaded) {
2551 + GT_0trace(COD_debugMask, GT_7CLASS,
2552 + "Base Image is already loaded. "
2553 + "Unloading it...\n");
2554 + hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs);
2555 + hMgr->fLoaded = false;
2557 + hMgr->fxns.closeFxn(hMgr->baseLib);
2558 + hMgr->baseLib = NULL;
2559 + } else {
2560 + GT_0trace(COD_debugMask, GT_1CLASS,
2561 + "COD_OpenBase: Opening the base image ...\n");
2563 + status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags, &lib);
2564 + if (DSP_FAILED(status)) {
2565 + GT_0trace(COD_debugMask, GT_7CLASS,
2566 + "COD_OpenBase: COD Open failed\n");
2567 + } else {
2568 + /* hang onto the library for subsequent sym table usage */
2569 + hMgr->baseLib = lib;
2570 + CSL_Strcpyn(hMgr->szZLFile, pszCoffPath, COD_MAXPATHLENGTH);
2573 + return status;
2577 + * ======== COD_ReadSection ========
2578 + * Purpose:
2579 + * Retrieve the content of a code section given the section name.
2580 + */
2581 +DSP_STATUS COD_ReadSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect,
2582 + OUT char *pstrContent, IN u32 cContentSize)
2584 + DSP_STATUS status = DSP_SOK;
2586 + DBC_Require(cRefs > 0);
2587 + DBC_Require(lib != NULL);
2588 + DBC_Require(IsValid(lib->hCodMgr));
2589 + DBC_Require(pstrSect != NULL);
2590 + DBC_Require(pstrContent != NULL);
2592 + GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_ReadSection Args: 0x%x,"
2593 + " 0x%x, 0x%x, 0x%x\n", lib, pstrSect, pstrContent,
2594 + cContentSize);
2596 + if (lib != NULL) {
2597 + status = lib->hCodMgr->fxns.readSectFxn(lib->dbllLib, pstrSect,
2598 + pstrContent,
2599 + cContentSize);
2600 + if (DSP_FAILED(status)) {
2601 + GT_1trace(COD_debugMask, GT_7CLASS,
2602 + "COD_ReadSection failed: 0x%lx\n", status);
2604 + } else {
2605 + status = COD_E_NOSYMBOLSLOADED;
2606 + GT_0trace(COD_debugMask, GT_7CLASS,
2607 + "COD_ReadSection: No Symbols loaded\n");
2609 + return status;
2613 + * ======== NoOp ========
2614 + * Purpose:
2615 + * No Operation.
2617 + */
2618 +static bool NoOp(void)
2620 + return true;
2623 Index: lk/drivers/dsp/bridge/pmgr/dbl.c
2624 ===================================================================
2625 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2626 +++ lk/drivers/dsp/bridge/pmgr/dbl.c 2008-08-18 10:38:37.000000000 +0300
2627 @@ -0,0 +1,1385 @@
2629 + * linux/drivers/dsp/bridge/pmgr/linux/dbl/dbl.c
2631 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
2633 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
2635 + * This package is free software; you can redistribute it and/or modify
2636 + * it under the terms of the GNU General Public License version 2 as
2637 + * published by the Free Software Foundation.
2639 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2640 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2641 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2642 + */
2646 + * ======== dbl.c ========
2647 + * Dynamic BOF Loader library. Contains functions related to
2648 + * loading and unloading symbols/code/data on DSP.
2649 + * Also contains other support functions.
2651 + *! Revision History
2652 + *! ================
2653 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
2654 + *! 24-May-2002 jeh Free DCD sects in DBL_close().
2655 + *! 19-Mar-2002 jeh Changes made to match dynamic loader (dbll.c): Pass
2656 + *! DBL_Library to DBL_getAddr() instead of DBL_Target,
2657 + *! eliminate scope param, use DBL_Symbol. Pass attrs to
2658 + *! DBL_load(), DBL_unload().
2659 + *! 20-Nov-2001 jeh Removed DBL_loadArgs().
2660 + *! 07-Sep-2001 jeh Added overlay support.
2661 + *! 31-Jul-2001 jeh Include windows.h.
2662 + *! 06-Jun-2001 jeh Created.
2663 + */
2665 +/* ----------------------------------- Host OS */
2666 +#include <host_os.h>
2668 +/* ----------------------------------- DSP/BIOS Bridge */
2669 +#include <std.h>
2670 +#include <dbdefs.h>
2671 +#include <errbase.h>
2673 +/* ----------------------------------- Trace & Debug */
2674 +#include <dbc.h>
2675 +#include <gt.h>
2677 +/* ----------------------------------- OS Adaptation Layer */
2678 +#include <csl.h>
2679 +#include <mem.h>
2680 +#include <kfile.h>
2682 +/* ----------------------------------- This */
2683 +#include <dbof.h>
2684 +#include <dbl.h>
2686 +#define DBL_TARGSIGNATURE 0x544c4244 /* "TLBD" */
2687 +#define DBL_LIBSIGNATURE 0x4c4c4244 /* "LLBD" */
2689 +#define C54TARG 0
2690 +#define C55TARG 1
2691 +#define NUMTARGS 2
2693 +#define C54MAGIC 0x98 /* Magic number for TI C54 COF */
2694 +#define C55MAGIC 0x9c /* Magic number for LEAD3 (C55) COF */
2696 +/* Three task phases */
2697 +#define CREATEPHASE 0
2698 +#define DELETEPHASE 1
2699 +#define EXECUTEPHASE 2
2700 +#define NONE 3 /* For overlay section with phase not specified */
2702 +/* Default load buffer size */
2703 +#define LOADBUFSIZE 0x800
2705 +#define SWAPLONG(x) ((((x) << 24) & 0xFF000000) | (((x) << 8) & 0xFF0000L) | \
2706 + (((x) >> 8) & 0xFF00L) | (((x) >> 24) & 0xFF))
2708 +#define SWAPWORD(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0xFF))
2711 + * Macros for accessing the following types of overlay data within a
2712 + * structure of type OvlyData:
2713 + * - Overlay data not associated with a particular phase
2714 + * - Create phase overlay data
2715 + * - Delete phase overlay data
2716 + * - Execute phase overlay data
2717 + */
2718 +#define numOtherSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numOtherSects)
2719 +#define numCreateSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numCreateSects)
2720 +#define numDeleteSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numDeleteSects)
2721 +#define numExecuteSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numExecuteSects)
2722 +#define otherOffset(pOvlyData) 0
2723 +#define createOffset(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numOtherSects)
2724 +#define deleteOffset(pOvlyData) (createOffset(pOvlyData) + \
2725 + (pOvlyData->hdr.dbofHdr.numCreateSects))
2726 +#define executeOffset(pOvlyData) (deleteOffset(pOvlyData) + \
2727 + (pOvlyData->hdr.dbofHdr.numDeleteSects))
2729 + * ======== OvlyHdr ========
2730 + */
2731 +struct OvlyHdr {
2732 + struct DBOF_OvlySectHdr dbofHdr;
2733 + char *pName; /* Name of overlay section */
2734 + u16 createRef; /* Reference count for create phase */
2735 + u16 deleteRef; /* Reference count for delete phase */
2736 + u16 executeRef; /* Execute phase ref count */
2737 + u16 otherRef; /* Unspecified phase ref count */
2738 +} ;
2741 + * ======== OvlyData ========
2742 + */
2743 +struct OvlyData {
2744 + struct OvlyHdr hdr;
2745 + struct DBOF_OvlySectData data[1];
2746 +} ;
2749 + * ======== Symbol ========
2750 + */
2751 +struct Symbol {
2752 + struct DBL_Symbol sym;
2753 + char *pSymName;
2757 + * ======== DCDSect ========
2758 + */
2759 +struct DCDSect {
2760 + struct DBOF_DCDSectHdr sectHdr;
2761 + char *pData;
2762 +} ;
2765 + * ======== DBL_TargetObj ========
2766 + */
2767 +struct DBL_TargetObj {
2768 + u32 dwSignature; /* For object validation */
2769 + struct DBL_Attrs dblAttrs; /* file read, write, etc. functions */
2770 + char *pBuf; /* Load buffer */
2774 + * ======== TargetInfo ========
2775 + */
2776 +struct TargetInfo {
2777 + u16 dspType; /* eg, C54TARG, C55TARG */
2778 + u32 magic; /* COFF magic number, identifies target type */
2779 + u16 wordSize; /* Size of a DSP word */
2780 + u16 mauSize; /* Size of minimum addressable unit */
2781 + u16 charSize; /* For C55x, mausize = 1, but charsize = 2 */
2782 +} ;
2785 + * ======== DBL_LibraryObj ========
2786 + * Represents a library loaded on a target.
2787 + */
2788 +struct DBL_LibraryObj {
2789 + u32 dwSignature; /* For object validation */
2790 + struct DBL_TargetObj *pTarget; /* Target for this library */
2791 + struct KFILE_FileObj *file; /* DBOF file handle */
2792 + bool byteSwapped; /* Are bytes swapped? */
2793 + struct DBOF_FileHdr fileHdr; /* Header of DBOF file */
2794 + u16 nSymbols; /* Number of DSP/Bridge symbols */
2795 + struct Symbol *symbols; /* Table of DSP/Bridge symbols */
2796 + u16 nDCDSects; /* Number of DCD sections */
2797 + u16 nOvlySects; /* Number of overlay nodes */
2798 + struct DCDSect *dcdSects; /* DCD section data */
2799 + struct OvlyData **ppOvlyData; /* Array of overlay section data */
2800 + struct TargetInfo *pTargetInfo; /* Entry in targetTab[] below */
2801 +} ;
2803 +#if GT_TRACE
2804 +static struct GT_Mask DBL_debugMask = { NULL, NULL }; /* GT trace variable */
2805 +#endif
2807 +static u32 cRefs; /* module reference count */
2809 +static u32 magicTab[NUMTARGS] = { C54MAGIC, C55MAGIC };
2811 +static struct TargetInfo targetTab[] = {
2812 + /* targ magic wordsize mausize charsize */
2813 + {C54TARG, C54MAGIC, 2, 2, 2}, /* C54 */
2814 + {C55TARG, C55MAGIC, 2, 1, 2}, /* C55 */
2817 +static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData,
2818 + s32 offset, s32 nSects);
2819 +static DSP_STATUS loadSect(struct DBL_TargetObj *dbl,
2820 + struct DBL_LibraryObj *pdblLib);
2821 +static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl,
2822 + struct DBL_LibraryObj *pdblLib);
2823 +static DSP_STATUS readHeader(struct DBL_TargetObj *dbl,
2824 + struct DBL_LibraryObj *pdblLib);
2825 +static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl,
2826 + struct DBL_LibraryObj *pdblLib);
2827 +static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl,
2828 + struct DBL_LibraryObj *pdblLib);
2831 + * ======== DBL_close ========
2832 + * Purpose:
2833 + * Close library opened with DBL_open.
2834 + */
2835 +void DBL_close(struct DBL_LibraryObj *lib)
2837 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
2838 + u16 i;
2840 + DBC_Require(cRefs > 0);
2841 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
2843 + GT_1trace(DBL_debugMask, GT_ENTER, "DBL_close: lib: 0x%x\n", lib);
2845 + /* Free symbols */
2846 + if (pdblLib->symbols) {
2847 + for (i = 0; i < pdblLib->nSymbols; i++) {
2848 + if (pdblLib->symbols[i].pSymName)
2849 + MEM_Free(pdblLib->symbols[i].pSymName);
2852 + MEM_Free(pdblLib->symbols);
2855 + /* Free DCD sects */
2856 + if (pdblLib->dcdSects) {
2857 + for (i = 0; i < pdblLib->nDCDSects; i++) {
2858 + if (pdblLib->dcdSects[i].pData)
2859 + MEM_Free(pdblLib->dcdSects[i].pData);
2862 + MEM_Free(pdblLib->dcdSects);
2865 + /* Free overlay sects */
2866 + if (pdblLib->ppOvlyData) {
2867 + for (i = 0; i < pdblLib->nOvlySects; i++) {
2868 + if (pdblLib->ppOvlyData[i]) {
2869 + if (pdblLib->ppOvlyData[i]->hdr.pName) {
2870 + MEM_Free(pdblLib->ppOvlyData[i]->
2871 + hdr.pName);
2873 + MEM_Free(pdblLib->ppOvlyData[i]);
2876 + MEM_Free(pdblLib->ppOvlyData);
2879 + /* Close the file */
2880 + if (pdblLib->file)
2881 + (*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file);
2884 + MEM_FreeObject(pdblLib);
2888 + * ======== DBL_create ========
2889 + * Purpose:
2890 + * Create a target object by specifying the alloc, free, and
2891 + * write functions for the target.
2892 + */
2893 +DSP_STATUS DBL_create(struct DBL_TargetObj **pTarget, struct DBL_Attrs *pAttrs)
2895 + struct DBL_TargetObj *pdblTarget = NULL;
2896 + DSP_STATUS status = DSP_SOK;
2898 + DBC_Require(cRefs > 0);
2899 + DBC_Require(pAttrs != NULL);
2900 + DBC_Require(pTarget != NULL);
2902 + GT_2trace(DBL_debugMask, GT_ENTER,
2903 + "DBL_create: pTarget: 0x%x pAttrs: 0x%x\n",
2904 + pTarget, pAttrs);
2905 + /* Allocate DBL target object */
2906 + MEM_AllocObject(pdblTarget, struct DBL_TargetObj, DBL_TARGSIGNATURE);
2907 + if (pdblTarget == NULL) {
2908 + GT_0trace(DBL_debugMask, GT_6CLASS,
2909 + "DBL_create: Memory allocation failed\n");
2910 + status = DSP_EMEMORY;
2911 + } else {
2912 + pdblTarget->dblAttrs = *pAttrs;
2913 + /* Allocate buffer for loading target */
2914 + pdblTarget->pBuf = MEM_Calloc(LOADBUFSIZE, MEM_PAGED);
2915 + if (pdblTarget->pBuf == NULL)
2916 + status = DSP_EMEMORY;
2919 + if (DSP_SUCCEEDED(status)) {
2920 + *pTarget = pdblTarget;
2921 + } else {
2922 + *pTarget = NULL;
2923 + if (pdblTarget)
2924 + DBL_delete(pdblTarget);
2927 + DBC_Ensure(DSP_SUCCEEDED(status) &&
2928 + ((MEM_IsValidHandle((*pTarget), DBL_TARGSIGNATURE)) ||
2929 + (DSP_FAILED(status) && *pTarget == NULL)));
2930 + return status;
2934 + * ======== DBL_delete ========
2935 + * Purpose:
2936 + * Delete target object and free resources for any loaded libraries.
2937 + */
2938 +void DBL_delete(struct DBL_TargetObj *target)
2940 + DBC_Require(cRefs > 0);
2941 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
2943 + GT_1trace(DBL_debugMask, GT_ENTER,
2944 + "DBL_delete: target: 0x%x\n", target);
2946 + if (target->pBuf)
2947 + MEM_Free(target->pBuf);
2949 + MEM_FreeObject(target);
2953 + * ======== DBL_exit ========
2954 + * Purpose
2955 + * Discontinue usage of DBL module.
2956 + */
2957 +void DBL_exit()
2959 + DBC_Require(cRefs > 0);
2960 + cRefs--;
2961 + GT_1trace(DBL_debugMask, GT_5CLASS,
2962 + "DBL_exit() ref count: 0x%x\n", cRefs);
2963 + DBC_Ensure(cRefs >= 0);
2967 + * ======== DBL_getAddr ========
2968 + * Purpose:
2969 + * Get address of name in the specified library.
2970 + */
2971 +bool DBL_getAddr(struct DBL_LibraryObj *lib, char *name,
2972 + struct DBL_Symbol **ppSym)
2974 + bool retVal = false;
2975 + struct Symbol *symbol;
2976 + u16 i;
2978 + DBC_Require(cRefs > 0);
2979 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
2980 + DBC_Require(name != NULL);
2981 + DBC_Require(ppSym != NULL);
2983 + GT_3trace(DBL_debugMask, GT_ENTER,
2984 + "DBL_getAddr: libt: 0x%x name: %s pAddr: "
2985 + "0x%x\n", lib, name, ppSym);
2986 + for (i = 0; i < lib->nSymbols; i++) {
2987 + symbol = &lib->symbols[i];
2988 + if (CSL_Strcmp(name, symbol->pSymName) == 0) {
2989 + /* Found it */
2990 + *ppSym = &lib->symbols[i].sym;
2991 + retVal = true;
2992 + break;
2995 + return retVal;
2999 + * ======== DBL_getAttrs ========
3000 + * Purpose:
3001 + * Retrieve the attributes of the target.
3002 + */
3003 +void DBL_getAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs)
3005 + DBC_Require(cRefs > 0);
3006 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
3007 + DBC_Require(pAttrs != NULL);
3008 + GT_2trace(DBL_debugMask, GT_ENTER, "DBL_getAttrs: target: 0x%x pAttrs: "
3009 + "0x%x\n", target, pAttrs);
3010 + *pAttrs = target->dblAttrs;
3014 + * ======== DBL_getCAddr ========
3015 + * Purpose:
3016 + * Get address of "C" name in the specified library.
3017 + */
3018 +bool DBL_getCAddr(struct DBL_LibraryObj *lib, char *name,
3019 + struct DBL_Symbol **ppSym)
3021 + bool retVal = false;
3022 + struct Symbol *symbol;
3023 + u16 i;
3025 + DBC_Require(cRefs > 0);
3026 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3027 + DBC_Require(name != NULL);
3028 + DBC_Require(ppSym != NULL);
3030 + GT_3trace(DBL_debugMask, GT_ENTER,
3031 + "DBL_getCAddr: target: 0x%x name:%s pAddr:"
3032 + " 0x%x\n", lib, name, ppSym);
3033 + for (i = 0; i < lib->nSymbols; i++) {
3034 + symbol = &lib->symbols[i];
3035 + if ((CSL_Strcmp(name, symbol->pSymName) == 0) ||
3036 + (CSL_Strcmp(name, symbol->pSymName + 1) == 0 &&
3037 + symbol->pSymName[0] == '_')) {
3038 + /* Found it */
3039 + *ppSym = &lib->symbols[i].sym;
3040 + retVal = true;
3041 + break;
3044 + return retVal;
3048 + * ======== DBL_getEntry ========
3049 + * Purpose:
3050 + * Get program entry point.
3052 + */
3053 +bool DBL_getEntry(struct DBL_LibraryObj *lib, u32 *pEntry)
3055 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3057 + DBC_Require(cRefs > 0);
3058 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3059 + DBC_Require(pEntry != NULL);
3061 + GT_2trace(DBL_debugMask, GT_ENTER,
3062 + "DBL_getEntry: lib: 0x%x pEntry: 0x%x\n", lib, pEntry);
3063 + *pEntry = pdblLib->fileHdr.entry;
3065 + return true;
3069 + * ======== DBL_getSect ========
3070 + * Purpose:
3071 + * Get address and size of a named section.
3072 + */
3073 +DSP_STATUS DBL_getSect(struct DBL_LibraryObj *lib, char *name, u32 *pAddr,
3074 + u32 *pSize)
3076 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3077 + u16 i;
3078 + DSP_STATUS status = DSP_ENOSECT;
3080 + DBC_Require(cRefs > 0);
3081 + DBC_Require(name != NULL);
3082 + DBC_Require(pAddr != NULL);
3083 + DBC_Require(pSize != NULL);
3084 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3086 + GT_4trace(DBL_debugMask, GT_ENTER,
3087 + "DBL_getSect: lib: 0x%x name: %s pAddr:"
3088 + " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize);
3090 + /*
3091 + * Check for DCD and overlay sections. Overlay loader uses DBL_getSect
3092 + * to determine whether or not a node has overlay sections.
3093 + * DCD section names begin with '.'
3094 + */
3095 + if (name[0] == '.') {
3096 + /* Get DCD section size (address is 0, since it's a NOLOAD). */
3097 + for (i = 0; i < pdblLib->nDCDSects; i++) {
3098 + if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name,
3099 + name) == 0) {
3100 + *pAddr = 0;
3101 + *pSize = pdblLib->dcdSects[i].sectHdr.size *
3102 + pdblLib->pTargetInfo->mauSize;
3103 + status = DSP_SOK;
3104 + break;
3107 + } else {
3108 + /* Check for overlay section */
3109 + for (i = 0; i < pdblLib->nOvlySects; i++) {
3110 + if (CSL_Strcmp(pdblLib->ppOvlyData[i]->hdr.pName,
3111 + name) == 0) {
3112 + /* Address and size are meaningless */
3113 + *pAddr = 0;
3114 + *pSize = 0;
3115 + status = DSP_SOK;
3116 + break;
3121 + return status;
3125 + * ======== DBL_init ========
3126 + * Purpose:
3127 + * Initialize DBL module.
3128 + */
3129 +bool DBL_init(void)
3131 + bool retVal = true;
3133 + DBC_Require(cRefs >= 0);
3135 + if (cRefs == 0) {
3136 + DBC_Assert(!DBL_debugMask.flags);
3137 + GT_create(&DBL_debugMask, "BL"); /* "BL" for dBL */
3141 + if (retVal)
3142 + cRefs++;
3145 + GT_1trace(DBL_debugMask, GT_5CLASS, "DBL_init(), ref count: 0x%x\n",
3146 + cRefs);
3148 + DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0)));
3150 + return retVal;
3154 + * ======== DBL_load ========
3155 + * Purpose:
3156 + * Add symbols/code/data defined in file to that already present
3157 + * on the target.
3158 + */
3159 +DSP_STATUS DBL_load(struct DBL_LibraryObj *lib, DBL_Flags flags,
3160 + struct DBL_Attrs *attrs, u32 *pEntry)
3162 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3163 + struct DBL_TargetObj *dbl;
3164 + u16 i;
3165 + u16 nSects;
3166 + DSP_STATUS status = DSP_EFAIL;
3168 + DBC_Require(cRefs > 0);
3169 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3170 + DBC_Require(pEntry != NULL);
3171 + DBC_Require(attrs != NULL);
3173 + GT_4trace(DBL_debugMask, GT_ENTER, "DBL_load: lib: 0x%x flags: "
3174 + "0x%x attrs: 0x%x pEntry: 0x%x\n", lib, flags, attrs, pEntry);
3176 + dbl = pdblLib->pTarget;
3177 + *pEntry = pdblLib->fileHdr.entry;
3178 + nSects = pdblLib->fileHdr.numSects;
3179 + dbl->dblAttrs = *attrs;
3181 + for (i = 0; i < nSects; i++) {
3182 + /* Load the section at the current file offset */
3183 + status = loadSect(dbl, lib);
3184 + if (DSP_FAILED(status))
3185 + break;
3189 + /* Done with file, we can close it */
3190 + if (pdblLib->file) {
3191 + (*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file);
3192 + pdblLib->file = NULL;
3194 + return status;
3198 + * ======== DBL_loadSect ========
3199 + * Purpose:
3200 + * Load a named section from an library (for overlay support).
3201 + */
3202 +DSP_STATUS DBL_loadSect(struct DBL_LibraryObj *lib, char *sectName,
3203 + struct DBL_Attrs *attrs)
3205 + struct DBL_TargetObj *dbl;
3206 + s32 i;
3207 + s32 phase;
3208 + s32 offset = -1;
3209 + s32 nSects = -1;
3210 + s32 allocdSects = 0;
3211 + u32 loadAddr;
3212 + u32 runAddr;
3213 + u32 size;
3214 + u32 space;
3215 + u32 ulBytes;
3216 + u16 mauSize;
3217 + u16 wordSize;
3218 + u16 *phaseRef = NULL;
3219 + u16 *otherRef = NULL;
3220 + char *name = NULL;
3221 + struct OvlyData *pOvlyData;
3222 + DSP_STATUS status = DSP_ENOSECT;
3224 + DBC_Require(cRefs > 0);
3225 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3226 + DBC_Require(sectName != NULL);
3227 + DBC_Require(attrs != NULL);
3228 + DBC_Require(attrs->write != NULL);
3229 + GT_3trace(DBL_debugMask, GT_ENTER,
3230 + "DBL_loadSect: lib: 0x%x sectName: %s "
3231 + "attrs: 0x%x\n", lib, sectName, attrs);
3232 + dbl = lib->pTarget;
3233 + mauSize = lib->pTargetInfo->mauSize;
3234 + wordSize = lib->pTargetInfo->wordSize;
3235 + /* Check for match of sect name in overlay table */
3236 + for (i = 0; i < lib->nOvlySects; i++) {
3237 + name = lib->ppOvlyData[i]->hdr.pName;
3238 + if (!CSL_Strncmp(name, sectName, CSL_Strlen(name))) {
3239 + /* Match found */
3240 + status = DSP_SOK;
3241 + break;
3244 + if (DSP_SUCCEEDED(status)) {
3245 + DBC_Assert(i < lib->nOvlySects);
3246 + pOvlyData = lib->ppOvlyData[i];
3247 + /*
3248 + * If node overlay, phase will be encoded in name. If not node
3249 + * overlay, set phase to NONE.
3250 + */
3251 + phase = (CSL_Strcmp(name, sectName)) ?
3252 + CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE;
3253 + /* Get reference count of node phase to be loaded, offset into
3254 + * overlay data array, and number of sections to overlay. */
3255 + switch (phase) {
3256 + case NONE:
3257 + /* Not a node overlay */
3258 + phaseRef = &pOvlyData->hdr.otherRef;
3259 + nSects = numOtherSects(pOvlyData);
3260 + offset = otherOffset(pOvlyData);
3261 + break;
3262 + case CREATEPHASE:
3263 + phaseRef = &pOvlyData->hdr.createRef;
3264 + otherRef = &pOvlyData->hdr.otherRef;
3265 + if (*otherRef) {
3266 + /* The overlay sections where node phase was
3267 + * not specified, have already been loaded. */
3268 + nSects = numCreateSects(pOvlyData);
3269 + offset = createOffset(pOvlyData);
3270 + } else {
3271 + /* Overlay sections where node phase was not
3272 + * specified get loaded at create time, along
3273 + * with create sects. */
3274 + nSects = numCreateSects(pOvlyData) +
3275 + numOtherSects(pOvlyData);
3276 + offset = otherOffset(pOvlyData);
3278 + break;
3279 + case DELETEPHASE:
3280 + phaseRef = &pOvlyData->hdr.deleteRef;
3281 + nSects = numDeleteSects(pOvlyData);
3282 + offset = deleteOffset(pOvlyData);
3283 + break;
3284 + case EXECUTEPHASE:
3285 + phaseRef = &pOvlyData->hdr.executeRef;
3286 + nSects = numExecuteSects(pOvlyData);
3287 + offset = executeOffset(pOvlyData);
3288 + break;
3289 + default:
3290 + /* ERROR */
3291 + DBC_Assert(false);
3292 + break;
3294 + /* Do overlay if reference count is 0 */
3295 + if (!(*phaseRef)) {
3296 + /* "Allocate" all sections */
3297 + for (i = 0; i < nSects; i++) {
3298 + runAddr = pOvlyData->data[offset + i].runAddr;
3299 + size = pOvlyData->data[offset + i].size;
3300 + space = pOvlyData->data[offset + i].page;
3301 + status = (dbl->dblAttrs.alloc)(dbl->dblAttrs.
3302 + rmmHandle, space, size, 0,
3303 + &runAddr, true);
3304 + if (DSP_FAILED(status))
3305 + break;
3307 + allocdSects++;
3309 + if (DSP_SUCCEEDED(status)) {
3310 + /* Load sections */
3311 + for (i = 0; i < nSects; i++) {
3312 + loadAddr = pOvlyData->data[offset + i].
3313 + loadAddr;
3314 + runAddr = pOvlyData->data[offset + i].
3315 + runAddr;
3316 + size = pOvlyData->data[offset + i].
3317 + size;
3318 + space = pOvlyData->data[offset + i].
3319 + page;
3320 + /* Convert to word address, call
3321 + * write function */
3322 + loadAddr /= (wordSize / mauSize);
3323 + runAddr /= (wordSize / mauSize);
3324 + ulBytes = size * mauSize;
3325 + if ((*attrs->write)(attrs->wHandle,
3326 + runAddr, (void *)loadAddr, ulBytes,
3327 + space) != ulBytes) {
3328 + GT_0trace(DBL_debugMask,
3329 + GT_6CLASS,
3330 + "DBL_loadSect: write"
3331 + " failed\n");
3332 + status = DSP_EFWRITE;
3333 + break;
3337 + /* Free sections on failure */
3338 + if (DSP_FAILED(status))
3339 + freeSects(dbl, pOvlyData, offset, allocdSects);
3343 + if (DSP_SUCCEEDED(status)) {
3344 + /* Increment reference counts */
3345 + if (otherRef)
3346 + *otherRef = *otherRef + 1;
3348 + *phaseRef = *phaseRef + 1;
3350 + return status;
3354 + * ======== DBL_open ========
3355 + * Purpose:
3356 + * DBL_open() returns a library handle that can be used to
3357 + * load/unload the symbols/code/data via DBL_load()/DBL_unload().
3358 + */
3359 +DSP_STATUS DBL_open(struct DBL_TargetObj *target, char *file, DBL_Flags flags,
3360 + struct DBL_LibraryObj **pLib)
3362 + struct DBL_LibraryObj *pdblLib = NULL;
3363 + u16 nSymbols;
3364 + u16 nDCDSects;
3365 + DSP_STATUS status = DSP_SOK;
3366 + DBC_Require(cRefs > 0);
3367 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
3368 + DBC_Require(target->dblAttrs.fopen != NULL);
3369 + DBC_Require(file != NULL);
3370 + DBC_Require(pLib != NULL);
3372 + GT_3trace(DBL_debugMask, GT_ENTER, "DBL_open: target: 0x%x file: %s "
3373 + "pLib: 0x%x\n", target, file, pLib);
3374 + /* Allocate DBL library object */
3375 + MEM_AllocObject(pdblLib, struct DBL_LibraryObj, DBL_LIBSIGNATURE);
3376 + if (pdblLib == NULL)
3377 + status = DSP_EMEMORY;
3379 + /* Open the file */
3380 + if (DSP_SUCCEEDED(status)) {
3381 + pdblLib->pTarget = target;
3382 + pdblLib->file = (*target->dblAttrs.fopen)(file, "rb");
3383 + if (pdblLib->file == NULL)
3384 + status = DSP_EFOPEN;
3387 + /* Read file header */
3388 + if (DSP_SUCCEEDED(status)) {
3389 + status = readHeader(target, pdblLib);
3390 + if (DSP_FAILED(status)) {
3391 + GT_0trace(DBL_debugMask, GT_6CLASS,
3392 + "DBL_open(): Failed to read file header\n");
3395 + /* Allocate symbol table */
3396 + if (DSP_SUCCEEDED(status)) {
3397 + nSymbols = pdblLib->nSymbols = pdblLib->fileHdr.numSymbols;
3398 + pdblLib->symbols = MEM_Calloc(nSymbols * sizeof(struct Symbol),
3399 + MEM_PAGED);
3400 + if (pdblLib->symbols == NULL)
3401 + status = DSP_EMEMORY;
3404 + /* Read all the symbols */
3405 + if (DSP_SUCCEEDED(status)) {
3406 + status = readSymbols(target, pdblLib);
3407 + if (DSP_FAILED(status)) {
3408 + GT_0trace(DBL_debugMask, GT_6CLASS,
3409 + "DBL_open(): Failed to read symbols\n");
3412 + /* Allocate DCD sect table */
3413 + if (DSP_SUCCEEDED(status)) {
3414 + nDCDSects = pdblLib->nDCDSects = pdblLib->fileHdr.numDCDSects;
3415 + pdblLib->dcdSects = MEM_Calloc(nDCDSects *
3416 + sizeof(struct DCDSect), MEM_PAGED);
3417 + if (pdblLib->dcdSects == NULL)
3418 + status = DSP_EMEMORY;
3421 + /* Read DCD sections */
3422 + if (DSP_SUCCEEDED(status)) {
3423 + status = readDCDSects(target, pdblLib);
3424 + if (DSP_FAILED(status)) {
3425 + GT_0trace(DBL_debugMask, GT_6CLASS,
3426 + "DBL_open(): Failed to read DCD sections\n");
3429 + /* Read overlay sections */
3430 + if (DSP_SUCCEEDED(status)) {
3431 + status = readOvlySects(target, pdblLib);
3432 + if (DSP_FAILED(status)) {
3433 + GT_0trace(DBL_debugMask, GT_6CLASS,
3434 + "DBL_open(): Failed to read "
3435 + "overlay sections\n");
3438 + if (DSP_FAILED(status)) {
3439 + *pLib = NULL;
3440 + if (pdblLib != NULL)
3441 + DBL_close((struct DBL_LibraryObj *) pdblLib);
3443 + } else {
3444 + *pLib = pdblLib;
3446 + DBC_Ensure((DSP_SUCCEEDED(status) &&
3447 + (MEM_IsValidHandle((*pLib), DBL_LIBSIGNATURE))) ||
3448 + (DSP_FAILED(status) && *pLib == NULL));
3449 + return status;
3453 + * ======== DBL_readSect ========
3454 + * Purpose:
3455 + * Read COFF section into a character buffer.
3456 + */
3457 +DSP_STATUS DBL_readSect(struct DBL_LibraryObj *lib, char *name, char *pContent,
3458 + u32 size)
3460 + struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
3461 + u16 i;
3462 + u32 mauSize;
3463 + u32 max;
3464 + DSP_STATUS status = DSP_ENOSECT;
3466 + DBC_Require(cRefs > 0);
3467 + DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
3468 + DBC_Require(name != NULL);
3469 + DBC_Require(pContent != NULL);
3470 + DBC_Require(size != 0);
3471 + GT_4trace(DBL_debugMask, GT_ENTER, "DBL_readSect: lib: 0x%x name: %s "
3472 + "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size);
3474 + mauSize = pdblLib->pTargetInfo->mauSize;
3476 + /* Attempt to find match with DCD section names. */
3477 + for (i = 0; i < pdblLib->nDCDSects; i++) {
3478 + if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name, name) == 0) {
3479 + /* Match found */
3480 + max = pdblLib->dcdSects[i].sectHdr.size * mauSize;
3481 + max = (max > size) ? size : max;
3482 + memcpy(pContent, pdblLib->dcdSects[i].pData, max);
3483 + status = DSP_SOK;
3484 + break;
3488 + return status;
3492 + * ======== DBL_setAttrs ========
3493 + * Purpose:
3494 + * Set the attributes of the target.
3495 + */
3496 +void DBL_setAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs)
3498 + DBC_Require(cRefs > 0);
3499 + DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
3500 + DBC_Require(pAttrs != NULL);
3502 + GT_2trace(DBL_debugMask, GT_ENTER, "DBL_setAttrs: target: 0x%x pAttrs: "
3503 + "0x%x\n", target, pAttrs);
3505 + target->dblAttrs = *pAttrs;
3509 + * ======== DBL_unload ========
3510 + * Purpose:
3511 + * Remove the symbols/code/data corresponding to the library lib.
3512 + */
3513 +void DBL_unload(struct DBL_LibraryObj *lib, struct DBL_Attrs *attrs)
3515 + DBC_Require(cRefs > 0);
3516 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3518 + GT_1trace(DBL_debugMask, GT_ENTER, "DBL_unload: lib: 0x%x\n", lib);
3520 + /* Nothing to do for static loading */
3524 + * ======== DBL_unloadSect ========
3525 + * Purpose:
3526 + * Unload a named section from an library (for overlay support).
3527 + */
3528 +DSP_STATUS DBL_unloadSect(struct DBL_LibraryObj *lib, char *sectName,
3529 + struct DBL_Attrs *attrs)
3531 + struct DBL_TargetObj *dbl;
3532 + s32 i;
3533 + s32 phase;
3534 + s32 offset = -1;
3535 + s32 nSects = -1;
3536 + u16 *phaseRef = NULL;
3537 + u16 *otherRef = NULL;
3538 + char *pName = NULL;
3539 + struct OvlyData *pOvlyData;
3540 + DSP_STATUS status = DSP_ENOSECT;
3542 + DBC_Require(cRefs > 0);
3543 + DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
3544 + DBC_Require(sectName != NULL);
3546 + GT_2trace(DBL_debugMask, GT_ENTER,
3547 + "DBL_unloadSect: lib: 0x%x sectName: %s\n", lib, sectName);
3548 + dbl = lib->pTarget;
3549 + /* Check for match of sect name in overlay table */
3550 + for (i = 0; i < lib->nOvlySects; i++) {
3551 + pName = lib->ppOvlyData[i]->hdr.pName;
3552 + if (!CSL_Strncmp(pName, sectName, CSL_Strlen(pName))) {
3553 + /* Match found */
3554 + status = DSP_SOK;
3555 + break;
3558 + if (DSP_SUCCEEDED(status)) {
3559 + DBC_Assert(i < lib->nOvlySects);
3560 + pOvlyData = lib->ppOvlyData[i];
3561 + /* If node overlay, phase will be encoded in name. */
3562 + phase = (CSL_Strcmp(pName, sectName)) ?
3563 + CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE;
3564 + switch (phase) {
3565 + case NONE:
3566 + nSects = numOtherSects(pOvlyData);
3567 + phaseRef = &pOvlyData->hdr.otherRef;
3568 + offset = otherOffset(pOvlyData);
3569 + break;
3570 + case CREATEPHASE:
3571 + nSects = numCreateSects(pOvlyData);
3572 + offset = createOffset(pOvlyData);
3573 + phaseRef = &pOvlyData->hdr.createRef;
3574 + break;
3575 + case DELETEPHASE:
3576 + nSects = numDeleteSects(pOvlyData);
3577 + offset = deleteOffset(pOvlyData);
3578 + phaseRef = &pOvlyData->hdr.deleteRef;
3579 + otherRef = &pOvlyData->hdr.otherRef;
3580 + break;
3581 + case EXECUTEPHASE:
3582 + nSects = numExecuteSects(pOvlyData);
3583 + offset = executeOffset(pOvlyData);
3584 + phaseRef = &pOvlyData->hdr.executeRef;
3585 + break;
3586 + default:
3587 + /* ERROR */
3588 + DBC_Assert(false);
3589 + break;
3591 + if (*phaseRef) {
3592 + *phaseRef = *phaseRef - 1;
3593 + if (*phaseRef == 0) {
3594 + /* Unload overlay sections for phase */
3595 + freeSects(dbl, pOvlyData, offset, nSects);
3597 + if (phase == DELETEPHASE) {
3598 + DBC_Assert(*otherRef);
3599 + *otherRef = *otherRef - 1;
3600 + if (*otherRef == 0) {
3601 + /* Unload other overlay sections */
3602 + nSects = numOtherSects(pOvlyData);
3603 + offset = otherOffset(pOvlyData);
3604 + freeSects(dbl, pOvlyData, offset,
3605 + nSects);
3611 + return status;
3615 + * ======== freeSects ========
3616 + * Purpose:
3617 + * Free section
3618 + */
3619 +static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData,
3620 + s32 offset, s32 nSects)
3622 + u32 runAddr;
3623 + u32 size;
3624 + u32 space;
3625 + s32 i;
3627 + for (i = 0; i < nSects; i++) {
3628 + runAddr = pOvlyData->data[offset + i].runAddr;
3629 + size = pOvlyData->data[offset + i].size;
3630 + space = pOvlyData->data[offset + i].page;
3631 + if (!(dbl->dblAttrs.free)
3632 + (dbl->dblAttrs.rmmHandle, space, runAddr, size, true)) {
3633 + /*
3634 + * Free function will not fail for overlay, unless
3635 + * address passed in is bad.
3636 + */
3637 + DBC_Assert(false);
3643 + * ======== loadSect ========
3644 + * Purpose:
3645 + * Load section to target
3646 + */
3647 +static DSP_STATUS loadSect(struct DBL_TargetObj *dbl,
3648 + struct DBL_LibraryObj *pdblLib)
3650 + struct DBOF_SectHdr sectHdr;
3651 + char *pBuf;
3652 + struct KFILE_FileObj *file;
3653 + u32 space;
3654 + u32 addr;
3655 + u32 total;
3656 + u32 nWords = 0;
3657 + u32 nBytes = 0;
3658 + u16 mauSize;
3659 + u32 bufSize;
3660 + DSP_STATUS status = DSP_SOK;
3662 + file = pdblLib->file;
3663 + mauSize = pdblLib->pTargetInfo->mauSize;
3664 + bufSize = LOADBUFSIZE / mauSize;
3665 + pBuf = dbl->pBuf;
3667 + /* Read the section header */
3668 + if ((*dbl->dblAttrs.fread)(&sectHdr, sizeof(struct DBOF_SectHdr),
3669 + 1, file) != 1) {
3670 + GT_0trace(DBL_debugMask, GT_6CLASS,
3671 + "Failed to read DCD sect header\n");
3672 + status = DSP_EFREAD;
3673 + } else {
3674 + if (pdblLib->byteSwapped) {
3675 + sectHdr.size = SWAPLONG(sectHdr.size);
3676 + sectHdr.addr = SWAPLONG(sectHdr.addr);
3677 + sectHdr.page = SWAPWORD(sectHdr.page);
3680 + if (DSP_SUCCEEDED(status)) {
3681 + addr = sectHdr.addr;
3682 + space = sectHdr.page;
3683 + for (total = sectHdr.size; total > 0; total -= nWords) {
3684 + nWords = min(total, bufSize);
3685 + nBytes = nWords * mauSize;
3686 + /* Read section data */
3687 + if ((*dbl->dblAttrs.fread)(pBuf, nBytes, 1,
3688 + file) != 1) {
3689 + GT_0trace(DBL_debugMask, GT_6CLASS,
3690 + "Failed to read DCD sect header\n");
3691 + status = DSP_EFREAD;
3692 + break;
3694 + /* Write section to target */
3695 + if (!(*dbl->dblAttrs.write)(dbl->dblAttrs.wHandle,
3696 + addr, pBuf, nBytes, space)) {
3697 + GT_0trace(DBL_debugMask, GT_6CLASS,
3698 + "Failed to write section data\n");
3699 + status = DSP_EFWRITE;
3700 + break;
3702 + addr += nWords;
3705 + return status;
3709 + * ======== readDCDSects ========
3710 + * Purpose:
3711 + * Read DCD sections.
3712 + */
3713 +static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl,
3714 + struct DBL_LibraryObj *pdblLib)
3716 + struct DBOF_DCDSectHdr *pSectHdr;
3717 + struct DCDSect *pSect;
3718 + struct KFILE_FileObj *file;
3719 + u16 nSects;
3720 + u16 i;
3721 + u16 mauSize;
3722 + DSP_STATUS status = DSP_SOK;
3724 + file = pdblLib->file;
3725 + mauSize = pdblLib->pTargetInfo->mauSize;
3726 + nSects = pdblLib->fileHdr.numDCDSects;
3727 + for (i = 0; i < nSects; i++) {
3728 + pSect = &pdblLib->dcdSects[i];
3729 + pSectHdr = &pdblLib->dcdSects[i].sectHdr;
3730 + /* Read sect header */
3731 + if ((*dbl->dblAttrs.fread)(pSectHdr,
3732 + sizeof(struct DBOF_DCDSectHdr), 1, file) != 1) {
3733 + GT_0trace(DBL_debugMask, GT_6CLASS,
3734 + "Failed to read DCD sect header\n");
3735 + status = DSP_EFREAD;
3736 + break;
3738 + if (pdblLib->byteSwapped)
3739 + pSectHdr->size = SWAPLONG(pSectHdr->size);
3741 + pSect->pData = (char *)MEM_Calloc(pSectHdr->size *
3742 + mauSize, MEM_PAGED);
3743 + if (pSect->pData == NULL) {
3744 + GT_2trace(DBL_debugMask, GT_6CLASS,
3745 + "Memory allocation for sect %s "
3746 + "data failed: Size: 0x%lx\n", pSectHdr->name,
3747 + pSectHdr->size);
3748 + status = DSP_EMEMORY;
3749 + break;
3751 + /* Read DCD sect data */
3752 + if ((*dbl->dblAttrs.fread)(pSect->pData, mauSize,
3753 + pSectHdr->size, file) != pSectHdr->size) {
3754 + GT_0trace(DBL_debugMask, GT_6CLASS,
3755 + "Failed to read DCD sect data\n");
3756 + status = DSP_EFREAD;
3757 + break;
3761 + return status;
3765 + * ======== readHeader ========
3766 + * Purpose:
3767 + * Read Header.
3768 + */
3769 +static DSP_STATUS readHeader(struct DBL_TargetObj *dbl,
3770 + struct DBL_LibraryObj *pdblLib)
3772 + struct KFILE_FileObj *file;
3773 + s32 i;
3774 + struct DBOF_FileHdr *pHdr;
3775 + u32 swapMagic;
3776 + DSP_STATUS status = DSP_SOK;
3778 + pdblLib->byteSwapped = false;
3779 + file = pdblLib->file;
3780 + pHdr = &pdblLib->fileHdr;
3781 + if ((*dbl->dblAttrs.fread)(pHdr, sizeof(struct DBOF_FileHdr), 1,
3782 + file) != 1) {
3783 + GT_0trace(DBL_debugMask, GT_6CLASS,
3784 + "readHeader: Failed to read file header\n");
3785 + status = DSP_EFREAD;
3788 + if (DSP_SUCCEEDED(status)) {
3789 + /* Determine if byte swapped */
3790 + for (i = 0; i < NUMTARGS; i++) {
3791 + swapMagic = SWAPLONG(pHdr->magic);
3792 + if (pHdr->magic == magicTab[i] || swapMagic ==
3793 + magicTab[i]) {
3794 + if (swapMagic == magicTab[i]) {
3795 + pdblLib->byteSwapped = true;
3796 + pHdr->magic = SWAPLONG(pHdr->magic);
3797 + pHdr->entry = SWAPLONG(pHdr->entry);
3798 + pHdr->symOffset = SWAPLONG(pHdr->
3799 + symOffset);
3800 + pHdr->dcdSectOffset = SWAPLONG(pHdr->
3801 + dcdSectOffset);
3802 + pHdr->loadSectOffset = SWAPLONG(pHdr->
3803 + loadSectOffset);
3804 + pHdr->ovlySectOffset = SWAPLONG(pHdr->
3805 + ovlySectOffset);
3806 + pHdr->numSymbols = SWAPWORD(pHdr->
3807 + numSymbols);
3808 + pHdr->numDCDSects = SWAPWORD(pHdr->
3809 + numDCDSects);
3810 + pHdr->numSects = SWAPWORD(pHdr->
3811 + numSects);
3812 + pHdr->numOvlySects = SWAPWORD(pHdr->
3813 + numOvlySects);
3815 + break;
3818 + if (i == NUMTARGS) {
3819 + GT_0trace(DBL_debugMask, GT_6CLASS,
3820 + "readHeader: Failed to determine"
3821 + " target type\n");
3822 + status = DSP_ECORRUPTFILE;
3823 + } else {
3824 + pdblLib->pTargetInfo = &targetTab[i];
3825 + GT_1trace(DBL_debugMask, GT_ENTER,
3826 + "COF type: 0x%lx\n", pHdr->magic);
3827 + GT_1trace(DBL_debugMask, GT_ENTER,
3828 + "Entry point:0x%lx\n", pHdr->entry);
3831 + return status;
3835 + * ======== readOvlySects ========
3836 + * Purpose:
3837 + * Read Overlay Sections
3838 + */
3839 +static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl,
3840 + struct DBL_LibraryObj *pdblLib)
3842 + struct DBOF_OvlySectHdr hdr;
3843 + struct DBOF_OvlySectData *pData;
3844 + struct OvlyData *pOvlyData;
3845 + char *pName;
3846 + struct KFILE_FileObj *file;
3847 + u16 i, j;
3848 + u16 nSects;
3849 + u16 n;
3850 + DSP_STATUS status = DSP_SOK;
3852 + pdblLib->nOvlySects = nSects = pdblLib->fileHdr.numOvlySects;
3853 + file = pdblLib->file;
3854 + if (nSects > 0) {
3855 + pdblLib->ppOvlyData = MEM_Calloc(nSects * sizeof(OvlyData *),
3856 + MEM_PAGED);
3857 + if (pdblLib->ppOvlyData == NULL) {
3858 + GT_0trace(DBL_debugMask, GT_7CLASS,
3859 + "Failed to allocatate overlay "
3860 + "data memory\n");
3861 + status = DSP_EMEMORY;
3864 + if (DSP_SUCCEEDED(status)) {
3865 + /* Read overlay data for each node */
3866 + for (i = 0; i < nSects; i++) {
3867 + /* Read overlay section header */
3868 + if ((*dbl->dblAttrs.fread)(&hdr,
3869 + sizeof(struct DBOF_OvlySectHdr), 1, file) != 1) {
3870 + GT_0trace(DBL_debugMask, GT_6CLASS,
3871 + "Failed to read overlay sect"
3872 + " header\n");
3873 + status = DSP_EFREAD;
3874 + break;
3876 + if (pdblLib->byteSwapped) {
3877 + hdr.nameLen = SWAPWORD(hdr.nameLen);
3878 + hdr.numCreateSects =
3879 + SWAPWORD(hdr.numCreateSects);
3880 + hdr.numDeleteSects =
3881 + SWAPWORD(hdr.numDeleteSects);
3882 + hdr.numExecuteSects =
3883 + SWAPWORD(hdr.numExecuteSects);
3884 + hdr.numOtherSects =
3885 + SWAPWORD(hdr.numOtherSects);
3886 + hdr.resvd = SWAPWORD(hdr.resvd);
3888 + n = hdr.numCreateSects + hdr.numDeleteSects +
3889 + hdr.numExecuteSects + hdr.numOtherSects;
3891 + /* Allocate memory for node's overlay data */
3892 + pOvlyData = (struct OvlyData *)MEM_Calloc
3893 + (sizeof(struct OvlyHdr) +
3894 + n * sizeof(struct DBOF_OvlySectData),
3895 + MEM_PAGED);
3896 + if (pOvlyData == NULL) {
3897 + GT_0trace(DBL_debugMask, GT_7CLASS,
3898 + "Failed to allocatate ovlyay"
3899 + " data memory\n");
3900 + status = DSP_EMEMORY;
3901 + break;
3903 + pOvlyData->hdr.dbofHdr = hdr;
3904 + pdblLib->ppOvlyData[i] = pOvlyData;
3905 + /* Allocate memory for section name */
3906 + pName = (char *)MEM_Calloc(hdr.nameLen + 1, MEM_PAGED);
3907 + if (pName == NULL) {
3908 + GT_0trace(DBL_debugMask, GT_7CLASS,
3909 + "Failed to allocatate ovlyay"
3910 + " section name\n");
3911 + status = DSP_EMEMORY;
3912 + break;
3914 + pOvlyData->hdr.pName = pName;
3915 + /* Read the overlay section name */
3916 + if ((*dbl->dblAttrs.fread)(pName, sizeof(char),
3917 + hdr.nameLen, file) != hdr.nameLen) {
3918 + GT_0trace(DBL_debugMask, GT_7CLASS,
3919 + "readOvlySects: Unable to "
3920 + "read overlay name.\n");
3921 + status = DSP_EFREAD;
3922 + break;
3924 + /* Read the overlay section data */
3925 + pData = pOvlyData->data;
3926 + if ((*dbl->dblAttrs.fread)(pData,
3927 + sizeof(struct DBOF_OvlySectData), n, file) != n) {
3928 + GT_0trace(DBL_debugMask, GT_7CLASS,
3929 + "readOvlySects: Unable to "
3930 + "read overlay data.\n");
3931 + status = DSP_EFREAD;
3932 + break;
3934 + /* Swap overlay data, if necessary */
3935 + if (pdblLib->byteSwapped) {
3936 + for (j = 0; j < n; j++) {
3937 + pData[j].loadAddr =
3938 + SWAPLONG(pData[j].loadAddr);
3939 + pData[j].runAddr =
3940 + SWAPLONG(pData[j].runAddr);
3941 + pData[j].size =
3942 + SWAPLONG(pData[j].size);
3943 + pData[j].page =
3944 + SWAPWORD(pData[j].page);
3949 + return status;
3953 + * ======== readSymbols ========
3954 + * Purpose:
3955 + * Read Symbols
3956 + */
3957 +static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl,
3958 + struct DBL_LibraryObj *pdblLib)
3960 + struct DBOF_SymbolHdr symHdr;
3961 + struct KFILE_FileObj *file;
3962 + u16 i;
3963 + u16 nSymbols;
3964 + u16 len;
3965 + char *pName = NULL;
3966 + DSP_STATUS status = DSP_SOK;
3968 + file = pdblLib->file;
3970 + nSymbols = pdblLib->fileHdr.numSymbols;
3972 + for (i = 0; i < nSymbols; i++) {
3973 + /* Read symbol value */
3974 + if ((*dbl->dblAttrs.fread)(&symHdr,
3975 + sizeof(struct DBOF_SymbolHdr), 1, file) != 1) {
3976 + GT_0trace(DBL_debugMask, GT_6CLASS,
3977 + "Failed to read symbol value\n");
3978 + status = DSP_EFREAD;
3979 + break;
3981 + if (pdblLib->byteSwapped) {
3982 + symHdr.nameLen = SWAPWORD(symHdr.nameLen);
3983 + symHdr.value = SWAPLONG(symHdr.value);
3985 + /* Allocate buffer for symbol name */
3986 + len = symHdr.nameLen;
3987 + pName = (char *)MEM_Calloc(len + 1, MEM_PAGED);
3988 + if (pName == NULL) {
3989 + GT_0trace(DBL_debugMask, GT_6CLASS,
3990 + "Memory allocation failed\n");
3991 + status = DSP_EMEMORY;
3992 + break;
3994 + pdblLib->symbols[i].pSymName = pName;
3995 + pdblLib->symbols[i].sym.value = symHdr.value;
3996 + /* Read symbol name */
3997 + if ((*dbl->dblAttrs.fread) (pName, sizeof(char), len, file) !=
3998 + len) {
3999 + GT_0trace(DBL_debugMask, GT_6CLASS,
4000 + "Failed to read symbol value\n");
4001 + status = DSP_EFREAD;
4002 + break;
4003 + } else {
4004 + pName[len] = '\0';
4005 + GT_2trace(DBL_debugMask, GT_ENTER,
4006 + "Symbol: %s Value: 0x%lx\n",
4007 + pName, symHdr.value);
4010 + return status;
4013 Index: lk/drivers/dsp/bridge/pmgr/dbll.c
4014 ===================================================================
4015 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
4016 +++ lk/drivers/dsp/bridge/pmgr/dbll.c 2008-08-18 10:38:37.000000000 +0300
4017 @@ -0,0 +1,1565 @@
4019 + * linux/drivers/dsp/bridge/pmgr/linux/dbll/dbll.c
4021 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
4023 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
4025 + * This package is free software; you can redistribute it and/or modify
4026 + * it under the terms of the GNU General Public License version 2 as
4027 + * published by the Free Software Foundation.
4029 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
4030 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
4031 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
4032 + */
4035 + * ======== dbll.c ========
4037 + *! Revision History
4038 + *! ================
4039 + *! 25-Apr-2030 map: Fixed symbol redefinition bug + unload and return error
4040 + *! 08-Apr-2003 map: Consolidated DBL with DBLL loader name
4041 + *! 24-Mar-2003 map: Updated findSymbol to support dllview update
4042 + *! 23-Jan-2003 map: Updated rmmAlloc to support memory granularity
4043 + *! 21-Nov-2002 map: Combine fopen and DLOAD_module_open to increase
4044 + *! performance on start.
4045 + *! 04-Oct-2002 map: Integrated new TIP dynamic loader w/ DOF api.
4046 + *! 27-Sep-2002 map: Changed handle passed to RemoteFree, instead of
4047 + *! RMM_free; added GT_trace to rmmDealloc
4048 + *! 20-Sep-2002 map: Updated from Code Review
4049 + *! 08-Aug-2002 jeh: Updated to support overlays.
4050 + *! 25-Jun-2002 jeh: Pass RMM_Addr object to alloc function in rmmAlloc().
4051 + *! 20-Mar-2002 jeh: Created.
4052 + */
4054 +/* ----------------------------------- Host OS */
4055 +#include <host_os.h>
4057 +/* ----------------------------------- DSP/BIOS Bridge */
4058 +#include <std.h>
4059 +#include <dbdefs.h>
4060 +#include <errbase.h>
4062 +/* ----------------------------------- Trace & Debug */
4063 +#include <gt.h>
4064 +#include <dbc.h>
4065 +#include <gh.h>
4067 +/* ----------------------------------- OS Adaptation Layer */
4068 +#include <csl.h>
4069 +#include <mem.h>
4071 +/* Dynamic loader library interface */
4072 +#include <dynamic_loader.h>
4073 +#include <getsection.h>
4075 +/* ----------------------------------- This */
4076 +#include <dbll.h>
4077 +#include <rmm.h>
4079 +#define DBLL_TARGSIGNATURE 0x544c4c44 /* "TLLD" */
4080 +#define DBLL_LIBSIGNATURE 0x4c4c4c44 /* "LLLD" */
4082 +/* Number of buckets for symbol hash table */
4083 +#define MAXBUCKETS 211
4085 +/* Max buffer length */
4086 +#define MAXEXPR 128
4088 +#ifndef UINT32_C
4089 +#define UINT32_C(zzz) ((uint32_t)zzz)
4090 +#endif
4091 +#define DOFF_ALIGN(x) (((x) + 3) & ~UINT32_C(3))
4094 + * ======== struct DBLL_TarObj* ========
4095 + * A target may have one or more libraries of symbols/code/data loaded
4096 + * onto it, where a library is simply the symbols/code/data contained
4097 + * in a DOFF file.
4098 + */
4100 + * ======== DBLL_TarObj ========
4101 + */
4102 +struct DBLL_TarObj {
4103 + u32 dwSignature; /* For object validation */
4104 + struct DBLL_Attrs attrs;
4105 + struct DBLL_LibraryObj *head; /* List of all opened libraries */
4106 +} ;
4109 + * The following 4 typedefs are "super classes" of the dynamic loader
4110 + * library types used in dynamic loader functions (dynamic_loader.h).
4111 + */
4113 + * ======== DBLLStream ========
4114 + * Contains Dynamic_Loader_Stream
4115 + */
4116 +struct DBLLStream {
4117 + struct Dynamic_Loader_Stream dlStream;
4118 + struct DBLL_LibraryObj *lib;
4119 +} ;
4122 + * ======== DBLLSymbol ========
4123 + */
4124 +struct DBLLSymbol {
4125 + struct Dynamic_Loader_Sym dlSymbol;
4126 + struct DBLL_LibraryObj *lib;
4127 +} ;
4130 + * ======== DBLLAlloc ========
4131 + */
4132 + struct DBLLAlloc {
4133 + struct Dynamic_Loader_Allocate dlAlloc;
4134 + struct DBLL_LibraryObj *lib;
4135 +} ;
4138 + * ======== DBLLInit ========
4139 + */
4140 +struct DBLLInit {
4141 + struct Dynamic_Loader_Initialize dlInit;
4142 + struct DBLL_LibraryObj *lib;
4146 + * ======== DBLL_Library ========
4147 + * A library handle is returned by DBLL_Open() and is passed to DBLL_load()
4148 + * to load symbols/code/data, and to DBLL_unload(), to remove the
4149 + * symbols/code/data loaded by DBLL_load().
4150 + */
4153 + * ======== DBLL_LibraryObj ========
4154 + */
4155 + struct DBLL_LibraryObj {
4156 + u32 dwSignature; /* For object validation */
4157 + struct DBLL_LibraryObj *next; /* Next library in target's list */
4158 + struct DBLL_LibraryObj *prev; /* Previous in the list */
4159 + struct DBLL_TarObj *pTarget; /* target for this library */
4161 + /* Objects needed by dynamic loader */
4162 + struct DBLLStream stream;
4163 + struct DBLLSymbol symbol;
4164 + struct DBLLAlloc allocate;
4165 + struct DBLLInit init;
4166 + DLOAD_mhandle mHandle;
4168 + char *fileName; /* COFF file name */
4169 + void *fp; /* Opaque file handle */
4170 + u32 entry; /* Entry point */
4171 + DLOAD_mhandle desc; /* desc of DOFF file loaded */
4172 + u32 openRef; /* Number of times opened */
4173 + u32 loadRef; /* Number of times loaded */
4174 + struct GH_THashTab *symTab; /* Hash table of symbols */
4175 + u32 ulPos;
4176 +} ;
4179 + * ======== Symbol ========
4180 + */
4181 +struct Symbol {
4182 + struct DBLL_Symbol value;
4183 + char *name;
4184 +} ;
4185 +extern bool bSymbolsReloaded;
4187 +static void dofClose(struct DBLL_LibraryObj *zlLib);
4188 +static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib);
4189 +static s32 NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr,
4190 + LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsiz);
4193 + * Functions called by dynamic loader
4195 + */
4196 +/* Dynamic_Loader_Stream */
4197 +static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer,
4198 + unsigned bufsize);
4199 +static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos);
4200 +/* Dynamic_Loader_Sym */
4201 +static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this,
4202 + const char *name);
4203 +static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this,
4204 + const char *name,
4205 + unsigned moduleId);
4206 +static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this,
4207 + const char *name,
4208 + unsigned moduleid);
4209 +static void purgeSymbolTable(struct Dynamic_Loader_Sym *this,
4210 + unsigned moduleId);
4211 +static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize);
4212 +static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr);
4213 +static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr,
4214 + va_list args);
4215 +/* Dynamic_Loader_Allocate */
4216 +static int rmmAlloc(struct Dynamic_Loader_Allocate *this,
4217 + struct LDR_SECTION_INFO *info, unsigned align);
4218 +static void rmmDealloc(struct Dynamic_Loader_Allocate *this,
4219 + struct LDR_SECTION_INFO *info);
4221 +/* Dynamic_Loader_Initialize */
4222 +static int connect(struct Dynamic_Loader_Initialize *this);
4223 +static int readMem(struct Dynamic_Loader_Initialize *this, void *buf,
4224 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
4225 + unsigned nbytes);
4226 +static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf,
4227 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
4228 + unsigned nbytes);
4229 +static int fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr,
4230 + struct LDR_SECTION_INFO *info, unsigned nbytes,
4231 + unsigned val);
4232 +static int execute(struct Dynamic_Loader_Initialize *this, LDR_ADDR start);
4233 +static void release(struct Dynamic_Loader_Initialize *this);
4235 +/* symbol table hash functions */
4236 +static u16 nameHash(void *name, u16 maxBucket);
4237 +static bool nameMatch(void *name, void *sp);
4238 +static void symDelete(void *sp);
4240 +#if GT_TRACE
4241 +static struct GT_Mask DBLL_debugMask = { NULL, NULL }; /* GT trace variable */
4242 +#endif
4244 +static u32 cRefs; /* module reference count */
4246 +/* Symbol Redefinition */
4247 +static int bRedefinedSymbol = 0;
4248 +static int bGblSearch = 1;
4251 + * ======== DBLL_close ========
4252 + */
4253 +void DBLL_close(struct DBLL_LibraryObj *zlLib)
4255 + struct DBLL_TarObj *zlTarget;
4257 + DBC_Require(cRefs > 0);
4258 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4259 + DBC_Require(zlLib->openRef > 0);
4260 + zlTarget = zlLib->pTarget;
4261 + GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_close: lib: 0x%x\n", zlLib);
4262 + zlLib->openRef--;
4263 + if (zlLib->openRef == 0) {
4264 + /* Remove library from list */
4265 + if (zlTarget->head == zlLib)
4266 + zlTarget->head = zlLib->next;
4268 + if (zlLib->prev)
4269 + (zlLib->prev)->next = zlLib->next;
4271 + if (zlLib->next)
4272 + (zlLib->next)->prev = zlLib->prev;
4274 + /* Free DOF resources */
4275 + dofClose(zlLib);
4276 + if (zlLib->fileName)
4277 + MEM_Free(zlLib->fileName);
4279 + /* remove symbols from symbol table */
4280 + if (zlLib->symTab)
4281 + GH_delete(zlLib->symTab);
4283 + /* remove the library object itself */
4284 + MEM_FreeObject(zlLib);
4285 + zlLib = NULL;
4290 + * ======== DBLL_create ========
4291 + */
4292 +DSP_STATUS DBLL_create(struct DBLL_TarObj **pTarget, struct DBLL_Attrs *pAttrs)
4294 + struct DBLL_TarObj *pzlTarget;
4295 + DSP_STATUS status = DSP_SOK;
4297 + DBC_Require(cRefs > 0);
4298 + DBC_Require(pAttrs != NULL);
4299 + DBC_Require(pTarget != NULL);
4301 + GT_2trace(DBLL_debugMask, GT_ENTER,
4302 + "DBLL_create: pTarget: 0x%x pAttrs: "
4303 + "0x%x\n", pTarget, pAttrs);
4304 + /* Allocate DBL target object */
4305 + MEM_AllocObject(pzlTarget, struct DBLL_TarObj, DBLL_TARGSIGNATURE);
4306 + if (pTarget != NULL) {
4307 + if (pzlTarget == NULL) {
4308 + GT_0trace(DBLL_debugMask, GT_6CLASS,
4309 + "DBLL_create: Memory allocation"
4310 + " failed\n");
4311 + *pTarget = NULL;
4312 + status = DSP_EMEMORY;
4313 + } else {
4314 + pzlTarget->attrs = *pAttrs;
4315 + *pTarget = (struct DBLL_TarObj *)pzlTarget;
4317 + DBC_Ensure((DSP_SUCCEEDED(status) &&
4318 + MEM_IsValidHandle(((struct DBLL_TarObj *)(*pTarget)),
4319 + DBLL_TARGSIGNATURE)) || (DSP_FAILED(status) &&
4320 + *pTarget == NULL));
4323 + return status;
4327 + * ======== DBLL_delete ========
4328 + */
4329 +void DBLL_delete(struct DBLL_TarObj *target)
4331 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4333 + DBC_Require(cRefs > 0);
4334 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4336 + GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_delete: target: 0x%x\n",
4337 + target);
4339 + if (zlTarget != NULL)
4340 + MEM_FreeObject(zlTarget);
4345 + * ======== DBLL_exit ========
4346 + * Discontinue usage of DBL module.
4347 + */
4348 +void DBLL_exit(void)
4350 + DBC_Require(cRefs > 0);
4352 + cRefs--;
4354 + GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_exit() ref count: 0x%x\n",
4355 + cRefs);
4357 + if (cRefs == 0) {
4358 + MEM_Exit();
4359 + CSL_Exit();
4360 + GH_exit();
4361 +#if GT_TRACE
4362 + DBLL_debugMask.flags = 0;
4363 +#endif
4366 + DBC_Ensure(cRefs >= 0);
4370 + * ======== DBLL_getAddr ========
4371 + * Get address of name in the specified library.
4372 + */
4373 +bool DBLL_getAddr(struct DBLL_LibraryObj *zlLib, char *name,
4374 + struct DBLL_Symbol **ppSym)
4376 + struct Symbol *sym;
4377 + bool status = false;
4379 + DBC_Require(cRefs > 0);
4380 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4381 + DBC_Require(name != NULL);
4382 + DBC_Require(ppSym != NULL);
4383 + DBC_Require(zlLib->symTab != NULL);
4385 + GT_3trace(DBLL_debugMask, GT_ENTER,
4386 + "DBLL_getAddr: lib: 0x%x name: %s pAddr:"
4387 + " 0x%x\n", zlLib, name, ppSym);
4388 + sym = (struct Symbol *)GH_find(zlLib->symTab, name);
4389 + if (sym != NULL) {
4390 + *ppSym = &sym->value;
4391 + status = true;
4393 + return status;
4397 + * ======== DBLL_getAttrs ========
4398 + * Retrieve the attributes of the target.
4399 + */
4400 +void DBLL_getAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs)
4402 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4404 + DBC_Require(cRefs > 0);
4405 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4406 + DBC_Require(pAttrs != NULL);
4408 + if ((pAttrs != NULL) && (zlTarget != NULL))
4409 + *pAttrs = zlTarget->attrs;
4414 + * ======== DBLL_getCAddr ========
4415 + * Get address of a "C" name in the specified library.
4416 + */
4417 +bool DBLL_getCAddr(struct DBLL_LibraryObj *zlLib, char *name,
4418 + struct DBLL_Symbol **ppSym)
4420 + struct Symbol *sym;
4421 + char cname[MAXEXPR + 1];
4422 + bool status = false;
4424 + DBC_Require(cRefs > 0);
4425 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4426 + DBC_Require(ppSym != NULL);
4427 + DBC_Require(zlLib->symTab != NULL);
4428 + DBC_Require(name != NULL);
4430 + cname[0] = '_';
4432 + CSL_Strcpyn(cname + 1, name, sizeof(cname) - 2);
4433 + cname[MAXEXPR] = '\0'; /* insure '\0' string termination */
4435 + /* Check for C name, if not found */
4436 + sym = (struct Symbol *)GH_find(zlLib->symTab, cname);
4438 + if (sym != NULL) {
4439 + *ppSym = &sym->value;
4440 + status = true;
4443 + return status;
4447 + * ======== DBLL_getSect ========
4448 + * Get the base address and size (in bytes) of a COFF section.
4449 + */
4450 +DSP_STATUS DBLL_getSect(struct DBLL_LibraryObj *lib, char *name, u32 *pAddr,
4451 + u32 *pSize)
4453 + u32 uByteSize;
4454 + bool fOpenedDoff = false;
4455 + const struct LDR_SECTION_INFO *sect = NULL;
4456 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4457 + DSP_STATUS status = DSP_SOK;
4459 + DBC_Require(cRefs > 0);
4460 + DBC_Require(name != NULL);
4461 + DBC_Require(pAddr != NULL);
4462 + DBC_Require(pSize != NULL);
4463 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4465 + GT_4trace(DBLL_debugMask, GT_ENTER,
4466 + "DBLL_getSect: lib: 0x%x name: %s pAddr:"
4467 + " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize);
4468 + /* If DOFF file is not open, we open it. */
4469 + if (zlLib != NULL) {
4470 + if (zlLib->fp == NULL) {
4471 + status = dofOpen(zlLib);
4472 + if (DSP_SUCCEEDED(status))
4473 + fOpenedDoff = true;
4475 + } else {
4476 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp,
4477 + zlLib->ulPos, SEEK_SET);
4480 + if (DSP_SUCCEEDED(status)) {
4481 + uByteSize = 1;
4482 + if (DLOAD_GetSectionInfo(zlLib->desc, name, &sect)) {
4483 + *pAddr = sect->load_addr;
4484 + *pSize = sect->size * uByteSize;
4485 + /* Make sure size is even for good swap */
4486 + if (*pSize % 2)
4487 + (*pSize)++;
4489 + /* Align size */
4490 + *pSize = DOFF_ALIGN(*pSize);
4491 + } else {
4492 + status = DSP_ENOSECT;
4495 + if (fOpenedDoff) {
4496 + dofClose(zlLib);
4497 + fOpenedDoff = false;
4500 + return status;
4504 + * ======== DBLL_init ========
4505 + */
4506 +bool DBLL_init(void)
4508 + bool retVal = true;
4510 + DBC_Require(cRefs >= 0);
4512 + if (cRefs == 0) {
4513 + DBC_Assert(!DBLL_debugMask.flags);
4514 + GT_create(&DBLL_debugMask, "DL"); /* "DL" for dbDL */
4515 + GH_init();
4516 + CSL_Init();
4517 + retVal = MEM_Init();
4518 + if (!retVal)
4519 + MEM_Exit();
4523 + if (retVal)
4524 + cRefs++;
4527 + GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_init(), ref count: 0x%x\n",
4528 + cRefs);
4530 + DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0)));
4532 + return retVal;
4536 + * ======== DBLL_load ========
4537 + */
4538 +DSP_STATUS DBLL_load(struct DBLL_LibraryObj *lib, DBLL_Flags flags,
4539 + struct DBLL_Attrs *attrs, u32 *pEntry)
4541 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4542 + struct DBLL_TarObj *dbzl;
4543 + bool gotSymbols = true;
4544 + s32 err;
4545 + DSP_STATUS status = DSP_SOK;
4546 + bool fOpenedDoff = false;
4547 + DBC_Require(cRefs > 0);
4548 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4549 + DBC_Require(pEntry != NULL);
4550 + DBC_Require(attrs != NULL);
4552 + GT_4trace(DBLL_debugMask, GT_ENTER,
4553 + "DBLL_load: lib: 0x%x flags: 0x%x pEntry:"
4554 + " 0x%x\n", lib, flags, attrs, pEntry);
4555 + /*
4556 + * Load if not already loaded.
4557 + */
4558 + if (zlLib->loadRef == 0 || !(flags & DBLL_DYNAMIC)) {
4559 + dbzl = zlLib->pTarget;
4560 + dbzl->attrs = *attrs;
4561 + /* Create a hash table for symbols if not already created */
4562 + if (zlLib->symTab == NULL) {
4563 + gotSymbols = false;
4564 + zlLib->symTab = GH_create(MAXBUCKETS,
4565 + sizeof(struct Symbol),
4566 + nameHash,
4567 + nameMatch, symDelete);
4568 + if (zlLib->symTab == NULL)
4569 + status = DSP_EMEMORY;
4572 + /*
4573 + * Set up objects needed by the dynamic loader
4574 + */
4575 + /* Stream */
4576 + zlLib->stream.dlStream.read_buffer = readBuffer;
4577 + zlLib->stream.dlStream.set_file_posn = setFilePosn;
4578 + zlLib->stream.lib = zlLib;
4579 + /* Symbol */
4580 + zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol;
4581 + if (gotSymbols) {
4582 + zlLib->symbol.dlSymbol.Add_To_Symbol_Table =
4583 + findInSymbolTable;
4584 + } else {
4585 + zlLib->symbol.dlSymbol.Add_To_Symbol_Table =
4586 + addToSymbolTable;
4588 + zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable;
4589 + zlLib->symbol.dlSymbol.Allocate = allocate;
4590 + zlLib->symbol.dlSymbol.Deallocate = deallocate;
4591 + zlLib->symbol.dlSymbol.Error_Report = errorReport;
4592 + zlLib->symbol.lib = zlLib;
4593 + /* Allocate */
4594 + zlLib->allocate.dlAlloc.Allocate = rmmAlloc;
4595 + zlLib->allocate.dlAlloc.Deallocate = rmmDealloc;
4596 + zlLib->allocate.lib = zlLib;
4597 + /* Init */
4598 + zlLib->init.dlInit.connect = connect;
4599 + zlLib->init.dlInit.readmem = readMem;
4600 + zlLib->init.dlInit.writemem = writeMem;
4601 + zlLib->init.dlInit.fillmem = fillMem;
4602 + zlLib->init.dlInit.execute = execute;
4603 + zlLib->init.dlInit.release = release;
4604 + zlLib->init.lib = zlLib;
4605 + /* If COFF file is not open, we open it. */
4606 + if (zlLib->fp == NULL) {
4607 + status = dofOpen(zlLib);
4608 + if (DSP_SUCCEEDED(status))
4609 + fOpenedDoff = true;
4612 + if (DSP_SUCCEEDED(status)) {
4613 + zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell))
4614 + (zlLib->fp);
4615 + /* Reset file cursor */
4616 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0,
4617 + SEEK_SET);
4618 + bSymbolsReloaded = true;
4619 + /* The 5th argument, DLOAD_INITBSS, tells the DLL
4620 + * module to zero-init all BSS sections. In general,
4621 + * this is not necessary and also increases load time.
4622 + * We may want to make this configurable by the user */
4623 + err = Dynamic_Load_Module(&zlLib->stream.dlStream,
4624 + &zlLib->symbol.dlSymbol, &zlLib->allocate.dlAlloc,
4625 + &zlLib->init.dlInit, DLOAD_INITBSS,
4626 + &zlLib->mHandle);
4628 + if (err != 0) {
4629 + GT_1trace(DBLL_debugMask, GT_6CLASS,
4630 + "DBLL_load: "
4631 + "Dynamic_Load_Module failed: 0x%lx\n",
4632 + err);
4633 + status = DSP_EDYNLOAD;
4634 + } else if (bRedefinedSymbol) {
4635 + zlLib->loadRef++;
4636 + DBLL_unload(zlLib, (struct DBLL_Attrs *) attrs);
4637 + bRedefinedSymbol = false;
4638 + status = DSP_EDYNLOAD;
4639 + } else {
4640 + *pEntry = zlLib->entry;
4644 + if (DSP_SUCCEEDED(status))
4645 + zlLib->loadRef++;
4647 + /* Clean up DOFF resources */
4648 + if (fOpenedDoff)
4649 + dofClose(zlLib);
4651 + DBC_Ensure(DSP_FAILED(status) || zlLib->loadRef > 0);
4652 + return status;
4656 + * ======== DBLL_loadSect ========
4657 + * Not supported for COFF.
4658 + */
4659 +DSP_STATUS DBLL_loadSect(struct DBLL_LibraryObj *zlLib, char *sectName,
4660 + struct DBLL_Attrs *attrs)
4662 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4664 + return DSP_ENOTIMPL;
4668 + * ======== DBLL_open ========
4669 + */
4670 +DSP_STATUS DBLL_open(struct DBLL_TarObj *target, char *file, DBLL_Flags flags,
4671 + struct DBLL_LibraryObj **pLib)
4673 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4674 + struct DBLL_LibraryObj *zlLib = NULL;
4675 + s32 err;
4676 + DSP_STATUS status = DSP_SOK;
4678 + DBC_Require(cRefs > 0);
4679 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4680 + DBC_Require(zlTarget->attrs.fopen != NULL);
4681 + DBC_Require(file != NULL);
4682 + DBC_Require(pLib != NULL);
4684 + GT_3trace(DBLL_debugMask, GT_ENTER,
4685 + "DBLL_open: target: 0x%x file: %s pLib:"
4686 + " 0x%x\n", target, file, pLib);
4687 + zlLib = zlTarget->head;
4688 + while (zlLib != NULL) {
4689 + if (CSL_Strcmp(zlLib->fileName, file) == 0) {
4690 + /* Library is already opened */
4691 + zlLib->openRef++;
4692 + break;
4694 + zlLib = zlLib->next;
4696 + if (zlLib == NULL) {
4697 + /* Allocate DBL library object */
4698 + MEM_AllocObject(zlLib, struct DBLL_LibraryObj,
4699 + DBLL_LIBSIGNATURE);
4700 + if (zlLib == NULL) {
4701 + GT_0trace(DBLL_debugMask, GT_6CLASS,
4702 + "DBLL_open: Memory allocation failed\n");
4703 + status = DSP_EMEMORY;
4704 + } else {
4705 + zlLib->ulPos = 0;
4706 + /* Increment ref count to allow close on failure
4707 + * later on */
4708 + zlLib->openRef++;
4709 + zlLib->pTarget = zlTarget;
4710 + /* Keep a copy of the file name */
4711 + zlLib->fileName = MEM_Calloc(CSL_Strlen(file) + 1,
4712 + MEM_PAGED);
4713 + if (zlLib->fileName == NULL) {
4714 + GT_0trace(DBLL_debugMask, GT_6CLASS,
4715 + "DBLL_open: Memory "
4716 + "allocation failed\n");
4717 + status = DSP_EMEMORY;
4718 + } else {
4719 + CSL_Strcpyn(zlLib->fileName, file,
4720 + CSL_Strlen(file) + 1);
4722 + zlLib->symTab = NULL;
4725 + /*
4726 + * Set up objects needed by the dynamic loader
4727 + */
4728 + if (DSP_FAILED(status))
4729 + goto func_cont;
4731 + /* Stream */
4732 + zlLib->stream.dlStream.read_buffer = readBuffer;
4733 + zlLib->stream.dlStream.set_file_posn = setFilePosn;
4734 + zlLib->stream.lib = zlLib;
4735 + /* Symbol */
4736 + zlLib->symbol.dlSymbol.Add_To_Symbol_Table = addToSymbolTable;
4737 + zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol;
4738 + zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable;
4739 + zlLib->symbol.dlSymbol.Allocate = allocate;
4740 + zlLib->symbol.dlSymbol.Deallocate = deallocate;
4741 + zlLib->symbol.dlSymbol.Error_Report = errorReport;
4742 + zlLib->symbol.lib = zlLib;
4743 + /* Allocate */
4744 + zlLib->allocate.dlAlloc.Allocate = rmmAlloc;
4745 + zlLib->allocate.dlAlloc.Deallocate = rmmDealloc;
4746 + zlLib->allocate.lib = zlLib;
4747 + /* Init */
4748 + zlLib->init.dlInit.connect = connect;
4749 + zlLib->init.dlInit.readmem = readMem;
4750 + zlLib->init.dlInit.writemem = writeMem;
4751 + zlLib->init.dlInit.fillmem = fillMem;
4752 + zlLib->init.dlInit.execute = execute;
4753 + zlLib->init.dlInit.release = release;
4754 + zlLib->init.lib = zlLib;
4755 + if (DSP_SUCCEEDED(status) && zlLib->fp == NULL)
4756 + status = dofOpen(zlLib);
4758 + zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell)) (zlLib->fp);
4759 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long) 0, SEEK_SET);
4760 + /* Create a hash table for symbols if flag is set */
4761 + if (zlLib->symTab != NULL || !(flags & DBLL_SYMB))
4762 + goto func_cont;
4764 + zlLib->symTab = GH_create(MAXBUCKETS, sizeof(struct Symbol), nameHash,
4765 + nameMatch, symDelete);
4766 + if (zlLib->symTab == NULL) {
4767 + status = DSP_EMEMORY;
4768 + } else {
4769 + /* Do a fake load to get symbols - set write function to NoOp */
4770 + zlLib->init.dlInit.writemem = NoOp;
4771 + err = Dynamic_Open_Module(&zlLib->stream.dlStream,
4772 + &zlLib->symbol.dlSymbol,
4773 + &zlLib->allocate.dlAlloc,
4774 + &zlLib->init.dlInit, 0,
4775 + &zlLib->mHandle);
4776 + if (err != 0) {
4777 + GT_1trace(DBLL_debugMask, GT_6CLASS, "DBLL_open: "
4778 + "Dynamic_Load_Module failed: 0x%lx\n", err);
4779 + status = DSP_EDYNLOAD;
4780 + } else {
4781 + /* Now that we have the symbol table, we can unload */
4782 + err = Dynamic_Unload_Module(zlLib->mHandle,
4783 + &zlLib->symbol.dlSymbol,
4784 + &zlLib->allocate.dlAlloc,
4785 + &zlLib->init.dlInit);
4786 + if (err != 0) {
4787 + GT_1trace(DBLL_debugMask, GT_6CLASS,
4788 + "DBLL_open: "
4789 + "Dynamic_Unload_Module failed: 0x%lx\n",
4790 + err);
4791 + status = DSP_EDYNLOAD;
4793 + zlLib->mHandle = NULL;
4796 +func_cont:
4797 + if (DSP_SUCCEEDED(status)) {
4798 + if (zlLib->openRef == 1) {
4799 + /* First time opened - insert in list */
4800 + if (zlTarget->head)
4801 + (zlTarget->head)->prev = zlLib;
4803 + zlLib->prev = NULL;
4804 + zlLib->next = zlTarget->head;
4805 + zlTarget->head = zlLib;
4807 + *pLib = (struct DBLL_LibraryObj *)zlLib;
4808 + } else {
4809 + *pLib = NULL;
4810 + if (zlLib != NULL)
4811 + DBLL_close((struct DBLL_LibraryObj *)zlLib);
4814 + DBC_Ensure((DSP_SUCCEEDED(status) && (zlLib->openRef > 0) &&
4815 + MEM_IsValidHandle(((struct DBLL_LibraryObj *)(*pLib)),
4816 + DBLL_LIBSIGNATURE)) || (DSP_FAILED(status) && *pLib == NULL));
4817 + return status;
4821 + * ======== DBLL_readSect ========
4822 + * Get the content of a COFF section.
4823 + */
4824 +DSP_STATUS DBLL_readSect(struct DBLL_LibraryObj *lib, char *name,
4825 + char *pContent, u32 size)
4827 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4828 + bool fOpenedDoff = false;
4829 + u32 uByteSize; /* size of bytes */
4830 + u32 ulSectSize; /* size of section */
4831 + const struct LDR_SECTION_INFO *sect = NULL;
4832 + DSP_STATUS status = DSP_SOK;
4834 + DBC_Require(cRefs > 0);
4835 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4836 + DBC_Require(name != NULL);
4837 + DBC_Require(pContent != NULL);
4838 + DBC_Require(size != 0);
4840 + GT_4trace(DBLL_debugMask, GT_ENTER,
4841 + "DBLL_readSect: lib: 0x%x name: %s "
4842 + "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size);
4843 + /* If DOFF file is not open, we open it. */
4844 + if (zlLib != NULL) {
4845 + if (zlLib->fp == NULL) {
4846 + status = dofOpen(zlLib);
4847 + if (DSP_SUCCEEDED(status))
4848 + fOpenedDoff = true;
4850 + } else {
4851 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp,
4852 + zlLib->ulPos, SEEK_SET);
4856 + if (DSP_FAILED(status))
4857 + goto func_cont;
4859 + uByteSize = 1;
4860 + if (!DLOAD_GetSectionInfo(zlLib->desc, name, &sect)) {
4861 + status = DSP_ENOSECT;
4862 + goto func_cont;
4864 + /*
4865 + * Ensure the supplied buffer size is sufficient to store
4866 + * the section content to be read.
4867 + */
4868 + ulSectSize = sect->size * uByteSize;
4869 + /* Make sure size is even for good swap */
4870 + if (ulSectSize % 2)
4871 + ulSectSize++;
4873 + /* Align size */
4874 + ulSectSize = DOFF_ALIGN(ulSectSize);
4875 + if (ulSectSize > size) {
4876 + status = DSP_EFAIL;
4877 + } else {
4878 + if (!DLOAD_GetSection(zlLib->desc, sect, pContent))
4879 + status = DSP_EFREAD;
4882 +func_cont:
4883 + if (fOpenedDoff) {
4884 + dofClose(zlLib);
4885 + fOpenedDoff = false;
4887 + return status;
4891 + * ======== DBLL_setAttrs ========
4892 + * Set the attributes of the target.
4893 + */
4894 +void DBLL_setAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs)
4896 + struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
4897 + DBC_Require(cRefs > 0);
4898 + DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
4899 + DBC_Require(pAttrs != NULL);
4900 + GT_2trace(DBLL_debugMask, GT_ENTER,
4901 + "DBLL_setAttrs: target: 0x%x pAttrs: "
4902 + "0x%x\n", target, pAttrs);
4903 + if ((pAttrs != NULL) && (zlTarget != NULL))
4904 + zlTarget->attrs = *pAttrs;
4909 + * ======== DBLL_unload ========
4910 + */
4911 +void DBLL_unload(struct DBLL_LibraryObj *lib, struct DBLL_Attrs *attrs)
4913 + struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
4914 + s32 err = 0;
4916 + DBC_Require(cRefs > 0);
4917 + DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
4918 + DBC_Require(zlLib->loadRef > 0);
4919 + GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_unload: lib: 0x%x\n", lib);
4920 + zlLib->loadRef--;
4921 + /* Unload only if reference count is 0 */
4922 + if (zlLib->loadRef != 0)
4923 + goto func_end;
4925 + zlLib->pTarget->attrs = *attrs;
4926 + if (zlLib != NULL) {
4927 + if (zlLib->mHandle) {
4928 + err = Dynamic_Unload_Module(zlLib->mHandle,
4929 + &zlLib->symbol.dlSymbol,
4930 + &zlLib->allocate.dlAlloc, &zlLib->init.dlInit);
4931 + if (err != 0) {
4932 + GT_1trace(DBLL_debugMask, GT_5CLASS,
4933 + "Dynamic_Unload_Module "
4934 + "failed: 0x%x\n", err);
4937 + /* remove symbols from symbol table */
4938 + if (zlLib->symTab != NULL) {
4939 + GH_delete(zlLib->symTab);
4940 + zlLib->symTab = NULL;
4942 + /* delete DOFF desc since it holds *lots* of host OS
4943 + * resources */
4944 + dofClose(zlLib);
4946 +func_end:
4947 + DBC_Ensure(zlLib->loadRef >= 0);
4951 + * ======== DBLL_unloadSect ========
4952 + * Not supported for COFF.
4953 + */
4954 +DSP_STATUS DBLL_unloadSect(struct DBLL_LibraryObj *lib, char *sectName,
4955 + struct DBLL_Attrs *attrs)
4957 + DBC_Require(cRefs > 0);
4958 + DBC_Require(sectName != NULL);
4959 + GT_2trace(DBLL_debugMask, GT_ENTER,
4960 + "DBLL_unloadSect: lib: 0x%x sectName: "
4961 + "%s\n", lib, sectName);
4962 + return DSP_ENOTIMPL;
4966 + * ======== dofClose ========
4967 + */
4968 +static void dofClose(struct DBLL_LibraryObj *zlLib)
4970 + if (zlLib->desc) {
4971 + DLOAD_module_close(zlLib->desc);
4972 + zlLib->desc = NULL;
4974 + /* close file */
4975 + if (zlLib->fp) {
4976 + (zlLib->pTarget->attrs.fclose) (zlLib->fp);
4977 + zlLib->fp = NULL;
4982 + * ======== dofOpen ========
4983 + */
4984 +static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib)
4986 + void *open = *(zlLib->pTarget->attrs.fopen);
4987 + DSP_STATUS status = DSP_SOK;
4989 + /* First open the file for the dynamic loader, then open COF */
4990 + zlLib->fp = (void *)((Fxn)(open))(zlLib->fileName, "rb");
4992 + /* Open DOFF module */
4993 + if (zlLib->fp && zlLib->desc == NULL) {
4994 + (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0, SEEK_SET);
4995 + zlLib->desc = DLOAD_module_open(&zlLib->stream.dlStream,
4996 + &zlLib->symbol.dlSymbol);
4997 + if (zlLib->desc == NULL) {
4998 + (zlLib->pTarget->attrs.fclose)(zlLib->fp);
4999 + zlLib->fp = NULL;
5000 + status = DSP_EFOPEN;
5002 + } else {
5003 + status = DSP_EFOPEN;
5006 + return status;
5010 + * ======== nameHash ========
5011 + */
5012 +static u16 nameHash(void *key, u16 maxBucket)
5014 + u16 ret;
5015 + u16 hash;
5016 + char *name = (char *)key;
5018 + DBC_Require(name != NULL);
5020 + hash = 0;
5022 + while (*name) {
5023 + hash <<= 1;
5024 + hash ^= *name++;
5027 + ret = hash % maxBucket;
5029 + return ret;
5033 + * ======== nameMatch ========
5034 + */
5035 +static bool nameMatch(void *key, void *value)
5037 + DBC_Require(key != NULL);
5038 + DBC_Require(value != NULL);
5040 + if ((key != NULL) && (value != NULL)) {
5041 + if (CSL_Strcmp((char *)key, ((struct Symbol *)value)->
5042 + name) == 0) {
5043 + return true;
5046 + return false;
5050 + * ======== NoOp ========
5051 + */
5052 +static int NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr,
5053 + LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsize)
5055 + return 1;
5059 + * ======== symDelete ========
5060 + */
5061 +static void symDelete(void *value)
5063 + struct Symbol *sp = (struct Symbol *)value;
5065 + MEM_Free(sp->name);
5069 + * Dynamic Loader Functions
5070 + */
5072 +/* Dynamic_Loader_Stream */
5074 + * ======== readBuffer ========
5075 + */
5076 +static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer,
5077 + unsigned bufsize)
5079 + struct DBLLStream *pStream = (struct DBLLStream *)this;
5080 + struct DBLL_LibraryObj *lib;
5081 + int bytesRead = 0;
5083 + DBC_Require(this != NULL);
5084 + lib = pStream->lib;
5085 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5087 + if (lib != NULL) {
5088 + bytesRead = (*(lib->pTarget->attrs.fread))(buffer, 1, bufsize,
5089 + lib->fp);
5091 + return bytesRead;
5095 + * ======== setFilePosn ========
5096 + */
5097 +static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos)
5099 + struct DBLLStream *pStream = (struct DBLLStream *)this;
5100 + struct DBLL_LibraryObj *lib;
5101 + int status = 0; /* Success */
5103 + DBC_Require(this != NULL);
5104 + lib = pStream->lib;
5105 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5107 + if (lib != NULL) {
5108 + status = (*(lib->pTarget->attrs.fseek))(lib->fp, (long)pos,
5109 + SEEK_SET);
5112 + return status;
5115 +/* Dynamic_Loader_Sym */
5118 + * ======== findSymbol ========
5119 + */
5120 +static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this,
5121 + const char *name)
5123 + struct dynload_symbol *retSym;
5124 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5125 + struct DBLL_LibraryObj *lib;
5126 + struct DBLL_Symbol *pSym = NULL;
5127 + bool status = false; /* Symbol not found yet */
5129 + DBC_Require(this != NULL);
5130 + lib = pSymbol->lib;
5131 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5133 + if (lib != NULL) {
5134 + if (lib->pTarget->attrs.symLookup) {
5135 + /* Check current lib + base lib + dep lib +
5136 + * persistent lib */
5137 + status = (*(lib->pTarget->attrs.symLookup))
5138 + (lib->pTarget->attrs.symHandle,
5139 + lib->pTarget->attrs.symArg,
5140 + lib->pTarget->attrs.rmmHandle, name, &pSym);
5141 + } else {
5142 + /* Just check current lib for symbol */
5143 + status = DBLL_getAddr((struct DBLL_LibraryObj *)lib,
5144 + (char *)name, &pSym);
5145 + if (!status) {
5146 + status =
5147 + DBLL_getCAddr((struct DBLL_LibraryObj *)lib,
5148 + (char *)name, &pSym);
5153 + if (!status && bGblSearch) {
5154 + GT_1trace(DBLL_debugMask, GT_6CLASS,
5155 + "findSymbol: Symbol not found: %s\n", name);
5158 + DBC_Assert((status && (pSym != NULL)) || (!status && (pSym == NULL)));
5160 + retSym = (struct dynload_symbol *)pSym;
5161 + return retSym;
5165 + * ======== findInSymbolTable ========
5166 + */
5167 +static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this,
5168 + const char *name,
5169 + unsigned moduleid)
5171 + struct dynload_symbol *retSym;
5172 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5173 + struct DBLL_LibraryObj *lib;
5174 + struct Symbol *sym;
5176 + DBC_Require(this != NULL);
5177 + lib = pSymbol->lib;
5178 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5179 + DBC_Require(lib->symTab != NULL);
5181 + sym = (struct Symbol *)GH_find(lib->symTab, (char *) name);
5183 + retSym = (struct dynload_symbol *)&sym->value;
5184 + return retSym;
5188 + * ======== addToSymbolTable ========
5189 + */
5190 +static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this,
5191 + const char *name,
5192 + unsigned moduleId)
5194 + struct Symbol *symPtr = NULL;
5195 + struct Symbol symbol;
5196 + struct dynload_symbol *pSym = NULL;
5197 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5198 + struct DBLL_LibraryObj *lib;
5199 + struct dynload_symbol *retVal;
5201 + DBC_Require(this != NULL);
5202 + lib = pSymbol->lib;
5203 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5205 + /* Check to see if symbol is already defined in symbol table */
5206 + if (!(lib->pTarget->attrs.baseImage)) {
5207 + bGblSearch = false;
5208 + pSym = findSymbol(this, name);
5209 + bGblSearch = true;
5210 + if (pSym) {
5211 + bRedefinedSymbol = true;
5212 + GT_1trace(DBLL_debugMask, GT_6CLASS,
5213 + "Symbol already defined in "
5214 + "symbol table: %s\n", name);
5215 + return NULL;
5218 + /* Allocate string to copy symbol name */
5219 + symbol.name = (char *)MEM_Calloc(CSL_Strlen((char *const)name) + 1,
5220 + MEM_PAGED);
5221 + if (symbol.name == NULL)
5222 + return NULL;
5224 + if (symbol.name != NULL) {
5225 + /* Just copy name (value will be filled in by dynamic loader) */
5226 + CSL_Strcpyn(symbol.name, (char *const)name,
5227 + CSL_Strlen((char *const)name) + 1);
5229 + /* Add symbol to symbol table */
5230 + symPtr = (struct Symbol *)GH_insert(lib->symTab, (void *)name,
5231 + (void *)&symbol);
5232 + if (symPtr == NULL)
5233 + MEM_Free(symbol.name);
5236 + if (symPtr != NULL)
5237 + retVal = (struct dynload_symbol *)&symPtr->value;
5238 + else
5239 + retVal = NULL;
5241 + return retVal;
5245 + * ======== purgeSymbolTable ========
5246 + */
5247 +static void purgeSymbolTable(struct Dynamic_Loader_Sym *this, unsigned moduleId)
5249 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5250 + struct DBLL_LibraryObj *lib;
5252 + DBC_Require(this != NULL);
5253 + lib = pSymbol->lib;
5254 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5256 + /* May not need to do anything */
5260 + * ======== allocate ========
5261 + */
5262 +static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize)
5264 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5265 + struct DBLL_LibraryObj *lib;
5266 + void *buf;
5268 + DBC_Require(this != NULL);
5269 + lib = pSymbol->lib;
5270 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5272 + buf = MEM_Calloc(memsize, MEM_PAGED);
5274 + return buf;
5278 + * ======== deallocate ========
5279 + */
5280 +static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr)
5282 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5283 + struct DBLL_LibraryObj *lib;
5285 + DBC_Require(this != NULL);
5286 + lib = pSymbol->lib;
5287 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5289 + MEM_Free(memPtr);
5293 + * ======== errorReport ========
5294 + */
5295 +static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr,
5296 + va_list args)
5298 + struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
5299 + struct DBLL_LibraryObj *lib;
5300 + char tempBuf[MAXEXPR];
5302 + DBC_Require(this != NULL);
5303 + lib = pSymbol->lib;
5304 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5305 + vsnprintf((char *)tempBuf, MAXEXPR, (char *)errstr, args);
5306 + GT_1trace(DBLL_debugMask, GT_5CLASS, "%s\n", tempBuf);
5309 +/* Dynamic_Loader_Allocate */
5312 + * ======== rmmAlloc ========
5313 + */
5314 +static int rmmAlloc(struct Dynamic_Loader_Allocate *this,
5315 + struct LDR_SECTION_INFO *info, unsigned align)
5317 + struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this;
5318 + struct DBLL_LibraryObj *lib;
5319 + DSP_STATUS status = DSP_SOK;
5320 + u32 memType;
5321 + struct RMM_Addr rmmAddr;
5322 + s32 retVal = TRUE;
5323 + unsigned stype = DLOAD_SECTION_TYPE(info->type);
5324 + char *pToken = NULL;
5325 + char *szSecLastToken = NULL;
5326 + char *szLastToken = NULL;
5327 + char *szSectName = NULL;
5328 + char *pszCur;
5329 + s32 tokenLen = 0;
5330 + s32 segId = -1;
5331 + s32 req = -1;
5332 + s32 count = 0;
5333 + u32 allocSize = 0;
5335 + DBC_Require(this != NULL);
5336 + lib = pAlloc->lib;
5337 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5339 + memType = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ?
5340 + DBLL_BSS : DBLL_DATA;
5342 + /* Attempt to extract the segment ID and requirement information from
5343 + the name of the section */
5344 + tokenLen = CSL_Strlen((char *)(info->name)) + 1;
5346 + szSectName = MEM_Calloc(tokenLen, MEM_PAGED);
5347 + szLastToken = MEM_Calloc(tokenLen, MEM_PAGED);
5348 + szSecLastToken = MEM_Calloc(tokenLen, MEM_PAGED);
5350 + if (szSectName == NULL || szSecLastToken == NULL ||
5351 + szLastToken == NULL) {
5352 + status = DSP_EMEMORY;
5353 + goto func_cont;
5355 + CSL_Strcpyn(szSectName, (char *)(info->name), tokenLen);
5356 + pToken = CSL_Strtokr(szSectName, ":", &pszCur);
5357 + while (pToken) {
5358 + CSL_Strcpyn(szSecLastToken, szLastToken,
5359 + CSL_Strlen(szLastToken) + 1);
5360 + CSL_Strcpyn(szLastToken, pToken, CSL_Strlen(pToken) + 1);
5361 + pToken = CSL_Strtokr(NULL, ":", &pszCur);
5362 + count++; /* optimizes processing*/
5364 + /* If pToken is 0 or 1, and szSecLastToken is DYN_DARAM or DYN_SARAM,
5365 + or DYN_EXTERNAL, then mem granularity information is present
5366 + within the section name - only process if there are at least three
5367 + tokens within the section name (just a minor optimization)*/
5368 + if (count >= 3)
5369 + req = CSL_Atoi(szLastToken);
5371 + if ((req == 0) || (req == 1)) {
5372 + if (CSL_Strcmp(szSecLastToken, "DYN_DARAM") == 0) {
5373 + segId = 0;
5374 + } else {
5375 + if (CSL_Strcmp(szSecLastToken, "DYN_SARAM") == 0) {
5376 + segId = 1;
5377 + } else {
5378 + if (CSL_Strcmp(szSecLastToken,
5379 + "DYN_EXTERNAL") == 0) {
5380 + segId = 2;
5384 + if (segId != -1) {
5385 + GT_2trace(DBLL_debugMask, GT_5CLASS,
5386 + "Extracted values for memory"
5387 + " granularity req [%d] segId [%d]\n",
5388 + req, segId);
5391 + MEM_Free(szSectName);
5392 + szSectName = NULL;
5393 + MEM_Free(szLastToken);
5394 + szLastToken = NULL;
5395 + MEM_Free(szSecLastToken);
5396 + szSecLastToken = NULL;
5397 +func_cont:
5398 + if (memType == DBLL_CODE)
5399 + allocSize = info->size + GEM_L1P_PREFETCH_SIZE;
5400 + else
5401 + allocSize = info->size;
5402 + /* TODO - ideally, we can pass the alignment requirement also
5403 + * from here */
5404 + if (lib != NULL) {
5405 + status = (lib->pTarget->attrs.alloc)(lib->pTarget->
5406 + attrs.rmmHandle, memType, allocSize, align,
5407 + (u32 *)&rmmAddr, segId, req, FALSE);
5409 + if (DSP_FAILED(status)) {
5410 + retVal = false;
5411 + } else {
5412 + /* RMM gives word address. Need to convert to byte address */
5413 + info->load_addr = rmmAddr.addr * DSPWORDSIZE;
5414 + info->run_addr = info->load_addr;
5415 + info->context = (u32)rmmAddr.segid;
5416 + GT_3trace(DBLL_debugMask, GT_5CLASS,
5417 + "Remote alloc: %s base = 0x%lx len"
5418 + "= 0x%lx\n", info->name, info->load_addr / DSPWORDSIZE,
5419 + info->size / DSPWORDSIZE);
5421 + return retVal;
5425 + * ======== rmmDealloc ========
5426 + */
5427 +static void rmmDealloc(struct Dynamic_Loader_Allocate *this,
5428 + struct LDR_SECTION_INFO *info)
5430 + struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this;
5431 + struct DBLL_LibraryObj *lib;
5432 + u32 segid;
5433 + DSP_STATUS status = DSP_SOK;
5434 + unsigned stype = DLOAD_SECTION_TYPE(info->type);
5435 + u32 memType;
5436 + u32 freeSize = 0;
5438 + memType = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ?
5439 + DBLL_BSS : DBLL_DATA;
5440 + DBC_Require(this != NULL);
5441 + lib = pAlloc->lib;
5442 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5443 + /* segid was set by alloc function */
5444 + segid = (u32)info->context;
5445 + if (memType == DBLL_CODE)
5446 + freeSize = info->size + GEM_L1P_PREFETCH_SIZE;
5447 + else
5448 + freeSize = info->size;
5449 + if (lib != NULL) {
5450 + status = (lib->pTarget->attrs.free)(lib->pTarget->
5451 + attrs.symHandle, segid, info->load_addr / DSPWORDSIZE,
5452 + freeSize, false);
5454 + if (DSP_SUCCEEDED(status)) {
5455 + GT_2trace(DBLL_debugMask, GT_5CLASS,
5456 + "Remote dealloc: base = 0x%lx len ="
5457 + "0x%lx\n", info->load_addr / DSPWORDSIZE,
5458 + freeSize / DSPWORDSIZE);
5462 +/* Dynamic_Loader_Initialize */
5464 + * ======== connect ========
5465 + */
5466 +static int connect(struct Dynamic_Loader_Initialize *this)
5468 + return true;
5472 + * ======== readMem ========
5473 + * This function does not need to be implemented.
5474 + */
5475 +static int readMem(struct Dynamic_Loader_Initialize *this, void *buf,
5476 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
5477 + unsigned nbytes)
5479 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5480 + struct DBLL_LibraryObj *lib;
5481 + int bytesRead = 0;
5483 + DBC_Require(this != NULL);
5484 + lib = pInit->lib;
5485 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5486 + /* Need WMD_BRD_Read function */
5487 + return bytesRead;
5491 + * ======== writeMem ========
5492 + */
5493 +static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf,
5494 + LDR_ADDR addr, struct LDR_SECTION_INFO *info,
5495 + unsigned nBytes)
5497 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5498 + struct DBLL_LibraryObj *lib;
5499 + struct DBLL_SectInfo sectInfo;
5500 + u32 memType;
5501 + bool retVal = true;
5503 + DBC_Require(this != NULL);
5504 + lib = pInit->lib;
5505 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5507 + memType = (DLOAD_SECTION_TYPE(info->type) == DLOAD_TEXT) ? DBLL_CODE :
5508 + DBLL_DATA;
5509 + if (lib != NULL) {
5510 + retVal = (*lib->pTarget->attrs.write)(lib->pTarget->
5511 + attrs.wHandle, addr, buf, nBytes, memType);
5513 + if (lib->pTarget->attrs.logWrite) {
5514 + sectInfo.name = info->name;
5515 + sectInfo.runAddr = info->run_addr;
5516 + sectInfo.loadAddr = info->load_addr;
5517 + sectInfo.size = info->size;
5518 + sectInfo.type = memType;
5519 + /* Pass the information about what we've written to
5520 + * another module */
5521 + (*lib->pTarget->attrs.logWrite)(lib->pTarget->
5522 + attrs.logWriteHandle, &sectInfo, addr, nBytes);
5524 + return retVal;
5528 + * ======== fillMem ========
5529 + * Fill nBytes of memory at a given address with a given value by
5530 + * writing from a buffer containing the given value. Write in
5531 + * sets of MAXEXPR (128) bytes to avoid large stack buffer issues.
5532 + */
5533 +static int fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr,
5534 + struct LDR_SECTION_INFO *info, unsigned nBytes,
5535 + unsigned val)
5537 + bool retVal = true;
5538 + char *pBuf;
5539 + struct DBLL_LibraryObj *lib;
5540 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5542 + DBC_Require(this != NULL);
5543 + lib = pInit->lib;
5544 + pBuf = NULL;
5545 + /* Pass the NULL pointer to writeMem to get the start address of Shared
5546 + memory. This is a trick to just get the start address, there is no
5547 + writing taking place with this Writemem
5548 + */
5549 + if ((lib->pTarget->attrs.write) != (DBLL_WriteFxn)NoOp)
5550 + writeMem(this, &pBuf, addr, info, 0);
5551 + if (pBuf)
5552 + memset(pBuf, val, nBytes);
5554 + return retVal;
5558 + * ======== execute ========
5559 + */
5560 +static int execute(struct Dynamic_Loader_Initialize *this, LDR_ADDR start)
5562 + struct DBLLInit *pInit = (struct DBLLInit *)this;
5563 + struct DBLL_LibraryObj *lib;
5564 + bool retVal = true;
5566 + DBC_Require(this != NULL);
5567 + lib = pInit->lib;
5568 + DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
5569 + /* Save entry point */
5570 + if (lib != NULL)
5571 + lib->entry = (u32)start;
5573 + return retVal;
5577 + * ======== release ========
5578 + */
5579 +static void release(struct Dynamic_Loader_Initialize *this)
5583 Index: lk/drivers/dsp/bridge/pmgr/dev.c
5584 ===================================================================
5585 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
5586 +++ lk/drivers/dsp/bridge/pmgr/dev.c 2008-08-18 10:38:37.000000000 +0300
5587 @@ -0,0 +1,1475 @@
5589 + * linux/drivers/dsp/bridge/pmgr/dev.c
5591 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5593 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
5595 + * This package is free software; you can redistribute it and/or modify
5596 + * it under the terms of the GNU General Public License version 2 as
5597 + * published by the Free Software Foundation.
5599 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
5600 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
5601 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
5602 + */
5606 + * ======== dev.c ========
5607 + * Description:
5608 + * Implementation of 'Bridge Mini-driver device operations.
5610 + * Public Functions:
5611 + * DEV_BrdWriteFxn
5612 + * DEV_CreateDevice
5613 + * DEV_Create2
5614 + * DEV_Destroy2
5615 + * DEV_DestroyDevice
5616 + * DEV_GetChnlMgr
5617 + * DEV_GetCmmMgr
5618 + * DEV_GetCodMgr
5619 + * DEV_GetDehMgr
5620 + * DEV_GetDevNode
5621 + * DEV_GetDSPWordSize
5622 + * DEV_GetFirst
5623 + * DEV_GetIntfFxns
5624 + * DEV_GetIOMgr
5625 + * DEV_GetNext
5626 + * DEV_GetNodeManager
5627 + * DEV_GetSymbol
5628 + * DEV_GetWMDContext
5629 + * DEV_Exit
5630 + * DEV_Init
5631 + * DEV_InsertProcObject
5632 + * DEV_IsLocked
5633 + * DEV_NotifyClient
5634 + * DEV_RegisterNotify
5635 + * DEV_ReleaseCodMgr
5636 + * DEV_RemoveDevice
5637 + * DEV_RemoveProcObject
5638 + * DEV_SetChnlMgr
5639 + * DEV_SetMsgMgr
5640 + * DEV_SetLockOwner
5641 + * DEV_StartDevice
5643 + * Private Functions:
5644 + * FxnNotImplemented
5645 + * InitCodMgr
5646 + * InsertDevObject
5647 + * IsValidHandle
5648 + * RemoveDevObject
5649 + * StoreInterfaceFxns
5651 + *! Revision History:
5652 + *! ================
5653 + *! 03-Jan-2005 hn Support for IVA DEH
5654 + *! 08-Mar-2004 sb Added the Dynamic Memory Mapping feature
5655 + *! 09-Feb-2004 vp Updated to support IVA.
5656 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
5657 + *! 29-Nov-2001 jeh Check for DSP_ENOTIMPL status of DEH create function.
5658 + *! 05-Nov-2001 kc Added support for DEH module.
5659 + *! 05-Aug-2001 ag Shared memory registration moved to WMD_IO_OnLoaded().
5660 + *! 11-Jul-2001 jeh Moved MGR_Create() from DSP_Init() to DEV_StartDevice().
5661 + *! 11-Apr-2001 rr: Removed CMM_RegisterGPPSMSeg.
5662 + *! 02-Apr-2001 rr: CHNL_Create failure is printed out.
5663 + *! 15-Jan-2001 jeh Removed call to IO_OnLoaded() from DEV_Create2().
5664 + *! 13-Feb-2001 kc: DSP/BIOS Bridge name update.
5665 + *! 15-Dec-2000 rr: Dev_Create2 returns error if NODE_CreateMgr fails.
5666 + *! 05-Dec-2000 jeh Moved IO_OnLoaded() to PROC_Load. Added DEV_SetMsgMgr.
5667 + *! 05-Dev-2000 ag SM Heap for messaging registered via CMM_RegisterGPPSMSeg().
5668 + *! SM heap base and size currently taken from registry.
5669 + *! 29-Nov-2000 rr: Incorporated code review changes.
5670 + *! 17-Nov-2000 jeh Added calls to get IO manager (IO_Create), IO_OnLoaded().
5671 + *! 06-Oct-2000 rr: DEV_Destroy2 and DEV_Create2 added.
5672 + *! 02-Oct-2000 rr: DEV_GetNodeManager added.
5673 + *! 11-Aug-2000 ag: Added DEV_GetCmmMgr(), CMM_Init() & CMM_Exit().
5674 + *! Removed <std.h> & <stdwin.h>, added <dbtype.h>
5675 + *! 10-Aug-2000 rr: DEV_InsertProcObject/RemoveProcObject added.
5676 + *! DEV_Cleanup calls PROC_Detach if it is a matching process.
5677 + *! 27-Jul-2000 rr: DEV is in new directoy DEV and produces devlib.lib
5678 + *! 17-Jul-2000 rr: DRV Object holds the list of Dev Objects. DEV gets
5679 + *! the List and Next devices through DRV.
5680 + *! DEV object has a back pointer to DRV Object.
5681 + *! 06-Jun-2000 jeh Added DEV_GetSymbol().
5682 + *! 09-May-2000 rr: dwMemBase has index for multiple windows need.
5683 + *! 28-Feb-2000 rr: New GT Usage implemented.
5684 + *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from
5685 + *! SERVICES)
5686 + *! 31-Jan-2000 rr: Comments changed after code review.
5687 + *! 21-Jan-2000 rr: windows.h, tchar.h, HMODULE removed. FreeLibrary replaced
5688 + *! with LDR_FreeModule
5689 + *! 17-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject.
5690 + *! StoreInterfaceFxns stores the new fxn WMD_BRD_SETSTATE.
5691 + *! 20-Nov-1999 ag: Actual uSMLength = total - monitor offset.
5692 + *! 12-Nov-1999 rr: bIRQ and IRQAttrib taken from the struct CFG_HOSTRES.
5693 + *! dMemBase is added with offset for monitor taken from
5694 + *! registry.
5695 + *! 31-Oct-1999 ag: Added CHNL support.
5696 + *! 10-Sep-1999 rr: GT Enabled. DEV_Create will Load the Mini Driver and will
5697 + *! find its fxn table. Right now lot of things are hardcoded
5698 + *! as the REG is not ready.
5699 + *! 10-Jun-1996 rr: Created from WSX
5700 + */
5702 +/* ----------------------------------- Host OS */
5703 +#include <host_os.h>
5705 +/* ----------------------------------- DSP/BIOS Bridge */
5706 +#include <std.h>
5707 +#include <dbdefs.h>
5708 +#include <errbase.h>
5710 +/* ----------------------------------- Trace & Debug */
5711 +#include <dbc.h>
5712 +#include <dbg.h>
5713 +#include <gt.h>
5715 +/* ----------------------------------- OS Adaptation Layer */
5716 +#include <cfg.h>
5717 +#include <ldr.h>
5718 +#include <list.h>
5719 +#include <mem.h>
5720 +#include <util.h>
5722 +/* ----------------------------------- Platform Manager */
5723 +#include <cod.h>
5724 +#include <drv.h>
5725 +#include <proc.h>
5726 +#include <dmm.h>
5728 +/* ----------------------------------- Resource Manager */
5729 +#include <mgr.h>
5730 +#include <node.h>
5732 +/* ----------------------------------- Others */
5733 +#include <dbreg.h>
5734 +#include <wcd.h> /* WCD version info. */
5736 +#include <chnl.h>
5737 +#include <io.h>
5738 +#include <msg.h>
5739 +#include <cmm.h>
5741 +/* ----------------------------------- This */
5742 +#include <dev.h>
5744 +/* ----------------------------------- Defines, Data Structures, Typedefs */
5746 +#define SIGNATURE 0x5f564544 /* "DEV_" (in reverse) */
5747 +#define MAKEVERSION(major, minor) (major * 10 + minor)
5748 +#define WCDVERSION MAKEVERSION(WCD_MAJOR_VERSION, WCD_MINOR_VERSION)
5750 +/* The WMD device object: */
5751 +struct DEV_OBJECT {
5752 + /* LST requires "link" to be first field! */
5753 + struct LST_ELEM link; /* Link to next DEV_OBJECT. */
5754 + u32 devType; /* Device Type */
5755 + u32 dwSignature; /* Used for object validation. */
5756 + struct CFG_DEVNODE *hDevNode; /* Platform specific device id */
5757 + struct WMD_DEV_CONTEXT *hWmdContext; /* WMD Context Handle */
5758 + struct WMD_DRV_INTERFACE intfFxns; /* Function interface to WMD. */
5759 + struct BRD_OBJECT *lockOwner; /* Client with exclusive access. */
5760 + struct COD_MANAGER *hCodMgr; /* Code manager handle. */
5761 + struct CHNL_MGR *hChnlMgr; /* Channel manager. */
5762 + struct DEH_MGR *hDehMgr; /* DEH manager. */
5763 + struct MSG_MGR *hMsgMgr; /* Message manager. */
5764 + struct IO_MGR *hIOMgr; /* IO manager (CHNL, MSG) */
5765 + struct CMM_OBJECT *hCmmMgr; /* SM memory manager. */
5766 + struct DMM_OBJECT *hDmmMgr; /* Dynamic memory manager. */
5767 + struct LDR_MODULE *hModule; /* WMD Module handle. */
5768 + u32 uWordSize; /* DSP word size: quick access. */
5769 + struct DRV_OBJECT *hDrvObject; /* Driver Object */
5770 + struct LST_LIST *procList; /* List of Proceeosr attached to
5771 + * this device */
5772 + struct NODE_MGR *hNodeMgr;
5773 +} ;
5775 +/* ----------------------------------- Globals */
5776 +static u32 cRefs; /* Module reference count */
5777 +#if GT_TRACE
5778 +static struct GT_Mask debugMask = { NULL, NULL }; /* For debugging */
5779 +#endif
5781 +/* ----------------------------------- Function Prototypes */
5782 +static DSP_STATUS FxnNotImplemented(int arg, ...);
5783 +static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject);
5784 +static bool IsValidHandle(struct DEV_OBJECT *hObj);
5785 +static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns,
5786 + OUT struct WMD_DRV_INTERFACE *pIntfFxns);
5788 + * ======== DEV_BrdWriteFxn ========
5789 + * Purpose:
5790 + * Exported function to be used as the COD write function. This function
5791 + * is passed a handle to a DEV_hObject, then calls the
5792 + * device's WMD_BRD_Write() function.
5793 + */
5794 +u32 DEV_BrdWriteFxn(void *pArb, u32 ulDspAddr, void *pHostBuf,
5795 + u32 ulNumBytes, u32 nMemSpace)
5797 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)pArb;
5798 + u32 ulWritten = 0;
5799 + DSP_STATUS status;
5801 + DBC_Require(cRefs > 0);
5802 + DBC_Require(pHostBuf != NULL); /* Required of BrdWrite(). */
5803 + GT_5trace(debugMask, GT_ENTER,
5804 + "Entered DEV_BrdWriteFxn, pArb: 0x%x\n\t\t"
5805 + "ulDspAddr: 0x%x\n\t\tpHostBuf: 0x%x\n \t\tulNumBytes: 0x%x\n"
5806 + "\t\tnMemSpace: 0x%x\n", pArb, ulDspAddr, pHostBuf,
5807 + ulNumBytes, nMemSpace);
5808 + if (IsValidHandle(pDevObject)) {
5809 + /* Require of BrdWrite() */
5810 + DBC_Assert(pDevObject->hWmdContext != NULL);
5811 + status = (*pDevObject->intfFxns.pfnBrdWrite)(pDevObject->
5812 + hWmdContext, pHostBuf, ulDspAddr, ulNumBytes,
5813 + nMemSpace);
5814 + /* Special case of getting the address only */
5815 + if (ulNumBytes == 0)
5816 + ulNumBytes = 1;
5817 + if (DSP_SUCCEEDED(status))
5818 + ulWritten = ulNumBytes;
5821 + GT_1trace(debugMask, GT_ENTER, "Exit DEV_BrdWriteFxn ulWritten: 0x%x\n",
5822 + ulWritten);
5823 + return ulWritten;
5827 + * ======== DEV_CreateDevice ========
5828 + * Purpose:
5829 + * Called by the operating system to load the PM Mini Driver for a
5830 + * PM board (device).
5831 + */
5832 +DSP_STATUS DEV_CreateDevice(OUT struct DEV_OBJECT **phDevObject,
5833 + IN CONST char *pstrWMDFileName,
5834 + IN CONST struct CFG_HOSTRES *pHostConfig,
5835 + IN CONST struct CFG_DSPRES *pDspConfig,
5836 + struct CFG_DEVNODE *hDevNode)
5838 + struct LDR_MODULE *hModule = NULL;
5839 + struct WMD_DRV_INTERFACE *pDrvFxns = NULL;
5840 + struct DEV_OBJECT *pDevObject = NULL;
5841 + struct CHNL_MGRATTRS mgrAttrs;
5842 + struct IO_ATTRS ioMgrAttrs;
5843 + u32 uNumWindows;
5844 + struct DRV_OBJECT *hDrvObject = NULL;
5845 + DSP_STATUS status = DSP_SOK;
5846 + DBC_Require(cRefs > 0);
5847 + DBC_Require(phDevObject != NULL);
5848 + DBC_Require(pstrWMDFileName != NULL);
5849 + DBC_Require(pHostConfig != NULL);
5850 + DBC_Require(pDspConfig != NULL);
5852 + GT_5trace(debugMask, GT_ENTER,
5853 + "Entered DEV_CreateDevice, phDevObject: 0x%x\n"
5854 + "\t\tpstrWMDFileName: 0x%x\n\t\tpHostConfig:0x%x\n\t\t"
5855 + "pDspConfig: 0x%x\n\t\tnhDevNode: 0x%x\n", phDevObject,
5856 + pstrWMDFileName, pHostConfig, pDspConfig, hDevNode);
5857 + /* Get the WMD interface functions*/
5858 + WMD_DRV_Entry(&pDrvFxns, pstrWMDFileName);
5859 + if (DSP_FAILED(CFG_GetObject((u32 *) &hDrvObject, REG_DRV_OBJECT))) {
5860 + /* don't propogate CFG errors from this PROC function */
5861 + GT_0trace(debugMask, GT_7CLASS,
5862 + "Failed to get the DRV Object \n");
5863 + status = DSP_EFAIL;
5865 + /* Create the device object, and pass a handle to the WMD for
5866 + * storage. */
5867 + if (DSP_SUCCEEDED(status)) {
5868 + DBC_Assert(pDrvFxns);
5869 + MEM_AllocObject(pDevObject, struct DEV_OBJECT, SIGNATURE);
5870 + if (pDevObject) {
5871 + /* Fill out the rest of the Dev Object structure: */
5872 + pDevObject->hDevNode = hDevNode;
5873 + pDevObject->hModule = hModule;
5874 + pDevObject->hCodMgr = NULL;
5875 + pDevObject->hChnlMgr = NULL;
5876 + pDevObject->hDehMgr = NULL;
5877 + pDevObject->lockOwner = NULL;
5878 + pDevObject->uWordSize = pDspConfig->uWordSize;
5879 + pDevObject->hDrvObject = hDrvObject;
5880 + pDevObject->devType = DSP_UNIT;
5881 + /* Store this WMD's interface functions, based on its
5882 + * version. */
5883 + StoreInterfaceFxns(pDrvFxns, &pDevObject->intfFxns);
5884 + /* Call WMD_DEV_CREATE() to get the WMD's device
5885 + * context handle. */
5886 + status = (pDevObject->intfFxns.pfnDevCreate)
5887 + (&pDevObject->hWmdContext, pDevObject,
5888 + pHostConfig, pDspConfig);
5889 + /* Assert WMD_DEV_Create()'s ensure clause: */
5890 + DBC_Assert(DSP_FAILED(status) || (pDevObject->
5891 + hWmdContext != NULL));
5892 + } else {
5893 + GT_0trace(debugMask, GT_7CLASS,
5894 + "DEV_Create: Out Of Memory");
5895 + status = DSP_EMEMORY;
5898 + /* Attempt to create the COD manager for this device: */
5899 + if (DSP_SUCCEEDED(status))
5900 + status = InitCodMgr(pDevObject);
5902 + /* Attempt to create the channel manager for this device: */
5903 + if (DSP_SUCCEEDED(status)) {
5904 + mgrAttrs.cChannels = CHNL_MAXCHANNELS;
5905 + ioMgrAttrs.bIRQ = pHostConfig->bIRQRegisters;
5906 + ioMgrAttrs.fShared = (pHostConfig->bIRQAttrib & CFG_IRQSHARED);
5907 + ioMgrAttrs.uWordSize = pDspConfig->uWordSize;
5908 + mgrAttrs.uWordSize = pDspConfig->uWordSize;
5909 + uNumWindows = pHostConfig->wNumMemWindows;
5910 + if (uNumWindows) {
5911 + /* Assume last memory window is for CHNL */
5912 + ioMgrAttrs.dwSMBase = pHostConfig->dwMemBase[1] +
5913 + pHostConfig->dwOffsetForMonitor;
5914 + ioMgrAttrs.uSMLength = pHostConfig->dwMemLength[1] -
5915 + pHostConfig->dwOffsetForMonitor;
5916 + } else {
5917 + ioMgrAttrs.dwSMBase = 0;
5918 + ioMgrAttrs.uSMLength = 0;
5919 + GT_0trace(debugMask, GT_7CLASS,
5920 + "**There is no memory reserved for "
5921 + "shared structures**\n");
5923 + status = CHNL_Create(&pDevObject->hChnlMgr, pDevObject,
5924 + &mgrAttrs);
5925 + if (status == DSP_ENOTIMPL) {
5926 + /* It's OK for a device not to have a channel
5927 + * manager: */
5928 + status = DSP_SOK;
5930 + /* Create CMM mgr even if Msg Mgr not impl. */
5931 + status = CMM_Create(&pDevObject->hCmmMgr,
5932 + (struct DEV_OBJECT *)pDevObject, NULL);
5933 + if (DSP_FAILED(status)) {
5934 + GT_0trace(debugMask, GT_7CLASS,
5935 + "DEV_Create: Failed to Create SM "
5936 + "Manager\n");
5938 + /* Only create IO manager if we have a channel manager */
5939 + if (DSP_SUCCEEDED(status) && pDevObject->hChnlMgr) {
5940 + status = IO_Create(&pDevObject->hIOMgr, pDevObject,
5941 + &ioMgrAttrs);
5943 + /* Only create DEH manager if we have an IO manager */
5944 + if (DSP_SUCCEEDED(status)) {
5945 + /* Instantiate the DEH module */
5946 + status = (*pDevObject->intfFxns.pfnDehCreate)
5947 + (&pDevObject->hDehMgr, pDevObject);
5949 + /* Create DMM mgr . */
5950 + status = DMM_Create(&pDevObject->hDmmMgr,
5951 + (struct DEV_OBJECT *)pDevObject, NULL);
5952 + if (DSP_FAILED(status)) {
5953 + GT_0trace(debugMask, GT_7CLASS,
5954 + "DEV_Create: Failed to Create DMM "
5955 + "Manager\n");
5958 + /* Add the new DEV_Object to the global list: */
5959 + if (DSP_SUCCEEDED(status)) {
5960 + LST_InitElem(&pDevObject->link);
5961 + status = DRV_InsertDevObject(hDrvObject, pDevObject);
5963 + /* Create the Processor List */
5964 + if (DSP_SUCCEEDED(status)) {
5965 + pDevObject->procList = LST_Create();
5966 + if (!(pDevObject->procList)) {
5967 + status = DSP_EFAIL;
5968 + GT_0trace(debugMask, GT_7CLASS, "DEV_Create: "
5969 + "Failed to Create Proc List");
5972 + /* If all went well, return a handle to the dev object;
5973 + * else, cleanup and return NULL in the OUT parameter. */
5974 + if (DSP_SUCCEEDED(status)) {
5975 + *phDevObject = pDevObject;
5976 + GT_1trace(debugMask, GT_1CLASS,
5977 + "DEV_CreateDevice Succeeded \nDevObject "
5978 + "0x%x\n", pDevObject);
5979 + } else {
5980 + if (pDevObject && pDevObject->procList)
5981 + LST_Delete(pDevObject->procList);
5983 + if (pDevObject && pDevObject->hCodMgr)
5984 + COD_Delete(pDevObject->hCodMgr);
5986 + if (pDevObject && pDevObject->hDmmMgr)
5987 + DMM_Destroy(pDevObject->hDmmMgr);
5989 + if (pDevObject)
5990 + MEM_FreeObject(pDevObject);
5992 + *phDevObject = NULL;
5993 + GT_0trace(debugMask, GT_7CLASS, "DEV_CreateDevice Failed\n");
5995 + GT_1trace(debugMask, GT_1CLASS, "Exiting DEV_Create: DevObject 0x%x\n",
5996 + *phDevObject);
5997 + DBC_Ensure((DSP_SUCCEEDED(status) && IsValidHandle(*phDevObject)) ||
5998 + (DSP_FAILED(status) && !*phDevObject));
5999 + return status;
6003 + * ======== DEV_Create2 ========
6004 + * Purpose:
6005 + * After successful loading of the image from WCD_InitComplete2
6006 + * (PROC Auto_Start) or PROC_Load this fxn is called. This creates
6007 + * the Node Manager and updates the DEV Object.
6008 + */
6009 +DSP_STATUS CDECL DEV_Create2(struct DEV_OBJECT *hDevObject)
6011 + DSP_STATUS status = DSP_SOK;
6012 + struct DEV_OBJECT *pDevObject = hDevObject;
6014 + DBC_Require(cRefs > 0);
6015 + DBC_Require(IsValidHandle(hDevObject));
6017 + GT_1trace(debugMask, GT_ENTER,
6018 + "Entered DEV_Create2, hDevObject: 0x%x\n", hDevObject);
6019 + /* There can be only one Node Manager per DEV object */
6020 + DBC_Assert(!pDevObject->hNodeMgr);
6021 + status = NODE_CreateMgr(&pDevObject->hNodeMgr, hDevObject);
6022 + if (DSP_FAILED(status)) {
6023 + GT_1trace(debugMask, GT_7CLASS,
6024 + "DEV_Create2: NODE_CreateMgr failed, "
6025 + "0x%x!\n", status);
6026 + pDevObject->hNodeMgr = NULL;
6027 + GT_0trace(debugMask, GT_7CLASS, "DEV_Create2: Failed!!\n");
6029 + DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr != NULL)
6030 + || (DSP_FAILED(status) && pDevObject->hNodeMgr == NULL));
6031 + GT_2trace(debugMask, GT_ENTER,
6032 + "Exiting DEV_Create2, hNodeMgr: 0x%x, status:"
6033 + " 0x%x\n", pDevObject->hNodeMgr, status);
6034 + return status;
6038 + * ======== DEV_Destroy2 ========
6039 + * Purpose:
6040 + * Destroys the Node manager for this device.
6041 + */
6042 +DSP_STATUS CDECL DEV_Destroy2(struct DEV_OBJECT *hDevObject)
6044 + DSP_STATUS status = DSP_SOK;
6045 + struct DEV_OBJECT *pDevObject = hDevObject;
6047 + DBC_Require(cRefs > 0);
6048 + DBC_Require(IsValidHandle(hDevObject));
6050 + GT_1trace(debugMask, GT_ENTER,
6051 + "Entered DEV_Destroy2, hDevObject: 0x%x\n",
6052 + hDevObject);
6053 + if (pDevObject->hNodeMgr) {
6054 + if (DSP_FAILED(NODE_DeleteMgr(pDevObject->hNodeMgr)))
6055 + status = DSP_EFAIL;
6056 + else
6057 + pDevObject->hNodeMgr = NULL;
6060 + if (DSP_FAILED(status))
6061 + GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy2 failed!!\n");
6063 + DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr == NULL) ||
6064 + DSP_FAILED(status));
6065 + GT_2trace(debugMask, GT_ENTER,
6066 + "Exiting DEV_Destroy2, hNodeMgr: 0x%x, status"
6067 + " = 0x%x\n", pDevObject->hNodeMgr, status);
6068 + return status;
6072 + * ======== DEV_DestroyDevice ========
6073 + * Purpose:
6074 + * Destroys the channel manager for this device, if any, calls
6075 + * WMD_DEV_Destroy(), and then attempts to unload the WMD module.
6076 + */
6077 +DSP_STATUS DEV_DestroyDevice(struct DEV_OBJECT *hDevObject)
6079 + DSP_STATUS status = DSP_SOK;
6080 + struct DEV_OBJECT *pDevObject = hDevObject;
6082 + DBC_Require(cRefs > 0);
6084 + GT_1trace(debugMask, GT_ENTER, "Entered DEV_DestroyDevice, hDevObject: "
6085 + "0x%x\n", hDevObject);
6086 + if (IsValidHandle(hDevObject)) {
6087 + if (pDevObject->hCodMgr)
6088 + COD_Delete(pDevObject->hCodMgr);
6090 + if (pDevObject->hNodeMgr)
6091 + NODE_DeleteMgr(pDevObject->hNodeMgr);
6093 + /* Free the io, channel, and message managers for this board: */
6094 + if (pDevObject->hIOMgr) {
6095 + IO_Destroy(pDevObject->hIOMgr);
6096 + pDevObject->hIOMgr = NULL;
6098 + if (pDevObject->hChnlMgr) {
6099 + CHNL_Destroy(pDevObject->hChnlMgr);
6100 + pDevObject->hChnlMgr = NULL;
6102 + if (pDevObject->hMsgMgr)
6103 + MSG_Delete(pDevObject->hMsgMgr);
6105 + if (pDevObject->hDehMgr) {
6106 + /* Uninitialize DEH module. */
6107 + (*pDevObject->intfFxns.pfnDehDestroy)
6108 + (pDevObject->hDehMgr);
6110 + if (pDevObject->hCmmMgr)
6111 + CMM_Destroy(pDevObject->hCmmMgr, true);
6113 + if (pDevObject->hDmmMgr)
6114 + DMM_Destroy(pDevObject->hDmmMgr);
6116 + /* Call the driver's WMD_DEV_Destroy() function: */
6117 + /* Require of DevDestroy */
6118 + DBC_Assert(pDevObject->hWmdContext != NULL);
6119 + status = (*pDevObject->intfFxns.pfnDevDestroy)
6120 + (pDevObject->hWmdContext);
6121 + if (DSP_SUCCEEDED(status)) {
6122 + if (pDevObject->procList)
6123 + LST_Delete(pDevObject->procList);
6125 + /* Remove this DEV_Object from the global list: */
6126 + DRV_RemoveDevObject(pDevObject->hDrvObject, pDevObject);
6127 + /* Free The library * LDR_FreeModule
6128 + * (pDevObject->hModule);*/
6129 + /* Free this dev object: */
6130 + MEM_FreeObject(pDevObject);
6132 + } else {
6133 + GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy: Invlaid handle");
6134 + status = DSP_EHANDLE;
6136 + GT_1trace(debugMask, GT_ENTER, "Exit DEV_destroy: status 0x%x\n",
6137 + status);
6138 + return status;
6142 + * ======== DEV_GetChnlMgr ========
6143 + * Purpose:
6144 + * Retrieve the handle to the channel manager handle created for this
6145 + * device.
6146 + */
6147 +DSP_STATUS DEV_GetChnlMgr(struct DEV_OBJECT *hDevObject,
6148 + OUT struct CHNL_MGR **phMgr)
6150 + DSP_STATUS status = DSP_SOK;
6151 + struct DEV_OBJECT *pDevObject = hDevObject;
6153 + DBC_Require(cRefs > 0);
6154 + DBC_Require(phMgr != NULL);
6156 + GT_2trace(debugMask, GT_ENTER,
6157 + "Entered DEV_GetChnlMgr, hDevObject: 0x%x\n\t"
6158 + "\tphMgr: 0x%x\n", hDevObject, phMgr);
6159 + if (IsValidHandle(hDevObject)) {
6160 + *phMgr = pDevObject->hChnlMgr;
6161 + } else {
6162 + *phMgr = NULL;
6163 + status = DSP_EHANDLE;
6164 + GT_0trace(debugMask, GT_7CLASS,
6165 + "DEV_GetChnlMgr: Invalid handle");
6167 + GT_2trace(debugMask, GT_ENTER,
6168 + "Exit DEV_GetChnlMgr: status 0x%x\t\n hMgr: "
6169 + "0x%x\n", status, *phMgr);
6170 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
6171 + (*phMgr == NULL)));
6172 + return status;
6176 + * ======== DEV_GetCmmMgr ========
6177 + * Purpose:
6178 + * Retrieve the handle to the shared memory manager created for this
6179 + * device.
6180 + */
6181 +DSP_STATUS DEV_GetCmmMgr(struct DEV_OBJECT *hDevObject,
6182 + OUT struct CMM_OBJECT **phMgr)
6184 + DSP_STATUS status = DSP_SOK;
6185 + struct DEV_OBJECT *pDevObject = hDevObject;
6187 + DBC_Require(cRefs > 0);
6188 + DBC_Require(phMgr != NULL);
6189 + GT_2trace(debugMask, GT_ENTER,
6190 + "Entered DEV_GetCmmMgr, hDevObject: 0x%x\n\t"
6191 + "\tphMgr: 0x%x\n", hDevObject, phMgr);
6192 + if (IsValidHandle(hDevObject)) {
6193 + *phMgr = pDevObject->hCmmMgr;
6194 + } else {
6195 + *phMgr = NULL;
6196 + status = DSP_EHANDLE;
6197 + GT_0trace(debugMask, GT_7CLASS,
6198 + "DEV_GetCmmMgr: Invalid handle");
6200 + GT_2trace(debugMask, GT_ENTER,
6201 + "Exit DEV_GetCmmMgr: status 0x%x\t\nhMgr: "
6202 + "0x%x\n", status, *phMgr);
6203 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
6204 + (*phMgr == NULL)));
6205 + return status;
6209 + * ======== DEV_GetDmmMgr ========
6210 + * Purpose:
6211 + * Retrieve the handle to the dynamic memory manager created for this
6212 + * device.
6213 + */
6214 +DSP_STATUS DEV_GetDmmMgr(struct DEV_OBJECT *hDevObject,
6215 + OUT struct DMM_OBJECT **phMgr)
6217 + DSP_STATUS status = DSP_SOK;
6218 + struct DEV_OBJECT *pDevObject = hDevObject;
6220 + DBC_Require(cRefs > 0);
6221 + DBC_Require(phMgr != NULL);
6223 + GT_2trace(debugMask, GT_ENTER, "Entered DEV_GetDmmMgr, hDevObject: "
6224 + "0x%x\n\t\tphMgr: 0x%x\n", hDevObject, phMgr);
6225 + if (IsValidHandle(hDevObject)) {
6226 + *phMgr = pDevObject->hDmmMgr;
6227 + } else {
6228 + *phMgr = NULL;
6229 + status = DSP_EHANDLE;
6230 + GT_0trace(debugMask, GT_7CLASS,
6231 + "DEV_GetDmmMgr: Invalid handle");
6233 + GT_2trace(debugMask, GT_ENTER,
6234 + "Exit DEV_GetDmmMgr: status 0x%x\t\n hMgr: "
6235 + "0x%x\n", status, *phMgr);
6236 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
6237 + (*phMgr == NULL)));
6238 + return status;
6242 + * ======== DEV_GetCodMgr ========
6243 + * Purpose:
6244 + * Retrieve the COD manager create for this device.
6245 + */
6246 +DSP_STATUS DEV_GetCodMgr(struct DEV_OBJECT *hDevObject,
6247 + OUT struct COD_MANAGER **phCodMgr)
6249 + DSP_STATUS status = DSP_SOK;
6250 + struct DEV_OBJECT *pDevObject = hDevObject;
6252 + DBC_Require(cRefs > 0);
6253 + DBC_Require(phCodMgr != NULL);
6255 + GT_2trace(debugMask, GT_ENTER,
6256 + "Entered DEV_GetCodMgr, hDevObject: 0x%x\n\t\t"
6257 + "phCodMgr: 0x%x\n", hDevObject, phCodMgr);
6258 + if (IsValidHandle(hDevObject)) {
6259 + *phCodMgr = pDevObject->hCodMgr;
6260 + } else {
6261 + *phCodMgr = NULL;
6262 + status = DSP_EHANDLE;
6263 + GT_1trace(debugMask, GT_7CLASS,
6264 + "DEV_GetCodMgr, invalid handle: 0x%x\n",
6265 + hDevObject);
6267 + GT_2trace(debugMask, GT_ENTER,
6268 + "Exit DEV_GetCodMgr: status 0x%x\t\n hCodMgr:"
6269 + " 0x%x\n", status, *phCodMgr);
6270 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phCodMgr != NULL) &&
6271 + (*phCodMgr == NULL)));
6272 + return status;
6276 + * ========= DEV_GetDehMgr ========
6277 + */
6278 +DSP_STATUS DEV_GetDehMgr(struct DEV_OBJECT *hDevObject,
6279 + OUT struct DEH_MGR **phDehMgr)
6281 + DSP_STATUS status = DSP_SOK;
6283 + DBC_Require(cRefs > 0);
6284 + DBC_Require(phDehMgr != NULL);
6285 + DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
6286 + if (IsValidHandle(hDevObject)) {
6287 + *phDehMgr = hDevObject->hDehMgr;
6288 + } else {
6289 + *phDehMgr = NULL;
6290 + status = DSP_EHANDLE;
6291 + GT_0trace(debugMask, GT_7CLASS,
6292 + "DEV_GetDehMgr: Invalid handle");
6294 + return status;
6298 + * ======== DEV_GetDevNode ========
6299 + * Purpose:
6300 + * Retrieve the platform specific device ID for this device.
6301 + */
6302 +DSP_STATUS DEV_GetDevNode(struct DEV_OBJECT *hDevObject,
6303 + OUT struct CFG_DEVNODE **phDevNode)
6305 + DSP_STATUS status = DSP_SOK;
6306 + struct DEV_OBJECT *pDevObject = hDevObject;
6308 + DBC_Require(cRefs > 0);
6309 + DBC_Require(phDevNode != NULL);
6311 + GT_2trace(debugMask, GT_ENTER,
6312 + "Entered DEV_GetDevNode, hDevObject: 0x%x\n\t"
6313 + "\tphDevNode: 0x%x\n", hDevObject, phDevNode);
6314 + if (IsValidHandle(hDevObject)) {
6315 + *phDevNode = pDevObject->hDevNode;
6316 + } else {
6317 + *phDevNode = NULL;
6318 + status = DSP_EHANDLE;
6319 + GT_0trace(debugMask, GT_7CLASS,
6320 + "DEV_GetDevNode: Invalid handle");
6322 + GT_2trace(debugMask, GT_ENTER,
6323 + "Exit DEV_GetDevNode: status 0x%x\t\nhDevNode:"
6324 + "0x%x\n", status, *phDevNode);
6325 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phDevNode != NULL) &&
6326 + (*phDevNode == NULL)));
6327 + return status;
6331 + * ======== DEV_GetFirst ========
6332 + * Purpose:
6333 + * Retrieve the first Device Object handle from an internal linked list
6334 + * DEV_OBJECTs maintained by DEV.
6335 + */
6336 +struct DEV_OBJECT *DEV_GetFirst(void)
6338 + struct DEV_OBJECT *pDevObject = NULL;
6340 + pDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject();
6342 + DBC_Ensure((pDevObject == NULL) || IsValidHandle(pDevObject));
6344 + return pDevObject;
6348 + * ======== DEV_GetIntfFxns ========
6349 + * Purpose:
6350 + * Retrieve the WMD interface function structure for the loaded WMD.
6351 + * ppIntfFxns != NULL.
6352 + */
6353 +DSP_STATUS DEV_GetIntfFxns(struct DEV_OBJECT *hDevObject,
6354 + OUT struct WMD_DRV_INTERFACE **ppIntfFxns)
6356 + DSP_STATUS status = DSP_SOK;
6357 + struct DEV_OBJECT *pDevObject = hDevObject;
6359 + DBC_Require(cRefs > 0);
6360 + DBC_Require(ppIntfFxns != NULL);
6362 + GT_2trace(debugMask, GT_ENTER,
6363 + "Entered DEV_GetIntfFxns, hDevObject: 0x%x\n\t"
6364 + "\tppIntfFxns: 0x%x\n", hDevObject, ppIntfFxns);
6365 + if (IsValidHandle(hDevObject)) {
6366 + *ppIntfFxns = &pDevObject->intfFxns;
6367 + } else {
6368 + *ppIntfFxns = NULL;
6369 + status = DSP_EHANDLE;
6370 + GT_0trace(debugMask, GT_7CLASS,
6371 + "DEV_GetIntDxns: Invalid handle");
6373 + GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetIntFxns: status 0x%x\t\n"
6374 + "ppIntFxns: 0x%x\n", status, *ppIntfFxns);
6375 + DBC_Ensure(DSP_SUCCEEDED(status) || ((ppIntfFxns != NULL) &&
6376 + (*ppIntfFxns == NULL)));
6377 + return status;
6381 + * ========= DEV_GetIOMgr ========
6382 + */
6383 +DSP_STATUS DEV_GetIOMgr(struct DEV_OBJECT *hDevObject,
6384 + OUT struct IO_MGR **phIOMgr)
6386 + DSP_STATUS status = DSP_SOK;
6388 + DBC_Require(cRefs > 0);
6389 + DBC_Require(phIOMgr != NULL);
6390 + DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
6392 + if (IsValidHandle(hDevObject)) {
6393 + *phIOMgr = hDevObject->hIOMgr;
6394 + } else {
6395 + *phIOMgr = NULL;
6396 + status = DSP_EHANDLE;
6397 + GT_0trace(debugMask, GT_7CLASS, "DEV_GetIOMgr: Invalid handle");
6400 + return status;
6404 + * ======== DEV_GetNext ========
6405 + * Purpose:
6406 + * Retrieve the next Device Object handle from an internal linked list
6407 + * of DEV_OBJECTs maintained by DEV, after having previously called
6408 + * DEV_GetFirst() and zero or more DEV_GetNext
6409 + */
6410 +struct DEV_OBJECT *DEV_GetNext(struct DEV_OBJECT *hDevObject)
6412 + struct DEV_OBJECT *pNextDevObject = NULL;
6414 + if (IsValidHandle(hDevObject)) {
6415 + pNextDevObject = (struct DEV_OBJECT *)
6416 + DRV_GetNextDevObject((u32)hDevObject);
6418 + DBC_Ensure((pNextDevObject == NULL) || IsValidHandle(pNextDevObject));
6419 + return pNextDevObject;
6423 + * ========= DEV_GetMsgMgr ========
6424 + */
6425 +void CDECL DEV_GetMsgMgr(struct DEV_OBJECT *hDevObject,
6426 + OUT struct MSG_MGR **phMsgMgr)
6428 + DBC_Require(cRefs > 0);
6429 + DBC_Require(phMsgMgr != NULL);
6430 + DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
6432 + *phMsgMgr = hDevObject->hMsgMgr;
6436 + * ======== DEV_GetNodeManager ========
6437 + * Purpose:
6438 + * Retrieve the Node Manager Handle
6439 + */
6440 +DSP_STATUS CDECL DEV_GetNodeManager(struct DEV_OBJECT *hDevObject,
6441 + OUT struct NODE_MGR **phNodeMgr)
6443 + DSP_STATUS status = DSP_SOK;
6444 + struct DEV_OBJECT *pDevObject = hDevObject;
6446 + DBC_Require(cRefs > 0);
6447 + DBC_Require(phNodeMgr != NULL);
6449 + GT_2trace(debugMask, GT_ENTER,
6450 + "Entered DEV_GetNodeManager, hDevObject: 0x%x"
6451 + "\n\t\tphNodeMgr: 0x%x\n", hDevObject, phNodeMgr);
6452 + if (IsValidHandle(hDevObject)) {
6453 + *phNodeMgr = pDevObject->hNodeMgr;
6454 + } else {
6455 + *phNodeMgr = NULL;
6456 + status = DSP_EHANDLE;
6457 + GT_1trace(debugMask, GT_7CLASS,
6458 + "DEV_GetNodeManager, invalid handle: 0x"
6459 + "%x\n", hDevObject);
6461 + GT_2trace(debugMask, GT_ENTER,
6462 + "Exit DEV_GetNodeManager: status 0x%x\t\nhMgr:"
6463 + " 0x%x\n", status, *phNodeMgr);
6464 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phNodeMgr != NULL) &&
6465 + (*phNodeMgr == NULL)));
6466 + return status;
6470 + * ======== DEV_GetSymbol ========
6471 + */
6472 +DSP_STATUS CDECL DEV_GetSymbol(struct DEV_OBJECT *hDevObject,
6473 + IN CONST char *pstrSym, OUT u32 *pulValue)
6475 + DSP_STATUS status = DSP_SOK;
6476 + struct COD_MANAGER *hCodMgr;
6478 + DBC_Require(cRefs > 0);
6479 + DBC_Require(pstrSym != NULL && pulValue != NULL);
6481 + GT_3trace(debugMask, GT_ENTER,
6482 + "Entered DEV_GetSymbol, hDevObject: 0x%x\n\t\t"
6483 + "pstrSym: 0x%x\n\t\tpulValue: 0x%x\n", hDevObject, pstrSym,
6484 + pulValue);
6485 + if (IsValidHandle(hDevObject)) {
6486 + status = DEV_GetCodMgr(hDevObject, &hCodMgr);
6487 + if (DSP_SUCCEEDED(status)) {
6488 + DBC_Assert(hCodMgr != NULL);
6489 + status = COD_GetSymValue(hCodMgr, (char *)pstrSym, pulValue);
6491 + } else {
6492 + status = DSP_EHANDLE;
6493 + GT_0trace(debugMask, GT_7CLASS,
6494 + "DEV_GetSymbol: Invalid handle");
6496 + GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetSymbol: status 0x%x\t\n"
6497 + "hWmdContext: 0x%x\n", status, *pulValue);
6498 + return status;
6502 + * ======== DEV_GetWMDContext ========
6503 + * Purpose:
6504 + * Retrieve the WMD Context handle, as returned by the WMD_Create fxn.
6505 + */
6506 +DSP_STATUS DEV_GetWMDContext(struct DEV_OBJECT *hDevObject,
6507 + OUT struct WMD_DEV_CONTEXT **phWmdContext)
6509 + DSP_STATUS status = DSP_SOK;
6510 + struct DEV_OBJECT *pDevObject = hDevObject;
6512 + DBC_Require(cRefs > 0);
6513 + DBC_Require(phWmdContext != NULL);
6514 + GT_2trace(debugMask, GT_ENTER,
6515 + "Entered DEV_GetWMDContext, hDevObject: 0x%x\n"
6516 + "\t\tphWmdContext: 0x%x\n", hDevObject, phWmdContext);
6517 + if (IsValidHandle(hDevObject)) {
6518 + *phWmdContext = pDevObject->hWmdContext;
6519 + } else {
6520 + *phWmdContext = NULL;
6521 + status = DSP_EHANDLE;
6522 + GT_0trace(debugMask, GT_7CLASS,
6523 + "DEV_GetWMDContext: Invalid handle");
6526 + GT_2trace(debugMask, GT_ENTER,
6527 + "Exit DEV_GetWMDContext: status 0x%x\t\n"
6528 + "hWmdContext: 0x%x\n", status, *phWmdContext);
6529 + DBC_Ensure(DSP_SUCCEEDED(status) || ((phWmdContext != NULL) &&
6530 + (*phWmdContext == NULL)));
6531 + return status;
6535 + * ======== DEV_Exit ========
6536 + * Purpose:
6537 + * Decrement reference count, and free resources when reference count is
6538 + * 0.
6539 + */
6540 +void CDECL DEV_Exit(void)
6542 + DBC_Require(cRefs > 0);
6544 + cRefs--;
6546 + if (cRefs == 0) {
6547 + CMM_Exit();
6548 + DMM_Exit();
6551 + GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Exit, ref count: 0x%x\n",
6552 + cRefs);
6554 + DBC_Ensure(cRefs >= 0);
6558 + * ======== DEV_Init ========
6559 + * Purpose:
6560 + * Initialize DEV's private state, keeping a reference count on each call.
6561 + */
6562 +bool CDECL DEV_Init(void)
6564 + bool fCmm, fDmm, fRetval = true;
6566 + DBC_Require(cRefs >= 0);
6568 + if (cRefs == 0) {
6569 + /* Set the Trace mask */
6570 + DBC_Assert(!debugMask.flags);
6571 + GT_create(&debugMask, "DV"); /* "DV" for DeVice */
6572 + fCmm = CMM_Init();
6573 + fDmm = DMM_Init();
6575 + fRetval = fCmm && fDmm;
6577 + if (!fRetval) {
6578 + if (fCmm)
6579 + CMM_Exit();
6582 + if (fDmm)
6583 + DMM_Exit();
6588 + if (fRetval)
6589 + cRefs++;
6592 + GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Init, ref count: 0x%x\n",
6593 + cRefs);
6595 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
6597 + return fRetval;
6601 + * ======== DEV_NotifyClients ========
6602 + * Purpose:
6603 + * Notify all clients of this device of a change in device status.
6604 + */
6605 +DSP_STATUS DEV_NotifyClients(struct DEV_OBJECT *hDevObject, u32 ulStatus)
6607 + DSP_STATUS status = DSP_SOK;
6609 + struct DEV_OBJECT *pDevObject = hDevObject;
6610 + DSP_HPROCESSOR hProcObject;
6612 + GT_2trace(debugMask, GT_ENTER,
6613 + "Entered DEV_NotifyClients, hDevObject: 0x%x\n"
6614 + "\t\tulStatus: 0x%x\n", hDevObject, ulStatus);
6615 + for (hProcObject = (DSP_HPROCESSOR)LST_First(pDevObject->procList);
6616 + hProcObject != NULL;
6617 + hProcObject = (DSP_HPROCESSOR)LST_Next(pDevObject->procList,
6618 + (struct LST_ELEM *)hProcObject))
6619 + PROC_NotifyClients(hProcObject, (u32) ulStatus);
6621 + return status;
6625 + * ======== DEV_RemoveDevice ========
6626 + */
6627 +DSP_STATUS CDECL DEV_RemoveDevice(struct CFG_DEVNODE *hDevNode)
6629 + struct DEV_OBJECT *hDevObject; /* handle to device object */
6630 + DSP_STATUS status = DSP_SOK;
6631 + struct DEV_OBJECT *pDevObject;
6633 + GT_1trace(debugMask, GT_ENTER,
6634 + "Entered DEV_RemoveDevice, hDevNode: 0x%x\n", hDevNode);
6635 + /* Retrieve the device object handle originaly stored with
6636 + * the DevNode: */
6637 + status = CFG_GetDevObject(hDevNode, (u32 *)&hDevObject);
6638 + if (DSP_SUCCEEDED(status)) {
6639 + /* Remove the Processor List */
6640 + pDevObject = (struct DEV_OBJECT *)hDevObject;
6641 + /* Destroy the device object. */
6642 + status = DEV_DestroyDevice(hDevObject);
6643 + if (DSP_SUCCEEDED(status)) {
6644 + /* Null out the handle stored with the DevNode. */
6645 + GT_0trace(debugMask, GT_1CLASS,
6646 + "DEV_RemoveDevice, success");
6649 + GT_1trace(debugMask, GT_ENTER, "Exit DEV_RemoveDevice, status: 0x%x\n",
6650 + status);
6651 + return status;
6655 + * ======== DEV_SetChnlMgr ========
6656 + * Purpose:
6657 + * Set the channel manager for this device.
6658 + */
6659 +DSP_STATUS DEV_SetChnlMgr(struct DEV_OBJECT *hDevObject, struct CHNL_MGR *hMgr)
6661 + DSP_STATUS status = DSP_SOK;
6662 + struct DEV_OBJECT *pDevObject = hDevObject;
6664 + DBC_Require(cRefs > 0);
6666 + GT_2trace(debugMask, GT_ENTER,
6667 + "Entered DEV_SetChnlMgr, hDevObject: 0x%x\n\t"
6668 + "\thMgr:0x%x\n", hDevObject, hMgr);
6669 + if (IsValidHandle(hDevObject)) {
6670 + pDevObject->hChnlMgr = hMgr;
6671 + } else {
6672 + status = DSP_EHANDLE;
6673 + GT_0trace(debugMask, GT_7CLASS,
6674 + "DEV_SetChnlMgr, Invalid handle\n");
6676 + DBC_Ensure(DSP_FAILED(status) || (pDevObject->hChnlMgr == hMgr));
6677 + return status;
6681 + * ======== DEV_SetMsgMgr ========
6682 + * Purpose:
6683 + * Set the message manager for this device.
6684 + */
6685 +void DEV_SetMsgMgr(struct DEV_OBJECT *hDevObject, struct MSG_MGR *hMgr)
6687 + DBC_Require(cRefs > 0);
6688 + DBC_Require(IsValidHandle(hDevObject));
6689 + GT_2trace(debugMask, GT_ENTER,
6690 + "Entered DEV_SetMsgMgr, hDevObject: 0x%x\n\t\t"
6691 + "hMgr: 0x%x\n", hDevObject, hMgr);
6692 + hDevObject->hMsgMgr = hMgr;
6696 + * ======== DEV_StartDevice ========
6697 + * Purpose:
6698 + * Initializes the new device with the BRIDGE environment.
6699 + */
6700 +DSP_STATUS CDECL DEV_StartDevice(struct CFG_DEVNODE *hDevNode)
6702 + struct DEV_OBJECT *hDevObject = NULL; /* handle to 'Bridge Device */
6703 + struct CFG_HOSTRES hostRes; /* resources struct. */
6704 + struct CFG_DSPRES dspRes; /* DSP resources struct */
6705 + char szWMDFileName[CFG_MAXSEARCHPATHLEN] = "UMA"; /* wmd filename */
6706 + DSP_STATUS status;
6707 + struct MGR_OBJECT *hMgrObject = NULL;
6709 + DBC_Require(cRefs > 0);
6711 + GT_1trace(debugMask, GT_ENTER,
6712 + "Entered DEV_StartDevice, hDevObject: 0x%x\n", hDevNode);
6713 + status = CFG_GetHostResources(hDevNode, &hostRes);
6714 + if (DSP_SUCCEEDED(status)) {
6715 + /* Get DSP resources of device from Registry: */
6716 + status = CFG_GetDSPResources(hDevNode, &dspRes);
6717 + if (DSP_FAILED(status)) {
6718 + GT_1trace(debugMask, GT_7CLASS,
6719 + "Failed to get WMD DSP resources"
6720 + " from registry: 0x%x ", status);
6722 + } else {
6723 + GT_1trace(debugMask, GT_7CLASS,
6724 + "Failed to get WMD Host resources "
6725 + "from registry: 0x%x ", status);
6727 + if (DSP_SUCCEEDED(status)) {
6728 + /* Given all resources, create a device object. */
6729 + status = DEV_CreateDevice(&hDevObject, szWMDFileName, &hostRes,
6730 + &dspRes, hDevNode);
6731 + if (DSP_SUCCEEDED(status)) {
6732 + /* Store away the hDevObject with the DEVNODE */
6733 + status = CFG_SetDevObject(hDevNode, (u32)hDevObject);
6734 + if (DSP_FAILED(status)) {
6735 + /* Clean up */
6736 + GT_1trace(debugMask, GT_7CLASS,
6737 + "Failed to set DevObject in the "
6738 + "Registry: 0x%x", status);
6739 + DEV_DestroyDevice(hDevObject);
6740 + hDevObject = NULL;
6742 + } else {
6743 + GT_1trace(debugMask, GT_7CLASS,
6744 + "Failed to Create Device: 0x%x",
6745 + status);
6748 + if (DSP_SUCCEEDED(status)) {
6749 + /* Create the Manager Object */
6750 + status = MGR_Create(&hMgrObject, hDevNode);
6752 + if (DSP_FAILED(status)) {
6753 + GT_1trace(debugMask, GT_7CLASS, "Failed to MGR object: 0x%x",
6754 + status);
6755 + status = DSP_EFAIL;
6757 + if (DSP_FAILED(status)) {
6758 + if (hDevObject)
6759 + DEV_DestroyDevice(hDevObject);
6761 + /* Ensure the device extension is NULL */
6762 + CFG_SetDevObject(hDevNode, 0L);
6764 + GT_1trace(debugMask, GT_ENTER, "Exiting DEV_StartDevice status 0x%x\n",
6765 + status);
6766 + return status;
6770 + * ======== FxnNotImplemented ========
6771 + * Purpose:
6772 + * Takes the place of a WMD Null Function.
6773 + * Parameters:
6774 + * Multiple, optional.
6775 + * Returns:
6776 + * DSP_ENOTIMPL: Always.
6777 + */
6778 +static DSP_STATUS FxnNotImplemented(int arg, ...)
6780 + DBG_Trace(DBG_LEVEL1,
6781 + "WARNING: Calling a non-implemented WMD function.\n");
6783 + return DSP_ENOTIMPL;
6787 + * ======== IsValidHandle ========
6788 + * Purpose:
6789 + * Validate the device object handle.
6790 + * Parameters:
6791 + * hDevObject: Handle to device object created with
6792 + * DEV_CreateDevice().
6793 + * Returns:
6794 + * true if handle is valid; false otherwise.
6795 + * Requires:
6796 + * Ensures:
6797 + */
6798 +static bool IsValidHandle(struct DEV_OBJECT *hObj)
6800 + bool retVal;
6802 + retVal = (hObj != NULL) && (hObj->dwSignature == SIGNATURE);
6804 + return retVal;
6808 + * ======== InitCodMgr ========
6809 + * Purpose:
6810 + * Create a COD manager for this device.
6811 + * Parameters:
6812 + * pDevObject: Pointer to device object created with
6813 + * DEV_CreateDevice()
6814 + * Returns:
6815 + * DSP_SOK: Success.
6816 + * DSP_EHANDLE: Invalid hDevObject.
6817 + * Requires:
6818 + * Should only be called once by DEV_CreateDevice() for a given DevObject.
6819 + * Ensures:
6820 + */
6821 +static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject)
6823 + DSP_STATUS status = DSP_SOK;
6824 + char *szDummyFile = "dummy";
6826 + DBC_Require(cRefs > 0);
6827 + DBC_Require(!IsValidHandle(pDevObject) ||
6828 + (pDevObject->hCodMgr == NULL));
6829 + GT_1trace(debugMask, GT_ENTER, "Entering InitCodMgr pDevObject: 0x%x",
6830 + pDevObject);
6831 + status = COD_Create(&pDevObject->hCodMgr, szDummyFile, NULL);
6832 + GT_1trace(debugMask, GT_ENTER, "Exiting InitCodMgr status 0x%x\n ",
6833 + status);
6834 + return status;
6838 + * ======== DEV_InsertProcObject ========
6839 + * Purpose:
6840 + * Insert a ProcObject into the list maintained by DEV.
6841 + * Parameters:
6842 + * pProcObject: Ptr to ProcObject to insert.
6843 + * pDevObject: Ptr to Dev Object where the list is.
6844 + * pbAlreadyAttached: Ptr to return the bool
6845 + * Returns:
6846 + * DSP_SOK: If successful.
6847 + * Requires:
6848 + * List Exists
6849 + * hDevObject is Valid handle
6850 + * DEV Initialized
6851 + * pbAlreadyAttached != NULL
6852 + * hProcObject != 0
6853 + * Ensures:
6854 + * DSP_SOK and List is not Empty.
6855 + */
6856 +DSP_STATUS CDECL DEV_InsertProcObject(struct DEV_OBJECT *hDevObject,
6857 + u32 hProcObject,
6858 + OUT bool *pbAlreadyAttached)
6860 + DSP_STATUS status = DSP_SOK;
6861 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject;
6863 + GT_2trace(debugMask, GT_ENTER,
6864 + "Entering DEV_InsetProcObject pProcObject 0x%x"
6865 + "pDevObject 0x%x\n", hProcObject, hDevObject);
6866 + DBC_Require(cRefs > 0);
6867 + DBC_Require(IsValidHandle(pDevObject));
6868 + DBC_Require(hProcObject != 0);
6869 + DBC_Require(pDevObject->procList != NULL);
6870 + DBC_Require(pbAlreadyAttached != NULL);
6871 + if (!LST_IsEmpty(pDevObject->procList))
6872 + *pbAlreadyAttached = true;
6874 + /* Add DevObject to tail. */
6875 + LST_PutTail(pDevObject->procList, (struct LST_ELEM *)hProcObject);
6877 + GT_1trace(debugMask, GT_ENTER,
6878 + "Exiting DEV_InsetProcObject status 0x%x\n", status);
6879 + DBC_Ensure(DSP_SUCCEEDED(status) && !LST_IsEmpty(pDevObject->procList));
6881 + return status;
6885 + * ======== DEV_RemoveProcObject ========
6886 + * Purpose:
6887 + * Search for and remove a Proc object from the given list maintained
6888 + * by the DEV
6889 + * Parameters:
6890 + * pProcObject: Ptr to ProcObject to insert.
6891 + * pDevObject Ptr to Dev Object where the list is.
6892 + * Returns:
6893 + * DSP_SOK: If successful.
6894 + * Requires:
6895 + * List exists and is not empty
6896 + * hProcObject != 0
6897 + * hDevObject is a valid Dev handle.
6898 + * Ensures:
6899 + * Details:
6900 + * List will be deleted when the DEV is destroyed.
6901 + */
6902 +DSP_STATUS CDECL DEV_RemoveProcObject(struct DEV_OBJECT *hDevObject,
6903 + u32 hProcObject)
6905 + DSP_STATUS status = DSP_EFAIL;
6906 + struct LST_ELEM *pCurElem;
6907 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject;
6909 + DBC_Require(IsValidHandle(pDevObject));
6910 + DBC_Require(hProcObject != 0);
6911 + DBC_Require(pDevObject->procList != NULL);
6912 + DBC_Require(!LST_IsEmpty(pDevObject->procList));
6914 + GT_1trace(debugMask, GT_ENTER,
6915 + "Entering DEV_RemoveProcObject hDevObject "
6916 + "0x%x\n", hDevObject);
6917 + /* Search list for pDevObject: */
6918 + for (pCurElem = LST_First(pDevObject->procList); pCurElem != NULL;
6919 + pCurElem = LST_Next(pDevObject->procList, pCurElem)) {
6920 + /* If found, remove it. */
6921 + if ((u32)pCurElem == hProcObject) {
6922 + LST_RemoveElem(pDevObject->procList, pCurElem);
6923 + status = DSP_SOK;
6924 + break;
6927 + GT_1trace(debugMask, GT_ENTER, "DEV_RemoveProcObject returning 0x%x\n",
6928 + status);
6929 + return status;
6932 +DSP_STATUS CDECL DEV_GetDevType(struct DEV_OBJECT *hdevObject, u32 *devType)
6934 + DSP_STATUS status = DSP_SOK;
6935 + struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hdevObject;
6937 + *devType = pDevObject->devType;
6939 + return status;
6943 + * ======== StoreInterfaceFxns ========
6944 + * Purpose:
6945 + * Copy the WMD's interface functions into the device object,
6946 + * ensuring that FxnNotImplemented() is set for:
6948 + * 1. All WMD function pointers which are NULL; and
6949 + * 2. All function slots in the struct DEV_OBJECT structure which have no
6950 + * corresponding slots in the the WMD's interface, because the WMD
6951 + * is of an *older* version.
6952 + * Parameters:
6953 + * pIntfFxns: Interface Fxn Structure of the WCD's Dev Object.
6954 + * pDrvFxns: Interface Fxns offered by the WMD during DEV_Create().
6955 + * Returns:
6956 + * Requires:
6957 + * Input pointers are valid.
6958 + * WMD is *not* written for a newer WCD.
6959 + * Ensures:
6960 + * All function pointers in the dev object's Fxn interface are not NULL.
6961 + */
6962 +static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns,
6963 + OUT struct WMD_DRV_INTERFACE *pIntfFxns)
6965 + u32 dwWMDVersion;
6967 + /* Local helper macro: */
6968 +#define StoreFxn(cast, pfn) \
6969 + (pIntfFxns->pfn = ((pDrvFxns->pfn != NULL) ? pDrvFxns->pfn : \
6970 + (cast)FxnNotImplemented))
6972 + DBC_Require(pIntfFxns != NULL);
6973 + DBC_Require(pDrvFxns != NULL);
6974 + DBC_Require(MAKEVERSION(pDrvFxns->dwWCDMajorVersion,
6975 + pDrvFxns->dwWCDMinorVersion) <= WCDVERSION);
6976 + dwWMDVersion = MAKEVERSION(pDrvFxns->dwWCDMajorVersion,
6977 + pDrvFxns->dwWCDMinorVersion);
6978 + pIntfFxns->dwWCDMajorVersion = pDrvFxns->dwWCDMajorVersion;
6979 + pIntfFxns->dwWCDMinorVersion = pDrvFxns->dwWCDMinorVersion;
6980 + /* Install functions up to WCD version .80 (first alpha): */
6981 + if (dwWMDVersion > 0) {
6982 + StoreFxn(WMD_DEV_CREATE, pfnDevCreate);
6983 + StoreFxn(WMD_DEV_DESTROY, pfnDevDestroy);
6984 + StoreFxn(WMD_DEV_CTRL, pfnDevCntrl);
6985 + StoreFxn(WMD_BRD_MONITOR, pfnBrdMonitor);
6986 + StoreFxn(WMD_BRD_START, pfnBrdStart);
6987 + StoreFxn(WMD_BRD_STOP, pfnBrdStop);
6988 + StoreFxn(WMD_BRD_STATUS, pfnBrdStatus);
6989 + StoreFxn(WMD_BRD_READ, pfnBrdRead);
6990 + StoreFxn(WMD_BRD_WRITE, pfnBrdWrite);
6991 + StoreFxn(WMD_BRD_SETSTATE, pfnBrdSetState);
6992 + StoreFxn(WMD_BRD_MEMCOPY, pfnBrdMemCopy);
6993 + StoreFxn(WMD_BRD_MEMWRITE, pfnBrdMemWrite);
6994 + StoreFxn(WMD_BRD_MEMMAP, pfnBrdMemMap);
6995 + StoreFxn(WMD_BRD_MEMUNMAP, pfnBrdMemUnMap);
6996 + StoreFxn(WMD_CHNL_CREATE, pfnChnlCreate);
6997 + StoreFxn(WMD_CHNL_DESTROY, pfnChnlDestroy);
6998 + StoreFxn(WMD_CHNL_OPEN, pfnChnlOpen);
6999 + StoreFxn(WMD_CHNL_CLOSE, pfnChnlClose);
7000 + StoreFxn(WMD_CHNL_ADDIOREQ, pfnChnlAddIOReq);
7001 + StoreFxn(WMD_CHNL_GETIOC, pfnChnlGetIOC);
7002 + StoreFxn(WMD_CHNL_CANCELIO, pfnChnlCancelIO);
7003 + StoreFxn(WMD_CHNL_FLUSHIO, pfnChnlFlushIO);
7004 + StoreFxn(WMD_CHNL_GETINFO, pfnChnlGetInfo);
7005 + StoreFxn(WMD_CHNL_GETMGRINFO, pfnChnlGetMgrInfo);
7006 + StoreFxn(WMD_CHNL_IDLE, pfnChnlIdle);
7007 + StoreFxn(WMD_CHNL_REGISTERNOTIFY, pfnChnlRegisterNotify);
7008 + StoreFxn(WMD_DEH_CREATE, pfnDehCreate);
7009 + StoreFxn(WMD_DEH_DESTROY, pfnDehDestroy);
7010 + StoreFxn(WMD_DEH_NOTIFY, pfnDehNotify);
7011 + StoreFxn(WMD_DEH_REGISTERNOTIFY, pfnDehRegisterNotify);
7012 + StoreFxn(WMD_DEH_GETINFO, pfnDehGetInfo);
7013 + StoreFxn(WMD_IO_CREATE, pfnIOCreate);
7014 + StoreFxn(WMD_IO_DESTROY, pfnIODestroy);
7015 + StoreFxn(WMD_IO_ONLOADED, pfnIOOnLoaded);
7016 + StoreFxn(WMD_IO_GETPROCLOAD, pfnIOGetProcLoad);
7017 + StoreFxn(WMD_MSG_CREATE, pfnMsgCreate);
7018 + StoreFxn(WMD_MSG_CREATEQUEUE, pfnMsgCreateQueue);
7019 + StoreFxn(WMD_MSG_DELETE, pfnMsgDelete);
7020 + StoreFxn(WMD_MSG_DELETEQUEUE, pfnMsgDeleteQueue);
7021 + StoreFxn(WMD_MSG_GET, pfnMsgGet);
7022 + StoreFxn(WMD_MSG_PUT, pfnMsgPut);
7023 + StoreFxn(WMD_MSG_REGISTERNOTIFY, pfnMsgRegisterNotify);
7024 + StoreFxn(WMD_MSG_SETQUEUEID, pfnMsgSetQueueId);
7026 + /* Add code for any additional functions in newer WMD versions here: */
7027 + /* Ensure postcondition: */
7028 + DBC_Ensure(pIntfFxns->pfnDevCreate != NULL);
7029 + DBC_Ensure(pIntfFxns->pfnDevDestroy != NULL);
7030 + DBC_Ensure(pIntfFxns->pfnDevCntrl != NULL);
7031 + DBC_Ensure(pIntfFxns->pfnBrdMonitor != NULL);
7032 + DBC_Ensure(pIntfFxns->pfnBrdStart != NULL);
7033 + DBC_Ensure(pIntfFxns->pfnBrdStop != NULL);
7034 + DBC_Ensure(pIntfFxns->pfnBrdStatus != NULL);
7035 + DBC_Ensure(pIntfFxns->pfnBrdRead != NULL);
7036 + DBC_Ensure(pIntfFxns->pfnBrdWrite != NULL);
7037 + DBC_Ensure(pIntfFxns->pfnChnlCreate != NULL);
7038 + DBC_Ensure(pIntfFxns->pfnChnlDestroy != NULL);
7039 + DBC_Ensure(pIntfFxns->pfnChnlOpen != NULL);
7040 + DBC_Ensure(pIntfFxns->pfnChnlClose != NULL);
7041 + DBC_Ensure(pIntfFxns->pfnChnlAddIOReq != NULL);
7042 + DBC_Ensure(pIntfFxns->pfnChnlGetIOC != NULL);
7043 + DBC_Ensure(pIntfFxns->pfnChnlCancelIO != NULL);
7044 + DBC_Ensure(pIntfFxns->pfnChnlFlushIO != NULL);
7045 + DBC_Ensure(pIntfFxns->pfnChnlGetInfo != NULL);
7046 + DBC_Ensure(pIntfFxns->pfnChnlGetMgrInfo != NULL);
7047 + DBC_Ensure(pIntfFxns->pfnChnlIdle != NULL);
7048 + DBC_Ensure(pIntfFxns->pfnChnlRegisterNotify != NULL);
7049 + DBC_Ensure(pIntfFxns->pfnDehCreate != NULL);
7050 + DBC_Ensure(pIntfFxns->pfnDehDestroy != NULL);
7051 + DBC_Ensure(pIntfFxns->pfnDehNotify != NULL);
7052 + DBC_Ensure(pIntfFxns->pfnDehRegisterNotify != NULL);
7053 + DBC_Ensure(pIntfFxns->pfnDehGetInfo != NULL);
7054 + DBC_Ensure(pIntfFxns->pfnIOCreate != NULL);
7055 + DBC_Ensure(pIntfFxns->pfnIODestroy != NULL);
7056 + DBC_Ensure(pIntfFxns->pfnIOOnLoaded != NULL);
7057 + DBC_Ensure(pIntfFxns->pfnIOGetProcLoad != NULL);
7058 + DBC_Ensure(pIntfFxns->pfnMsgSetQueueId != NULL);
7060 +#undef StoreFxn
7063 Index: lk/drivers/dsp/bridge/pmgr/dmm.c
7064 ===================================================================
7065 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
7066 +++ lk/drivers/dsp/bridge/pmgr/dmm.c 2008-08-18 10:38:37.000000000 +0300
7067 @@ -0,0 +1,646 @@
7069 + * linux/drivers/dsp/bridge/pmgr/dmm.c
7071 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
7073 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
7075 + * This package is free software; you can redistribute it and/or modify
7076 + * it under the terms of the GNU General Public License version 2 as
7077 + * published by the Free Software Foundation.
7079 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
7080 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7081 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
7082 + */
7085 + * ======== dmm.c ========
7086 + * Purpose:
7087 + * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
7088 + * space that can be directly mapped to any MPU buffer or memory region
7090 + * Public Functions:
7091 + * DMM_CreateTables
7092 + * DMM_Create
7093 + * DMM_Destroy
7094 + * DMM_Exit
7095 + * DMM_Init
7096 + * DMM_MapMemory
7097 + * DMM_Reset
7098 + * DMM_ReserveMemory
7099 + * DMM_UnMapMemory
7100 + * DMM_UnReserveMemory
7102 + * Private Functions:
7103 + * AddRegion
7104 + * CreateRegion
7105 + * GetRegion
7106 + * GetFreeRegion
7107 + * GetMappedRegion
7109 + * Notes:
7110 + * Region: Generic memory entitiy having a start address and a size
7111 + * Chunk: Reserved region
7114 + *! Revision History:
7115 + *! ================
7116 + *! 04-Jun-2008 Hari K : Optimized DMM implementation. Removed linked list
7117 + *! and instead used Table approach.
7118 + *! 19-Apr-2004 sb: Integrated Alan's code review updates.
7119 + *! 17-Mar-2004 ap: Fixed GetRegion for size=0 using tighter bound.
7120 + *! 20-Feb-2004 sb: Created.
7121 + *!
7122 + */
7124 +/* ----------------------------------- Host OS */
7125 +#include <host_os.h>
7127 +/* ----------------------------------- DSP/BIOS Bridge */
7128 +#include <std.h>
7129 +#include <dbdefs.h>
7131 +/* ----------------------------------- Trace & Debug */
7132 +#include <dbc.h>
7133 +#include <errbase.h>
7134 +#include <gt.h>
7136 +/* ----------------------------------- OS Adaptation Layer */
7137 +#include <list.h>
7138 +#include <mem.h>
7139 +#include <sync.h>
7141 +/* ----------------------------------- Platform Manager */
7142 +#include <dev.h>
7143 +#include <proc.h>
7145 +/* ----------------------------------- This */
7146 +#include <dmm.h>
7148 +/* ----------------------------------- Defines, Data Structures, Typedefs */
7149 +/* Object signatures */
7150 +#define DMMSIGNATURE 0x004d4d44 /* "DMM" (in reverse) */
7152 +#define DMM_ADDR_VIRTUAL(a) \
7153 + (((struct MapPage *)(a) - pVirtualMappingTable) * PG_SIZE_4K +\
7154 + dynMemMapBeg)
7155 +#define DMM_ADDR_TO_INDEX(a) (((a) - dynMemMapBeg) / PG_SIZE_4K)
7157 +/* DMM Mgr */
7158 +struct DMM_OBJECT {
7159 + u32 dwSignature; /* Used for object validation */
7160 + /* Dmm Lock is used to serialize access mem manager for
7161 + * multi-threads. */
7162 + struct SYNC_CSOBJECT *hDmmLock; /* Lock to access dmm mgr */
7166 +/* ----------------------------------- Globals */
7167 +#if GT_TRACE
7168 +static struct GT_Mask DMM_debugMask = { NULL, NULL }; /* GT trace variable */
7169 +#endif
7171 +static u32 cRefs; /* module reference count */
7172 +struct MapPage {
7173 + u32 RegionSize:15;
7174 + u32 MappedSize:15;
7175 + u32 bReserved:1;
7176 + u32 bMapped:1;
7179 +/* Create the free list */
7180 +static struct MapPage *pVirtualMappingTable;
7181 +static u32 iFreeRegion; /* The index of free region */
7182 +static u32 iFreeSize;
7183 +static u32 *pPhysicalAddrTable; /* Physical address of MPU buffer */
7184 +static u32 dynMemMapBeg; /* The Beginning of dynamic memory mapping */
7185 +static u32 TableSize;/* The size of virtual and physical pages tables */
7187 +/* ----------------------------------- Function Prototypes */
7188 +static struct MapPage *GetRegion(u32 addr);
7189 +static struct MapPage *GetFreeRegion(u32 aSize);
7190 +static struct MapPage *GetMappedRegion(u32 aAddr);
7192 +/* ======== DMM_CreateTables ========
7193 + * Purpose:
7194 + * Create table to hold the information of physical address
7195 + * the buffer pages that is passed by the user, and the table
7196 + * to hold the information of the virtual memory that is reserved
7197 + * for DSP.
7198 + */
7199 +DSP_STATUS DMM_CreateTables(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size)
7201 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7202 + DSP_STATUS status = DSP_SOK;
7204 + GT_3trace(DMM_debugMask, GT_ENTER,
7205 + "Entered DMM_CreateTables () hDmmMgr %x, addr"
7206 + " %x, size %x\n", hDmmMgr, addr, size);
7207 + status = DMM_DeleteTables(pDmmObj);
7208 + if (DSP_SUCCEEDED(status)) {
7209 + SYNC_EnterCS(pDmmObj->hDmmLock);
7210 + dynMemMapBeg = addr;
7211 + TableSize = (size/PG_SIZE_4K) + 1;
7212 + /* Create the free list */
7213 + pVirtualMappingTable = (struct MapPage *) MEM_Calloc
7214 + (TableSize*sizeof(struct MapPage), MEM_NONPAGED);
7215 + if (pVirtualMappingTable == NULL)
7216 + status = DSP_EMEMORY;
7217 + else {
7218 + /* This table will be used
7219 + * to store the virtual to physical
7220 + * address translations
7221 + */
7222 + pPhysicalAddrTable = (u32 *)MEM_Calloc
7223 + (TableSize*sizeof(u32), MEM_NONPAGED);
7224 + GT_1trace(DMM_debugMask, GT_4CLASS,
7225 + "DMM_CreateTables: Allocate"
7226 + "memory for pPhysicalAddrTable=%d entries\n",
7227 + TableSize);
7228 + if (pPhysicalAddrTable == NULL) {
7229 + status = DSP_EMEMORY;
7230 + GT_0trace(DMM_debugMask, GT_7CLASS,
7231 + "DMM_CreateTables: Memory allocation for "
7232 + "pPhysicalAddrTable failed\n");
7233 + } else {
7234 + /* On successful allocation,
7235 + * all entries are zero ('free') */
7236 + iFreeRegion = 0;
7237 + iFreeSize = TableSize*PG_SIZE_4K;
7238 + pVirtualMappingTable[0].RegionSize = TableSize;
7241 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7242 + } else
7243 + GT_0trace(DMM_debugMask, GT_7CLASS,
7244 + "DMM_CreateTables: DMM_DeleteTables"
7245 + "Failure\n");
7247 + GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_CreateTables status"
7248 + "0x%x\n", status);
7249 + return status;
7253 + * ======== DMM_Create ========
7254 + * Purpose:
7255 + * Create a dynamic memory manager object.
7256 + */
7257 +DSP_STATUS DMM_Create(OUT struct DMM_OBJECT **phDmmMgr,
7258 + struct DEV_OBJECT *hDevObject,
7259 + IN CONST struct DMM_MGRATTRS *pMgrAttrs)
7261 + struct DMM_OBJECT *pDmmObject = NULL;
7262 + DSP_STATUS status = DSP_SOK;
7263 + DBC_Require(cRefs > 0);
7264 + DBC_Require(phDmmMgr != NULL);
7266 + GT_3trace(DMM_debugMask, GT_ENTER,
7267 + "DMM_Create: phDmmMgr: 0x%x hDevObject: "
7268 + "0x%x pMgrAttrs: 0x%x\n", phDmmMgr, hDevObject, pMgrAttrs);
7269 + *phDmmMgr = NULL;
7270 + /* create, zero, and tag a cmm mgr object */
7271 + MEM_AllocObject(pDmmObject, struct DMM_OBJECT, DMMSIGNATURE);
7272 + if (pDmmObject != NULL) {
7273 + status = SYNC_InitializeCS(&pDmmObject->hDmmLock);
7274 + if (DSP_SUCCEEDED(status))
7275 + *phDmmMgr = pDmmObject;
7276 + else
7277 + DMM_Destroy(pDmmObject);
7278 + } else {
7279 + GT_0trace(DMM_debugMask, GT_7CLASS,
7280 + "DMM_Create: Object Allocation "
7281 + "Failure(DMM Object)\n");
7282 + status = DSP_EMEMORY;
7284 + GT_2trace(DMM_debugMask, GT_4CLASS,
7285 + "Leaving DMM_Create status %x pDmmObject %x\n",
7286 + status, pDmmObject);
7288 + return status;
7292 + * ======== DMM_Destroy ========
7293 + * Purpose:
7294 + * Release the communication memory manager resources.
7295 + */
7296 +DSP_STATUS DMM_Destroy(struct DMM_OBJECT *hDmmMgr)
7298 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7299 + DSP_STATUS status = DSP_SOK;
7301 + GT_1trace(DMM_debugMask, GT_ENTER,
7302 + "Entered DMM_Destroy () hDmmMgr %x\n", hDmmMgr);
7303 + DBC_Require(cRefs > 0);
7304 + if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) {
7305 + status = DMM_DeleteTables(pDmmObj);
7306 + if (DSP_SUCCEEDED(status)) {
7307 + /* Delete CS & dmm mgr object */
7308 + SYNC_DeleteCS(pDmmObj->hDmmLock);
7309 + MEM_FreeObject(pDmmObj);
7310 + } else
7311 + GT_0trace(DMM_debugMask, GT_7CLASS,
7312 + "DMM_Destroy: DMM_DeleteTables "
7313 + "Failure\n");
7314 + } else
7315 + status = DSP_EHANDLE;
7316 + GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_Destroy status %x\n",
7317 + status);
7318 + return status;
7323 + * ======== DMM_DeleteTables ========
7324 + * Purpose:
7325 + * Delete DMM Tables.
7326 + */
7327 +DSP_STATUS DMM_DeleteTables(struct DMM_OBJECT *hDmmMgr)
7329 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7330 + DSP_STATUS status = DSP_SOK;
7332 + GT_1trace(DMM_debugMask, GT_ENTER,
7333 + "Entered DMM_DeleteTables () hDmmMgr %x\n", hDmmMgr);
7334 + DBC_Require(cRefs > 0);
7335 + if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) {
7336 + /* Delete all DMM tables */
7337 + SYNC_EnterCS(pDmmObj->hDmmLock);
7339 + if (pVirtualMappingTable != NULL)
7340 + MEM_Free(pVirtualMappingTable);
7342 + if (pPhysicalAddrTable != NULL)
7343 + MEM_Free(pPhysicalAddrTable);
7345 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7346 + } else
7347 + status = DSP_EHANDLE;
7348 + GT_1trace(DMM_debugMask, GT_4CLASS,
7349 + "Leaving DMM_DeleteTables status %x\n", status);
7350 + return status;
7357 + * ======== DMM_Exit ========
7358 + * Purpose:
7359 + * Discontinue usage of module; free resources when reference count
7360 + * reaches 0.
7361 + */
7362 +void DMM_Exit(void)
7364 + DBC_Require(cRefs > 0);
7366 + cRefs--;
7368 + GT_1trace(DMM_debugMask, GT_ENTER,
7369 + "exiting DMM_Exit, ref count:0x%x\n", cRefs);
7373 + * ======== DMM_GetHandle ========
7374 + * Purpose:
7375 + * Return the dynamic memory manager object for this device.
7376 + * This is typically called from the client process.
7377 + */
7378 +DSP_STATUS DMM_GetHandle(DSP_HPROCESSOR hProcessor,
7379 + OUT struct DMM_OBJECT **phDmmMgr)
7381 + DSP_STATUS status = DSP_SOK;
7382 + struct DEV_OBJECT *hDevObject;
7384 + GT_2trace(DMM_debugMask, GT_ENTER,
7385 + "DMM_GetHandle: hProcessor %x, phDmmMgr"
7386 + "%x\n", hProcessor, phDmmMgr);
7387 + DBC_Require(cRefs > 0);
7388 + DBC_Require(phDmmMgr != NULL);
7389 + if (hProcessor != NULL)
7390 + status = PROC_GetDevObject(hProcessor, &hDevObject);
7391 + else
7392 + hDevObject = DEV_GetFirst(); /* default */
7394 + if (DSP_SUCCEEDED(status))
7395 + status = DEV_GetDmmMgr(hDevObject, phDmmMgr);
7397 + GT_2trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_GetHandle status %x, "
7398 + "*phDmmMgr %x\n", status, phDmmMgr ? *phDmmMgr : 0);
7399 + return status;
7403 + * ======== DMM_Init ========
7404 + * Purpose:
7405 + * Initializes private state of DMM module.
7406 + */
7407 +bool DMM_Init(void)
7409 + bool fRetval = true;
7411 + DBC_Require(cRefs >= 0);
7413 + if (cRefs == 0) {
7414 + /* Set the Trace mask */
7415 + /*"DM" for Dymanic Memory Manager */
7416 + GT_create(&DMM_debugMask, "DM");
7419 + if (fRetval)
7420 + cRefs++;
7422 + GT_1trace(DMM_debugMask, GT_ENTER,
7423 + "Entered DMM_Init, ref count:0x%x\n", cRefs);
7425 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
7427 + pVirtualMappingTable = NULL ;
7428 + pPhysicalAddrTable = NULL ;
7429 + TableSize = 0;
7431 + return fRetval;
7435 + * ======== DMM_MapMemory ========
7436 + * Purpose:
7437 + * Add a mapping block to the reserved chunk. DMM assumes that this block
7438 + * will be mapped in the DSP/IVA's address space. DMM returns an error if a
7439 + * mapping overlaps another one. This function stores the info that will be
7440 + * required later while unmapping the block.
7441 + */
7442 +DSP_STATUS DMM_MapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size)
7444 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7445 + struct MapPage *chunk;
7446 + DSP_STATUS status = DSP_SOK;
7448 + GT_3trace(DMM_debugMask, GT_ENTER,
7449 + "Entered DMM_MapMemory () hDmmMgr %x, "
7450 + "addr %x, size %x\n", hDmmMgr, addr, size);
7451 + SYNC_EnterCS(pDmmObj->hDmmLock);
7452 + /* Find the Reserved memory chunk containing the DSP block to
7453 + * be mapped */
7454 + chunk = (struct MapPage *)GetRegion(addr);
7455 + if (chunk != NULL) {
7456 + /* Mark the region 'mapped', leave the 'reserved' info as-is */
7457 + chunk->bMapped = true;
7458 + chunk->MappedSize = (size/PG_SIZE_4K);
7459 + } else
7460 + status = DSP_ENOTFOUND;
7461 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7462 + GT_2trace(DMM_debugMask, GT_4CLASS,
7463 + "Leaving DMM_MapMemory status %x, chunk %x\n",
7464 + status, chunk);
7465 + return status;
7469 + * ======== DMM_ReserveMemory ========
7470 + * Purpose:
7471 + * Reserve a chunk of virtually contiguous DSP/IVA address space.
7472 + */
7473 +DSP_STATUS DMM_ReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 size,
7474 + u32 *pRsvAddr)
7476 + DSP_STATUS status = DSP_SOK;
7477 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7478 + struct MapPage *node;
7479 + u32 rsvAddr = 0;
7480 + u32 rsvSize = 0;
7482 + GT_3trace(DMM_debugMask, GT_ENTER,
7483 + "Entered DMM_ReserveMemory () hDmmMgr %x, "
7484 + "size %x, pRsvAddr %x\n", hDmmMgr, size, pRsvAddr);
7485 + SYNC_EnterCS(pDmmObj->hDmmLock);
7487 + /* Try to get a DSP chunk from the free list */
7488 + node = GetFreeRegion(size);
7489 + if (node != NULL) {
7490 + /* DSP chunk of given size is available. */
7491 + rsvAddr = DMM_ADDR_VIRTUAL(node);
7492 + /* Calculate the number entries to use */
7493 + rsvSize = size/PG_SIZE_4K;
7494 + if (rsvSize < node->RegionSize) {
7495 + /* Mark remainder of free region */
7496 + node[rsvSize].bMapped = false;
7497 + node[rsvSize].bReserved = false;
7498 + node[rsvSize].RegionSize = node->RegionSize - rsvSize;
7499 + node[rsvSize].MappedSize = 0;
7501 + /* GetRegion will return first fit chunk. But we only use what
7502 + is requested. */
7503 + node->bMapped = false;
7504 + node->bReserved = true;
7505 + node->RegionSize = rsvSize;
7506 + node->MappedSize = 0;
7507 + /* Return the chunk's starting address */
7508 + *pRsvAddr = rsvAddr;
7509 + } else
7510 + /*dSP chunk of given size is not available */
7511 + status = DSP_EMEMORY;
7513 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7514 + GT_3trace(DMM_debugMask, GT_4CLASS,
7515 + "Leaving ReserveMemory status %x, rsvAddr"
7516 + " %x, rsvSize %x\n", status, rsvAddr, rsvSize);
7517 + return status;
7522 + * ======== DMM_UnMapMemory ========
7523 + * Purpose:
7524 + * Remove the mapped block from the reserved chunk.
7525 + */
7526 +DSP_STATUS DMM_UnMapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 *pSize)
7528 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7529 + struct MapPage *chunk;
7530 + DSP_STATUS status = DSP_SOK;
7532 + GT_3trace(DMM_debugMask, GT_ENTER,
7533 + "Entered DMM_UnMapMemory () hDmmMgr %x, "
7534 + "addr %x, pSize %x\n", hDmmMgr, addr, pSize);
7535 + SYNC_EnterCS(pDmmObj->hDmmLock);
7536 + chunk = GetMappedRegion(addr) ;
7537 + if (chunk == NULL)
7538 + status = DSP_ENOTFOUND ;
7540 + if (DSP_SUCCEEDED(status)) {
7541 + /* Unmap the region */
7542 + *pSize = chunk->MappedSize * PG_SIZE_4K;
7543 + chunk->bMapped = false;
7544 + chunk->MappedSize = 0;
7546 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7547 + GT_3trace(DMM_debugMask, GT_ENTER,
7548 + "Leaving DMM_UnMapMemory status %x, chunk"
7549 + " %x, *pSize %x\n", status, chunk, *pSize);
7551 + return status;
7555 + * ======== DMM_UnReserveMemory ========
7556 + * Purpose:
7557 + * Free a chunk of reserved DSP/IVA address space.
7558 + */
7559 +DSP_STATUS DMM_UnReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 rsvAddr)
7561 + struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
7562 + struct MapPage *chunk;
7563 + u32 i;
7564 + DSP_STATUS status = DSP_SOK;
7565 + u32 chunkSize;
7567 + GT_2trace(DMM_debugMask, GT_ENTER,
7568 + "Entered DMM_UnReserveMemory () hDmmMgr "
7569 + "%x, rsvAddr %x\n", hDmmMgr, rsvAddr);
7571 + SYNC_EnterCS(pDmmObj->hDmmLock);
7573 + /* Find the chunk containing the reserved address */
7574 + chunk = GetMappedRegion(rsvAddr);
7575 + if (chunk == NULL)
7576 + status = DSP_ENOTFOUND;
7578 + if (DSP_SUCCEEDED(status)) {
7579 + /* Free all the mapped pages for this reserved region */
7580 + i = 0;
7581 + while (i < chunk->RegionSize) {
7582 + if (chunk[i].bMapped) {
7583 + /* Remove mapping from the page tables. */
7584 + chunkSize = chunk[i].MappedSize;
7585 + /* Clear the mapping flags */
7586 + chunk[i].bMapped = false;
7587 + chunk[i].MappedSize = 0;
7588 + i += chunkSize;
7589 + } else
7590 + i++;
7592 + /* Clear the flags (mark the region 'free') */
7593 + chunk->bReserved = false;
7594 + /* NOTE: We do NOT coalesce free regions here.
7595 + * Free regions are coalesced in GetRegion(), as it traverses
7596 + *the whole mapping table
7597 + */
7599 + SYNC_LeaveCS(pDmmObj->hDmmLock);
7600 + GT_2trace(DMM_debugMask, GT_ENTER,
7601 + "Leaving DMM_UnReserveMemory status %x"
7602 + " chunk %x\n", status, chunk);
7603 + return status;
7608 + * ======== GetRegion ========
7609 + * Purpose:
7610 + * Returns a region containing the specified memory region
7611 + */
7612 +struct MapPage *GetRegion(u32 aAddr)
7614 + struct MapPage *currRegion = NULL;
7615 + u32 i = 0;
7617 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetRegion () "
7618 + " aAddr %x\n", aAddr);
7620 + if (pVirtualMappingTable != NULL) {
7621 + /* find page mapped by this address */
7622 + i = DMM_ADDR_TO_INDEX(aAddr);
7623 + if (i < TableSize)
7624 + currRegion = pVirtualMappingTable + i;
7626 + GT_3trace(DMM_debugMask, GT_4CLASS,
7627 + "Leaving GetRegion currRegion %x, iFreeRegion %d\n,"
7628 + "iFreeSize %d\n", currRegion, iFreeRegion, iFreeSize) ;
7629 + return currRegion;
7633 + * ======== GetFreeRegion ========
7634 + * Purpose:
7635 + * Returns the requested free region
7636 + */
7637 +struct MapPage *GetFreeRegion(u32 aSize)
7639 + struct MapPage *currRegion = NULL;
7640 + u32 i = 0;
7641 + u32 RegionSize = 0;
7642 + u32 nextI = 0;
7643 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetFreeRegion () "
7644 + "aSize 0x%x\n", aSize);
7646 + if (pVirtualMappingTable == NULL)
7647 + return currRegion;
7648 + if (aSize > iFreeSize) {
7649 + /* Find the largest free region
7650 + * (coalesce during the traversal) */
7651 + while (i < TableSize) {
7652 + RegionSize = pVirtualMappingTable[i].RegionSize;
7653 + nextI = i+RegionSize;
7654 + if (pVirtualMappingTable[i].bReserved == false) {
7655 + /* Coalesce, if possible */
7656 + if (nextI < TableSize &&
7657 + pVirtualMappingTable[nextI].bReserved
7658 + == false) {
7659 + pVirtualMappingTable[i].RegionSize +=
7660 + pVirtualMappingTable[nextI].RegionSize;
7661 + continue;
7663 + RegionSize *= PG_SIZE_4K;
7664 + if (RegionSize > iFreeSize) {
7665 + iFreeRegion = i;
7666 + iFreeSize = RegionSize;
7669 + i = nextI;
7672 + if (aSize <= iFreeSize) {
7673 + currRegion = pVirtualMappingTable + iFreeRegion;
7674 + iFreeRegion += (aSize / PG_SIZE_4K);
7675 + iFreeSize -= aSize;
7677 + return currRegion;
7681 + * ======== GetMappedRegion ========
7682 + * Purpose:
7683 + * Returns the requestedmapped region
7684 + */
7685 +struct MapPage *GetMappedRegion(u32 aAddr)
7687 + u32 i = 0;
7688 + struct MapPage *currRegion = NULL;
7689 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetMappedRegion () "
7690 + "aAddr 0x%x\n", aAddr);
7692 + if (pVirtualMappingTable == NULL)
7693 + return currRegion;
7695 + i = DMM_ADDR_TO_INDEX(aAddr);
7696 + if (i < TableSize && (pVirtualMappingTable[i].bMapped ||
7697 + pVirtualMappingTable[i].bReserved))
7698 + currRegion = pVirtualMappingTable + i;
7699 + return currRegion;
7703 + * ======== DMM_GetPhysicalAddrTable ========
7704 + * Purpose:
7705 + * Returns the physical table address
7706 + */
7707 +u32 *DMM_GetPhysicalAddrTable(void)
7709 + GT_1trace(DMM_debugMask, GT_ENTER, "Entered "
7710 + "DMM_GetPhysicalAddrTable()- pPhysicalAddrTable 0x%x\n",
7711 + pPhysicalAddrTable);
7712 + return pPhysicalAddrTable;
7714 Index: lk/drivers/dsp/bridge/pmgr/io.c
7715 ===================================================================
7716 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
7717 +++ lk/drivers/dsp/bridge/pmgr/io.c 2008-08-18 10:38:37.000000000 +0300
7718 @@ -0,0 +1,204 @@
7720 + * linux/drivers/dsp/bridge/pmgr/io.c
7722 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
7724 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
7726 + * This package is free software; you can redistribute it and/or modify
7727 + * it under the terms of the GNU General Public License version 2 as
7728 + * published by the Free Software Foundation.
7730 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
7731 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7732 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
7733 + */
7737 + * ======== io.c ========
7738 + * Description:
7739 + * IO manager interface: Manages IO between CHNL and MSG.
7741 + * Public Functions:
7742 + * IO_Create
7743 + * IO_Destroy
7744 + * IO_Exit
7745 + * IO_Init
7746 + * IO_OnLoaded
7748 + * Notes:
7749 + * This interface is basically a pass through to the WMD IO functions.
7751 + *! Revision History:
7752 + *! ================
7753 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
7754 + *! 04-Apr-2001 rr WSX_STATUS initialized in IO_Create.
7755 + *! 07-Nov-2000 jeh Created.
7756 + */
7758 +/* ----------------------------------- Host OS */
7759 +#include <host_os.h>
7761 +/* ----------------------------------- DSP/BIOS Bridge */
7762 +#include <std.h>
7763 +#include <dbdefs.h>
7764 +#include <errbase.h>
7766 +/* ----------------------------------- Trace & Debug */
7767 +#include <dbc.h>
7768 +#include <gt.h>
7770 +/* ----------------------------------- OS Adaptation Layer */
7771 +#include <cfg.h>
7772 +#include <mem.h>
7774 +/* ----------------------------------- Platform Manager */
7775 +#include <dev.h>
7777 +/* ----------------------------------- This */
7778 +#include <ioobj.h>
7779 +#include <iodefs.h>
7781 +/* ----------------------------------- Globals */
7782 +static u32 cRefs;
7784 +#if GT_TRACE
7785 +static struct GT_Mask IO_DebugMask = { NULL, NULL }; /* WCD IO Mask */
7786 +#endif
7789 + * ======== IO_Create ========
7790 + * Purpose:
7791 + * Create an IO manager object, responsible for managing IO between
7792 + * CHNL and MSG
7793 + */
7794 +DSP_STATUS IO_Create(OUT struct IO_MGR **phIOMgr, struct DEV_OBJECT *hDevObject,
7795 + IN CONST struct IO_ATTRS *pMgrAttrs)
7797 + struct WMD_DRV_INTERFACE *pIntfFxns;
7798 + struct IO_MGR *hIOMgr = NULL;
7799 + struct IO_MGR_ *pIOMgr = NULL;
7800 + DSP_STATUS status = DSP_SOK;
7802 + DBC_Require(cRefs > 0);
7803 + DBC_Require(phIOMgr != NULL);
7804 + DBC_Require(pMgrAttrs != NULL);
7806 + GT_3trace(IO_DebugMask, GT_ENTER, "Entered IO_Create: phIOMgr: 0x%x\t "
7807 + "hDevObject: 0x%x\tpMgrAttrs: 0x%x\n",
7808 + phIOMgr, hDevObject, pMgrAttrs);
7810 + *phIOMgr = NULL;
7812 + /* A memory base of 0 implies no memory base: */
7813 + if ((pMgrAttrs->dwSMBase != 0) && (pMgrAttrs->uSMLength == 0)) {
7814 + status = CHNL_E_INVALIDMEMBASE;
7815 + GT_0trace(IO_DebugMask, GT_7CLASS,
7816 + "IO_Create:Invalid Mem Base\n");
7819 + if (pMgrAttrs->uWordSize == 0) {
7820 + status = CHNL_E_INVALIDWORDSIZE;
7821 + GT_0trace(IO_DebugMask, GT_7CLASS,
7822 + "IO_Create:Invalid Word size\n");
7825 + if (DSP_SUCCEEDED(status)) {
7826 + DEV_GetIntfFxns(hDevObject, &pIntfFxns);
7828 + /* Let WMD channel module finish the create: */
7829 + status = (*pIntfFxns->pfnIOCreate)(&hIOMgr, hDevObject,
7830 + pMgrAttrs);
7832 + if (DSP_SUCCEEDED(status)) {
7833 + pIOMgr = (struct IO_MGR_ *) hIOMgr;
7834 + pIOMgr->pIntfFxns = pIntfFxns;
7835 + pIOMgr->hDevObject = hDevObject;
7837 + /* Return the new channel manager handle: */
7838 + *phIOMgr = hIOMgr;
7839 + GT_1trace(IO_DebugMask, GT_1CLASS,
7840 + "IO_Create: Success hIOMgr: 0x%x\n",
7841 + hIOMgr);
7845 + GT_2trace(IO_DebugMask, GT_ENTER,
7846 + "Exiting IO_Create: hIOMgr: 0x%x, status:"
7847 + " 0x%x\n", hIOMgr, status);
7849 + return status;
7853 + * ======== IO_Destroy ========
7854 + * Purpose:
7855 + * Delete IO manager.
7856 + */
7857 +DSP_STATUS IO_Destroy(struct IO_MGR *hIOMgr)
7859 + struct WMD_DRV_INTERFACE *pIntfFxns;
7860 + struct IO_MGR_ *pIOMgr = (struct IO_MGR_ *)hIOMgr;
7861 + DSP_STATUS status;
7863 + DBC_Require(cRefs > 0);
7865 + GT_1trace(IO_DebugMask, GT_ENTER, "Entered IO_Destroy: hIOMgr: 0x%x\n",
7866 + hIOMgr);
7868 + pIntfFxns = pIOMgr->pIntfFxns;
7870 + /* Let WMD channel module destroy the IO_MGR: */
7871 + status = (*pIntfFxns->pfnIODestroy) (hIOMgr);
7873 + GT_2trace(IO_DebugMask, GT_ENTER,
7874 + "Exiting IO_Destroy: pIOMgr: 0x%x, status:"
7875 + " 0x%x\n", pIOMgr, status);
7876 + return status;
7880 + * ======== IO_Exit ========
7881 + * Purpose:
7882 + * Discontinue usage of the IO module.
7883 + */
7884 +void IO_Exit(void)
7886 + DBC_Require(cRefs > 0);
7888 + cRefs--;
7890 + GT_1trace(IO_DebugMask, GT_5CLASS,
7891 + "Entered IO_Exit, ref count: 0x%x\n", cRefs);
7893 + DBC_Ensure(cRefs >= 0);
7897 + * ======== IO_Init ========
7898 + * Purpose:
7899 + * Initialize the IO module's private state.
7900 + */
7901 +bool IO_Init(void)
7903 + bool fRetval = true;
7905 + DBC_Require(cRefs >= 0);
7907 + if (cRefs == 0) {
7908 + DBC_Assert(!IO_DebugMask.flags);
7909 + GT_create(&IO_DebugMask, "IO"); /* "IO" for IO */
7912 + if (fRetval)
7913 + cRefs++;
7916 + GT_1trace(IO_DebugMask, GT_5CLASS,
7917 + "Entered IO_Init, ref count: 0x%x\n", cRefs);
7919 + DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
7921 + return fRetval;
7923 Index: lk/drivers/dsp/bridge/pmgr/ioobj.h
7924 ===================================================================
7925 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
7926 +++ lk/drivers/dsp/bridge/pmgr/ioobj.h 2008-08-18 10:38:37.000000000 +0300
7927 @@ -0,0 +1,52 @@
7929 + * linux/drivers/dsp/bridge/pmgr/ioobj.h
7931 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
7933 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
7935 + * This package is free software; you can redistribute it and/or modify
7936 + * it under the terms of the GNU General Public License version 2 as
7937 + * published by the Free Software Foundation.
7939 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
7940 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7941 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
7942 + */
7946 + * ======== ioobj.h ========
7947 + * Description:
7948 + * Structure subcomponents of channel class library IO objects which
7949 + * are exposed to class driver from mini-driver.
7951 + * Public Functions:
7952 + * None.
7954 + *! Revision History:
7955 + *! ================
7956 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
7957 + *! 01/16/97 gp: Created from chnlpriv.h
7958 + */
7960 +#ifndef IOOBJ_
7961 +#define IOOBJ_
7963 +#include <devdefs.h>
7964 +#include <wmd.h>
7967 + * This struct is the first field in a IO_MGR struct, as implemented in
7968 + * a WMD channel class library. Other, implementation specific fields
7969 + * follow this structure in memory.
7970 + */
7971 +struct IO_MGR_ {
7972 + /* These must be the first fields in a IO_MGR struct: */
7973 + u32 dwSignature; /* Used for object validation. */
7974 + struct WMD_DEV_CONTEXT *hWmdContext; /* WMD device context. */
7975 + struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */
7976 + struct DEV_OBJECT *hDevObject; /* Device this board represents. */
7977 +} ;
7979 +#endif /* IOOBJ_ */
7980 Index: lk/drivers/dsp/bridge/pmgr/msg.c
7981 ===================================================================
7982 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
7983 +++ lk/drivers/dsp/bridge/pmgr/msg.c 2008-08-18 10:38:37.000000000 +0300
7984 @@ -0,0 +1,173 @@
7986 + * linux/drivers/dsp/bridge/pmgr/msg.c
7988 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
7990 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
7992 + * This package is free software; you can redistribute it and/or modify
7993 + * it under the terms of the GNU General Public License version 2 as
7994 + * published by the Free Software Foundation.
7996 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
7997 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7998 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
7999 + */
8003 + * ======== msg.c ========
8004 + * Description:
8005 + * DSP/BIOS Bridge MSG Module.
8007 + * Public Functions:
8008 + * MSG_Create
8009 + * MSG_Delete
8010 + * MSG_Exit
8011 + * MSG_Init
8013 + *! Revision History:
8014 + *! =================
8015 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
8016 + *! 15-May-2001 ag Changed SUCCEEDED to DSP_SUCCEEDED.
8017 + *! 16-Feb-2001 jeh Fixed some comments.
8018 + *! 15-Dec-2000 rr MSG_Create returns DSP_EFAIL if pfnMsgCreate fails.
8019 + *! 12-Sep-2000 jeh Created.
8020 + */
8022 +/* ----------------------------------- Host OS */
8023 +#include <host_os.h>
8025 +/* ----------------------------------- DSP/BIOS Bridge */
8026 +#include <std.h>
8027 +#include <dbdefs.h>
8028 +#include <errbase.h>
8030 +/* ----------------------------------- Trace & Debug */
8031 +#include <dbc.h>
8032 +#include <gt.h>
8034 +/* ----------------------------------- OS Adaptation Layer */
8035 +#include <list.h>
8036 +#include <mem.h>
8038 +/* ----------------------------------- Mini Driver */
8039 +#include <wmd.h>
8041 +/* ----------------------------------- Platform Manager */
8042 +#include <dev.h>
8044 +/* ----------------------------------- This */
8045 +#include <msgobj.h>
8046 +#include <msg.h>
8048 +/* ----------------------------------- Globals */
8049 +#if GT_TRACE
8050 +static struct GT_Mask MSG_debugMask = { NULL, NULL }; /* GT trace variable */
8051 +#endif
8052 +static u32 cRefs; /* module reference count */
8055 + * ======== MSG_Create ========
8056 + * Purpose:
8057 + * Create an object to manage message queues. Only one of these objects
8058 + * can exist per device object.
8059 + */
8060 +DSP_STATUS MSG_Create(OUT struct MSG_MGR **phMsgMgr,
8061 + struct DEV_OBJECT *hDevObject, MSG_ONEXIT msgCallback)
8063 + struct WMD_DRV_INTERFACE *pIntfFxns;
8064 + struct MSG_MGR_ *pMsgMgr;
8065 + struct MSG_MGR *hMsgMgr;
8066 + DSP_STATUS status = DSP_SOK;
8068 + DBC_Require(cRefs > 0);
8069 + DBC_Require(phMsgMgr != NULL);
8070 + DBC_Require(msgCallback != NULL);
8071 + DBC_Require(hDevObject != NULL);
8073 + GT_3trace(MSG_debugMask, GT_ENTER, "MSG_Create: phMsgMgr: 0x%x\t"
8074 + "hDevObject: 0x%x\tmsgCallback: 0x%x\n",
8075 + phMsgMgr, hDevObject, msgCallback);
8077 + *phMsgMgr = NULL;
8079 + DEV_GetIntfFxns(hDevObject, &pIntfFxns);
8081 + /* Let WMD message module finish the create: */
8082 + status = (*pIntfFxns->pfnMsgCreate)(&hMsgMgr, hDevObject, msgCallback);
8084 + if (DSP_SUCCEEDED(status)) {
8085 + /* Fill in WCD message module's fields of the MSG_MGR
8086 + * structure */
8087 + pMsgMgr = (struct MSG_MGR_ *)hMsgMgr;
8088 + pMsgMgr->pIntfFxns = pIntfFxns;
8090 + /* Finally, return the new message manager handle: */
8091 + *phMsgMgr = hMsgMgr;
8092 + GT_1trace(MSG_debugMask, GT_1CLASS,
8093 + "MSG_Create: Success pMsgMgr: 0x%x\n", pMsgMgr);
8094 + } else {
8095 + status = DSP_EFAIL;
8097 + return status;
8101 + * ======== MSG_Delete ========
8102 + * Purpose:
8103 + * Delete a MSG manager allocated in MSG_Create().
8104 + */
8105 +void MSG_Delete(struct MSG_MGR *hMsgMgr)
8107 + struct MSG_MGR_ *pMsgMgr = (struct MSG_MGR_ *)hMsgMgr;
8108 + struct WMD_DRV_INTERFACE *pIntfFxns;
8110 + DBC_Require(cRefs > 0);
8111 + DBC_Require(MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE));
8113 + GT_1trace(MSG_debugMask, GT_ENTER, "MSG_Delete: hMsgMgr: 0x%x\n",
8114 + hMsgMgr);
8116 + pIntfFxns = pMsgMgr->pIntfFxns;
8118 + /* Let WMD message module destroy the MSG_MGR: */
8119 + (*pIntfFxns->pfnMsgDelete)(hMsgMgr);
8121 + DBC_Ensure(!MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE));
8125 + * ======== MSG_Exit ========
8126 + */
8127 +void MSG_Exit(void)
8129 + DBC_Require(cRefs > 0);
8130 + cRefs--;
8131 + GT_1trace(MSG_debugMask, GT_5CLASS,
8132 + "Entered MSG_Exit, ref count: 0x%x\n", cRefs);
8133 + DBC_Ensure(cRefs >= 0);
8137 + * ======== MSG_Init ========
8138 + */
8139 +bool MSG_Init(void)
8141 + DBC_Require(cRefs >= 0);
8143 + if (cRefs == 0) {
8144 + DBC_Assert(!MSG_debugMask.flags);
8145 + GT_create(&MSG_debugMask, "MG"); /* "MG" for MsG */
8148 + cRefs++;
8150 + GT_1trace(MSG_debugMask, GT_5CLASS, "MSG_Init(), ref count: 0x%x\n",
8151 + cRefs);
8153 + DBC_Ensure(cRefs >= 0);
8155 + return true;
8158 Index: lk/drivers/dsp/bridge/pmgr/msgobj.h
8159 ===================================================================
8160 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
8161 +++ lk/drivers/dsp/bridge/pmgr/msgobj.h 2008-08-18 10:38:37.000000000 +0300
8162 @@ -0,0 +1,52 @@
8164 + * linux/drivers/dsp/bridge/pmgr/msgobj.h
8166 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
8168 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
8170 + * This package is free software; you can redistribute it and/or modify
8171 + * it under the terms of the GNU General Public License version 2 as
8172 + * published by the Free Software Foundation.
8174 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
8175 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
8176 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8177 + */
8181 + * ======== msgobj.h ========
8182 + * Description:
8183 + * Structure subcomponents of channel class library MSG objects which
8184 + * are exposed to class driver from mini-driver.
8186 + * Public Functions:
8187 + * None.
8189 + *! Revision History:
8190 + *! ================
8191 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
8192 + *! 17-Nov-2000 jeh Created.
8193 + */
8195 +#ifndef MSGOBJ_
8196 +#define MSGOBJ_
8198 +#include <wmd.h>
8200 +#include <msgdefs.h>
8203 + * This struct is the first field in a MSG_MGR struct, as implemented in
8204 + * a WMD channel class library. Other, implementation specific fields
8205 + * follow this structure in memory.
8206 + */
8207 +struct MSG_MGR_ {
8208 + /* The first two fields must match those in msgobj.h */
8209 + u32 dwSignature;
8210 + struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */
8213 +#endif /* MSGOBJ_ */
8215 Index: lk/drivers/dsp/bridge/pmgr/wcd.c
8216 ===================================================================
8217 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
8218 +++ lk/drivers/dsp/bridge/pmgr/wcd.c 2008-08-18 10:38:37.000000000 +0300
8219 @@ -0,0 +1,1641 @@
8221 + * linux/drivers/dsp/bridge/pmgr/wcd.c
8223 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
8225 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
8227 + * This package is free software; you can redistribute it and/or modify
8228 + * it under the terms of the GNU General Public License version 2 as
8229 + * published by the Free Software Foundation.
8231 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
8232 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
8233 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8234 + */
8237 + * ======== wcd.c ========
8238 + * Description:
8239 + * Common WCD functions, also includes the wrapper
8240 + * functions called directly by the DeviceIOControl interface.
8242 + * Public Functions:
8243 + * WCD_CallDevIOCtl
8244 + * WCD_Init
8245 + * WCD_InitComplete2
8246 + * WCD_Exit
8247 + * <MOD>WRAP_*
8249 + *! Revision History:
8250 + *! ================
8251 + *! 29-Apr-2004 hp Call PROC_AutoStart only for DSP device
8252 + *! 19-Apr-2004 sb Aligned DMM definitions with Symbian
8253 + *! 08-Mar-2004 sb Added the Dynamic Memory Mapping APIs
8254 + *! 03-Apr-2003 sb Process environment pointer in PROCWRAP_Load
8255 + *! 24-Feb-2003 swa PMGR Code review comments incorporated.
8256 + *! 30-Jan-2002 ag CMMWRAP_AllocBuf name changed to CMMWRAP_CallocBuf
8257 + *! 15-Jan-2002 ag Added actual bufSize param to STRMWRAP_Reclaim[issue].
8258 + *! 14-Dec-2001 rr ARGS_NODE_CONNECT maps the pAttr.
8259 + *! 03-Oct-2001 rr ARGS_NODE_ALLOCMSGBUF/FREEMSGBUF maps the pAttr.
8260 + *! 10-Sep-2001 ag Added CMD_CMM_GETHANDLE.
8261 + *! 23-Apr-2001 jeh Pass pStatus to NODE_Terminate.
8262 + *! 11-Apr-2001 jeh STRMWRAP_Reclaim embedded pointer is mapped and unmapped.
8263 + *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates.
8264 + *! 06-Dec-2000 jeh WRAP_MAP2CALLER pointers in RegisterNotify calls.
8265 + *! 05-Dec-2000 ag: Removed MAP2CALLER in NODEWRAP_FreeMsgBuf().
8266 + *! 22-Nov-2000 kc: Added MGRWRAP_GetPerf_Data().
8267 + *! 20-Nov-2000 jeh Added MSG_Init()/MSG_Exit(), IO_Init()/IO_Exit().
8268 + *! WRAP pointers to handles for PROC_Attach, NODE_Allocate.
8269 + *! 27-Oct-2000 jeh Added NODEWRAP_AllocMsgBuf, NODEWRAP_FreeMsgBuf. Removed
8270 + *! NODEWRAP_GetMessageStream.
8271 + *! 12-Oct-2000 ag: Added user CMM wrappers.
8272 + *! 05-Oct-2000 rr: WcdInitComplete2 will fail even if one BRD or PROC
8273 + *! AutoStart fails.
8274 + *! 25-Sep-2000 rr: Updated to Version 0.9
8275 + *! 13-Sep-2000 jeh Pass ARGS_NODE_CONNECT.pAttrs to NODE_Connect().
8276 + *! 11-Aug-2000 rr: Part of node enabled.
8277 + *! 31-Jul-2000 rr: UTIL_Wrap and MEM_Wrap added to RM.
8278 + *! 27-Jul-2000 rr: PROCWRAP, NODEWRAP and STRMWRAP implemented.
8279 + *! STRM and some NODE Wrappers are not implemented.
8280 + *! 27-Jun-2000 rr: MGRWRAP fxns added.IFDEF to build for PM or DSP/BIOS Bridge
8281 + *! 08-Feb-2000 rr File name changed to wcd.c
8282 + *! 03-Feb-2000 rr: Module initialization are done by SERVICES init. GT Class
8283 + *! changes for module init/exit fxns.
8284 + *! 24-Jan-2000 rr: Merged with Scott's code.
8285 + *! 21-Jan-1999 sg: Changed ARGS_CHNL_GETMODE field name from pdwMode to pMode.
8286 + *! 17-Jan-2000 rr: BRD_GetStatus does WRAP_MAP2CALLER for state.
8287 + *! 14-Dec-1999 ag: Removed _MAP2CALLER in CHNL_GetMgr().
8288 + *! 13-Dec-1999 rr: BRDWRAP_GetSymbol, BRDWRAP_GetTrace uses WRAP_MAP2CALLER
8289 + *! macros.BRDWRAP_Load maps and unmaps embedded pointers.
8290 + *! 10-Dec-1999 ag: User CHNL bufs mapped in _AddIOReq & _GetIOCompletion.
8291 + *! 09-Dec-1999 rr: BRDWRAP_Open and CHNLWRAP_GetMgr does not map
8292 + *! pointer as there was a change in config.c
8293 + *! 06-Dec-1999 rr: BRD_Read and Write Maps the buf pointers.
8294 + *! 03-Dec-1999 rr: CHNLWRAP_GetMgr and BRDWRAP_Open maps hDevNode pointer.
8295 + *! WCD_InitComplete2 Included for BRD_AutoStart.
8296 + *! 16-Nov-1999 ag: Map buf to process in CHNLWRAP_AllocBuffer().
8297 + *! CHNL_GetMgr() Mapping Fix.
8298 + *! 10-Nov-1999 ag: Removed unnecessary calls to WRAP_MAP2CALLER.
8299 + *! 08-Nov-1999 kc: Added MEMRY & enabled BRD_IOCtl for tests.
8300 + *! 29-Oct-1999 ag: Added CHNL.
8301 + *! 29-Oct-1999 kc: Added trace statements; added ptr mapping; updated
8302 + *! use of UTIL module API.
8303 + *! 29-Oct-1999 rr: Wrapper functions does the Mapping of the Pointers.
8304 + *! in WinCE all the explicit pointers will be converted
8305 + *! by the OS during interprocess but not the embedded pointers.
8306 + *! 16-Oct-1999 kc: Code review cleanup.
8307 + *! 07-Oct-1999 kc: Added UTILWRAP_TestDll() to run PM test harness. See
8308 + *! /src/doc/pmtest.doc for more detail.
8309 + *! 09-Sep-1999 rr: After exactly two years(!). Adopted for WinCE. GT Enabled.
8310 + *! 09-Sep-1997 gp: Created.
8311 + */
8313 +/* ----------------------------------- Host OS */
8314 +#include <host_os.h>
8316 +/* ----------------------------------- DSP/BIOS Bridge */
8317 +#include <std.h>
8318 +#include <dbdefs.h>
8319 +#include <errbase.h>
8321 +/* ----------------------------------- Trace & Debug */
8322 +#include <dbc.h>
8323 +#include <gt.h>
8325 +/* ----------------------------------- OS Adaptation Layer */
8326 +#include <cfg.h>
8327 +#include <mem.h>
8328 +#include <ntfy.h>
8329 +#include <services.h>
8330 +#include <util.h>
8332 +/* ----------------------------------- Platform Manager */
8333 +#include <chnl.h>
8334 +#include <dev.h>
8335 +#include <drv.h>
8337 +#include <proc.h>
8338 +#include <strm.h>
8340 +/* ----------------------------------- Resource Manager */
8341 +#include <disp.h>
8342 +#include <mgr.h>
8343 +#include <node.h>
8344 +#include <rmm.h>
8347 +/* ----------------------------------- Others */
8348 +#include <msg.h>
8349 +#include <cmm.h>
8350 +#include <io.h>
8352 +/* ----------------------------------- This */
8353 +#include <_dcd.h>
8354 +#include <dbdcd.h>
8356 +#ifndef RES_CLEANUP_DISABLE
8357 +#include <resourcecleanup.h>
8358 +#endif
8360 +/* ----------------------------------- Defines, Data Structures, Typedefs */
8361 +#define MAX_TRACEBUFLEN 255
8362 +#define MAX_LOADARGS 16
8363 +#define MAX_NODES 64
8364 +#define MAX_STREAMS 16
8365 +#define MAX_BUFS 64
8367 +/* Following two macros should ideally have do{}while(0) */
8369 +#define cp_fm_usr(dest, src, status, elements) \
8370 + if (DSP_SUCCEEDED(status)) {\
8371 + if (unlikely(src == NULL) || \
8372 + unlikely(copy_from_user(dest, src, elements * sizeof(*(dest))))) { \
8373 + GT_1trace(WCD_debugMask, GT_7CLASS, \
8374 + "copy_from_user failed, src=0x%x\n", src); \
8375 + status = DSP_EPOINTER ; \
8376 + } \
8379 +#define cp_to_usr(dest, src, status, elements) \
8380 + if (DSP_SUCCEEDED(status)) {\
8381 + if (unlikely(dest == NULL) || \
8382 + unlikely(copy_to_user(dest, src, elements * sizeof(*(src))))) { \
8383 + GT_1trace(WCD_debugMask, GT_7CLASS, \
8384 + "copy_to_user failed, dest=0x%x\n", dest); \
8385 + status = DSP_EPOINTER ;\
8386 + } \
8389 +/* Device IOCtl function pointer */
8390 +struct WCD_Cmd {
8391 + u32(*fxn)(union Trapped_Args *args);
8392 + u32 dwIndex;
8393 +} ;
8395 +/* ----------------------------------- Globals */
8396 +struct GT_Mask WCD_debugMask = { NULL, NULL }; /* Core VxD Mask */
8397 +u32 WCD_cRefs;
8400 + * Function table.
8401 + * The order of these functions MUST be the same as the order of the command
8402 + * numbers defined in wcdioctl.h This is how an IOCTL number in user mode
8403 + * turns into a function call in kernel mode.
8404 + */
8405 +struct WCD_Cmd WCD_cmdTable[] = {
8406 + /* MGR module */
8407 + {MGRWRAP_EnumNode_Info, CMD_MGR_ENUMNODE_INFO_OFFSET},
8408 + {MGRWRAP_EnumProc_Info, CMD_MGR_ENUMPROC_INFO_OFFSET},
8409 + {MGRWRAP_RegisterObject, CMD_MGR_REGISTEROBJECT_OFFSET},
8410 + {MGRWRAP_UnregisterObject, CMD_MGR_UNREGISTEROBJECT_OFFSET},
8411 + {MGRWRAP_WaitForBridgeEvents, CMD_MGR_WAIT_OFFSET},
8412 +#ifndef RES_CLEANUP_DISABLE
8413 + {MGRWRAP_GetProcessResourcesInfo, CMD_MGR_RESOUCES_OFFSET},
8414 +#endif
8415 + /* PROC Module */
8416 + {PROCWRAP_Attach, CMD_PROC_ATTACH_OFFSET},
8417 + {PROCWRAP_Ctrl, CMD_PROC_CTRL_OFFSET},
8418 + {PROCWRAP_Detach, CMD_PROC_DETACH_OFFSET},
8419 + {PROCWRAP_EnumNode_Info, CMD_PROC_ENUMNODE_OFFSET},
8420 + {PROCWRAP_EnumResources, CMD_PROC_ENUMRESOURCES_OFFSET},
8421 + {PROCWRAP_GetState, CMD_PROC_GETSTATE_OFFSET},
8422 + {PROCWRAP_GetTrace, CMD_PROC_GETTRACE_OFFSET},
8423 + {PROCWRAP_Load, CMD_PROC_LOAD_OFFSET},
8424 + {PROCWRAP_RegisterNotify, CMD_PROC_REGISTERNOTIFY_OFFSET},
8425 + {PROCWRAP_Start, CMD_PROC_START_OFFSET},
8426 + {PROCWRAP_ReserveMemory, CMD_PROC_RSVMEM_OFFSET},
8427 + {PROCWRAP_UnReserveMemory, CMD_PROC_UNRSVMEM_OFFSET},
8428 + {PROCWRAP_Map, CMD_PROC_MAPMEM_OFFSET},
8429 + {PROCWRAP_UnMap, CMD_PROC_UNMAPMEM_OFFSET},
8430 + {PROCWRAP_FlushMemory, CMD_PROC_FLUSHMEMORY_OFFSET},
8431 + {PROCWRAP_Stop, CMD_PROC_STOP_OFFSET},
8432 + {PROCWRAP_InvalidateMemory, CMD_PROC_INVALIDATEMEMORY_OFFSET},
8433 + /* NODE Module */
8434 + {NODEWRAP_Allocate, CMD_NODE_ALLOCATE_OFFSET},
8435 + {NODEWRAP_AllocMsgBuf, CMD_NODE_ALLOCMSGBUF_OFFSET},
8436 + {NODEWRAP_ChangePriority, CMD_NODE_CHANGEPRIORITY_OFFSET},
8437 + {NODEWRAP_Connect, CMD_NODE_CONNECT_OFFSET},
8438 + {NODEWRAP_Create, CMD_NODE_CREATE_OFFSET},
8439 + {NODEWRAP_Delete, CMD_NODE_DELETE_OFFSET},
8440 + {NODEWRAP_FreeMsgBuf, CMD_NODE_FREEMSGBUF_OFFSET},
8441 + {NODEWRAP_GetAttr, CMD_NODE_GETATTR_OFFSET},
8442 + {NODEWRAP_GetMessage, CMD_NODE_GETMESSAGE_OFFSET},
8443 + {NODEWRAP_Pause, CMD_NODE_PAUSE_OFFSET},
8444 + {NODEWRAP_PutMessage, CMD_NODE_PUTMESSAGE_OFFSET},
8445 + {NODEWRAP_RegisterNotify, CMD_NODE_REGISTERNOTIFY_OFFSET},
8446 + {NODEWRAP_Run, CMD_NODE_RUN_OFFSET},
8447 + {NODEWRAP_Terminate, CMD_NODE_TERMINATE_OFFSET},
8448 + {NODEWRAP_GetUUIDProps, CMD_NODE_GETUUIDPROPS_OFFSET},
8449 + /* STRM wrapper functions */
8450 + {STRMWRAP_AllocateBuffer, CMD_STRM_ALLOCATEBUFFER_OFFSET},
8451 + {STRMWRAP_Close, CMD_STRM_CLOSE_OFFSET},
8452 + {STRMWRAP_FreeBuffer, CMD_STRM_FREEBUFFER_OFFSET},
8453 + {STRMWRAP_GetEventHandle, CMD_STRM_GETEVENTHANDLE_OFFSET},
8454 + {STRMWRAP_GetInfo, CMD_STRM_GETINFO_OFFSET},
8455 + {STRMWRAP_Idle, CMD_STRM_IDLE_OFFSET},
8456 + {STRMWRAP_Issue, CMD_STRM_ISSUE_OFFSET},
8457 + {STRMWRAP_Open, CMD_STRM_OPEN_OFFSET},
8458 + {STRMWRAP_Reclaim, CMD_STRM_RECLAIM_OFFSET},
8459 + {STRMWRAP_RegisterNotify, CMD_STRM_REGISTERNOTIFY_OFFSET},
8460 + {STRMWRAP_Select, CMD_STRM_SELECT_OFFSET},
8461 + /* CMM module */
8462 + {CMMWRAP_CallocBuf, CMD_CMM_ALLOCBUF_OFFSET},
8463 + {CMMWRAP_FreeBuf, CMD_CMM_FREEBUF_OFFSET},
8464 + {CMMWRAP_GetHandle, CMD_CMM_GETHANDLE_OFFSET},
8465 + {CMMWRAP_GetInfo, CMD_CMM_GETINFO_OFFSET}
8469 + * ======== WCD_CallDevIOCtl ========
8470 + * Purpose:
8471 + * Call the (wrapper) function for the corresponding WCD IOCTL.
8472 + */
8473 +inline DSP_STATUS WCD_CallDevIOCtl(u32 cmd, union Trapped_Args *args,
8474 + u32 *pResult)
8476 + if ((cmd < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)))) {
8477 + /* make the fxn call via the cmd table */
8478 + *pResult = (*WCD_cmdTable[cmd].fxn) (args);
8479 + return DSP_SOK;
8480 + } else {
8481 + return DSP_EINVALIDARG;
8486 + * ======== WCD_Exit ========
8487 + */
8488 +void WCD_Exit(void)
8490 + DBC_Require(WCD_cRefs > 0);
8491 + WCD_cRefs--;
8492 + GT_1trace(WCD_debugMask, GT_5CLASS,
8493 + "Entered WCD_Exit, ref count: 0x%x\n", WCD_cRefs);
8494 + if (WCD_cRefs == 0) {
8495 + /* Release all WCD modules initialized in WCD_Init(). */
8496 + COD_Exit();
8497 + DEV_Exit();
8498 + CHNL_Exit();
8499 + MSG_Exit();
8500 + IO_Exit();
8501 + STRM_Exit();
8502 + NTFY_Exit();
8503 + DISP_Exit();
8504 + NODE_Exit();
8505 + PROC_Exit();
8506 + MGR_Exit();
8507 + RMM_exit();
8508 + DRV_Exit();
8509 + SERVICES_Exit();
8511 + DBC_Ensure(WCD_cRefs >= 0);
8515 + * ======== WCD_Init ========
8516 + * Purpose:
8517 + * Module initialization is done by SERVICES Init.
8518 + */
8519 +bool WCD_Init(void)
8521 + bool fInit = true;
8522 + bool fDRV, fDEV, fCOD, fSERVICES, fCHNL, fMSG, fIO;
8523 + bool fMGR, fPROC, fNODE, fDISP, fNTFY, fSTRM, fRMM;
8524 +#ifdef DEBUG
8525 + /* runtime check of Device IOCtl array. */
8526 + u32 i;
8527 + for (i = 1; i < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)); i++)
8528 + DBC_Assert(WCD_cmdTable[i - 1].dwIndex == i);
8530 +#endif
8531 + if (WCD_cRefs == 0) {
8532 + /* initialize all SERVICES modules */
8533 + fSERVICES = SERVICES_Init();
8534 + /* initialize debugging module */
8535 + DBC_Assert(!WCD_debugMask.flags);
8536 + GT_create(&WCD_debugMask, "CD"); /* CD for class driver */
8537 + /* initialize class driver and other modules */
8538 + fDRV = DRV_Init();
8539 + fMGR = MGR_Init();
8540 + fPROC = PROC_Init();
8541 + fNODE = NODE_Init();
8542 + fDISP = DISP_Init();
8543 + fNTFY = NTFY_Init();
8544 + fSTRM = STRM_Init();
8545 + fRMM = RMM_init();
8546 + fCHNL = CHNL_Init();
8547 + fMSG = MSG_Init();
8548 + fIO = IO_Init();
8549 + fDEV = DEV_Init();
8550 + fCOD = COD_Init();
8551 + fInit = fSERVICES && fDRV && fDEV && fCHNL && fCOD &&
8552 + fMSG && fIO;
8553 + fInit = fInit && fMGR && fPROC && fRMM;
8554 + if (!fInit) {
8555 + if (fSERVICES)
8556 + SERVICES_Exit();
8558 + if (fDRV)
8559 + DRV_Exit();
8561 + if (fMGR)
8562 + MGR_Exit();
8564 + if (fSTRM)
8565 + STRM_Exit();
8567 + if (fPROC)
8568 + PROC_Exit();
8570 + if (fNODE)
8571 + NODE_Exit();
8573 + if (fDISP)
8574 + DISP_Exit();
8576 + if (fNTFY)
8577 + NTFY_Exit();
8579 + if (fCHNL)
8580 + CHNL_Exit();
8582 + if (fMSG)
8583 + MSG_Exit();
8585 + if (fIO)
8586 + IO_Exit();
8588 + if (fDEV)
8589 + DEV_Exit();
8591 + if (fCOD)
8592 + COD_Exit();
8594 + if (fRMM)
8595 + RMM_exit();
8599 + if (fInit)
8600 + WCD_cRefs++;
8602 + GT_1trace(WCD_debugMask, GT_5CLASS,
8603 + "Entered WCD_Init, ref count: 0x%x\n", WCD_cRefs);
8604 + return fInit;
8608 + * ======== WCD_InitComplete2 ========
8609 + * Purpose:
8610 + * Perform any required WCD, and WMD initialization which
8611 + * cannot not be performed in WCD_Init() or DEV_StartDevice() due
8612 + * to the fact that some services are not yet
8613 + * completely initialized.
8614 + * Parameters:
8615 + * Returns:
8616 + * DSP_SOK: Allow this device to load
8617 + * DSP_EFAIL: Failure.
8618 + * Requires:
8619 + * WCD initialized.
8620 + * Ensures:
8621 + */
8622 +DSP_STATUS WCD_InitComplete2(void)
8624 + DSP_STATUS status = DSP_SOK;
8625 + struct CFG_DEVNODE *DevNode;
8626 + struct DEV_OBJECT *hDevObject;
8627 + u32 devType;
8629 + DBC_Require(WCD_cRefs > 0);
8630 + GT_0trace(WCD_debugMask, GT_ENTER, "Entered WCD_InitComplete\n");
8631 + /* Walk the list of DevObjects, get each devnode, and attempting to
8632 + * autostart the board. Note that this requires COF loading, which
8633 + * requires KFILE. */
8634 + for (hDevObject = DEV_GetFirst(); hDevObject != NULL;
8635 + hDevObject = DEV_GetNext(hDevObject)) {
8636 + if (DSP_FAILED(DEV_GetDevNode(hDevObject, &DevNode)))
8637 + continue;
8639 + if (DSP_FAILED(DEV_GetDevType(hDevObject, &devType)))
8640 + continue;
8642 + if ((devType == DSP_UNIT) || (devType == IVA_UNIT)) {
8643 + if (DSP_FAILED(PROC_AutoStart(DevNode, hDevObject))) {
8644 + GT_0trace(WCD_debugMask, GT_1CLASS,
8645 + "WCD_InitComplete2 Failed\n");
8646 + status = DSP_EFAIL;
8647 + /* break; */
8649 + } else
8650 + GT_1trace(WCD_debugMask, GT_ENTER,
8651 + "Ignoring PROC_AutoStart "
8652 + "for Device Type = 0x%x \n", devType);
8653 + } /* End For Loop */
8654 + GT_1trace(WCD_debugMask, GT_ENTER,
8655 + "Exiting WCD_InitComplete status 0x%x\n", status);
8656 + return status;
8660 + * ======== MGRWRAP_EnumNode_Info ========
8661 + */
8662 +u32 MGRWRAP_EnumNode_Info(union Trapped_Args *args)
8664 + u8 *pNDBProps;
8665 + u32 uNumNodes;
8666 + DSP_STATUS status = DSP_SOK;
8667 + u32 size = args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize;
8669 + GT_4trace(WCD_debugMask, GT_ENTER,
8670 + "MGR_EnumNodeInfo: entered args:\n0x%x"
8671 + " uNode: 0x%x\tpNDBProps: 0x%x\tuNDBPropsSize: "
8672 + "0x%x\tpuNumNodes\n", args->ARGS_MGR_ENUMNODE_INFO.uNode,
8673 + args->ARGS_MGR_ENUMNODE_INFO.pNDBProps,
8674 + args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize,
8675 + args->ARGS_MGR_ENUMNODE_INFO.puNumNodes);
8676 + pNDBProps = MEM_Alloc(size, MEM_NONPAGED);
8677 + if (pNDBProps == NULL)
8678 + status = DSP_EMEMORY;
8680 + if (DSP_SUCCEEDED(status)) {
8681 + status = MGR_EnumNodeInfo(args->ARGS_MGR_ENUMNODE_INFO.uNode,
8682 + (struct DSP_NDBPROPS *)pNDBProps,
8683 + size, &uNumNodes);
8685 + cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.pNDBProps, pNDBProps, status,
8686 + size);
8687 + cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.puNumNodes, &uNumNodes, status,
8688 + 1);
8689 + if (pNDBProps)
8690 + MEM_Free(pNDBProps);
8692 + return status;
8696 + * ======== MGRWRAP_EnumProc_Info ========
8697 + */
8698 +u32 MGRWRAP_EnumProc_Info(union Trapped_Args *args)
8700 + u8 *pProcessorInfo;
8701 + u32 uNumProcs;
8702 + DSP_STATUS status = DSP_SOK;
8703 + u32 size = args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize;
8705 + GT_4trace(WCD_debugMask, GT_ENTER,
8706 + "MGRWRAP_EnumProc_Info: entered args:\n"
8707 + "0x%x uProcessor: 0x%x\tpProcessorInfo: 0x%x\t"
8708 + "uProcessorInfoSize: 0x%x\tpuNumProcs \n",
8709 + args->ARGS_MGR_ENUMPROC_INFO.uProcessor,
8710 + args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo,
8711 + args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize,
8712 + args->ARGS_MGR_ENUMPROC_INFO.puNumProcs);
8713 + pProcessorInfo = MEM_Alloc(size, MEM_NONPAGED);
8714 + if (pProcessorInfo == NULL)
8715 + status = DSP_EMEMORY;
8717 + if (DSP_SUCCEEDED(status)) {
8718 + status = MGR_EnumProcessorInfo(args->
8719 + ARGS_MGR_ENUMPROC_INFO.uProcessor,
8720 + (struct DSP_PROCESSORINFO *)pProcessorInfo,
8721 + size, &uNumProcs);
8723 + cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo, pProcessorInfo,
8724 + status, size);
8725 + cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.puNumProcs, &uNumProcs,
8726 + status, 1);
8727 + if (pProcessorInfo)
8728 + MEM_Free(pProcessorInfo);
8730 + return status;
8733 +#define WRAP_MAP2CALLER(x) x
8735 + * ======== MGRWRAP_RegisterObject ========
8736 + */
8737 +u32 MGRWRAP_RegisterObject(union Trapped_Args *args)
8739 + u32 retVal;
8741 + GT_1trace(WCD_debugMask, GT_ENTER,
8742 + "MGRWRAP_RegisterObject: entered pg2hMsg "
8743 + "0x%x\n", args->ARGS_MGR_REGISTEROBJECT.pUuid);
8744 + retVal = DCD_RegisterObject(WRAP_MAP2CALLER
8745 + (args->ARGS_MGR_REGISTEROBJECT.pUuid),
8746 + args->ARGS_MGR_REGISTEROBJECT.objType,
8747 + WRAP_MAP2CALLER(args->ARGS_MGR_REGISTEROBJECT.pszPathName));
8748 + return retVal;
8752 + * ======== MGRWRAP_UnregisterObject ========
8753 + */
8754 +u32 MGRWRAP_UnregisterObject(union Trapped_Args *args)
8756 + u32 retVal;
8758 + GT_1trace(WCD_debugMask, GT_ENTER,
8759 + "MGRWRAP_UnregisterObject: entered pg2hMsg"
8760 + " 0x%x\n", args->ARGS_MGR_UNREGISTEROBJECT.pUuid);
8761 + retVal = DCD_UnregisterObject(WRAP_MAP2CALLER
8762 + (args->ARGS_MGR_UNREGISTEROBJECT.pUuid),
8763 + args->ARGS_MGR_UNREGISTEROBJECT.objType);
8765 + return retVal;
8769 + * ======== MGRWRAP_WaitForBridgeEvents ========
8770 + */
8771 +u32 MGRWRAP_WaitForBridgeEvents(union Trapped_Args *args)
8773 + DSP_STATUS status = DSP_SOK;
8774 + struct DSP_NOTIFICATION *aNotifications[MAX_EVENTS];
8775 + struct DSP_NOTIFICATION notifications[MAX_EVENTS];
8776 + u32 uIndex, i;
8777 + u32 uCount = args->ARGS_MGR_WAIT.uCount;
8779 + GT_0trace(WCD_debugMask, GT_ENTER,
8780 + "MGRWRAP_WaitForBridgeEvents: entered\n");
8782 + if (uCount > MAX_EVENTS)
8783 + status = DSP_EINVALIDARG;
8785 + /* get the array of pointers to user structures */
8786 + cp_fm_usr(aNotifications, args->ARGS_MGR_WAIT.aNotifications,
8787 + status, uCount);
8788 + /* get the events */
8789 + for (i = 0; i < uCount; i++) {
8790 + cp_fm_usr(&notifications[i], aNotifications[i], status, 1);
8791 + if (DSP_SUCCEEDED(status)) {
8792 + /* set the array of pointers to kernel structures*/
8793 + aNotifications[i] = &notifications[i];
8796 + if (DSP_SUCCEEDED(status)) {
8797 + status = MGR_WaitForBridgeEvents(aNotifications, uCount,
8798 + &uIndex, args->ARGS_MGR_WAIT.uTimeout);
8800 + cp_to_usr(args->ARGS_MGR_WAIT.puIndex, &uIndex, status, 1);
8801 + return status;
8805 +#ifndef RES_CLEANUP_DISABLE
8807 + * ======== MGRWRAP_GetProcessResourceInfo ========
8808 + */
8809 +u32 MGRWRAP_GetProcessResourcesInfo(union Trapped_Args *args)
8811 + DSP_STATUS status = DSP_SOK;
8812 + u32 uSize = 0;
8813 + u8 *pBuf = MEM_Alloc(8092, MEM_NONPAGED);
8814 + status = DRV_ProcDisplayResInfo(pBuf, &uSize);
8815 + GT_1trace(WCD_debugMask, GT_ENTER,
8816 + "MGRWRAP_GetProcessResourcesInfo:uSize=%d :\n", uSize);
8817 + cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status, uSize);
8818 + GT_0trace(WCD_debugMask, GT_ENTER, "\n***********"
8819 + "123MGRWRAP_GetProcessResourcesInfo:**************\n");
8820 + GT_0trace(WCD_debugMask, GT_ENTER, "\n***********"
8821 + "456MGRWRAP_GetProcessResourcesInfo:**************\n");
8822 + cp_to_usr(args->ARGS_PROC_GETTRACE.pSize, &uSize, status, 1);
8823 + MEM_Free(pBuf);
8824 + return status;
8826 +#endif
8830 + * ======== PROCWRAP_Attach ========
8831 + */
8832 +u32 PROCWRAP_Attach(union Trapped_Args *args)
8834 + DSP_HPROCESSOR processor;
8835 + DSP_STATUS status = DSP_SOK;
8836 + struct DSP_PROCESSORATTRIN attrIn, *pAttrIn = NULL;
8838 + GT_3trace(WCD_debugMask, GT_ENTER,
8839 + "PROCWRAP_Attach: entered args:\n" "0x%x"
8840 + " uProcessor: 0x%x\tpAttrIn: 0x%x\tphProcessor \n",
8841 + args->ARGS_PROC_ATTACH.uProcessor,
8842 + args->ARGS_PROC_ATTACH.pAttrIn,
8843 + args->ARGS_PROC_ATTACH.phProcessor);
8844 + /* Optional argument */
8845 + if (args->ARGS_PROC_ATTACH.pAttrIn) {
8846 + cp_fm_usr(&attrIn, args->ARGS_PROC_ATTACH.pAttrIn, status, 1);
8847 + if (DSP_SUCCEEDED(status))
8848 + pAttrIn = &attrIn;
8851 + status = PROC_Attach(args->ARGS_PROC_ATTACH.uProcessor, pAttrIn,
8852 + &processor);
8853 + cp_to_usr(args->ARGS_PROC_ATTACH.phProcessor, &processor, status, 1);
8854 + return status;
8858 + * ======== PROCWRAP_Ctrl ========
8859 + */
8860 +u32 PROCWRAP_Ctrl(union Trapped_Args *args)
8862 + u32 cbDataSize, *pSize = (u32 *)args->ARGS_PROC_CTRL.pArgs;
8863 + u8 *pArgs = NULL;
8864 + DSP_STATUS status = DSP_SOK;
8866 + GT_3trace(WCD_debugMask, GT_ENTER,
8867 + "PROCWRAP_Ctrl: entered args:\n 0x%x"
8868 + " uProcessor: 0x%x\tdwCmd: 0x%x\tpArgs \n",
8869 + args->ARGS_PROC_CTRL.hProcessor,
8870 + args->ARGS_PROC_CTRL.dwCmd,
8871 + args->ARGS_PROC_CTRL.pArgs);
8872 + if (pSize) {
8873 + if (get_user(cbDataSize, pSize))
8874 + status = DSP_EFAIL;
8876 + cbDataSize += sizeof(u32);
8877 + if (DSP_SUCCEEDED(status)) {
8878 + pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
8879 + if (pArgs == NULL)
8880 + status = DSP_EMEMORY;
8883 + cp_fm_usr(pArgs, args->ARGS_PROC_CTRL.pArgs, status,
8884 + cbDataSize);
8886 + if (DSP_SUCCEEDED(status)) {
8887 + status = PROC_Ctrl(args->ARGS_PROC_CTRL.hProcessor,
8888 + args->ARGS_PROC_CTRL.dwCmd,
8889 + (struct DSP_CBDATA *)pArgs);
8892 + /* cp_to_usr(args->ARGS_PROC_CTRL.pArgs, pArgs, status, 1);*/
8893 + if (pArgs)
8894 + MEM_Free(pArgs);
8896 + return status;
8900 + * ======== PROCWRAP_Detach ========
8901 + */
8902 +u32 PROCWRAP_Detach(union Trapped_Args *args)
8904 + u32 retVal;
8906 + GT_1trace(WCD_debugMask, GT_ENTER,
8907 + "PROCWRAP_Detach: entered args\n0x%x "
8908 + "hProceesor \n", args->ARGS_PROC_DETACH.hProcessor);
8909 + retVal = PROC_Detach(args->ARGS_PROC_DETACH.hProcessor);
8911 + return retVal;
8915 + * ======== PROCWRAP_EnumNode_Info ========
8916 + */
8917 +u32 PROCWRAP_EnumNode_Info(union Trapped_Args *args)
8919 + DSP_STATUS status;
8920 + DSP_HNODE aNodeTab[MAX_NODES];
8921 + u32 uNumNodes;
8922 + u32 uAllocated;
8924 + GT_5trace(WCD_debugMask, GT_ENTER,
8925 + "PROCWRAP_EnumNode_Info:entered args:\n0x"
8926 + "%xhProcessor:0x%x\taNodeTab:0x%x\tuNodeTabSize:"
8927 + "%0x%x\tpuNumNodes%\n0x%x puAllocated: \n",
8928 + args->ARGS_PROC_ENUMNODE_INFO.hProcessor,
8929 + args->ARGS_PROC_ENUMNODE_INFO.aNodeTab,
8930 + args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize,
8931 + args->ARGS_PROC_ENUMNODE_INFO.puNumNodes,
8932 + args->ARGS_PROC_ENUMNODE_INFO.puAllocated);
8933 + DBC_Require(args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize <= MAX_NODES);
8934 + status = PROC_EnumNodes(args->ARGS_PROC_ENUMNODE_INFO.hProcessor,
8935 + aNodeTab,
8936 + args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize,
8937 + &uNumNodes, &uAllocated);
8938 + cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.aNodeTab, aNodeTab, status,
8939 + uNumNodes);
8940 + cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puNumNodes, &uNumNodes,
8941 + status, 1);
8942 + cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puAllocated, &uAllocated,
8943 + status, 1);
8944 + return status;
8948 + * ======== PROCWRAP_FlushMemory ========
8949 + */
8950 +u32 PROCWRAP_FlushMemory(union Trapped_Args *args)
8952 + DSP_STATUS status;
8954 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_FlushMemory: entered\n");
8956 + status = PROC_FlushMemory(args->ARGS_PROC_FLUSHMEMORY.hProcessor,
8957 + args->ARGS_PROC_FLUSHMEMORY.pMpuAddr,
8958 + args->ARGS_PROC_FLUSHMEMORY.ulSize,
8959 + args->ARGS_PROC_FLUSHMEMORY.ulFlags);
8960 + return status;
8965 + * ======== PROCWRAP_InvalidateMemory ========
8966 + */
8967 +u32 PROCWRAP_InvalidateMemory(union Trapped_Args *args)
8969 + DSP_STATUS status;
8971 + GT_0trace(WCD_debugMask, GT_ENTER,
8972 + "PROCWRAP_InvalidateMemory:entered\n");
8974 + status = PROC_InvalidateMemory(
8975 + args->ARGS_PROC_INVALIDATEMEMORY.hProcessor,
8976 + args->ARGS_PROC_INVALIDATEMEMORY.pMpuAddr,
8977 + args->ARGS_PROC_INVALIDATEMEMORY.ulSize);
8978 + return status;
8983 + * ======== PROCWRAP_EnumResources ========
8984 + */
8985 +u32 PROCWRAP_EnumResources(union Trapped_Args *args)
8987 + u32 retVal;
8989 + GT_4trace(WCD_debugMask, GT_ENTER,
8990 + "PROCWRAP_EnumResources: entered args:\n"
8991 + "0x%x hProcessor: 0x%x\tuResourceMask: 0x%x\tpResourceInfo"
8992 + " 0x%x\tuResourceInfoSixe \n",
8993 + args->ARGS_PROC_ENUMRESOURCES.hProcessor,
8994 + args->ARGS_PROC_ENUMRESOURCES.uResourceType,
8995 + args->ARGS_PROC_ENUMRESOURCES.pResourceInfo,
8996 + args->ARGS_PROC_ENUMRESOURCES.uResourceInfoSize);
8997 + retVal = PROC_GetResourceInfo(args->ARGS_PROC_ENUMRESOURCES.hProcessor,
8998 + args->ARGS_PROC_ENUMRESOURCES.uResourceType,
8999 + WRAP_MAP2CALLER(args->ARGS_PROC_ENUMRESOURCES.
9000 + pResourceInfo), args->ARGS_PROC_ENUMRESOURCES.
9001 + uResourceInfoSize);
9003 + return retVal;
9007 + * ======== PROCWRAP_GetState ========
9008 + */
9009 +u32 PROCWRAP_GetState(union Trapped_Args *args)
9011 + DSP_STATUS status;
9012 + struct DSP_PROCESSORSTATE procStatus;
9013 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetState: entered\n");
9014 + status = PROC_GetState(args->ARGS_PROC_GETSTATE.hProcessor, &procStatus,
9015 + args->ARGS_PROC_GETSTATE.uStateInfoSize);
9016 + cp_to_usr(args->ARGS_PROC_GETSTATE.pProcStatus, &procStatus, status, 1);
9017 + return status;
9022 + * ======== PROCWRAP_GetTrace ========
9023 + */
9024 +u32 PROCWRAP_GetTrace(union Trapped_Args *args)
9026 + DSP_STATUS status;
9027 + u8 *pBuf;
9029 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetTrace: entered\n");
9031 + DBC_Require(args->ARGS_PROC_GETTRACE.uMaxSize <= MAX_TRACEBUFLEN);
9033 + pBuf = MEM_Calloc(args->ARGS_PROC_GETTRACE.uMaxSize, MEM_NONPAGED);
9034 + if (pBuf != NULL) {
9035 + status = PROC_GetTrace(args->ARGS_PROC_GETTRACE.hProcessor,
9036 + pBuf, args->ARGS_PROC_GETTRACE.uMaxSize);
9037 + } else {
9038 + status = DSP_EMEMORY;
9040 + cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status,
9041 + args->ARGS_PROC_GETTRACE.uMaxSize);
9042 + if (pBuf)
9043 + MEM_Free(pBuf);
9045 + return status;
9049 + * ======== PROCWRAP_Load ========
9050 + */
9051 +u32 PROCWRAP_Load(union Trapped_Args *args)
9053 + s32 i, len;
9054 + DSP_STATUS status = DSP_SOK;
9055 + u8 *temp;
9056 + s32 argc = args->ARGS_PROC_LOAD.iArgc;
9057 + u8 **argv, **envp = NULL;
9059 + DBC_Require(argc > 0);
9060 + DBC_Require(argc <= MAX_LOADARGS);
9062 + argv = MEM_Alloc(argc * sizeof(u8 *), MEM_NONPAGED);
9063 + if (argv == NULL)
9064 + status = DSP_EMEMORY;
9066 + cp_fm_usr(argv, args->ARGS_PROC_LOAD.aArgv, status, argc);
9067 + for (i = 0; DSP_SUCCEEDED(status) && (i < argc); i++) {
9068 + if (argv[i] != NULL) {
9069 + temp = argv[i]; /* User space pointer to argument */
9070 + len = strlen_user((char *)temp);
9071 + /* Kernel space pointer to argument */
9072 + argv[i] = MEM_Alloc(len, MEM_NONPAGED);
9073 + if (argv[i] == NULL) {
9074 + status = DSP_EMEMORY;
9075 + break;
9077 + cp_fm_usr(argv[i], temp, status, len);
9080 + /* TODO: validate this */
9081 + if (args->ARGS_PROC_LOAD.aEnvp != NULL) {
9082 + /* number of elements in the envp array including NULL */
9083 + len = 0;
9084 + do {
9085 + len++;
9086 + get_user(temp, args->ARGS_PROC_LOAD.aEnvp);
9087 + } while (temp);
9088 + envp = MEM_Alloc(len * sizeof(u8 *), MEM_NONPAGED);
9089 + if (envp == NULL)
9090 + status = DSP_EMEMORY;
9092 + cp_fm_usr(envp, args->ARGS_PROC_LOAD.aEnvp, status, len);
9093 + for (i = 0; DSP_SUCCEEDED(status) && (envp[i] != NULL); i++) {
9094 + temp = envp[i]; /* User space pointer to argument */
9095 + len = strlen_user((char *)temp);
9096 + /* Kernel space pointer to argument */
9097 + envp[i] = MEM_Alloc(len, MEM_NONPAGED);
9098 + if (envp[i] == NULL) {
9099 + status = DSP_EMEMORY;
9100 + break;
9102 + cp_fm_usr(envp[i], temp, status, len);
9105 + GT_5trace(WCD_debugMask, GT_ENTER,
9106 + "PROCWRAP_Load, hProcessor: 0x%x\n\tiArgc:"
9107 + "0x%x\n\taArgv: 0x%x\n\taArgv[0]: %s\n\taEnvp: 0x%0x\n",
9108 + args->ARGS_PROC_LOAD.hProcessor,
9109 + args->ARGS_PROC_LOAD.iArgc, args->ARGS_PROC_LOAD.aArgv,
9110 + argv[0], args->ARGS_PROC_LOAD.aEnvp);
9111 + if (DSP_SUCCEEDED(status)) {
9112 + status = PROC_Load(args->ARGS_PROC_LOAD.hProcessor,
9113 + args->ARGS_PROC_LOAD.iArgc,
9114 + (CONST char **)argv, (CONST char **)envp);
9116 + if (envp != NULL) {
9117 + i = 0;
9118 + while (envp[i] != NULL)
9119 + MEM_Free(envp[i++]);
9121 + MEM_Free(envp);
9123 + if (argv != NULL) {
9124 + for (i = 0; i < argc; i++) {
9125 + if (argv[i] != NULL)
9126 + MEM_Free(argv[i]);
9129 + MEM_Free(argv);
9131 + return status;
9135 + * ======== PROCWRAP_Map ========
9136 + */
9137 +u32 PROCWRAP_Map(union Trapped_Args *args)
9139 + DSP_STATUS status;
9140 + void *pMapAddr;
9142 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Map: entered\n");
9143 + status = PROC_Map(args->ARGS_PROC_MAPMEM.hProcessor,
9144 + args->ARGS_PROC_MAPMEM.pMpuAddr,
9145 + args->ARGS_PROC_MAPMEM.ulSize,
9146 + args->ARGS_PROC_MAPMEM.pReqAddr, &pMapAddr,
9147 + args->ARGS_PROC_MAPMEM.ulMapAttr);
9148 + if (DSP_SUCCEEDED(status)) {
9149 + if (put_user(pMapAddr, args->ARGS_PROC_MAPMEM.ppMapAddr))
9150 + status = DSP_EINVALIDARG;
9153 + return status;
9157 + * ======== PROCWRAP_RegisterNotify ========
9158 + */
9159 +u32 PROCWRAP_RegisterNotify(union Trapped_Args *args)
9161 + DSP_STATUS status;
9162 + struct DSP_NOTIFICATION notification;
9164 + GT_0trace(WCD_debugMask, GT_ENTER,
9165 + "PROCWRAP_RegisterNotify: entered\n");
9167 + /* Initialize the notification data structure */
9168 + notification.psName = NULL;
9169 + notification.handle = NULL;
9171 + status = PROC_RegisterNotify(args->ARGS_PROC_REGISTER_NOTIFY.hProcessor,
9172 + args->ARGS_PROC_REGISTER_NOTIFY.uEventMask,
9173 + args->ARGS_PROC_REGISTER_NOTIFY.uNotifyType,
9174 + &notification);
9175 + cp_to_usr(args->ARGS_PROC_REGISTER_NOTIFY.hNotification, &notification,
9176 + status, 1);
9177 + return status;
9181 + * ======== PROCWRAP_ReserveMemory ========
9182 + */
9183 +u32 PROCWRAP_ReserveMemory(union Trapped_Args *args)
9185 + DSP_STATUS status;
9186 + void *pRsvAddr;
9188 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_ReserveMemory: entered\n");
9189 + status = PROC_ReserveMemory(args->ARGS_PROC_RSVMEM.hProcessor,
9190 + args->ARGS_PROC_RSVMEM.ulSize, &pRsvAddr);
9191 + if (put_user(pRsvAddr, args->ARGS_PROC_RSVMEM.ppRsvAddr))
9192 + status = DSP_EINVALIDARG;
9194 + return status;
9198 + * ======== PROCWRAP_Start ========
9199 + */
9200 +u32 PROCWRAP_Start(union Trapped_Args *args)
9202 + u32 retVal;
9204 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Start: entered\n");
9205 + retVal = PROC_Start(args->ARGS_PROC_START.hProcessor);
9206 + return retVal;
9210 + * ======== PROCWRAP_UnMap ========
9211 + */
9212 +u32 PROCWRAP_UnMap(union Trapped_Args *args)
9214 + DSP_STATUS status;
9216 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_UnMap: entered\n");
9217 + status = PROC_UnMap(args->ARGS_PROC_UNMAPMEM.hProcessor,
9218 + args->ARGS_PROC_UNMAPMEM.pMapAddr);
9219 + return status;
9223 + * ======== PROCWRAP_UnReserveMemory ========
9224 + */
9225 +u32 PROCWRAP_UnReserveMemory(union Trapped_Args *args)
9227 + DSP_STATUS status;
9229 + GT_0trace(WCD_debugMask, GT_ENTER,
9230 + "PROCWRAP_UnReserveMemory: entered\n");
9231 + status = PROC_UnReserveMemory(args->ARGS_PROC_UNRSVMEM.hProcessor,
9232 + args->ARGS_PROC_UNRSVMEM.pRsvAddr);
9233 + return status;
9237 + * ======== PROCWRAP_Stop ========
9238 + */
9239 +u32 PROCWRAP_Stop(union Trapped_Args *args)
9241 + u32 retVal;
9243 + GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Stop: entered\n");
9244 + retVal = PROC_Stop(args->ARGS_PROC_STOP.hProcessor);
9246 + return retVal;
9250 + * ======== NODEWRAP_Allocate ========
9251 + */
9252 +u32 NODEWRAP_Allocate(union Trapped_Args *args)
9254 + DSP_STATUS status = DSP_SOK;
9255 + struct DSP_UUID nodeId;
9256 + u32 cbDataSize;
9257 + u32 *pSize = (u32 *)args->ARGS_NODE_ALLOCATE.pArgs;
9258 + u8 *pArgs = NULL;
9259 + struct DSP_NODEATTRIN attrIn, *pAttrIn = NULL;
9260 + struct NODE_OBJECT *hNode;
9262 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Allocate: entered\n");
9264 + /* Optional argument */
9265 + if (pSize) {
9266 + if (get_user(cbDataSize, pSize))
9267 + status = DSP_EFAIL;
9269 + cbDataSize += sizeof(u32);
9270 + if (DSP_SUCCEEDED(status)) {
9271 + pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
9272 + if (pArgs == NULL)
9273 + status = DSP_EMEMORY;
9276 + cp_fm_usr(pArgs, args->ARGS_NODE_ALLOCATE.pArgs, status,
9277 + cbDataSize);
9279 + cp_fm_usr(&nodeId, args->ARGS_NODE_ALLOCATE.pNodeID, status, 1);
9280 + /* Optional argument */
9281 + if (args->ARGS_NODE_ALLOCATE.pAttrIn) {
9282 + cp_fm_usr(&attrIn, args->ARGS_NODE_ALLOCATE.pAttrIn, status, 1);
9283 + if (DSP_SUCCEEDED(status))
9284 + pAttrIn = &attrIn;
9287 + if (DSP_SUCCEEDED(status)) {
9288 + status = NODE_Allocate(args->ARGS_NODE_ALLOCATE.hProcessor,
9289 + &nodeId, (struct DSP_CBDATA *)pArgs,
9290 + pAttrIn, &hNode);
9292 + cp_to_usr(args->ARGS_NODE_ALLOCATE.phNode, &hNode, status, 1);
9293 + if (pArgs)
9294 + MEM_Free(pArgs);
9296 + return status;
9300 + * ======== NODEWRAP_AllocMsgBuf ========
9301 + */
9302 +u32 NODEWRAP_AllocMsgBuf(union Trapped_Args *args)
9304 + DSP_STATUS status = DSP_SOK;
9305 + struct DSP_BUFFERATTR *pAttr = NULL;
9306 + struct DSP_BUFFERATTR attr;
9307 + u8 *pBuffer = NULL;
9309 + if (args->ARGS_NODE_ALLOCMSGBUF.pAttr) { /* Optional argument */
9310 + cp_fm_usr(&attr, args->ARGS_NODE_ALLOCMSGBUF.pAttr, status, 1);
9311 + if (DSP_SUCCEEDED(status))
9312 + pAttr = &attr;
9315 + /* IN OUT argument */
9316 + cp_fm_usr(&pBuffer, args->ARGS_NODE_ALLOCMSGBUF.pBuffer, status, 1);
9317 + if (DSP_SUCCEEDED(status)) {
9318 + status = NODE_AllocMsgBuf(args->ARGS_NODE_ALLOCMSGBUF.hNode,
9319 + args->ARGS_NODE_ALLOCMSGBUF.uSize,
9320 + pAttr, &pBuffer);
9322 + cp_to_usr(args->ARGS_NODE_ALLOCMSGBUF.pBuffer, &pBuffer, status, 1)
9323 + return status;
9327 + * ======== NODEWRAP_ChangePriority ========
9328 + */
9329 +u32 NODEWRAP_ChangePriority(union Trapped_Args *args)
9331 + u32 retVal;
9333 + GT_0trace(WCD_debugMask, GT_ENTER,
9334 + "NODEWRAP_ChangePriority: entered\n");
9335 + retVal = NODE_ChangePriority(args->ARGS_NODE_CHANGEPRIORITY.hNode,
9336 + args->ARGS_NODE_CHANGEPRIORITY.iPriority);
9338 + return retVal;
9342 + * ======== NODEWRAP_Connect ========
9343 + */
9344 +u32 NODEWRAP_Connect(union Trapped_Args *args)
9346 + DSP_STATUS status = DSP_SOK;
9347 + struct DSP_STRMATTR attrs;
9348 + struct DSP_STRMATTR *pAttrs = NULL;
9349 + u32 cbDataSize;
9350 + u32 *pSize = (u32 *)args->ARGS_NODE_CONNECT.pConnParam;
9351 + u8 *pArgs = NULL;
9353 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Connect: entered\n");
9355 + /* Optional argument */
9356 + if (pSize) {
9357 + if (get_user(cbDataSize, pSize))
9358 + status = DSP_EFAIL;
9360 + cbDataSize += sizeof(u32);
9361 + if (DSP_SUCCEEDED(status)) {
9362 + pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
9363 + if (pArgs == NULL)
9364 + status = DSP_EMEMORY;
9367 + cp_fm_usr(pArgs, args->ARGS_NODE_CONNECT.pConnParam, status,
9368 + cbDataSize);
9370 + if (args->ARGS_NODE_CONNECT.pAttrs) { /* Optional argument */
9371 + cp_fm_usr(&attrs, args->ARGS_NODE_CONNECT.pAttrs, status, 1);
9372 + if (DSP_SUCCEEDED(status))
9373 + pAttrs = &attrs;
9376 + if (DSP_SUCCEEDED(status)) {
9377 + status = NODE_Connect(args->ARGS_NODE_CONNECT.hNode,
9378 + args->ARGS_NODE_CONNECT.uStream,
9379 + args->ARGS_NODE_CONNECT.hOtherNode,
9380 + args->ARGS_NODE_CONNECT.uOtherStream,
9381 + pAttrs, (struct DSP_CBDATA *)pArgs);
9383 + if (pArgs)
9384 + MEM_Free(pArgs);
9386 + return status;
9390 + * ======== NODEWRAP_Create ========
9391 + */
9392 +u32 NODEWRAP_Create(union Trapped_Args *args)
9394 + u32 retVal;
9396 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Create: entered\n");
9397 + retVal = NODE_Create(args->ARGS_NODE_CREATE.hNode);
9399 + return retVal;
9403 + * ======== NODEWRAP_Delete ========
9404 + */
9405 +u32 NODEWRAP_Delete(union Trapped_Args *args)
9407 + u32 retVal;
9409 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Delete: entered\n");
9410 + retVal = NODE_Delete(args->ARGS_NODE_DELETE.hNode);
9412 + return retVal;
9416 + * ======== NODEWRAP_FreeMsgBuf ========
9417 + */
9418 +u32 NODEWRAP_FreeMsgBuf(union Trapped_Args *args)
9420 + DSP_STATUS status = DSP_SOK;
9421 + struct DSP_BUFFERATTR *pAttr = NULL;
9422 + struct DSP_BUFFERATTR attr;
9423 + if (args->ARGS_NODE_FREEMSGBUF.pAttr) { /* Optional argument */
9424 + cp_fm_usr(&attr, args->ARGS_NODE_FREEMSGBUF.pAttr, status, 1);
9425 + if (DSP_SUCCEEDED(status))
9426 + pAttr = &attr;
9429 + if (DSP_SUCCEEDED(status)) {
9430 + status = NODE_FreeMsgBuf(args->ARGS_NODE_FREEMSGBUF.hNode,
9431 + args->ARGS_NODE_FREEMSGBUF.pBuffer,
9432 + pAttr);
9435 + return status;
9439 + * ======== NODEWRAP_GetAttr ========
9440 + */
9441 +u32 NODEWRAP_GetAttr(union Trapped_Args *args)
9443 + DSP_STATUS status = DSP_SOK;
9444 + struct DSP_NODEATTR attr;
9446 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetAttr: entered\n");
9448 + status = NODE_GetAttr(args->ARGS_NODE_GETATTR.hNode, &attr,
9449 + args->ARGS_NODE_GETATTR.uAttrSize);
9450 + cp_to_usr(args->ARGS_NODE_GETATTR.pAttr, &attr, status, 1);
9452 + return status;
9456 + * ======== NODEWRAP_GetMessage ========
9457 + */
9458 +u32 NODEWRAP_GetMessage(union Trapped_Args *args)
9460 + DSP_STATUS status;
9461 + struct DSP_MSG msg;
9463 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetMessage: entered\n");
9465 + status = NODE_GetMessage(args->ARGS_NODE_GETMESSAGE.hNode, &msg,
9466 + args->ARGS_NODE_GETMESSAGE.uTimeout);
9468 + cp_to_usr(args->ARGS_NODE_GETMESSAGE.pMessage, &msg, status, 1);
9470 + return status;
9474 + * ======== NODEWRAP_Pause ========
9475 + */
9476 +u32 NODEWRAP_Pause(union Trapped_Args *args)
9478 + u32 retVal;
9480 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Pause: entered\n");
9481 + retVal = NODE_Pause(args->ARGS_NODE_PAUSE.hNode);
9483 + return retVal;
9487 + * ======== NODEWRAP_PutMessage ========
9488 + */
9489 +u32 NODEWRAP_PutMessage(union Trapped_Args *args)
9491 + DSP_STATUS status = DSP_SOK;
9492 + struct DSP_MSG msg;
9494 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_PutMessage: entered\n");
9496 + cp_fm_usr(&msg, args->ARGS_NODE_PUTMESSAGE.pMessage, status, 1);
9498 + if (DSP_SUCCEEDED(status)) {
9499 + status = NODE_PutMessage(args->ARGS_NODE_PUTMESSAGE.hNode, &msg,
9500 + args->ARGS_NODE_PUTMESSAGE.uTimeout);
9503 + return status;
9507 + * ======== NODEWRAP_RegisterNotify ========
9508 + */
9509 +u32 NODEWRAP_RegisterNotify(union Trapped_Args *args)
9511 + DSP_STATUS status = DSP_SOK;
9512 + struct DSP_NOTIFICATION notification;
9514 + GT_0trace(WCD_debugMask, GT_ENTER,
9515 + "NODEWRAP_RegisterNotify: entered\n");
9517 + /* Initialize the notification data structure */
9518 + notification.psName = NULL;
9519 + notification.handle = NULL;
9521 + status = NODE_RegisterNotify(args->ARGS_NODE_REGISTERNOTIFY.hNode,
9522 + args->ARGS_NODE_REGISTERNOTIFY.uEventMask,
9523 + args->ARGS_NODE_REGISTERNOTIFY.uNotifyType,
9524 + &notification);
9525 + cp_to_usr(args->ARGS_NODE_REGISTERNOTIFY.hNotification, &notification,
9526 + status, 1);
9527 + return status;
9531 + * ======== NODEWRAP_Run ========
9532 + */
9533 +u32 NODEWRAP_Run(union Trapped_Args *args)
9535 + u32 retVal;
9537 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Run: entered\n");
9538 + retVal = NODE_Run(args->ARGS_NODE_RUN.hNode);
9540 + return retVal;
9544 + * ======== NODEWRAP_Terminate ========
9545 + */
9546 +u32 NODEWRAP_Terminate(union Trapped_Args *args)
9548 + DSP_STATUS status;
9549 + DSP_STATUS tempstatus;
9551 + GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Terminate: entered\n");
9553 + status = NODE_Terminate(args->ARGS_NODE_TERMINATE.hNode, &tempstatus);
9555 + cp_to_usr(args->ARGS_NODE_TERMINATE.pStatus, &tempstatus, status, 1);
9557 + return status;
9562 + * ======== NODEWRAP_GetUUIDProps ========
9563 + */
9564 +u32 NODEWRAP_GetUUIDProps(union Trapped_Args *args)
9566 + DSP_STATUS status = DSP_SOK;
9567 + struct DSP_UUID nodeId;
9568 + struct DSP_NDBPROPS *pnodeProps = NULL;
9570 + GT_0trace(WCD_debugMask, GT_ENTER,
9571 + "NODEWRAP_GetUUIDPropste: entered\n");
9574 + cp_fm_usr(&nodeId, args->ARGS_NODE_GETUUIDPROPS.pNodeID, status, 1);
9575 + pnodeProps = MEM_Alloc(sizeof(struct DSP_NDBPROPS), MEM_NONPAGED);
9576 + if (pnodeProps != NULL) {
9577 + status = NODE_GetUUIDProps(args->
9578 + ARGS_NODE_GETUUIDPROPS.hProcessor,
9579 + &nodeId, pnodeProps);
9580 + cp_to_usr(args->ARGS_NODE_GETUUIDPROPS.pNodeProps, pnodeProps,
9581 + status, 1);
9582 + } else
9583 + status = DSP_EMEMORY;
9584 + if (pnodeProps)
9585 + MEM_Free(pnodeProps);
9586 + return status;
9590 + * ======== STRMWRAP_AllocateBuffer ========
9591 + */
9592 +u32 STRMWRAP_AllocateBuffer(union Trapped_Args *args)
9594 + DSP_STATUS status;
9595 + u8 **apBuffer = NULL;
9596 + u32 uNumBufs = args->ARGS_STRM_ALLOCATEBUFFER.uNumBufs;
9598 + DBC_Require(uNumBufs <= MAX_BUFS);
9600 + apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED);
9602 + status = STRM_AllocateBuffer(args->ARGS_STRM_ALLOCATEBUFFER.hStream,
9603 + args->ARGS_STRM_ALLOCATEBUFFER.uSize,
9604 + apBuffer, uNumBufs);
9605 + cp_to_usr(args->ARGS_STRM_ALLOCATEBUFFER.apBuffer, apBuffer, status,
9606 + uNumBufs);
9607 + if (apBuffer)
9608 + MEM_Free(apBuffer);
9610 + return status;
9614 + * ======== STRMWRAP_Close ========
9615 + */
9616 +u32 STRMWRAP_Close(union Trapped_Args *args)
9618 + u32 retVal;
9620 + retVal = STRM_Close(args->ARGS_STRM_CLOSE.hStream);
9622 + return retVal;
9626 + * ======== STRMWRAP_FreeBuffer ========
9627 + */
9628 +u32 STRMWRAP_FreeBuffer(union Trapped_Args *args)
9630 + DSP_STATUS status = DSP_SOK;
9631 + u8 **apBuffer = NULL;
9632 + u32 uNumBufs = args->ARGS_STRM_FREEBUFFER.uNumBufs;
9634 + DBC_Require(uNumBufs <= MAX_BUFS);
9636 + apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED);
9638 + cp_fm_usr(apBuffer, args->ARGS_STRM_FREEBUFFER.apBuffer, status,
9639 + uNumBufs);
9641 + if (DSP_SUCCEEDED(status)) {
9642 + status = STRM_FreeBuffer(args->ARGS_STRM_FREEBUFFER.hStream,
9643 + apBuffer, uNumBufs);
9645 + cp_to_usr(args->ARGS_STRM_FREEBUFFER.apBuffer, apBuffer, status,
9646 + uNumBufs);
9647 + if (apBuffer)
9648 + MEM_Free(apBuffer);
9650 + return status;
9654 + * ======== STRMWRAP_GetEventHandle ========
9655 + */
9656 +u32 STRMWRAP_GetEventHandle(union Trapped_Args *args)
9658 + return DSP_ENOTIMPL;
9662 + * ======== STRMWRAP_GetInfo ========
9663 + */
9664 +u32 STRMWRAP_GetInfo(union Trapped_Args *args)
9666 + DSP_STATUS status = DSP_SOK;
9667 + struct STRM_INFO strmInfo;
9668 + struct DSP_STREAMINFO user;
9669 + struct DSP_STREAMINFO *temp;
9671 + cp_fm_usr(&strmInfo, args->ARGS_STRM_GETINFO.pStreamInfo, status, 1);
9672 + temp = strmInfo.pUser;
9674 + strmInfo.pUser = &user;
9676 + if (DSP_SUCCEEDED(status)) {
9677 + status = STRM_GetInfo(args->ARGS_STRM_GETINFO.hStream,
9678 + &strmInfo, args->ARGS_STRM_GETINFO.uStreamInfoSize);
9680 + cp_to_usr(temp, strmInfo.pUser, status, 1);
9681 + strmInfo.pUser = temp;
9682 + cp_to_usr(args->ARGS_STRM_GETINFO.pStreamInfo, &strmInfo, status, 1);
9683 + return status;
9687 + * ======== STRMWRAP_Idle ========
9688 + */
9689 +u32 STRMWRAP_Idle(union Trapped_Args *args)
9691 + u32 retVal;
9693 + retVal = STRM_Idle(args->ARGS_STRM_IDLE.hStream,
9694 + args->ARGS_STRM_IDLE.bFlush);
9696 + return retVal;
9700 + * ======== STRMWRAP_Issue ========
9701 + */
9702 +u32 STRMWRAP_Issue(union Trapped_Args *args)
9704 + u32 retVal;
9706 + retVal = STRM_Issue(args->ARGS_STRM_ISSUE.hStream,
9707 + args->ARGS_STRM_ISSUE.pBuffer,
9708 + args->ARGS_STRM_ISSUE.dwBytes,
9709 + args->ARGS_STRM_ISSUE.dwBufSize,
9710 + args->ARGS_STRM_ISSUE.dwArg);
9712 + /* This is a user space pointer */
9713 + return retVal;
9717 + * ======== STRMWRAP_Open ========
9718 + */
9719 +u32 STRMWRAP_Open(union Trapped_Args *args)
9721 + DSP_STATUS status = DSP_SOK;
9722 + struct STRM_ATTR attr;
9723 + struct STRM_OBJECT *pStrm;
9724 + struct DSP_STREAMATTRIN strmAttrIn;
9726 + cp_fm_usr(&attr, args->ARGS_STRM_OPEN.pAttrIn, status, 1);
9728 + if (attr.pStreamAttrIn != NULL) { /* Optional argument */
9729 + cp_fm_usr(&strmAttrIn, attr.pStreamAttrIn, status, 1);
9730 + if (DSP_SUCCEEDED(status))
9731 + attr.pStreamAttrIn = &strmAttrIn;
9734 + status = STRM_Open(args->ARGS_STRM_OPEN.hNode,
9735 + args->ARGS_STRM_OPEN.uDirection,
9736 + args->ARGS_STRM_OPEN.uIndex, &attr, &pStrm);
9737 + cp_to_usr(args->ARGS_STRM_OPEN.phStream, &pStrm, status, 1);
9738 + return status;
9742 + * ======== STRMWRAP_Reclaim ========
9743 + */
9744 +u32 STRMWRAP_Reclaim(union Trapped_Args *args)
9746 + DSP_STATUS status = DSP_SOK;
9747 + u8 *pBufPtr;
9748 + u32 ulBytes;
9749 + u32 dwArg;
9750 + u32 ulBufSize;
9752 + status = STRM_Reclaim(args->ARGS_STRM_RECLAIM.hStream, &pBufPtr,
9753 + &ulBytes, &ulBufSize, &dwArg);
9754 + cp_to_usr(args->ARGS_STRM_RECLAIM.pBufPtr, &pBufPtr, status, 1);
9755 + cp_to_usr(args->ARGS_STRM_RECLAIM.pBytes, &ulBytes, status, 1);
9756 + cp_to_usr(args->ARGS_STRM_RECLAIM.pdwArg, &dwArg, status, 1);
9758 + if (args->ARGS_STRM_RECLAIM.pBufSize != NULL) {
9759 + cp_to_usr(args->ARGS_STRM_RECLAIM.pBufSize, &ulBufSize,
9760 + status, 1);
9763 + return status;
9767 + * ======== STRMWRAP_RegisterNotify ========
9768 + */
9769 +u32 STRMWRAP_RegisterNotify(union Trapped_Args *args)
9771 + DSP_STATUS status = DSP_SOK;
9772 + struct DSP_NOTIFICATION notification;
9774 + GT_0trace(WCD_debugMask, GT_ENTER,
9775 + "NODEWRAP_RegisterNotify: entered\n");
9777 + /* Initialize the notification data structure */
9778 + notification.psName = NULL;
9779 + notification.handle = NULL;
9781 + status = STRM_RegisterNotify(args->ARGS_STRM_REGISTERNOTIFY.hStream,
9782 + args->ARGS_STRM_REGISTERNOTIFY.uEventMask,
9783 + args->ARGS_STRM_REGISTERNOTIFY.uNotifyType,
9784 + &notification);
9785 + cp_to_usr(args->ARGS_STRM_REGISTERNOTIFY.hNotification, &notification,
9786 + status, 1);
9788 + return status;
9792 + * ======== STRMWRAP_Select ========
9793 + */
9794 +u32 STRMWRAP_Select(union Trapped_Args *args)
9796 + u32 mask;
9797 + struct STRM_OBJECT *aStrmTab[MAX_STREAMS];
9798 + DSP_STATUS status = DSP_SOK;
9800 + DBC_Require(args->ARGS_STRM_SELECT.nStreams <= MAX_STREAMS);
9802 + cp_fm_usr(aStrmTab, args->ARGS_STRM_SELECT.aStreamTab, status,
9803 + args->ARGS_STRM_SELECT.nStreams);
9804 + if (DSP_SUCCEEDED(status)) {
9805 + status = STRM_Select(aStrmTab, args->ARGS_STRM_SELECT.nStreams,
9806 + &mask, args->ARGS_STRM_SELECT.uTimeout);
9808 + cp_to_usr(args->ARGS_STRM_SELECT.pMask, &mask, status, 1);
9809 + return status;
9812 +/* CMM */
9815 + * ======== CMMWRAP_CallocBuf ========
9816 + */
9817 +u32 CMMWRAP_CallocBuf(union Trapped_Args *args)
9819 + /* This operation is done in kernel */
9820 + return DSP_ENOTIMPL;
9824 + * ======== CMMWRAP_FreeBuf ========
9825 + */
9826 +u32 CMMWRAP_FreeBuf(union Trapped_Args *args)
9828 + /* This operation is done in kernel */
9829 + return DSP_ENOTIMPL;
9833 + * ======== CMMWRAP_GetHandle ========
9834 + */
9835 +u32 CMMWRAP_GetHandle(union Trapped_Args *args)
9837 + DSP_STATUS status = DSP_SOK;
9838 + struct CMM_OBJECT *hCmmMgr;
9840 + status = CMM_GetHandle(args->ARGS_CMM_GETHANDLE.hProcessor, &hCmmMgr);
9842 + cp_to_usr(args->ARGS_CMM_GETHANDLE.phCmmMgr, &hCmmMgr, status, 1);
9844 + return status;
9848 + * ======== CMMWRAP_GetInfo ========
9849 + */
9850 +u32 CMMWRAP_GetInfo(union Trapped_Args *args)
9852 + DSP_STATUS status = DSP_SOK;
9853 + struct CMM_INFO cmmInfo;
9855 + status = CMM_GetInfo(args->ARGS_CMM_GETINFO.hCmmMgr, &cmmInfo);
9857 + cp_to_usr(args->ARGS_CMM_GETINFO.pCmmInfo, &cmmInfo, status, 1);
9859 + return status;