Commit 08a74abb authored by Hari Kanigeri's avatar Hari Kanigeri

SYSLINK:proc-add virt to phys and map tiler functionality

This patch provides the following functionality:
	1. Virt_To_Phys - Given a Co-processor's virtual
	address, the pages that are mapped are retured
	in the buffer passed by the user.
	2. Given a Chiron's virtual address, maps to
	Ducati virtual address. This is a hack for now
	to address Tiler memory until the dynmamic memory
	allocation for Tiler is supported.

	This patch also fixed bug in memory unmap function
	using iommu for Super and Large page cases.
Signed-off-by: default avatarHari Kanigeri <h-kanigeri2@ti.com>
parent 6a4438ee
......@@ -17,6 +17,8 @@
#define _DDUCATIMMU_ENABLER_H_
#include <linux/types.h>
#include <linux/mm.h>
#include <syslink/hw_defs.h>
#include <syslink/hw_mmu.h>
......@@ -124,6 +126,8 @@
#define DSP_MAPELEMSIZE64 0x00000040
#define DSP_MAPVMALLOCADDR 0x00000080
#define DSP_MAPTILERADDR 0x00000100
#define PG_MASK(pg_size) (~((pg_size)-1))
#define PG_ALIGN_LOW(addr, pg_size) ((addr) & PG_MASK(pg_size))
......@@ -193,4 +197,6 @@ void ducati_destroy(void);
u32 get_ducati_virt_mem();
int ducati_mem_map(u32 va, u32 da, u32 num_bytes, u32 map_attr);
int ducati_mem_unmap(u32 da, u32 num_bytes);
u32 user_va2pa(struct mm_struct *mm, u32 address);
inline u32 ducati_mem_virtToPhys(u32 da);
#endif /* _DDUCATIMMU_ENABLER_H_*/
......@@ -271,4 +271,10 @@ int proc_mgr_register_notify(void *handle, proc_mgr_callback_fxn fxn,
* processor.
*/
int proc_mgr_get_proc_info(void *handle, struct proc_mgr_proc_info *proc_info);
/* Function that returns virtual to physical translations
*/
int proc_mgr_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
u32 num_of_entries);
#endif
......@@ -234,10 +234,11 @@ int ducati_mem_unmap(u32 da, u32 num_bytes)
if (*iopte & IOPTE_LARGE) {
nent = 16;
/* rewind to the 1st entry */
iopte = (u32 *)((u32)iopte & IOLARGE_MASK);
} else
phyaddress = *iopte & IOLARGE_MASK;
} else {
nent = 1;
phyaddress = (*iopte) & IOPAGE_MASK;
}
} else {
if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) {
nent = 4096;
......@@ -271,13 +272,44 @@ int ducati_mem_unmap(u32 da, u32 num_bytes)
}
/*
* ======== ducati_mem_virtToPhys ========
* This funciton provides the translation from
* Remote virtual address to Physical address
*/
inline u32 ducati_mem_virtToPhys(u32 da)
{
u32 *iopgd = iopgd_offset(ducati_iommu_ptr, da);
u32 phyaddress;
if (*iopgd & IOPGD_TABLE) {
u32 *iopte = iopte_offset(iopgd, da);
if (*iopte & IOPTE_LARGE) {
phyaddress = *iopte & IOLARGE_MASK;
phyaddress |= (da & (IOLARGE_SIZE - 1));
} else
phyaddress = (*iopte) & IOPAGE_MASK;
} else {
if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) {
phyaddress = *iopgd & IOSUPER_MASK;
phyaddress |= (da & (IOSUPER_SIZE - 1));
} else {
phyaddress = (*iopgd) & IOPGD_MASK;
phyaddress |= (da & (IOPGD_SIZE - 1));
}
}
return phyaddress;
}
/*
* ======== user_va2pa ========
* Purpose:
* This function walks through the Linux page tables to convert a userland
* virtual address to physical address
*/
static u32 user_va2pa(struct mm_struct *mm, u32 address)
u32 user_va2pa(struct mm_struct *mm, u32 address)
{
pgd_t *pgd;
pmd_t *pmd;
......@@ -329,6 +361,7 @@ int ducati_mem_map(u32 mpu_addr, u32 ul_virt_addr,
return -EINVAL;
if (map_attr != 0) {
attrs = map_attr;
attrs |= DSP_MAPELEMSIZE32;
} else {
/* Assign default attributes */
attrs = DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE32;
......
......@@ -16,11 +16,13 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/delay.h>
/* Module level headers */
#include "../procdefs.h"
......@@ -247,6 +249,7 @@ void *proc4430_create(u16 proc_id, const struct proc4430_params *params)
handle->proc_fxn_table.map = &proc4430_map;
handle->proc_fxn_table.unmap = &proc4430_unmap;
handle->proc_fxn_table.procinfo = &proc4430_proc_info;
handle->proc_fxn_table.virt_to_phys = &proc4430_virt_to_phys;
handle->state = PROC_MGR_STATE_UNKNOWN;
handle->object = vmalloc
(sizeof(struct proc4430_object));
......@@ -461,13 +464,14 @@ int proc4430_start(void *handle, u32 entry_pt,
{
switch (start_params->params->proc_id) {
case SYS_M3:
/* De-assert RST2 */
__raw_writel(0x02, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET);
break;
case APP_M3:
__raw_writel(0x0, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET);
break;
default:
printk("proc4430_start: ERROR input\n");
printk(KERN_ERR "proc4430_start: ERROR input\n");
break;
}
return 0;
......@@ -620,6 +624,17 @@ int proc4430_map(void *handle, u32 proc_addr,
u32 va_align;
u32 size_align;
/* FIX ME: Temporary work around until the dynamic memory mapping
* for Tiler address space is available
*/
if ((map_attribs & DSP_MAPTILERADDR)) {
da_align = user_va2pa(current->mm, proc_addr);
*mapped_addr = (da_align | (proc_addr & (PAGE_SIZE - 1)));
printk(KERN_INFO "proc4430_map -tiler: user_va2pa: mapped_addr"
"= 0x%x\n", *mapped_addr);
return 0;
}
dmm_reserve_memory(size, &da);
/* Calculate the page-aligned PA, VA and size */
da_align = PG_ALIGN_LOW((u32)da, PAGE_SIZE);
......@@ -658,6 +673,36 @@ error_exit:
return ret_val;
}
/*=================================================
* Function to return list of translated mem entries
*
* This function takes the remote processor address as
* an input and returns the mapped Page entries in the
* buffer passed
*/
int proc4430_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
u32 num_of_entries)
{
int da_align;
int i;
int ret_val = 0;
if (handle == NULL || mapped_entries == NULL || num_of_entries == 0) {
ret_val = -EFAULT;
goto error_exit;
}
da_align = PG_ALIGN_LOW((u32)da, PAGE_SIZE);
for (i = 0; i < num_of_entries; i++) {
mapped_entries[i] = ducati_mem_virtToPhys(da_align);
da_align += PAGE_SIZE;
}
return 0;
error_exit:
printk(KERN_WARNING "proc4430_virtToPhys failed !!!!\n");
return ret_val;
}
/*=================================================
* Function to return PROC4430 mem_entries info
*
......@@ -669,6 +714,7 @@ int proc4430_proc_info(void *handle, struct proc_mgr_proc_info *procinfo)
struct proc4430_object *object = NULL;
struct proc4430_mem_entry *entry = NULL;
int i;
if (WARN_ON(handle == NULL))
goto error_exit;
if (WARN_ON(procinfo == NULL))
......
......@@ -106,6 +106,10 @@ int proc4430_map(void *handle, u32 proc_addr, u32 size, u32 *mapped_addr,
/* Function to unmap the slave address to host address space */
int proc4430_unmap(void *handle, u32 mapped_addr);
/* Function to retrive physical address translations */
int proc4430_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
u32 num_of_entries);
/* =================================================
* APIs
* =================================================
......
......@@ -139,6 +139,13 @@ typedef int (*processor_unmap_fxn) (void *handle, u32 mapped_addr);
typedef int (*processor_proc_info) (void *handle,
struct proc_mgr_proc_info *proc_info);
/*
*Function pointer type for the function that returns proc info
*/
typedef int (*processor_virt_to_phys_fxn) (void *handle, u32 da,
u32 *mapped_entries, u32 num_of_entries);
/* =============================
* Function table interface
* =============================
......@@ -168,6 +175,8 @@ struct processor_fxn_table {
processor_unmap_fxn unmap;
/* Function to unmap slave addresses to master address space */
processor_proc_info procinfo;
/* Function to convert Virtual to Physical pages */
processor_virt_to_phys_fxn virt_to_phys;
};
/* =============================
......
......@@ -381,3 +381,17 @@ int processor_get_proc_info(void *handle, struct proc_mgr_proc_info *procinfo)
retval = proc_handle->proc_fxn_table.procinfo(proc_handle, procinfo);
return retval;
}
/*
* Function that returns the address translations
*/
int processor_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
u32 num_of_entries)
{
struct processor_object *proc_handle =
(struct processor_object *)handle;
int retval;
retval = proc_handle->proc_fxn_table.virt_to_phys(handle, da,
mapped_entries, num_of_entries);
return retval;
}
......@@ -77,4 +77,7 @@ int processor_register_notify(void *handle, proc_mgr_callback_fxn fxn,
/* Function that returns the return value of specific processor info
*/
int processor_get_proc_info(void *handle, struct proc_mgr_proc_info *procinfo);
int processor_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
u32 num_of_entries);
#endif
......@@ -947,3 +947,28 @@ error_exit:
return -EFAULT;
}
EXPORT_SYMBOL(proc_mgr_get_proc_info);
/*============================================
* Function to get virtual to physical address translations
*
* This function retrieves physical entries
*
*/
int proc_mgr_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
u32 num_of_entries)
{
int retval = 0;
struct proc_mgr_object *proc_mgr_handle =
(struct proc_mgr_object *)handle;
WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
/* Map to host address space. */
retval = processor_virt_to_phys(proc_mgr_handle->proc_handle, da,
mapped_entries, num_of_entries);
WARN_ON(retval < 0);
mutex_unlock(proc_mgr_obj_state.gate_handle);
return retval;;
}
EXPORT_SYMBOL(proc_mgr_virt_to_phys);
......@@ -574,7 +574,26 @@ static int proc_mgr_drv_ioctl(struct inode *inode, struct file *filp,
}
break;
case CMD_PROCMGR_GETVIRTTOPHYS:
{
struct proc_mgr_cmd_args_get_virt_to_phys src_args;
retval = copy_from_user((void *)&src_args,
(const void *)(args),
sizeof(struct proc_mgr_cmd_args_get_virt_to_phys));
retval = proc_mgr_virt_to_phys(src_args.handle,
src_args.da, (src_args.mem_entries),
src_args.num_of_entries);
if (WARN_ON(retval < 0))
goto func_exit;
retval = copy_to_user((void *)(args), (const void *)&src_args,
sizeof(struct proc_mgr_cmd_args_get_virt_to_phys));
WARN_ON(retval < 0);
}
break;
default:
printk(KERN_ERR"PROC_MGR_DRV: WRONG IOCTL !!!!\n");
BUG_ON(1);
break;
}
......
......@@ -176,6 +176,12 @@ struct proc_mgr_cmd_args {
*/
#define CMD_PROCMGR_UNMAP (PROCMGR_BASE_CMD + 27)
/*
* Command for ProcMgr_getVirtToPhysPages
*/
#define CMD_PROCMGR_GETVIRTTOPHYS (PROCMGR_BASE_CMD + 28)
/* ----------------------------------------------------------------------------
......@@ -516,5 +522,20 @@ struct proc_mgr_cmd_args_get_proc_info {
struct proc_mgr_proc_info *proc_info;
/*Pointer to the ProcInfo object to be populated. */
};
/*
* Command arguments for ProcMgr_virtToPhys
*/
struct proc_mgr_cmd_args_get_virt_to_phys {
struct proc_mgr_cmd_args commond_args;
/*Common command args */
void *handle;
u32 da;
/* mem entries buffer */
u32 *mem_entries;
/* number of entries */
u32 num_of_entries;
};
#endif
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