OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [proc/] [mem.c] - Diff between revs 1628 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1628 Rev 1765
/*
/*
 *  linux/fs/proc/mem.c
 *  linux/fs/proc/mem.c
 *
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */
 */
 
 
/*
/*
 * uClinux revisions for NO_MM
 * uClinux revisions for NO_MM
 * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
 * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
 *                     The Silver Hammer Group, Ltd.
 *                     The Silver Hammer Group, Ltd.
 */
 */
 
 
#include <linux/types.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mm.h>
 
 
#include <asm/page.h>
#include <asm/page.h>
#include <asm/segment.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>
 
 
#ifndef NO_MM
#ifndef NO_MM
 
 
/*
/*
 * mem_write isn't really a good idea right now. It needs
 * mem_write isn't really a good idea right now. It needs
 * to check a lot more: if the process we try to write to
 * to check a lot more: if the process we try to write to
 * dies in the middle right now, mem_write will overwrite
 * dies in the middle right now, mem_write will overwrite
 * kernel memory.. This disables it altogether.
 * kernel memory.. This disables it altogether.
 */
 */
#define mem_write NULL
#define mem_write NULL
 
 
static int check_range(struct mm_struct * mm, unsigned long addr, int count)
static int check_range(struct mm_struct * mm, unsigned long addr, int count)
{
{
        struct vm_area_struct *vma;
        struct vm_area_struct *vma;
        int retval;
        int retval;
 
 
        vma = find_vma(mm, addr);
        vma = find_vma(mm, addr);
        if (!vma)
        if (!vma)
                return -EACCES;
                return -EACCES;
        if (vma->vm_start > addr)
        if (vma->vm_start > addr)
                return -EACCES;
                return -EACCES;
        if (!(vma->vm_flags & VM_READ))
        if (!(vma->vm_flags & VM_READ))
                return -EACCES;
                return -EACCES;
        while ((retval = vma->vm_end - addr) < count) {
        while ((retval = vma->vm_end - addr) < count) {
                struct vm_area_struct *next = vma->vm_next;
                struct vm_area_struct *next = vma->vm_next;
                if (!next)
                if (!next)
                        break;
                        break;
                if (vma->vm_end != next->vm_start)
                if (vma->vm_end != next->vm_start)
                        break;
                        break;
                if (!(next->vm_flags & VM_READ))
                if (!(next->vm_flags & VM_READ))
                        break;
                        break;
                vma = next;
                vma = next;
        }
        }
        if (retval > count)
        if (retval > count)
                retval = count;
                retval = count;
        return retval;
        return retval;
}
}
 
 
static struct task_struct * get_task(int pid)
static struct task_struct * get_task(int pid)
{
{
        struct task_struct * tsk = current;
        struct task_struct * tsk = current;
 
 
        if (pid != tsk->pid) {
        if (pid != tsk->pid) {
                int i;
                int i;
                tsk = NULL;
                tsk = NULL;
                for (i = 1 ; i < NR_TASKS ; i++)
                for (i = 1 ; i < NR_TASKS ; i++)
                        if (task[i] && task[i]->pid == pid) {
                        if (task[i] && task[i]->pid == pid) {
                                tsk = task[i];
                                tsk = task[i];
                                break;
                                break;
                        }
                        }
                /*
                /*
                 * allow accesses only under the same circumstances
                 * allow accesses only under the same circumstances
                 * that we would allow ptrace to work
                 * that we would allow ptrace to work
                 */
                 */
                if (tsk) {
                if (tsk) {
                        if (!(tsk->flags & PF_PTRACED)
                        if (!(tsk->flags & PF_PTRACED)
                            || tsk->state != TASK_STOPPED
                            || tsk->state != TASK_STOPPED
                            || tsk->p_pptr != current)
                            || tsk->p_pptr != current)
                                tsk = NULL;
                                tsk = NULL;
                }
                }
        }
        }
        return tsk;
        return tsk;
}
}
 
 
static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
{
{
        pgd_t *page_dir;
        pgd_t *page_dir;
        pmd_t *page_middle;
        pmd_t *page_middle;
        pte_t pte;
        pte_t pte;
        char * page;
        char * page;
        struct task_struct * tsk;
        struct task_struct * tsk;
        unsigned long addr;
        unsigned long addr;
        char *tmp;
        char *tmp;
        int i;
        int i;
 
 
        if (count < 0)
        if (count < 0)
                return -EINVAL;
                return -EINVAL;
        tsk = get_task(inode->i_ino >> 16);
        tsk = get_task(inode->i_ino >> 16);
        if (!tsk)
        if (!tsk)
                return -ESRCH;
                return -ESRCH;
        addr = file->f_pos;
        addr = file->f_pos;
        count = check_range(tsk->mm, addr, count);
        count = check_range(tsk->mm, addr, count);
        if (count < 0)
        if (count < 0)
                return count;
                return count;
        tmp = buf;
        tmp = buf;
        while (count > 0) {
        while (count > 0) {
                if (current->signal & ~current->blocked)
                if (current->signal & ~current->blocked)
                        break;
                        break;
                page_dir = pgd_offset(tsk->mm,addr);
                page_dir = pgd_offset(tsk->mm,addr);
                if (pgd_none(*page_dir))
                if (pgd_none(*page_dir))
                        break;
                        break;
                if (pgd_bad(*page_dir)) {
                if (pgd_bad(*page_dir)) {
                        printk("Bad page dir entry %08lx\n", pgd_val(*page_dir));
                        printk("Bad page dir entry %08lx\n", pgd_val(*page_dir));
                        pgd_clear(page_dir);
                        pgd_clear(page_dir);
                        break;
                        break;
                }
                }
                page_middle = pmd_offset(page_dir,addr);
                page_middle = pmd_offset(page_dir,addr);
                if (pmd_none(*page_middle))
                if (pmd_none(*page_middle))
                        break;
                        break;
                if (pmd_bad(*page_middle)) {
                if (pmd_bad(*page_middle)) {
                        printk("Bad page middle entry %08lx\n", pmd_val(*page_middle));
                        printk("Bad page middle entry %08lx\n", pmd_val(*page_middle));
                        pmd_clear(page_middle);
                        pmd_clear(page_middle);
                        break;
                        break;
                }
                }
                pte = *pte_offset(page_middle,addr);
                pte = *pte_offset(page_middle,addr);
                if (!pte_present(pte))
                if (!pte_present(pte))
                        break;
                        break;
                page = (char *) pte_page(pte) + (addr & ~PAGE_MASK);
                page = (char *) pte_page(pte) + (addr & ~PAGE_MASK);
                i = PAGE_SIZE-(addr & ~PAGE_MASK);
                i = PAGE_SIZE-(addr & ~PAGE_MASK);
                if (i > count)
                if (i > count)
                        i = count;
                        i = count;
                memcpy_tofs(tmp, page, i);
                memcpy_tofs(tmp, page, i);
                addr += i;
                addr += i;
                tmp += i;
                tmp += i;
                count -= i;
                count -= i;
        }
        }
        file->f_pos = addr;
        file->f_pos = addr;
        return tmp-buf;
        return tmp-buf;
}
}
 
 
#ifndef mem_write
#ifndef mem_write
 
 
static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
{
{
        pgd_t *page_dir;
        pgd_t *page_dir;
        pmd_t *page_middle;
        pmd_t *page_middle;
        pte_t pte;
        pte_t pte;
        char * page;
        char * page;
        struct task_struct * tsk;
        struct task_struct * tsk;
        unsigned long addr;
        unsigned long addr;
        char *tmp;
        char *tmp;
        int i;
        int i;
 
 
        if (count < 0)
        if (count < 0)
                return -EINVAL;
                return -EINVAL;
        addr = file->f_pos;
        addr = file->f_pos;
        tsk = get_task(inode->i_ino >> 16);
        tsk = get_task(inode->i_ino >> 16);
        if (!tsk)
        if (!tsk)
                return -ESRCH;
                return -ESRCH;
        tmp = buf;
        tmp = buf;
        while (count > 0) {
        while (count > 0) {
                if (current->signal & ~current->blocked)
                if (current->signal & ~current->blocked)
                        break;
                        break;
                page_dir = pgd_offset(tsk,addr);
                page_dir = pgd_offset(tsk,addr);
                if (pgd_none(*page_dir))
                if (pgd_none(*page_dir))
                        break;
                        break;
                if (pgd_bad(*page_dir)) {
                if (pgd_bad(*page_dir)) {
                        printk("Bad page dir entry %08lx\n", pgd_val(*page_dir));
                        printk("Bad page dir entry %08lx\n", pgd_val(*page_dir));
                        pgd_clear(page_dir);
                        pgd_clear(page_dir);
                        break;
                        break;
                }
                }
                page_middle = pmd_offset(page_dir,addr);
                page_middle = pmd_offset(page_dir,addr);
                if (pmd_none(*page_middle))
                if (pmd_none(*page_middle))
                        break;
                        break;
                if (pmd_bad(*page_middle)) {
                if (pmd_bad(*page_middle)) {
                        printk("Bad page middle entry %08lx\n", pmd_val(*page_middle));
                        printk("Bad page middle entry %08lx\n", pmd_val(*page_middle));
                        pmd_clear(page_middle);
                        pmd_clear(page_middle);
                        break;
                        break;
                }
                }
                pte = *pte_offset(page_middle,addr);
                pte = *pte_offset(page_middle,addr);
                if (!pte_present(pte))
                if (!pte_present(pte))
                        break;
                        break;
                if (!pte_write(pte))
                if (!pte_write(pte))
                        break;
                        break;
                page = (char *) pte_page(pte) + (addr & ~PAGE_MASK);
                page = (char *) pte_page(pte) + (addr & ~PAGE_MASK);
                i = PAGE_SIZE-(addr & ~PAGE_MASK);
                i = PAGE_SIZE-(addr & ~PAGE_MASK);
                if (i > count)
                if (i > count)
                        i = count;
                        i = count;
                memcpy_fromfs(page, tmp, i);
                memcpy_fromfs(page, tmp, i);
                addr += i;
                addr += i;
                tmp += i;
                tmp += i;
                count -= i;
                count -= i;
        }
        }
        file->f_pos = addr;
        file->f_pos = addr;
        if (tmp != buf)
        if (tmp != buf)
                return tmp-buf;
                return tmp-buf;
        if (current->signal & ~current->blocked)
        if (current->signal & ~current->blocked)
                return -ERESTARTSYS;
                return -ERESTARTSYS;
        return 0;
        return 0;
}
}
 
 
#endif
#endif
 
 
static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
{
{
        switch (orig) {
        switch (orig) {
                case 0:
                case 0:
                        file->f_pos = offset;
                        file->f_pos = offset;
                        return file->f_pos;
                        return file->f_pos;
                case 1:
                case 1:
                        file->f_pos += offset;
                        file->f_pos += offset;
                        return file->f_pos;
                        return file->f_pos;
                default:
                default:
                        return -EINVAL;
                        return -EINVAL;
        }
        }
}
}
 
 
/*
/*
 * This isn't really reliable by any means..
 * This isn't really reliable by any means..
 */
 */
