Commit 4dd1944a authored by Fernando Guzman Lugo's avatar Fernando Guzman Lugo Committed by Greg Kroah-Hartman

staging: tidspbridge - rename bridge_brd_mem_map/unmap to a proper name

Now these functions only map user space addresses to dsp virtual
addresses, so now the functions have a more meaningful name.
Also now user_to_dsp_map returns the mapped address.
Signed-off-by: default avatarFernando Guzman Lugo <x0095840@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 0c10e91b
...@@ -383,4 +383,28 @@ extern s32 dsp_debug; ...@@ -383,4 +383,28 @@ extern s32 dsp_debug;
*/ */
int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val);
/**
* user_to_dsp_map() - maps user to dsp virtual address
* @mmu: Pointer to iommu handle.
* @uva: Virtual user space address.
* @da DSP address
* @size Buffer size to map.
* @usr_pgs struct page array pointer where the user pages will be stored
*
* This function maps a user space buffer into DSP virtual address.
*
*/
u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
struct page **usr_pgs);
/**
* user_to_dsp_unmap() - unmaps DSP virtual buffer.
* @mmu: Pointer to iommu handle.
* @da DSP address
*
* This function unmaps a user space buffer into DSP virtual address.
*
*/
int user_to_dsp_unmap(struct iommu *mmu, u32 da);
#endif /* _TIOMAP_ */ #endif /* _TIOMAP_ */
...@@ -97,12 +97,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, ...@@ -97,12 +97,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
u8 *host_buff, u32 dsp_addr, u8 *host_buff, u32 dsp_addr,
u32 ul_num_bytes, u32 mem_type); u32 ul_num_bytes, u32 mem_type);
static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
u32 ul_mpu_addr, u32 virt_addr,
u32 ul_num_bytes, u32 ul_map_attr,
struct page **mapped_pages);
static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
u32 da);
static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_create(struct bridge_dev_context
**dev_cntxt, **dev_cntxt,
struct dev_object *hdev_obj, struct dev_object *hdev_obj,
...@@ -110,9 +104,6 @@ static int bridge_dev_create(struct bridge_dev_context ...@@ -110,9 +104,6 @@ static int bridge_dev_create(struct bridge_dev_context
static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
u32 dw_cmd, void *pargs); u32 dw_cmd, void *pargs);
static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
struct page **usr_pgs);
static u32 user_va2_pa(struct mm_struct *mm, u32 address);
static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
u32 va, u32 size, u32 va, u32 size,
struct hw_mmu_map_attrs_t *map_attrs); struct hw_mmu_map_attrs_t *map_attrs);
...@@ -182,8 +173,6 @@ static struct bridge_drv_interface drv_interface_fxns = { ...@@ -182,8 +173,6 @@ static struct bridge_drv_interface drv_interface_fxns = {
bridge_brd_set_state, bridge_brd_set_state,
bridge_brd_mem_copy, bridge_brd_mem_copy,
bridge_brd_mem_write, bridge_brd_mem_write,
bridge_brd_mem_map,
bridge_brd_mem_un_map,
/* The following CHNL functions are provided by chnl_io.lib: */ /* The following CHNL functions are provided by chnl_io.lib: */
bridge_chnl_create, bridge_chnl_create,
bridge_chnl_destroy, bridge_chnl_destroy,
...@@ -1154,22 +1143,77 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, ...@@ -1154,22 +1143,77 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
} }
/* /*
* ======== bridge_brd_mem_map ======== * ======== user_va2_pa ========
* This function maps MPU buffer to the DSP address space. It performs * Purpose:
* linear to physical address translation if required. It translates each * This function walks through the page tables to convert a userland
* page since linear addresses can be physically non-contiguous * virtual address to physical address
* All address & size arguments are assumed to be page aligned (in proc.c) */
static u32 user_va2_pa(struct mm_struct *mm, u32 address)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *ptep, pte;
pgd = pgd_offset(mm, address);
if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
pmd = pmd_offset(pgd, address);
if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
ptep = pte_offset_map(pmd, address);
if (ptep) {
pte = *ptep;
if (pte_present(pte))
return pte & PAGE_MASK;
}
}
}
return 0;
}
/**
* get_io_pages() - pin and get pages of io user's buffer.
* @mm: mm_struct Pointer of the process.
* @uva: Virtual user space address.
* @pages Pages to be pined.
* @usr_pgs struct page array pointer where the user pages will be stored
* *
* TODO: Disable MMU while updating the page tables (but that'll stall DSP)
*/ */
static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx, static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
u32 uva, u32 da, u32 size, u32 attr, struct page **usr_pgs)
struct page **usr_pgs) {
u32 pa;
int i;
struct page *pg;
for (i = 0; i < pages; i++) {
pa = user_va2_pa(mm, uva);
if (!pfn_valid(__phys_to_pfn(pa)))
break;
pg = PHYS_TO_PAGE(pa);
usr_pgs[i] = pg;
get_page(pg);
}
return i;
}
/**
* user_to_dsp_map() - maps user to dsp virtual address
* @mmu: Pointer to iommu handle.
* @uva: Virtual user space address.
* @da DSP address
* @size Buffer size to map.
* @usr_pgs struct page array pointer where the user pages will be stored
*
* This function maps a user space buffer into DSP virtual address.
*
*/
u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
struct page **usr_pgs)
{ {
int res, w; int res, w;
unsigned pages, i; unsigned pages, i;
struct iommu *mmu = dev_ctx->dsp_mmu;
struct vm_area_struct *vma; struct vm_area_struct *vma;
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
struct sg_table *sgt; struct sg_table *sgt;
...@@ -1226,7 +1270,7 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx, ...@@ -1226,7 +1270,7 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
if (!IS_ERR_VALUE(da)) if (!IS_ERR_VALUE(da))
return 0; return da;
res = (int)da; res = (int)da;
sg_free_table(sgt); sg_free_table(sgt);
...@@ -1239,21 +1283,21 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx, ...@@ -1239,21 +1283,21 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
return res; return res;
} }
/* /**
* ======== bridge_brd_mem_un_map ======== * user_to_dsp_unmap() - unmaps DSP virtual buffer.
* Invalidate the PTEs for the DSP VA block to be unmapped. * @mmu: Pointer to iommu handle.
* @da DSP address
*
* This function unmaps a user space buffer into DSP virtual address.
* *
* PTEs of a mapped memory block are contiguous in any page table
* So, instead of looking up the PTE address for every 4K block,
* we clear consecutive PTEs until we unmap all the bytes
*/ */
static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da) int user_to_dsp_unmap(struct iommu *mmu, u32 da)
{ {
unsigned i; unsigned i;
struct sg_table *sgt; struct sg_table *sgt;
struct scatterlist *sg; struct scatterlist *sg;
sgt = iommu_vunmap(dev_ctx->dsp_mmu, da); sgt = iommu_vunmap(mmu, da);
if (!sgt) if (!sgt)
return -EFAULT; return -EFAULT;
...@@ -1265,55 +1309,6 @@ static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da) ...@@ -1265,55 +1309,6 @@ static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da)
return 0; return 0;
} }
static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
struct page **usr_pgs)
{
u32 pa;
int i;
struct page *pg;
for (i = 0; i < pages; i++) {
pa = user_va2_pa(mm, uva);
if (!pfn_valid(__phys_to_pfn(pa)))
break;
pg = PHYS_TO_PAGE(pa);
usr_pgs[i] = pg;
get_page(pg);
}
return i;
}
/*
* ======== user_va2_pa ========
* Purpose:
* This function walks through the page tables to convert a userland
* virtual address to physical address
*/
static u32 user_va2_pa(struct mm_struct *mm, u32 address)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *ptep, pte;
pgd = pgd_offset(mm, address);
if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
pmd = pmd_offset(pgd, address);
if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
ptep = pte_offset_map(pmd, address);
if (ptep) {
pte = *ptep;
if (pte_present(pte))
return pte & PAGE_MASK;
}
}
}
return 0;
}
/* /*
* ======== pte_update ======== * ======== pte_update ========
* This function calculates the optimum page-aligned addresses and sizes * This function calculates the optimum page-aligned addresses and sizes
......
...@@ -161,48 +161,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context ...@@ -161,48 +161,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context
u32 dsp_addr, u32 ul_num_bytes, u32 dsp_addr, u32 ul_num_bytes,
u32 mem_type); u32 mem_type);
/*
* ======== bridge_brd_mem_map ========
* Purpose:
* Map a MPU memory region to a DSP/IVA memory space
* Parameters:
* dev_ctxt: Handle to Bridge driver defined device info.
* ul_mpu_addr: MPU memory region start address.
* virt_addr: DSP/IVA memory region u8 address.
* ul_num_bytes: Number of bytes to map.
* map_attrs: Mapping attributes (e.g. endianness).
* Returns:
* 0: Success.
* -EPERM: Other, unspecified error.
* Requires:
* dev_ctxt != NULL;
* Ensures:
*/
typedef int(*fxn_brd_memmap) (struct bridge_dev_context
* dev_ctxt, u32 ul_mpu_addr,
u32 virt_addr, u32 ul_num_bytes,
u32 map_attr,
struct page **mapped_pages);
/*
* ======== bridge_brd_mem_un_map ========
* Purpose:
* UnMap an MPU memory region from DSP/IVA memory space
* Parameters:
* dev_ctxt: Handle to Bridge driver defined device info.
* virt_addr: DSP/IVA memory region u8 address.
* ul_num_bytes: Number of bytes to unmap.
* Returns:
* 0: Success.
* -EPERM: Other, unspecified error.
* Requires:
* dev_ctxt != NULL;
* Ensures:
*/
typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
* dev_ctxt,
u32 da);
/* /*
* ======== bridge_brd_stop ======== * ======== bridge_brd_stop ========
* Purpose: * Purpose:
...@@ -993,8 +951,6 @@ struct bridge_drv_interface { ...@@ -993,8 +951,6 @@ struct bridge_drv_interface {
fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */ fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */
fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */ fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */
fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */ fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */
fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */
fxn_brd_memunmap pfn_brd_mem_un_map; /* Unmaps MPU mem to DSP mem */
fxn_chnl_create pfn_chnl_create; /* Create channel manager. */ fxn_chnl_create pfn_chnl_create; /* Create channel manager. */
fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */ fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */
fxn_chnl_open pfn_chnl_open; /* Create a new channel. */ fxn_chnl_open pfn_chnl_open; /* Create a new channel. */
......
...@@ -1118,8 +1118,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, ...@@ -1118,8 +1118,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
STORE_FXN(fxn_brd_setstate, pfn_brd_set_state); STORE_FXN(fxn_brd_setstate, pfn_brd_set_state);
STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy); STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy);
STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write); STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write);
STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map);
STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map);
STORE_FXN(fxn_chnl_create, pfn_chnl_create); STORE_FXN(fxn_chnl_create, pfn_chnl_create);
STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy); STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy);
STORE_FXN(fxn_chnl_open, pfn_chnl_open); STORE_FXN(fxn_chnl_open, pfn_chnl_open);
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <dspbridge/msg.h> #include <dspbridge/msg.h>
#include <dspbridge/dspioctl.h> #include <dspbridge/dspioctl.h>
#include <dspbridge/drv.h> #include <dspbridge/drv.h>
#include <_tiomap.h>
/* ----------------------------------- This */ /* ----------------------------------- This */
#include <dspbridge/proc.h> #include <dspbridge/proc.h>
...@@ -1357,7 +1358,6 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, ...@@ -1357,7 +1358,6 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
int status = 0; int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor; struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
struct dmm_map_object *map_obj; struct dmm_map_object *map_obj;
u32 tmp_addr = 0;
#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK #ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
if ((ul_map_attr & BUFMODE_MASK) != RBUF) { if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
...@@ -1390,24 +1390,27 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, ...@@ -1390,24 +1390,27 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
/* Add mapping to the page tables. */ /* Add mapping to the page tables. */
if (!status) { if (!status) {
/* Mapped address = MSB of VA | LSB of PA */
tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
/* mapped memory resource tracking */ /* mapped memory resource tracking */
map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr, map_obj = add_mapping_info(pr_ctxt, pa_align, va_align,
size_align); size_align);
if (!map_obj) if (!map_obj) {
status = -ENOMEM; status = -ENOMEM;
else } else {
status = (*p_proc_object->intf_fxns->pfn_brd_mem_map) va_align = user_to_dsp_map(
(p_proc_object->hbridge_context, pa_align, va_align, p_proc_object->hbridge_context->dsp_mmu,
size_align, ul_map_attr, map_obj->pages); pa_align, va_align, size_align,
map_obj->pages);
if (IS_ERR_VALUE(va_align))
status = (int)va_align;
}
} }
if (!status) { if (!status) {
/* Mapped address = MSB of VA | LSB of PA */ /* Mapped address = MSB of VA | LSB of PA */
*pp_map_addr = (void *) tmp_addr; map_obj->dsp_addr = (va_align |
((u32)pmpu_addr & (PG_SIZE4K - 1)));
*pp_map_addr = (void *)map_obj->dsp_addr;
} else { } else {
remove_mapping_information(pr_ctxt, tmp_addr, size_align); remove_mapping_information(pr_ctxt, va_align, size_align);
dmm_un_map_memory(dmm_mgr, va_align, &size_align); dmm_un_map_memory(dmm_mgr, va_align, &size_align);
} }
mutex_unlock(&proc_lock); mutex_unlock(&proc_lock);
...@@ -1721,10 +1724,9 @@ int proc_un_map(void *hprocessor, void *map_addr, ...@@ -1721,10 +1724,9 @@ int proc_un_map(void *hprocessor, void *map_addr,
*/ */
status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align); status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
/* Remove mapping from the page tables. */ /* Remove mapping from the page tables. */
if (!status) { if (!status)
status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map) status = user_to_dsp_unmap(
(p_proc_object->hbridge_context, va_align); p_proc_object->hbridge_context->dsp_mmu, va_align);
}
mutex_unlock(&proc_lock); mutex_unlock(&proc_lock);
if (status) if (status)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment