Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
io_sm.c
Go to the documentation of this file.
1 /*
2  * io_sm.c
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * IO dispatcher for a shared memory channel driver.
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 /*
20  * Channel Invariant:
21  * There is an important invariant condition which must be maintained per
22  * channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of
23  * which may cause timeouts and/or failure of the sync_wait_on_event
24  * function.
25  */
26 #include <linux/types.h>
27 #include <linux/list.h>
28 
29 /* Host OS */
30 #include <dspbridge/host_os.h>
31 #include <linux/workqueue.h>
32 
33 /* ----------------------------------- DSP/BIOS Bridge */
34 #include <dspbridge/dbdefs.h>
35 
36 /* Services Layer */
37 #include <dspbridge/ntfy.h>
38 #include <dspbridge/sync.h>
39 
40 /* Hardware Abstraction Layer */
41 #include <hw_defs.h>
42 #include <hw_mmu.h>
43 
44 /* Bridge Driver */
45 #include <dspbridge/dspdeh.h>
46 #include <dspbridge/dspio.h>
47 #include <dspbridge/dspioctl.h>
48 #include <dspbridge/wdt.h>
49 #include <_tiomap.h>
50 #include <tiomap_io.h>
51 #include <_tiomap_pwr.h>
52 
53 /* Platform Manager */
54 #include <dspbridge/cod.h>
55 #include <dspbridge/node.h>
56 #include <dspbridge/dev.h>
57 
58 /* Others */
59 #include <dspbridge/rms_sh.h>
60 #include <dspbridge/mgr.h>
61 #include <dspbridge/drv.h>
62 #include "_cmm.h"
63 #include "module_list.h"
64 
65 /* This */
66 #include <dspbridge/io_sm.h>
67 #include "_msg_sm.h"
68 
69 /* Defines, Data Structures, Typedefs */
70 #define OUTPUTNOTREADY 0xffff
71 #define NOTENABLED 0xffff /* Channel(s) not enabled */
72 
73 #define EXTEND "_EXT_END"
74 
75 #define SWAP_WORD(x) (x)
76 #define UL_PAGE_ALIGN_SIZE 0x10000 /* Page Align Size */
77 
78 #define MAX_PM_REQS 32
79 
80 #define MMU_FAULT_HEAD1 0xa5a5a5a5
81 #define MMU_FAULT_HEAD2 0x96969696
82 #define POLL_MAX 1000
83 #define MAX_MMU_DBGBUFF 10240
84 
85 /* IO Manager: only one created per board */
86 struct io_mgr {
87  /* These four fields must be the first fields in a io_mgr_ struct */
88  /* Bridge device context */
90  /* Function interface to Bridge driver */
92  struct dev_object *dev_obj; /* Device this board represents */
93 
94  /* These fields initialized in bridge_io_create() */
95  struct chnl_mgr *chnl_mgr;
96  struct shm *shared_mem; /* Shared Memory control */
97  u8 *input; /* Address of input channel */
98  u8 *output; /* Address of output channel */
99  struct msg_mgr *msg_mgr; /* Message manager */
100  /* Msg control for from DSP messages */
102  /* Msg control for to DSP messages */
104  u8 *msg_input; /* Address of input messages */
105  u8 *msg_output; /* Address of output messages */
106  u32 sm_buf_size; /* Size of a shared memory I/O channel */
107  bool shared_irq; /* Is this IRQ shared? */
108  u32 word_size; /* Size in bytes of DSP word */
109  u16 intr_val; /* Interrupt value */
110  /* Private extnd proc info; mmu setup */
112  struct cmm_object *cmm_mgr; /* Shared Mem Mngr */
113  struct work_struct io_workq; /* workqueue */
114 #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
115  u32 trace_buffer_begin; /* Trace message start address */
116  u32 trace_buffer_end; /* Trace message end address */
117  u32 trace_buffer_current; /* Trace message current address */
118  u32 gpp_read_pointer; /* GPP Read pointer to Trace buffer */
119  u8 *msg;
120  u32 gpp_va;
121  u32 dsp_va;
122 #endif
123  /* IO Dpc */
124  u32 dpc_req; /* Number of requested DPC's. */
125  u32 dpc_sched; /* Number of executed DPC's. */
128 
129 };
130 
139 };
140 
141 /* Function Prototypes */
142 static void io_dispatch_pm(struct io_mgr *pio_mgr);
143 static void notify_chnl_complete(struct chnl_object *pchnl,
144  struct chnl_irp *chnl_packet_obj);
145 static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
146  u8 io_mode);
147 static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
148  u8 io_mode);
149 static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr);
150 static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr);
151 static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj,
152  struct chnl_object *pchnl, u32 mask);
153 
154 /* Bus Addr (cached kernel) */
155 static int register_shm_segs(struct io_mgr *hio_mgr,
156  struct cod_manager *cod_man,
157  u32 dw_gpp_base_pa);
158 
159 static inline void set_chnl_free(struct shm *sm, u32 chnl)
160 {
161  sm->host_free_mask &= ~(1 << chnl);
162 }
163 
164 static inline void set_chnl_busy(struct shm *sm, u32 chnl)
165 {
166  sm->host_free_mask |= 1 << chnl;
167 }
168 
169 
170 /*
171  * ======== bridge_io_create ========
172  * Create an IO manager object.
173  */
174 int bridge_io_create(struct io_mgr **io_man,
175  struct dev_object *hdev_obj,
176  const struct io_attrs *mgr_attrts)
177 {
178  struct io_mgr *pio_mgr = NULL;
179  struct bridge_dev_context *hbridge_context = NULL;
180  struct cfg_devnode *dev_node_obj;
181  struct chnl_mgr *hchnl_mgr;
182  u8 dev_type;
183 
184  /* Check requirements */
185  if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0)
186  return -EFAULT;
187 
188  *io_man = NULL;
189 
190  dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
191  if (!hchnl_mgr || hchnl_mgr->iomgr)
192  return -EFAULT;
193 
194  /*
195  * Message manager will be created when a file is loaded, since
196  * size of message buffer in shared memory is configurable in
197  * the base image.
198  */
199  dev_get_bridge_context(hdev_obj, &hbridge_context);
200  if (!hbridge_context)
201  return -EFAULT;
202 
203  dev_get_dev_type(hdev_obj, &dev_type);
204 
205  /* Allocate IO manager object */
206  pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL);
207  if (!pio_mgr)
208  return -ENOMEM;
209 
210  /* Initialize chnl_mgr object */
211  pio_mgr->chnl_mgr = hchnl_mgr;
212  pio_mgr->word_size = mgr_attrts->word_size;
213 
214  if (dev_type == DSP_UNIT) {
215  /* Create an IO DPC */
216  tasklet_init(&pio_mgr->dpc_tasklet, io_dpc, (u32) pio_mgr);
217 
218  /* Initialize DPC counters */
219  pio_mgr->dpc_req = 0;
220  pio_mgr->dpc_sched = 0;
221 
222  spin_lock_init(&pio_mgr->dpc_lock);
223 
224  if (dev_get_dev_node(hdev_obj, &dev_node_obj)) {
225  bridge_io_destroy(pio_mgr);
226  return -EIO;
227  }
228  }
229 
230  pio_mgr->bridge_context = hbridge_context;
231  pio_mgr->shared_irq = mgr_attrts->irq_shared;
232  if (dsp_wdt_init()) {
233  bridge_io_destroy(pio_mgr);
234  return -EPERM;
235  }
236 
237  /* Return IO manager object to caller... */
238  hchnl_mgr->iomgr = pio_mgr;
239  *io_man = pio_mgr;
240 
241  return 0;
242 }
243 
244 /*
245  * ======== bridge_io_destroy ========
246  * Purpose:
247  * Disable interrupts, destroy the IO manager.
248  */
249 int bridge_io_destroy(struct io_mgr *hio_mgr)
250 {
251  int status = 0;
252  if (hio_mgr) {
253  /* Free IO DPC object */
254  tasklet_kill(&hio_mgr->dpc_tasklet);
255 
256 #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
257  kfree(hio_mgr->msg);
258 #endif
259  dsp_wdt_exit();
260  /* Free this IO manager object */
261  kfree(hio_mgr);
262  } else {
263  status = -EFAULT;
264  }
265 
266  return status;
267 }
268 
270 {
271  struct shm_symbol_val *s;
272  struct cod_manager *cod_man;
273  int status;
274 
275  s = kzalloc(sizeof(*s), GFP_KERNEL);
276  if (!s)
277  return ERR_PTR(-ENOMEM);
278 
279  status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man);
280  if (status)
281  goto free_symbol;
282 
283  /* Get start and length of channel part of shared memory */
285  &s->shm_base);
286  if (status)
287  goto free_symbol;
288 
290  &s->shm_lim);
291  if (status)
292  goto free_symbol;
293 
294  if (s->shm_lim <= s->shm_base) {
295  status = -EINVAL;
296  goto free_symbol;
297  }
298 
299  /* Get start and length of message part of shared memory */
301  &s->msg_base);
302  if (status)
303  goto free_symbol;
304 
306  &s->msg_lim);
307  if (status)
308  goto free_symbol;
309 
310  if (s->msg_lim <= s->msg_base) {
311  status = -EINVAL;
312  goto free_symbol;
313  }
314 
315 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
316  status = cod_get_sym_value(cod_man, DSP_TRACESEC_END, &s->shm0_end);
317 #else
318  status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM, &s->shm0_end);
319 #endif
320  if (status)
321  goto free_symbol;
322 
323  status = cod_get_sym_value(cod_man, DYNEXTBASE, &s->dyn_ext);
324  if (status)
325  goto free_symbol;
326 
327  status = cod_get_sym_value(cod_man, EXTEND, &s->ext_end);
328  if (status)
329  goto free_symbol;
330 
331  return s;
332 
333 free_symbol:
334  kfree(s);
335  return ERR_PTR(status);
336 }
337 
338 /*
339  * ======== bridge_io_on_loaded ========
340  * Purpose:
341  * Called when a new program is loaded to get shared memory buffer
342  * parameters from COFF file. ulSharedBufferBase and ulSharedBufferLimit
343  * are in DSP address units.
344  */
345 int bridge_io_on_loaded(struct io_mgr *hio_mgr)
346 {
347  struct bridge_dev_context *dc = hio_mgr->bridge_context;
348  struct cfg_hostres *cfg_res = dc->resources;
349  struct bridge_ioctl_extproc *eproc;
350  struct cod_manager *cod_man;
351  struct chnl_mgr *hchnl_mgr;
352  struct msg_mgr *hmsg_mgr;
353  struct shm_symbol_val *s;
354  int status;
355  u8 num_procs;
356  s32 ndx;
357  u32 i;
358  u32 mem_sz, msg_sz, pad_sz, shm_sz, shm_base_offs;
359  u32 seg0_sz, seg1_sz;
360  u32 pa, va, da;
361  u32 pa_curr, va_curr, da_curr;
362  u32 bytes;
363  u32 all_bits = 0;
364  u32 page_size[] = {
367  };
370 
371  status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man);
372  if (status)
373  return status;
374 
375  hchnl_mgr = hio_mgr->chnl_mgr;
376 
377  /* The message manager is destroyed when the board is stopped */
378  dev_get_msg_mgr(hio_mgr->dev_obj, &hio_mgr->msg_mgr);
379  hmsg_mgr = hio_mgr->msg_mgr;
380  if (!hchnl_mgr || !hmsg_mgr)
381  return -EFAULT;
382 
383  if (hio_mgr->shared_mem)
384  hio_mgr->shared_mem = NULL;
385 
386  s = _get_shm_symbol_values(hio_mgr);
387  if (IS_ERR(s))
388  return PTR_ERR(s);
389 
390  /* Get total length in bytes */
391  shm_sz = (s->shm_lim - s->shm_base + 1) * hio_mgr->word_size;
392 
393  /* Calculate size of a PROCCOPY shared memory region */
394  dev_dbg(bridge, "%s: (proc)proccopy shmmem size: 0x%x bytes\n",
395  __func__, shm_sz - sizeof(struct shm));
396 
397  /* Length (bytes) of messaging part of shared memory */
398  msg_sz = (s->msg_lim - s->msg_base + 1) * hio_mgr->word_size;
399 
400  /* Total length (bytes) of shared memory: chnl + msg */
401  mem_sz = shm_sz + msg_sz;
402 
403  /* Get memory reserved in host resources */
404  (void)mgr_enum_processor_info(0,
405  (struct dsp_processorinfo *)
406  &hio_mgr->ext_proc_info,
407  sizeof(struct mgr_processorextinfo),
408  &num_procs);
409 
410  /* IO supports only one DSP for now */
411  if (num_procs != 1) {
412  status = -EINVAL;
413  goto free_symbol;
414  }
415 
416  /* The first MMU TLB entry(TLB_0) in DCD is ShmBase */
417  pa = cfg_res->mem_phys[1];
418  va = cfg_res->mem_base[1];
419 
420  /* This is the virtual uncached ioremapped address!!! */
421  /* Why can't we directly take the DSPVA from the symbols? */
422  da = hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt;
423  seg0_sz = (s->shm0_end - da) * hio_mgr->word_size;
424  seg1_sz = (s->ext_end - s->dyn_ext) * hio_mgr->word_size;
425 
426  /* 4K align */
427  seg1_sz = (seg1_sz + 0xFFF) & (~0xFFFUL);
428 
429  /* 64K align */
430  seg0_sz = (seg0_sz + 0xFFFF) & (~0xFFFFUL);
431 
432  pad_sz = UL_PAGE_ALIGN_SIZE - ((pa + seg1_sz) % UL_PAGE_ALIGN_SIZE);
433  if (pad_sz == UL_PAGE_ALIGN_SIZE)
434  pad_sz = 0x0;
435 
436  dev_dbg(bridge, "%s: pa %x, va %x, da %x\n", __func__, pa, va, da);
437  dev_dbg(bridge,
438  "shm0_end %x, dyn_ext %x, ext_end %x, seg0_sz %x seg1_sz %x\n",
439  s->shm0_end, s->dyn_ext, s->ext_end, seg0_sz, seg1_sz);
440 
441  if ((seg0_sz + seg1_sz + pad_sz) > cfg_res->mem_length[1]) {
442  pr_err("%s: shm Error, reserved 0x%x required 0x%x\n",
443  __func__, cfg_res->mem_length[1],
444  seg0_sz + seg1_sz + pad_sz);
445  status = -ENOMEM;
446  goto free_symbol;
447  }
448 
449  pa_curr = pa;
450  va_curr = s->dyn_ext * hio_mgr->word_size;
451  da_curr = va;
452  bytes = seg1_sz;
453 
454  /*
455  * Try to fit into TLB entries. If not possible, push them to page
456  * tables. It is quite possible that if sections are not on
457  * bigger page boundary, we may end up making several small pages.
458  * So, push them onto page tables, if that is the case.
459  */
460  while (bytes) {
461  /*
462  * To find the max. page size with which both PA & VA are
463  * aligned.
464  */
465  all_bits = pa_curr | va_curr;
466  dev_dbg(bridge,
467  "seg all_bits %x, pa_curr %x, va_curr %x, bytes %x\n",
468  all_bits, pa_curr, va_curr, bytes);
469 
470  for (i = 0; i < 4; i++) {
471  if ((bytes >= page_size[i]) &&
472  ((all_bits & (page_size[i] - 1)) == 0)) {
473  status = hio_mgr->intf_fxns->brd_mem_map(dc,
474  pa_curr, va_curr,
475  page_size[i], map_attrs,
476  NULL);
477  if (status)
478  goto free_symbol;
479 
480  pa_curr += page_size[i];
481  va_curr += page_size[i];
482  da_curr += page_size[i];
483  bytes -= page_size[i];
484  /*
485  * Don't try smaller sizes. Hopefully we have
486  * reached an address aligned to a bigger page
487  * size.
488  */
489  break;
490  }
491  }
492  }
493 
494  pa_curr += pad_sz;
495  va_curr += pad_sz;
496  da_curr += pad_sz;
497  bytes = seg0_sz;
498  va_curr = da * hio_mgr->word_size;
499 
500  eproc = kzalloc(sizeof(*eproc) * BRDIOCTL_NUMOFMMUTLB, GFP_KERNEL);
501  if (!eproc) {
502  status = -ENOMEM;
503  goto free_symbol;
504  }
505 
506  ndx = 0;
507  /* Configure the TLB entries for the next cacheable segment */
508  while (bytes) {
509  /*
510  * To find the max. page size with which both PA & VA are
511  * aligned.
512  */
513  all_bits = pa_curr | va_curr;
514  dev_dbg(bridge,
515  "seg1 all_bits %x, pa_curr %x, va_curr %x, bytes %x\n",
516  all_bits, pa_curr, va_curr, bytes);
517 
518  for (i = 0; i < 4; i++) {
519  if (!(bytes >= page_size[i]) ||
520  !((all_bits & (page_size[i] - 1)) == 0))
521  continue;
522 
523  if (ndx >= MAX_LOCK_TLB_ENTRIES) {
524  status = hio_mgr->intf_fxns->brd_mem_map(dc,
525  pa_curr, va_curr,
526  page_size[i], map_attrs,
527  NULL);
528  dev_dbg(bridge,
529  "PTE pa %x va %x dsp_va %x sz %x\n",
530  eproc[ndx].gpp_pa,
531  eproc[ndx].gpp_va,
532  eproc[ndx].dsp_va *
533  hio_mgr->word_size, page_size[i]);
534  if (status)
535  goto free_eproc;
536  }
537 
538  /* This is the physical address written to DSP MMU */
539  eproc[ndx].gpp_pa = pa_curr;
540 
541  /*
542  * This is the virtual uncached ioremapped
543  * address!!!
544  */
545  eproc[ndx].gpp_va = da_curr;
546  eproc[ndx].dsp_va = va_curr / hio_mgr->word_size;
547  eproc[ndx].size = page_size[i];
548  eproc[ndx].endianism = HW_LITTLE_ENDIAN;
549  eproc[ndx].elem_size = HW_ELEM_SIZE16BIT;
550  eproc[ndx].mixed_mode = HW_MMU_CPUES;
551  dev_dbg(bridge, "%s: tlb pa %x va %x dsp_va %x sz %x\n",
552  __func__, eproc[ndx].gpp_pa,
553  eproc[ndx].gpp_va,
554  eproc[ndx].dsp_va * hio_mgr->word_size,
555  page_size[i]);
556  ndx++;
557 
558  pa_curr += page_size[i];
559  va_curr += page_size[i];
560  da_curr += page_size[i];
561  bytes -= page_size[i];
562  /*
563  * Don't try smaller sizes. Hopefully we have reached
564  * an address aligned to a bigger page size.
565  */
566  break;
567  }
568  }
569 
570  /*
571  * Copy remaining entries from CDB. All entries are 1 MB and
572  * should not conflict with shm entries on MPU or DSP side.
573  */
574  for (i = 3; i < 7 && ndx < BRDIOCTL_NUMOFMMUTLB; i++) {
575  struct mgr_processorextinfo *ep = &hio_mgr->ext_proc_info;
576  u32 word_sz = hio_mgr->word_size;
577 
578  if (ep->ty_tlb[i].gpp_phys == 0)
579  continue;
580 
581  if ((ep->ty_tlb[i].gpp_phys > pa - 0x100000 &&
582  ep->ty_tlb[i].gpp_phys <= pa + seg0_sz) ||
583  (ep->ty_tlb[i].dsp_virt > da - 0x100000 / word_sz &&
584  ep->ty_tlb[i].dsp_virt <= da + seg0_sz / word_sz)) {
585  dev_dbg(bridge,
586  "err cdb%d pa %x da %x shm pa %x da %x sz %x\n",
587  i, ep->ty_tlb[i].gpp_phys,
588  ep->ty_tlb[i].dsp_virt, pa, da, seg0_sz);
589  status = -EPERM;
590  goto free_eproc;
591  }
592 
593  if (ndx >= MAX_LOCK_TLB_ENTRIES) {
594  status = hio_mgr->intf_fxns->brd_mem_map(dc,
595  ep->ty_tlb[i].gpp_phys,
596  ep->ty_tlb[i].dsp_virt,
597  0x100000, map_attrs, NULL);
598  if (status)
599  goto free_eproc;
600  }
601 
602  eproc[ndx].dsp_va = ep->ty_tlb[i].dsp_virt;
603  eproc[ndx].gpp_pa = ep->ty_tlb[i].gpp_phys;
604  eproc[ndx].gpp_va = 0;
605 
606  /* 1 MB */
607  eproc[ndx].size = 0x100000;
608  dev_dbg(bridge, "shm MMU entry pa %x da 0x%x\n",
609  eproc[ndx].gpp_pa, eproc[ndx].dsp_va);
610  ndx++;
611  }
612 
613  /* Map the L4 peripherals */
614  i = 0;
615  while (l4_peripheral_table[i].phys_addr) {
616  status = hio_mgr->intf_fxns->brd_mem_map(dc,
617  l4_peripheral_table[i].phys_addr,
618  l4_peripheral_table[i].dsp_virt_addr,
619  HW_PAGE_SIZE4KB, map_attrs, NULL);
620  if (status)
621  goto free_eproc;
622  i++;
623  }
624 
625  for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) {
626  eproc[i].dsp_va = 0;
627  eproc[i].gpp_pa = 0;
628  eproc[i].gpp_va = 0;
629  eproc[i].size = 0;
630  }
631 
632  /*
633  * Set the shm physical address entry (grayed out in CDB file)
634  * to the virtual uncached ioremapped address of shm reserved
635  * on MPU.
636  */
637  hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys =
638  (va + seg1_sz + pad_sz);
639 
640  /*
641  * Need shm Phys addr. IO supports only one DSP for now:
642  * num_procs = 1.
643  */
644  if (!hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys)
645  return -EFAULT;
646 
647  if (eproc[0].dsp_va > s->shm_base)
648  return -EPERM;
649 
650  /* shm_base may not be at ul_dsp_va address */
651  shm_base_offs = (s->shm_base - eproc[0].dsp_va) *
652  hio_mgr->word_size;
653  /*
654  * bridge_dev_ctrl() will set dev context dsp-mmu info. In
655  * bridge_brd_start() the MMU will be re-programed with MMU
656  * DSPVa-GPPPa pair info while DSP is in a known
657  * (reset) state.
658  */
659  status = hio_mgr->intf_fxns->dev_cntrl(hio_mgr->bridge_context,
660  BRDIOCTL_SETMMUCONFIG, eproc);
661  if (status)
662  goto free_eproc;
663 
664  s->shm_base = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys;
665  s->shm_base += shm_base_offs;
666  s->shm_base = (u32) MEM_LINEAR_ADDRESS((void *)s->shm_base,
667  mem_sz);
668  if (!s->shm_base) {
669  status = -EFAULT;
670  goto free_eproc;
671  }
672 
673  /* Register SM */
674  status = register_shm_segs(hio_mgr, cod_man, eproc[0].gpp_pa);
675 
676  hio_mgr->shared_mem = (struct shm *)s->shm_base;
677  hio_mgr->input = (u8 *) hio_mgr->shared_mem + sizeof(struct shm);
678  hio_mgr->output = hio_mgr->input + (shm_sz -
679  sizeof(struct shm)) / 2;
680  hio_mgr->sm_buf_size = hio_mgr->output - hio_mgr->input;
681 
682  /* Set up Shared memory addresses for messaging */
683  hio_mgr->msg_input_ctrl =
684  (struct msg_ctrl *)((u8 *) hio_mgr->shared_mem + shm_sz);
685  hio_mgr->msg_input =
686  (u8 *) hio_mgr->msg_input_ctrl + sizeof(struct msg_ctrl);
687  hio_mgr->msg_output_ctrl =
688  (struct msg_ctrl *)((u8 *) hio_mgr->msg_input_ctrl +
689  msg_sz / 2);
690  hio_mgr->msg_output =
691  (u8 *) hio_mgr->msg_output_ctrl + sizeof(struct msg_ctrl);
692  hmsg_mgr->max_msgs =
693  ((u8 *) hio_mgr->msg_output_ctrl - hio_mgr->msg_input) /
694  sizeof(struct msg_dspmsg);
695 
696  dev_dbg(bridge, "IO MGR shm details: shared_mem %p, input %p, "
697  "output %p, msg_input_ctrl %p, msg_input %p, "
698  "msg_output_ctrl %p, msg_output %p\n",
699  (u8 *) hio_mgr->shared_mem, hio_mgr->input,
700  hio_mgr->output, (u8 *) hio_mgr->msg_input_ctrl,
701  hio_mgr->msg_input, (u8 *) hio_mgr->msg_output_ctrl,
702  hio_mgr->msg_output);
703  dev_dbg(bridge, "(proc) Mas msgs in shared memory: 0x%x\n",
704  hmsg_mgr->max_msgs);
705  memset((void *)hio_mgr->shared_mem, 0, sizeof(struct shm));
706 
707 #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
708  /* Get the start address of trace buffer */
709  status = cod_get_sym_value(cod_man, SYS_PUTCBEG,
710  &hio_mgr->trace_buffer_begin);
711  if (status)
712  goto free_eproc;
713 
714  hio_mgr->gpp_read_pointer =
715  hio_mgr->trace_buffer_begin =
716  (va + seg1_sz + pad_sz) +
717  (hio_mgr->trace_buffer_begin - da);
718 
719  /* Get the end address of trace buffer */
720  status = cod_get_sym_value(cod_man, SYS_PUTCEND,
721  &hio_mgr->trace_buffer_end);
722  if (status)
723  goto free_eproc;
724 
725  hio_mgr->trace_buffer_end =
726  (va + seg1_sz + pad_sz) +
727  (hio_mgr->trace_buffer_end - da);
728 
729  /* Get the current address of DSP write pointer */
730  status = cod_get_sym_value(cod_man, BRIDGE_SYS_PUTC_CURRENT,
731  &hio_mgr->trace_buffer_current);
732  if (status)
733  goto free_eproc;
734 
735  hio_mgr->trace_buffer_current =
736  (va + seg1_sz + pad_sz) +
737  (hio_mgr->trace_buffer_current - da);
738 
739  /* Calculate the size of trace buffer */
740  kfree(hio_mgr->msg);
741  hio_mgr->msg = kmalloc(((hio_mgr->trace_buffer_end -
742  hio_mgr->trace_buffer_begin) *
743  hio_mgr->word_size) + 2, GFP_KERNEL);
744  if (!hio_mgr->msg) {
745  status = -ENOMEM;
746  goto free_eproc;
747  }
748 
749  hio_mgr->dsp_va = da;
750  hio_mgr->gpp_va = (va + seg1_sz + pad_sz);
751 #endif
752 
753 free_eproc:
754  kfree(eproc);
755 free_symbol:
756  kfree(s);
757 
758  return status;
759 }
760 
761 /*
762  * ======== io_buf_size ========
763  * Size of shared memory I/O channel.
764  */
765 u32 io_buf_size(struct io_mgr *hio_mgr)
766 {
767  if (hio_mgr)
768  return hio_mgr->sm_buf_size;
769  else
770  return 0;
771 }
772 
773 /*
774  * ======== io_cancel_chnl ========
775  * Cancel IO on a given PCPY channel.
776  */
777 void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl)
778 {
779  struct io_mgr *pio_mgr = (struct io_mgr *)hio_mgr;
780  struct shm *sm;
781 
782  if (!hio_mgr)
783  goto func_end;
784  sm = hio_mgr->shared_mem;
785 
786  /* Inform DSP that we have no more buffers on this channel */
787  set_chnl_free(sm, chnl);
788 
790 func_end:
791  return;
792 }
793 
794 
795 /*
796  * ======== io_dispatch_pm ========
797  * Performs I/O dispatch on PM related messages from DSP
798  */
799 static void io_dispatch_pm(struct io_mgr *pio_mgr)
800 {
801  int status;
802  u32 parg[2];
803 
804  /* Perform Power message processing here */
805  parg[0] = pio_mgr->intr_val;
806 
807  /* Send the command to the Bridge clk/pwr manager to handle */
808  if (parg[0] == MBX_PM_HIBERNATE_EN) {
809  dev_dbg(bridge, "PM: Hibernate command\n");
810  status = pio_mgr->intf_fxns->
811  dev_cntrl(pio_mgr->bridge_context,
812  BRDIOCTL_PWR_HIBERNATE, parg);
813  if (status)
814  pr_err("%s: hibernate cmd failed 0x%x\n",
815  __func__, status);
816  } else if (parg[0] == MBX_PM_OPP_REQ) {
817  parg[1] = pio_mgr->shared_mem->opp_request.rqst_opp_pt;
818  dev_dbg(bridge, "PM: Requested OPP = 0x%x\n", parg[1]);
819  status = pio_mgr->intf_fxns->
820  dev_cntrl(pio_mgr->bridge_context,
822  if (status)
823  dev_dbg(bridge, "PM: Failed to set constraint "
824  "= 0x%x\n", parg[1]);
825  } else {
826  dev_dbg(bridge, "PM: clk control value of msg = 0x%x\n",
827  parg[0]);
828  status = pio_mgr->intf_fxns->
829  dev_cntrl(pio_mgr->bridge_context,
830  BRDIOCTL_CLK_CTRL, parg);
831  if (status)
832  dev_dbg(bridge, "PM: Failed to ctrl the DSP clk"
833  "= 0x%x\n", *parg);
834  }
835 }
836 
837 /*
838  * ======== io_dpc ========
839  * Deferred procedure call for shared memory channel driver ISR. Carries
840  * out the dispatch of I/O as a non-preemptible event. It can only be
841  * pre-empted by an ISR.
842  */
843 void io_dpc(unsigned long ref_data)
844 {
845  struct io_mgr *pio_mgr = (struct io_mgr *)ref_data;
846  struct chnl_mgr *chnl_mgr_obj;
847  struct msg_mgr *msg_mgr_obj;
848  struct deh_mgr *hdeh_mgr;
849  u32 requested;
850  u32 serviced;
851 
852  if (!pio_mgr)
853  goto func_end;
854  chnl_mgr_obj = pio_mgr->chnl_mgr;
855  dev_get_msg_mgr(pio_mgr->dev_obj, &msg_mgr_obj);
856  dev_get_deh_mgr(pio_mgr->dev_obj, &hdeh_mgr);
857  if (!chnl_mgr_obj)
858  goto func_end;
859 
860  requested = pio_mgr->dpc_req;
861  serviced = pio_mgr->dpc_sched;
862 
863  if (serviced == requested)
864  goto func_end;
865 
866  /* Process pending DPC's */
867  do {
868  /* Check value of interrupt reg to ensure it's a valid error */
869  if ((pio_mgr->intr_val > DEH_BASE) &&
870  (pio_mgr->intr_val < DEH_LIMIT)) {
871  /* Notify DSP/BIOS exception */
872  if (hdeh_mgr) {
873 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
874  print_dsp_debug_trace(pio_mgr);
875 #endif
877  pio_mgr->intr_val);
878  }
879  }
880  /* Proc-copy channel dispatch */
881  input_chnl(pio_mgr, NULL, IO_SERVICE);
882  output_chnl(pio_mgr, NULL, IO_SERVICE);
883 
884 #ifdef CHNL_MESSAGES
885  if (msg_mgr_obj) {
886  /* Perform I/O dispatch on message queues */
887  input_msg(pio_mgr, msg_mgr_obj);
888  output_msg(pio_mgr, msg_mgr_obj);
889  }
890 
891 #endif
892 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
893  if (pio_mgr->intr_val & MBX_DBG_SYSPRINTF) {
894  /* Notify DSP Trace message */
895  print_dsp_debug_trace(pio_mgr);
896  }
897 #endif
898  serviced++;
899  } while (serviced != requested);
900  pio_mgr->dpc_sched = requested;
901 func_end:
902  return;
903 }
904 
905 /*
906  * ======== io_mbox_msg ========
907  * Main interrupt handler for the shared memory IO manager.
908  * Calls the Bridge's CHNL_ISR to determine if this interrupt is ours, then
909  * schedules a DPC to dispatch I/O.
910  */
911 int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg)
912 {
913  struct io_mgr *pio_mgr;
914  struct dev_object *dev_obj;
915  unsigned long flags;
916 
917  dev_obj = dev_get_first();
918  dev_get_io_mgr(dev_obj, &pio_mgr);
919 
920  if (!pio_mgr)
921  return NOTIFY_BAD;
922 
923  pio_mgr->intr_val = (u16)((u32)msg);
924  if (pio_mgr->intr_val & MBX_PM_CLASS)
925  io_dispatch_pm(pio_mgr);
926 
927  if (pio_mgr->intr_val == MBX_DEH_RESET) {
928  pio_mgr->intr_val = 0;
929  } else {
930  spin_lock_irqsave(&pio_mgr->dpc_lock, flags);
931  pio_mgr->dpc_req++;
932  spin_unlock_irqrestore(&pio_mgr->dpc_lock, flags);
933  tasklet_schedule(&pio_mgr->dpc_tasklet);
934  }
935  return NOTIFY_OK;
936 }
937 
938 /*
939  * ======== io_request_chnl ========
940  * Purpose:
941  * Request channel I/O from the DSP. Sets flags in shared memory, then
942  * interrupts the DSP.
943  */
944 void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl,
945  u8 io_mode, u16 *mbx_val)
946 {
947  struct chnl_mgr *chnl_mgr_obj;
948  struct shm *sm;
949 
950  if (!pchnl || !mbx_val)
951  goto func_end;
952  chnl_mgr_obj = io_manager->chnl_mgr;
953  sm = io_manager->shared_mem;
954  if (io_mode == IO_INPUT) {
955  /* Indicate to the DSP we have a buffer available for input */
956  set_chnl_busy(sm, pchnl->chnl_id);
957  *mbx_val = MBX_PCPY_CLASS;
958  } else if (io_mode == IO_OUTPUT) {
959  /*
960  * Record the fact that we have a buffer available for
961  * output.
962  */
963  chnl_mgr_obj->output_mask |= (1 << pchnl->chnl_id);
964  } else {
965  }
966 func_end:
967  return;
968 }
969 
970 /*
971  * ======== iosm_schedule ========
972  * Schedule DPC for IO.
973  */
974 void iosm_schedule(struct io_mgr *io_manager)
975 {
976  unsigned long flags;
977 
978  if (!io_manager)
979  return;
980 
981  /* Increment count of DPC's pending. */
982  spin_lock_irqsave(&io_manager->dpc_lock, flags);
983  io_manager->dpc_req++;
984  spin_unlock_irqrestore(&io_manager->dpc_lock, flags);
985 
986  /* Schedule DPC */
987  tasklet_schedule(&io_manager->dpc_tasklet);
988 }
989 
990 /*
991  * ======== find_ready_output ========
992  * Search for a host output channel which is ready to send. If this is
993  * called as a result of servicing the DPC, then implement a round
994  * robin search; otherwise, this was called by a client thread (via
995  * IO_Dispatch()), so just start searching from the current channel id.
996  */
997 static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj,
998  struct chnl_object *pchnl, u32 mask)
999 {
1001  u32 id, start_id;
1002  u32 shift;
1003 
1004  id = (pchnl !=
1005  NULL ? pchnl->chnl_id : (chnl_mgr_obj->last_output + 1));
1006  id = ((id == CHNL_MAXCHANNELS) ? 0 : id);
1007  if (id >= CHNL_MAXCHANNELS)
1008  goto func_end;
1009  if (mask) {
1010  shift = (1 << id);
1011  start_id = id;
1012  do {
1013  if (mask & shift) {
1014  ret = id;
1015  if (pchnl == NULL)
1016  chnl_mgr_obj->last_output = id;
1017  break;
1018  }
1019  id = id + 1;
1020  id = ((id == CHNL_MAXCHANNELS) ? 0 : id);
1021  shift = (1 << id);
1022  } while (id != start_id);
1023  }
1024 func_end:
1025  return ret;
1026 }
1027 
1028 /*
1029  * ======== input_chnl ========
1030  * Dispatch a buffer on an input channel.
1031  */
1032 static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
1033  u8 io_mode)
1034 {
1035  struct chnl_mgr *chnl_mgr_obj;
1036  struct shm *sm;
1037  u32 chnl_id;
1038  u32 bytes;
1039  struct chnl_irp *chnl_packet_obj = NULL;
1040  u32 dw_arg;
1041  bool clear_chnl = false;
1042  bool notify_client = false;
1043 
1044  sm = pio_mgr->shared_mem;
1045  chnl_mgr_obj = pio_mgr->chnl_mgr;
1046 
1047  /* Attempt to perform input */
1048  if (!sm->input_full)
1049  goto func_end;
1050 
1051  bytes = sm->input_size * chnl_mgr_obj->word_size;
1052  chnl_id = sm->input_id;
1053  dw_arg = sm->arg;
1054  if (chnl_id >= CHNL_MAXCHANNELS) {
1055  /* Shouldn't be here: would indicate corrupted shm. */
1056  goto func_end;
1057  }
1058  pchnl = chnl_mgr_obj->channels[chnl_id];
1059  if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) {
1060  if ((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY) {
1061  /* Get the I/O request, and attempt a transfer */
1062  if (!list_empty(&pchnl->io_requests)) {
1063  if (!pchnl->cio_reqs)
1064  goto func_end;
1065 
1066  chnl_packet_obj = list_first_entry(
1067  &pchnl->io_requests,
1068  struct chnl_irp, link);
1069  list_del(&chnl_packet_obj->link);
1070  pchnl->cio_reqs--;
1071 
1072  /*
1073  * Ensure we don't overflow the client's
1074  * buffer.
1075  */
1076  bytes = min(bytes, chnl_packet_obj->byte_size);
1077  memcpy(chnl_packet_obj->host_sys_buf,
1078  pio_mgr->input, bytes);
1079  pchnl->bytes_moved += bytes;
1080  chnl_packet_obj->byte_size = bytes;
1081  chnl_packet_obj->arg = dw_arg;
1082  chnl_packet_obj->status = CHNL_IOCSTATCOMPLETE;
1083 
1084  if (bytes == 0) {
1085  /*
1086  * This assertion fails if the DSP
1087  * sends EOS more than once on this
1088  * channel.
1089  */
1090  if (pchnl->state & CHNL_STATEEOS)
1091  goto func_end;
1092  /*
1093  * Zero bytes indicates EOS. Update
1094  * IOC status for this chirp, and also
1095  * the channel state.
1096  */
1097  chnl_packet_obj->status |=
1099  pchnl->state |= CHNL_STATEEOS;
1100  /*
1101  * Notify that end of stream has
1102  * occurred.
1103  */
1104  ntfy_notify(pchnl->ntfy_obj,
1105  DSP_STREAMDONE);
1106  }
1107  /* Tell DSP if no more I/O buffers available */
1108  if (list_empty(&pchnl->io_requests))
1109  set_chnl_free(sm, pchnl->chnl_id);
1110  clear_chnl = true;
1111  notify_client = true;
1112  } else {
1113  /*
1114  * Input full for this channel, but we have no
1115  * buffers available. The channel must be
1116  * "idling". Clear out the physical input
1117  * channel.
1118  */
1119  clear_chnl = true;
1120  }
1121  } else {
1122  /* Input channel cancelled: clear input channel */
1123  clear_chnl = true;
1124  }
1125  } else {
1126  /* DPC fired after host closed channel: clear input channel */
1127  clear_chnl = true;
1128  }
1129  if (clear_chnl) {
1130  /* Indicate to the DSP we have read the input */
1131  sm->input_full = 0;
1133  }
1134  if (notify_client) {
1135  /* Notify client with IO completion record */
1136  notify_chnl_complete(pchnl, chnl_packet_obj);
1137  }
1138 func_end:
1139  return;
1140 }
1141 
1142 /*
1143  * ======== input_msg ========
1144  * Copies messages from shared memory to the message queues.
1145  */
1146 static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
1147 {
1148  u32 num_msgs;
1149  u32 i;
1150  u8 *msg_input;
1151  struct msg_queue *msg_queue_obj;
1152  struct msg_frame *pmsg;
1153  struct msg_dspmsg msg;
1154  struct msg_ctrl *msg_ctr_obj;
1155  u32 input_empty;
1156  u32 addr;
1157 
1158  msg_ctr_obj = pio_mgr->msg_input_ctrl;
1159  /* Get the number of input messages to be read */
1160  input_empty = msg_ctr_obj->buf_empty;
1161  num_msgs = msg_ctr_obj->size;
1162  if (input_empty)
1163  return;
1164 
1165  msg_input = pio_mgr->msg_input;
1166  for (i = 0; i < num_msgs; i++) {
1167  /* Read the next message */
1168  addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.cmd);
1169  msg.msg.cmd =
1170  read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
1171  addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg1);
1172  msg.msg.arg1 =
1173  read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
1174  addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg2);
1175  msg.msg.arg2 =
1176  read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
1177  addr = (u32) &(((struct msg_dspmsg *)msg_input)->msgq_id);
1178  msg.msgq_id =
1179  read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
1180  msg_input += sizeof(struct msg_dspmsg);
1181 
1182  /* Determine which queue to put the message in */
1183  dev_dbg(bridge, "input msg: cmd=0x%x arg1=0x%x "
1184  "arg2=0x%x msgq_id=0x%x\n", msg.msg.cmd,
1185  msg.msg.arg1, msg.msg.arg2, msg.msgq_id);
1186  /*
1187  * Interrupt may occur before shared memory and message
1188  * input locations have been set up. If all nodes were
1189  * cleaned up, hmsg_mgr->max_msgs should be 0.
1190  */
1191  list_for_each_entry(msg_queue_obj, &hmsg_mgr->queue_list,
1192  list_elem) {
1193  if (msg.msgq_id != msg_queue_obj->msgq_id)
1194  continue;
1195  /* Found it */
1196  if (msg.msg.cmd == RMS_EXITACK) {
1197  /*
1198  * Call the node exit notification.
1199  * The exit message does not get
1200  * queued.
1201  */
1202  (*hmsg_mgr->on_exit)(msg_queue_obj->arg,
1203  msg.msg.arg1);
1204  break;
1205  }
1206  /*
1207  * Not an exit acknowledgement, queue
1208  * the message.
1209  */
1210  if (list_empty(&msg_queue_obj->msg_free_list)) {
1211  /*
1212  * No free frame to copy the
1213  * message into.
1214  */
1215  pr_err("%s: no free msg frames,"
1216  " discarding msg\n",
1217  __func__);
1218  break;
1219  }
1220 
1221  pmsg = list_first_entry(&msg_queue_obj->msg_free_list,
1222  struct msg_frame, list_elem);
1223  list_del(&pmsg->list_elem);
1224  pmsg->msg_data = msg;
1225  list_add_tail(&pmsg->list_elem,
1226  &msg_queue_obj->msg_used_list);
1227  ntfy_notify(msg_queue_obj->ntfy_obj,
1229  sync_set_event(msg_queue_obj->sync_event);
1230  }
1231  }
1232  /* Set the post SWI flag */
1233  if (num_msgs > 0) {
1234  /* Tell the DSP we've read the messages */
1235  msg_ctr_obj->buf_empty = true;
1236  msg_ctr_obj->post_swi = true;
1238  }
1239 }
1240 
1241 /*
1242  * ======== notify_chnl_complete ========
1243  * Purpose:
1244  * Signal the channel event, notifying the client that I/O has completed.
1245  */
1246 static void notify_chnl_complete(struct chnl_object *pchnl,
1247  struct chnl_irp *chnl_packet_obj)
1248 {
1249  bool signal_event;
1250 
1251  if (!pchnl || !pchnl->sync_event || !chnl_packet_obj)
1252  goto func_end;
1253 
1254  /*
1255  * Note: we signal the channel event only if the queue of IO
1256  * completions is empty. If it is not empty, the event is sure to be
1257  * signalled by the only IO completion list consumer:
1258  * bridge_chnl_get_ioc().
1259  */
1260  signal_event = list_empty(&pchnl->io_completions);
1261  /* Enqueue the IO completion info for the client */
1262  list_add_tail(&chnl_packet_obj->link, &pchnl->io_completions);
1263  pchnl->cio_cs++;
1264 
1265  if (pchnl->cio_cs > pchnl->chnl_packets)
1266  goto func_end;
1267  /* Signal the channel event (if not already set) that IO is complete */
1268  if (signal_event)
1269  sync_set_event(pchnl->sync_event);
1270 
1271  /* Notify that IO is complete */
1272  ntfy_notify(pchnl->ntfy_obj, DSP_STREAMIOCOMPLETION);
1273 func_end:
1274  return;
1275 }
1276 
1277 /*
1278  * ======== output_chnl ========
1279  * Purpose:
1280  * Dispatch a buffer on an output channel.
1281  */
1282 static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
1283  u8 io_mode)
1284 {
1285  struct chnl_mgr *chnl_mgr_obj;
1286  struct shm *sm;
1287  u32 chnl_id;
1288  struct chnl_irp *chnl_packet_obj;
1289  u32 dw_dsp_f_mask;
1290 
1291  chnl_mgr_obj = pio_mgr->chnl_mgr;
1292  sm = pio_mgr->shared_mem;
1293  /* Attempt to perform output */
1294  if (sm->output_full)
1295  goto func_end;
1296 
1297  if (pchnl && !((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY))
1298  goto func_end;
1299 
1300  /* Look to see if both a PC and DSP output channel are ready */
1301  dw_dsp_f_mask = sm->dsp_free_mask;
1302  chnl_id =
1303  find_ready_output(chnl_mgr_obj, pchnl,
1304  (chnl_mgr_obj->output_mask & dw_dsp_f_mask));
1305  if (chnl_id == OUTPUTNOTREADY)
1306  goto func_end;
1307 
1308  pchnl = chnl_mgr_obj->channels[chnl_id];
1309  if (!pchnl || list_empty(&pchnl->io_requests)) {
1310  /* Shouldn't get here */
1311  goto func_end;
1312  }
1313 
1314  if (!pchnl->cio_reqs)
1315  goto func_end;
1316 
1317  /* Get the I/O request, and attempt a transfer */
1318  chnl_packet_obj = list_first_entry(&pchnl->io_requests,
1319  struct chnl_irp, link);
1320  list_del(&chnl_packet_obj->link);
1321 
1322  pchnl->cio_reqs--;
1323 
1324  /* Record fact that no more I/O buffers available */
1325  if (list_empty(&pchnl->io_requests))
1326  chnl_mgr_obj->output_mask &= ~(1 << chnl_id);
1327 
1328  /* Transfer buffer to DSP side */
1329  chnl_packet_obj->byte_size = min(pio_mgr->sm_buf_size,
1330  chnl_packet_obj->byte_size);
1331  memcpy(pio_mgr->output, chnl_packet_obj->host_sys_buf,
1332  chnl_packet_obj->byte_size);
1333  pchnl->bytes_moved += chnl_packet_obj->byte_size;
1334  /* Write all 32 bits of arg */
1335  sm->arg = chnl_packet_obj->arg;
1336 #if _CHNL_WORDSIZE == 2
1337  /* Access can be different SM access word size (e.g. 16/32 bit words) */
1338  sm->output_id = (u16) chnl_id;
1339  sm->output_size = (u16) (chnl_packet_obj->byte_size +
1340  chnl_mgr_obj->word_size - 1) /
1341  (u16) chnl_mgr_obj->word_size;
1342 #else
1343  sm->output_id = chnl_id;
1344  sm->output_size = (chnl_packet_obj->byte_size +
1345  chnl_mgr_obj->word_size - 1) / chnl_mgr_obj->word_size;
1346 #endif
1347  sm->output_full = 1;
1348  /* Indicate to the DSP we have written the output */
1350  /* Notify client with IO completion record (keep EOS) */
1351  chnl_packet_obj->status &= CHNL_IOCSTATEOS;
1352  notify_chnl_complete(pchnl, chnl_packet_obj);
1353  /* Notify if stream is done. */
1354  if (chnl_packet_obj->status & CHNL_IOCSTATEOS)
1355  ntfy_notify(pchnl->ntfy_obj, DSP_STREAMDONE);
1356 
1357 func_end:
1358  return;
1359 }
1360 
1361 /*
1362  * ======== output_msg ========
1363  * Copies messages from the message queues to the shared memory.
1364  */
1365 static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
1366 {
1367  u32 num_msgs = 0;
1368  u32 i;
1369  struct msg_dspmsg *msg_output;
1370  struct msg_frame *pmsg;
1371  struct msg_ctrl *msg_ctr_obj;
1372  u32 val;
1373  u32 addr;
1374 
1375  msg_ctr_obj = pio_mgr->msg_output_ctrl;
1376 
1377  /* Check if output has been cleared */
1378  if (!msg_ctr_obj->buf_empty)
1379  return;
1380 
1381  num_msgs = (hmsg_mgr->msgs_pending > hmsg_mgr->max_msgs) ?
1382  hmsg_mgr->max_msgs : hmsg_mgr->msgs_pending;
1383  msg_output = (struct msg_dspmsg *) pio_mgr->msg_output;
1384 
1385  /* Copy num_msgs messages into shared memory */
1386  for (i = 0; i < num_msgs; i++) {
1387  if (list_empty(&hmsg_mgr->msg_used_list))
1388  continue;
1389 
1390  pmsg = list_first_entry(&hmsg_mgr->msg_used_list,
1391  struct msg_frame, list_elem);
1392  list_del(&pmsg->list_elem);
1393 
1394  val = (pmsg->msg_data).msgq_id;
1395  addr = (u32) &msg_output->msgq_id;
1396  write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
1397 
1398  val = (pmsg->msg_data).msg.cmd;
1399  addr = (u32) &msg_output->msg.cmd;
1400  write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
1401 
1402  val = (pmsg->msg_data).msg.arg1;
1403  addr = (u32) &msg_output->msg.arg1;
1404  write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
1405 
1406  val = (pmsg->msg_data).msg.arg2;
1407  addr = (u32) &msg_output->msg.arg2;
1408  write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
1409 
1410  msg_output++;
1411  list_add_tail(&pmsg->list_elem, &hmsg_mgr->msg_free_list);
1412  sync_set_event(hmsg_mgr->sync_event);
1413  }
1414 
1415  if (num_msgs > 0) {
1416  hmsg_mgr->msgs_pending -= num_msgs;
1417 #if _CHNL_WORDSIZE == 2
1418  /*
1419  * Access can be different SM access word size
1420  * (e.g. 16/32 bit words)
1421  */
1422  msg_ctr_obj->size = (u16) num_msgs;
1423 #else
1424  msg_ctr_obj->size = num_msgs;
1425 #endif
1426  msg_ctr_obj->buf_empty = false;
1427  /* Set the post SWI flag */
1428  msg_ctr_obj->post_swi = true;
1429  /* Tell the DSP we have written the output. */
1431  }
1432 }
1433 
1434 /*
1435  * ======== register_shm_segs ========
1436  * purpose:
1437  * Registers GPP SM segment with CMM.
1438  */
1439 static int register_shm_segs(struct io_mgr *hio_mgr,
1440  struct cod_manager *cod_man,
1441  u32 dw_gpp_base_pa)
1442 {
1443  int status = 0;
1444  u32 ul_shm0_base = 0;
1445  u32 shm0_end = 0;
1446  u32 ul_shm0_rsrvd_start = 0;
1447  u32 ul_rsrvd_size = 0;
1448  u32 ul_gpp_phys;
1449  u32 ul_dsp_virt;
1450  u32 ul_shm_seg_id0 = 0;
1451  u32 dw_offset, dw_gpp_base_va, ul_dsp_size;
1452 
1453  /*
1454  * Read address and size info for first SM region.
1455  * Get start of 1st SM Heap region.
1456  */
1457  status =
1458  cod_get_sym_value(cod_man, SHM0_SHARED_BASE_SYM, &ul_shm0_base);
1459  if (ul_shm0_base == 0) {
1460  status = -EPERM;
1461  goto func_end;
1462  }
1463  /* Get end of 1st SM Heap region */
1464  if (!status) {
1465  /* Get start and length of message part of shared memory */
1466  status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM,
1467  &shm0_end);
1468  if (shm0_end == 0) {
1469  status = -EPERM;
1470  goto func_end;
1471  }
1472  }
1473  /* Start of Gpp reserved region */
1474  if (!status) {
1475  /* Get start and length of message part of shared memory */
1476  status =
1478  &ul_shm0_rsrvd_start);
1479  if (ul_shm0_rsrvd_start == 0) {
1480  status = -EPERM;
1481  goto func_end;
1482  }
1483  }
1484  /* Register with CMM */
1485  if (!status) {
1486  status = dev_get_cmm_mgr(hio_mgr->dev_obj, &hio_mgr->cmm_mgr);
1487  if (!status) {
1488  status = cmm_un_register_gppsm_seg(hio_mgr->cmm_mgr,
1489  CMM_ALLSEGMENTS);
1490  }
1491  }
1492  /* Register new SM region(s) */
1493  if (!status && (shm0_end - ul_shm0_base) > 0) {
1494  /* Calc size (bytes) of SM the GPP can alloc from */
1495  ul_rsrvd_size =
1496  (shm0_end - ul_shm0_rsrvd_start + 1) * hio_mgr->word_size;
1497  if (ul_rsrvd_size <= 0) {
1498  status = -EPERM;
1499  goto func_end;
1500  }
1501  /* Calc size of SM DSP can alloc from */
1502  ul_dsp_size =
1503  (ul_shm0_rsrvd_start - ul_shm0_base) * hio_mgr->word_size;
1504  if (ul_dsp_size <= 0) {
1505  status = -EPERM;
1506  goto func_end;
1507  }
1508  /* First TLB entry reserved for Bridge SM use. */
1509  ul_gpp_phys = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys;
1510  /* Get size in bytes */
1511  ul_dsp_virt =
1512  hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt *
1513  hio_mgr->word_size;
1514  /*
1515  * Calc byte offset used to convert GPP phys <-> DSP byte
1516  * address.
1517  */
1518  if (dw_gpp_base_pa > ul_dsp_virt)
1519  dw_offset = dw_gpp_base_pa - ul_dsp_virt;
1520  else
1521  dw_offset = ul_dsp_virt - dw_gpp_base_pa;
1522 
1523  if (ul_shm0_rsrvd_start * hio_mgr->word_size < ul_dsp_virt) {
1524  status = -EPERM;
1525  goto func_end;
1526  }
1527  /*
1528  * Calc Gpp phys base of SM region.
1529  * This is actually uncached kernel virtual address.
1530  */
1531  dw_gpp_base_va =
1532  ul_gpp_phys + ul_shm0_rsrvd_start * hio_mgr->word_size -
1533  ul_dsp_virt;
1534  /*
1535  * Calc Gpp phys base of SM region.
1536  * This is the physical address.
1537  */
1538  dw_gpp_base_pa =
1539  dw_gpp_base_pa + ul_shm0_rsrvd_start * hio_mgr->word_size -
1540  ul_dsp_virt;
1541  /* Register SM Segment 0. */
1542  status =
1543  cmm_register_gppsm_seg(hio_mgr->cmm_mgr, dw_gpp_base_pa,
1544  ul_rsrvd_size, dw_offset,
1545  (dw_gpp_base_pa >
1546  ul_dsp_virt) ? CMM_ADDTODSPPA :
1548  (u32) (ul_shm0_base *
1549  hio_mgr->word_size),
1550  ul_dsp_size, &ul_shm_seg_id0,
1551  dw_gpp_base_va);
1552  /* First SM region is seg_id = 1 */
1553  if (ul_shm_seg_id0 != 1)
1554  status = -EPERM;
1555  }
1556 func_end:
1557  return status;
1558 }
1559 
1560 /* ZCPY IO routines. */
1561 /*
1562  * ======== IO_SHMcontrol ========
1563  * Sets the requested shm setting.
1564  */
1565 int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs)
1566 {
1567 #ifdef CONFIG_TIDSPBRIDGE_DVFS
1568  u32 i;
1569  struct dspbridge_platform_data *pdata =
1570  omap_dspbridge_dev->dev.platform_data;
1571 
1572  switch (desc) {
1573  case SHM_CURROPP:
1574  /* Update the shared memory with requested OPP information */
1575  if (pargs != NULL)
1576  hio_mgr->shared_mem->opp_table_struct.curr_opp_pt =
1577  *(u32 *) pargs;
1578  else
1579  return -EPERM;
1580  break;
1581  case SHM_OPPINFO:
1582  /*
1583  * Update the shared memory with the voltage, frequency,
1584  * min and max frequency values for an OPP.
1585  */
1586  for (i = 0; i <= dsp_max_opps; i++) {
1587  hio_mgr->shared_mem->opp_table_struct.opp_point[i].
1588  voltage = vdd1_dsp_freq[i][0];
1589  dev_dbg(bridge, "OPP-shm: voltage: %d\n",
1590  vdd1_dsp_freq[i][0]);
1591  hio_mgr->shared_mem->opp_table_struct.
1592  opp_point[i].frequency = vdd1_dsp_freq[i][1];
1593  dev_dbg(bridge, "OPP-shm: frequency: %d\n",
1594  vdd1_dsp_freq[i][1]);
1595  hio_mgr->shared_mem->opp_table_struct.opp_point[i].
1596  min_freq = vdd1_dsp_freq[i][2];
1597  dev_dbg(bridge, "OPP-shm: min freq: %d\n",
1598  vdd1_dsp_freq[i][2]);
1599  hio_mgr->shared_mem->opp_table_struct.opp_point[i].
1600  max_freq = vdd1_dsp_freq[i][3];
1601  dev_dbg(bridge, "OPP-shm: max freq: %d\n",
1602  vdd1_dsp_freq[i][3]);
1603  }
1604  hio_mgr->shared_mem->opp_table_struct.num_opp_pts =
1605  dsp_max_opps;
1606  dev_dbg(bridge, "OPP-shm: max OPP number: %d\n", dsp_max_opps);
1607  /* Update the current OPP number */
1608  if (pdata->dsp_get_opp)
1609  i = (*pdata->dsp_get_opp) ();
1610  hio_mgr->shared_mem->opp_table_struct.curr_opp_pt = i;
1611  dev_dbg(bridge, "OPP-shm: value programmed = %d\n", i);
1612  break;
1613  case SHM_GETOPP:
1614  /* Get the OPP that DSP has requested */
1615  *(u32 *) pargs = hio_mgr->shared_mem->opp_request.rqst_opp_pt;
1616  break;
1617  default:
1618  break;
1619  }
1620 #endif
1621  return 0;
1622 }
1623 
1624 /*
1625  * ======== bridge_io_get_proc_load ========
1626  * Gets the Processor's Load information
1627  */
1628 int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
1629  struct dsp_procloadstat *proc_lstat)
1630 {
1631  if (!hio_mgr->shared_mem)
1632  return -EFAULT;
1633 
1634  proc_lstat->curr_load =
1635  hio_mgr->shared_mem->load_mon_info.curr_dsp_load;
1636  proc_lstat->predicted_load =
1637  hio_mgr->shared_mem->load_mon_info.pred_dsp_load;
1638  proc_lstat->curr_dsp_freq =
1639  hio_mgr->shared_mem->load_mon_info.curr_dsp_freq;
1640  proc_lstat->predicted_freq =
1641  hio_mgr->shared_mem->load_mon_info.pred_dsp_freq;
1642 
1643  dev_dbg(bridge, "Curr Load = %d, Pred Load = %d, Curr Freq = %d, "
1644  "Pred Freq = %d\n", proc_lstat->curr_load,
1645  proc_lstat->predicted_load, proc_lstat->curr_dsp_freq,
1646  proc_lstat->predicted_freq);
1647  return 0;
1648 }
1649 
1650 
1651 #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
1652 void print_dsp_debug_trace(struct io_mgr *hio_mgr)
1653 {
1654  u32 ul_new_message_length = 0, ul_gpp_cur_pointer;
1655 
1656  while (true) {
1657  /* Get the DSP current pointer */
1658  ul_gpp_cur_pointer =
1659  *(u32 *) (hio_mgr->trace_buffer_current);
1660  ul_gpp_cur_pointer =
1661  hio_mgr->gpp_va + (ul_gpp_cur_pointer -
1662  hio_mgr->dsp_va);
1663 
1664  /* No new debug messages available yet */
1665  if (ul_gpp_cur_pointer == hio_mgr->gpp_read_pointer) {
1666  break;
1667  } else if (ul_gpp_cur_pointer > hio_mgr->gpp_read_pointer) {
1668  /* Continuous data */
1669  ul_new_message_length =
1670  ul_gpp_cur_pointer - hio_mgr->gpp_read_pointer;
1671 
1672  memcpy(hio_mgr->msg,
1673  (char *)hio_mgr->gpp_read_pointer,
1674  ul_new_message_length);
1675  hio_mgr->msg[ul_new_message_length] = '\0';
1676  /*
1677  * Advance the GPP trace pointer to DSP current
1678  * pointer.
1679  */
1680  hio_mgr->gpp_read_pointer += ul_new_message_length;
1681  /* Print the trace messages */
1682  pr_info("DSPTrace: %s\n", hio_mgr->msg);
1683  } else if (ul_gpp_cur_pointer < hio_mgr->gpp_read_pointer) {
1684  /* Handle trace buffer wraparound */
1685  memcpy(hio_mgr->msg,
1686  (char *)hio_mgr->gpp_read_pointer,
1687  hio_mgr->trace_buffer_end -
1688  hio_mgr->gpp_read_pointer);
1689  ul_new_message_length =
1690  ul_gpp_cur_pointer - hio_mgr->trace_buffer_begin;
1691  memcpy(&hio_mgr->msg[hio_mgr->trace_buffer_end -
1692  hio_mgr->gpp_read_pointer],
1693  (char *)hio_mgr->trace_buffer_begin,
1694  ul_new_message_length);
1695  hio_mgr->msg[hio_mgr->trace_buffer_end -
1696  hio_mgr->gpp_read_pointer +
1697  ul_new_message_length] = '\0';
1698  /*
1699  * Advance the GPP trace pointer to DSP current
1700  * pointer.
1701  */
1702  hio_mgr->gpp_read_pointer =
1703  hio_mgr->trace_buffer_begin +
1704  ul_new_message_length;
1705  /* Print the trace messages */
1706  pr_info("DSPTrace: %s\n", hio_mgr->msg);
1707  }
1708  }
1709 }
1710 #endif
1711 
1712 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
1713 /*
1714  * ======== print_dsp_trace_buffer ========
1715  * Prints the trace buffer returned from the DSP (if DBG_Trace is enabled).
1716  * Parameters:
1717  * hdeh_mgr: Handle to DEH manager object
1718  * number of extra carriage returns to generate.
1719  * Returns:
1720  * 0: Success.
1721  * -ENOMEM: Unable to allocate memory.
1722  * Requires:
1723  * hdeh_mgr muse be valid. Checked in bridge_deh_notify.
1724  */
1725 int print_dsp_trace_buffer(struct bridge_dev_context *hbridge_context)
1726 {
1727  int status = 0;
1728  struct cod_manager *cod_mgr;
1729  u32 ul_trace_end;
1730  u32 ul_trace_begin;
1731  u32 trace_cur_pos;
1732  u32 ul_num_bytes = 0;
1733  u32 ul_num_words = 0;
1734  u32 ul_word_size = 2;
1735  char *psz_buf;
1736  char *str_beg;
1737  char *trace_end;
1738  char *buf_end;
1739  char *new_line;
1740 
1741  struct bridge_dev_context *pbridge_context = hbridge_context;
1742  struct bridge_drv_interface *intf_fxns;
1743  struct dev_object *dev_obj = (struct dev_object *)
1744  pbridge_context->dev_obj;
1745 
1746  status = dev_get_cod_mgr(dev_obj, &cod_mgr);
1747 
1748  if (cod_mgr) {
1749  /* Look for SYS_PUTCBEG/SYS_PUTCEND */
1750  status =
1751  cod_get_sym_value(cod_mgr, COD_TRACEBEG, &ul_trace_begin);
1752  } else {
1753  status = -EFAULT;
1754  }
1755  if (!status)
1756  status =
1757  cod_get_sym_value(cod_mgr, COD_TRACEEND, &ul_trace_end);
1758 
1759  if (!status)
1760  /* trace_cur_pos will hold the address of a DSP pointer */
1761  status = cod_get_sym_value(cod_mgr, COD_TRACECURPOS,
1762  &trace_cur_pos);
1763 
1764  if (status)
1765  goto func_end;
1766 
1767  ul_num_bytes = (ul_trace_end - ul_trace_begin);
1768 
1769  ul_num_words = ul_num_bytes * ul_word_size;
1770  status = dev_get_intf_fxns(dev_obj, &intf_fxns);
1771 
1772  if (status)
1773  goto func_end;
1774 
1775  psz_buf = kzalloc(ul_num_bytes + 2, GFP_ATOMIC);
1776  if (psz_buf != NULL) {
1777  /* Read trace buffer data */
1778  status = (*intf_fxns->brd_read)(pbridge_context,
1779  (u8 *)psz_buf, (u32)ul_trace_begin,
1780  ul_num_bytes, 0);
1781 
1782  if (status)
1783  goto func_end;
1784 
1785  /* Pack and do newline conversion */
1786  pr_debug("PrintDspTraceBuffer: "
1787  "before pack and unpack.\n");
1788  pr_debug("%s: DSP Trace Buffer Begin:\n"
1789  "=======================\n%s\n",
1790  __func__, psz_buf);
1791 
1792  /* Read the value at the DSP address in trace_cur_pos. */
1793  status = (*intf_fxns->brd_read)(pbridge_context,
1794  (u8 *)&trace_cur_pos, (u32)trace_cur_pos,
1795  4, 0);
1796  if (status)
1797  goto func_end;
1798  /* Pack and do newline conversion */
1799  pr_info("DSP Trace Buffer Begin:\n"
1800  "=======================\n%s\n",
1801  psz_buf);
1802 
1803 
1804  /* convert to offset */
1805  trace_cur_pos = trace_cur_pos - ul_trace_begin;
1806 
1807  if (ul_num_bytes) {
1808  /*
1809  * The buffer is not full, find the end of the
1810  * data -- buf_end will be >= pszBuf after
1811  * while.
1812  */
1813  buf_end = &psz_buf[ul_num_bytes+1];
1814  /* DSP print position */
1815  trace_end = &psz_buf[trace_cur_pos];
1816 
1817  /*
1818  * Search buffer for a new_line and replace it
1819  * with '\0', then print as string.
1820  * Continue until end of buffer is reached.
1821  */
1822  str_beg = trace_end;
1823  ul_num_bytes = buf_end - str_beg;
1824 
1825  while (str_beg < buf_end) {
1826  new_line = strnchr(str_beg, ul_num_bytes,
1827  '\n');
1828  if (new_line && new_line < buf_end) {
1829  *new_line = 0;
1830  pr_debug("%s\n", str_beg);
1831  str_beg = ++new_line;
1832  ul_num_bytes = buf_end - str_beg;
1833  } else {
1834  /*
1835  * Assume buffer empty if it contains
1836  * a zero
1837  */
1838  if (*str_beg != '\0') {
1839  str_beg[ul_num_bytes] = 0;
1840  pr_debug("%s\n", str_beg);
1841  }
1842  str_beg = buf_end;
1843  ul_num_bytes = 0;
1844  }
1845  }
1846  /*
1847  * Search buffer for a nNewLine and replace it
1848  * with '\0', then print as string.
1849  * Continue until buffer is exhausted.
1850  */
1851  str_beg = psz_buf;
1852  ul_num_bytes = trace_end - str_beg;
1853 
1854  while (str_beg < trace_end) {
1855  new_line = strnchr(str_beg, ul_num_bytes, '\n');
1856  if (new_line != NULL && new_line < trace_end) {
1857  *new_line = 0;
1858  pr_debug("%s\n", str_beg);
1859  str_beg = ++new_line;
1860  ul_num_bytes = trace_end - str_beg;
1861  } else {
1862  /*
1863  * Assume buffer empty if it contains
1864  * a zero
1865  */
1866  if (*str_beg != '\0') {
1867  str_beg[ul_num_bytes] = 0;
1868  pr_debug("%s\n", str_beg);
1869  }
1870  str_beg = trace_end;
1871  ul_num_bytes = 0;
1872  }
1873  }
1874  }
1875  pr_info("\n=======================\n"
1876  "DSP Trace Buffer End:\n");
1877  kfree(psz_buf);
1878  } else {
1879  status = -ENOMEM;
1880  }
1881 func_end:
1882  if (status)
1883  dev_dbg(bridge, "%s Failed, status 0x%x\n", __func__, status);
1884  return status;
1885 }
1886 
1892 int dump_dsp_stack(struct bridge_dev_context *bridge_context)
1893 {
1894  int status = 0;
1895  struct cod_manager *code_mgr;
1896  struct node_mgr *node_mgr;
1897  u32 trace_begin;
1898  char name[256];
1899  struct {
1900  u32 head[2];
1901  u32 size;
1902  } mmu_fault_dbg_info;
1903  u32 *buffer;
1904  u32 *buffer_beg;
1905  u32 *buffer_end;
1906  u32 exc_type;
1907  u32 dyn_ext_base;
1908  u32 i;
1909  u32 offset_output;
1910  u32 total_size;
1911  u32 poll_cnt;
1912  const char *dsp_regs[] = {"EFR", "IERR", "ITSR", "NTSR",
1913  "IRP", "NRP", "AMR", "SSR",
1914  "ILC", "RILC", "IER", "CSR"};
1915  const char *exec_ctxt[] = {"Task", "SWI", "HWI", "Unknown"};
1916  struct bridge_drv_interface *intf_fxns;
1917  struct dev_object *dev_object = bridge_context->dev_obj;
1918 
1919  status = dev_get_cod_mgr(dev_object, &code_mgr);
1920  if (!code_mgr) {
1921  pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__);
1922  status = -EFAULT;
1923  }
1924 
1925  if (!status) {
1926  status = dev_get_node_manager(dev_object, &node_mgr);
1927  if (!node_mgr) {
1928  pr_debug("%s: Failed on dev_get_node_manager.\n",
1929  __func__);
1930  status = -EFAULT;
1931  }
1932  }
1933 
1934  if (!status) {
1935  /* Look for SYS_PUTCBEG/SYS_PUTCEND: */
1936  status =
1937  cod_get_sym_value(code_mgr, COD_TRACEBEG, &trace_begin);
1938  pr_debug("%s: trace_begin Value 0x%x\n",
1939  __func__, trace_begin);
1940  if (status)
1941  pr_debug("%s: Failed on cod_get_sym_value.\n",
1942  __func__);
1943  }
1944  if (!status)
1945  status = dev_get_intf_fxns(dev_object, &intf_fxns);
1946  /*
1947  * Check for the "magic number" in the trace buffer. If it has
1948  * yet to appear then poll the trace buffer to wait for it. Its
1949  * appearance signals that the DSP has finished dumping its state.
1950  */
1951  mmu_fault_dbg_info.head[0] = 0;
1952  mmu_fault_dbg_info.head[1] = 0;
1953  if (!status) {
1954  poll_cnt = 0;
1955  while ((mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 ||
1956  mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) &&
1957  poll_cnt < POLL_MAX) {
1958 
1959  /* Read DSP dump size from the DSP trace buffer... */
1960  status = (*intf_fxns->brd_read)(bridge_context,
1961  (u8 *)&mmu_fault_dbg_info, (u32)trace_begin,
1962  sizeof(mmu_fault_dbg_info), 0);
1963 
1964  if (status)
1965  break;
1966 
1967  poll_cnt++;
1968  }
1969 
1970  if (mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 &&
1971  mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) {
1972  status = -ETIME;
1973  pr_err("%s:No DSP MMU-Fault information available.\n",
1974  __func__);
1975  }
1976  }
1977 
1978  if (!status) {
1979  total_size = mmu_fault_dbg_info.size;
1980  /* Limit the size in case DSP went crazy */
1981  if (total_size > MAX_MMU_DBGBUFF)
1982  total_size = MAX_MMU_DBGBUFF;
1983 
1984  buffer = kzalloc(total_size, GFP_ATOMIC);
1985  if (!buffer) {
1986  status = -ENOMEM;
1987  pr_debug("%s: Failed to "
1988  "allocate stack dump buffer.\n", __func__);
1989  goto func_end;
1990  }
1991 
1992  buffer_beg = buffer;
1993  buffer_end = buffer + total_size / 4;
1994 
1995  /* Read bytes from the DSP trace buffer... */
1996  status = (*intf_fxns->brd_read)(bridge_context,
1997  (u8 *)buffer, (u32)trace_begin,
1998  total_size, 0);
1999  if (status) {
2000  pr_debug("%s: Failed to Read Trace Buffer.\n",
2001  __func__);
2002  goto func_end;
2003  }
2004 
2005  pr_err("\nAproximate Crash Position:\n"
2006  "--------------------------\n");
2007 
2008  exc_type = buffer[3];
2009  if (!exc_type)
2010  i = buffer[79]; /* IRP */
2011  else
2012  i = buffer[80]; /* NRP */
2013 
2014  status =
2015  cod_get_sym_value(code_mgr, DYNEXTBASE, &dyn_ext_base);
2016  if (status) {
2017  status = -EFAULT;
2018  goto func_end;
2019  }
2020 
2021  if ((i > dyn_ext_base) && (node_find_addr(node_mgr, i,
2022  0x1000, &offset_output, name) == 0))
2023  pr_err("0x%-8x [\"%s\" + 0x%x]\n", i, name,
2024  i - offset_output);
2025  else
2026  pr_err("0x%-8x [Unable to match to a symbol.]\n", i);
2027 
2028  buffer += 4;
2029 
2030  pr_err("\nExecution Info:\n"
2031  "---------------\n");
2032 
2033  if (*buffer < ARRAY_SIZE(exec_ctxt)) {
2034  pr_err("Execution context \t%s\n",
2035  exec_ctxt[*buffer++]);
2036  } else {
2037  pr_err("Execution context corrupt\n");
2038  kfree(buffer_beg);
2039  return -EFAULT;
2040  }
2041  pr_err("Task Handle\t\t0x%x\n", *buffer++);
2042  pr_err("Stack Pointer\t\t0x%x\n", *buffer++);
2043  pr_err("Stack Top\t\t0x%x\n", *buffer++);
2044  pr_err("Stack Bottom\t\t0x%x\n", *buffer++);
2045  pr_err("Stack Size\t\t0x%x\n", *buffer++);
2046  pr_err("Stack Size In Use\t0x%x\n", *buffer++);
2047 
2048  pr_err("\nCPU Registers\n"
2049  "---------------\n");
2050 
2051  for (i = 0; i < 32; i++) {
2052  if (i == 4 || i == 6 || i == 8)
2053  pr_err("A%d 0x%-8x [Function Argument %d]\n",
2054  i, *buffer++, i-3);
2055  else if (i == 15)
2056  pr_err("A15 0x%-8x [Frame Pointer]\n",
2057  *buffer++);
2058  else
2059  pr_err("A%d 0x%x\n", i, *buffer++);
2060  }
2061 
2062  pr_err("\nB0 0x%x\n", *buffer++);
2063  pr_err("B1 0x%x\n", *buffer++);
2064  pr_err("B2 0x%x\n", *buffer++);
2065 
2066  if ((*buffer > dyn_ext_base) && (node_find_addr(node_mgr,
2067  *buffer, 0x1000, &offset_output, name) == 0))
2068 
2069  pr_err("B3 0x%-8x [Function Return Pointer:"
2070  " \"%s\" + 0x%x]\n", *buffer, name,
2071  *buffer - offset_output);
2072  else
2073  pr_err("B3 0x%-8x [Function Return Pointer:"
2074  "Unable to match to a symbol.]\n", *buffer);
2075 
2076  buffer++;
2077 
2078  for (i = 4; i < 32; i++) {
2079  if (i == 4 || i == 6 || i == 8)
2080  pr_err("B%d 0x%-8x [Function Argument %d]\n",
2081  i, *buffer++, i-2);
2082  else if (i == 14)
2083  pr_err("B14 0x%-8x [Data Page Pointer]\n",
2084  *buffer++);
2085  else
2086  pr_err("B%d 0x%x\n", i, *buffer++);
2087  }
2088 
2089  pr_err("\n");
2090 
2091  for (i = 0; i < ARRAY_SIZE(dsp_regs); i++)
2092  pr_err("%s 0x%x\n", dsp_regs[i], *buffer++);
2093 
2094  pr_err("\nStack:\n"
2095  "------\n");
2096 
2097  for (i = 0; buffer < buffer_end; i++, buffer++) {
2098  if ((*buffer > dyn_ext_base) && (
2099  node_find_addr(node_mgr, *buffer , 0x600,
2100  &offset_output, name) == 0))
2101  pr_err("[%d] 0x%-8x [\"%s\" + 0x%x]\n",
2102  i, *buffer, name,
2103  *buffer - offset_output);
2104  else
2105  pr_err("[%d] 0x%x\n", i, *buffer);
2106  }
2107  kfree(buffer_beg);
2108  }
2109 func_end:
2110  return status;
2111 }
2112 
2118 void dump_dl_modules(struct bridge_dev_context *bridge_context)
2119 {
2120  struct cod_manager *code_mgr;
2121  struct bridge_drv_interface *intf_fxns;
2122  struct bridge_dev_context *bridge_ctxt = bridge_context;
2123  struct dev_object *dev_object = bridge_ctxt->dev_obj;
2124  struct modules_header modules_hdr;
2125  struct dll_module *module_struct = NULL;
2126  u32 module_dsp_addr;
2127  u32 module_size;
2128  u32 module_struct_size = 0;
2129  u32 sect_ndx;
2130  char *sect_str ;
2131  int status = 0;
2132 
2133  status = dev_get_intf_fxns(dev_object, &intf_fxns);
2134  if (status) {
2135  pr_debug("%s: Failed on dev_get_intf_fxns.\n", __func__);
2136  goto func_end;
2137  }
2138 
2139  status = dev_get_cod_mgr(dev_object, &code_mgr);
2140  if (!code_mgr) {
2141  pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__);
2142  status = -EFAULT;
2143  goto func_end;
2144  }
2145 
2146  /* Lookup the address of the modules_header structure */
2147  status = cod_get_sym_value(code_mgr, "_DLModules", &module_dsp_addr);
2148  if (status) {
2149  pr_debug("%s: Failed on cod_get_sym_value for _DLModules.\n",
2150  __func__);
2151  goto func_end;
2152  }
2153 
2154  pr_debug("%s: _DLModules at 0x%x\n", __func__, module_dsp_addr);
2155 
2156  /* Copy the modules_header structure from DSP memory. */
2157  status = (*intf_fxns->brd_read)(bridge_context, (u8 *) &modules_hdr,
2158  (u32) module_dsp_addr, sizeof(modules_hdr), 0);
2159 
2160  if (status) {
2161  pr_debug("%s: Failed failed to read modules header.\n",
2162  __func__);
2163  goto func_end;
2164  }
2165 
2166  module_dsp_addr = modules_hdr.first_module;
2167  module_size = modules_hdr.first_module_size;
2168 
2169  pr_debug("%s: dll_module_header 0x%x %d\n", __func__, module_dsp_addr,
2170  module_size);
2171 
2172  pr_err("\nDynamically Loaded Modules:\n"
2173  "---------------------------\n");
2174 
2175  /* For each dll_module structure in the list... */
2176  while (module_size) {
2177  /*
2178  * Allocate/re-allocate memory to hold the dll_module
2179  * structure. The memory is re-allocated only if the existing
2180  * allocation is too small.
2181  */
2182  if (module_size > module_struct_size) {
2183  kfree(module_struct);
2184  module_struct = kzalloc(module_size+128, GFP_ATOMIC);
2185  module_struct_size = module_size+128;
2186  pr_debug("%s: allocated module struct %p %d\n",
2187  __func__, module_struct, module_struct_size);
2188  if (!module_struct)
2189  goto func_end;
2190  }
2191  /* Copy the dll_module structure from DSP memory */
2192  status = (*intf_fxns->brd_read)(bridge_context,
2193  (u8 *)module_struct, module_dsp_addr, module_size, 0);
2194 
2195  if (status) {
2196  pr_debug(
2197  "%s: Failed to read dll_module struct for 0x%x.\n",
2198  __func__, module_dsp_addr);
2199  break;
2200  }
2201 
2202  /* Update info regarding the _next_ module in the list. */
2203  module_dsp_addr = module_struct->next_module;
2204  module_size = module_struct->next_module_size;
2205 
2206  pr_debug("%s: next module 0x%x %d, this module num sects %d\n",
2207  __func__, module_dsp_addr, module_size,
2208  module_struct->num_sects);
2209 
2210  /*
2211  * The section name strings start immediately following
2212  * the array of dll_sect structures.
2213  */
2214  sect_str = (char *) &module_struct->
2215  sects[module_struct->num_sects];
2216  pr_err("%s\n", sect_str);
2217 
2218  /*
2219  * Advance to the first section name string.
2220  * Each string follows the one before.
2221  */
2222  sect_str += strlen(sect_str) + 1;
2223 
2224  /* Access each dll_sect structure and its name string. */
2225  for (sect_ndx = 0;
2226  sect_ndx < module_struct->num_sects; sect_ndx++) {
2227  pr_err(" Section: 0x%x ",
2228  module_struct->sects[sect_ndx].sect_load_adr);
2229 
2230  if (((u32) sect_str - (u32) module_struct) <
2231  module_struct_size) {
2232  pr_err("%s\n", sect_str);
2233  /* Each string follows the one before. */
2234  sect_str += strlen(sect_str)+1;
2235  } else {
2236  pr_err("<string error>\n");
2237  pr_debug("%s: section name sting address "
2238  "is invalid %p\n", __func__, sect_str);
2239  }
2240  }
2241  }
2242 func_end:
2243  kfree(module_struct);
2244 }
2245 #endif