Merge branch 'dev_ck_v2.1_lwh' into 'dev_ck_v2.1'

delete ko source code

See merge request ucp/driver/ucp4008_platform_arm!1
This commit is contained in:
Xianfeng Du 2023-07-15 06:25:18 +00:00
commit cd47bbce35
15 changed files with 0 additions and 2025 deletions

25
driver/cache/Makefile vendored
View File

@ -1,25 +0,0 @@
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
#KERNELDIR = /public/liweihua/workspace/linux-5.15.40
KERNELDIR = /public/liweihua/workspace/linux-5.10.165
OBJ = SM_DDR
PWD = $(shell pwd)
# Kernel modules
ifeq ($(OBJ),SM_DDR)
obj-m=ucp4008cache.o
#ucp4008cache-objs=osp_sm_ddr.o
#ucp4008cache-objs = cache.o osp_sm_ddr.o
ucp4008cache-y:=osp_sm_ddr.o cache.o
endif
# Specify flags for the module compilation.
ccflags-y = -g -O0
#INCLUDE += -l./../../common/
build: kernel_modules
kernel_modules:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean

78
driver/cache/cache.S vendored
View File

@ -1,78 +0,0 @@
/*
* Cache maintenance
*
* Copyright (C) 2001 Deep Blue Solutions Ltd.
* Copyright (C) 2012 ARM Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/errno.h>
#include <linux/linkage.h>
#include <linux/init.h>
//#include <asm/assembler.h>
#include <asm/alternative.h>
#include <asm/asm-uaccess.h>
/*
* dcache_line_size - get the safe D-cache line size across all CPUs
*/
.macro mydcache_line_size, reg, tmp
//read_ctr \tmp
mrs \tmp, ctr_el0
ubfm \tmp, \tmp, #16, #19 // cache line size encoding
mov \reg, #4 // bytes per word
lsl \reg, \reg, \tmp // actual cache line size
.endm
/*
* __inval_dcache_area(kaddr, size)
*
* Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
* are invalidated. Any partial lines at the ends of the interval are
* also cleaned to PoC to prevent data loss.
*
* - kaddr - kernel address
* - size - size in question
*/
SYM_FUNC_START(__myinval_dcache_area)
/* FALLTHROUGH */
/*
* __dma_inv_area(start, size)
* - start - virtual start address of region
* - size - size in question
*/
__mydma_inv_area:
add x1, x1, x0
mydcache_line_size x2, x3
sub x3, x2, #1
tst x1, x3 // end cache line aligned?
bic x1, x1, x3
b.eq 1f
dc civac, x1 // clean & invalidate D / U line
1: tst x0, x3 // start cache line aligned?
bic x0, x0, x3
b.eq 2f
dc civac, x0 // clean & invalidate D / U line
b 3f
2: dc ivac, x0 // invalidate D / U line
3: add x0, x0, x2
cmp x0, x1
b.lo 2b
dsb sy
ret
//ENDPIPROC(__myinval_dcache_area)
//SYM_FUNC_END(__mydma_inv_area)
SYM_FUNC_END(__myinval_dcache_area)

View File

