03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgsbbc.h> /* To get fn_t type definition */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Config information
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Enable or disable dr
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* name properties for some Serengeti device nodes */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* last item must be blank */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * In the case of a busy mbox, if a status cmd comes in we return a cached
03831d35f7499c87d51205817c93e9a8d42c4baestevel * copy. This cache is a link list of wnodes that contains bd structs with
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the appropriate info. When a new wnode is created a whole entry is added
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to the list.
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_wnode_t *first_node = NULL; /* first wnode. Entry to the link list */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint cur_num_wnodes = 0; /* how many nodes are currently running */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Macros to access fields in the previous array */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Prototypes
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Module linkage information for the kernel.
03831d35f7499c87d51205817c93e9a8d42c4baestevel "Serengeti sbdp",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * VA area used during CPU shutdown.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Mutex to protect our inventory
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (e != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (e);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_shutdown_va = vmem_alloc(heap_arena, PAGESIZE, VM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_valp = (uint64_t *)vmem_alloc(static_alloc_arena,
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&sbdp_wnode_mutex, NULL, MUTEX_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (e);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Remove the module.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (e != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (e);
03831d35f7499c87d51205817c93e9a8d42c4baestevel vmem_free(static_alloc_arena, (void *)sbdp_valp, sizeof (uint64_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (e);
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_get_bd_and_wnode_num(pnode_t nodeid, int *bd, int *wnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * decode the board number
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_get_board_num(sbdp_handle_t *hp, dev_info_t *dip)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Portid has encoded the nodeid and the agent id. The top
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 4 bits are correspond to the wcnodeid and the lower 5 are the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * agent id.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Each agent id represents a physical location hence we can
03831d35f7499c87d51205817c93e9a8d42c4baestevel * obtain the board number
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sbdp_get_bd_and_wnode_num(nodeid, &bd, &wnode) < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (&sbdp_devattr[0]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prom_getprop(nodeid, "device_type", (caddr_t)dev_type) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check to see if this is a cpci node
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cpci nodes are assign unit nums of 5 for now
03831d35f7499c87d51205817c93e9a8d42c4baestevel * So they don't conflict with the pci unit nums
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (4);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prom_getprop(nodeid, "portid", (caddr_t)&portid) <= 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (len <= 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prom_getprop(nodeid, "reg", (caddr_t)regs) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_get_mem_dip(pnode_t node, void *arg, uint_t flags)
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct sbdp_mem_dip *smdp = (struct sbdp_mem_dip *)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We need to find the dip only for the first nodeid
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Update the board info. Required after a copy rename
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Grab the lock
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we get the top nodes here. This will have a side effect of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * updating the present bit for cpus
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_walk_prom_tree(prom_rootnode(), sbdp_select_top_nodes,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We need to clear nnum since we are looking again for the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If a dip is found by sbdp_get_mem_dip(), it will be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * returned held
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_walk_prom_tree(prom_rootnode(), sbdp_get_mem_dip, &smd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel hp->h_err = kmem_zalloc(sizeof (*hp->h_err), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if the board doesn't have banks initialize them,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * otherwise we assume they have been updated if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * necessary
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sbdphw_get_base_physaddr(hp, smd.dip, &bdp->bpa))
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize the board struct. This remains cached. We update it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * every time we have a successful show_board and after a copy-rename
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&bdp->bd_mutex, NULL, MUTEX_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bdp->bd_sc = (show_board_t *)kmem_zalloc(sizeof (show_board_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This entry is going away. Clean up
03831d35f7499c87d51205817c93e9a8d42c4baestevel * A new wnode has arrived. Initialize the struct and create
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the board structures.
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_wnode_init(sbdp_wnode_t *wnodep, int wnode, int boards)
03831d35f7499c87d51205817c93e9a8d42c4baestevel wnodep->bds = kmem_zalloc(sizeof (sbdp_bd_t) * boards, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < boards; i++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Wnode got DRed out. Clean up all the node stuff including the boards
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < boards; i++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add all the necessary fields to this board's struct
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This board has gone away. Clean the necessary fields
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("cleaning up bd info for bd %d\n", board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Grab the lock
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Traverse the list looking for wnode. Return it when found
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0, cur = first_node; i < cur_num_wnodes; i++,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Insert this brand new node into our master list. It leaves it all
03831d35f7499c87d51205817c93e9a8d42c4baestevel * initialized
03831d35f7499c87d51205817c93e9a8d42c4baestevel wnodep = kmem_zalloc(sizeof (sbdp_wnode_t), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This node is gone. Remove it from the list and also clean up
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. This is called when a new node is added. We
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create an entry in our inventory and initialize all the stuff that will be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We get this directly from ssm
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("sbdp_setup_instance: instance %d wnode %d\n", instance,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This node has not been instanstiated
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create one
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. This is called when a node has been removed (or is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * going away. We do all the necessary cleanup
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ssm should have set this up
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("sbdp_teardown_instance: instance %d wnode %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find this node and then remove it
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_release_component(sbdp_handle_t *hp, dev_info_t *dip)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Serengeti DR passthrus are for debugging purposes only.
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* the following line must always be last */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_ioctl(sbdp_handle_t *hp, sbdp_ioctl_arg_t *sbdpi)
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_ioctl_arg_t *sbdi = (sbd_ioctl_arg_t *)sbdpi->h_iap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_copyin(sbdi->i_opts, buf, sbdi->i_len, sbdpi->h_mode)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check the dnode we obtained. Need to find a better way to determine
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if the node has the correct starting address
03831d35f7499c87d51205817c93e9a8d42c4baestevel return ((node == OBP_NONODE) || (node == OBP_BADNODE) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Retrieve the information we have on this board from
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the inventory
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((wnodep == NULL) || ((board < 0) && (board > max_bds))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We might not have the complete bd info. With cheetah we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cannot access the memory decode registers when then cpu is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * in reset. If the mem info is incomplete, then we try to gather it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * There are certain cases where obp marks components as failed
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the status is ok the node won't have any status property. It
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is only there if the status is other than ok.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prom_getprop(nodeid, (char *)status, status_buf) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(status_buf, failed, strlen(failed)) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_cpu_in_reset(int node, int bd, int unit, int reset)
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("marking cpu %d %s for board %d\n", unit,
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);