Initial commit
This commit is contained in:
commit
04e0949162
|
@ -0,0 +1,22 @@
|
|||
ifndef KERNEL
|
||||
KERNEL = /lib/modules/$(shell uname -r)/build
|
||||
endif
|
||||
EXTRA_CFLAGS := -Wall -Wstrict-prototypes -O2 -fno-strict-aliasing
|
||||
obj-m += amifldrv_mod.o
|
||||
amifldrv_mod-objs := amifldrv.o amiwrap.o
|
||||
default:
|
||||
make -C $(KERNEL) SUBDIRS=$(PWD) modules
|
||||
rm -f amifldrv.o_shipped
|
||||
mv amifldrv.o amifldrv.o_shipped
|
||||
rm -f amifldrv_mod.o
|
||||
mv amifldrv_mod.ko ../amifldrv_mod
|
||||
.PHONY : clean
|
||||
clean:
|
||||
rm -f *.*~
|
||||
rm -f test
|
||||
rm -f .*cmd
|
||||
rm -f *.o
|
||||
rm -f *mod*
|
||||
rm -f *.ko
|
||||
rm -f amifldrv.o_shipped
|
||||
rm -rf .tmp_versions/
|
|
@ -0,0 +1,191 @@
|
|||
#include <linux/mm.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include "amifldrv.h"
|
||||
#include "amiwrap.h"
|
||||
int amifldrv_ioctl(void);
|
||||
int amifldrv_mmap(void);
|
||||
static int *kmalloc_area = NULL;
|
||||
static int *kmalloc_ptr = NULL;
|
||||
static unsigned long kmalloc_len = 0L;
|
||||
static int major;
|
||||
static AMIFLDRV_ALLOC kmalloc_drv[128];
|
||||
static int kcount = 0;
|
||||
static int amifldrv_init_module(void)
|
||||
{
|
||||
ulArg0 = 0;
|
||||
pvArg0 = &amifldrv_fops;
|
||||
if ((major=wrap_register_chrdev()) < 0) {
|
||||
return (-EIO);
|
||||
}
|
||||
memset(kmalloc_drv, 0, sizeof(AMIFLDRV_ALLOC) * 128);
|
||||
return(0);
|
||||
}
|
||||
static void amifldrv_cleanup_module(void)
|
||||
{
|
||||
unsigned long virt_addr;
|
||||
int iloop = 0;
|
||||
if (kcount > 0) {
|
||||
for (iloop=0; iloop<kcount; iloop++) {
|
||||
kmalloc_ptr = kmalloc_drv[iloop].kmallocptr;
|
||||
kmalloc_area = kmalloc_drv[iloop].kvirtadd;
|
||||
kmalloc_len = kmalloc_drv[iloop].kvirtlen;
|
||||
if (kmalloc_ptr) {
|
||||
for(virt_addr=(unsigned long)kmalloc_area; virt_addr<(unsigned long)kmalloc_area+kmalloc_len; virt_addr+=PAGE_SIZE) {
|
||||
ulArg0 = virt_addr;
|
||||
pvArg0 = wrap_virt_to_page();
|
||||
wrap_mem_map_unreserve();
|
||||
}
|
||||
if (kmalloc_ptr) {
|
||||
pvArg0 = kmalloc_ptr;
|
||||
wrap_kfree();
|
||||
}
|
||||
}
|
||||
}
|
||||
kcount = 0;
|
||||
}
|
||||
ulArg0 = major;
|
||||
wrap_unregister_chrdev();
|
||||
return;
|
||||
}
|
||||
module_init(amifldrv_init_module);
|
||||
module_exit(amifldrv_cleanup_module);
|
||||
int amifldrv_ioctl(void)
|
||||
{
|
||||
unsigned int cmd = (unsigned int)ulArg0;
|
||||
unsigned long arg = ulArg1;
|
||||
switch(cmd)
|
||||
{
|
||||
case CMD_ALLOC:
|
||||
{
|
||||
int i;
|
||||
unsigned long virt_addr;
|
||||
AMIFLDRV_ALLOC arg_kernel_space;
|
||||
if (kcount >= 128) return -EINVAL;
|
||||
kmalloc_ptr = NULL;
|
||||
if (!arg || kmalloc_ptr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
pvArg0 = (void*)&arg_kernel_space;
|
||||
pvArg1 = (void*)arg;
|
||||
ulArg0 = sizeof(AMIFLDRV_ALLOC);
|
||||
wrap_copy_from_user();
|
||||
if (arg_kernel_space.size > 128*1024) return -EINVAL;
|
||||
kmalloc_len = ((arg_kernel_space.size + PAGE_SIZE -1) & PAGE_MASK);
|
||||
ulArg0 = kmalloc_len+2*PAGE_SIZE;
|
||||
ulArg1 = GFP_DMA|GFP_KERNEL;
|
||||
kmalloc_ptr = wrap_kmalloc();
|
||||
kmalloc_area=(int *)(((unsigned long)kmalloc_ptr + PAGE_SIZE -1) & PAGE_MASK);
|
||||
for (virt_addr=(unsigned long)kmalloc_area; virt_addr<(unsigned long)kmalloc_area+kmalloc_len; virt_addr+=PAGE_SIZE)
|
||||
{
|
||||
ulArg0 = virt_addr;
|
||||
pvArg0 = wrap_virt_to_page();
|
||||
wrap_mem_map_reserve();
|
||||
}
|
||||
for (i=0; i<(kmalloc_len/sizeof(int)); i++) {
|
||||
kmalloc_area[i]=(0xafd0<<16) +i;
|
||||
}
|
||||
kmalloc_drv[kcount].size = arg_kernel_space.size;
|
||||
kmalloc_drv[kcount].kmallocptr = kmalloc_ptr;
|
||||
kmalloc_drv[kcount].kvirtlen = kmalloc_len;
|
||||
kmalloc_drv[kcount].kvirtadd = kmalloc_area;
|
||||
kmalloc_drv[kcount].kphysadd = (void *)((unsigned long)virt_to_phys(kmalloc_area));
|
||||
kcount++;
|
||||
arg_kernel_space.kvirtadd = kmalloc_area;
|
||||
arg_kernel_space.kphysadd = (void *)((unsigned long)virt_to_phys(kmalloc_area));
|
||||
pvArg0 = (void*)arg;
|
||||
pvArg1 = (void*)&arg_kernel_space;
|
||||
ulArg0 = sizeof(AMIFLDRV_ALLOC);
|
||||
wrap_copy_to_user();
|
||||
return 0;
|
||||
}
|
||||
case CMD_FREE:
|
||||
{
|
||||
unsigned long virt_addr;
|
||||
AMIFLDRV_ALLOC arg_kernel_space;
|
||||
int isearch = 0;
|
||||
pvArg0 = (void*)&arg_kernel_space;
|
||||
pvArg1 = (void*)arg;
|
||||
ulArg0 = sizeof(AMIFLDRV_ALLOC);
|
||||
wrap_copy_from_user();
|
||||
if (kcount > 0) {
|
||||
for (isearch=0; isearch<kcount; isearch++) {
|
||||
if (kmalloc_drv[isearch].kphysadd == arg_kernel_space.kphysadd) break;
|
||||
}
|
||||
if (isearch >= kcount) return 0;
|
||||
kmalloc_ptr = kmalloc_drv[isearch].kmallocptr;
|
||||
kmalloc_area = kmalloc_drv[isearch].kvirtadd;
|
||||
kmalloc_len = kmalloc_drv[isearch].kvirtlen;
|
||||
} else
|
||||
return 0;
|
||||
if (kmalloc_ptr) {
|
||||
for(virt_addr=(unsigned long)kmalloc_area; virt_addr<(unsigned long)kmalloc_area+kmalloc_len; virt_addr+=PAGE_SIZE)
|
||||
{
|
||||
ulArg0 = virt_addr;
|
||||
pvArg0 = wrap_virt_to_page();
|
||||
wrap_mem_map_unreserve();
|
||||
}
|
||||
if (kmalloc_ptr) {
|
||||
pvArg0 = kmalloc_ptr;
|
||||
wrap_kfree();
|
||||
}
|
||||
kmalloc_len = 0L;
|
||||
kmalloc_ptr = NULL;
|
||||
kmalloc_area = NULL;
|
||||
kcount--;
|
||||
if (isearch != kcount) {
|
||||
kmalloc_drv[isearch].size = kmalloc_drv[kcount].size;
|
||||
kmalloc_drv[isearch].kmallocptr = kmalloc_drv[kcount].kmallocptr;
|
||||
kmalloc_drv[isearch].kvirtlen = kmalloc_drv[kcount].kvirtlen;
|
||||
kmalloc_drv[isearch].kvirtadd = kmalloc_drv[kcount].kvirtadd;
|
||||
kmalloc_drv[isearch].kphysadd = kmalloc_drv[kcount].kphysadd;
|
||||
}
|
||||
kmalloc_drv[kcount].size = 0;
|
||||
kmalloc_drv[kcount].kmallocptr = NULL;
|
||||
kmalloc_drv[kcount].kvirtlen = 0;
|
||||
kmalloc_drv[kcount].kvirtadd = NULL;
|
||||
kmalloc_drv[kcount].kphysadd = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case CMD_LOCK_KB:
|
||||
disable_irq(1);
|
||||
return 0;
|
||||
case CMD_UNLOCK_KB:
|
||||
enable_irq(1);
|
||||
return 0;
|
||||
}
|
||||
return -ENOTTY;
|
||||
}
|
||||
int amifldrv_mmap(void)
|
||||
{
|
||||
struct vm_area_struct *vma = (struct vm_area_struct *)pvArg1;
|
||||
unsigned long offset = vma->vm_pgoff<<PAGE_SHIFT;
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
if (offset & ~PAGE_MASK) {
|
||||
return -ENXIO;
|
||||
}
|
||||
if (!kmalloc_ptr) {
|
||||
return(-ENXIO);
|
||||
}
|
||||
if (size>kmalloc_len) {
|
||||
return(-ENXIO);
|
||||
}
|
||||
if ((offset+size)>kmalloc_len) {
|
||||
return -ENXIO;
|
||||
}
|
||||
if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
|
||||
return(-EINVAL);
|
||||
}
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
pvArg0 = vma;
|
||||
ulArg0 = vma->vm_start;
|
||||
ulArg1 = virt_to_phys((void*)((unsigned long)kmalloc_area));
|
||||
ulArg2 = size;
|
||||
pgArg0 = PAGE_SHARED;
|
||||
if (wrap_remap_page_range()) {
|
||||
return -ENXIO;
|
||||
}
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
extern struct file_operations amifldrv_fops;
|
||||
#define CMD_ALLOC 0x4160
|
||||
#define CMD_FREE 0x4161
|
||||
#define CMD_LOCK_KB 0x4162
|
||||
#define CMD_UNLOCK_KB 0x4163
|
||||
typedef struct tagAMIFLDRV_ALLOC
|
||||
{
|
||||
long size;
|
||||
unsigned long kvirtlen;
|
||||
void * kmallocptr;
|
||||
void * kvirtadd;
|
||||
void * kphysadd;
|
||||
} AMIFLDRV_ALLOC;
|
|
@ -0,0 +1,191 @@
|
|||
//-------------------------------------------------------------------------------------------------
|
||||
// AMI Firmware Update Utility(APTIO) v5.05.04
|
||||
// Copyright (C)2011 American Megatrends Inc. All Rights Reserved.
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
||||
#include <linux/wrapper.h>
|
||||
#endif
|
||||
#include "amiwrap.h"
|
||||
|
||||
extern int amifldrv_ioctl(void);
|
||||
extern int amifldrv_mmap(void);
|
||||
unsigned long ulArg0;
|
||||
unsigned long ulArg1;
|
||||
unsigned long ulArg2;
|
||||
pgprot_t pgArg0;
|
||||
void *pvArg0;
|
||||
void *pvArg1;
|
||||
|
||||
AFU_ATTRIBUTE_FUNC static int wrap_open(struct inode *inode, struct file *file);
|
||||
AFU_ATTRIBUTE_FUNC static int wrap_release(struct inode *inode, struct file *file);
|
||||
#if defined(HAVE_UNLOCKED_IOCTL)
|
||||
AFU_ATTRIBUTE_FUNC static long wrap_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
|
||||
#else
|
||||
AFU_ATTRIBUTE_FUNC static int wrap_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
|
||||
#endif
|
||||
AFU_ATTRIBUTE_FUNC static int wrap_mmap(struct file *file, struct vm_area_struct *vma);
|
||||
|
||||
struct file_operations amifldrv_fops =
|
||||
{
|
||||
owner:
|
||||
THIS_MODULE,
|
||||
open:
|
||||
wrap_open,
|
||||
release:
|
||||
wrap_release,
|
||||
#if defined(HAVE_UNLOCKED_IOCTL)
|
||||
unlocked_ioctl:
|
||||
wrap_unlocked_ioctl,
|
||||
#else
|
||||
ioctl:
|
||||
wrap_ioctl,
|
||||
#endif
|
||||
mmap:
|
||||
wrap_mmap,
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags))
|
||||
#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags))
|
||||
MODULE_AUTHOR("American Megatrends Inc.");
|
||||
MODULE_DESCRIPTION("AMI Flash Update utility driver");
|
||||
MODULE_LICENSE("Proprietary");
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
static int device_open_count = 0;
|
||||
#endif
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
int wrap_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
||||
MOD_INC_USE_COUNT;
|
||||
#else
|
||||
if (device_open_count)
|
||||
return -EBUSY;
|
||||
device_open_count++;
|
||||
try_module_get(THIS_MODULE);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
int wrap_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
||||
MOD_DEC_USE_COUNT;
|
||||
#else
|
||||
device_open_count--;
|
||||
module_put(THIS_MODULE);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
#if defined(HAVE_UNLOCKED_IOCTL)
|
||||
long wrap_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
#else
|
||||
int wrap_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
#endif
|
||||
{
|
||||
#ifndef HAVE_UNLOCKED_IOCTL
|
||||
pvArg0 = inode;
|
||||
#endif
|
||||
pvArg1 = filp;
|
||||
ulArg0 = cmd;
|
||||
ulArg1 = arg;
|
||||
#if defined(HAVE_UNLOCKED_IOCTL)
|
||||
return (long)amifldrv_ioctl();
|
||||
#else
|
||||
return amifldrv_ioctl();
|
||||
#endif
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
int wrap_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
pvArg0 = file;
|
||||
pvArg1 = vma;
|
||||
return amifldrv_mmap();
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
int wrap_register_chrdev()
|
||||
{
|
||||
return register_chrdev((unsigned int)ulArg0, "amifldrv", (struct file_operations *)pvArg0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
void wrap_unregister_chrdev()
|
||||
{
|
||||
unregister_chrdev((unsigned int)ulArg0, "amifldrv");
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
void wrap_mem_map_reserve()
|
||||
{
|
||||
mem_map_reserve((struct page*)pvArg0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
void wrap_mem_map_unreserve()
|
||||
{
|
||||
mem_map_unreserve((struct page*)pvArg0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
struct page *wrap_virt_to_page()
|
||||
{
|
||||
return virt_to_page(ulArg0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
int wrap_remap_page_range()
|
||||
{
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
|
||||
ulArg1 = ulArg1>>PAGE_SHIFT;
|
||||
return remap_pfn_range((struct vm_area_struct *)pvArg0, ulArg0, ulArg1, ulArg2, pgArg0);
|
||||
#else
|
||||
return remap_page_range((struct vm_area_struct *)pvArg0, ulArg0, ulArg1, ulArg2, pgArg0);
|
||||
#endif
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
void *wrap_kmalloc()
|
||||
{
|
||||
return kmalloc((size_t)ulArg0, (int)ulArg1);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
void wrap_kfree()
|
||||
{
|
||||
kfree(pvArg0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
unsigned long wrap_copy_from_user()
|
||||
{
|
||||
return copy_from_user(pvArg0, pvArg1, ulArg0);
|
||||
}
|
||||
|
||||
AFU_ATTRIBUTE_FUNC
|
||||
unsigned long wrap_copy_to_user()
|
||||
{
|
||||
return copy_to_user(pvArg0, pvArg1, ulArg0);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//-------------------------------------------------------------------------------------------------
|
||||
// AMI Firmware Update Utility(APTIO) v5.05.04
|
||||
// Copyright (C)2011 American Megatrends Inc. All Rights Reserved.
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
#define AFU_ATTRIBUTE_FUNC
|
||||
AFU_ATTRIBUTE_FUNC int wrap_register_chrdev(void);
|
||||
AFU_ATTRIBUTE_FUNC void wrap_unregister_chrdev(void);
|
||||
AFU_ATTRIBUTE_FUNC void wrap_mem_map_reserve(void);
|
||||
AFU_ATTRIBUTE_FUNC void wrap_mem_map_unreserve(void);
|
||||
AFU_ATTRIBUTE_FUNC int wrap_remap_page_range(void);
|
||||
AFU_ATTRIBUTE_FUNC struct page *wrap_virt_to_page(void);
|
||||
AFU_ATTRIBUTE_FUNC void *wrap_kmalloc(void);
|
||||
AFU_ATTRIBUTE_FUNC void wrap_kfree(void);
|
||||
AFU_ATTRIBUTE_FUNC unsigned long wrap_copy_from_user(void);
|
||||
AFU_ATTRIBUTE_FUNC unsigned long wrap_copy_to_user(void);
|
||||
extern unsigned long ulArg0;
|
||||
extern unsigned long ulArg1;
|
||||
extern unsigned long ulArg2;
|
||||
extern pgprot_t pgArg0;
|
||||
extern void *pvArg0;
|
||||
extern void *pvArg1;
|
Loading…
Reference in New Issue