@ -1,532 +0,0 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mod_devicetable.h>
#include <linux/of_address.h>
#include <asm/io.h>
#include <linux/async_tx.h>
#include <linux/dmaengine.h>
#include <linux/gfp.h>
#include <linux/dma-mapping.h>
/*函数原型*/
static int __init ucp_sm_ddr_module_init(void);
int ucp_sm_ddr_cache_open(struct inode *inode, struct file *filp);
int ucp_sm_ddr_noncache_open(struct inode *inode, struct file *filp);
int ucp_sm_ddr_cache_release(struct inode *inode, struct file *filp);
int ucp_sm_ddr_noncache_release(struct inode *inode, struct file *filp);
ssize_t ucp_sm_ddr_cache_read(struct file *filp, char __user *buf, size_t size_in, loff_t *ppos);
ssize_t ucp_sm_ddr_noncache_read(struct file *filp, char __user *buf, size_t size_in, loff_t *ppos);
ssize_t ucp_sm_ddr_cache_write(struct file *filp, char __user *buf, size_t size, loff_t *ppos);
ssize_t ucp_sm_ddr_noncache_write(struct file *filp, char __user *buf, size_t size, loff_t *ppos);
static long ucp_sm_ddr_cache_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
static long ucp_sm_ddr_noncache_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
static int ucp_sm_ddr_cache_mmap(struct file *filp, struct vm_area_struct *vma);
static int ucp_sm_ddr_noncache_mmap(struct file *filp, struct vm_area_struct *vma);
static ssize_t ucp_mem_show(struct device *dev,struct device_attribute *attr, char *buf);
static void __exit ucp_sm_ddr_module_exit(void);
extern void __myinval_dcache_area(unsigned long vir_cache_add, unsigned long len);
static const struct vm_operations_struct osp_mmap_mem_ops = {
#ifdef CONFIG_HAVE_IOREMAP_PROT
.access = generic_access_phys
#endif
};
/*申请设备名称*/
#define DEVICE_NAME_SM_DDR_CACHE "ucp_sm_ddr_cache"
#define DEVICE_NAME_SM_DDR_NONCACHE "ucp_sm_ddr_noncache"
/*设备物理地址*/
#if 1 //4008 add
#define ECS_SM_BASE 0x07200000ul
#define PET_SM_BASE 0x08700000ul
#define SHARE_SM_BASE 0x09d00000ul
#define DDR_BASE 0x10000000ul
#define ARM_APE_MSG_BASE_PHY_ADDR 0x0A0000000UL
#define ARM_STACK_BASE_PHY_ADDR 0x100000000UL //0x0B8000000UL
/*size num*/
#define S128KB 0x00020000ul // 128K
#define S8MB 0x00800000ul // 8M
#define S16GB 0x1F0000000ul //0x400000000ul // 16G
#define LEN_OF_ARM_STACK 0x100000000UL
#define LEN_OF_ARM_APE_MSG 0x008000000UL
/*设备空间大小*/
#define ECS_SM_SIZE 0x000060000UL
#define ECS_SM_MAX 0x00725fffful
#define PET_SM_SIZE 0x000060000UL
#define PET_SM_MAX 0x00875fffful
#define SHARE_SM_SIZE S8MB
#define SHARE_SM_MAX 0x0a4ffffful
#define DDR_SIZE S16GB
#define DDR_MAX 0x1fffffffful
#endif
#if 0 //1002 add
#define ECS_SM_BASE 0x02360000ul
#define PET_SM_BASE 0x03860000ul
#define SHARE_SM_BASE 0x04e60000ul
#define DDR_BASE 0x10000000ul
#define S128KB 0x00020000ul // 128K
#define S8MB 0x00800000ul // 8M
#define S16GB 0x400000000ul // 16G
#define ECS_SM_SIZE S128KB
#define ECS_SM_MAX 0x0237fffful
#define PET_SM_SIZE S128KB
#define PET_SM_MAX 0x0387fffful
#define SHARE_SM_SIZE S8MB
#define SHARE_SM_MAX 0x0565fffful
#define DDR_SIZE S16GB
#define DDR_MAX 0x40ffffffful
#endif
/*error num*/
#define EINVAL 22 /* Invalid argument */
/*全局变量声明初始化*/
/*file operation structure*/
static const struct file_operations ucp_sm_ddr_cache_fops =
{
.owner = THIS_MODULE,
.open = ucp_sm_ddr_cache_open,
.unlocked_ioctl = ucp_sm_ddr_cache_ioctl,
.mmap = ucp_sm_ddr_cache_mmap,
.release = ucp_sm_ddr_cache_release,
};
static const struct file_operations ucp_sm_ddr_noncache_fops =
{
.owner = THIS_MODULE,
.open = ucp_sm_ddr_noncache_open,
.unlocked_ioctl = ucp_sm_ddr_noncache_ioctl,
.mmap = ucp_sm_ddr_noncache_mmap,
.release = ucp_sm_ddr_noncache_release,
};
static struct miscdevice ucp_sm_ddr_cache_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME_SM_DDR_CACHE,
.fops = &ucp_sm_ddr_cache_fops,
};
static struct miscdevice ucp_sm_ddr_noncache_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME_SM_DDR_NONCACHE,
.fops = &ucp_sm_ddr_noncache_fops,
};
void __iomem * g_vir_ecs_sm_cache_add = NULL;
void __iomem * g_vir_pet_sm_cache_add = NULL;
void __iomem * g_vir_share_sm_cache_add = NULL;
void __iomem * g_vir_ddr_cache_add = NULL;
void __iomem * g_vir_msg_cache_add = NULL;
void __iomem * g_vir_stack_cache_add = NULL;
static DEVICE_ATTR(ucp_sm_ddr_cache, S_IRUGO, ucp_mem_show, NULL);
static DEVICE_ATTR(ucp_sm_ddr_noncache, S_IRUGO, ucp_mem_show, NULL);
/********************************************************************/
/*********************sm0~sm5 & ddr driver init function********************/
/********************************************************************/
static int __init ucp_sm_ddr_module_init(void)
{
int iRet=0;
/*注册 设备驱动*/
iRet = misc_register(&ucp_sm_ddr_cache_miscdev);
if(iRet)
{
goto sm_ddr_misc_err;
}
iRet = misc_register(&ucp_sm_ddr_noncache_miscdev);
if(iRet)
{
goto sm_ddr_misc_err;
}
/*在/sys/class 目录下创建对应的属性文件*/
iRet = device_create_file(ucp_sm_ddr_cache_miscdev.this_device, &dev_attr_ucp_sm_ddr_cache);
if (iRet)
{
goto sm_ddr_cache_attr_err;
printk(KERN_EMERG "ucp_sm_ddr_cache_module_init failed \r\n");
}
printk(KERN_EMERG "ucp_sm_ddr_cache_module_init ok cat /sys/devices/virtual/misc/ucp_sm_ddr_cache\r\n");
iRet = device_create_file(ucp_sm_ddr_noncache_miscdev.this_device, &dev_attr_ucp_sm_ddr_noncache);
if (iRet)
{
goto sm_ddr_noncache_attr_err;
printk(KERN_EMERG "ucp_sm_ddr_noncache_module_init failed \r\n");
}
printk(KERN_EMERG "ucp_sm_ddr_noncache_module_init ok cat /sys/devices/virtual/misc/ucp_sm_ddr_noncache\r\n");
g_vir_ecs_sm_cache_add = ioremap(ECS_SM_BASE, ECS_SM_SIZE);
g_vir_pet_sm_cache_add = ioremap(PET_SM_BASE, PET_SM_SIZE);
g_vir_share_sm_cache_add = ioremap(SHARE_SM_BASE, SHARE_SM_SIZE);
g_vir_msg_cache_add = ioremap(ARM_APE_MSG_BASE_PHY_ADDR, LEN_OF_ARM_APE_MSG);
g_vir_stack_cache_add = ioremap(ARM_STACK_BASE_PHY_ADDR, LEN_OF_ARM_STACK);
printk(KERN_EMERG "globle g_vir_ecs_sm_cache_add = 0x%lx \n ",(uint64_t)g_vir_ecs_sm_cache_add);
printk(KERN_EMERG "globle g_vir_pet_sm_cache_add = 0x%lx \n ",(uint64_t)g_vir_pet_sm_cache_add);
printk(KERN_EMERG "globle g_vir_share_sm_cache_add = 0x%lx \n ",(uint64_t)g_vir_share_sm_cache_add);
//printk(KERN_EMERG "globle g_vir_ddr_cache_add = 0x%lx \n ",g_vir_ddr_cache_add);
printk(KERN_EMERG "globle g_vir_msg_cache_add = 0x%lx \n ",(uint64_t)g_vir_msg_cache_add);
printk(KERN_EMERG "globle g_vir_stack_cache_add = 0x%lx \n ",(uint64_t)g_vir_stack_cache_add);
return 0;
sm_ddr_cache_attr_err:
misc_deregister(&ucp_sm_ddr_cache_miscdev);
sm_ddr_noncache_attr_err:
misc_deregister(&ucp_sm_ddr_noncache_miscdev);
sm_ddr_misc_err:
return -EINVAL;
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/*********************sm0~sm5 & ddr driver open function********************/
/********************************************************************/
int ucp_sm_ddr_cache_open(struct inode *inode, struct file *filp)
{
/* device structure pointer assgined to file private data pointer */
printk("enter %s\n",__func__);
return 0;
}
int ucp_sm_ddr_noncache_open(struct inode *inode, struct file *filp)
{
/* device structure pointer assgined to file private data pointer */
printk("enter %s\n",__func__);
return 0;
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/*********************sm0~sm5 & ddr driver release function*******************/
/********************************************************************/
int ucp_sm_ddr_cache_release(struct inode *inode, struct file *filp)
{
return 0;
}
int ucp_sm_ddr_noncache_release(struct inode *inode, struct file *filp)
{
return 0;
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/*********************sm0~sm5 & ddr driver read function*******************/
/********************************************************************/
ssize_t ucp_sm_ddr_cache_read(struct file *filp, char __user *buf, size_t size_in, loff_t *ppos)
{
return 0;
}
ssize_t ucp_sm_ddr_noncache_read(struct file *filp, char __user *buf, size_t size_in, loff_t *ppos)
{
return 0;
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/*********************sm0~sm5 & ddr driver write function*******************/
/********************************************************************/
ssize_t ucp_sm_ddr_cache_write(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
ssize_t ucp_sm_ddr_noncache_write(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/*********************sm0~sm5 & ddr driver ioctl function*******************/
/********************************************************************/
static long ucp_sm_ddr_cache_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
void __iomem *vir_cache_add = NULL;
unsigned long uiOffset= 0, addr = arg, len = cmd;
//printk("enter %s\n\n",__func__);
//printk("addr = %#lx len = %#lx\n\n",cmd,arg);
if(addr >= ECS_SM_BASE && addr <= ECS_SM_MAX)
{
uiOffset = addr - ECS_SM_BASE;
vir_cache_add = g_vir_ecs_sm_cache_add + uiOffset ;
}
else if(addr >= PET_SM_BASE && addr <= PET_SM_MAX)
{
uiOffset = addr - PET_SM_BASE;
vir_cache_add = g_vir_pet_sm_cache_add + uiOffset ;
}
else if(addr >= SHARE_SM_BASE && addr <= SHARE_SM_MAX)
{
uiOffset = addr - SHARE_SM_BASE;
vir_cache_add = g_vir_share_sm_cache_add + uiOffset ;
}
else if(addr >= ARM_APE_MSG_BASE_PHY_ADDR && addr < ARM_APE_MSG_BASE_PHY_ADDR + LEN_OF_ARM_APE_MSG)
{
uiOffset = addr - ARM_APE_MSG_BASE_PHY_ADDR;
vir_cache_add = g_vir_msg_cache_add + uiOffset ;
}
else if(addr >= ARM_STACK_BASE_PHY_ADDR && addr < ARM_STACK_BASE_PHY_ADDR + LEN_OF_ARM_STACK)
{
uiOffset = addr - ARM_STACK_BASE_PHY_ADDR;
vir_cache_add = g_vir_stack_cache_add + uiOffset ;
}
else
{
printk("ucp_sm_ddr_cache_ioctl phy add out of range \n ");
return -1;
}
//__mydma_inv_area(vir_cache_add, arg);
__myinval_dcache_area((unsigned long)vir_cache_add, len);
return 0;
}
static long ucp_sm_ddr_noncache_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
return 0;
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/*********************sm0~sm5 & ddr driver mmap function*******************/
/********************************************************************/
static int ucp_sm_ddr_cache_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long vmsize = vma->vm_end - vma->vm_start;
unsigned long psize = PAGE_SIZE - offset;
pgprot_t prot = vma->vm_page_prot;
/* 设置IO标志 */
/*if(vmsize > psize) {
return -ENXIO;
}*/
printk("enter %s,phyaddr = %#lx,vm_start = %#lx\n",__func__,offset,vma->vm_start);
//printk(KERN_EMERG "titan : cached mode is cache \n");
//printk(KERN_EMERG "titan : vma->vm_pgoff = 0x%x \n",offset);
vma->vm_ops = &osp_mmap_mem_ops;
if(remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vmsize, prot) != 0) {
return -EAGAIN;
}
//printk(KERN_EMERG "titan : vma->vm_start = 0x%x \n",vma->vm_start);
return 0;
}
static int ucp_sm_ddr_noncache_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long vmsize = vma->vm_end - vma->vm_start;
unsigned long psize = PAGE_SIZE - offset;
pgprot_t prot = vma->vm_page_prot;
/* 设置IO标志 */
// vir_sm_noncache_add = ioremap_nocache(SM_BASE, SM_SIZE);
// vir_ddr_noncache_add = ioremap_nocache(DDR_BASE, DDR_SIZE);
/*if(vmsize > psize) {
return -ENXIO;
} */
printk("enter %s,phyaddr = %#lx,vm_start = %#lx\n",__func__,offset,vma->vm_start);
//printk(KERN_EMERG "titan : vma->vm_pgoff = 0x%x \n",offset);
prot = pgprot_writecombine(prot);
vma->vm_ops = &osp_mmap_mem_ops;
//printk(KERN_EMERG "titan : cached mode is non cache \n");
if(remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vmsize, prot) != 0) {
return -EAGAIN;
}
return 0;
}
/********************************************************************/
/********************************************************************/
static ssize_t ucp_mem_show(struct device *dev,struct device_attribute *attr, char *buf)
{
return 0;
}
/********************************************************************/
/*********************sm0~sm5 & ddr driver exit function*******************/
/********************************************************************/
/* module unload function*/
static void __exit ucp_sm_ddr_module_exit(void)
{
iounmap(g_vir_ecs_sm_cache_add);
iounmap(g_vir_pet_sm_cache_add);
iounmap(g_vir_share_sm_cache_add);
iounmap(g_vir_ddr_cache_add);
device_remove_file(ucp_sm_ddr_cache_miscdev.this_device, &dev_attr_ucp_sm_ddr_cache);
device_remove_file(ucp_sm_ddr_noncache_miscdev.this_device, &dev_attr_ucp_sm_ddr_noncache);
misc_deregister(&ucp_sm_ddr_cache_miscdev);
misc_deregister(&ucp_sm_ddr_noncache_miscdev);
}
/********************************************************************/
/********************************************************************/
/*
* a simple char device driver: ExtInt without mutex
*
* Copyright (C) 2014 Barry Song (baohua@kernel.org)
*
* Licensed under GPLv2 or later.
*/
MODULE_AUTHOR ("lte team");
MODULE_DESCRIPTION ("ucp_sm_ddr driver module" );
MODULE_LICENSE ("GPL");
module_init(ucp_sm_ddr_module_init);
module_exit(ucp_sm_ddr_module_exit);
MODULE_INFO(intree, "Y");

View File

@ -1,20 +0,0 @@
export ARCH = arm64
export CROSS_COMPILE = aarch64-linux-gnu-
ARCH=arm64
CROSS_COMPILE = aarch64-linux-gnu-
KERNELDIR ?= /public/linboheng/workspace/ucp4008_nr_integrated_small_cell_new_kernel/kernel/linux-5.10.165
PWD = $(shell pwd)
obj-m := ioreg.o
# Specify flags for the module compilation.
ccflags-y = -g -O0
build: kernel_modules
kernel_modules:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean

View File

@ -1,182 +0,0 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/mod_devicetable.h>
#include <linux/of_address.h>
#include <asm/io.h>
#include <linux/async_tx.h>
#include <linux/dmaengine.h>
#include <linux/gfp.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/mailbox_client.h>
#include <asm/div64.h>
#include <linux/of_irq.h>
#include <linux/io.h>
#include <linux/semaphore.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/timex.h>
#define IOCTL_MMAPREG _IO('k',0x20)
#define DEVICE_NAME "ioreg"
void __iomem * addr;
/*file open function*/
int ioreg_open(struct inode *inode, struct file *filp)
{
/* device structure pointer assgined to file private data pointer */
return 0;
}
/*file release function*/
int ioreg_release(struct inode *inode, struct file *filp)
{
return 0;
}
/* ioctl device control function */
static long ioreg_ioctl(struct file *filp, u32 cmd, unsigned long arg)
{
u32 val;
switch ((int)cmd)
{
case IOCTL_MMAPREG:
get_user(val, (unsigned long *)arg);
addr = ioremap(val, 4096);
break;
default:
return - EINVAL;
}
return 0;
}
ssize_t ioreg_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
if (copy_to_user(buf, (void *)(addr), size))
{
return -EFAULT;
}
iounmap(addr);
return 0;
}
ssize_t ioreg_write(struct file *filp,const char __user *buf, size_t size, loff_t *ppos)
{
if(copy_from_user((void *)(addr), buf, size))
{
return -EFAULT;
}
iounmap(addr);
return 0;
}
/*file operation structure*/
static const struct file_operations ioreg_fops =
{
.owner = THIS_MODULE,
.open = ioreg_open,
.read = ioreg_read,
.write = ioreg_write,
.unlocked_ioctl = ioreg_ioctl,
.release = ioreg_release,
};
static struct miscdevice ioreg_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &ioreg_fops,
};
static int __init ioreg_module_init(void)
{
struct device_node *np;
int ret;
ret = misc_register(&ioreg_miscdev);
if(ret)
{
return -1;
}
printk(KERN_EMERG "ioreg_module_init ok ");
return 0;
}
/* module unload function*/
static void __exit ioreg_module_exit(void)
{
misc_deregister(&ioreg_miscdev);
}
/*
* a simple char device driver: ExtInt without mutex
*
* Copyright (C) 2014 Barry Song (baohua@kernel.org)
*
* Licensed under GPLv2 or later.
*/
MODULE_AUTHOR ("lte team");
MODULE_DESCRIPTION ("FRAME_SYNC driver module" );
MODULE_LICENSE ("GPL");
module_init(ioreg_module_init);
module_exit(ioreg_module_exit);

