diff --git a/linux/mod_mcctrl/Makefile b/linux/mod_mcctrl/Makefile new file mode 100644 index 00000000..f82a87e0 --- /dev/null +++ b/linux/mod_mcctrl/Makefile @@ -0,0 +1,22 @@ +ifeq ($(K),"current") +KDIR=/lib/modules/`uname -r `/build +else +KDIR=../target +endif + +obj-m += mcctrl.o + +mcctrl-objs := driver.o control.o + +AAL_BASE=$(src)/../../../aal +EXTRA_CFLAGS = -I$(AAL_BASE)/host/include -I$(AAL_BASE)/ikc/include -I$(src)/../include + +.PHONY: clean install + +modules: + $(MAKE) -C $(KDIR) M=$(PWD) modules + +clean: + $(RM) .*.cmd *.mod.c *.o *.ko* Module.symvers modules.order -r .tmp* + +install: diff --git a/linux/mod_mcctrl/control.c b/linux/mod_mcctrl/control.c new file mode 100644 index 00000000..f9ffc74b --- /dev/null +++ b/linux/mod_mcctrl/control.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include "mcctrl.h" + +static struct aal_ikc_listen_param __listen_param = { + .port = 501, + .handler = test_handler, + .pkt_size = sizeof(struct ikc_test_packet), + .queue_size = 4096, + .magic = 0x29, +}; + +static long mcexec_prepare_image(struct mcctrl_priv *data, + struct program_load_desc * __user udesc) +{ + struct program_load_desc desc; + + if (!copy_from_user(&desc, udesc, + sizeof(struct program_load_desc))) { + return -EFAULT; + } + if (desc.num_sections <= 0 || desc.num_sections > 16) { + return -EINVAL; + } + data->desc = kmalloc(sizeof(struct program_load_desc) + + sizeof(struct program_image_section) + * desc.num_sections, GFP_KERNEL); + memcpy(data->desc, &desc, sizeof(struct program_load_desc)); + if (!copy_from_user(data->desc->sections, udesc->sections, + sizeof(struct program_image_section) + * desc.num_sections)) { + kfree(data->desc); + return -EFAULT; + } + + return 0; +} + +long __mcctrl_control(struct mcctrl_priv *data, unsigned int req, + unsigned long arg) +{ + switch (req) { + case MCEXEC_UP_PREPARE_IMAGE: + return mcexec_prepare_image((struct mcctrl_priv *)data, + (struct program_load_desc *)arg); + } + return -EINVAL; +} + diff --git a/linux/mod_mcctrl/driver.c b/linux/mod_mcctrl/driver.c new file mode 100644 index 00000000..010e1970 --- /dev/null +++ b/linux/mod_mcctrl/driver.c @@ -0,0 +1,73 @@ +/* + * + */ + +#include +#include +#include +#include +#include +#include "mcctrl.h" + +extern long __mcctrl_control(struct mcctrl_priv *, unsigned int, unsigned long); + +static int mcctrl_open(struct inode *inode, struct file *file) +{ + struct mcctrl_priv *mcc_data; + + mcc_data = kzalloc(sizeof(struct mcctrl_priv), GFP_KERNEL); + if (!mcc_data) { + return -ENOMEM; + } + + file->private_data = mcc_data; + return 0; +} + +static int mcctrl_release(struct inode *inode, struct file *file) +{ + struct mcctrl_priv *mcc_data = file->private_data; + + if (mcc_data) { + if (mcc_data->desc) { + kfree(mcc_data->desc); + } + kfree(mcc_data); + } + + return 0; +} + +static long mcctrl_ioctl(struct file *file, unsigned int request, + unsigned long arg) +{ + struct mcctrl_priv *mcc_data = file->private_data; + + return __mcctrl_control(mcc_data, request, arg); +} + +static struct file_operations mcctrl_ops = { + .open = mcctrl_open, + .unlocked_ioctl = mcctrl_ioctl, + .release = mcctrl_release, +}; + +static struct miscdevice mcctrl_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "mcctrl", + .fops = &mcctrl_ops, +}; + +static int __init mcctrl_init(void) +{ + return misc_register(&mcctrl_dev); +} + +static void __exit mcctrl_exit(void) +{ + misc_deregister(&mcctrl_dev); +} + +MODULE_LICENSE("GPL v2"); +module_init(mcctrl_init); +module_exit(mcctrl_exit); diff --git a/linux/mod_mcctrl/mcctrl.h b/linux/mod_mcctrl/mcctrl.h new file mode 100644 index 00000000..167cd42a --- /dev/null +++ b/linux/mod_mcctrl/mcctrl.h @@ -0,0 +1,12 @@ +#ifndef HEADER_MCCTRL_H +#define HEADER_MCCTRL_H + +#include +#include + +struct mcctrl_priv { + aal_os_t os; + struct program_load_desc *desc; +}; + +#endif