diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index c51f651dfd1bd29347c0eff19e5ae4e6e40d17ec..480a3845a24ce014fa203ce8a0e1297eb8e75b8d 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -128,6 +128,16 @@ struct io_mgr { }; +struct shm_symbol_val { + u32 shm_base; + u32 shm_lim; + u32 msg_base; + u32 msg_lim; + u32 shm0_end; + u32 dyn_ext; + u32 ext_end; +}; + /* Function Prototypes */ static void io_dispatch_pm(struct io_mgr *pio_mgr); static void notify_chnl_complete(struct chnl_object *pchnl, @@ -256,6 +266,75 @@ int bridge_io_destroy(struct io_mgr *hio_mgr) return status; } +struct shm_symbol_val *_get_shm_symbol_values(struct io_mgr *hio_mgr) +{ + struct shm_symbol_val *s; + struct cod_manager *cod_man; + int status; + + s = kzalloc(sizeof(*s), GFP_KERNEL); + if (!s) + return ERR_PTR(-ENOMEM); + + status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man); + if (status) + goto free_symbol; + + /* Get start and length of channel part of shared memory */ + status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_BASE_SYM, + &s->shm_base); + if (status) + goto free_symbol; + + status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_LIMIT_SYM, + &s->shm_lim); + if (status) + goto free_symbol; + + if (s->shm_lim <= s->shm_base) { + status = -EINVAL; + goto free_symbol; + } + + /* Get start and length of message part of shared memory */ + status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_BASE_SYM, + &s->msg_base); + if (status) + goto free_symbol; + + status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_LIMIT_SYM, + &s->msg_lim); + if (status) + goto free_symbol; + + if (s->msg_lim <= s->msg_base) { + status = -EINVAL; + goto free_symbol; + } + +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE + status = cod_get_sym_value(cod_man, DSP_TRACESEC_END, &s->shm0_end); +#else + status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM, &s->shm0_end); +#endif + if (status) + goto free_symbol; + + status = cod_get_sym_value(cod_man, DYNEXTBASE, &s->dyn_ext); + if (status) + goto free_symbol; + + status = cod_get_sym_value(cod_man, EXTEND, &s->ext_end); + if (status) + goto free_symbol; + + return s; + +free_symbol: + kfree(s); + return ERR_PTR(status); +} + /* * ======== bridge_io_on_loaded ======== * Purpose: @@ -265,193 +344,112 @@ int bridge_io_destroy(struct io_mgr *hio_mgr) */ int bridge_io_on_loaded(struct io_mgr *hio_mgr) { + struct bridge_dev_context *dc = hio_mgr->bridge_context; + struct cfg_hostres *cfg_res = dc->resources; + struct bridge_ioctl_extproc *eproc; struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; - u32 ul_shm_base; - u32 ul_shm_base_offset; - u32 ul_shm_limit; - u32 ul_shm_length = -1; - u32 ul_mem_length = -1; - u32 ul_msg_base; - u32 ul_msg_limit; - u32 ul_msg_length = -1; - u32 ul_ext_end; - u32 ul_gpp_pa = 0; - u32 ul_gpp_va = 0; - u32 ul_dsp_va = 0; - u32 ul_seg_size = 0; - u32 ul_pad_size = 0; + struct shm_symbol_val *s; + int status; + u8 num_procs; + s32 ndx; u32 i; - int status = 0; - u8 num_procs = 0; - s32 ndx = 0; - /* DSP MMU setup table */ - struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB]; - struct cfg_hostres *host_res; - struct bridge_dev_context *pbridge_context; - u32 map_attrs; - u32 shm0_end; - u32 ul_dyn_ext_base; - u32 ul_seg1_size = 0; - u32 pa_curr = 0; - u32 va_curr = 0; - u32 gpp_va_curr = 0; - u32 num_bytes = 0; + u32 mem_sz, msg_sz, pad_sz, shm_sz, shm_base_offs; + u32 seg0_sz, seg1_sz; + u32 pa, va, da; + u32 pa_curr, va_curr, da_curr; + u32 bytes; u32 all_bits = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, + u32 page_size[] = { + HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB }; + u32 map_attrs = DSP_MAPLITTLEENDIAN | DSP_MAPPHYSICALADDR | + DSP_MAPELEMSIZE32 | DSP_MAPDONOTLOCK; - status = dev_get_bridge_context(hio_mgr->dev_obj, &pbridge_context); - if (!pbridge_context) { - status = -EFAULT; - goto func_end; - } - - host_res = pbridge_context->resources; - if (!host_res) { - status = -EFAULT; - goto func_end; - } status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man); - if (!cod_man) { - status = -EFAULT; - goto func_end; - } + if (status) + return status; + hchnl_mgr = hio_mgr->chnl_mgr; - /* The message manager is destroyed when the board is stopped. */ + + /* The message manager is destroyed when the board is stopped */ dev_get_msg_mgr(hio_mgr->dev_obj, &hio_mgr->msg_mgr); hmsg_mgr = hio_mgr->msg_mgr; - if (!hchnl_mgr || !hmsg_mgr) { - status = -EFAULT; - goto func_end; - } + if (!hchnl_mgr || !hmsg_mgr) + return -EFAULT; + if (hio_mgr->shared_mem) hio_mgr->shared_mem = NULL; - /* Get start and length of channel part of shared memory */ - status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_BASE_SYM, - &ul_shm_base); - if (status) { - status = -EFAULT; - goto func_end; - } - status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_LIMIT_SYM, - &ul_shm_limit); - if (status) { - status = -EFAULT; - goto func_end; - } - if (ul_shm_limit <= ul_shm_base) { - status = -EINVAL; - goto func_end; - } + s = _get_shm_symbol_values(hio_mgr); + if (IS_ERR(s)) + return PTR_ERR(s); + /* Get total length in bytes */ - ul_shm_length = (ul_shm_limit - ul_shm_base + 1) * hio_mgr->word_size; + shm_sz = (s->shm_lim - s->shm_base + 1) * hio_mgr->word_size; + /* Calculate size of a PROCCOPY shared memory region */ dev_dbg(bridge, "%s: (proc)proccopy shmmem size: 0x%x bytes\n", - __func__, (ul_shm_length - sizeof(struct shm))); + __func__, shm_sz - sizeof(struct shm)); - /* Get start and length of message part of shared memory */ - status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_BASE_SYM, - &ul_msg_base); - if (!status) { - status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_LIMIT_SYM, - &ul_msg_limit); - if (!status) { - if (ul_msg_limit <= ul_msg_base) { - status = -EINVAL; - } else { - /* - * Length (bytes) of messaging part of shared - * memory. - */ - ul_msg_length = - (ul_msg_limit - ul_msg_base + - 1) * hio_mgr->word_size; - /* - * Total length (bytes) of shared memory: - * chnl + msg. - */ - ul_mem_length = ul_shm_length + ul_msg_length; - } - } else { - status = -EFAULT; - } - } else { - status = -EFAULT; - } - if (!status) { -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) - status = - cod_get_sym_value(cod_man, DSP_TRACESEC_END, &shm0_end); -#else - status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM, - &shm0_end); -#endif - if (status) - status = -EFAULT; - } - if (!status) { - status = - cod_get_sym_value(cod_man, DYNEXTBASE, &ul_dyn_ext_base); - if (status) - status = -EFAULT; - } - if (!status) { - status = cod_get_sym_value(cod_man, EXTEND, &ul_ext_end); - if (status) - status = -EFAULT; + /* Length (bytes) of messaging part of shared memory */ + msg_sz = (s->msg_lim - s->msg_base + 1) * hio_mgr->word_size; + + /* Total length (bytes) of shared memory: chnl + msg */ + mem_sz = shm_sz + msg_sz; + + /* Get memory reserved in host resources */ + (void)mgr_enum_processor_info(0, + (struct dsp_processorinfo *) + &hio_mgr->ext_proc_info, + sizeof(struct mgr_processorextinfo), + &num_procs); + + /* IO supports only one DSP for now */ + if (num_procs != 1) { + status = -EINVAL; + goto free_symbol; } - if (!status) { - /* Get memory reserved in host resources */ - (void)mgr_enum_processor_info(0, (struct dsp_processorinfo *) - &hio_mgr->ext_proc_info, - sizeof(struct - mgr_processorextinfo), - &num_procs); - - /* The first MMU TLB entry(TLB_0) in DCD is ShmBase. */ - ndx = 0; - ul_gpp_pa = host_res->mem_phys[1]; - ul_gpp_va = host_res->mem_base[1]; - /* This is the virtual uncached ioremapped address!!! */ - /* Why can't we directly take the DSPVA from the symbols? */ - ul_dsp_va = hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt; - ul_seg_size = (shm0_end - ul_dsp_va) * hio_mgr->word_size; - ul_seg1_size = - (ul_ext_end - ul_dyn_ext_base) * hio_mgr->word_size; - /* 4K align */ - ul_seg1_size = (ul_seg1_size + 0xFFF) & (~0xFFFUL); - /* 64K align */ - ul_seg_size = (ul_seg_size + 0xFFFF) & (~0xFFFFUL); - ul_pad_size = UL_PAGE_ALIGN_SIZE - ((ul_gpp_pa + ul_seg1_size) % - UL_PAGE_ALIGN_SIZE); - if (ul_pad_size == UL_PAGE_ALIGN_SIZE) - ul_pad_size = 0x0; - - dev_dbg(bridge, "%s: ul_gpp_pa %x, ul_gpp_va %x, ul_dsp_va %x, " - "shm0_end %x, ul_dyn_ext_base %x, ul_ext_end %x, " - "ul_seg_size %x ul_seg1_size %x \n", __func__, - ul_gpp_pa, ul_gpp_va, ul_dsp_va, shm0_end, - ul_dyn_ext_base, ul_ext_end, ul_seg_size, ul_seg1_size); - - if ((ul_seg_size + ul_seg1_size + ul_pad_size) > - host_res->mem_length[1]) { - pr_err("%s: shm Error, reserved 0x%x required 0x%x\n", - __func__, host_res->mem_length[1], - ul_seg_size + ul_seg1_size + ul_pad_size); - status = -ENOMEM; - } + + /* The first MMU TLB entry(TLB_0) in DCD is ShmBase */ + pa = cfg_res->mem_phys[1]; + va = cfg_res->mem_base[1]; + + /* This is the virtual uncached ioremapped address!!! */ + /* Why can't we directly take the DSPVA from the symbols? */ + da = hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt; + seg0_sz = (s->shm0_end - da) * hio_mgr->word_size; + seg1_sz = (s->ext_end - s->dyn_ext) * hio_mgr->word_size; + + /* 4K align */ + seg1_sz = (seg1_sz + 0xFFF) & (~0xFFFUL); + + /* 64K align */ + seg0_sz = (seg0_sz + 0xFFFF) & (~0xFFFFUL); + + pad_sz = UL_PAGE_ALIGN_SIZE - ((pa + seg1_sz) % UL_PAGE_ALIGN_SIZE); + if (pad_sz == UL_PAGE_ALIGN_SIZE) + pad_sz = 0x0; + + dev_dbg(bridge, "%s: pa %x, va %x, da %x\n", __func__, pa, va, da); + dev_dbg(bridge, + "shm0_end %x, dyn_ext %x, ext_end %x, seg0_sz %x seg1_sz %x\n", + s->shm0_end, s->dyn_ext, s->ext_end, seg0_sz, seg1_sz); + + if ((seg0_sz + seg1_sz + pad_sz) > cfg_res->mem_length[1]) { + pr_err("%s: shm Error, reserved 0x%x required 0x%x\n", + __func__, cfg_res->mem_length[1], + seg0_sz + seg1_sz + pad_sz); + status = -ENOMEM; + goto free_symbol; } - if (status) - goto func_end; - pa_curr = ul_gpp_pa; - va_curr = ul_dyn_ext_base * hio_mgr->word_size; - gpp_va_curr = ul_gpp_va; - num_bytes = ul_seg1_size; + pa_curr = pa; + va_curr = s->dyn_ext * hio_mgr->word_size; + da_curr = va; + bytes = seg1_sz; /* * Try to fit into TLB entries. If not possible, push them to page @@ -459,37 +457,30 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) * bigger page boundary, we may end up making several small pages. * So, push them onto page tables, if that is the case. */ - map_attrs = 0x00000000; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - while (num_bytes) { + while (bytes) { /* * To find the max. page size with which both PA & VA are * aligned. */ all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, " - "num_bytes %x\n", all_bits, pa_curr, va_curr, - num_bytes); + dev_dbg(bridge, + "seg all_bits %x, pa_curr %x, va_curr %x, bytes %x\n", + all_bits, pa_curr, va_curr, bytes); + for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & - (page_size[i] - - 1)) == 0)) { - status = - hio_mgr->intf_fxns-> - brd_mem_map(hio_mgr->bridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); + if ((bytes >= page_size[i]) && + ((all_bits & (page_size[i] - 1)) == 0)) { + status = hio_mgr->intf_fxns->brd_mem_map(dc, + pa_curr, va_curr, + page_size[i], map_attrs, + NULL); if (status) - goto func_end; + goto free_symbol; + pa_curr += page_size[i]; va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; + da_curr += page_size[i]; + bytes -= page_size[i]; /* * Don't try smaller sizes. Hopefully we have * reached an address aligned to a bigger page @@ -499,71 +490,75 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) } } } - pa_curr += ul_pad_size; - va_curr += ul_pad_size; - gpp_va_curr += ul_pad_size; + pa_curr += pad_sz; + va_curr += pad_sz; + da_curr += pad_sz; + bytes = seg0_sz; + va_curr = da * hio_mgr->word_size; + + eproc = kzalloc(sizeof(*eproc) * BRDIOCTL_NUMOFMMUTLB, GFP_KERNEL); + if (!eproc) { + status = -ENOMEM; + goto free_symbol; + } + + ndx = 0; /* Configure the TLB entries for the next cacheable segment */ - num_bytes = ul_seg_size; - va_curr = ul_dsp_va * hio_mgr->word_size; - while (num_bytes) { + while (bytes) { /* * To find the max. page size with which both PA & VA are * aligned. */ all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, " - "va_curr %x, num_bytes %x\n", all_bits, pa_curr, - va_curr, num_bytes); + dev_dbg(bridge, + "seg1 all_bits %x, pa_curr %x, va_curr %x, bytes %x\n", + all_bits, pa_curr, va_curr, bytes); + for (i = 0; i < 4; i++) { - if (!(num_bytes >= page_size[i]) || + if (!(bytes >= page_size[i]) || !((all_bits & (page_size[i] - 1)) == 0)) continue; - if (ndx < MAX_LOCK_TLB_ENTRIES) { - /* - * This is the physical address written to - * DSP MMU. - */ - ae_proc[ndx].gpp_pa = pa_curr; - /* - * This is the virtual uncached ioremapped - * address!!! - */ - ae_proc[ndx].gpp_va = gpp_va_curr; - ae_proc[ndx].dsp_va = - va_curr / hio_mgr->word_size; - ae_proc[ndx].size = page_size[i]; - ae_proc[ndx].endianism = HW_LITTLE_ENDIAN; - ae_proc[ndx].elem_size = HW_ELEM_SIZE16BIT; - ae_proc[ndx].mixed_mode = HW_MMU_CPUES; - dev_dbg(bridge, "shm MMU TLB entry PA %x" - " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].gpp_pa, - ae_proc[ndx].gpp_va, - ae_proc[ndx].dsp_va * - hio_mgr->word_size, page_size[i]); - ndx++; - } else { - status = - hio_mgr->intf_fxns-> - brd_mem_map(hio_mgr->bridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); + + if (ndx >= MAX_LOCK_TLB_ENTRIES) { + status = hio_mgr->intf_fxns->brd_mem_map(dc, + pa_curr, va_curr, + page_size[i], map_attrs, + NULL); dev_dbg(bridge, - "shm MMU PTE entry PA %x" - " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].gpp_pa, - ae_proc[ndx].gpp_va, - ae_proc[ndx].dsp_va * + "PTE pa %x va %x dsp_va %x sz %x\n", + eproc[ndx].gpp_pa, + eproc[ndx].gpp_va, + eproc[ndx].dsp_va * hio_mgr->word_size, page_size[i]); if (status) - goto func_end; + goto free_eproc; } + + /* This is the physical address written to DSP MMU */ + eproc[ndx].gpp_pa = pa_curr; + + /* + * This is the virtual uncached ioremapped + * address!!! + */ + eproc[ndx].gpp_va = da_curr; + eproc[ndx].dsp_va = va_curr / hio_mgr->word_size; + eproc[ndx].size = page_size[i]; + eproc[ndx].endianism = HW_LITTLE_ENDIAN; + eproc[ndx].elem_size = HW_ELEM_SIZE16BIT; + eproc[ndx].mixed_mode = HW_MMU_CPUES; + dev_dbg(bridge, "%s: tlb pa %x va %x dsp_va %x sz %x\n", + __func__, eproc[ndx].gpp_pa, + eproc[ndx].gpp_va, + eproc[ndx].dsp_va * hio_mgr->word_size, + page_size[i]); + ndx++; + pa_curr += page_size[i]; va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; + da_curr += page_size[i]; + bytes -= page_size[i]; /* * Don't try smaller sizes. Hopefully we have reached * an address aligned to a bigger page size. @@ -577,146 +572,127 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) * should not conflict with shm entries on MPU or DSP side. */ for (i = 3; i < 7 && ndx < BRDIOCTL_NUMOFMMUTLB; i++) { - if (hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys == 0) + struct mgr_processorextinfo *ep = &hio_mgr->ext_proc_info; + u32 word_sz = hio_mgr->word_size; + + if (ep->ty_tlb[i].gpp_phys == 0) continue; - if ((hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys > - ul_gpp_pa - 0x100000 - && hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys <= - ul_gpp_pa + ul_seg_size) - || (hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt > - ul_dsp_va - 0x100000 / hio_mgr->word_size - && hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt <= - ul_dsp_va + ul_seg_size / hio_mgr->word_size)) { + if ((ep->ty_tlb[i].gpp_phys > pa - 0x100000 && + ep->ty_tlb[i].gpp_phys <= pa + seg0_sz) || + (ep->ty_tlb[i].dsp_virt > da - 0x100000 / word_sz && + ep->ty_tlb[i].dsp_virt <= da + seg0_sz / word_sz)) { dev_dbg(bridge, - "CDB MMU entry %d conflicts with " - "shm.\n\tCDB: GppPa %x, DspVa %x.\n\tSHM: " - "GppPa %x, DspVa %x, Bytes %x.\n", i, - hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys, - hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt, - ul_gpp_pa, ul_dsp_va, ul_seg_size); + "err cdb%d pa %x da %x shm pa %x da %x sz %x\n", + i, ep->ty_tlb[i].gpp_phys, + ep->ty_tlb[i].dsp_virt, pa, da, seg0_sz); status = -EPERM; - } else { - if (ndx < MAX_LOCK_TLB_ENTRIES) { - ae_proc[ndx].dsp_va = - hio_mgr->ext_proc_info.ty_tlb[i]. - dsp_virt; - ae_proc[ndx].gpp_pa = - hio_mgr->ext_proc_info.ty_tlb[i]. - gpp_phys; - ae_proc[ndx].gpp_va = 0; - /* 1 MB */ - ae_proc[ndx].size = 0x100000; - dev_dbg(bridge, "shm MMU entry PA %x " - "DSP_VA 0x%x\n", ae_proc[ndx].gpp_pa, - ae_proc[ndx].dsp_va); - ndx++; - } else { - status = hio_mgr->intf_fxns->brd_mem_map - (hio_mgr->bridge_context, - hio_mgr->ext_proc_info.ty_tlb[i]. - gpp_phys, - hio_mgr->ext_proc_info.ty_tlb[i]. - dsp_virt, 0x100000, map_attrs, - NULL); - } + goto free_eproc; + } + + if (ndx >= MAX_LOCK_TLB_ENTRIES) { + status = hio_mgr->intf_fxns->brd_mem_map(dc, + ep->ty_tlb[i].gpp_phys, + ep->ty_tlb[i].dsp_virt, + 0x100000, map_attrs, NULL); + if (status) + goto free_eproc; } - if (status) - goto func_end; - } - map_attrs = 0x00000000; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; + eproc[ndx].dsp_va = ep->ty_tlb[i].dsp_virt; + eproc[ndx].gpp_pa = ep->ty_tlb[i].gpp_phys; + eproc[ndx].gpp_va = 0; + + /* 1 MB */ + eproc[ndx].size = 0x100000; + dev_dbg(bridge, "shm MMU entry pa %x da 0x%x\n", + eproc[ndx].gpp_pa, eproc[ndx].dsp_va); + ndx++; + } /* Map the L4 peripherals */ i = 0; while (l4_peripheral_table[i].phys_addr) { - status = hio_mgr->intf_fxns->brd_mem_map - (hio_mgr->bridge_context, l4_peripheral_table[i].phys_addr, - l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB, - map_attrs, NULL); + status = hio_mgr->intf_fxns->brd_mem_map(dc, + l4_peripheral_table[i].phys_addr, + l4_peripheral_table[i].dsp_virt_addr, + HW_PAGE_SIZE4KB, map_attrs, NULL); if (status) - goto func_end; + goto free_eproc; i++; } for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) { - ae_proc[i].dsp_va = 0; - ae_proc[i].gpp_pa = 0; - ae_proc[i].gpp_va = 0; - ae_proc[i].size = 0; + eproc[i].dsp_va = 0; + eproc[i].gpp_pa = 0; + eproc[i].gpp_va = 0; + eproc[i].size = 0; } + /* * Set the shm physical address entry (grayed out in CDB file) * to the virtual uncached ioremapped address of shm reserved * on MPU. */ hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys = - (ul_gpp_va + ul_seg1_size + ul_pad_size); + (va + seg1_sz + pad_sz); /* * Need shm Phys addr. IO supports only one DSP for now: * num_procs = 1. */ - if (!hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys || num_procs != 1) { - status = -EFAULT; - goto func_end; - } else { - if (ae_proc[0].dsp_va > ul_shm_base) { - status = -EPERM; - goto func_end; - } - /* ul_shm_base may not be at ul_dsp_va address */ - ul_shm_base_offset = (ul_shm_base - ae_proc[0].dsp_va) * + if (!hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys) + return -EFAULT; + + if (eproc[0].dsp_va > s->shm_base) + return -EPERM; + + /* shm_base may not be at ul_dsp_va address */ + shm_base_offs = (s->shm_base - eproc[0].dsp_va) * hio_mgr->word_size; - /* - * bridge_dev_ctrl() will set dev context dsp-mmu info. In - * bridge_brd_start() the MMU will be re-programed with MMU - * DSPVa-GPPPa pair info while DSP is in a known - * (reset) state. - */ + /* + * bridge_dev_ctrl() will set dev context dsp-mmu info. In + * bridge_brd_start() the MMU will be re-programed with MMU + * DSPVa-GPPPa pair info while DSP is in a known + * (reset) state. + */ + status = hio_mgr->intf_fxns->dev_cntrl(hio_mgr->bridge_context, + BRDIOCTL_SETMMUCONFIG, eproc); + if (status) + goto free_eproc; - status = - hio_mgr->intf_fxns->dev_cntrl(hio_mgr->bridge_context, - BRDIOCTL_SETMMUCONFIG, - ae_proc); - if (status) - goto func_end; - ul_shm_base = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys; - ul_shm_base += ul_shm_base_offset; - ul_shm_base = (u32) MEM_LINEAR_ADDRESS((void *)ul_shm_base, - ul_mem_length); - if (ul_shm_base == 0) { - status = -EFAULT; - goto func_end; - } - /* Register SM */ - status = - register_shm_segs(hio_mgr, cod_man, ae_proc[0].gpp_pa); + s->shm_base = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys; + s->shm_base += shm_base_offs; + s->shm_base = (u32) MEM_LINEAR_ADDRESS((void *)s->shm_base, + mem_sz); + if (!s->shm_base) { + status = -EFAULT; + goto free_eproc; } - hio_mgr->shared_mem = (struct shm *)ul_shm_base; + /* Register SM */ + status = register_shm_segs(hio_mgr, cod_man, eproc[0].gpp_pa); + + hio_mgr->shared_mem = (struct shm *)s->shm_base; hio_mgr->input = (u8 *) hio_mgr->shared_mem + sizeof(struct shm); - hio_mgr->output = hio_mgr->input + (ul_shm_length - + hio_mgr->output = hio_mgr->input + (shm_sz - sizeof(struct shm)) / 2; hio_mgr->sm_buf_size = hio_mgr->output - hio_mgr->input; - /* Set up Shared memory addresses for messaging. */ - hio_mgr->msg_input_ctrl = (struct msg_ctrl *)((u8 *) hio_mgr->shared_mem - + ul_shm_length); + /* Set up Shared memory addresses for messaging */ + hio_mgr->msg_input_ctrl = + (struct msg_ctrl *)((u8 *) hio_mgr->shared_mem + shm_sz); hio_mgr->msg_input = - (u8 *) hio_mgr->msg_input_ctrl + sizeof(struct msg_ctrl); + (u8 *) hio_mgr->msg_input_ctrl + sizeof(struct msg_ctrl); hio_mgr->msg_output_ctrl = - (struct msg_ctrl *)((u8 *) hio_mgr->msg_input_ctrl + - ul_msg_length / 2); + (struct msg_ctrl *)((u8 *) hio_mgr->msg_input_ctrl + + msg_sz / 2); hio_mgr->msg_output = - (u8 *) hio_mgr->msg_output_ctrl + sizeof(struct msg_ctrl); + (u8 *) hio_mgr->msg_output_ctrl + sizeof(struct msg_ctrl); hmsg_mgr->max_msgs = - ((u8 *) hio_mgr->msg_output_ctrl - hio_mgr->msg_input) - / sizeof(struct msg_dspmsg); + ((u8 *) hio_mgr->msg_output_ctrl - hio_mgr->msg_input) / + sizeof(struct msg_dspmsg); + dev_dbg(bridge, "IO MGR shm details: shared_mem %p, input %p, " "output %p, msg_input_ctrl %p, msg_input %p, " "msg_output_ctrl %p, msg_output %p\n", @@ -732,47 +708,53 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) /* Get the start address of trace buffer */ status = cod_get_sym_value(cod_man, SYS_PUTCBEG, &hio_mgr->trace_buffer_begin); - if (status) { - status = -EFAULT; - goto func_end; - } + if (status) + goto free_eproc; + + hio_mgr->gpp_read_pointer = + hio_mgr->trace_buffer_begin = + (va + seg1_sz + pad_sz) + + (hio_mgr->trace_buffer_begin - da); - hio_mgr->gpp_read_pointer = hio_mgr->trace_buffer_begin = - (ul_gpp_va + ul_seg1_size + ul_pad_size) + - (hio_mgr->trace_buffer_begin - ul_dsp_va); /* Get the end address of trace buffer */ status = cod_get_sym_value(cod_man, SYS_PUTCEND, &hio_mgr->trace_buffer_end); - if (status) { - status = -EFAULT; - goto func_end; - } + if (status) + goto free_eproc; + hio_mgr->trace_buffer_end = - (ul_gpp_va + ul_seg1_size + ul_pad_size) + - (hio_mgr->trace_buffer_end - ul_dsp_va); + (va + seg1_sz + pad_sz) + + (hio_mgr->trace_buffer_end - da); + /* Get the current address of DSP write pointer */ status = cod_get_sym_value(cod_man, BRIDGE_SYS_PUTC_CURRENT, &hio_mgr->trace_buffer_current); - if (status) { - status = -EFAULT; - goto func_end; - } + if (status) + goto free_eproc; + hio_mgr->trace_buffer_current = - (ul_gpp_va + ul_seg1_size + ul_pad_size) + - (hio_mgr->trace_buffer_current - ul_dsp_va); + (va + seg1_sz + pad_sz) + + (hio_mgr->trace_buffer_current - da); + /* Calculate the size of trace buffer */ kfree(hio_mgr->msg); hio_mgr->msg = kmalloc(((hio_mgr->trace_buffer_end - hio_mgr->trace_buffer_begin) * hio_mgr->word_size) + 2, GFP_KERNEL); - if (!hio_mgr->msg) + if (!hio_mgr->msg) { status = -ENOMEM; + goto free_eproc; + } - hio_mgr->dsp_va = ul_dsp_va; - hio_mgr->gpp_va = (ul_gpp_va + ul_seg1_size + ul_pad_size); - + hio_mgr->dsp_va = da; + hio_mgr->gpp_va = (va + seg1_sz + pad_sz); #endif -func_end: + +free_eproc: + kfree(eproc); +free_symbol: + kfree(s); + return status; }