View File

@ -1,288 +0,0 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/poll.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/mm.h>//remap_pfn_range
/* 主设备号 */
#define BSP_DEV_MAJOR 0
/* 主设备名 */
#define BSP_DEV_NAME "mem_dump"
/* 模块加载函数 */
static int osp_mem_init(void);
/* 模块卸载函数 */
static void osp_mem_exit(void);
/* 打开设备函数 */
int mem_bsp_open(struct inode *inode, struct file *filp);
/* 释放设备函数 */
int mem_bsp_release(struct inode *inode, struct file *filp);
/* 读函数 */
static ssize_t mem_bsp_read (struct file *filp, __user char *buf, size_t count, loff_t *f_pos);
/* ioctl函数 */
long mem_bsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
/* mmap函数 */
int mem_bsp_mmap(struct file *filp, struct vm_area_struct *vma);
/* 写函数 */
ssize_t mem_bsp_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
/******************************* 局部宏定义 ***********************************/
/* bsp 主设备号 */
typedef struct mem_struct{
int g_s32BspDevMajor ;
unsigned int g_u32CacheCoherent;
struct cdev g_struBspDev;
struct class *cls;
dev_t g_devno;
struct device *parent;
struct device *this_device;
}mem_st;
/******************************* 函数实现 *************************************/
/*******************************************************************************
* : mem_init
* :
* :
* :int
* :
* :
* 0
* <0
* Linux错误信息头文件
*******************************************************************************/
static mem_st mem_dev ={
.g_s32BspDevMajor = 0,
.g_u32CacheCoherent = 0,
.g_devno = 0,
};
static struct file_operations g_struBspOp = {
.owner = THIS_MODULE,
.read = mem_bsp_read,
.write = mem_bsp_write,
.open = mem_bsp_open,
.release = mem_bsp_release,
.mmap = mem_bsp_mmap,
.unlocked_ioctl = mem_bsp_ioctl,
};
static int osp_mem_init(void)
{
/*函数调用结果*/
int result;
/*设备编号*/
dev_t devno;
printk("bsp_init.\n");
/* 获取设备号 */
if (0 == mem_dev.g_s32BspDevMajor)
{
/* 分配设备区域 */
result = alloc_chrdev_region(&devno, 0, 1, BSP_DEV_NAME);
/* 判断返回值 */
if (result < 0)
{
printk(KERN_WARNING "bsp: alloc_chrdev_region error! errno = %d\n", result);
return result;
}
mem_dev.g_devno = devno;
/* 保存主设备号信息 */
mem_dev.g_s32BspDevMajor = MAJOR(devno);
/* 初始化dev变量 */
cdev_init(&(mem_dev.g_struBspDev), &g_struBspOp);
/* 设备dev相应变量值 */
mem_dev.g_struBspDev.owner = THIS_MODULE;
mem_dev.g_struBspDev.ops = &g_struBspOp;
/* 向系统增加dev设备 */
result = cdev_add(&mem_dev.g_struBspDev, devno, 1);
if (result < 0)
{
printk ("cdev_add error!errno = %d", result);
}
// ret = device_create_file(ucp_smem_miscdev.this_device, &dev_attr_ucp_smem);
mem_dev.cls = class_create(THIS_MODULE, "mem_dump");
device_create(mem_dev.cls, NULL, devno, NULL, "mem_dump");
printk("bsp module init success!\n");
/* 返回成功 */
return 0;
}
else
{
printk("bsp module already init!\n");
/* 返回 */
return -EBUSY;
}
}
/*******************************************************************************
* : ad9371_exit
* :
* :
* :void
* :
* :
*
*******************************************************************************/
static void osp_mem_exit(void)
{
/* 判断是否执行过模块加载 */
if(mem_dev.g_s32BspDevMajor > 0)
{
/* 删除该字符设备 */
device_destroy(mem_dev.cls, mem_dev.g_devno);
class_destroy(mem_dev.cls);
cdev_del(&(mem_dev.g_struBspDev));
/* 释放已分配的空间 */
unregister_chrdev_region(MKDEV(mem_dev.g_s32BspDevMajor, 0), 1);
/* 清空主设备号 */
mem_dev.g_s32BspDevMajor = 0;
/* 调试信息输出 */
printk("bsp module cleanup success!\n");
}
return;
}
/*******************************************************************************
* : ad9731_bsp_open
* :
* :
* :int
* :
*
* /
* -------- ---- --- -----------
* inode struct inode* input
* filp struct file* input
* :
* 0
*
*******************************************************************************/
int mem_bsp_open(struct inode *inode, struct file *filp)
{
return 0;
}
/*******************************************************************************
* : ad9731_bsp_release
* :
* :
* :int
* :
*
* /
* -------- ---- --- -----------
* inode struct inode* input
* filp struct file* input
* :
* 0
*
*******************************************************************************/
int mem_bsp_release(struct inode *inode, struct file *filp)
{
/* 操作成功 */
return 0;
}
/*******************************************************************************
* : ad9731_bsp_read ()
*
* :
* : <>
* :
*******************************************************************************/
static ssize_t mem_bsp_read (struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
return 0;
}
/*******************************************************************************
* : ad9731_bsp_write ()
*
* :
* : <>
* :
*******************************************************************************/
ssize_t mem_bsp_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
return 0;
}
/*******************************************************************************
* : ad9731_bsp_ioctl
* : IO控制
* :
* :int
* :
*******************************************************************************/
long mem_bsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
return 0;
}
/*******************************************************************************
* : mem_bsp_mmap
* : IO内存映射
* :
* :int
* :
*
*******************************************************************************/
int mem_bsp_mmap(struct file *filp, struct vm_area_struct *vma)
{
/* 设置IO标志 */
vma->vm_flags |= VM_IO;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
printk("mmap start\n\r");
/* 建立映射 */
if (remap_pfn_range(vma,
vma->vm_start,
vma->vm_pgoff,
vma->vm_end-vma->vm_start,
vma->vm_page_prot) < 0)
{
return -EAGAIN;
}
return 0;
}
MODULE_AUTHOR ("mr yang");
MODULE_DESCRIPTION ("mem_dump" );
MODULE_LICENSE ("GPL");
module_init(osp_mem_init);
module_exit(osp_mem_exit);
/******************************* 源文件结束 ***********************************/

