03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
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 *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
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 *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cpuvar.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cpu_module.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kmem.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/param.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/obpdefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/prom_plat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgsbbc_mailbox.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbd_ioctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbdp_priv.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbdp_mbox.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/promif.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/plat_ecc_dimm.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define UNKNOWN "unknown"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define INITL_STATUS 0xdead
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint sbdp_mbox_wait = 86400; /* in seconds */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint sbdp_shw_bd_wait = 5; /* in seconds */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint sbdp_sc_err_translation(int);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint sbdp_poweroff_wkaround = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * By default, DR of non-Panther procs is not allowed into a Panther
03831d35f7499c87d51205817c93e9a8d42c4baestevel * domain with large page sizes enabled. Setting this to 0 will remove
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the restriction.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sbdp_large_page_restriction = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize the data structs for the common part of the pkts
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_init_msg_pkt(sbbc_msg_t *msg, uint16_t sub_type, int len, caddr_t buf)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg->msg_type.type = DR_MBOX;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg->msg_type.sub_type = sub_type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg->msg_status = INITL_STATUS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg->msg_len = len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg->msg_buf = buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg->msg_data[0] = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg->msg_data[1] = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Convert a showboard data structure to the board structure shared
03831d35f7499c87d51205817c93e9a8d42c4baestevel * between sbd and sbdp
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_showbd_2_sbd_stat(show_board_t *shbp, sbd_stat_t *stp, int board)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_showbd_2_sbd_stat";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_board = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strcpy(stp->s_info, shbp->s_info);
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_power = shbp->s_power;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strcpy(stp->s_type, shbp->s_type);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (shbp->s_present == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This should go away since the SC should put the unknown
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We leave this here so Symon and other scripts don't have
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a problem
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strcpy(stp->s_type, UNKNOWN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_rstate = SBD_STAT_EMPTY;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (shbp->s_claimed == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_rstate = SBD_STAT_DISCONNECTED;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_rstate = SBD_STAT_CONNECTED;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_assigned = shbp->s_assigned;
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_cond = shbp->s_cond;
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. Get the status from the SC and then convert
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the info returned into something that sbd understands
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the request times out or fails other than an illegal transaction
03831d35f7499c87d51205817c93e9a8d42c4baestevel * copy the info from our inventory
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_get_board_status(sbdp_handle_t *hp, sbd_stat_t *stp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel info_t inform, *informp = &inform;
03831d35f7499c87d51205817c93e9a8d42c4baestevel show_board_t show_bd, *shbp = &show_bd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_bd_t *bdp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_get_board_status";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for options. If there are any, fail the operation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bdp = sbdp_get_bd_info(node, board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->board = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->node = node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->revision = 0xdead;
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_SHOW_BOARD, len, (caddr_t)informp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero(shbp, sizeof (show_board_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel shbp->s_cond = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel shbp->s_power = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel shbp->s_assigned = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel shbp->s_claimed = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel shbp->s_present = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (show_board_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_SHOW_BOARD, len, (caddr_t)shbp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_shw_bd_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("show board completed: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This domain has no access to this board. Return failure
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((resp->msg_status == SG_MBOX_STATUS_BOARD_ACCESS_DENIED) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel (resp->msg_status == SG_MBOX_STATUS_ILLEGAL_SLOT) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel (resp->msg_status == SG_MBOX_STATUS_ILLEGAL_NODE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * invalidate cached copy.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bdp->valid_cp = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESGT_GET_BOARD_STAT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we get any error see if we can return a cached copy of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * board info. If one exists turn the busy flag on
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&bdp->bd_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bdp->valid_cp == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESGT_GET_BOARD_STAT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&bdp->bd_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we have a valid copy. Return it and set the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * busy flag on so the user know this is not the most
03831d35f7499c87d51205817c93e9a8d42c4baestevel * recent copy
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(bdp->bd_sc, shbp, sizeof (show_board_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&bdp->bd_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel stp->s_busy = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The sbbc returns the error in both parts (i.e rv and status)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so since we just took care of it reset rv
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * revalidate our copy of the returned data
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bdp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MBOX("HUGE ERROR\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&bdp->bd_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(shbp, bdp->bd_sc, sizeof (show_board_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel bdp->valid_cp = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&bdp->bd_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MBOX("Showboard: board\t%d\n\trevision\t%d\n\ts_cond\t%d\n\t"
03831d35f7499c87d51205817c93e9a8d42c4baestevel "s_power\t%d\n\ts_assigned\t%d\n\ts_claimed\t%d\n\t"
03831d35f7499c87d51205817c93e9a8d42c4baestevel "s_present\t%d\n\ts_ledstatus\t%d\n\ts_type\t%s\n\t"
03831d35f7499c87d51205817c93e9a8d42c4baestevel "s_info\t%s\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel board, shbp->revision, shbp->s_cond, shbp->s_power,
03831d35f7499c87d51205817c93e9a8d42c4baestevel shbp->s_assigned, shbp->s_claimed, shbp->s_present,
03831d35f7499c87d51205817c93e9a8d42c4baestevel shbp->s_ledstatus, shbp->s_type, shbp->s_info);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now that we got the info run through the sbd-sbdp translator
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_showbd_2_sbd_stat(shbp, stp, board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Last add the platform options
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_PLATFORM_OPTS(stp->s_platopts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. Call down to the SC to assign the board
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We simply return the status the SC told us
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_assign_board(sbdp_handle_t *hp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int cmd_rev = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel info2_t inform, *informp = &inform;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_assign_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for options. If there are any, fail the operation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->board = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->node = node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->extra = SBDP_ASSIGN;
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (info2_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_ASSIGN, len, (caddr_t)informp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_ASSIGN, len, (caddr_t)&cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to assign board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. Call down to the SC to unassign the board
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We simply return the status the SC told us
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_unassign_board(sbdp_handle_t *hp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int cmd_rev = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel info2_t inform, *informp = &inform;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_unassign_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for options. If there are any, fail the operation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->board = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->node = node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->extra = SBDP_UNASSIGN;
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (info2_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_ASSIGN, len, (caddr_t)informp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_ASSIGN, len, (caddr_t)&cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to unassign board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsg_attach_board(void *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_handle_t *hp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cpuset_t cset;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sg_attach_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel hp = (sbdp_handle_t *)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel cset = cpu_ready_set;
03831d35f7499c87d51205817c93e9a8d42c4baestevel promsafe_xc_attention(cset);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = prom_serengeti_attach_board(hp->h_wnode, hp->h_board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel xc_dismissed(cset);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsg_detach_board(void *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_handle_t *hp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cpuset_t cset;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sg_detach_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel hp = (sbdp_handle_t *)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel cset = cpu_ready_set;
03831d35f7499c87d51205817c93e9a8d42c4baestevel promsafe_xc_attention(cset);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = prom_serengeti_detach_board(hp->h_wnode, hp->h_board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel xc_dismissed(cset);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. First we call down to the SC to "attach/claim" this
03831d35f7499c87d51205817c93e9a8d42c4baestevel * board. As a side effect the SC updates the pda info so obp can create the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * device tree. If we are successful, we ask OBP to probe the board. OBP
03831d35f7499c87d51205817c93e9a8d42c4baestevel * creates new nodes on its own obp tree
03831d35f7499c87d51205817c93e9a8d42c4baestevel * As an added bonus, since we don't use the inkernel prober, we need to create
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the dev_info nodes but just to a point where they are created but
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Solaris can't use them (i.e BIND)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_connect_board(sbdp_handle_t *hp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board, node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_connect_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel int panther_pages_enabled;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for options. If there are any, fail the operation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Currently, we pass the info in the extra data fields.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This may change in the SC. We need to change it then
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_CLAIM, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_data[0] = node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_data[1] = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_CLAIM, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to claim board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = prom_tree_update(sg_attach_board, hp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to prom attach board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESGT_PROM_ATTACH, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Clean up
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_data[0] = node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_data[1] = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("prom attach worked\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_attach_bd(node, board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * XXX Until the Solaris large pages support heterogeneous cpu
03831d35f7499c87d51205817c93e9a8d42c4baestevel * domains, DR needs to prevent the addition of non-Panther cpus
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to an all-Panther domain with large pages enabled.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel panther_pages_enabled = (page_num_pagesizes() > DEFAULT_MMU_PAGE_SIZES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sbdp_board_non_panther_cpus(node, board) > 0 &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel panther_pages_enabled && sbdp_large_page_restriction) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Domain shutdown is required to add a non-"
03831d35f7499c87d51205817c93e9a8d42c4baestevel "UltraSPARC-IV+ board into an all UltraSPARC-IV+ domain");
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sbdp_disconnect_board(hp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESGT_NOT_SUPP, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now that the board has been successfully attached, obtain
03831d35f7499c87d51205817c93e9a8d42c4baestevel * platform-specific DIMM serial id information for the board.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (SG_BOARD_IS_CPU_TYPE(board) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel plat_ecc_capability_sc_get(PLAT_ECC_DIMM_SID_MESSAGE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) plat_request_mem_sids(board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. Undo the connect call. We first need to remove
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the "dummy (i.e unusable)" nodes from solaris. We then call down to OBP
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to prune its tree. After all has been cleaned up from OBP and Solaris
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We call the SC to "detach/unclain" the board. A side effect is that the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SC will clear the pda entries for this board
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_disconnect_board(sbdp_handle_t *hp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board, node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_disconnect_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("sbdp_disconnect_board: board = %d node = %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel board, node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for options. If there are any, fail the operation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sbdp_detach_bd(node, board, sep)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_attach_bd(node, board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_ALL("failed to detach board %d\n", board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = prom_tree_update(sg_detach_board, hp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Clean up
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_attach_bd(node, board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to prom detach board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESGT_PROM_DETACH, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("prom detach worked\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Currently, we pass the info in the extra data fields.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This may change in the SC. We need to change it then
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_data[0] = node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_data[1] = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to unclaim board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* bring back the obp tree to what it was */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) prom_tree_update(sg_attach_board, hp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now that the board has been successfully detached, discard
03831d35f7499c87d51205817c93e9a8d42c4baestevel * platform-specific DIMM serial id information for the board.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!rv && SG_BOARD_IS_CPU_TYPE(board) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel plat_ecc_capability_sc_get(PLAT_ECC_DIMM_SID_MESSAGE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) plat_discard_mem_sids(board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. Very simple. Just ask the SC to poweoff the board
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Return the status from the SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_poweroff_board(sbdp_handle_t *hp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int cmd_rev = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel info2_t inform, *informp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_poweroff_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for options. If there are any, fail the operation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Can't check for bad options here since we use this for workaround
03831d35f7499c87d51205817c93e9a8d42c4baestevel * on poweron.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp = &inform;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->extra = SBDP_POWER_OFF;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (info2_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_POWER, len, (caddr_t)informp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_POWER, len, (caddr_t)&cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to poweroff board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. Ask the SC to poweron the board
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Return the status from the SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_poweron_board(sbdp_handle_t *hp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int cmd_rev = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel info2_t inform, *informp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_poweron_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for options. If there are any, fail the operation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sbdp_poweroff_wkaround)
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (SG_BOARD_IS_CPU_TYPE(board)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rv = sbdp_poweroff_board(hp)) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp = &inform;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->extra = SBDP_POWER_ON;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (info2_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_POWER, len, (caddr_t)informp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_POWER, len, (caddr_t)&cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to poweron board: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_get_diag(sbdp_opts_t *opts)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *cptr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_get_diag";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((opts == NULL) || (opts->copts == NULL))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_NVCI);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((cptr = strstr(opts->copts, "diag=")) != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We have args and need to process them
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel cptr += strlen("diag=");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(cptr, "off", sizeof ("off")) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_OFF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strncmp(cptr, "init", sizeof ("init")) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_INIT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strncmp(cptr, "quick", sizeof ("quick")) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_QUICK);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strncmp(cptr, "min", sizeof ("min")) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_MIN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strncmp(cptr, "default", sizeof ("default")) == 0 ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel strncmp(cptr, "max", sizeof ("max")) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_DEFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strncmp(cptr, "mem1", sizeof ("mem1")) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_MEM1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strncmp(cptr, "mem2", sizeof ("mem2")) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SBDP_DIAG_MEM2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("error: unrecognized arg\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Entry point from sbd. Ask the SC to test the board. We still need to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * worry about the diag level. The user may have changed it
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * NOTE: The flag field has 2 different meanings whether we are dealing
03831d35f7499c87d51205817c93e9a8d42c4baestevel * with a cpu/mem board or an io board. In the case of a cpu/mem board it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * means retest the board to the diag level specified. In the case of an IO
03831d35f7499c87d51205817c93e9a8d42c4baestevel * board, it means: Perform the necessary steps to prepare the board
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for the claim without running POST at the diag level specified.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_test_board(sbdp_handle_t *hp, sbdp_opts_t *opts)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board = hp->h_board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int node = hp->h_wnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int cmd_rev = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel testb_t inform, *informp = &inform;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbd_error_t *sep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int diag;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_test_board";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sep = hp->h_err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel diag = sbdp_get_diag(opts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (diag == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, ESBD_INVAL_OPT, opts != NULL ?
03831d35f7499c87d51205817c93e9a8d42c4baestevel opts->copts : NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("Diag level is 0x%x\n", diag);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->info.board = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->info.node = node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->info.extra = diag;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Only force retest on CPU boards
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (SG_BOARD_IS_CPU_TYPE(board))
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->flag = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For CPULESS IO pass the force to the SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (hp->h_flags & SBDP_IOCTL_FLAG_FORCE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->flag = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->flag = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (testb_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_TEST_BD, len, (caddr_t)informp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_TEST_BD, len, (caddr_t)&cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to test board: rv = %d status = %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv, resp->msg_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = resp->msg_status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Request the SC to update POST's memory slice table by swapping
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the entries for the two board numbers given
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This is used when performing a copy-rename operation.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_swap_slices(int bd1, int bd2)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int cmd_rev = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel swap_slices_t inform, *informp = &inform;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_swap_slices";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->board1 = bd1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel informp->board2 = bd2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (swap_slices_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_SWAP_SLICES, len, (caddr_t)informp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_SWAP_SLICES, len, (caddr_t)&cmd_rev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to swap slices %d<->%d: rv = %d "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "status = %d\n", bd1, bd2, rv, resp->msg_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbdp_sc_err_translation(resp->msg_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_sc_err_translation(int error)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_sc_err_translation";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (error) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_HARDWARE_FAILURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_HW_FAIL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_ILLEGAL_PARAMETER:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_ILLEGAL_NODE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_ILLEGAL_SLOT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_INVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_BOARD_ACCESS_DENIED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_BD_ACCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_STALE_CONTENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_STALE_CMP;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_STALE_OBJECT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_STALE_OBJ;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NO_SEPROM_SPACE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_NO_SEPROM_SPACE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NO_MEMORY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_NO_MEM;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NOT_SUPPORTED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_NOT_SUPP;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_COMMAND_FAILURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ESGT_INTERNAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_stop_cpu(processorid_t cpu)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_stop_cpu";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (processorid_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_STOP_CPU, len, (caddr_t)&cpu);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_STOP_CPU, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to stop cpu: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_start_cpu(processorid_t cpu)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_start_cpu";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cpu);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_START_CPU, len, (caddr_t)&cpu);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_START_CPU, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to start cpu: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * With the SIR implementation for CPU unconfigure, this mailbox
03831d35f7499c87d51205817c93e9a8d42c4baestevel * call is obsolete.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_start_cpu_pairs(processorid_t cpu)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sbdp_start_cpu_pairs";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_FUNC("%s\n", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel len = sizeof (cpu);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(reqp, DR_MBOX_START_CPU_PAIRS, len, (caddr_t)&cpu);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_init_msg_pkt(resp, DR_MBOX_START_CPU_PAIRS, 0, (caddr_t)NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_MISC("failed to start cpu pair: rv = %d\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}