int mem_mmap(struct inode * inode, struct file * file,
int mem_mmap(struct inode * inode, struct file * file,
             struct vm_area_struct * vma)
             struct vm_area_struct * vma)
{
{
        struct task_struct *tsk;
        struct task_struct *tsk;
        pgd_t *src_dir, *dest_dir;
        pgd_t *src_dir, *dest_dir;
        pmd_t *src_middle, *dest_middle;
        pmd_t *src_middle, *dest_middle;
        pte_t *src_table, *dest_table;
        pte_t *src_table, *dest_table;
        unsigned long stmp, dtmp, mapnr;
        unsigned long stmp, dtmp, mapnr;
        struct vm_area_struct *src_vma = NULL;
        struct vm_area_struct *src_vma = NULL;
 
 
        /* Get the source's task information */
        /* Get the source's task information */
 
 
        tsk = get_task(inode->i_ino >> 16);
        tsk = get_task(inode->i_ino >> 16);
 
 
        if (!tsk)
        if (!tsk)
                return -ESRCH;
                return -ESRCH;
 
 
        /* Ensure that we have a valid source area.  (Has to be mmap'ed and
        /* Ensure that we have a valid source area.  (Has to be mmap'ed and
         have valid page information.)  We can't map shared memory at the
         have valid page information.)  We can't map shared memory at the
         moment because working out the vm_area_struct & nattach stuff isn't
         moment because working out the vm_area_struct & nattach stuff isn't
         worth it. */
         worth it. */
 
 
        src_vma = tsk->mm->mmap;
        src_vma = tsk->mm->mmap;
        stmp = vma->vm_offset;
        stmp = vma->vm_offset;
        while (stmp < vma->vm_offset + (vma->vm_end - vma->vm_start)) {
        while (stmp < vma->vm_offset + (vma->vm_end - vma->vm_start)) {
                while (src_vma && stmp > src_vma->vm_end)
                while (src_vma && stmp > src_vma->vm_end)
                        src_vma = src_vma->vm_next;
                        src_vma = src_vma->vm_next;
                if (!src_vma || (src_vma->vm_flags & VM_SHM))
                if (!src_vma || (src_vma->vm_flags & VM_SHM))
                        return -EINVAL;
                        return -EINVAL;
 
 
                src_dir = pgd_offset(tsk->mm, stmp);
                src_dir = pgd_offset(tsk->mm, stmp);
                if (pgd_none(*src_dir))
                if (pgd_none(*src_dir))
                        return -EINVAL;
                        return -EINVAL;
                if (pgd_bad(*src_dir)) {
                if (pgd_bad(*src_dir)) {
                        printk("Bad source page dir entry %08lx\n", pgd_val(*src_dir));
                        printk("Bad source page dir entry %08lx\n", pgd_val(*src_dir));
                        return -EINVAL;
                        return -EINVAL;
                }
                }
                src_middle = pmd_offset(src_dir, stmp);
                src_middle = pmd_offset(src_dir, stmp);
                if (pmd_none(*src_middle))
                if (pmd_none(*src_middle))
                        return -EINVAL;
                        return -EINVAL;
                if (pmd_bad(*src_middle)) {
                if (pmd_bad(*src_middle)) {
                        printk("Bad source page middle entry %08lx\n", pmd_val(*src_middle));
                        printk("Bad source page middle entry %08lx\n", pmd_val(*src_middle));
                        return -EINVAL;
                        return -EINVAL;
                }
                }
                src_table = pte_offset(src_middle, stmp);
                src_table = pte_offset(src_middle, stmp);
                if (pte_none(*src_table))
                if (pte_none(*src_table))
                        return -EINVAL;
                        return -EINVAL;
 
 
                if (stmp < src_vma->vm_start) {
                if (stmp < src_vma->vm_start) {
                        if (!(src_vma->vm_flags & VM_GROWSDOWN))
                        if (!(src_vma->vm_flags & VM_GROWSDOWN))
                                return -EINVAL;
                                return -EINVAL;
                        if (src_vma->vm_end - stmp > current->rlim[RLIMIT_STACK].rlim_cur)
                        if (src_vma->vm_end - stmp > current->rlim[RLIMIT_STACK].rlim_cur)
                                return -EINVAL;
                                return -EINVAL;
                }
                }
                stmp += PAGE_SIZE;
                stmp += PAGE_SIZE;
        }
        }
 
 
        src_vma = tsk->mm->mmap;
        src_vma = tsk->mm->mmap;
        stmp    = vma->vm_offset;
        stmp    = vma->vm_offset;
        dtmp    = vma->vm_start;
        dtmp    = vma->vm_start;
 
 
        flush_cache_range(vma->vm_mm, vma->vm_start, vma->vm_end);
        flush_cache_range(vma->vm_mm, vma->vm_start, vma->vm_end);
        flush_cache_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
        flush_cache_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
        while (dtmp < vma->vm_end) {
        while (dtmp < vma->vm_end) {
                while (src_vma && stmp > src_vma->vm_end)
                while (src_vma && stmp > src_vma->vm_end)
                        src_vma = src_vma->vm_next;
                        src_vma = src_vma->vm_next;
 
 
                src_dir = pgd_offset(tsk->mm, stmp);
                src_dir = pgd_offset(tsk->mm, stmp);
                src_middle = pmd_offset(src_dir, stmp);
                src_middle = pmd_offset(src_dir, stmp);
                src_table = pte_offset(src_middle, stmp);
                src_table = pte_offset(src_middle, stmp);
 
 
                dest_dir = pgd_offset(current->mm, dtmp);
                dest_dir = pgd_offset(current->mm, dtmp);
                dest_middle = pmd_alloc(dest_dir, dtmp);
                dest_middle = pmd_alloc(dest_dir, dtmp);
                if (!dest_middle)
                if (!dest_middle)
                        return -ENOMEM;
                        return -ENOMEM;
                dest_table = pte_alloc(dest_middle, dtmp);
                dest_table = pte_alloc(dest_middle, dtmp);
                if (!dest_table)
                if (!dest_table)
                        return -ENOMEM;
                        return -ENOMEM;
 
 
                if (!pte_present(*src_table))
                if (!pte_present(*src_table))
                        do_no_page(tsk, src_vma, stmp, 1);
                        do_no_page(tsk, src_vma, stmp, 1);
 
 
                if ((vma->vm_flags & VM_WRITE) && !pte_write(*src_table))
                if ((vma->vm_flags & VM_WRITE) && !pte_write(*src_table))
                        do_wp_page(tsk, src_vma, stmp, 1);
                        do_wp_page(tsk, src_vma, stmp, 1);
 
 
                set_pte(src_table, pte_mkdirty(*src_table));
                set_pte(src_table, pte_mkdirty(*src_table));
                set_pte(dest_table, *src_table);
                set_pte(dest_table, *src_table);
                mapnr = MAP_NR(pte_page(*src_table));
                mapnr = MAP_NR(pte_page(*src_table));
                if (mapnr < MAP_NR(high_memory))
                if (mapnr < MAP_NR(high_memory))
                        mem_map[mapnr].count++;
                        mem_map[mapnr].count++;
 
 
                stmp += PAGE_SIZE;
                stmp += PAGE_SIZE;
                dtmp += PAGE_SIZE;
                dtmp += PAGE_SIZE;
        }
        }
 
 
        flush_tlb_range(vma->vm_mm, vma->vm_start, vma->vm_end);
        flush_tlb_range(vma->vm_mm, vma->vm_start, vma->vm_end);
        flush_tlb_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
        flush_tlb_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
        return 0;
        return 0;
}
}
 
 
static struct file_operations proc_mem_operations = {
static struct file_operations proc_mem_operations = {
        mem_lseek,
        mem_lseek,
        mem_read,
        mem_read,
        mem_write,
        mem_write,
        NULL,           /* mem_readdir */
        NULL,           /* mem_readdir */
        NULL,           /* mem_select */
        NULL,           /* mem_select */
        NULL,           /* mem_ioctl */
        NULL,           /* mem_ioctl */
        mem_mmap,       /* mmap */
        mem_mmap,       /* mmap */
        NULL,           /* no special open code */
        NULL,           /* no special open code */
        NULL,           /* no special release code */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
        NULL            /* can't fsync */
};
};
 
 
struct inode_operations proc_mem_inode_operations = {
struct inode_operations proc_mem_inode_operations = {
        &proc_mem_operations,   /* default base directory file-ops */
        &proc_mem_operations,   /* default base directory file-ops */
        NULL,                   /* create */
        NULL,                   /* create */
        NULL,                   /* lookup */
        NULL,                   /* lookup */
        NULL,                   /* link */
        NULL,                   /* link */
        NULL,                   /* unlink */
        NULL,                   /* unlink */
        NULL,                   /* symlink */
        NULL,                   /* symlink */
        NULL,                   /* mkdir */
        NULL,                   /* mkdir */
        NULL,                   /* rmdir */
        NULL,                   /* rmdir */
        NULL,                   /* mknod */
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL                    /* permission */
        NULL                    /* permission */
};
};
 
 
#else /* NO_MM */
#else /* NO_MM */
 
 
/*
/*
 * mem_write isn't really a good idea right now. It needs
 * mem_write isn't really a good idea right now. It needs
 * to check a lot more: if the process we try to write to
 * to check a lot more: if the process we try to write to
 * dies in the middle right now, mem_write will overwrite
 * dies in the middle right now, mem_write will overwrite
 * kernel memory.. This disables it altogether.
 * kernel memory.. This disables it altogether.
 */
 */
