1/*
2 * proc.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Processor interface at the driver level.
7 *
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19#include <linux/types.h>
20/* ------------------------------------ Host OS */
21#include <linux/dma-mapping.h>
22#include <linux/scatterlist.h>
23#include <dspbridge/host_os.h>
24
25/*  ----------------------------------- DSP/BIOS Bridge */
26#include <dspbridge/dbdefs.h>
27
28/*  ----------------------------------- Trace & Debug */
29#include <dspbridge/dbc.h>
30
31/*  ----------------------------------- OS Adaptation Layer */
32#include <dspbridge/ntfy.h>
33#include <dspbridge/sync.h>
34/*  ----------------------------------- Bridge Driver */
35#include <dspbridge/dspdefs.h>
36#include <dspbridge/dspdeh.h>
37/*  ----------------------------------- Platform Manager */
38#include <dspbridge/cod.h>
39#include <dspbridge/dev.h>
40#include <dspbridge/procpriv.h>
41#include <dspbridge/dmm.h>
42
43/*  ----------------------------------- Resource Manager */
44#include <dspbridge/mgr.h>
45#include <dspbridge/node.h>
46#include <dspbridge/nldr.h>
47#include <dspbridge/rmm.h>
48
49/*  ----------------------------------- Others */
50#include <dspbridge/dbdcd.h>
51#include <dspbridge/msg.h>
52#include <dspbridge/dspioctl.h>
53#include <dspbridge/drv.h>
54
55/*  ----------------------------------- This */
56#include <dspbridge/proc.h>
57#include <dspbridge/pwr.h>
58
59#include <dspbridge/resourcecleanup.h>
60/*  ----------------------------------- Defines, Data Structures, Typedefs */
61#define MAXCMDLINELEN       255
62#define PROC_ENVPROCID      "PROC_ID=%d"
63#define MAXPROCIDLEN	(8 + 5)
64#define PROC_DFLT_TIMEOUT   10000	/* Time out in milliseconds */
65#define PWR_TIMEOUT	 500	/* Sleep/wake timout in msec */
66#define EXTEND	      "_EXT_END"	/* Extmem end addr in DSP binary */
67
68#define DSP_CACHE_LINE 128
69
70#define BUFMODE_MASK	(3 << 14)
71
72/* Buffer modes from DSP perspective */
73#define RBUF		0x4000		/* Input buffer */
74#define WBUF		0x8000		/* Output Buffer */
75
76extern struct device *bridge;
77
78/*  ----------------------------------- Globals */
79
80/* The proc_object structure. */
81struct proc_object {
82	struct list_head link;	/* Link to next proc_object */
83	struct dev_object *dev_obj;	/* Device this PROC represents */
84	u32 process;		/* Process owning this Processor */
85	struct mgr_object *mgr_obj;	/* Manager Object Handle */
86	u32 attach_count;	/* Processor attach count */
87	u32 processor_id;	/* Processor number */
88	u32 timeout;		/* Time out count */
89	enum dsp_procstate proc_state;	/* Processor state */
90	u32 unit;		/* DDSP unit number */
91	bool is_already_attached;	/*
92					 * True if the Device below has
93					 * GPP Client attached
94					 */
95	struct ntfy_object *ntfy_obj;	/* Manages  notifications */
96	/* Bridge Context Handle */
97	struct bridge_dev_context *bridge_context;
98	/* Function interface to Bridge driver */
99	struct bridge_drv_interface *intf_fxns;
100	char *last_coff;
101	struct list_head proc_list;
102};
103
104static u32 refs;
105
106DEFINE_MUTEX(proc_lock);	/* For critical sections */
107
108/*  ----------------------------------- Function Prototypes */
109static int proc_monitor(struct proc_object *proc_obj);
110static s32 get_envp_count(char **envp);
111static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
112			   s32 cnew_envp, char *sz_var);
113
114/* remember mapping information */
115static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt,
116				u32 mpu_addr, u32 dsp_addr, u32 size)
117{
118	struct dmm_map_object *map_obj;
119
120	u32 num_usr_pgs = size / PG_SIZE4K;
121
122	pr_debug("%s: adding map info: mpu_addr 0x%x virt 0x%x size 0x%x\n",
123						__func__, mpu_addr,
124						dsp_addr, size);
125
126	map_obj = kzalloc(sizeof(struct dmm_map_object), GFP_KERNEL);
127	if (!map_obj) {
128		pr_err("%s: kzalloc failed\n", __func__);
129		return NULL;
130	}
131	INIT_LIST_HEAD(&map_obj->link);
132
133	map_obj->pages = kcalloc(num_usr_pgs, sizeof(struct page *),
134							GFP_KERNEL);
135	if (!map_obj->pages) {
136		pr_err("%s: kzalloc failed\n", __func__);
137		kfree(map_obj);
138		return NULL;
139	}
140
141	map_obj->mpu_addr = mpu_addr;
142	map_obj->dsp_addr = dsp_addr;
143	map_obj->size = size;
144	map_obj->num_usr_pgs = num_usr_pgs;
145
146	spin_lock(&pr_ctxt->dmm_map_lock);
147	list_add(&map_obj->link, &pr_ctxt->dmm_map_list);
148	spin_unlock(&pr_ctxt->dmm_map_lock);
149
150	return map_obj;
151}
152
153static int match_exact_map_obj(struct dmm_map_object *map_obj,
154					u32 dsp_addr, u32 size)
155{
156	if (map_obj->dsp_addr == dsp_addr && map_obj->size != size)
157		pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n",
158				__func__, dsp_addr, map_obj->size, size);
159
160	return map_obj->dsp_addr == dsp_addr &&
161		map_obj->size == size;
162}
163
164static void remove_mapping_information(struct process_context *pr_ctxt,
165						u32 dsp_addr, u32 size)
166{
167	struct dmm_map_object *map_obj;
168
169	pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__,
170							dsp_addr, size);
171
172	spin_lock(&pr_ctxt->dmm_map_lock);
173	list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
174		pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
175							__func__,
176							map_obj->mpu_addr,
177							map_obj->dsp_addr,
178							map_obj->size);
179
180		if (match_exact_map_obj(map_obj, dsp_addr, size)) {
181			pr_debug("%s: match, deleting map info\n", __func__);
182			list_del(&map_obj->link);
183			kfree(map_obj->dma_info.sg);
184			kfree(map_obj->pages);
185			kfree(map_obj);
186			goto out;
187		}
188		pr_debug("%s: candidate didn't match\n", __func__);
189	}
190
191	pr_err("%s: failed to find given map info\n", __func__);
192out:
193	spin_unlock(&pr_ctxt->dmm_map_lock);
194}
195
196static int match_containing_map_obj(struct dmm_map_object *map_obj,
197					u32 mpu_addr, u32 size)
198{
199	u32 map_obj_end = map_obj->mpu_addr + map_obj->size;
200
201	return mpu_addr >= map_obj->mpu_addr &&
202		mpu_addr + size <= map_obj_end;
203}
204
205static struct dmm_map_object *find_containing_mapping(
206				struct process_context *pr_ctxt,
207				u32 mpu_addr, u32 size)
208{
209	struct dmm_map_object *map_obj;
210	pr_debug("%s: looking for mpu_addr 0x%x size 0x%x\n", __func__,
211						mpu_addr, size);
212
213	spin_lock(&pr_ctxt->dmm_map_lock);
214	list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
215		pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
216						__func__,
217						map_obj->mpu_addr,
218						map_obj->dsp_addr,
219						map_obj->size);
220		if (match_containing_map_obj(map_obj, mpu_addr, size)) {
221			pr_debug("%s: match!\n", __func__);
222			goto out;
223		}
224
225		pr_debug("%s: no match!\n", __func__);
226	}
227
228	map_obj = NULL;
229out:
230	spin_unlock(&pr_ctxt->dmm_map_lock);
231	return map_obj;
232}
233
234static int find_first_page_in_cache(struct dmm_map_object *map_obj,
235					unsigned long mpu_addr)
236{
237	u32 mapped_base_page = map_obj->mpu_addr >> PAGE_SHIFT;
238	u32 requested_base_page = mpu_addr >> PAGE_SHIFT;
239	int pg_index = requested_base_page - mapped_base_page;
240
241	if (pg_index < 0 || pg_index >= map_obj->num_usr_pgs) {
242		pr_err("%s: failed (got %d)\n", __func__, pg_index);
243		return -1;
244	}
245
246	pr_debug("%s: first page is %d\n", __func__, pg_index);
247	return pg_index;
248}
249
250static inline struct page *get_mapping_page(struct dmm_map_object *map_obj,
251								int pg_i)
252{
253	pr_debug("%s: looking for pg_i %d, num_usr_pgs: %d\n", __func__,
254					pg_i, map_obj->num_usr_pgs);
255
256	if (pg_i < 0 || pg_i >= map_obj->num_usr_pgs) {
257		pr_err("%s: requested pg_i %d is out of mapped range\n",
258				__func__, pg_i);
259		return NULL;
260	}
261
262	return map_obj->pages[pg_i];
263}
264
265/*
266 *  ======== proc_attach ========
267 *  Purpose:
268 *      Prepare for communication with a particular DSP processor, and return
269 *      a handle to the processor object.
270 */
271int
272proc_attach(u32 processor_id,
273	    const struct dsp_processorattrin *attr_in,
274	    void **ph_processor, struct process_context *pr_ctxt)
275{
276	int status = 0;
277	struct dev_object *hdev_obj;
278	struct proc_object *p_proc_object = NULL;
279	struct mgr_object *hmgr_obj = NULL;
280	struct drv_object *hdrv_obj = NULL;
281	struct drv_data *drv_datap = dev_get_drvdata(bridge);
282	u8 dev_type;
283
284	DBC_REQUIRE(refs > 0);
285	DBC_REQUIRE(ph_processor != NULL);
286
287	if (pr_ctxt->processor) {
288		*ph_processor = pr_ctxt->processor;
289		return status;
290	}
291
292	/* Get the Driver and Manager Object Handles */
293	if (!drv_datap || !drv_datap->drv_object || !drv_datap->mgr_object) {
294		status = -ENODATA;
295		pr_err("%s: Failed to get object handles\n", __func__);
296	} else {
297		hdrv_obj = drv_datap->drv_object;
298		hmgr_obj = drv_datap->mgr_object;
299	}
300
301	if (!status) {
302		/* Get the Device Object */
303		status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
304	}
305	if (!status)
306		status = dev_get_dev_type(hdev_obj, &dev_type);
307
308	if (status)
309		goto func_end;
310
311	/* If we made it this far, create the Proceesor object: */
312	p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
313	/* Fill out the Processor Object: */
314	if (p_proc_object == NULL) {
315		status = -ENOMEM;
316		goto func_end;
317	}
318	p_proc_object->dev_obj = hdev_obj;
319	p_proc_object->mgr_obj = hmgr_obj;
320	p_proc_object->processor_id = dev_type;
321	/* Store TGID instead of process handle */
322	p_proc_object->process = current->tgid;
323
324	INIT_LIST_HEAD(&p_proc_object->proc_list);
325
326	if (attr_in)
327		p_proc_object->timeout = attr_in->timeout;
328	else
329		p_proc_object->timeout = PROC_DFLT_TIMEOUT;
330
331	status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
332	if (!status) {
333		status = dev_get_bridge_context(hdev_obj,
334					     &p_proc_object->bridge_context);
335		if (status)
336			kfree(p_proc_object);
337	} else
338		kfree(p_proc_object);
339
340	if (status)
341		goto func_end;
342
343	/* Create the Notification Object */
344	/* This is created with no event mask, no notify mask
345	 * and no valid handle to the notification. They all get
346	 * filled up when proc_register_notify is called */
347	p_proc_object->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
348							GFP_KERNEL);
349	if (p_proc_object->ntfy_obj)
350		ntfy_init(p_proc_object->ntfy_obj);
351	else
352		status = -ENOMEM;
353
354	if (!status) {
355		/* Insert the Processor Object into the DEV List.
356		 * Return handle to this Processor Object:
357		 * Find out if the Device is already attached to a
358		 * Processor. If so, return AlreadyAttached status */
359		status = dev_insert_proc_object(p_proc_object->dev_obj,
360						(u32) p_proc_object,
361						&p_proc_object->
362						is_already_attached);
363		if (!status) {
364			if (p_proc_object->is_already_attached)
365				status = 0;
366		} else {
367			if (p_proc_object->ntfy_obj) {
368				ntfy_delete(p_proc_object->ntfy_obj);
369				kfree(p_proc_object->ntfy_obj);
370			}
371
372			kfree(p_proc_object);
373		}
374		if (!status) {
375			*ph_processor = (void *)p_proc_object;
376			pr_ctxt->processor = *ph_processor;
377			(void)proc_notify_clients(p_proc_object,
378						  DSP_PROCESSORATTACH);
379		}
380	} else {
381		/* Don't leak memory if status is failed */
382		kfree(p_proc_object);
383	}
384func_end:
385	DBC_ENSURE((status == -EPERM && *ph_processor == NULL) ||
386		   (!status && p_proc_object) ||
387		   (status == 0 && p_proc_object));
388
389	return status;
390}
391
392static int get_exec_file(struct cfg_devnode *dev_node_obj,
393				struct dev_object *hdev_obj,
394				u32 size, char *exec_file)
395{
396	u8 dev_type;
397	s32 len;
398	struct drv_data *drv_datap = dev_get_drvdata(bridge);
399
400	dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
401
402	if (!exec_file)
403		return -EFAULT;
404
405	if (dev_type == DSP_UNIT) {
406		if (!drv_datap || !drv_datap->base_img)
407			return -EFAULT;
408
409		if (strlen(drv_datap->base_img) > size)
410			return -EINVAL;
411
412		strcpy(exec_file, drv_datap->base_img);
413	} else if (dev_type == IVA_UNIT && iva_img) {
414		len = strlen(iva_img);
415		strncpy(exec_file, iva_img, len + 1);
416	} else {
417		return -ENOENT;
418	}
419
420	return 0;
421}
422
423/*
424 *  ======== proc_auto_start ======== =
425 *  Purpose:
426 *      A Particular device gets loaded with the default image
427 *      if the AutoStart flag is set.
428 *  Parameters:
429 *      hdev_obj:     Handle to the Device
430 *  Returns:
431 *      0:   On Successful Loading
432 *      -EPERM  General Failure
433 *  Requires:
434 *      hdev_obj != NULL
435 *  Ensures:
436 */
437int proc_auto_start(struct cfg_devnode *dev_node_obj,
438			   struct dev_object *hdev_obj)
439{
440	int status = -EPERM;
441	struct proc_object *p_proc_object;
442	char sz_exec_file[MAXCMDLINELEN];
443	char *argv[2];
444	struct mgr_object *hmgr_obj = NULL;
445	struct drv_data *drv_datap = dev_get_drvdata(bridge);
446	u8 dev_type;
447
448	DBC_REQUIRE(refs > 0);
449	DBC_REQUIRE(dev_node_obj != NULL);
450	DBC_REQUIRE(hdev_obj != NULL);
451
452	/* Create a Dummy PROC Object */
453	if (!drv_datap || !drv_datap->mgr_object) {
454		status = -ENODATA;
455		pr_err("%s: Failed to retrieve the object handle\n", __func__);
456		goto func_end;
457	} else {
458		hmgr_obj = drv_datap->mgr_object;
459	}
460
461	p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
462	if (p_proc_object == NULL) {
463		status = -ENOMEM;
464		goto func_end;
465	}
466	p_proc_object->dev_obj = hdev_obj;
467	p_proc_object->mgr_obj = hmgr_obj;
468	status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
469	if (!status)
470		status = dev_get_bridge_context(hdev_obj,
471					     &p_proc_object->bridge_context);
472	if (status)
473		goto func_cont;
474
475	/* Stop the Device, put it into standby mode */
476	status = proc_stop(p_proc_object);
477
478	if (status)
479		goto func_cont;
480
481	/* Get the default executable for this board... */
482	dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
483	p_proc_object->processor_id = dev_type;
484	status = get_exec_file(dev_node_obj, hdev_obj, sizeof(sz_exec_file),
485			       sz_exec_file);
486	if (!status) {
487		argv[0] = sz_exec_file;
488		argv[1] = NULL;
489		/* ...and try to load it: */
490		status = proc_load(p_proc_object, 1, (const char **)argv, NULL);
491		if (!status)
492			status = proc_start(p_proc_object);
493	}
494	kfree(p_proc_object->last_coff);
495	p_proc_object->last_coff = NULL;
496func_cont:
497	kfree(p_proc_object);
498func_end:
499	return status;
500}
501
502/*
503 *  ======== proc_ctrl ========
504 *  Purpose:
505 *      Pass control information to the GPP device driver managing the
506 *      DSP processor.
507 *
508 *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
509 *      application developer's API.
510 *      Call the bridge_dev_ctrl fxn with the Argument. This is a Synchronous
511 *      Operation. arg can be null.
512 */
513int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg)
514{
515	int status = 0;
516	struct proc_object *p_proc_object = hprocessor;
517	u32 timeout = 0;
518
519	DBC_REQUIRE(refs > 0);
520
521	if (p_proc_object) {
522		/* intercept PWR deep sleep command */
523		if (dw_cmd == BRDIOCTL_DEEPSLEEP) {
524			timeout = arg->cb_data;
525			status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
526		}
527		/* intercept PWR emergency sleep command */
528		else if (dw_cmd == BRDIOCTL_EMERGENCYSLEEP) {
529			timeout = arg->cb_data;
530			status = pwr_sleep_dsp(PWR_EMERGENCYDEEPSLEEP, timeout);
531		} else if (dw_cmd == PWR_DEEPSLEEP) {
532			/* timeout = arg->cb_data; */
533			status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
534		}
535		/* intercept PWR wake commands */
536		else if (dw_cmd == BRDIOCTL_WAKEUP) {
537			timeout = arg->cb_data;
538			status = pwr_wake_dsp(timeout);
539		} else if (dw_cmd == PWR_WAKEUP) {
540			/* timeout = arg->cb_data; */
541			status = pwr_wake_dsp(timeout);
542		} else
543		    if (!((*p_proc_object->intf_fxns->dev_cntrl)
544				      (p_proc_object->bridge_context, dw_cmd,
545				       arg))) {
546			status = 0;
547		} else {
548			status = -EPERM;
549		}
550	} else {
551		status = -EFAULT;
552	}
553
554	return status;
555}
556
557/*
558 *  ======== proc_detach ========
559 *  Purpose:
560 *      Destroys the  Processor Object. Removes the notification from the Dev
561 *      List.
562 */
563int proc_detach(struct process_context *pr_ctxt)
564{
565	int status = 0;
566	struct proc_object *p_proc_object = NULL;
567
568	DBC_REQUIRE(refs > 0);
569
570	p_proc_object = (struct proc_object *)pr_ctxt->processor;
571
572	if (p_proc_object) {
573		/* Notify the Client */
574		ntfy_notify(p_proc_object->ntfy_obj, DSP_PROCESSORDETACH);
575		/* Remove the notification memory */
576		if (p_proc_object->ntfy_obj) {
577			ntfy_delete(p_proc_object->ntfy_obj);
578			kfree(p_proc_object->ntfy_obj);
579		}
580
581		kfree(p_proc_object->last_coff);
582		p_proc_object->last_coff = NULL;
583		/* Remove the Proc from the DEV List */
584		(void)dev_remove_proc_object(p_proc_object->dev_obj,
585					     (u32) p_proc_object);
586		/* Free the Processor Object */
587		kfree(p_proc_object);
588		pr_ctxt->processor = NULL;
589	} else {
590		status = -EFAULT;
591	}
592
593	return status;
594}
595
596/*
597 *  ======== proc_enum_nodes ========
598 *  Purpose:
599 *      Enumerate and get configuration information about nodes allocated
600 *      on a DSP processor.
601 */
602int proc_enum_nodes(void *hprocessor, void **node_tab,
603			   u32 node_tab_size, u32 *pu_num_nodes,
604			   u32 *pu_allocated)
605{
606	int status = -EPERM;
607	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
608	struct node_mgr *hnode_mgr = NULL;
609
610	DBC_REQUIRE(refs > 0);
611	DBC_REQUIRE(node_tab != NULL || node_tab_size == 0);
612	DBC_REQUIRE(pu_num_nodes != NULL);
613	DBC_REQUIRE(pu_allocated != NULL);
614
615	if (p_proc_object) {
616		if (!(dev_get_node_manager(p_proc_object->dev_obj,
617						       &hnode_mgr))) {
618			if (hnode_mgr) {
619				status = node_enum_nodes(hnode_mgr, node_tab,
620							 node_tab_size,
621							 pu_num_nodes,
622							 pu_allocated);
623			}
624		}
625	} else {
626		status = -EFAULT;
627	}
628
629	return status;
630}
631
632/* Cache operation against kernel address instead of users */
633static int build_dma_sg(struct dmm_map_object *map_obj, unsigned long start,
634						ssize_t len, int pg_i)
635{
636	struct page *page;
637	unsigned long offset;
638	ssize_t rest;
639	int ret = 0, i = 0;
640	struct scatterlist *sg = map_obj->dma_info.sg;
641
642	while (len) {
643		page = get_mapping_page(map_obj, pg_i);
644		if (!page) {
645			pr_err("%s: no page for %08lx\n", __func__, start);
646			ret = -EINVAL;
647			goto out;
648		} else if (IS_ERR(page)) {
649			pr_err("%s: err page for %08lx(%lu)\n", __func__, start,
650			       PTR_ERR(page));
651			ret = PTR_ERR(page);
652			goto out;
653		}
654
655		offset = start & ~PAGE_MASK;
656		rest = min_t(ssize_t, PAGE_SIZE - offset, len);
657
658		sg_set_page(&sg[i], page, rest, offset);
659
660		len -= rest;
661		start += rest;
662		pg_i++, i++;
663	}
664
665	if (i != map_obj->dma_info.num_pages) {
666		pr_err("%s: bad number of sg iterations\n", __func__);
667		ret = -EFAULT;
668		goto out;
669	}
670
671out:
672	return ret;
673}
674
675static int memory_regain_ownership(struct dmm_map_object *map_obj,
676		unsigned long start, ssize_t len, enum dma_data_direction dir)
677{
678	int ret = 0;
679	unsigned long first_data_page = start >> PAGE_SHIFT;
680	unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
681	/* calculating the number of pages this area spans */
682	unsigned long num_pages = last_data_page - first_data_page + 1;
683	struct bridge_dma_map_info *dma_info = &map_obj->dma_info;
684
685	if (!dma_info->sg)
686		goto out;
687
688	if (dma_info->dir != dir || dma_info->num_pages != num_pages) {
689		pr_err("%s: dma info doesn't match given params\n", __func__);
690		return -EINVAL;
691	}
692
693	dma_unmap_sg(bridge, dma_info->sg, num_pages, dma_info->dir);
694
695	pr_debug("%s: dma_map_sg unmapped\n", __func__);
696
697	kfree(dma_info->sg);
698
699	map_obj->dma_info.sg = NULL;
700
701out:
702	return ret;
703}
704
705/* Cache operation against kernel address instead of users */
706static int memory_give_ownership(struct dmm_map_object *map_obj,
707		unsigned long start, ssize_t len, enum dma_data_direction dir)
708{
709	int pg_i, ret, sg_num;
710	struct scatterlist *sg;
711	unsigned long first_data_page = start >> PAGE_SHIFT;
712	unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
713	/* calculating the number of pages this area spans */
714	unsigned long num_pages = last_data_page - first_data_page + 1;
715
716	pg_i = find_first_page_in_cache(map_obj, start);
717	if (pg_i < 0) {
718		pr_err("%s: failed to find first page in cache\n", __func__);
719		ret = -EINVAL;
720		goto out;
721	}
722
723	sg = kcalloc(num_pages, sizeof(*sg), GFP_KERNEL);
724	if (!sg) {
725		pr_err("%s: kcalloc failed\n", __func__);
726		ret = -ENOMEM;
727		goto out;
728	}
729
730	sg_init_table(sg, num_pages);
731
732	/* cleanup a previous sg allocation */
733	/* this may happen if application doesn't signal for e/o DMA */
734	kfree(map_obj->dma_info.sg);
735
736	map_obj->dma_info.sg = sg;
737	map_obj->dma_info.dir = dir;
738	map_obj->dma_info.num_pages = num_pages;
739
740	ret = build_dma_sg(map_obj, start, len, pg_i);
741	if (ret)
742		goto kfree_sg;
743
744	sg_num = dma_map_sg(bridge, sg, num_pages, dir);
745	if (sg_num < 1) {
746		pr_err("%s: dma_map_sg failed: %d\n", __func__, sg_num);
747		ret = -EFAULT;
748		goto kfree_sg;
749	}
750
751	pr_debug("%s: dma_map_sg mapped %d elements\n", __func__, sg_num);
752	map_obj->dma_info.sg_num = sg_num;
753
754	return 0;
755
756kfree_sg:
757	kfree(sg);
758	map_obj->dma_info.sg = NULL;
759out:
760	return ret;
761}
762
763int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
764				enum dma_data_direction dir)
765{
766	/* Keep STATUS here for future additions to this function */
767	int status = 0;
768	struct process_context *pr_ctxt = (struct process_context *) hprocessor;
769	struct dmm_map_object *map_obj;
770
771	DBC_REQUIRE(refs > 0);
772
773	if (!pr_ctxt) {
774		status = -EFAULT;
775		goto err_out;
776	}
777
778	pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
779							(u32)pmpu_addr,
780							ul_size, dir);
781
782	mutex_lock(&proc_lock);
783
784	/* find requested memory are in cached mapping information */
785	map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
786	if (!map_obj) {
787		pr_err("%s: find_containing_mapping failed\n", __func__);
788		status = -EFAULT;
789		goto no_map;
790	}
791
792	if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
793		pr_err("%s: InValid address parameters %p %x\n",
794			       __func__, pmpu_addr, ul_size);
795		status = -EFAULT;
796	}
797
798no_map:
799	mutex_unlock(&proc_lock);
800err_out:
801
802	return status;
803}
804
805int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
806			enum dma_data_direction dir)
807{
808	/* Keep STATUS here for future additions to this function */
809	int status = 0;
810	struct process_context *pr_ctxt = (struct process_context *) hprocessor;
811	struct dmm_map_object *map_obj;
812
813	DBC_REQUIRE(refs > 0);
814
815	if (!pr_ctxt) {
816		status = -EFAULT;
817		goto err_out;
818	}
819
820	pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
821							(u32)pmpu_addr,
822							ul_size, dir);
823
824	mutex_lock(&proc_lock);
825
826	/* find requested memory are in cached mapping information */
827	map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
828	if (!map_obj) {
829		pr_err("%s: find_containing_mapping failed\n", __func__);
830		status = -EFAULT;
831		goto no_map;
832	}
833
834	if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
835		pr_err("%s: InValid address parameters %p %x\n",
836		       __func__, pmpu_addr, ul_size);
837		status = -EFAULT;
838	}
839
840no_map:
841	mutex_unlock(&proc_lock);
842err_out:
843	return status;
844}
845
846/*
847 *  ======== proc_flush_memory ========
848 *  Purpose:
849 *     Flush cache
850 */
851int proc_flush_memory(void *hprocessor, void *pmpu_addr,
852			     u32 ul_size, u32 ul_flags)
853{
854	enum dma_data_direction dir = DMA_BIDIRECTIONAL;
855
856	return proc_begin_dma(hprocessor, pmpu_addr, ul_size, dir);
857}
858
859/*
860 *  ======== proc_invalidate_memory ========
861 *  Purpose:
862 *     Invalidates the memory specified
863 */
864int proc_invalidate_memory(void *hprocessor, void *pmpu_addr, u32 size)
865{
866	enum dma_data_direction dir = DMA_FROM_DEVICE;
867
868	return proc_begin_dma(hprocessor, pmpu_addr, size, dir);
869}
870
871/*
872 *  ======== proc_get_resource_info ========
873 *  Purpose:
874 *      Enumerate the resources currently available on a processor.
875 */
876int proc_get_resource_info(void *hprocessor, u32 resource_type,
877				  struct dsp_resourceinfo *resource_info,
878				  u32 resource_info_size)
879{
880	int status = -EPERM;
881	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
882	struct node_mgr *hnode_mgr = NULL;
883	struct nldr_object *nldr_obj = NULL;
884	struct rmm_target_obj *rmm = NULL;
885	struct io_mgr *hio_mgr = NULL;	/* IO manager handle */
886
887	DBC_REQUIRE(refs > 0);
888	DBC_REQUIRE(resource_info != NULL);
889	DBC_REQUIRE(resource_info_size >= sizeof(struct dsp_resourceinfo));
890
891	if (!p_proc_object) {
892		status = -EFAULT;
893		goto func_end;
894	}
895	switch (resource_type) {
896	case DSP_RESOURCE_DYNDARAM:
897	case DSP_RESOURCE_DYNSARAM:
898	case DSP_RESOURCE_DYNEXTERNAL:
899	case DSP_RESOURCE_DYNSRAM:
900		status = dev_get_node_manager(p_proc_object->dev_obj,
901					      &hnode_mgr);
902		if (!hnode_mgr) {
903			status = -EFAULT;
904			goto func_end;
905		}
906
907		status = node_get_nldr_obj(hnode_mgr, &nldr_obj);
908		if (!status) {
909			status = nldr_get_rmm_manager(nldr_obj, &rmm);
910			if (rmm) {
911				if (!rmm_stat(rmm,
912					      (enum dsp_memtype)resource_type,
913					      (struct dsp_memstat *)
914					      &(resource_info->result.
915						mem_stat)))
916					status = -EINVAL;
917			} else {
918				status = -EFAULT;
919			}
920		}
921		break;
922	case DSP_RESOURCE_PROCLOAD:
923		status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr);
924		if (hio_mgr)
925			status =
926			    p_proc_object->intf_fxns->
927			    io_get_proc_load(hio_mgr,
928						 (struct dsp_procloadstat *)
929						 &(resource_info->result.
930						   proc_load_stat));
931		else
932			status = -EFAULT;
933		break;
934	default:
935		status = -EPERM;
936		break;
937	}
938func_end:
939	return status;
940}
941
942/*
943 *  ======== proc_exit ========
944 *  Purpose:
945 *      Decrement reference count, and free resources when reference count is
946 *      0.
947 */
948void proc_exit(void)
949{
950	DBC_REQUIRE(refs > 0);
951
952	refs--;
953
954	DBC_ENSURE(refs >= 0);
955}
956
957/*
958 *  ======== proc_get_dev_object ========
959 *  Purpose:
960 *      Return the Dev Object handle for a given Processor.
961 *
962 */
963int proc_get_dev_object(void *hprocessor,
964			       struct dev_object **device_obj)
965{
966	int status = -EPERM;
967	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
968
969	DBC_REQUIRE(refs > 0);
970	DBC_REQUIRE(device_obj != NULL);
971
972	if (p_proc_object) {
973		*device_obj = p_proc_object->dev_obj;
974		status = 0;
975	} else {
976		*device_obj = NULL;
977		status = -EFAULT;
978	}
979
980	DBC_ENSURE((!status && *device_obj != NULL) ||
981		   (status && *device_obj == NULL));
982
983	return status;
984}
985
986/*
987 *  ======== proc_get_state ========
988 *  Purpose:
989 *      Report the state of the specified DSP processor.
990 */
991int proc_get_state(void *hprocessor,
992			  struct dsp_processorstate *proc_state_obj,
993			  u32 state_info_size)
994{
995	int status = 0;
996	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
997	int brd_status;
998
999	DBC_REQUIRE(refs > 0);
1000	DBC_REQUIRE(proc_state_obj != NULL);
1001	DBC_REQUIRE(state_info_size >= sizeof(struct dsp_processorstate));
1002
1003	if (p_proc_object) {
1004		/* First, retrieve BRD state information */
1005		status = (*p_proc_object->intf_fxns->brd_status)
1006		    (p_proc_object->bridge_context, &brd_status);
1007		if (!status) {
1008			switch (brd_status) {
1009			case BRD_STOPPED:
1010				proc_state_obj->proc_state = PROC_STOPPED;
1011				break;
1012			case BRD_SLEEP_TRANSITION:
1013			case BRD_DSP_HIBERNATION:
1014				/* Fall through */
1015			case BRD_RUNNING:
1016				proc_state_obj->proc_state = PROC_RUNNING;
1017				break;
1018			case BRD_LOADED:
1019				proc_state_obj->proc_state = PROC_LOADED;
1020				break;
1021			case BRD_ERROR:
1022				proc_state_obj->proc_state = PROC_ERROR;
1023				break;
1024			default:
1025				proc_state_obj->proc_state = 0xFF;
1026				status = -EPERM;
1027				break;
1028			}
1029		}
1030	} else {
1031		status = -EFAULT;
1032	}
1033	dev_dbg(bridge, "%s, results: status: 0x%x proc_state_obj: 0x%x\n",
1034		__func__, status, proc_state_obj->proc_state);
1035	return status;
1036}
1037
1038/*
1039 *  ======== proc_get_trace ========
1040 *  Purpose:
1041 *      Retrieve the current contents of the trace buffer, located on the
1042 *      Processor.  Predefined symbols for the trace buffer must have been
1043 *      configured into the DSP executable.
1044 *  Details:
1045 *      We support using the symbols SYS_PUTCBEG and SYS_PUTCEND to define a
1046 *      trace buffer, only.  Treat it as an undocumented feature.
1047 *      This call is destructive, meaning the processor is placed in the monitor
1048 *      state as a result of this function.
1049 */
1050int proc_get_trace(void *hprocessor, u8 * pbuf, u32 max_size)
1051{
1052	int status;
1053	status = -ENOSYS;
1054	return status;
1055}
1056
1057/*
1058 *  ======== proc_init ========
1059 *  Purpose:
1060 *      Initialize PROC's private state, keeping a reference count on each call
1061 */
1062bool proc_init(void)
1063{
1064	bool ret = true;
1065
1066	DBC_REQUIRE(refs >= 0);
1067
1068	if (ret)
1069		refs++;
1070
1071	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
1072
1073	return ret;
1074}
1075
1076/*
1077 *  ======== proc_load ========
1078 *  Purpose:
1079 *      Reset a processor and load a new base program image.
1080 *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
1081 *      application developer's API.
1082 */
1083int proc_load(void *hprocessor, const s32 argc_index,
1084		     const char **user_args, const char **user_envp)
1085{
1086	int status = 0;
1087	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1088	struct io_mgr *hio_mgr;	/* IO manager handle */
1089	struct msg_mgr *hmsg_mgr;
1090	struct cod_manager *cod_mgr;	/* Code manager handle */
1091	char *pargv0;		/* temp argv[0] ptr */
1092	char **new_envp;	/* Updated envp[] array. */
1093	char sz_proc_id[MAXPROCIDLEN];	/* Size of "PROC_ID=<n>" */
1094	s32 envp_elems;		/* Num elements in envp[]. */
1095	s32 cnew_envp;		/* "  " in new_envp[] */
1096	s32 nproc_id = 0;	/* Anticipate MP version. */
1097	struct dcd_manager *hdcd_handle;
1098	struct dmm_object *dmm_mgr;
1099	u32 dw_ext_end;
1100	u32 proc_id;
1101	int brd_state;
1102	struct drv_data *drv_datap = dev_get_drvdata(bridge);
1103
1104#ifdef OPT_LOAD_TIME_INSTRUMENTATION
1105	struct timeval tv1;
1106	struct timeval tv2;
1107#endif
1108
1109#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1110	struct dspbridge_platform_data *pdata =
1111	    omap_dspbridge_dev->dev.platform_data;
1112#endif
1113
1114	DBC_REQUIRE(refs > 0);
1115	DBC_REQUIRE(argc_index > 0);
1116	DBC_REQUIRE(user_args != NULL);
1117
1118#ifdef OPT_LOAD_TIME_INSTRUMENTATION
1119	do_gettimeofday(&tv1);
1120#endif
1121	if (!p_proc_object) {
1122		status = -EFAULT;
1123		goto func_end;
1124	}
1125	dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr);
1126	if (!cod_mgr) {
1127		status = -EPERM;
1128		goto func_end;
1129	}
1130	status = proc_stop(hprocessor);
1131	if (status)
1132		goto func_end;
1133
1134	/* Place the board in the monitor state. */
1135	status = proc_monitor(hprocessor);
1136	if (status)
1137		goto func_end;
1138
1139	/* Save ptr to  original argv[0]. */
1140	pargv0 = (char *)user_args[0];
1141	/*Prepend "PROC_ID=<nproc_id>"to envp array for target. */
1142	envp_elems = get_envp_count((char **)user_envp);
1143	cnew_envp = (envp_elems ? (envp_elems + 1) : (envp_elems + 2));
1144	new_envp = kzalloc(cnew_envp * sizeof(char **), GFP_KERNEL);
1145	if (new_envp) {
1146		status = snprintf(sz_proc_id, MAXPROCIDLEN, PROC_ENVPROCID,
1147				  nproc_id);
1148		if (status == -1) {
1149			dev_dbg(bridge, "%s: Proc ID string overflow\n",
1150				__func__);
1151			status = -EPERM;
1152		} else {
1153			new_envp =
1154			    prepend_envp(new_envp, (char **)user_envp,
1155					 envp_elems, cnew_envp, sz_proc_id);
1156			/* Get the DCD Handle */
1157			status = mgr_get_dcd_handle(p_proc_object->mgr_obj,
1158						    (u32 *) &hdcd_handle);
1159			if (!status) {
1160				/*  Before proceeding with new load,
1161				 *  check if a previously registered COFF
1162				 *  exists.
1163				 *  If yes, unregister nodes in previously
1164				 *  registered COFF.  If any error occurred,
1165				 *  set previously registered COFF to NULL. */
1166				if (p_proc_object->last_coff != NULL) {
1167					status =
1168					    dcd_auto_unregister(hdcd_handle,
1169								p_proc_object->
1170								last_coff);
1171					/* Regardless of auto unregister status,
1172					 *  free previously allocated
1173					 *  memory. */
1174					kfree(p_proc_object->last_coff);
1175					p_proc_object->last_coff = NULL;
1176				}
1177			}
1178			/* On success, do cod_open_base() */
1179			status = cod_open_base(cod_mgr, (char *)user_args[0],
1180					       COD_SYMB);
1181		}
1182	} else {
1183		status = -ENOMEM;
1184	}
1185	if (!status) {
1186		/* Auto-register data base */
1187		/* Get the DCD Handle */
1188		status = mgr_get_dcd_handle(p_proc_object->mgr_obj,
1189					    (u32 *) &hdcd_handle);
1190		if (!status) {
1191			/*  Auto register nodes in specified COFF
1192			 *  file.  If registration did not fail,
1193			 *  (status = 0 or -EACCES)
1194			 *  save the name of the COFF file for
1195			 *  de-registration in the future. */
1196			status =
1197			    dcd_auto_register(hdcd_handle,
1198					      (char *)user_args[0]);
1199			if (status == -EACCES)
1200				status = 0;
1201
1202			if (status) {
1203				status = -EPERM;
1204			} else {
1205				DBC_ASSERT(p_proc_object->last_coff ==
1206					   NULL);
1207				/* Allocate memory for pszLastCoff */
1208				p_proc_object->last_coff =
1209						kzalloc((strlen(user_args[0]) +
1210						1), GFP_KERNEL);
1211				/* If memory allocated, save COFF file name */
1212				if (p_proc_object->last_coff) {
1213					strncpy(p_proc_object->last_coff,
1214						(char *)user_args[0],
1215						(strlen((char *)user_args[0]) +
1216						 1));
1217				}
1218			}
1219		}
1220	}
1221	/* Update shared memory address and size */
1222	if (!status) {
1223		/*  Create the message manager. This must be done
1224		 *  before calling the IOOnLoaded function. */
1225		dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr);
1226		if (!hmsg_mgr) {
1227			status = msg_create(&hmsg_mgr, p_proc_object->dev_obj,
1228					    (msg_onexit) node_on_exit);
1229			DBC_ASSERT(!status);
1230			dev_set_msg_mgr(p_proc_object->dev_obj, hmsg_mgr);
1231		}
1232	}
1233	if (!status) {
1234		/* Set the Device object's message manager */
1235		status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr);
1236		if (hio_mgr)
1237			status = (*p_proc_object->intf_fxns->io_on_loaded)
1238								(hio_mgr);
1239		else
1240			status = -EFAULT;
1241	}
1242	if (!status) {
1243		/* Now, attempt to load an exec: */
1244
1245		/* Boost the OPP level to Maximum level supported by baseport */
1246#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1247		if (pdata->cpu_set_freq)
1248			(*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP5]);
1249#endif
1250		status = cod_load_base(cod_mgr, argc_index, (char **)user_args,
1251				       dev_brd_write_fxn,
1252				       p_proc_object->dev_obj, NULL);
1253		if (status) {
1254			if (status == -EBADF) {
1255				dev_dbg(bridge, "%s: Failure to Load the EXE\n",
1256					__func__);
1257			}
1258			if (status == -ESPIPE) {
1259				pr_err("%s: Couldn't parse the file\n",
1260				       __func__);
1261			}
1262		}
1263		/* Requesting the lowest opp supported */
1264#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1265		if (pdata->cpu_set_freq)
1266			(*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
1267#endif
1268
1269	}
1270	if (!status) {
1271		/* Update the Processor status to loaded */
1272		status = (*p_proc_object->intf_fxns->brd_set_state)
1273		    (p_proc_object->bridge_context, BRD_LOADED);
1274		if (!status) {
1275			p_proc_object->proc_state = PROC_LOADED;
1276			if (p_proc_object->ntfy_obj)
1277				proc_notify_clients(p_proc_object,
1278						    DSP_PROCESSORSTATECHANGE);
1279		}
1280	}
1281	if (!status) {
1282		status = proc_get_processor_id(hprocessor, &proc_id);
1283		if (proc_id == DSP_UNIT) {
1284			/* Use all available DSP address space after EXTMEM
1285			 * for DMM */
1286			if (!status)
1287				status = cod_get_sym_value(cod_mgr, EXTEND,
1288							   &dw_ext_end);
1289
1290			/* Reset DMM structs and add an initial free chunk */
1291			if (!status) {
1292				status =
1293				    dev_get_dmm_mgr(p_proc_object->dev_obj,
1294						    &dmm_mgr);
1295				if (dmm_mgr) {
1296					/* Set dw_ext_end to DMM START u8
1297					 * address */
1298					dw_ext_end =
1299					    (dw_ext_end + 1) * DSPWORDSIZE;
1300					/* DMM memory is from EXT_END */
1301					status = dmm_create_tables(dmm_mgr,
1302								   dw_ext_end,
1303								   DMMPOOLSIZE);
1304				} else {
1305					status = -EFAULT;
1306				}
1307			}
1308		}
1309	}
1310	/* Restore the original argv[0] */
1311	kfree(new_envp);
1312	user_args[0] = pargv0;
1313	if (!status) {
1314		if (!((*p_proc_object->intf_fxns->brd_status)
1315				(p_proc_object->bridge_context, &brd_state))) {
1316			pr_info("%s: Processor Loaded %s\n", __func__, pargv0);
1317			kfree(drv_datap->base_img);
1318			drv_datap->base_img = kmalloc(strlen(pargv0) + 1,
1319								GFP_KERNEL);
1320			if (drv_datap->base_img)
1321				strncpy(drv_datap->base_img, pargv0,
1322							strlen(pargv0) + 1);
1323			else
1324				status = -ENOMEM;
1325			DBC_ASSERT(brd_state == BRD_LOADED);
1326		}
1327	}
1328
1329func_end:
1330	if (status) {
1331		pr_err("%s: Processor failed to load\n", __func__);
1332		proc_stop(p_proc_object);
1333	}
1334	DBC_ENSURE((!status
1335		    && p_proc_object->proc_state == PROC_LOADED)
1336		   || status);
1337#ifdef OPT_LOAD_TIME_INSTRUMENTATION
1338	do_gettimeofday(&tv2);
1339	if (tv2.tv_usec < tv1.tv_usec) {
1340		tv2.tv_usec += 1000000;
1341		tv2.tv_sec--;
1342	}
1343	dev_dbg(bridge, "%s: time to load %d sec and %d usec\n", __func__,
1344		tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec);
1345#endif
1346	return status;
1347}
1348
1349/*
1350 *  ======== proc_map ========
1351 *  Purpose:
1352 *      Maps a MPU buffer to DSP address space.
1353 */
1354int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
1355		    void *req_addr, void **pp_map_addr, u32 ul_map_attr,
1356		    struct process_context *pr_ctxt)
1357{
1358	u32 va_align;
1359	u32 pa_align;
1360	struct dmm_object *dmm_mgr;
1361	u32 size_align;
1362	int status = 0;
1363	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1364	struct dmm_map_object *map_obj;
1365	u32 tmp_addr = 0;
1366
1367#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
1368	if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
1369		if (!IS_ALIGNED((u32)pmpu_addr, DSP_CACHE_LINE) ||
1370		    !IS_ALIGNED(ul_size, DSP_CACHE_LINE)) {
1371			pr_err("%s: not aligned: 0x%x (%d)\n", __func__,
1372						(u32)pmpu_addr, ul_size);
1373			return -EFAULT;
1374		}
1375	}
1376#endif
1377
1378	/* Calculate the page-aligned PA, VA and size */
1379	va_align = PG_ALIGN_LOW((u32) req_addr, PG_SIZE4K);
1380	pa_align = PG_ALIGN_LOW((u32) pmpu_addr, PG_SIZE4K);
1381	size_align = PG_ALIGN_HIGH(ul_size + (u32) pmpu_addr - pa_align,
1382				   PG_SIZE4K);
1383
1384	if (!p_proc_object) {
1385		status = -EFAULT;
1386		goto func_end;
1387	}
1388	/* Critical section */
1389	mutex_lock(&proc_lock);
1390	dmm_get_handle(p_proc_object, &dmm_mgr);
1391	if (dmm_mgr)
1392		status = dmm_map_memory(dmm_mgr, va_align, size_align);
1393	else
1394		status = -EFAULT;
1395
1396	/* Add mapping to the page tables. */
1397	if (!status) {
1398
1399		/* Mapped address = MSB of VA | LSB of PA */
1400		tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
1401		/* mapped memory resource tracking */
1402		map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
1403						size_align);
1404		if (!map_obj)
1405			status = -ENOMEM;
1406		else
1407			status = (*p_proc_object->intf_fxns->brd_mem_map)
1408			    (p_proc_object->bridge_context, pa_align, va_align,
1409			     size_align, ul_map_attr, map_obj->pages);
1410	}
1411	if (!status) {
1412		/* Mapped address = MSB of VA | LSB of PA */
1413		*pp_map_addr = (void *) tmp_addr;
1414	} else {
1415		remove_mapping_information(pr_ctxt, tmp_addr, size_align);
1416		dmm_un_map_memory(dmm_mgr, va_align, &size_align);
1417	}
1418	mutex_unlock(&proc_lock);
1419
1420	if (status)
1421		goto func_end;
1422
1423func_end:
1424	dev_dbg(bridge, "%s: hprocessor %p, pmpu_addr %p, ul_size %x, "
1425		"req_addr %p, ul_map_attr %x, pp_map_addr %p, va_align %x, "
1426		"pa_align %x, size_align %x status 0x%x\n", __func__,
1427		hprocessor, pmpu_addr, ul_size, req_addr, ul_map_attr,
1428		pp_map_addr, va_align, pa_align, size_align, status);
1429
1430	return status;
1431}
1432
1433/*
1434 *  ======== proc_register_notify ========
1435 *  Purpose:
1436 *      Register to be notified of specific processor events.
1437 */
1438int proc_register_notify(void *hprocessor, u32 event_mask,
1439				u32 notify_type, struct dsp_notification
1440				* hnotification)
1441{
1442	int status = 0;
1443	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1444	struct deh_mgr *hdeh_mgr;
1445
1446	DBC_REQUIRE(hnotification != NULL);
1447	DBC_REQUIRE(refs > 0);
1448
1449	/* Check processor handle */
1450	if (!p_proc_object) {
1451		status = -EFAULT;
1452		goto func_end;
1453	}
1454	/* Check if event mask is a valid processor related event */
1455	if (event_mask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH |
1456			DSP_PROCESSORDETACH | DSP_PROCESSORRESTART |
1457			DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR |
1458			DSP_WDTOVERFLOW))
1459		status = -EINVAL;
1460
1461	/* Check if notify type is valid */
1462	if (notify_type != DSP_SIGNALEVENT)
1463		status = -EINVAL;
1464
1465	if (!status) {
1466		/* If event mask is not DSP_SYSERROR, DSP_MMUFAULT,
1467		 * or DSP_PWRERROR then register event immediately. */
1468		if (event_mask &
1469		    ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR |
1470				DSP_WDTOVERFLOW)) {
1471			status = ntfy_register(p_proc_object->ntfy_obj,
1472					       hnotification, event_mask,
1473					       notify_type);
1474			/* Special case alert, special case alert!
1475			 * If we're trying to *deregister* (i.e. event_mask
1476			 * is 0), a DSP_SYSERROR or DSP_MMUFAULT notification,
1477			 * we have to deregister with the DEH manager.
1478			 * There's no way to know, based on event_mask which
1479			 * manager the notification event was registered with,
1480			 * so if we're trying to deregister and ntfy_register
1481			 * failed, we'll give the deh manager a shot.
1482			 */
1483			if ((event_mask == 0) && status) {
1484				status =
1485				    dev_get_deh_mgr(p_proc_object->dev_obj,
1486						    &hdeh_mgr);
1487				status =
1488					bridge_deh_register_notify(hdeh_mgr,
1489							event_mask,
1490							notify_type,
1491							hnotification);
1492			}
1493		} else {
1494			status = dev_get_deh_mgr(p_proc_object->dev_obj,
1495						 &hdeh_mgr);
1496			status =
1497			    bridge_deh_register_notify(hdeh_mgr,
1498					    event_mask,
1499					    notify_type,
1500					    hnotification);
1501
1502		}
1503	}
1504func_end:
1505	return status;
1506}
1507
1508/*
1509 *  ======== proc_reserve_memory ========
1510 *  Purpose:
1511 *      Reserve a virtually contiguous region of DSP address space.
1512 */
1513int proc_reserve_memory(void *hprocessor, u32 ul_size,
1514			       void **pp_rsv_addr,
1515			       struct process_context *pr_ctxt)
1516{
1517	struct dmm_object *dmm_mgr;
1518	int status = 0;
1519	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1520	struct dmm_rsv_object *rsv_obj;
1521
1522	if (!p_proc_object) {
1523		status = -EFAULT;
1524		goto func_end;
1525	}
1526
1527	status = dmm_get_handle(p_proc_object, &dmm_mgr);
1528	if (!dmm_mgr) {
1529		status = -EFAULT;
1530		goto func_end;
1531	}
1532
1533	status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr);
1534	if (status != 0)
1535		goto func_end;
1536
1537	/*
1538	 * A successful reserve should be followed by insertion of rsv_obj
1539	 * into dmm_rsv_list, so that reserved memory resource tracking
1540	 * remains uptodate
1541	 */
1542	rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL);
1543	if (rsv_obj) {
1544		rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr;
1545		spin_lock(&pr_ctxt->dmm_rsv_lock);
1546		list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
1547		spin_unlock(&pr_ctxt->dmm_rsv_lock);
1548	}
1549
1550func_end:
1551	dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
1552		"status 0x%x\n", __func__, hprocessor,
1553		ul_size, pp_rsv_addr, status);
1554	return status;
1555}
1556
1557/*
1558 *  ======== proc_start ========
1559 *  Purpose:
1560 *      Start a processor running.
1561 */
1562int proc_start(void *hprocessor)
1563{
1564	int status = 0;
1565	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1566	struct cod_manager *cod_mgr;	/* Code manager handle */
1567	u32 dw_dsp_addr;	/* Loaded code's entry point. */
1568	int brd_state;
1569
1570	DBC_REQUIRE(refs > 0);
1571	if (!p_proc_object) {
1572		status = -EFAULT;
1573		goto func_end;
1574	}
1575	/* Call the bridge_brd_start */
1576	if (p_proc_object->proc_state != PROC_LOADED) {
1577		status = -EBADR;
1578		goto func_end;
1579	}
1580	status = dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr);
1581	if (!cod_mgr) {
1582		status = -EFAULT;
1583		goto func_cont;
1584	}
1585
1586	status = cod_get_entry(cod_mgr, &dw_dsp_addr);
1587	if (status)
1588		goto func_cont;
1589
1590	status = (*p_proc_object->intf_fxns->brd_start)
1591	    (p_proc_object->bridge_context, dw_dsp_addr);
1592	if (status)
1593		goto func_cont;
1594
1595	/* Call dev_create2 */
1596	status = dev_create2(p_proc_object->dev_obj);
1597	if (!status) {
1598		p_proc_object->proc_state = PROC_RUNNING;
1599		/* Deep sleep switces off the peripheral clocks.
1600		 * we just put the DSP CPU in idle in the idle loop.
1601		 * so there is no need to send a command to DSP */
1602
1603		if (p_proc_object->ntfy_obj) {
1604			proc_notify_clients(p_proc_object,
1605					    DSP_PROCESSORSTATECHANGE);
1606		}
1607	} else {
1608		/* Failed to Create Node Manager and DISP Object
1609		 * Stop the Processor from running. Put it in STOPPED State */
1610		(void)(*p_proc_object->intf_fxns->
1611		       brd_stop) (p_proc_object->bridge_context);
1612		p_proc_object->proc_state = PROC_STOPPED;
1613	}
1614func_cont:
1615	if (!status) {
1616		if (!((*p_proc_object->intf_fxns->brd_status)
1617				(p_proc_object->bridge_context, &brd_state))) {
1618			pr_info("%s: dsp in running state\n", __func__);
1619			DBC_ASSERT(brd_state != BRD_HIBERNATION);
1620		}
1621	} else {
1622		pr_err("%s: Failed to start the dsp\n", __func__);
1623		proc_stop(p_proc_object);
1624	}
1625
1626func_end:
1627	DBC_ENSURE((!status && p_proc_object->proc_state ==
1628		    PROC_RUNNING) || status);
1629	return status;
1630}
1631
1632/*
1633 *  ======== proc_stop ========
1634 *  Purpose:
1635 *      Stop a processor running.
1636 */
1637int proc_stop(void *hprocessor)
1638{
1639	int status = 0;
1640	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1641	struct msg_mgr *hmsg_mgr;
1642	struct node_mgr *hnode_mgr;
1643	void *hnode;
1644	u32 node_tab_size = 1;
1645	u32 num_nodes = 0;
1646	u32 nodes_allocated = 0;
1647	int brd_state;
1648
1649	DBC_REQUIRE(refs > 0);
1650	if (!p_proc_object) {
1651		status = -EFAULT;
1652		goto func_end;
1653	}
1654	/* check if there are any running nodes */
1655	status = dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr);
1656	if (!status && hnode_mgr) {
1657		status = node_enum_nodes(hnode_mgr, &hnode, node_tab_size,
1658					 &num_nodes, &nodes_allocated);
1659		if ((status == -EINVAL) || (nodes_allocated > 0)) {
1660			pr_err("%s: Can't stop device, active nodes = %d \n",
1661			       __func__, nodes_allocated);
1662			return -EBADR;
1663		}
1664	}
1665	/* Call the bridge_brd_stop */
1666	/* It is OK to stop a device that does n't have nodes OR not started */
1667	status =
1668	    (*p_proc_object->intf_fxns->
1669	     brd_stop) (p_proc_object->bridge_context);
1670	if (!status) {
1671		dev_dbg(bridge, "%s: processor in standby mode\n", __func__);
1672		p_proc_object->proc_state = PROC_STOPPED;
1673		/* Destroy the Node Manager, msg_ctrl Manager */
1674		if (!(dev_destroy2(p_proc_object->dev_obj))) {
1675			/* Destroy the msg_ctrl by calling msg_delete */
1676			dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr);
1677			if (hmsg_mgr) {
1678				msg_delete(hmsg_mgr);
1679				dev_set_msg_mgr(p_proc_object->dev_obj, NULL);
1680			}
1681			if (!((*p_proc_object->
1682			      intf_fxns->brd_status) (p_proc_object->
1683							  bridge_context,
1684							  &brd_state)))
1685				DBC_ASSERT(brd_state == BRD_STOPPED);
1686		}
1687	} else {
1688		pr_err("%s: Failed to stop the processor\n", __func__);
1689	}
1690func_end:
1691
1692	return status;
1693}
1694
1695/*
1696 *  ======== proc_un_map ========
1697 *  Purpose:
1698 *      Removes a MPU buffer mapping from the DSP address space.
1699 */
1700int proc_un_map(void *hprocessor, void *map_addr,
1701		       struct process_context *pr_ctxt)
1702{
1703	int status = 0;
1704	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1705	struct dmm_object *dmm_mgr;
1706	u32 va_align;
1707	u32 size_align;
1708
1709	va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K);
1710	if (!p_proc_object) {
1711		status = -EFAULT;
1712		goto func_end;
1713	}
1714
1715	status = dmm_get_handle(hprocessor, &dmm_mgr);
1716	if (!dmm_mgr) {
1717		status = -EFAULT;
1718		goto func_end;
1719	}
1720
1721	/* Critical section */
1722	mutex_lock(&proc_lock);
1723	/*
1724	 * Update DMM structures. Get the size to unmap.
1725	 * This function returns error if the VA is not mapped
1726	 */
1727	status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
1728	/* Remove mapping from the page tables. */
1729	if (!status) {
1730		status = (*p_proc_object->intf_fxns->brd_mem_un_map)
1731		    (p_proc_object->bridge_context, va_align, size_align);
1732	}
1733
1734	if (status)
1735		goto unmap_failed;
1736
1737	/*
1738	 * A successful unmap should be followed by removal of map_obj
1739	 * from dmm_map_list, so that mapped memory resource tracking
1740	 * remains uptodate
1741	 */
1742	remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);
1743
1744unmap_failed:
1745	mutex_unlock(&proc_lock);
1746
1747func_end:
1748	dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n",
1749		__func__, hprocessor, map_addr, status);
1750	return status;
1751}
1752
1753/*
1754 *  ======== proc_un_reserve_memory ========
1755 *  Purpose:
1756 *      Frees a previously reserved region of DSP address space.
1757 */
1758int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
1759				  struct process_context *pr_ctxt)
1760{
1761	struct dmm_object *dmm_mgr;
1762	int status = 0;
1763	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
1764	struct dmm_rsv_object *rsv_obj;
1765
1766	if (!p_proc_object) {
1767		status = -EFAULT;
1768		goto func_end;
1769	}
1770
1771	status = dmm_get_handle(p_proc_object, &dmm_mgr);
1772	if (!dmm_mgr) {
1773		status = -EFAULT;
1774		goto func_end;
1775	}
1776
1777	status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr);
1778	if (status != 0)
1779		goto func_end;
1780
1781	/*
1782	 * A successful unreserve should be followed by removal of rsv_obj
1783	 * from dmm_rsv_list, so that reserved memory resource tracking
1784	 * remains uptodate
1785	 */
1786	spin_lock(&pr_ctxt->dmm_rsv_lock);
1787	list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) {
1788		if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) {
1789			list_del(&rsv_obj->link);
1790			kfree(rsv_obj);
1791			break;
1792		}
1793	}
1794	spin_unlock(&pr_ctxt->dmm_rsv_lock);
1795
1796func_end:
1797	dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
1798		__func__, hprocessor, prsv_addr, status);
1799	return status;
1800}
1801
1802/*
1803 *  ======== = proc_monitor ======== ==
1804 *  Purpose:
1805 *      Place the Processor in Monitor State. This is an internal
1806 *      function and a requirement before Processor is loaded.
1807 *      This does a bridge_brd_stop, dev_destroy2 and bridge_brd_monitor.
1808 *      In dev_destroy2 we delete the node manager.
1809 *  Parameters:
1810 *      p_proc_object:    Pointer to Processor Object
1811 *  Returns:
1812 *      0:	Processor placed in monitor mode.
1813 *      !0:       Failed to place processor in monitor mode.
1814 *  Requires:
1815 *      Valid Processor Handle
1816 *  Ensures:
1817 *      Success:	ProcObject state is PROC_IDLE
1818 */
1819static int proc_monitor(struct proc_object *proc_obj)
1820{
1821	int status = -EPERM;
1822	struct msg_mgr *hmsg_mgr;
1823	int brd_state;
1824
1825	DBC_REQUIRE(refs > 0);
1826	DBC_REQUIRE(proc_obj);
1827
1828	/* This is needed only when Device is loaded when it is
1829	 * already 'ACTIVE' */
1830	/* Destroy the Node Manager, msg_ctrl Manager */
1831	if (!dev_destroy2(proc_obj->dev_obj)) {
1832		/* Destroy the msg_ctrl by calling msg_delete */
1833		dev_get_msg_mgr(proc_obj->dev_obj, &hmsg_mgr);
1834		if (hmsg_mgr) {
1835			msg_delete(hmsg_mgr);
1836			dev_set_msg_mgr(proc_obj->dev_obj, NULL);
1837		}
1838	}
1839	/* Place the Board in the Monitor State */
1840	if (!((*proc_obj->intf_fxns->brd_monitor)
1841			  (proc_obj->bridge_context))) {
1842		status = 0;
1843		if (!((*proc_obj->intf_fxns->brd_status)
1844				  (proc_obj->bridge_context, &brd_state)))
1845			DBC_ASSERT(brd_state == BRD_IDLE);
1846	}
1847
1848	DBC_ENSURE((!status && brd_state == BRD_IDLE) ||
1849		   status);
1850	return status;
1851}
1852
1853/*
1854 *  ======== get_envp_count ========
1855 *  Purpose:
1856 *      Return the number of elements in the envp array, including the
1857 *      terminating NULL element.
1858 */
1859static s32 get_envp_count(char **envp)
1860{
1861	s32 ret = 0;
1862	if (envp) {
1863		while (*envp++)
1864			ret++;
1865
1866		ret += 1;	/* Include the terminating NULL in the count. */
1867	}
1868
1869	return ret;
1870}
1871
1872/*
1873 *  ======== prepend_envp ========
1874 *  Purpose:
1875 *      Prepend an environment variable=value pair to the new envp array, and
1876 *      copy in the existing var=value pairs in the old envp array.
1877 */
1878static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
1879			   s32 cnew_envp, char *sz_var)
1880{
1881	char **pp_envp = new_envp;
1882
1883	DBC_REQUIRE(new_envp);
1884
1885	/* Prepend new environ var=value string */
1886	*new_envp++ = sz_var;
1887
1888	/* Copy user's environment into our own. */
1889	while (envp_elems--)
1890		*new_envp++ = *envp++;
1891
1892	/* Ensure NULL terminates the new environment strings array. */
1893	if (envp_elems == 0)
1894		*new_envp = NULL;
1895
1896	return pp_envp;
1897}
1898
1899/*
1900 *  ======== proc_notify_clients ========
1901 *  Purpose:
1902 *      Notify the processor the events.
1903 */
1904int proc_notify_clients(void *proc, u32 events)
1905{
1906	int status = 0;
1907	struct proc_object *p_proc_object = (struct proc_object *)proc;
1908
1909	DBC_REQUIRE(p_proc_object);
1910	DBC_REQUIRE(is_valid_proc_event(events));
1911	DBC_REQUIRE(refs > 0);
1912	if (!p_proc_object) {
1913		status = -EFAULT;
1914		goto func_end;
1915	}
1916
1917	ntfy_notify(p_proc_object->ntfy_obj, events);
1918func_end:
1919	return status;
1920}
1921
1922/*
1923 *  ======== proc_notify_all_clients ========
1924 *  Purpose:
1925 *      Notify the processor the events. This includes notifying all clients
1926 *      attached to a particulat DSP.
1927 */
1928int proc_notify_all_clients(void *proc, u32 events)
1929{
1930	int status = 0;
1931	struct proc_object *p_proc_object = (struct proc_object *)proc;
1932
1933	DBC_REQUIRE(is_valid_proc_event(events));
1934	DBC_REQUIRE(refs > 0);
1935
1936	if (!p_proc_object) {
1937		status = -EFAULT;
1938		goto func_end;
1939	}
1940
1941	dev_notify_clients(p_proc_object->dev_obj, events);
1942
1943func_end:
1944	return status;
1945}
1946
1947/*
1948 *  ======== proc_get_processor_id ========
1949 *  Purpose:
1950 *      Retrieves the processor ID.
1951 */
1952int proc_get_processor_id(void *proc, u32 * proc_id)
1953{
1954	int status = 0;
1955	struct proc_object *p_proc_object = (struct proc_object *)proc;
1956
1957	if (p_proc_object)
1958		*proc_id = p_proc_object->processor_id;
1959	else
1960		status = -EFAULT;
1961
1962	return status;
1963}
1964