sbdp_mbox.c revision 03831d35f7499c87d51205817c93e9a8d42c4bae
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/cpu_module.h>
#include <sys/prom_plat.h>
#include <sys/sgsbbc_mailbox.h>
#include <sys/sbd_ioctl.h>
#include <sys/sbdp_priv.h>
#include <sys/sbdp_mbox.h>
#include <sys/plat_ecc_dimm.h>
#define UNKNOWN "unknown"
#define INITL_STATUS 0xdead
int sbdp_sc_err_translation(int);
int sbdp_poweroff_wkaround = 1;
/*
* By default, DR of non-Panther procs is not allowed into a Panther
* domain with large page sizes enabled. Setting this to 0 will remove
* the restriction.
*/
static int sbdp_large_page_restriction = 1;
/*
* Initialize the data structs for the common part of the pkts
*/
void
{
}
/*
* Convert a showboard data structure to the board structure shared
* between sbd and sbdp
*/
void
{
static fn_t f = "sbdp_showbd_2_sbd_stat";
SBDP_DBG_FUNC("%s\n", f);
/*
* This should go away since the SC should put the unknown
* We leave this here so Symon and other scripts don't have
* a problem
*/
else
}
/*
* Entry point from sbd. Get the status from the SC and then convert
* the info returned into something that sbd understands
* If the request times out or fails other than an illegal transaction
* copy the info from our inventory
*/
int
{
int rv = 0;
int len;
static fn_t f = "sbdp_get_board_status";
SBDP_DBG_FUNC("%s\n", f);
/*
* Check for options. If there are any, fail the operation
*/
return (-1);
}
len = sizeof (show_board_t);
/*
* This domain has no access to this board. Return failure
*/
/*
* invalidate cached copy.
*/
return (EIO);
}
/*
* If we get any error see if we can return a cached copy of the
* board info. If one exists turn the busy flag on
*/
if (rv != 0) {
NULL);
return (EIO);
}
/*
* we have a valid copy. Return it and set the
* busy flag on so the user know this is not the most
* recent copy
*/
/*
* The sbbc returns the error in both parts (i.e rv and status)
* so since we just took care of it reset rv
*/
rv = 0;
} else {
/*
* revalidate our copy of the returned data
*/
SBDP_DBG_MBOX("HUGE ERROR\n");
} else {
}
}
SBDP_DBG_MBOX("Showboard: board\t%d\n\trevision\t%d\n\ts_cond\t%d\n\t"
"s_power\t%d\n\ts_assigned\t%d\n\ts_claimed\t%d\n\t"
"s_present\t%d\n\ts_ledstatus\t%d\n\ts_type\t%s\n\t"
"s_info\t%s\n",
/*
* Now that we got the info run through the sbd-sbdp translator
*/
/*
* Last add the platform options
*/
return (rv);
}
/*
* Entry point from sbd. Call down to the SC to assign the board
* We simply return the status the SC told us
*/
int
{
int cmd_rev = -1;
int rv = 0;
int len;
static fn_t f = "sbdp_assign_board";
SBDP_DBG_FUNC("%s\n", f);
/*
* Check for options. If there are any, fail the operation
*/
return (-1);
}
NULL);
}
return (rv);
}
/*
* Entry point from sbd. Call down to the SC to unassign the board
* We simply return the status the SC told us
*/
int
{
int cmd_rev = -1;
int rv = 0;
int len;
static fn_t f = "sbdp_unassign_board";
SBDP_DBG_FUNC("%s\n", f);
/*
* Check for options. If there are any, fail the operation
*/
return (-1);
}
NULL);
}
return (rv);
}
static int
sg_attach_board(void *arg)
{
int rv;
static fn_t f = "sg_attach_board";
SBDP_DBG_FUNC("%s\n", f);
return (rv);
}
static int
sg_detach_board(void *arg)
{
int rv;
static fn_t f = "sg_detach_board";
SBDP_DBG_FUNC("%s\n", f);
return (rv);
}
/*
* board. As a side effect the SC updates the pda info so obp can create the
* device tree. If we are successful, we ask OBP to probe the board. OBP
* creates new nodes on its own obp tree
* As an added bonus, since we don't use the inkernel prober, we need to create
* the dev_info nodes but just to a point where they are created but
* Solaris can't use them (i.e BIND)
*/
int
{
int rv = 0;
static fn_t f = "sbdp_connect_board";
SBDP_DBG_FUNC("%s\n", f);
/*
* Check for options. If there are any, fail the operation
*/
return (-1);
}
/*
* Currently, we pass the info in the extra data fields.
* This may change in the SC. We need to change it then
*/
NULL);
return (rv);
}
if (rv != 0) {
/*
* Clean up
*/
return (rv);
}
SBDP_DBG_MISC("prom attach worked\n");
/*
* XXX Until the Solaris large pages support heterogeneous cpu
* domains, DR needs to prevent the addition of non-Panther cpus
* to an all-Panther domain with large pages enabled.
*/
"UltraSPARC-IV+ board into an all UltraSPARC-IV+ domain");
(void) sbdp_disconnect_board(hp);
return (-1);
}
/*
* Now that the board has been successfully attached, obtain
* platform-specific DIMM serial id information for the board.
*/
if (SG_BOARD_IS_CPU_TYPE(board) &&
(void) plat_request_mem_sids(board);
}
return (rv);
}
/*
* Entry point from sbd. Undo the connect call. We first need to remove
* the "dummy (i.e unusable)" nodes from solaris. We then call down to OBP
* to prune its tree. After all has been cleaned up from OBP and Solaris
* SC will clear the pda entries for this board
*/
int
{
int rv = 0;
static fn_t f = "sbdp_disconnect_board";
SBDP_DBG_FUNC("%s\n", f);
SBDP_DBG_MISC("sbdp_disconnect_board: board = %d node = %d\n",
/*
* Check for options. If there are any, fail the operation
*/
return (-1);
}
return (-1);
}
if (rv == -1) {
/*
* Clean up
*/
return (rv);
}
SBDP_DBG_MISC("prom detach worked\n");
/*
* Currently, we pass the info in the extra data fields.
* This may change in the SC. We need to change it then
*/
NULL);
/* bring back the obp tree to what it was */
}
/*
* Now that the board has been successfully detached, discard
* platform-specific DIMM serial id information for the board.
*/
(void) plat_discard_mem_sids(board);
}
return (rv);
}
/*
* Entry point from sbd. Very simple. Just ask the SC to poweoff the board
* Return the status from the SC
*/
int
{
int cmd_rev = -1;
int rv = 0;
int len;
static fn_t f = "sbdp_poweroff_board";
SBDP_DBG_FUNC("%s\n", f);
/*
* Check for options. If there are any, fail the operation
*/
return (-1);
}
/*
* Can't check for bad options here since we use this for workaround
* on poweron.
*/
NULL);
}
return (rv);
}
/*
* Entry point from sbd. Ask the SC to poweron the board
* Return the status from the SC
*/
int
{
int cmd_rev = -1;
int rv = 0;
int len;
static fn_t f = "sbdp_poweron_board";
SBDP_DBG_FUNC("%s\n", f);
/*
* Check for options. If there are any, fail the operation
*/
return (-1);
}
if (SG_BOARD_IS_CPU_TYPE(board)) {
return (rv);
}
NULL);
}
return (rv);
}
int
{
char *cptr;
static fn_t f = "sbdp_get_diag";
SBDP_DBG_FUNC("%s\n", f);
return (SBDP_DIAG_NVCI);
/*
* We have args and need to process them
*/
return (SBDP_DIAG_OFF);
return (SBDP_DIAG_INIT);
return (SBDP_DIAG_QUICK);
return (SBDP_DIAG_MIN);
return (SBDP_DIAG_DEFAULT);
return (SBDP_DIAG_MEM1);
return (SBDP_DIAG_MEM2);
}
}
SBDP_DBG_MISC("error: unrecognized arg\n");
return (-1);
}
/*
* Entry point from sbd. Ask the SC to test the board. We still need to
* worry about the diag level. The user may have changed it
*
* NOTE: The flag field has 2 different meanings whether we are dealing
* means retest the board to the diag level specified. In the case of an IO
* board, it means: Perform the necessary steps to prepare the board
* for the claim without running POST at the diag level specified.
*/
int
{
int cmd_rev = -1;
int rv = 0;
int diag;
int len;
static fn_t f = "sbdp_test_board";
SBDP_DBG_FUNC("%s\n", f);
if (diag == -1) {
return (-1);
}
/*
* Only force retest on CPU boards
*/
if (SG_BOARD_IS_CPU_TYPE(board))
else {
/*
* For CPULESS IO pass the force to the SC
*/
else
}
SBDP_DBG_MISC("failed to test board: rv = %d status = %d\n",
NULL);
}
return (rv);
}
/*
* Request the SC to update POST's memory slice table by swapping
* the entries for the two board numbers given
* This is used when performing a copy-rename operation.
*/
int
{
int cmd_rev = -1;
int rv;
int len;
static fn_t f = "sbdp_swap_slices";
SBDP_DBG_FUNC("%s\n", f);
len = sizeof (swap_slices_t);
SBDP_DBG_MISC("failed to swap slices %d<->%d: rv = %d "
}
return (rv);
}
int
{
int err;
static fn_t f = "sbdp_sc_err_translation";
SBDP_DBG_FUNC("%s\n", f);
switch (error) {
err = ESGT_HW_FAIL;
break;
err = ESGT_INVAL;
break;
break;
break;
break;
break;
case SG_MBOX_STATUS_NO_MEMORY:
err = ESGT_NO_MEM;
break;
err = ESGT_NOT_SUPP;
break;
default:
err = ESGT_INTERNAL;
break;
}
return (err);
}
int
{
int rv = 0;
int len;
static fn_t f = "sbdp_stop_cpu";
SBDP_DBG_FUNC("%s\n", f);
len = sizeof (processorid_t);
}
return (rv);
}
int
{
int rv = 0;
int len;
static fn_t f = "sbdp_start_cpu";
SBDP_DBG_FUNC("%s\n", f);
}
return (rv);
}
/*
* With the SIR implementation for CPU unconfigure, this mailbox
* call is obsolete.
*/
int
{
int rv = 0;
int len;
static fn_t f = "sbdp_start_cpu_pairs";
SBDP_DBG_FUNC("%s\n", f);
}
return (rv);
}