#define mem_write NULL
#define mem_write NULL
 
 
static struct task_struct * get_task(int pid)
static struct task_struct * get_task(int pid)
{
{
        struct task_struct * tsk = current;
        struct task_struct * tsk = current;
 
 
        if (pid != tsk->pid) {
        if (pid != tsk->pid) {
                int i;
                int i;
                tsk = NULL;
                tsk = NULL;
                for (i = 1 ; i < NR_TASKS ; i++)
                for (i = 1 ; i < NR_TASKS ; i++)
                        if (task[i] && task[i]->pid == pid) {
                        if (task[i] && task[i]->pid == pid) {
                                tsk = task[i];
                                tsk = task[i];
                                break;
                                break;
                        }
                        }
                /*
                /*
                 * allow accesses only under the same circumstances
                 * allow accesses only under the same circumstances
                 * that we would allow ptrace to work
                 * that we would allow ptrace to work
                 */
                 */
                if (tsk) {
                if (tsk) {
                        if (!(tsk->flags & PF_PTRACED)
                        if (!(tsk->flags & PF_PTRACED)
                            || tsk->state != TASK_STOPPED
                            || tsk->state != TASK_STOPPED
                            || tsk->p_pptr != current)
                            || tsk->p_pptr != current)
                                tsk = NULL;
                                tsk = NULL;
                }
                }
        }
        }
        return tsk;
        return tsk;
}
}
 
 
static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
{
{
        struct task_struct * tsk;
        struct task_struct * tsk;
        unsigned long addr;
        unsigned long addr;
        char *tmp;
        char *tmp;
        int i;
        int i;
 
 
        if (count < 0)
        if (count < 0)
                return -EINVAL;
                return -EINVAL;
        tsk = get_task(inode->i_ino >> 16);
        tsk = get_task(inode->i_ino >> 16);
        if (!tsk)
        if (!tsk)
                return -ESRCH;
                return -ESRCH;
        addr = file->f_pos;
        addr = file->f_pos;
        tmp = buf;
        tmp = buf;
        while (count > 0) {
        while (count > 0) {
                if (current->signal & ~current->blocked)
                if (current->signal & ~current->blocked)
                        break;
                        break;
                i = count;
                i = count;
                memcpy_tofs(tmp, (void*)addr, i);
                memcpy_tofs(tmp, (void*)addr, i);
                addr += i;
                addr += i;
                tmp += i;
                tmp += i;
                count -= i;
                count -= i;
        }
        }
        file->f_pos = addr;
        file->f_pos = addr;
        return tmp-buf;
        return tmp-buf;
}
}
 
 
#ifndef mem_write
#ifndef mem_write
 
 
static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
{
{
        struct task_struct * tsk;
        struct task_struct * tsk;
        unsigned long addr;
        unsigned long addr;
        char *tmp;
        char *tmp;
        int i;
        int i;
 
 
        if (count < 0)
        if (count < 0)
                return -EINVAL;
                return -EINVAL;
        addr = file->f_pos;
        addr = file->f_pos;
        tsk = get_task(inode->i_ino >> 16);
        tsk = get_task(inode->i_ino >> 16);
        if (!tsk)
        if (!tsk)
                return -ESRCH;
                return -ESRCH;
        tmp = buf;
        tmp = buf;
        while (count > 0) {
        while (count > 0) {
                if (current->signal & ~current->blocked)
                if (current->signal & ~current->blocked)
                        break;
                        break;
                i = count;
                i = count;
                memcpy_fromfs((void*)addr, tmp, i);
                memcpy_fromfs((void*)addr, tmp, i);
                addr += i;
                addr += i;
                tmp += i;
                tmp += i;
                count -= i;
                count -= i;
        }
        }
        file->f_pos = addr;
        file->f_pos = addr;
        if (tmp != buf)
        if (tmp != buf)
                return tmp-buf;
                return tmp-buf;
        if (current->signal & ~current->blocked)
        if (current->signal & ~current->blocked)
                return -ERESTARTSYS;
                return -ERESTARTSYS;
        return 0;
        return 0;
}
}
 
 
#endif
#endif
 
 
int mem_mmap(struct inode * inode, struct file * file,
int mem_mmap(struct inode * inode, struct file * file,
             struct vm_area_struct * vma)
             struct vm_area_struct * vma)
{
{
        vma->vm_start = vma->vm_offset;
        vma->vm_start = vma->vm_offset;
        return 0;
        return 0;
}
}
 
 
static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
{
{
        switch (orig) {
        switch (orig) {
                case 0:
                case 0:
                        file->f_pos = offset;
                        file->f_pos = offset;
                        return file->f_pos;
                        return file->f_pos;
                case 1:
                case 1:
                        file->f_pos += offset;
                        file->f_pos += offset;
                        return file->f_pos;
                        return file->f_pos;
                default:
                default:
                        return -EINVAL;
                        return -EINVAL;
        }
        }
}
}
 
 
static struct file_operations proc_mem_operations = {
static struct file_operations proc_mem_operations = {
        mem_lseek,
        mem_lseek,
        mem_read,
        mem_read,
        mem_write,
        mem_write,
        NULL,           /* mem_readdir */
        NULL,           /* mem_readdir */
        NULL,           /* mem_select */
        NULL,           /* mem_select */
        NULL,           /* mem_ioctl */
        NULL,           /* mem_ioctl */
        mem_mmap,       /* mmap */
        mem_mmap,       /* mmap */
        NULL,           /* no special open code */
        NULL,           /* no special open code */
        NULL,           /* no special release code */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
        NULL            /* can't fsync */
};
};
 
 
struct inode_operations proc_mem_inode_operations = {
struct inode_operations proc_mem_inode_operations = {
        &proc_mem_operations,   /* default base directory file-ops */
        &proc_mem_operations,   /* default base directory file-ops */
        NULL,                   /* create */
        NULL,                   /* create */
        NULL,                   /* lookup */
        NULL,                   /* lookup */
        NULL,                   /* link */
        NULL,                   /* link */
        NULL,                   /* unlink */
        NULL,                   /* unlink */
        NULL,                   /* symlink */
        NULL,                   /* symlink */
        NULL,                   /* mkdir */
        NULL,                   /* mkdir */
        NULL,                   /* rmdir */
        NULL,                   /* rmdir */
        NULL,                   /* mknod */
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL                    /* permission */
        NULL                    /* permission */
};
};
 
 
#endif /* NO_MM */
#endif /* NO_MM */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.