View File

@ -1,25 +0,0 @@
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
#KERNELDIR = /public/liweihua/workspace/linux-5.0.21
KERNELDIR = /public/liweihua/workspace/linux-5.10.165
OBJ = ARM_STC
PWD = $(shell pwd)
# Kernel modules
ifeq ($(OBJ),ARM_STC)
obj-m = stc.o
#mycache-objs = osp_sm_ddr.o cache.o
stc-y := stc-dev.o
endif
# Specify flags for the module compilation.
ccflags-y = -g -O2
#INCLUDE += -l./../../common/
build: kernel_modules
kernel_modules:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean

View File

@ -1,357 +0,0 @@
/*
* Driver for stc module.
*
* Copyright (C) 2022, liweihua@smartlogictech.com
* Copyright 2022
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include "stc_def.h"
#define UCP4008_STC_MODULE_VERSION ("V1.0")
#define UCP4008_STC_DEVICE_NAME "stc_irq"
struct stc_driver g_stc_drv;
static irqreturn_t stc_tod_1pps_handler(int irqid, void *param)
{
struct stc_driver *pirqstc = param;
__raw_writel(0x1,pirqstc->io_base_addr + 4); //clear int
pirqstc->irq_1pps_tod_cnt++;
pirqstc->cond_1pps_tod = STC_TOD_1PPS;
//printk("enter:%s,complete_cond = %d,\n",__func__,pirqstc->complete_cond);
wake_up_interruptible(&pirqstc->pp1s_tod_queue);
return IRQ_HANDLED;
}
static irqreturn_t stc_1pps_in_handler(int irqid, void *param)
{
struct stc_driver *pirqstc = param;
__raw_writel(0x2,pirqstc->io_base_addr + 4); //clear int
pirqstc->irq_1pps_in_cnt++;
pirqstc->cond_1pps_in = STC_EX_1PPS_IN;
//printk("enter:%s,complete_cond = %d,\n",__func__,pirqstc->complete_cond);
wake_up_interruptible(&pirqstc->pp1s_in_queue);
return IRQ_HANDLED;
}
static irqreturn_t stc_hscc_dump_handler(int irqid, void *param)
{
struct stc_driver *pirqstc = param;
__raw_writel(0x4,pirqstc->io_base_addr + 4); //clear int
pirqstc->irq_hscc_dump_cnt++;
pirqstc->cond_hscc_dump = STC_HSCC_DUMP;
//printk("enter:%s,complete_cond = %d,\n",__func__,pirqstc->complete_cond);
wake_up_interruptible(&pirqstc->hscc_dump_queue);
return IRQ_HANDLED;
}
static int stc_open(struct inode* inode, struct file* file)
{
printk(KERN_INFO "[%s]\n", __func__);
return 0;
}
static ssize_t stc_read(struct file* file, char __user* buf, size_t size, loff_t* pos)
{
sint32 ret;
uint32 cond_value;
if(STC_TOD_1PPS == size)
{
ret = wait_event_interruptible(g_stc_drv.pp1s_tod_queue, g_stc_drv.cond_1pps_tod);
cond_value = g_stc_drv.irq_1pps_tod_cnt;
g_stc_drv.cond_1pps_tod = STC_INT_RESERVED;
}
else if(STC_EX_1PPS_IN == size)
{
ret = wait_event_interruptible(g_stc_drv.pp1s_in_queue, g_stc_drv.cond_1pps_in);
cond_value = g_stc_drv.irq_1pps_in_cnt;
g_stc_drv.cond_1pps_in = STC_INT_RESERVED;
}
else if(STC_HSCC_DUMP == size)
{
ret = wait_event_interruptible(g_stc_drv.hscc_dump_queue, g_stc_drv.cond_hscc_dump);
cond_value = g_stc_drv.irq_hscc_dump_cnt;
g_stc_drv.cond_hscc_dump = STC_INT_RESERVED;
}
else
{
return FAILURE;
}
if(ret != 0)
{
printk("exe:%s error!\n",__func__);
return FAILURE;
}
ret = copy_to_user(buf, &cond_value, sizeof(uint32));
return ret;
}
static ssize_t stc_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
return 0;
}
static sint64 stc_ioctl(struct file* file, unsigned int cmd, unsigned long arg)
{
sint32 s32Ret = SUCCESS;
stc_int_type_e int_type;
struct stc_driver *stc_drv = &g_stc_drv;
uint32 irq_enable = __raw_readl(g_stc_drv.io_base_addr + 8);
printk("enter:%s\n",__func__);
switch(cmd)
{
case STC_INT_CFG:
{
s32Ret = copy_from_user(&int_type, (void __user*)arg, sizeof(stc_int_type_e));
if(s32Ret != 0)
{
printk(KERN_INFO "[%s]Copy user data failed!\n", __func__);
return FAILURE;
}
switch(int_type)
{
case STC_TOD_1PPS:
{
s32Ret = request_irq(stc_drv->irq_1pps_tod, stc_tod_1pps_handler, IRQF_SHARED, "tod_1pps", (void *)stc_drv);
if(s32Ret != SUCCESS)
{
free_irq(stc_drv->irq_1pps_tod, stc_drv);
printk(KERN_INFO "[%s]irq_ipps_tod request error!\n", __func__);
return FAILURE;
}
irq_enable |= 1;
__raw_writel(irq_enable,g_stc_drv.io_base_addr + 8); //
break;
}
case STC_EX_1PPS_IN:
{
s32Ret = request_irq(stc_drv->irq_1pps_in, stc_1pps_in_handler, IRQF_SHARED, "1pps_in", (void *)stc_drv);
if(s32Ret != SUCCESS)
{
free_irq(stc_drv->irq_1pps_in, stc_drv);
printk(KERN_INFO "[%s]irq_ipps_in request error!\n", __func__);
return FAILURE;
}
printk(KERN_INFO "[%s]enable irq_ipps_in int!\n", __func__);
irq_enable |= 2;
__raw_writel(irq_enable,g_stc_drv.io_base_addr + 8); //
break;
}
case STC_HSCC_DUMP:
{
s32Ret = request_irq(stc_drv->irq_hscc_dump, stc_hscc_dump_handler, IRQF_SHARED,"hscc_dump" ,(void *)stc_drv);
if(s32Ret != SUCCESS)
{
free_irq(stc_drv->irq_hscc_dump, stc_drv);
printk(KERN_INFO "[%s]irq_hscc_dump request error!\n", __func__);
return FAILURE;
}
irq_enable |= 4;
__raw_writel(irq_enable,g_stc_drv.io_base_addr + 8); //
break;
}
default:break;
}
break;
}
default:
{
s32Ret = FAILURE;
break;
}
}
return s32Ret;
}
static int stc_release(struct inode* inode, struct file* file)
{
printk(KERN_INFO "[%s]realease \n", __func__);
return 0;
}
static struct file_operations stc_fops = {
.owner = THIS_MODULE,
.open = stc_open,
.read = stc_read,
.write = stc_write,
.release = stc_release,
.unlocked_ioctl = stc_ioctl,
};
static struct miscdevice g_stc_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "stc_dev",
.fops = &stc_fops,
};
#if 0
static int stc_module_init(void)
{
sint32 iRet;
uint32 u32idx;
iRet = misc_register(&g_stc_dev);
if(iRet != SUCCESS)
{
printk("misc_register error! iRet = %d\n", iRet);
return -1;
}
memset(&g_stc_drv, 0, sizeof(struct stc_driver));
g_stc_drv.irq_ipps_in = UCP4008_IRQ_1PPS_IN;
g_stc_drv.irq_hscc_dump = UCP4008_IRQ_HSCC_DUMP;
g_stc_drv.irq_ipps_tod = UCP4008_IRQ_1PPS_TOD;
g_stc_drv.irq_ipps_in_cnt = 0;
g_stc_drv.irq_hscc_dump_cnt = 0;
g_stc_drv.irq_ipps_tod_cnt = 0;
init_waitqueue_head(&g_stc_drv.complete_queue);
g_stc_drv.complete_cond = STC_INT_RESERVED;
g_stc_drv.io_base_addr = ioremap(STC_REG_BASE_ADDR,STC_REG_LEN);
//init timer
#if 0
init_timer(&g_stc_drv.avcn_timer_list);
setup_timer(&g_stc_drv.avcn_timer_list, avcn_debounce_timer, GPIO_INT_FUNC_RESET);
#else
//timer_setup(&g_stc_drv.avcn_timer_list, avcn_debounce_timer, 0);
#endif
printk(KERN_INFO "[%s] module version %s init...\n", __func__, UCP4008_STC_MODULE_VERSION);
return 0;
}
static void stc_module_exit(void)
{
misc_deregister(&g_stc_dev);
free_irq(g_stc_drv.irq_ipps_in , &g_stc_drv);
free_irq(g_stc_drv.irq_ipps_tod , &g_stc_drv);
free_irq(g_stc_drv.irq_hscc_dump , &g_stc_drv);
printk(KERN_INFO "[%s] module version %s exit...\n", __func__, UCP4008_STC_MODULE_VERSION);
}
#endif
static int smartlogic_stc_probe(struct platform_device *pdev)
{
struct resource *res_common;
struct device *dev = &pdev->dev;
int i, irq, iRet;
int irq_no[3];
printk("enter:%s\n",__func__);
iRet = misc_register(&g_stc_dev);
if(iRet != SUCCESS)
{
printk("misc_register error! iRet = %d\n", iRet);
return -1;
}
for (i = 0; i < 3; ++i)
{
irq = platform_get_irq(pdev, i);
if (irq < 0) {
dev_err(dev, "failed to get irq index %d\n", i);
return -ENODEV;
}
irq_no[i] = irq;
}
g_stc_drv.irq_1pps_tod = irq_no[0];
g_stc_drv.irq_1pps_in = irq_no[1];
g_stc_drv.irq_hscc_dump = irq_no[2];
res_common = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res_common)
{
dev_err(&pdev->dev, "memory resource not found");
return -EINVAL;
}
g_stc_drv.io_base_addr = devm_ioremap_resource(dev, res_common);
if (IS_ERR(g_stc_drv.io_base_addr))
{
return PTR_ERR(g_stc_drv.io_base_addr);
}
init_waitqueue_head(&g_stc_drv.pp1s_tod_queue);
init_waitqueue_head(&g_stc_drv.pp1s_in_queue);
init_waitqueue_head(&g_stc_drv.hscc_dump_queue);
g_stc_drv.cond_1pps_tod = STC_INT_RESERVED;
g_stc_drv.cond_1pps_in = STC_INT_RESERVED;
g_stc_drv.cond_hscc_dump = STC_INT_RESERVED;
g_stc_drv.irq_1pps_tod_cnt = 0;
g_stc_drv.irq_1pps_in_cnt = 0;
g_stc_drv.irq_hscc_dump_cnt = 0;
return 0;
}
static int smartlogic_stc_remove(struct platform_device *pdev)
{
misc_deregister(&g_stc_dev);
free_irq(g_stc_drv.irq_1pps_in , &g_stc_drv);
free_irq(g_stc_drv.irq_1pps_tod , &g_stc_drv);
free_irq(g_stc_drv.irq_hscc_dump , &g_stc_drv);
printk(KERN_INFO "[%s] module version %s exit...\n", __func__, UCP4008_STC_MODULE_VERSION);
return 0;
}
static const struct of_device_id smartlogic_stc_match[] = {
{ .compatible = "smartlogic,stc" },
{},
};
MODULE_DEVICE_TABLE(of, smartlogic_stc_match);
static struct platform_driver smartlogic_stc_driver = {
.driver = {
.name = "smartlogic_stc",
.of_match_table = smartlogic_stc_match,
},
.probe = smartlogic_stc_probe,
.remove = smartlogic_stc_remove,
};
module_platform_driver(smartlogic_stc_driver);
MODULE_AUTHOR("liweihua@smartlogictech.com");
MODULE_DESCRIPTION ("Smartlogictech STC module driver!");
MODULE_LICENSE ("GPL");

View File

@ -1,69 +0,0 @@
#ifndef _STC_DEF_H_
#define _STC_DEF_H_
#include <linux/module.h>
#include <linux/kernel.h> /*声明printk()这个内核态的函数*/
#include <linux/fs.h> /*文件系统有关的结构体file_operations也在fs头文件定义*/
#include <linux/init.h> /*init和exit相关宏*/
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h> /*linux中断定义*/
#include <asm/irq.h>
#include <linux/interrupt.h> /*包含与中断相关的大部分宏及结构体的定义request_irq()等*/
#include <asm/uaccess.h> /*linux中的用户态内存交互函数copy_from_user(),copy_to_user()等*/
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h> /*misc混合设备注册与注销*/
#include <asm/io.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
typedef char sint8;
typedef unsigned char uint8;
typedef int sint32;
typedef unsigned int uint32;
typedef long sint64;
typedef unsigned long uint64;
#define SUCCESS (0)
#define FAILURE (-1)
#define IRQ_EXCEPTION (0xFFFFFF)
#define STC_MODULE_MAGIC 'g'
#define STC_INT_CFG _IOWR(STC_MODULE_MAGIC, 0x01, uint32)
#define STC_REG_BASE_ADDR (0x08568000ull) //STC鍩哄湴鍧€
#define STC_REG_LEN (0x08000)
typedef enum
{
STC_INT_RESERVED = 0, /* Reserved*/ /* Reserved*/
STC_TOD_1PPS, /* stc 1pps*/
STC_EX_1PPS_IN, /* external 1pps */
STC_HSCC_DUMP = 4 /* HSCC_DUMP */
} stc_int_type_e;
struct stc_driver{
sint32 irq_1pps_tod;
sint32 irq_1pps_in;
sint32 irq_hscc_dump;
uint32 irq_1pps_tod_cnt;
uint32 irq_1pps_in_cnt;
uint32 irq_hscc_dump_cnt;
stc_int_type_e cond_1pps_tod;
stc_int_type_e cond_1pps_in;
stc_int_type_e cond_hscc_dump;
wait_queue_head_t pp1s_tod_queue;
wait_queue_head_t pp1s_in_queue;
wait_queue_head_t hscc_dump_queue;
void __iomem *io_base_addr;
};
#endif

