^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * arch/um/drivers/mmapper_kern.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * BRIEF MODULE DESCRIPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2000 RidgeRun, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author: RidgeRun, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <mem_user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* These are set in mmapper_init, which is called at boot time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static unsigned long mmapper_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static unsigned long p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static char *v_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static ssize_t mmapper_read(struct file *file, char __user *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static ssize_t mmapper_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (*ppos > mmapper_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return simple_write_to_buffer(v_buf, mmapper_size, ppos, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int mmapper_mmap(struct file *file, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (vma->vm_pgoff != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) size = vma->vm_end - vma->vm_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (size > mmapper_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * XXX A comment above remap_pfn_range says it should only be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * called when the mm semaphore is held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (remap_pfn_range(vma, vma->vm_start, p_buf >> PAGE_SHIFT, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) vma->vm_page_prot))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int mmapper_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int mmapper_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const struct file_operations mmapper_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .read = mmapper_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .write = mmapper_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .unlocked_ioctl = mmapper_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .mmap = mmapper_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .open = mmapper_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .release = mmapper_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * No locking needed - only used (and modified) by below initcall and exitcall.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static struct miscdevice mmapper_dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .minor = MISC_DYNAMIC_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .name = "mmapper",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .fops = &mmapper_fops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int __init mmapper_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) printk(KERN_INFO "Mapper v0.1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) v_buf = (char *) find_iomem("mmapper", &mmapper_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (mmapper_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) printk(KERN_ERR "mmapper_init - find_iomem failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) p_buf = __pa(v_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) err = misc_register(&mmapper_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void mmapper_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) misc_deregister(&mmapper_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) module_init(mmapper_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) module_exit(mmapper_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) MODULE_LICENSE("GPL");