Add openprom(4) for octeon.
authorvisa <visa@openbsd.org>
Tue, 5 Jul 2016 12:53:40 +0000 (12:53 +0000)
committervisa <visa@openbsd.org>
Tue, 5 Jul 2016 12:53:40 +0000 (12:53 +0000)
ok kettenis@ deraadt@ jasper@

sys/arch/octeon/conf/GENERIC
sys/arch/octeon/conf/RAMDISK
sys/arch/octeon/conf/files.octeon
sys/arch/octeon/include/conf.h
sys/arch/octeon/include/openpromio.h [new file with mode: 0644]
sys/arch/octeon/octeon/conf.c
sys/arch/octeon/octeon/openprom.c [new file with mode: 0644]

index 08c227f..593f9a2 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: GENERIC,v 1.27 2016/06/28 04:41:37 jmatthew Exp $
+#      $OpenBSD: GENERIC,v 1.28 2016/07/05 12:53:40 visa Exp $
 #
 # For further information on compiling OpenBSD kernels, see the config(8)
 # man page.
@@ -176,3 +176,5 @@ owid*               at onewire?     # ID
 owsbm*         at onewire?     # Smart Battery Monitor
 owtemp*        at onewire?     # Temperature
 owctr*         at onewire?     # Counter device
+
+pseudo-device  openprom
index 3d8ad0b..400c9be 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: RAMDISK,v 1.25 2016/06/28 04:41:37 jmatthew Exp $
+#      $OpenBSD: RAMDISK,v 1.26 2016/07/05 12:53:40 visa Exp $
 
 machine                octeon mips64
 maxusers       4
@@ -101,6 +101,7 @@ ukphy*              at mii?
 atphy*         at mii?
 brswphy*       at mii?
 
+pseudo-device  openprom
 pseudo-device  loop 1
 pseudo-device  bpfilter 1
 pseudo-device  rd 1
index 093da55..5fe9f32 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: files.octeon,v 1.30 2016/07/01 15:12:37 visa Exp $
+#      $OpenBSD: files.octeon,v 1.31 2016/07/05 12:53:40 visa Exp $
 
 # Standard stanzas config(8) can't run without
 maxpartitions 16
@@ -117,3 +117,6 @@ file        arch/octeon/dev/octeon_pcibus.c                 pcibus
 file   arch/octeon/dev/octeon_bus_space.c
 
 file   arch/octeon/octeon/pciide_machdep.c             pciide
+
+pseudo-device  openprom
+file   arch/octeon/octeon/openprom.c                   openprom needs-flag
index 7013e1b..e84bc9e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conf.h,v 1.1 2010/09/20 06:32:30 syuu Exp $   */
+/*     $OpenBSD: conf.h,v 1.2 2016/07/05 12:53:40 visa Exp $   */
 /*     $NetBSD: conf.h,v 1.2 1996/05/05 19:28:34 christos Exp $        */
 
 /*
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef _OCTEON_CONF_H_
+#define _OCTEON_CONF_H_
+
 #include <sys/conf.h>
+
+/* open, close, ioctl */
+#define cdev_openprom_init(c,n) { \
+       dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+       (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+       (dev_type_stop((*))) nullop, 0, selfalse, \
+       (dev_type_mmap((*))) enodev }
+
+cdev_decl(openprom);
+
+#endif /* _OCTEON_CONF_H_ */
diff --git a/sys/arch/octeon/include/openpromio.h b/sys/arch/octeon/include/openpromio.h
new file mode 100644 (file)
index 0000000..de824d7
--- /dev/null
@@ -0,0 +1,57 @@
+/*     $OpenBSD: openpromio.h,v 1.1 2016/07/05 12:53:40 visa Exp $     */
+/*     $NetBSD: openpromio.h,v 1.1.1.1 1998/06/20 04:58:52 eeh Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ *
+ *     @(#)openpromio.h        8.1 (Berkeley) 6/11/93
+ */
+
+struct opiocdesc {
+       int     op_nodeid;              /* passed or returned node id */
+       int     op_namelen;             /* length of op_name */
+       char    *op_name;               /* pointer to field name */
+       int     op_buflen;              /* length of op_buf (value-result) */
+       char    *op_buf;                /* pointer to field value */
+};
+
+#define        OPIOCGET        _IOWR('O', 1, struct opiocdesc) /* get openprom field */
+#define        OPIOCSET        _IOW('O', 2, struct opiocdesc) /* set openprom field */
+#define        OPIOCNEXTPROP   _IOWR('O', 3, struct opiocdesc) /* get next property */
+#define        OPIOCGETOPTNODE _IOR('O', 4, int)       /* get openprom field */
+#define        OPIOCGETNEXT    _IOWR('O', 5, int)      /* get next node of node */
+#define        OPIOCGETCHILD   _IOWR('O', 6, int)      /* get first child of node */
index 47de018..50e1d87 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conf.c,v 1.17 2016/04/25 20:09:14 tedu Exp $ */
+/*     $OpenBSD: conf.c,v 1.18 2016/07/05 12:53:40 visa Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -140,6 +140,7 @@ cdev_decl(pci);
 #include "vscsi.h"
 #include "pppx.h"
 #include "fuse.h"
+#include "openprom.h"
 
 struct cdevsw  cdevsw[] =
 {
@@ -167,7 +168,7 @@ struct cdevsw       cdevsw[] =
        cdev_tty_init(NCOM,com),        /* 17: 16C450 serial interface */
        cdev_disk_init(NWD,wd),         /* 18: ST506/ESDI/IDE disk */
        cdev_disk_init(NAMDCF,amdcf),   /* 19: CF disk */