View File

@ -1,18 +0,0 @@
PWD := $(shell pwd)
#KERNELDIR := /public/liweihua/workspace/linux-5.0.21
KERNELDIR := /public/liweihua/workspace/linux-5.10.165
obj-m := tsc.o
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.order irq-test
.PHONY: modules modules_install clean

View File

@ -1,67 +0,0 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/smp.h>
#define ARMV8_PMCR_MASK 0x3f
#define ARMV8_PMCR_E (1 << 0)
#define ARMV8_PMCR_LC (1 << 6)
static inline u32 armv8pmu_pmcr_read(void)
{
u64 val = 0;
asm volatile("mrs %0, pmcr_el0" : "=r" (val));
return (u32)val;
}
static inline void armv8pmu_pmcr_write(u32 val)
{
val &= ARMV8_PMCR_MASK;
isb();
asm volatile("msr pmcr_el0, %0" : : "r" ((u64)val));
}
static inline long long armv8_read_CNTPCT_EL0(void)
{
long long val;
asm volatile("mrs %0, CNTVCT_EL0" : "=r" (val));
return val;
}
static void
enable_cpu_counters(void* data)
{
asm volatile("msr pmuserenr_el0, %0" : : "r"(0xf));
armv8pmu_pmcr_write(ARMV8_PMCR_LC|ARMV8_PMCR_E);
asm volatile("msr PMCNTENSET_EL0, %0" :: "r" ((u32)(1<<31)));
armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMCR_E|ARMV8_PMCR_LC);
printk("\nCPU:%d ", smp_processor_id());
}
static void
disable_cpu_counters(void* data)
{
printk(KERN_INFO "\ndisabling user-mode PMU access on CPU #%d",
smp_processor_id());
armv8pmu_pmcr_write(armv8pmu_pmcr_read() |~ARMV8_PMCR_E);
asm volatile("msr pmuserenr_el0, %0" : : "r"((u64)0));
}
static int __init init(void)
{
on_each_cpu(enable_cpu_counters, NULL, 1);
printk(KERN_INFO "Enable Access PMU Initialized");
return 0;
}
static void __exit fini(void)
{
on_each_cpu(disable_cpu_counters, NULL, 1);
printk(KERN_INFO "Access PMU Disabled");
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("titan");

View File

@ -1,12 +0,0 @@
KERN_DIR = /public/liweihua/workspace/linux-5.0.21
all:
make -C ${KERN_DIR} M=`pwd` modules
clean:
make -C ${KERN_DIR} M=`pwd` modules clean
rm -rf modules.order
obj-m += ucp_2_revmem.o

View File

@ -1,3 +0,0 @@
export ARCH=arm64
export CROSS_COMPILE=/public/liweihua/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
make

View File

@ -1,325 +0,0 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/mod_devicetable.h>
#include <linux/of_address.h>
#include <asm/io.h>
#include <linux/async_tx.h>
#include <linux/dmaengine.h>
#include <linux/gfp.h>
#include <linux/dma-mapping.h>
#include "ucp_2_revmem.h"
/*暂时将ucp_mem的主设备号定义为10 */
typedef struct tag_OSP_CACHE_REV
{
unsigned int phy_addr;
unsigned int len;
}OSP_CACHE_REV;
struct ucp_2_rev_device{
struct device *dev;
struct miscdevice *miscdev;
void __iomem *vir_head;
unsigned int phy_head;
};
struct ucp_2_rev_device *ucp_2_rev_dev;
#define DEVICE_NAME "ucp_2_revmem"
//#define DEVICE_NAME "ucp_2_mmap"
#define IOCTL_CACHE_INVALID _IO('k',0x10)
#define IOCTL_CACHE_FLUSH _IO('k',0x20)
#define IOCTL_SET_CACHE _IO('k',0x30)
#define IOCTL_SET_NOCACHE _IO('k',0x40)
#define UP_ALIGNED(num, n) (((num) + (n) - 1) & (~((n) - 1)))
#define REV_WITH_CACHE 2
#define REV_WITH_NOCACHE 3
int is_cached=0;
extern void arch_sync_dma_for_device_p(struct device *dev, void *addr,
size_t size, enum dma_data_direction dir);
extern void arch_sync_dma_for_cpu_p(struct device *dev, void *addr,
size_t size, enum dma_data_direction dir);
/*file open function*/
int ucp_2_revmem_open(struct inode *inode, struct file *filp)
{
/* device structure pointer assgined to file private data pointer */
printk("enter %s !!!\n",__func__);
return 0;
}
ssize_t ucp_2_revmem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
/*file release function*/
int ucp_2_revmem_release(struct inode *inode, struct file *filp)
{
return 0;
}
/* ioctl device control function */
static long ucp_2_revmem_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
OSP_CACHE_REV operation;
void __iomem *vir;
struct ucp_2_rev_device *rev_dev = ucp_2_rev_dev;
struct miscdevice *miscdev = rev_dev->miscdev;
// printk("%s\n",miscdev->name);
switch(cmd)
{
case IOCTL_SET_CACHE:
is_cached = REV_WITH_CACHE;
// dev_info(rev_dev->dev,"ioctl set with cache");
break;
case IOCTL_SET_NOCACHE:
is_cached = REV_WITH_NOCACHE;
// dev_info(rev_dev->dev,"ioctl set no cache");
break;
case IOCTL_CACHE_FLUSH:
if(copy_from_user((void *)(&operation), (char *)arg, sizeof(OSP_CACHE_REV)))
{
dev_info(rev_dev->dev,"ioctl copy_from_user error");
return - EINVAL;
}
if(operation.phy_addr<=0 || operation.len <=0)
{
dev_info(rev_dev->dev,"ioctl user arg error");
return - EINVAL;
}
operation.len = UP_ALIGNED(operation.len,4);
// vir = ioremap_cache(operation.phy_addr,operation.len);
vir = rev_dev->vir_head + (operation.phy_addr - rev_dev->phy_head);
if(vir == NULL)
{
dev_info(rev_dev->dev,"ioctl vir error");
return - EINVAL;
}
arch_sync_dma_for_device_p(rev_dev->dev, vir, operation.len, DMA_TO_DEVICE);
break;
case IOCTL_CACHE_INVALID:
if(copy_from_user((void *)(&operation), (char *)arg, sizeof(OSP_CACHE_REV)))
{
dev_info(rev_dev->dev,"ioctl copy_from_user error");
return - EINVAL;
}
if(operation.phy_addr<=0 || operation.len <=0)
{
dev_info(rev_dev->dev,"ioctl user arg error");
return - EINVAL;
}
operation.len = UP_ALIGNED(operation.len,4);
// vir = ioremap_cache(operation.phy_addr,operation.len);
vir = rev_dev->vir_head + (operation.phy_addr - rev_dev->phy_head);
if(vir == NULL)
{
dev_info(rev_dev->dev,"ioctl vir error");
return - EINVAL;
}
arch_sync_dma_for_cpu_p(rev_dev->dev, vir, operation.len, DMA_FROM_DEVICE);
break;
default:
return - EINVAL;
}
// iounmap(vir);
return 0;
}
static int ucp_2_revmem_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct ucp_2_rev_device *rev_dev = ucp_2_rev_dev;
struct miscdevice *miscdev = rev_dev->miscdev;
uint64_t offset = vma->vm_pgoff << PAGE_SHIFT;
printk("enter %s !!!\n",__func__);
printk("ucp_revmem_mmap offset = %#llx,start = %#llx\n",offset,vma->vm_start);
vma->vm_flags |= VM_IO | VM_LOCKED;
if(offset < ARM_STACK_BASE_PHY_ADDR)
{
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
}
#if 0
if(is_cached == REV_WITH_NOCACHE)
{
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
}
else if(is_cached == REV_WITH_CACHE)
{
}
else
{
dev_info(rev_dev->dev,"flag is_cached is error %d\n",is_cached);
return -EAGAIN;
}
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
#endif
if (remap_pfn_range(vma,
vma->vm_start,
vma->vm_pgoff,
vma->vm_end-vma->vm_start,
vma->vm_page_prot) < 0)
{
return -EAGAIN;
}
// dev_info(rev_dev->dev,"ucp_revmem_mmap:%d ok\n",is_cached);
printk("leave %s !!!\n",__func__);
is_cached = 0;
return 0;
}
/*file operation structure*/
static const struct file_operations ucp_2_revmem_fops =
{
.owner = THIS_MODULE,
.open = ucp_2_revmem_open,
.unlocked_ioctl = ucp_2_revmem_ioctl,
.mmap = ucp_2_revmem_mmap,
.release = ucp_2_revmem_release,
};
static ssize_t ucp_2_revmem_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int len=0;
len += sprintf(buf+len, "%s\r\n", "ucp_2_mem attribute OK!");
return len;
}
static DEVICE_ATTR(ucp_2_revmem, S_IRUGO, ucp_2_revmem_show, NULL);
static struct miscdevice ucp_2_revmem_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &ucp_2_revmem_fops,
};
static int __init ucp_2_revmem_module_init(void)
{
int ret;
struct miscdevice *misc_device;
void __iomem * vir_addr;
dma_addr_t phy_addr;
int i;
ucp_2_rev_dev = (struct ucp_2_rev_device *)kzalloc(sizeof(*ucp_2_rev_dev), GFP_KERNEL);
if (!ucp_2_rev_dev)
return -ENOMEM;
misc_device = &ucp_2_revmem_miscdev;
ret = misc_register(&ucp_2_revmem_miscdev);
if(ret)
{
goto misc_err;
}
ret = device_create_file(ucp_2_revmem_miscdev.this_device, &dev_attr_ucp_2_revmem);
if (ret)
{
goto attr_err;
}
ucp_2_rev_dev->dev = ucp_2_revmem_miscdev.this_device;
ucp_2_rev_dev->miscdev = &ucp_2_revmem_miscdev;
dev_set_drvdata(ucp_2_revmem_miscdev.this_device, ucp_2_rev_dev);
ucp_2_rev_dev->phy_head = UCP_2_APE_REV_MEM_START;
ucp_2_rev_dev->vir_head = ioremap_cache(UCP_2_APE_REV_MEM_START,UCP_2_APE_REM_MEM_LEN);
dma_coerce_mask_and_coherent(ucp_2_rev_dev->dev, DMA_BIT_MASK(32));
/*
for(i = 0; i< 100; i++)
{ //GFP_ATOMIC,GFP_KERNEL
vir_addr = dma_alloc_coherent(ucp_2_rev_dev->dev, 0x64000, (dma_addr_t *)&phy_addr, GFP_ATOMIC);
if(vir_addr == NULL)
{
printk("revmem dma_alloc_coherent error:%d\n",i);
}
}
*/
dev_info(ucp_2_rev_dev->dev,"ucp_2_revem_module_init ok\n");
return 0;
misc_err:
device_remove_file(ucp_2_revmem_miscdev.this_device, &dev_attr_ucp_2_revmem);
attr_err:
misc_deregister(&ucp_2_revmem_miscdev);
return -1;
}
/* module unload function*/
static void __exit ucp_2_revmem_module_exit(void)
{
device_remove_file(ucp_2_revmem_miscdev.this_device, &dev_attr_ucp_2_revmem);
misc_deregister(&ucp_2_revmem_miscdev);
}
/*
* a simple char device driver: ExtInt without mutex
*
* Copyright (C) 2014 Barry Song (baohua@kernel.org)
*
* Licensed under GPLv2 or later.
*/
MODULE_AUTHOR ("lte team");
MODULE_DESCRIPTION ("ucp_mem driver module" );
MODULE_LICENSE ("GPL");
module_init(ucp_2_revmem_module_init);
module_exit(ucp_2_revmem_module_exit);

View File

@ -1,24 +0,0 @@
#ifndef __HPP_REVMEM_H__
#define __HPP_REVMEM_H__
#define UCP_2_APE_REV_MEM_START 0x90000000
#define UCP_2_APE_REV_MEM_BLOCK_SIZE 0x100000
#define UCP_2_APE_REV_MEM_BLOCK_NUM 18
/*#define HPP_APE_REM_MEM_LEN (HPP_APE_REV_MEM_BLOCK_NUM * HPP_APE_REV_MEM_BLOCK_SIZE)*/
#define UCP_2_APE_REM_MEM_LEN 0x20000000
#define SHARE_MEM_BASE_PHY_ADDR 0x009D00000UL
#define LEN_OF_SHARE_MEM 0x000800000UL
#define SHARE_MEM_END_PHY_ADDR (SHARE_MEM_BASE_PHY_ADDR + LEN_OF_SHARE_MEM)
#define ARM_STACK_BASE_PHY_ADDR 0x0B8000000UL
//
#endif