Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sh3/sh3 suitable for SH3/SH4 memory architecture.



details:   https://anonhg.NetBSD.org/src/rev/b30629e15798
branches:  trunk
changeset: 526731:b30629e15798
user:      uch <uch%NetBSD.org@localhost>
date:      Thu May 09 12:29:48 2002 +0000

description:
suitable for SH3/SH4 memory architecture.
support non-contiguos memory banks.

diffstat:

 sys/arch/sh3/sh3/mem.c |  120 +++++++++++++++++++++---------------------------
 1 files changed, 52 insertions(+), 68 deletions(-)

diffs (201 lines):

diff -r 9a5818289f58 -r b30629e15798 sys/arch/sh3/sh3/mem.c
--- a/sys/arch/sh3/sh3/mem.c    Thu May 09 12:29:16 2002 +0000
+++ b/sys/arch/sh3/sh3/mem.c    Thu May 09 12:29:48 2002 +0000
@@ -1,6 +1,8 @@
-/*     $NetBSD: mem.c,v 1.10 2002/05/07 03:28:25 thorpej Exp $ */
+/*     $NetBSD: mem.c,v 1.11 2002/05/09 12:29:48 uch Exp $     */
 
 /*
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1982, 1986, 1990, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -40,39 +42,28 @@
  *     @(#)mem.c       8.3 (Berkeley) 1/12/94
  */
 
-#include "opt_compat_netbsd.h"
-
 /*
  * Memory special file
  */
 
 #include <sys/param.h>
+#include <sys/systm.h>
 #include <sys/buf.h>
-#include <sys/systm.h>
 #include <sys/uio.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
-#include <sys/fcntl.h>
+#include <uvm/uvm_extern.h>
 
-#include <machine/cpu.h>
 #include <machine/conf.h>
 
-#include <uvm/uvm_extern.h>
-
-char *kvm_start = (char *)VM_MIN_KERNEL_ADDRESS;
-extern paddr_t avail_end;
 caddr_t zeropage;
+boolean_t __mm_mem_addr(paddr_t);
 
 /*ARGSUSED*/
 int
 mmopen(dev_t dev, int flag, int mode, struct proc *p)
 {
 
-       switch (minor(dev)) {
-
-       default:
-               break;
-       }
        return (0);
 }
 
@@ -88,24 +79,11 @@
 int
 mmrw(dev_t dev, struct uio *uio, int flags)
 {
-       register vaddr_t o, v;
-       register int c;
-       register struct iovec *iov;
+       struct iovec *iov;
+       vaddr_t v, o;
+       int c;
        int error = 0;
-       static int physlock;
-       vm_prot_t prot;
 
-       if (minor(dev) == DEV_MEM) {
-               /* lock against other uses of shared kvm_start */
-               while (physlock > 0) {
-                       physlock++;
-                       error = tsleep((caddr_t)&physlock, PZERO | PCATCH,
-                           "mmrw", 0);
-                       if (error)
-                               return (error);
-               }
-               physlock = 1;
-       }
        while (uio->uio_resid > 0 && !error) {
                iov = uio->uio_iov;
                if (iov->iov_len == 0) {
@@ -115,32 +93,39 @@
                                panic("mmrw");
                        continue;
                }
+
+               v = uio->uio_offset;
+
                switch (minor(dev)) {
-
+               kmemphys:
                case DEV_MEM:
-                       v = uio->uio_offset;
-                       prot = uio->uio_rw == UIO_READ ? VM_PROT_READ :
-                           VM_PROT_WRITE;
-                       pmap_enter(pmap_kernel(), (vaddr_t)kvm_start,
-                           trunc_page(v), prot, prot|PMAP_WIRED);
-                       pmap_update(pmap_kernel());
-                       o = uio->uio_offset & PGOFSET;
-                       c = min(uio->uio_resid, (int)(NBPG - o));
-                       error = uiomove((caddr_t)kvm_start + o, c, uio);
-                       pmap_remove(pmap_kernel(), (vaddr_t)kvm_start,
-                           (vaddr_t)kvm_start + NBPG);
-                       pmap_update(pmap_kernel());
+                       /* Physical address */
+                       if (__mm_mem_addr(v)) {
+                               o = v & PGOFSET;
+                               c = min(uio->uio_resid, (int)(NBPG - o));
+                               error = uiomove((caddr_t)SH3_PHYS_TO_P1SEG(v),
+                                   c, uio);
+                       } else {
+                               return (EFAULT);
+                       }
                        break;
 
                case DEV_KMEM:
-                       v = uio->uio_offset;
-                       c = min(iov->iov_len, MAXPHYS);
+                       /* P0 */
                        if (v < SH3_P1SEG_BASE)
                                return (EFAULT);
-                       if (v + c > SH3_PHYS_TO_P1SEG(avail_end +
-                                       sh3_round_page(MSGBUFSIZE)) &&
-                           (v < SH3_P3SEG_BASE || !uvm_kernacc((void *)v, c,
-                           uio->uio_rw == UIO_READ ? B_READ : B_WRITE)))
+                       /* P1 */
+                       if (v < SH3_P2SEG_BASE) {
+                               v = SH3_P1SEG_TO_PHYS(v);
+                               goto kmemphys;
+                       }
+                       /* P2 */
+                       if (v < SH3_P3SEG_BASE)
+                               return (EFAULT);
+                       /* P3 */
+                       c = min(iov->iov_len, MAXPHYS);
+                       if (!uvm_kernacc((void *)v, c,
+                           uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
                                return (EFAULT);
                        error = uiomove((caddr_t)v, c, uio);
                        break;
@@ -156,8 +141,7 @@
                                return (0);
                        }
                        if (zeropage == NULL) {
-                               zeropage = (caddr_t)
-                                   malloc(NBPG, M_TEMP, M_WAITOK);
+                               zeropage = malloc(NBPG, M_TEMP, M_WAITOK);
                                memset(zeropage, 0, NBPG);
                        }
                        c = min(iov->iov_len, NBPG);
@@ -168,31 +152,31 @@
                        return (ENXIO);
                }
        }
-       if (minor(dev) == DEV_MEM) {
-               if (physlock > 1)
-                       wakeup((caddr_t)&physlock);
-               physlock = 0;
-       }
+
        return (error);
 }
 
 paddr_t
 mmmmap(dev_t dev, off_t off, int prot)
 {
-       struct proc *p = curproc;       /* XXX */
+       struct proc *p = curproc;
 
-       /*
-        * /dev/mem is the only one that makes sense through this
-        * interface.  For /dev/kmem any physaddr we return here
-        * could be transient and hence incorrect or invalid at
-        * a later time.  /dev/null just doesn't make any sense
-        * and /dev/zero is a hack that is handled via the default
-        * pager in mmap().
-        */
        if (minor(dev) != DEV_MEM)
                return (-1);
 
-       if ((u_int)off > ctob(physmem) && suser(p->p_ucred, &p->p_acflag) != 0)
+       if (!__mm_mem_addr(off) && suser(p->p_ucred, &p->p_acflag) != 0)
                return (-1);
-       return (sh3_btop((u_int)off));
+       return (trunc_page((paddr_t)off));
 }
+
+/*
+ * boolean_t __mm_mem_addr(paddr_t pa):
+ *     Check specified physical address is memory device.
+ */
+boolean_t
+__mm_mem_addr(paddr_t pa)
+{
+
+       return ((atop(pa) < vm_physmem[0].start || PHYS_TO_VM_PAGE(pa) != NULL)
+           ? TRUE : FALSE);
+}



Home | Main Index | Thread Index | Old Index