29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER START
29949e866e40b95795203f3ee46f44a197c946e4stevel * The contents of this file are subject to the terms of the
29949e866e40b95795203f3ee46f44a197c946e4stevel * Common Development and Distribution License (the "License").
29949e866e40b95795203f3ee46f44a197c946e4stevel * You may not use this file except in compliance with the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
29949e866e40b95795203f3ee46f44a197c946e4stevel * See the License for the specific language governing permissions
29949e866e40b95795203f3ee46f44a197c946e4stevel * and limitations under the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel * When distributing Covered Code, include this CDDL HEADER in each
29949e866e40b95795203f3ee46f44a197c946e4stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
29949e866e40b95795203f3ee46f44a197c946e4stevel * If applicable, add the following below this CDDL HEADER, with the
29949e866e40b95795203f3ee46f44a197c946e4stevel * fields enclosed by brackets "[]" replaced with your own identifying
29949e866e40b95795203f3ee46f44a197c946e4stevel * information: Portions Copyright [yyyy] [name of copyright owner]
29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER END
29949e866e40b95795203f3ee46f44a197c946e4stevel * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Use is subject to license terms.
29949e866e40b95795203f3ee46f44a197c946e4stevel#pragma ident "%Z%%M% %I% %E% SMI"
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic fhc_bd_resizable_t boards; /* booted and hotplugged boards */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic fhc_bd_resizable_t clocks; /* clocks under central. */
29949e866e40b95795203f3ee46f44a197c946e4stevel * !! IMPORTANT !! fhc_bdlist_rwlock is implemented as a single
29949e866e40b95795203f3ee46f44a197c946e4stevel * RW_WRITER lock with *no* RW_READERs -- and it should stay that
29949e866e40b95795203f3ee46f44a197c946e4stevel * way. The fhc_bdlist_rwlock should never be used with RW_READER.
29949e866e40b95795203f3ee46f44a197c946e4stevel * The lock was originally a mutex, but was changed to a
29949e866e40b95795203f3ee46f44a197c946e4stevel * single-writer, zero-reader rwlock to force requesting threads
29949e866e40b95795203f3ee46f44a197c946e4stevel * to block (sleep, not spin) when the RW_WRITER lock is already
29949e866e40b95795203f3ee46f44a197c946e4stevel * held by a thread currently running.
29949e866e40b95795203f3ee46f44a197c946e4stevel#define fhc_bd_sc_evt(s, e) (*fbe->update)(fbe->soft, s, e)
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_b_search(in_array.boards, board, 0, in_array.last);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int fhc_bd_disabled(int);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void fhc_check_array(int);
29949e866e40b95795203f3ee46f44a197c946e4stevel * fhc_bdmax gets set in fhc_bdlist_prime() and does not
29949e866e40b95795203f3ee46f44a197c946e4stevel * change thereafter.
29949e866e40b95795203f3ee46f44a197c946e4stevel int n, h, i, j;
29949e866e40b95795203f3ee46f44a197c946e4stevel /* sort array a[lb..ub] */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* compute largest increment */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (n < 14)
29949e866e40b95795203f3ee46f44a197c946e4stevel while (h < n)
29949e866e40b95795203f3ee46f44a197c946e4stevel while (h > 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* sort-by-insertion in increments of h */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (j = i - h;
29949e866e40b95795203f3ee46f44a197c946e4stevel a[j+h] = a[j];
29949e866e40b95795203f3ee46f44a197c946e4stevel a[j+h] = t;
29949e866e40b95795203f3ee46f44a197c946e4stevel /* compute next increment */
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_b_search(fhc_bd_t *in_array[], int board, int first, int last)
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Array of length 0 case. */
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Array of length > 0 case. */
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (1);
29949e866e40b95795203f3ee46f44a197c946e4stevel return ((boards.boards[index]->softsp)->jt_master.is_master);
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.sorted = TRUE; /* Array of 0 elements is sorted. */
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.sorted = TRUE; /* Array of 0 elements is sorted. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* RW_WRITER *ONLY*. Never use RW_READER! */
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_resize(fhc_bd_t ***in_array, int oldsize, int newsize)
29949e866e40b95795203f3ee46f44a197c946e4stevel /* This function only grows arrays. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Allocate new array. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Bcopy old array and free it. */
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_init(struct fhc_soft_state *softsp, int board, enum board_type type)
29949e866e40b95795203f3ee46f44a197c946e4stevel /* See if board already exists. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If index == -1 board does not exist. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Keep arrays sorted. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Untill fhc_bdlist_prime runs anything is valid. */
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel * Find the disabled board list property if present.
29949e866e40b95795203f3ee46f44a197c946e4stevel * The disabled board list is in the options node under root;
29949e866e40b95795203f3ee46f44a197c946e4stevel * it is a null terminated list of boards in a string.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Each char represents a board. The driver must
29949e866e40b95795203f3ee46f44a197c946e4stevel * reject illegal chars in case a user places them in the
29949e866e40b95795203f3ee46f44a197c946e4stevel * property.
29949e866e40b95795203f3ee46f44a197c946e4stevel if (((node = prom_finddevice("/options")) == OBP_BADNODE) ||
29949e866e40b95795203f3ee46f44a197c946e4stevel ((len = prom_getproplen(node, "disabled-board-list")) == -1))
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) prom_getprop(node, "disabled-board-list", dlist);
29949e866e40b95795203f3ee46f44a197c946e4stevel * now loop thru the string, and create disabled board list
29949e866e40b95795203f3ee46f44a197c946e4stevel * entries for all legal boards in the list.
29949e866e40b95795203f3ee46f44a197c946e4stevel /* junk entry */
29949e866e40b95795203f3ee46f44a197c946e4stevel bcopy((caddr_t)sc->prom_rev, uip->prom_rev, sizeof (uip->prom_rev));
29949e866e40b95795203f3ee46f44a197c946e4stevel bcopy((caddr_t)&sc->bd, &uip->bd, sizeof (union bd_un));
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel * Search the children of root to see if there are any
29949e866e40b95795203f3ee46f44a197c946e4stevel * disk boards in the tree.
29949e866e40b95795203f3ee46f44a197c946e4stevel dnode != NULL; dnode = ddi_get_next_sibling(dnode)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strcmp(ddi_node_name(dnode), "disk-board") == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * Get the board number property.
29949e866e40b95795203f3ee46f44a197c946e4stevel "Could not find board number");
29949e866e40b95795203f3ee46f44a197c946e4stevel * Now search for the JTAG master and place the addresses for
29949e866e40b95795203f3ee46f44a197c946e4stevel * command into the fhc soft state structure.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Disk board do not have softsp set.
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp))
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->softsp && (bdp->softsp->jt_master.is_master == 1)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * Search only subset of array. We hold mutex so
29949e866e40b95795203f3ee46f44a197c946e4stevel * noone can add new elements to it.
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards[boards.last + 1]->sc.type = UNKNOWN_BOARD;
29949e866e40b95795203f3ee46f44a197c946e4stevel * Initialize our copy of the disabled board list.
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "fhc_bdlist_prime: no jtag master");
29949e866e40b95795203f3ee46f44a197c946e4stevel * Go through the board list, skipping illegal slots
29949e866e40b95795203f3ee46f44a197c946e4stevel * and initialize each slot.
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * Disk boards are handled differently
29949e866e40b95795203f3ee46f44a197c946e4stevel * in that they don't fail POST and have
29949e866e40b95795203f3ee46f44a197c946e4stevel * no fhc attached.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Set the condition to FAILED if POST has
29949e866e40b95795203f3ee46f44a197c946e4stevel * failed. A failed board is physically
29949e866e40b95795203f3ee46f44a197c946e4stevel * present, is not on the disabled list and
29949e866e40b95795203f3ee46f44a197c946e4stevel * is of type UNKNOWN.
29949e866e40b95795203f3ee46f44a197c946e4stevel * NOTE: a non-present board which is
29949e866e40b95795203f3ee46f44a197c946e4stevel * (potentially) on the disabled board
29949e866e40b95795203f3ee46f44a197c946e4stevel * list has been ignored in the empty
29949e866e40b95795203f3ee46f44a197c946e4stevel * slot case.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Do the disk specific initialization. This routine scans
29949e866e40b95795203f3ee46f44a197c946e4stevel * for all disk boards, so we call it only once.
29949e866e40b95795203f3ee46f44a197c946e4stevel { 0, 0, 0, 0},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 0, 0, 0, 0},
29949e866e40b95795203f3ee46f44a197c946e4stevel * set_cpu_info
29949e866e40b95795203f3ee46f44a197c946e4stevel * This routine extracts CPU module information used later for
29949e866e40b95795203f3ee46f44a197c946e4stevel * determining hotplug compatibility.
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0; i < 2; i++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.cpu[i].cpu_speed = table[speed_pins].cpu_freq;
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.cpu[i].cpu_sram_mode = table[speed_pins].sram_mode;
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_scan(sysc_cfga_rstate_t rstate, struct jt_mstr *jtm)
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * Check the boards in EMPTY and DISCONNECTED
29949e866e40b95795203f3ee46f44a197c946e4stevel * states. We need to check a board in the
29949e866e40b95795203f3ee46f44a197c946e4stevel * DISCONNECTED state in case it had been replugged.
29949e866e40b95795203f3ee46f44a197c946e4stevel continue; /* no board present */
29949e866e40b95795203f3ee46f44a197c946e4stevel * Scan the FHC to turn off the board insert
29949e866e40b95795203f3ee46f44a197c946e4stevel * interrupt and modify LEDs based on hotplug
29949e866e40b95795203f3ee46f44a197c946e4stevel * A replugged board will still have its kstat info.
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "fhc_bd_insert_scan: no jtag master");
29949e866e40b95795203f3ee46f44a197c946e4stevel /* first check empty then disconnected */
29949e866e40b95795203f3ee46f44a197c946e4stevel found = fhc_bdlist_scan(SYSC_CFGA_RSTATE_EMPTY, jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel found |= fhc_bdlist_scan(SYSC_CFGA_RSTATE_DISCONNECTED, jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "Could not find hotplugged core system board");
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "fhc_bd_remove_scan: no jtag master");
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * While there is a board in the disconnected state
29949e866e40b95795203f3ee46f44a197c946e4stevel * continue polling. When the last board is removed,
29949e866e40b95795203f3ee46f44a197c946e4stevel * we will get one last scan.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Scan to see if the board is still in.
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_sc_register(void (*f)(void *, sysc_cfga_stat_t *, sysc_evt_t), void *sp)
29949e866e40b95795203f3ee46f44a197c946e4stevel * There is a window where this routine might be called
29949e866e40b95795203f3ee46f44a197c946e4stevel * as a result of the environ thread before sysctrl has
29949e866e40b95795203f3ee46f44a197c946e4stevel * attached and registered the callback.
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "fhc_bd_test: simulate board %d insertion",
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "fhc_bd_test: simulate board %d removal",
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel * force a board condition for test purpose
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_test_set_cond(int board, sysc_cfga_pkt_t *sysc_pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);