From: jsg Date: Fri, 23 Apr 2021 12:01:02 +0000 (+0000) Subject: reuse arm64 openprom(4) on riscv64 X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=05c58b1ca33d9e5e16804b779e02573a84003b78;p=openbsd reuse arm64 openprom(4) on riscv64 ok kettenis@ --- diff --git a/sys/arch/riscv64/conf/GENERIC b/sys/arch/riscv64/conf/GENERIC index 61fb6aa9cfa..fc44e7d66e8 100644 --- a/sys/arch/riscv64/conf/GENERIC +++ b/sys/arch/riscv64/conf/GENERIC @@ -53,3 +53,6 @@ sd* at scsibus? cd* at scsibus? ch* at scsibus? uk* at scsibus? + +# Pseudo-Devices +pseudo-device openprom diff --git a/sys/arch/riscv64/conf/files.riscv64 b/sys/arch/riscv64/conf/files.riscv64 index 12111dbe04d..e599f4f8f63 100644 --- a/sys/arch/riscv64/conf/files.riscv64 +++ b/sys/arch/riscv64/conf/files.riscv64 @@ -41,6 +41,9 @@ file arch/riscv64/riscv64/db_disasm.c ddb file arch/riscv64/riscv64/db_interface.c ddb file arch/riscv64/riscv64/db_trace.c ddb +pseudo-device openprom +file arch/riscv64/riscv64/openprom.c openprom needs-flag + define fdt {[early = 0]} # diff --git a/sys/arch/riscv64/include/openpromio.h b/sys/arch/riscv64/include/openpromio.h new file mode 100644 index 00000000000..c3f33087240 --- /dev/null +++ b/sys/arch/riscv64/include/openpromio.h @@ -0,0 +1,57 @@ +/* $OpenBSD: openpromio.h,v 1.1 2021/04/23 12:01:03 jsg 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 */ diff --git a/sys/arch/riscv64/riscv64/conf.c b/sys/arch/riscv64/riscv64/conf.c index 46eaa2088cd..e6bc20152aa 100644 --- a/sys/arch/riscv64/riscv64/conf.c +++ b/sys/arch/riscv64/riscv64/conf.c @@ -141,7 +141,7 @@ cdev_decl(pci); #include "vscsi.h" #include "pppx.h" #include "fuse.h" -//#include "openprom.h" +#include "openprom.h" #include "gpio.h" #include "ipmi.h" #include "switch.h" diff --git a/sys/arch/riscv64/riscv64/openprom.c b/sys/arch/riscv64/riscv64/openprom.c new file mode 100644 index 00000000000..790d21b87a6 --- /dev/null +++ b/sys/arch/riscv64/riscv64/openprom.c @@ -0,0 +1,227 @@ +/* $OpenBSD: openprom.c,v 1.1 2021/04/23 12:01:03 jsg 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static int lastnode; /* speed hack */ +static int optionsnode; /* node ID of ROM's options */ + +int openpromcheckid(int, int); +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; + char *name, *value, *nextprop; + + if (optionsnode == 0) + optionsnode = OF_getnodebyname(0, "options"); + + /* 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 */ + ok = openpromcheckid(OF_peer(0), node); + 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; + len = OF_getproplen(node, name); + 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); + OF_getprop(node, name, value, len); + error = copyout(value, op->op_buf, len); + break; + + case OPIOCNEXTPROP: + if ((flags & FREAD) == 0) + return (EBADF); + if (node == 0) + 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(OFMAXPARAM, M_TEMP, + M_WAITOK | M_CANFAIL); + if (nextprop == NULL) { + error = ENOMEM; + break; + } + error = OF_nextprop(node, name, nextprop); + if (error == -1) { + 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); + node = OF_peer(node); + *(int *)data = lastnode = node; + break; + + case OPIOCGETCHILD: + if ((flags & FREAD) == 0) + return (EBADF); + if (node == 0) + return (EINVAL); + node = OF_child(node); + *(int *)data = lastnode = node; + break; + + default: + return (ENOTTY); + } + + free(name, M_TEMP, 0); + free(value, M_TEMP, 0); + + return (error); +}