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 * This file contains the Starcat Solaris Mailbox Client module. This module
03831d35f7499c87d51205817c93e9a8d42c4baestevel * handles mailbox messages from the SC to the OS (as opposed to messages sent
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to specific drivers) and vice versa. Two task queues are created upon
03831d35f7499c87d51205817c93e9a8d42c4baestevel * startup; one handles reading and processing of all incoming messages, while
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the other handles transmission of all outgoing messages.
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* mailbox keys */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* mailbox commands */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_ENVIRON (SCDM_CMD | 0x4) /* environmental intr */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_SHUTDOWN (SCDM_CMD | 0x5) /* setkeyswitch STANDBY */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_GET_NODENAME (SCDM_CMD | 0x6) /* get domain nodename */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_LOG_ECC_ERROR (SCDM_CMD | 0x7) /* ECC error logging */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_LOG_ECC_INDICTMENT (SCDM_CMD | 0x8) /* ECC indictment logging */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_LOG_ECC_CAP_INIT (SCDM_CMD | 0xa) /* ECC Capability Init */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_LOG_ECC_CAP_RESP (SCDM_CMD | 0xb) /* ECC Capability Response */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_DIMM_SERIAL_ID (SCDM_CMD | 0xc) /* DIMM ser# req/resp */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_DP_ERROR_MSG (SCDM_CMD | 0xd) /* datapath error */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCDM_DP_FAULT_MSG (SCDM_CMD | 0xe) /* datapath fault */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* general constants */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When a message needs to be sent to the SC, an scosmb_msgdata_t should be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * populated with the data to be used for the message, and a call to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_process_output should be dispatched on the scosmb_output_taskq, with
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the address of the scosmb_msgdata_t structure as its arg. The "length" and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * "data" fields can be used if the message needs to include data beyond the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * header fields (type, cmd, and transid) and that information must be recorded
03831d35f7499c87d51205817c93e9a8d42c4baestevel * when the message is placed on the taskq. If appropriate for the message type
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (e.g. nodename info that should always be the most recent available), the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * "data" field can be set to NULL and the additional data can be assembled
03831d35f7499c87d51205817c93e9a8d42c4baestevel * immediately prior to sending the message in scosmb_process_output().
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If log_error is set, any errors in delivering the message cause a
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cmn_err() message to be issued. If it is zero, the error is expressed
03831d35f7499c87d51205817c93e9a8d42c4baestevel * only through return values.
03831d35f7499c87d51205817c93e9a8d42c4baesteveltypedef struct {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Datapath error and fault messages arrive unsolicited. The message data
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is contained in a plat_datapath_info_t structure.
03831d35f7499c87d51205817c93e9a8d42c4baesteveltypedef struct {
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t t_value; /* SERD timeout threshold (seconds) */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* externally visible routines */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* local routines */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int scosmb_process_output(scosmb_msgdata_t *arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* local variables */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Structures from modctl.h used for loadable module support.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SCOSMB is a "miscellaneous" module.
03831d35f7499c87d51205817c93e9a8d42c4baestevel "Sun Fire 15000 OS Mbox Client v1.10",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Loadable module support routine. Initializes mutex and condition variables
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and starts thread.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize the mailboxes
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s mboxsc_init failed (0x%x)\n", scosmb_hdr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((error = mboxsc_init(DMSC_KEY, MBOXSC_MBOX_OUT, NULL)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s mboxsc_init failed (0x%x)\n", scosmb_hdr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize the global lock
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&scosmb_mutex, NULL, MUTEX_DEFAULT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Create the task queues used for processing input and output messages
03831d35f7499c87d51205817c93e9a8d42c4baestevel scosmb_input_taskq = taskq_create("scosmb_input_taskq", 1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel minclsyspri, MIN_INPUTQ_TASKS, MAX_INPUTQ_TASKS, TASKQ_PREPOPULATE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel scosmb_output_taskq = taskq_create("scosmb_output_taskq", 1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Attempt to install the module. If unsuccessful, uninitialize
03831d35f7499c87d51205817c93e9a8d42c4baestevel * everything.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (error != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Loadable module support routine. Since this routine shouldn't be unloaded (it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * provides a critical service, and its symbols may be referenced externally),
03831d35f7499c87d51205817c93e9a8d42c4baestevel * EBUSY is returned to prevent unloading.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Loadable module support routine.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_inbox_handler() - mbox API event handler.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This routine adds an entry to the scosmb_input_taskq that will cause the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_process_input() routine to be called to service the SCDM mailbox. The
03831d35f7499c87d51205817c93e9a8d42c4baestevel * possibility that taskq_dispatch may fail when given KM_NOSLEEP is safely
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ignored because there can only be one message waiting in the mailbox at any
03831d35f7499c87d51205817c93e9a8d42c4baestevel * given time, so the current message will end up being handled by one of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * previously queued jobs (and a previous message presumably timed out before we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * got around to reading it).
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) taskq_dispatch(scosmb_input_taskq, scosmb_process_input, NULL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dp_get_cores()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Checks cpu implementation for the input cpuid and returns
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the number of cores.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If implementation cannot be determined, returns 1
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find first with valid implementation */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dp_payload_add_cpus()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * From datapath mailbox message, determines the number of and safari IDs
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for affected cpus, then adds this info to the datapath ereport.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Input maxcat (if set) is a count of maxcat cpus actually present - it is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a count of cpuids, which takes into account multi-core architecture.
03831d35f7499c87d51205817c93e9a8d42c4baesteveldp_payload_add_cpus(plat_datapath_info_t *dpmsg, nvlist_t *erp, int maxcat)
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check for multiple core architectures */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Determine the number of cpu cores impacted
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SC-DE supplies the base cpuid affected, if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * maxcat id was given, there's no slot 0 board
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Slot 0 id was given - set numcpus */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* there may/may not be maxcats. set a count anyway */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Allocate space for cores */
03831d35f7499c87d51205817c93e9a8d42c4baestevel dparray = kmem_zalloc(num * sizeof (uint16_t *), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * populate dparray with impacted cores (only those present)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For a CDS error, it's the reporting cpuid
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and it's other core (if present)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For a DX error, it's the reporting cpuid (all
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cores), and the other CPU sharing the same
03831d35f7499c87d51205817c93e9a8d42c4baestevel * DX<-->DCDS interface (all cores)
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* reporting cpuid */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find partner cpuid */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* add partner cpuid */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For an EX error, it is all cpuids (all cores)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * on the reporting board
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For a CP error, it is all cpuids (all cores)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * on both boards (SB & IO) in the boardset
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Do slot 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Do slot 1 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The datapath message could not be associated with any
03831d35f7499c87d51205817c93e9a8d42c4baestevel * configured CPU.
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel snarray = kmem_zalloc(jj * sizeof (uint64_t *), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret |= nvlist_add_uint16_array(erp, DP_LIST, dparray, jj);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret |= nvlist_add_uint64_array(erp, SN_LIST, snarray, jj);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dp_trans_event() - datapath message handler.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Process datapath error and fault messages received from the SC. Checks
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for, and disregards, messages associated with I/O boards. Otherwise,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * extracts message info to produce a datapath ereport.
03831d35f7499c87d51205817c93e9a8d42c4baesteveldp_trans_event(plat_datapath_info_t *dpmsg, int msgtype)
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check for I/O board message */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < STARCAT_SLOT1_CPU_MAX; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* maxcat cpu present */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Ignore I/O board msg
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate space for ereport */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Member Name Data Type Comments
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ----------- --------- -----------
03831d35f7499c87d51205817c93e9a8d42c4baestevel * version uint8 0
03831d35f7499c87d51205817c93e9a8d42c4baestevel * class string "asic"
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ENA uint64 ENA Format 1
03831d35f7499c87d51205817c93e9a8d42c4baestevel * detector fmri aggregated ID data for SC-DE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Datapath ereport subclasses and data payloads:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * There will be two types of ereports (error and fault) which will be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * identified by the "type" member.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ereport.asic.starcat.dx.dx-dp
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Member Name Data Type Comments
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ----------- --------- -----------
03831d35f7499c87d51205817c93e9a8d42c4baestevel * erptype uint16 derived from message type: error or
03831d35f7499c87d51205817c93e9a8d42c4baestevel * t-value uint32 SC's datapath SERD timeout threshold
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dp-list-sz uint8 number of dp-list array elements
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dp-list array of uint16 Safari IDs of affected cpus
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sn-list array of uint64 Serial numbers of affected cpus
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* compose common ereport elements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Create legacy FMRI for the detector
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_add_string(hcelem, FM_FMRI_HC_NAME, FM_FMRI_LEGACY_HC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_add_string(hcelem, FM_FMRI_HC_ID, buf);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_add_uint8(detector, FM_VERSION, FM_HC_SCHEME_VERSION);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_add_string(detector, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_add_string(detector, FM_FMRI_HC_ROOT, "");
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_add_uint32(detector, FM_FMRI_HC_LIST_SZ, 1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_add_nvlist_array(detector, FM_FMRI_HC_LIST, &hcelem, 1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* build ereport class name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buf, FM_MAX_CLASS, "asic.starcat.%s.%s-%s",
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki dperrtype[dpmsg->type], dperrtype[dpmsg->type],
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki fm_ena_generate(0, FM_ENA_FMT1), detector, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* add payload elements */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki DP_EREPORT_TYPE, DATA_TYPE_UINT16, DP_ERROR, NULL);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki DP_EREPORT_TYPE, DATA_TYPE_UINT16, DP_FAULT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel fm_payload_set(erp, DP_TVALUE, DATA_TYPE_UINT32, dpmsg->t_value, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* post ereport */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free ereport memory */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_process_input() - incoming message processing routine
03831d35f7499c87d51205817c93e9a8d42c4baestevel * this routine attempts to read a message from the SCDM mailbox and, if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * successful, processes the command. if an unrecoverable error is encountered,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the scosmb_task thread will be terminated.
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel plat_capability_data_t *cap; /* capability msg contents ptr */
03831d35f7499c87d51205817c93e9a8d42c4baestevel scosmb_msgdata_t *cap_msgdatap; /* capability msg response */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Attempt to read a message from the SCDM mailbox.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Setup a local buffer to read incoming messages from the SC.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cap_ver_len = strlen(utsname.release) + strlen(utsname.version) + 2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cap_size = sizeof (plat_capability_data_t) + cap_ver_len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_size = MAX(cap_size, sizeof (plat_dimm_sid_board_data_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel error = mboxsc_getmsg(SCDM_KEY, &msg.type, &msg.cmd, &msg.transid,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If EAGAIN or ETIMEDOUT was received, give up. The SC can just try
03831d35f7499c87d51205817c93e9a8d42c4baestevel * again if it was important. If any other non-zero error was
03831d35f7499c87d51205817c93e9a8d42c4baestevel * encountered, the mailbox service is broken, and there's nothing more
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we can do.
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (error != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The mailbox service appears to be badly broken. If it was
03831d35f7499c87d51205817c93e9a8d42c4baestevel * working previously, generate a warning and set a flag to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * avoid repeating the warning on subsequent failures.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s mboxsc error (0x%x)\n", scosmb_hdr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the mailbox module failed previously, it appears to have
03831d35f7499c87d51205817c93e9a8d42c4baestevel * recovered, so we'll want to generate a warning if it fails
03831d35f7499c87d51205817c93e9a8d42c4baestevel * A message was successfully received, so go ahead and process it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_PANIC, "%s SC requested PANIC\n", scosmb_hdr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s SC requested a shutdown ", scosmb_hdr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * In the event kadmin does not bring down the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * domain, environmental shutdown is forced
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*FALLTHROUGH*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Send SIGPWR to init(1) it will run rc0,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * which will uadmin to power down.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we're still booting and init(1) isn't set up yet,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * simply halt.
03831d35f7499c87d51205817c93e9a8d42c4baestevel extern void halt(char *);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * else, graceful shutdown with inittab and all
03831d35f7499c87d51205817c93e9a8d42c4baestevel * getting involved
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The SC has responded to our initiator capability message
03831d35f7499c87d51205817c93e9a8d42c4baestevel * issued during the boot flow via scosmb_update_nodename().
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Parse the incoming data, and appropriately set SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel * capabilities...
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The SC has initiated a capability messaging exchange with
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We start out just as we do for an SC response capability
03831d35f7499c87d51205817c93e9a8d42c4baestevel * message, a parse of incoming data to appropriately set SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel * described capabilities...
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The next step is setting up our Response to the SC.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Allocate memory for message data, initialize appropriately,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and place a new job on the scosmb_output_taskq for
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SCDM_LOG_ECC_CAP_RESP, our OS capability messaging response
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to the SC initiated sequence detected here.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cap_msgdatap = kmem_zalloc(sizeof (scosmb_msgdata_t), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s invalid command (0x%x)\n", scosmb_hdr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Free up buffer for incoming messasge data that we allocated earlier
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_process_output() - outgoing message processing routine
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This routine handles jobs that are queued on the scosmb_output_taskq, or
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sent directly from scosmb_log_ecc_error. Each job corresponds to a single
03831d35f7499c87d51205817c93e9a8d42c4baestevel * mailbox message that needs to be sent to the SC via the DMSC mailbox. Some
03831d35f7499c87d51205817c93e9a8d42c4baestevel * processing of the message may be performed before it is sent to the SC,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * depending on the value of the command field.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This shouldn't ever happen, but it can't hurt to check anyway.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If data was passed in, we'll need to free it before returning.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Some commands may need additional processing prior to transmission.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Since the SC is only interested in the most recent value of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * utsname.nodename, we wait until now to collect that data. We
03831d35f7499c87d51205817c93e9a8d42c4baestevel * also use a global flag to prevent multiple event-type
03831d35f7499c87d51205817c93e9a8d42c4baestevel * nodename messages from being queued at the same time for the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * same reason.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (length == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SCDM_LOG_ECC_CAP_INIT
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initiator Capability message from OS to SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We construct and send an initiator capability message
03831d35f7499c87d51205817c93e9a8d42c4baestevel * every time we go through scosmb_update_nodename(), which
03831d35f7499c87d51205817c93e9a8d42c4baestevel * works out to getting an "initiator" capability message
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sent from the OS to the SC during the OS boot flow.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The SC also issues a request to scosmb_update_nodename()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * during an SC reboot. Which results in an additional
03831d35f7499c87d51205817c93e9a8d42c4baestevel * capability message exchange during SC reboot scenarios.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SCDM_LOG_ECC_CAP_RESP
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Response Capability message from SC to OS
03831d35f7499c87d51205817c93e9a8d42c4baestevel * In certain scenarios, the SC could initiate a capability
03831d35f7499c87d51205817c93e9a8d42c4baestevel * messaging exchange with the OS. Processing starts in
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_process_input(), where we detect an incoming
03831d35f7499c87d51205817c93e9a8d42c4baestevel * initiator capability message from the SC. We finish
03831d35f7499c87d51205817c93e9a8d42c4baestevel * processing here, by sending a response capability message
03831d35f7499c87d51205817c93e9a8d42c4baestevel * back to the SC that reflects OS capabilities.
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*FALLTHROUGH*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel cap->capd_major_version = PLAT_ECC_CAP_VERSION_MAJOR;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cap->capd_minor_version = PLAT_ECC_CAP_VERSION_MINOR;
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Build the capability solaris_version string:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * utsname.release + " " + utsname.version
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The capability message is constructed, now plug it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * into the starcat msgdatap:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Finished with initiator/response capability
03831d35f7499c87d51205817c93e9a8d42c4baestevel * message set up.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Note that after sending an "initiator" capability
03831d35f7499c87d51205817c93e9a8d42c4baestevel * message, we can expect a subsequent "response"
03831d35f7499c87d51205817c93e9a8d42c4baestevel * capability message from the SC, which we will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pick up and minimally handle later,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * in scosmb_process_input().
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we're sending a "response" capability message
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to the SC, then we're done once the message is sent.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Attempt to send the message.
03831d35f7499c87d51205817c93e9a8d42c4baestevel error = mboxsc_putmsg(DMSC_KEY, msgdatap->type, msgdatap->cmd,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &msgdatap->transid, msgdatap->length, msgdatap->data,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Free any allocated memory that was passed in.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If EAGAIN or ETIMEDOUT was received, give up. The sender can try
03831d35f7499c87d51205817c93e9a8d42c4baestevel * again if it was important. If any other non-zero error was
03831d35f7499c87d51205817c93e9a8d42c4baestevel * encountered, the mailbox service is broken, and there's nothing more
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we can do.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (msgdatap->log_error && !scosmb_mboxsc_timedout) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Indictment mailbox messages use the return value to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * indicate a problem in the mailbox. For Error
03831d35f7499c87d51205817c93e9a8d42c4baestevel * mailbox messages, we'll have to use a syslog message.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_NOTE, "!Solaris failed to send a message "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "(0x%x/0x%x) to the System Controller. Error: %d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (error != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The mailbox service appears to be badly broken. If it was
03831d35f7499c87d51205817c93e9a8d42c4baestevel * working previously, generate a warning and set a flag to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * avoid repeating the warning on subsequent failures.
03831d35f7499c87d51205817c93e9a8d42c4baestevel "while processing this message (0x%x/0x%x)",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the mailbox module failed previously, it appears to have
03831d35f7499c87d51205817c93e9a8d42c4baestevel * recovered, so we'll want to generate a warning if it fails
03831d35f7499c87d51205817c93e9a8d42c4baestevel scosmb_mboxsc_failed = scosmb_mboxsc_timedout = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_update_nodename() - nodename update routine
03831d35f7499c87d51205817c93e9a8d42c4baestevel * this routine, which may be invoked from outside of the scosmb module, will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cause the current nodename to be sent to the SC. The mailbox message sent to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the SC will use the indicated transaction ID, and will either be a reply
03831d35f7499c87d51205817c93e9a8d42c4baestevel * message if the ID is non-zero or an event message if it is 0.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Capability messaging enhancements:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Every time we move through this code flow, we put an "initiator
03831d35f7499c87d51205817c93e9a8d42c4baestevel * capability message" on the message output taskq. This action will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * get a capability message sent to the SC from the OS during boot
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scenarios. A capability message exchange will also happen for
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SC reboot scenarios, as the SC will initiate a nodename update
03831d35f7499c87d51205817c93e9a8d42c4baestevel * as a matter of course while coming back up.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We'll also get an extraneous capability message sent
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to the SC from time to time, but that won't hurt anything.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we're generating an unsolicited nodename update (presumably having
03831d35f7499c87d51205817c93e9a8d42c4baestevel * been called from platmod:plat_nodename_set()), there's no need to add
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a new job to the queue if there is already one on it that will be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sending the latest nodename data.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Allocate memory for the message data, initialize it, and place a new
03831d35f7499c87d51205817c93e9a8d42c4baestevel * job on the scosmb_output_taskq for SCDM_GET_NODENAME.
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgdatap = (scosmb_msgdata_t *)kmem_zalloc(sizeof (scosmb_msgdata_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgdatap->type = (transid == 0) ? MBOXSC_MSG_EVENT : MBOXSC_MSG_REPLY;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (task_func_t *)scosmb_process_output, msgdatap, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Next, allocate memory, initialize, and place a new job on the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_output_taskq for SCDM_LOG_ECC_CAP_INIT. That's a
03831d35f7499c87d51205817c93e9a8d42c4baestevel * capability message, where we're the initiator.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cap_msgdatap = kmem_zalloc(sizeof (scosmb_msgdata_t), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (task_func_t *)scosmb_process_output, cap_msgdatap, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scosmb_log_ecc_error() - Record ECC error information to SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For ECC error messages, send the messages through a taskq mechanism
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to prevent impaired system performance during ECC floods. Indictment
03831d35f7499c87d51205817c93e9a8d42c4baestevel * messages have already passed through a taskq, so directly call the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * output function.
03831d35f7499c87d51205817c93e9a8d42c4baestevelscosmb_log_ecc_error(plat_ecc_message_type_t msg_type, void *datap)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Set header type and length for message
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We do not want to sleep in an error logging thread. So,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we set the NOSLEEP flag and go through a taskq before we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * send the message.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For indictment messages, we're allowed to sleep, and we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * can directly call the output function, since we've already
03831d35f7499c87d51205817c93e9a8d42c4baestevel * gone through a taskq
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For indictment2 messages, we're allowed to sleep, and we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * can directly call the output function, since we've already
03831d35f7499c87d51205817c93e9a8d42c4baestevel * gone through a taskq
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For DIMM sid request messages, we're allowed to sleep, and we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * can directly call the output function, since we've already
03831d35f7499c87d51205817c93e9a8d42c4baestevel * gone through a taskq
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Allocate memory for the mailbox message header.
03831d35f7499c87d51205817c93e9a8d42c4baestevel (scosmb_msgdata_t *)kmem_zalloc(sizeof (scosmb_msgdata_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "failed to allocate space for scosmb "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "message header.");
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Allocate memory for the mailbox message payload.
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg_header_ptr->data = kmem_zalloc((size_t)msg_length, sleep_flag);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "failed to allocate space for scosmb "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "message data.");
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(msg_header_ptr, sizeof (scosmb_msgdata_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(datap, msg_header_ptr->data, (size_t)msg_length);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Based on our earlier look at the message type, we either go through
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a taskq or directly call the output function.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Place a new job on the scosmb_output_taskq.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "failed to dispatch a task to send "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "ECC mailbox message.");
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(msg_header_ptr->data, msg_header_ptr->length);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(msg_header_ptr, sizeof (scosmb_msgdata_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);