summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-06-27 21:22:31 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-06-27 21:22:31 +0000
commit51795e950480c053c2e7ee1c5361ec8fb1a9fe19 (patch)
tree1136538ca6bc9ee47705be9e0c4107a4277aa136 /sys
parentb66c9672202165bd9a54fc9a413daa73f6ef77f8 (diff)
/dev/{null,mem,kmem,...}
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/powerpc64/conf/files.powerpc643
-rw-r--r--sys/arch/powerpc64/powerpc64/conf.c7
-rw-r--r--sys/arch/powerpc64/powerpc64/mem.c201
-rw-r--r--sys/arch/powerpc64/powerpc64/pmap.c5
4 files changed, 212 insertions, 4 deletions
diff --git a/sys/arch/powerpc64/conf/files.powerpc64 b/sys/arch/powerpc64/conf/files.powerpc64
index 3dcaa7247bb..bdb6735c188 100644
--- a/sys/arch/powerpc64/conf/files.powerpc64
+++ b/sys/arch/powerpc64/conf/files.powerpc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.powerpc64,v 1.14 2020/06/27 15:04:49 kettenis Exp $
+# $OpenBSD: files.powerpc64,v 1.15 2020/06/27 21:22:29 kettenis Exp $
maxpartitions 16
maxusers 2 8 128
@@ -18,6 +18,7 @@ file arch/powerpc64/powerpc64/disksubr.c
file arch/powerpc64/powerpc64/fpu.c
file arch/powerpc64/powerpc64/intr.c
file arch/powerpc64/powerpc64/machdep.c
+file arch/powerpc64/powerpc64/mem.c
file arch/powerpc64/powerpc64/pmap.c
file arch/powerpc64/powerpc64/process_machdep.c
file arch/powerpc64/powerpc64/softintr.c
diff --git a/sys/arch/powerpc64/powerpc64/conf.c b/sys/arch/powerpc64/powerpc64/conf.c
index 7b7edc1b836..e2d0576770c 100644
--- a/sys/arch/powerpc64/powerpc64/conf.c
+++ b/sys/arch/powerpc64/powerpc64/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.3 2020/06/22 21:13:40 kettenis Exp $ */
+/* $OpenBSD: conf.c,v 1.4 2020/06/27 21:22:30 kettenis Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
@@ -45,6 +45,9 @@ struct bdevsw bdevsw[] =
};
int nblkdev = nitems(bdevsw);
+#define mmread mmrw
+#define mmwrite mmrw
+cdev_decl(mm);
#include "pty.h"
#include "opalcons.h"
@@ -52,7 +55,7 @@ struct cdevsw cdevsw[] =
{
cdev_cn_init(1,cn), /* 0: virtual console */
cdev_ctty_init(1,ctty), /* 1: controlling terminal */
- cdev_notdef(),
+ cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */
cdev_notdef(),
cdev_notdef(),
cdev_tty_init(NPTY,pts), /* 5: pseudo-tty slave */
diff --git a/sys/arch/powerpc64/powerpc64/mem.c b/sys/arch/powerpc64/powerpc64/mem.c
new file mode 100644
index 00000000000..93c48a950fb
--- /dev/null
+++ b/sys/arch/powerpc64/powerpc64/mem.c
@@ -0,0 +1,201 @@
+/* $OpenBSD: mem.c,v 1.1 2020/06/27 21:22:30 kettenis Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * 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.
+ *
+ * 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.
+ * 3. 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.
+ *
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/filio.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/ioccom.h>
+#include <sys/malloc.h>
+#include <sys/fcntl.h>
+#include <sys/rwlock.h>
+
+#include <machine/cpu.h>
+#include <machine/conf.h>
+
+#include <uvm/uvm_extern.h>
+
+extern char *vmmap; /* poor name! */
+caddr_t zeropage;
+
+static struct rwlock physlock = RWLOCK_INITIALIZER("mmrw");
+
+int
+mmopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ extern int allowkmem;
+
+ switch (minor(dev)) {
+ case 0:
+ case 1:
+ if (securelevel <= 0 || allowkmem)
+ break;
+ return (EPERM);
+ case 2:
+ case 12:
+ break;
+ default:
+ return (ENXIO);
+ }
+ return (0);
+}
+
+int
+mmclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ return (0);
+}
+
+int
+mmrw(dev_t dev, struct uio *uio, int flags)
+{
+ vaddr_t o, v;
+ size_t c;
+ struct iovec *iov;
+ int error = 0;
+
+ if (minor(dev) == 0) {
+ /* lock against other uses of shared vmmap */
+ error = rw_enter(&physlock, RW_WRITE | RW_INTR);
+ if (error)
+ return (error);
+ }
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("mmrw");
+ continue;
+ }
+ switch (minor(dev)) {
+
+ /* minor device 0 is physical memory */
+ case 0:
+ v = uio->uio_offset;
+ pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
+ trunc_page(v), uio->uio_rw == UIO_READ ?
+ PROT_READ : PROT_WRITE, PMAP_WIRED);
+ pmap_update(pmap_kernel());
+ o = uio->uio_offset & PGOFSET;
+ c = ulmin(uio->uio_resid, NBPG - o);
+ error = uiomove((caddr_t)vmmap + o, c, uio);
+ pmap_remove(pmap_kernel(), (vaddr_t)vmmap,
+ (vaddr_t)vmmap + NBPG);
+ pmap_update(pmap_kernel());
+ continue;
+
+ /* minor device 1 is kernel memory */
+ case 1:
+ v = uio->uio_offset;
+ c = ulmin(iov->iov_len, MAXPHYS);
+ if (!uvm_kernacc((caddr_t)v, c,
+ uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
+ return (EFAULT);
+ error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+ /* minor device 2 is /dev/null */
+ case 2:
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return (0);
+
+ /* minor device 12 is /dev/zero */
+ case 12:
+ if (uio->uio_rw == UIO_WRITE) {
+ c = iov->iov_len;
+ break;
+ }
+ if (zeropage == NULL) {
+ zeropage = malloc(PAGE_SIZE, M_TEMP,
+ M_WAITOK|M_ZERO);
+ }
+ c = ulmin(iov->iov_len, PAGE_SIZE);
+ error = uiomove(zeropage, c, uio);
+ continue;
+
+ default:
+ return (ENXIO);
+ }
+ iov->iov_base = (char *)iov->iov_base + c;
+ iov->iov_len -= c;
+ uio->uio_offset += c;
+ uio->uio_resid -= c;
+ }
+ if (minor(dev) == 0) {
+ rw_exit(&physlock);
+ }
+ return (error);
+}
+
+paddr_t
+mmmmap(dev_t dev, off_t off, int prot)
+{
+ struct proc *p = curproc; /* XXX */
+
+ switch (minor(dev)) {
+ /* minor device 0 is physical memory */
+ case 0:
+ if ((u_int)off > ptoa(physmem) && suser(p) != 0)
+ return -1;
+ return off;
+
+ default:
+ return -1;
+ }
+}
+
+int
+mmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ switch (cmd) {
+ case FIONBIO:
+ case FIOASYNC:
+ /* handled by fd layer */
+ return 0;
+ }
+
+ return (ENODEV);
+}
diff --git a/sys/arch/powerpc64/powerpc64/pmap.c b/sys/arch/powerpc64/powerpc64/pmap.c
index 38e11807f8a..6022affba6b 100644
--- a/sys/arch/powerpc64/powerpc64/pmap.c
+++ b/sys/arch/powerpc64/powerpc64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.19 2020/06/26 20:58:38 kettenis Exp $ */
+/* $OpenBSD: pmap.c,v 1.20 2020/06/27 21:22:30 kettenis Exp $ */
/*
* Copyright (c) 2015 Martin Pieuchot
@@ -817,6 +817,7 @@ extern struct fdt_reg initrd_reg;
void memreg_add(const struct fdt_reg *);
void memreg_remove(const struct fdt_reg *);
+vaddr_t vmmap;
vaddr_t zero_page;
vaddr_t copy_src_page;
vaddr_t copy_dst_page;
@@ -1449,6 +1450,8 @@ pmap_bootstrap(void)
va += 256 * 1024 * 1024)
pmap_set_kernel_slb(idx++, va);
+ vmmap = virtual_avail;
+ virtual_avail += PAGE_SIZE;
zero_page = virtual_avail;
virtual_avail += MAXCPUS * PAGE_SIZE;
copy_src_page = virtual_avail;