312 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			312 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*-----------------------------------------------------------------------------*/
 | |
| /* Include Header Files                                                        */
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| #include <linux/module.h>
 | |
| #include <asm/io.h>
 | |
| #include <asm/uaccess.h>
 | |
| #include <plat/hardware.h> //for NVT_TIMER_BASE_VIRT
 | |
| #include <linux/platform_device.h>
 | |
| #include <linux/cdev.h>
 | |
| 
 | |
| #define __MODULE__    vos_ioctl
 | |
| #define __DBGLVL__    8 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER
 | |
| #define __DBGFLT__    "*"
 | |
| #include <kwrap/debug.h>
 | |
| #include <kwrap/cpu.h>
 | |
| #include <kwrap/dev.h>
 | |
| #include <kwrap/flag.h>
 | |
| #include <kwrap/perf.h>
 | |
| #include <kwrap/semaphore.h>
 | |
| #include <kwrap/task.h>
 | |
| #include <kwrap/util.h>
 | |
| #include "vos_ioctl.h"
 | |
| 
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| /* Local Types Declarations                                                    */
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| #define VOS_IOCTL_MINOR_CNT      1
 | |
| 
 | |
| #define VOS_STRCPY(dst, src, dst_size) do { \
 | |
| 	strncpy(dst, src, (dst_size)-1); \
 | |
| 	dst[(dst_size)-1] = '\0'; \
 | |
| } while(0)
 | |
| 
 | |
| typedef struct {
 | |
| 	dev_t                   devt;
 | |
| 	struct cdev             cdev;
 | |
| 	struct class            *p_class;
 | |
| 	struct device           *p_device;
 | |
| } VOS_IOCTL_T;
 | |
| 
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| /* Local Global Variables                                                      */
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| unsigned int vos_ioctl_debug_level = NVT_DBG_WRN;
 | |
| static VOS_IOCTL_T g_ioctl = {0};
 | |
| 
 | |
| module_param_named(vos_ioctl_debug_level, vos_ioctl_debug_level, int, S_IRUGO | S_IWUSR);
 | |
| MODULE_PARM_DESC(vos_ioctl_debug_level, "Debug message level");
 | |
| 
 | |
| //=============================================================================
 | |
| // platform device
 | |
| //=============================================================================
 | |
| static int _dev_register(void);
 | |
| static void _dev_unregister(void);
 | |
| 
 | |
| static int _dev_platdrv_probe(struct platform_device *pdev);
 | |
| static int _dev_platdrv_remove(struct platform_device *pdev);
 | |
| 
 | |
| static int _dev_fops_open (struct inode *inode, struct file *file);
 | |
| static int _dev_fops_release (struct inode *inode, struct file *file);
 | |
| static long _dev_fops_ioctl (struct file *file,  unsigned int cmd, unsigned long arg);
 | |
| 
 | |
| static void _dev_platdev_release(struct device *dev)
 | |
| {
 | |
| }
 | |
| 
 | |
| static struct platform_device _dev_platdev_struct = {
 | |
| 	.name   =   VOS_IOCTL_DEV_NAME,
 | |
| 	.id     =   0,
 | |
| 	.resource = NULL,
 | |
| 	.dev = {
 | |
| 		.release = _dev_platdev_release,
 | |
| 	},
 | |
| };
 | |
| 
 | |
| static struct platform_driver _dev_platdrv_struct = {
 | |
| 	.probe  =   _dev_platdrv_probe,
 | |
| 	.remove =   _dev_platdrv_remove,
 | |
| 	.driver =   {
 | |
| 		.name   =   VOS_IOCTL_DEV_NAME,
 | |
| 		.owner  =   THIS_MODULE,
 | |
| 	},
 | |
| };
 | |
| 
 | |
| // Kernel interface
 | |
| static struct file_operations _dev_fops = {
 | |
| 	.owner          =   THIS_MODULE,
 | |
| 	.open           =   _dev_fops_open,
 | |
| 	.release        =   _dev_fops_release,
 | |
| 	.unlocked_ioctl =   _dev_fops_ioctl,
 | |
| };
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| /* Interface Functions                                                         */
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| void vos_ioctl_init(void *param)
 | |