-       cdev_notdef(),                  /* 20: */
+       cdev_openprom_init(NOPENPROM,openprom), /* 20: /dev/openprom */
        cdev_notdef(),                  /* 21: */
        cdev_disk_init(NRD,rd),         /* 22: ramdisk device */
        cdev_notdef(),                  /* 23: was: concatenated disk driver */
diff --git a/sys/arch/octeon/octeon/openprom.c b/sys/arch/octeon/octeon/openprom.c
new file mode 100644 (file)
index 0000000..7706331
--- /dev/null
@@ -0,0 +1,272 @@
+/*     $OpenBSD: openprom.c,v 1.1 2016/07/05 12:53:40 visa Exp $       */
+/*     $NetBSD: openprom.c,v 1.4 2002/01/10 06:21:53 briggs Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ *
+ *     @(#)openprom.c  8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+
+#include <machine/openpromio.h>
+#include <machine/conf.h>
+
+#include <dev/ofw/openfirm.h>
+
+#define OPROMMAXPARAM          32
+
+static int lastnode;                   /* speed hack */
+static int optionsnode;                /* node ID of ROM's options */
+
+static int openpromcheckid(int, int);
+static int openpromgetstr(int, char *, char **);
+void    openpromattach(int);
+
+void
+openpromattach(int num)
+{
+}
+
+int
+openpromopen(dev_t dev, int flags, int mode, struct proc *p)
+{
+       return (0);
+}
+
+int
+openpromclose(dev_t dev, int flags, int mode, struct proc *p)
+{
+       return (0);
+}
+
+/*
+ * Verify target ID is valid (exists in the OPENPROM tree), as
+ * listed from node ID sid forward.
+ */
+int
+openpromcheckid(int sid, int tid)
+{
+       for (; sid != 0; sid = OF_peer(sid))
+               if (sid == tid || openpromcheckid(OF_child(sid), tid))
+                       return (1);
+
+       return (0);
+}
+
+int
+openpromgetstr(int len, char *user, char **cpp)
+{
+       int error;
+       char *cp;
+
+       /* Reject obvious bogus requests */
+       if ((u_int)len > (8 * 1024) - 1)
+               return (ENAMETOOLONG);
+
+       *cpp = cp = malloc(len + 1, M_TEMP, M_WAITOK);
+       error = copyin(user, cp, len);
+       cp[len] = '\0';
+       return (error);
+}
+
+int
+openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+       struct opiocdesc *op;
+       int node, len, ok, error, s;
+       char *name, *value, *nextprop;
+       static char buf[32];    /* XXX */
+
+       if (optionsnode == 0) {
+               s = splhigh();
+               optionsnode = OF_getnodebyname(0, "options");
+               splx(s);
+       }
+
+       /* All too easy... */
+       if (cmd == OPIOCGETOPTNODE) {
+               *(int *)data = optionsnode;
+               return (0);
+       }
+
+       /* Verify node id */
+       op = (struct opiocdesc *)data;
+       node = op->op_nodeid;
+       if (node != 0 && node != lastnode && node != optionsnode) {
+               /* Not an easy one, must search for it */
+               s = splhigh();
+               ok = openpromcheckid(OF_peer(0), node);
+               splx(s);
+               if (!ok)
+                       return (EINVAL);
+               lastnode = node;
+       }
+
+       name = value = NULL;
+       error = 0;
+       switch (cmd) {
+
+       case OPIOCGET:
+               if ((flags & FREAD) == 0)
+                       return (EBADF);
+               if (node == 0)
+                       return (EINVAL);
+               error = openpromgetstr(op->op_namelen, op->op_name, &name);
+               if (error)
+                       break;
+               s = splhigh();
+               strlcpy(buf, name, 32); /* XXX */
+               len = OF_getproplen(node, buf);
+               splx(s);
+               if (len > op->op_buflen) {
+                       error = ENOMEM;
+                       break;
+               }
+               op->op_buflen = len;
+               /* -1 means no entry; 0 means no value */
+               if (len <= 0)
+                       break;
+               value = malloc(len, M_TEMP, M_WAITOK);
+               s = splhigh();
+               strlcpy(buf, name, 32); /* XXX */
+               OF_getprop(node, buf, value, len);
+               splx(s);
+               error = copyout(value, op->op_buf, len);
+               break;
+
+#if 0
+       case OPIOCSET:
+               if ((flags & FWRITE) == 0)
+                       return (EBADF);
+               if (node == 0)
+                       return (EINVAL);
+               error = openpromgetstr(op->op_namelen, op->op_name, &name);
+               if (error)
+                       break;
+               error = openpromgetstr(op->op_buflen, op->op_buf, &value);
+               if (error)
+                       break;
+               s = splhigh();
+               strlcpy(buf, name, 32); /* XXX */
+               len = OF_setprop(node, buf, value, op->op_buflen + 1);
+               splx(s);
+               if (len != op->op_buflen)
+                       error = EINVAL;
+               break;
+#endif
+
+       case OPIOCNEXTPROP:
+               if ((flags & FREAD) == 0)
+                       return (EBADF);
+               if (node == 0) {
+                       printf("%s node == 0\n", __func__);
+                       return (EINVAL);
+               }
+               error = openpromgetstr(op->op_namelen, op->op_name, &name);
+               if (error)
+                       break;
+               if (op->op_buflen <= 0) {
+                       error = ENAMETOOLONG;
+                       break;
+               }
+               value = nextprop = malloc(OPROMMAXPARAM, M_TEMP,
+                   M_WAITOK | M_CANFAIL);
+               if (nextprop == NULL) {
+                       error = ENOMEM;
+                       break;
+               }
+               s = splhigh();
+               strlcpy(buf, name, 32); /* XXX */
+               error = OF_nextprop(node, buf, nextprop);
+               splx(s);
+               if (error == -1) {
+                       printf("%s OF_nextprop\n", __func__);
+                       error = EINVAL;
+                       break;
+               }
+               if (error == 0) {
+                       char nul = '\0';
+
+                       op->op_buflen = 0;
+                       error = copyout(&nul, op->op_buf, sizeof(char));
+                       break;
+               }
+               len = strlen(nextprop);
+               if (len > op->op_buflen)
+                       len = op->op_buflen;
+               else
+                       op->op_buflen = len;
+               error = copyout(nextprop, op->op_buf, len);
+               break;
+
+       case OPIOCGETNEXT:
+               if ((flags & FREAD) == 0)
+                       return (EBADF);
+               s = splhigh();
+               node = OF_peer(node);
+               splx(s);
+               *(int *)data = lastnode = node;
+               break;
+
+       case OPIOCGETCHILD:
+               if ((flags & FREAD) == 0)
+                       return (EBADF);
+               if (node == 0)
+                       return (EINVAL);
+               s = splhigh();
+               node = OF_child(node);
+               splx(s);
+               *(int *)data = lastnode = node;
+               break;
+
+       default:
+               return (ENOTTY);
+       }
+
+       free(name, M_TEMP, 0);
+       free(value, M_TEMP, 0);
+
+       return (error);
+}