summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authorssouhlal <ssouhlal@FreeBSD.org>2004-08-16 13:07:40 +0000
committerssouhlal <ssouhlal@FreeBSD.org>2004-08-16 13:07:40 +0000
commit43e0cc18c44f87e4df804eeba2d1caa26db52ec3 (patch)
treeb157d8deb4868d4c8be8ccfaa470af595c4ef1ef /sys/powerpc
parent9dc119c4b67e0952e92a5feb416e18e610733b7b (diff)
downloadFreeBSD-src-43e0cc18c44f87e4df804eeba2d1caa26db52ec3.zip
FreeBSD-src-43e0cc18c44f87e4df804eeba2d1caa26db52ec3.tar.gz
Add /dev/mem and /dev/kmem to powerpc.
Approved by: grehan (mentor)
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/aim/mmu_oea.c16
-rw-r--r--sys/powerpc/aim/ofw_machdep.c13
-rw-r--r--sys/powerpc/conf/GENERIC1
-rw-r--r--sys/powerpc/include/memdev.h40
-rw-r--r--sys/powerpc/include/ofw_machdep.h1
-rw-r--r--sys/powerpc/include/pmap.h2
-rw-r--r--sys/powerpc/powerpc/mem.c182
-rw-r--r--sys/powerpc/powerpc/mmu_oea.c16
-rw-r--r--sys/powerpc/powerpc/ofw_machdep.c13
-rw-r--r--sys/powerpc/powerpc/pmap.c16
10 files changed, 300 insertions, 0 deletions
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 62bdcec..08d7275 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -2308,6 +2308,22 @@ pmap_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
return (0);
}
+int
+pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
+{
+ int i;
+
+ /*
+ * This currently does not work for entries that
+ * overlap 256M BAT segments.
+ */
+
+ for(i = 0; i < 16; i++)
+ if (pmap_bat_mapped(i, pa, size) == 0)
+ return (0);
+
+ return (EFAULT);
+}
/*
* Map a set of physical memory pages into the kernel virtual
diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c
index 15b04a0..c00ca86 100644
--- a/sys/powerpc/aim/ofw_machdep.c
+++ b/sys/powerpc/aim/ofw_machdep.c
@@ -242,3 +242,16 @@ OF_getetheraddr(device_t dev, u_char *addr)
node = ofw_pci_find_node(dev);
OF_getprop(node, "local-mac-address", addr, ETHER_ADDR_LEN);
}
+
+int
+mem_valid(vm_offset_t addr, int len)
+{
+ int i;
+
+ for (i = 0; i < OFMEM_REGIONS; i++)
+ if ((addr >= OFmem[i].mr_start)
+ && (addr + len < OFmem[i].mr_start + OFmem[i].mr_size))
+ return (0);
+
+ return (EFAULT);
+}
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index e89b1db..bbd5ca3 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -103,6 +103,7 @@ device fxp # Intel EtherExpress PRO/100B (82557, 82558)
# Pseudo devices.
device loop # Network loopback
+device mem # Memory and kernel memory devices
device random # Entropy device
device ether # Ethernet support
device sl # Kernel SLIP
diff --git a/sys/powerpc/include/memdev.h b/sys/powerpc/include/memdev.h
new file mode 100644
index 0000000..69072d9
--- /dev/null
+++ b/sys/powerpc/include/memdev.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2004 Mark R V Murray
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define CDEV_MAJOR 2
+#define CDEV_MINOR_MEM 0
+#define CDEV_MINOR_KMEM 1
+
+d_open_t memopen;
+d_read_t memrw;
+#define memioctl (d_ioctl_t *)NULL
+d_mmap_t memmmap;
+
+void dev_mem_md_init(void);
+
+MALLOC_DECLARE(M_MEMDEV);
diff --git a/sys/powerpc/include/ofw_machdep.h b/sys/powerpc/include/ofw_machdep.h
index 35b09b9..7f3aa0e 100644
--- a/sys/powerpc/include/ofw_machdep.h
+++ b/sys/powerpc/include/ofw_machdep.h
@@ -31,5 +31,6 @@
#include <sys/bus.h>
void OF_getetheraddr(device_t dev, u_char *addr);
+int mem_valid(vm_offset_t addr, int len);
#endif /* _MACHINE_OFW_MACHDEP_H_ */
diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h
index d9013a9..16fc5c6 100644
--- a/sys/powerpc/include/pmap.h
+++ b/sys/powerpc/include/pmap.h
@@ -82,6 +82,8 @@ vm_offset_t pmap_kextract(vm_offset_t);
int pmap_pte_spill(vm_offset_t);
+int pmap_dev_direct_mapped(vm_offset_t, vm_size_t);
+
#define vtophys(va) pmap_kextract(((vm_offset_t)(va)))
extern vm_offset_t phys_avail[];
diff --git a/sys/powerpc/powerpc/mem.c b/sys/powerpc/powerpc/mem.c
new file mode 100644
index 0000000..c7f30205
--- /dev/null
+++ b/sys/powerpc/powerpc/mem.c
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department, and code derived from software contributed to
+ * Berkeley by William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah $Hdr: mem.c 1.13 89/10/08$
+ * from: @(#)mem.c 7.2 (Berkeley) 5/9/91
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/memrange.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/msgbuf.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/uio.h>
+
+#include <machine/md_var.h>
+#include <machine/ofw_machdep.h>
+#include <machine/vmparam.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <machine/memdev.h>
+
+struct mem_range_softc mem_range_softc;
+
+/* ARGSUSED */
+int
+memrw(struct cdev *dev, struct uio *uio, int flags)
+{
+ struct iovec *iov;
+ int error = 0;
+ vm_offset_t va, eva, off, v;
+ vm_prot_t prot;
+ vm_size_t cnt;
+
+ cnt = 0;
+ error = 0;
+
+ GIANT_REQUIRED;
+
+ while (uio->uio_resid > 0 && !error) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("memrw");
+ continue;
+ }
+ if (minor(dev) == CDEV_MINOR_MEM) {
+kmem_direct_mapped: v = uio->uio_offset;
+
+ off = uio->uio_offset & PAGE_MASK;
+ cnt = PAGE_SIZE - ((vm_offset_t)iov->iov_base &
+ PAGE_MASK);
+ cnt = min(cnt, PAGE_SIZE - off);
+ cnt = min(cnt, iov->iov_len);
+
+ if (mem_valid(v, cnt)
+ && pmap_dev_direct_mapped(v, cnt)) {
+ error = EFAULT;
+ break;
+ }
+
+ uiomove((void *)v, cnt, uio);
+ break;
+ }
+ else if (minor(dev) == CDEV_MINOR_KMEM) {
+ va = uio->uio_offset;
+
+ if ((va < VM_MIN_KERNEL_ADDRESS)
+ || (va > VM_MAX_KERNEL_ADDRESS))
+ goto kmem_direct_mapped;
+
+ va = trunc_page(uio->uio_offset);
+ eva = round_page(uio->uio_offset
+ + iov->iov_len);
+
+ /*
+ * Make sure that all the pages are currently resident
+ * so that we don't create any zero-fill pages.
+ */
+
+ for (; va < eva; va += PAGE_SIZE)
+ if (pmap_extract(kernel_pmap, va)
+ == 0)
+ return (EFAULT);
+
+ prot = (uio->uio_rw == UIO_READ)
+ ? VM_PROT_READ : VM_PROT_WRITE;
+
+ va = uio->uio_offset;
+ if (kernacc((void *) va, iov->iov_len, prot)
+ == FALSE)
+ return (EFAULT);
+
+ error = uiomove((void *)va, iov->iov_len, uio);
+
+ continue;
+ }
+ }
+
+ return (error);
+}
+
+/*
+ * allow user processes to MMAP some memory sections
+ * instead of going through read/write
+ */
+int
+memmmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int prot)
+{
+ /*
+ * /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.
+ */
+ if (minor(dev) != CDEV_MINOR_MEM)
+ return (-1);
+
+ /* Only direct-mapped addresses. */
+ if (mem_valid(offset, 0)
+ && pmap_dev_direct_mapped(offset, 0))
+ return (EFAULT);
+
+ *paddr = offset;
+
+ return (0);
+}
+
+void
+dev_mem_md_init(void)
+{
+}
diff --git a/sys/powerpc/powerpc/mmu_oea.c b/sys/powerpc/powerpc/mmu_oea.c
index 62bdcec..08d7275 100644
--- a/sys/powerpc/powerpc/mmu_oea.c
+++ b/sys/powerpc/powerpc/mmu_oea.c
@@ -2308,6 +2308,22 @@ pmap_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
return (0);
}
+int
+pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
+{
+ int i;
+
+ /*
+ * This currently does not work for entries that
+ * overlap 256M BAT segments.
+ */
+
+ for(i = 0; i < 16; i++)
+ if (pmap_bat_mapped(i, pa, size) == 0)
+ return (0);
+
+ return (EFAULT);
+}
/*
* Map a set of physical memory pages into the kernel virtual
diff --git a/sys/powerpc/powerpc/ofw_machdep.c b/sys/powerpc/powerpc/ofw_machdep.c
index 15b04a0..c00ca86 100644
--- a/sys/powerpc/powerpc/ofw_machdep.c
+++ b/sys/powerpc/powerpc/ofw_machdep.c
@@ -242,3 +242,16 @@ OF_getetheraddr(device_t dev, u_char *addr)
node = ofw_pci_find_node(dev);
OF_getprop(node, "local-mac-address", addr, ETHER_ADDR_LEN);
}
+
+int
+mem_valid(vm_offset_t addr, int len)
+{
+ int i;
+
+ for (i = 0; i < OFMEM_REGIONS; i++)
+ if ((addr >= OFmem[i].mr_start)
+ && (addr + len < OFmem[i].mr_start + OFmem[i].mr_size))
+ return (0);
+
+ return (EFAULT);
+}
diff --git a/sys/powerpc/powerpc/pmap.c b/sys/powerpc/powerpc/pmap.c
index 62bdcec..08d7275 100644
--- a/sys/powerpc/powerpc/pmap.c
+++ b/sys/powerpc/powerpc/pmap.c
@@ -2308,6 +2308,22 @@ pmap_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
return (0);
}
+int
+pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
+{
+ int i;
+
+ /*
+ * This currently does not work for entries that
+ * overlap 256M BAT segments.
+ */
+
+ for(i = 0; i < 16; i++)
+ if (pmap_bat_mapped(i, pa, size) == 0)
+ return (0);
+
+ return (EFAULT);
+}
/*
* Map a set of physical memory pages into the kernel virtual
OpenPOWER on IntegriCloud