| {
 | |
| 	DBG_FUNC_BEGIN("\r\n");
 | |
| 
 | |
| 	if (0 != _dev_register()) {
 | |
| 		DBG_ERR("_dev_register failed\r\n");
 | |
| 		goto END_INIT;
 | |
| 	}
 | |
| 
 | |
| END_INIT:
 | |
| 	DBG_FUNC_END("\r\n");
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| void vos_ioctl_exit(void)
 | |
| {
 | |
| 	_dev_unregister();
 | |
| }
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| /* Kernel IOCTL                                                                */
 | |
| /*-----------------------------------------------------------------------------*/
 | |
| static int _dev_register(void)
 | |
| {
 | |
| 	//register device
 | |
| 	if (0 != platform_device_register(&_dev_platdev_struct)) {
 | |
| 		DBG_ERR("platform_device_register failed\n");
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	if (0 != platform_driver_register(&_dev_platdrv_struct)) {
 | |
| 		DBG_ERR("platform_driver_register failed\n");
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static void _dev_unregister(void)
 | |
| {
 | |
| 	platform_driver_unregister(&_dev_platdrv_struct);
 | |
| 	platform_device_unregister(&_dev_platdev_struct);
 | |
| }
 | |
| 
 | |
| static int _dev_platdrv_probe(struct platform_device *pdev)
 | |
| {
 | |
| 	int reg_err = 0, cdev_err = 0;
 | |
| 
 | |
| 	reg_err = vos_alloc_chrdev_region(&g_ioctl.devt, VOS_IOCTL_MINOR_CNT, VOS_IOCTL_DEV_NAME);
 | |
| 	if (reg_err) {
 | |
| 		DBG_ERR(" alloc_chrdev_region failed!\n");
 | |
| 		goto _dev_platdrv_probe_err;
 | |
| 	}
 | |
| 
 | |
| 	cdev_init(&g_ioctl.cdev, &_dev_fops);
 | |
| 	g_ioctl.cdev.owner = THIS_MODULE;
 | |
| 
 | |
| 	cdev_err = cdev_add(&g_ioctl.cdev, g_ioctl.devt, VOS_IOCTL_MINOR_CNT);
 | |
| 	if (cdev_err) {
 | |
| 		DBG_ERR(" cdev_add failed!\n");
 | |
| 		goto _dev_platdrv_probe_err;
 | |
| 	}
 | |
| 
 | |
| 	g_ioctl.p_class = class_create(THIS_MODULE, VOS_IOCTL_DEV_NAME);
 | |
| 	if (IS_ERR(g_ioctl.p_class)) {
 | |
| 		DBG_ERR(" class_create failed!\n");
 | |
| 		goto _dev_platdrv_probe_err;
 | |
| 	}
 | |
| 
 | |
| 	g_ioctl.p_device = device_create(g_ioctl.p_class, NULL, g_ioctl.devt, NULL, VOS_IOCTL_DEV_NAME);
 | |
| 	if (NULL == g_ioctl.p_device) {
 | |
| 		DBG_ERR(" device_create failed!\n");
 | |
| 		goto _dev_platdrv_probe_err;
 | |
| 	}
 | |
| 	return 0;
 | |
| 
 | |
| _dev_platdrv_probe_err:
 | |
| 
 | |
| 	if (g_ioctl.p_device) {
 | |
| 		device_destroy(g_ioctl.p_class, g_ioctl.devt);
 | |
| 	}
 | |
| 	if (g_ioctl.p_class) {
 | |
| 		class_destroy(g_ioctl.p_class);
 | |
| 	}
 | |
| 	if (!cdev_err) {
 | |
| 		cdev_del(&g_ioctl.cdev);
 | |
| 	}
 | |
| 	if (!reg_err) {
 | |
| 		vos_unregister_chrdev_region(g_ioctl.devt, VOS_IOCTL_MINOR_CNT);
 | |
| 	}
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| static int _dev_platdrv_remove(struct platform_device *pdev)
 | |
| {
 | |
| 	device_destroy(g_ioctl.p_class, g_ioctl.devt);
 | |
| 	class_destroy(g_ioctl.p_class);
 | |
| 
 | |
| 	cdev_del(&g_ioctl.cdev);
 | |
| 	vos_unregister_chrdev_region(g_ioctl.devt, VOS_IOCTL_MINOR_CNT);
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int _dev_fops_open(struct inode *inode, struct file *file)
 | |
| {
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| static int _dev_fops_release(struct inode *inode, struct file *file)
 | |
| {
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static long _dev_fops_ioctl(struct file *file,  unsigned int cmd, unsigned long arg)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 
 | |
| 	switch (cmd) {
 | |
| 	// CPU IOCTL
 | |
| 	case VOS_CPU_IOCMD_DCACHE_SYNC:
 | |
| 		ret = _IOFUNC_CPU_IOCMD_DCACHE_SYNC(arg);
 | |
| 		break;
 | |
| 	case VOS_CPU_IOCMD_GET_PHY_ADDR:
 | |
| 		ret = _IOFUNC_CPU_IOCMD_GET_PHY_ADDR(arg);
 | |
| 		break;
 | |
| 	case VOS_CPU_IOCMD_SYNC_CPU:
 | |
| 		ret = _IOFUNC_CPU_IOCMD_SYNC_CPU(arg);
 | |
| 		break;
 | |
| 
 | |
| 	// DEBUG IOCTL
 | |
| 	case VOS_DEBUG_IOCMD_HALT:
 | |
| 		ret = _IOFUNC_DEBUG_IOCMD_HALT(arg);
 | |
| 		break;
 | |
| 
 | |
| 	// FLAG IOCTL
 | |
| 	case VOS_FLAG_IOCMD_CREATE:
 | |
| 		ret = _IOFUNC_FLAG_IOCMD_CREATE(arg);
 | |
| 		break;
 | |
| 	case VOS_FLAG_IOCMD_SET:
 | |
| 		ret = _IOFUNC_FLAG_IOCMD_SET(arg);
 | |
| 		break;
 | |
| 	case VOS_FLAG_IOCMD_CLR:
 | |
| 		ret = _IOFUNC_FLAG_IOCMD_CLR(arg);
 | |
| 		break;
 | |
| 	case VOS_FLAG_IOCMD_WAIT:
 | |
| 		ret = _IOFUNC_FLAG_IOCMD_WAIT(arg);
 | |
| 		break;
 | |
| 	case VOS_FLAG_IOCMD_CHK:
 | |
| 		ret = _IOFUNC_FLAG_IOCMD_CHK(arg);
 | |
| 		break;
 | |
| 	case VOS_FLAG_IOCMD_DESTROY:
 | |
| 		ret = _IOFUNC_FLAG_IOCMD_DESTROY(arg);
 | |
| 		break;
 | |
| 
 | |
| 	// SEM IOCTL
 | |
| 	case VOS_SEM_IOCMD_CREATE:
 | |
| 		ret = _IOFUNC_SEM_IOCMD_CREATE(arg);
 | |
| 		break;
 | |
| 	case VOS_SEM_IOCMD_WAIT:
 | |
| 		ret = _IOFUNC_SEM_IOCMD_WAIT(arg);
 | |
| 		break;
 | |
| 	case VOS_SEM_IOCMD_SIG:
 | |
| 		ret = _IOFUNC_SEM_IOCMD_SIG(arg);
 | |
| 		break;
 | |
| 	case VOS_SEM_IOCMD_DESTROY:
 | |
| 		ret = _IOFUNC_SEM_IOCMD_DESTROY(arg);
 | |
| 		break;
 | |
| 
 | |
| 	// TASK IOCTL
 | |
| 	case VOS_TASK_IOCMD_SET_UINFO:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_SET_UINFO(arg);
 | |
| 		break;
 | |
| 	case VOS_TASK_IOCMD_GET_UINFO:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_GET_UINFO(arg);
 | |
| 		break;
 | |
| 	case VOS_TASK_IOCMD_REG_N_RUN:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_REG_N_RUN(arg);
 | |
| 		break;
 | |
| 	case VOS_TASK_IOCMD_SET_PRIORITY:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_SET_PRIORITY(arg);
 | |
| 		break;
 | |
| 	case VOS_TASK_IOCMD_DESTROY:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_DESTROY(arg);
 | |
| 		break;
 | |
| 	case VOS_TASK_IOCMD_RETURN:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_RETURN(arg);
 | |
| 		break;
 | |
| 	case VOS_TASK_IOCMD_RESUME:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_RESUME(arg);
 | |
| 		break;
 | |
| 	case VOS_TASK_IOCMD_CONVERT_HDL:
 | |
| 		ret = _IOFUNC_TASK_IOCMD_CONVERT_HDL(arg);
 | |
| 		break;
 | |
| 
 | |
| 	// PERF IOCTL
 | |
| 	case VOS_PERF_IOCMD_MARK:
 | |
| 		ret = _IOFUNC_PERF_IOCMD_MARK(arg);
 | |
| 		break;
 | |
| 	case VOS_PERF_IOCMD_LIST_MARK:
 | |
| 		ret = _IOFUNC_PERF_IOCMD_LIST_MARK(arg);
 | |
| 		break;
 | |
| 	case VOS_PERF_IOCMD_LIST_DUMP:
 | |
| 		ret = _IOFUNC_PERF_IOCMD_LIST_DUMP(arg);
 | |
| 		break;
 | |
| 	case VOS_PERF_IOCMD_LIST_RESET:
 | |
| 		ret = _IOFUNC_PERF_IOCMD_LIST_RESET(arg);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		DBG_WRN("Unknown IOCMD 0x%08X\n", (u32)cmd);
 | |
| 		ret = -EINVAL;
 | |
| 		break;
 | |
| 	}
 | |
| 
 | |
| 	return ret;
 | |
| }
 | 
