1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER START
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The contents of this file are subject to the terms of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Common Development and Distribution License (the "License").
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You may not use this file except in compliance with the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * or http://www.opensolaris.org/os/licensing.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * See the License for the specific language governing permissions
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and limitations under the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * When distributing Covered Code, include this CDDL HEADER in each
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If applicable, add the following below this CDDL HEADER, with the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * fields enclosed by brackets "[]" replaced with your own identifying
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * information: Portions Copyright [yyyy] [name of copyright owner]
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER END
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
de81a4f48d467f6d0263221cbf4a199b6a925948jm * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Use is subject to license terms.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#pragma ident "%Z%%M% %I% %E% SMI"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/promif_impl.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/kmem.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#include <sys/machsystm.h>
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * A property attached to a node in the kernel's
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * shadow copy of the PROM device tree.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppotypedef struct prom_prop {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *pp_next;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *pp_name;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int pp_len;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo void *pp_val;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo} prom_prop_t;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * A node in the kernel's shadow copy of the PROM
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * device tree.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppotypedef struct prom_node {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnode_t pn_nodeid;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *pn_propp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_node *pn_parent;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_node *pn_child;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_node *pn_sibling;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo} prom_node_t;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic prom_node_t *promif_root;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic prom_node_t *find_node(pnode_t nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic prom_node_t *find_node_work(prom_node_t *np, pnode_t node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int getproplen(prom_node_t *pnp, char *name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void *getprop(prom_node_t *pnp, char *name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic char *nextprop(prom_node_t *pnp, char *name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifndef _KMDB
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void create_prop(prom_node_t *pnp, char *name, void *val, int len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic prom_node_t *create_node(prom_node_t *parent, pnode_t node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void create_peers(prom_node_t *pnp, pnode_t node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void create_children(prom_node_t *pnp, pnode_t parent);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Hooks for kmdb for accessing the PROM shadow tree. The driver portion
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * of kmdb will retrieve the root of the tree and pass it down to the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * debugger portion of kmdb. As the kmdb debugger is standalone, it has
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * its own promif_root pointer that it will be set to the value passed by
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * the driver so that kmdb points to the shadow tree maintained by the kernel.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * So the "get" function is in the kernel while the "set" function is in kmdb.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifdef _KMDB
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovoid
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_setroot(void *root)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo promif_root = (prom_node_t *)root;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#else
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovoid *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_getroot(void)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (promif_root);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Interfaces used internally by promif functions.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * These hide all accesses to the shadow tree.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopnode_t
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_parentnode(pnode_t nodeid)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = find_node(nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp && pnp->pn_parent) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pnp->pn_parent->pn_nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (OBP_NONODE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopnode_t
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_childnode(pnode_t nodeid)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = find_node(nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp && pnp->pn_child)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pnp->pn_child->pn_nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (OBP_NONODE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopnode_t
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_nextnode(pnode_t nodeid)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Note: next(0) returns the root node
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = find_node(nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp && (nodeid == OBP_NONODE))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pnp->pn_nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp && pnp->pn_sibling)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pnp->pn_sibling->pn_nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (OBP_NONODE);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_getproplen(pnode_t nodeid, char *name)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = find_node(nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp == NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (getproplen(pnp, name));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_getprop(pnode_t nodeid, char *name, void *value)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo void *prop;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int len;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = find_node(nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("find_node: no node?\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo len = getproplen(pnp, name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (len > 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prop = getprop(pnp, name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bcopy(prop, value, len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo } else {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("find_node: getproplen: %d\n", len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppochar *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_nextprop(pnode_t nodeid, char *name, char *next)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char *propname;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo next[0] = '\0';
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = find_node(nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp == NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo propname = nextprop(pnp, name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (propname == NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (next);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_strcpy(next, propname);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (next);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic prom_node_t *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppofind_node_work(prom_node_t *np, pnode_t node)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *nnp;
c3bc9566581e85093f7711d6fe1e718d65de42c6ae prom_node_t *snp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
c3bc9566581e85093f7711d6fe1e718d65de42c6ae for (snp = np; snp != NULL; snp = snp->pn_sibling) {
c3bc9566581e85093f7711d6fe1e718d65de42c6ae if (snp->pn_nodeid == node)
c3bc9566581e85093f7711d6fe1e718d65de42c6ae return (snp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
c3bc9566581e85093f7711d6fe1e718d65de42c6ae if (snp->pn_child)
c3bc9566581e85093f7711d6fe1e718d65de42c6ae if ((nnp = find_node_work(snp->pn_child, node)) != NULL)
c3bc9566581e85093f7711d6fe1e718d65de42c6ae return (nnp);
c3bc9566581e85093f7711d6fe1e718d65de42c6ae }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic prom_node_t *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppofind_node(pnode_t nodeid)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (nodeid == OBP_NONODE)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (promif_root);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (promif_root == NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (find_node_work(promif_root, nodeid));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic int
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppogetproplen(prom_node_t *pnp, char *name)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *propp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (propp = pnp->pn_propp; propp != NULL; propp = propp->pp_next)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_strcmp(propp->pp_name, name) == 0)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (propp->pp_len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppogetprop(prom_node_t *np, char *name)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *propp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (propp = np->pn_propp; propp != NULL; propp = propp->pp_next)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_strcmp(propp->pp_name, name) == 0)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (propp->pp_val);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic char *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fhepponextprop(prom_node_t *pnp, char *name)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *propp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * getting next of NULL or a null string returns the first prop name
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (name == NULL || *name == '\0')
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp->pn_propp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pnp->pn_propp->pp_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (propp = pnp->pn_propp; propp != NULL; propp = propp->pp_next)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_strcmp(propp->pp_name, name) == 0)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (propp->pp_next)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (propp->pp_next->pp_name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#ifndef _KMDB
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoint
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_setprop(pnode_t nodeid, char *name, void *value, int len)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *prop;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = find_node(nodeid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("find_node: no node?\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If a property with this name exists, replace the existing
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * value.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (prop = pnp->pn_propp; prop; prop = prop->pp_next)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_strcmp(prop->pp_name, name) == 0) {
de81a4f48d467f6d0263221cbf4a199b6a925948jm /*
de81a4f48d467f6d0263221cbf4a199b6a925948jm * Make sure we don't get dispatched onto a
de81a4f48d467f6d0263221cbf4a199b6a925948jm * different cpu if we happen to sleep. See
de81a4f48d467f6d0263221cbf4a199b6a925948jm * kern_postprom().
de81a4f48d467f6d0263221cbf4a199b6a925948jm */
de81a4f48d467f6d0263221cbf4a199b6a925948jm thread_affinity_set(curthread, CPU->cpu_id);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo kmem_free(prop->pp_val, prop->pp_len);
de81a4f48d467f6d0263221cbf4a199b6a925948jm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prop->pp_val = NULL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (len > 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prop->pp_val = kmem_zalloc(len, KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bcopy(value, prop->pp_val, len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
de81a4f48d467f6d0263221cbf4a199b6a925948jm thread_affinity_clear(curthread);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prop->pp_len = len;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (len);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (-1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/*
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Create a promif private copy of boot's device tree.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppovoid
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_stree_init(void)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnode_t node;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo node = prom_rootnode();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo promif_root = pnp = create_node(OBP_NONODE, node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo create_peers(pnp, node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo create_children(pnp, node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppocreate_children(prom_node_t *pnp, pnode_t parent)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *cnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnode_t child;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(CONSTCOND)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo child = prom_childnode(parent);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (child == 0)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_getproplen(child, "name") <= 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo parent = child;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo cnp = create_node(pnp, child);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp->pn_child = cnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo create_peers(cnp, child);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = cnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo parent = child;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppocreate_peers(prom_node_t *np, pnode_t node)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnode_t peer;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(CONSTCOND)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo peer = prom_nextnode(node);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (peer == 0)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_getproplen(peer, "name") <= 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo node = peer;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = create_node(np->pn_parent, peer);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo np->pn_sibling = pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo create_children(pnp, peer);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo np = pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo node = peer;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic prom_node_t *
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppocreate_node(prom_node_t *parent, pnode_t node)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_node_t *pnp;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char prvname[OBP_MAXPROPNAME];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo char propname[OBP_MAXPROPNAME];
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int proplen;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo void *propval;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm /*
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm * Make sure we don't get dispatched onto a different
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm * cpu if we happen to sleep. See kern_postprom().
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm */
de81a4f48d467f6d0263221cbf4a199b6a925948jm thread_affinity_set(curthread, CPU->cpu_id);
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp = kmem_zalloc(sizeof (prom_node_t), KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp->pn_nodeid = node;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp->pn_parent = parent;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prvname[0] = '\0';
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo _NOTE(CONSTCOND)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (1) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_nextprop(node, prvname, propname);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (prom_strlen(propname) == 0)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo break;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((proplen = prom_getproplen(node, propname)) == -1)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo continue;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo propval = NULL;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (proplen != 0) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo propval = kmem_zalloc(proplen, KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_getprop(node, propname, propval);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo create_prop(pnp, propname, propval, proplen);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_strcpy(prvname, propname);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm thread_affinity_clear(curthread);
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (pnp);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppocreate_prop(prom_node_t *pnp, char *name, void *val, int len)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *prop;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo struct prom_prop *newprop;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm /*
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm * Make sure we don't get dispatched onto a different
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm * cpu if we happen to sleep. See kern_postprom().
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm */
de81a4f48d467f6d0263221cbf4a199b6a925948jm thread_affinity_set(curthread, CPU->cpu_id);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo newprop = kmem_zalloc(sizeof (*newprop), KM_SLEEP);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo newprop->pp_name = kmem_zalloc(prom_strlen(name) + 1, KM_SLEEP);
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm thread_affinity_clear(curthread);
a47315d76ac34b1416ba8bd333c4d3b7ee54a56bjm
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) prom_strcpy(newprop->pp_name, name);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo newprop->pp_val = val;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo newprop->pp_len = len;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp->pn_propp == NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo pnp->pn_propp = newprop;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* move to the end of the prop list */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (prop = pnp->pn_propp; prop->pp_next != NULL; prop = prop->pp_next)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* empty */;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* append the new prop */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prop->pp_next = newprop;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic void
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppopromif_dump_tree(prom_node_t *pnp)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo{
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int i;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo static int level = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp == NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < level; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf(" ");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo prom_printf("Node 0x%x (parent=0x%x, sibling=0x%x)\n", pnp->pn_nodeid,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (pnp->pn_parent) ? pnp->pn_parent->pn_nodeid : 0,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (pnp->pn_sibling) ? pnp->pn_sibling->pn_nodeid : 0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp->pn_child != NULL) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo level++;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo promif_dump_tree(pnp->pn_child);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo level--;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo }
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (pnp->pn_sibling != NULL)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo promif_dump_tree(pnp->pn_sibling);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo}
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif