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
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Use is subject to license terms.
89b43686db1fe9681d80a7cf5662730cb9378caeBayard Bell * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Useful debugging Stuff */
29949e866e40b95795203f3ee46f44a197c946e4stevel * Function prototypes
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int ac_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int ac_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void ac_get_memory_status(struct ac_soft_state *, enum ac_bank_id);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void ac_eval_memory_status(struct ac_soft_state *, enum ac_bank_id);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int ac_pkt_init(ac_cfga_pkt_t *pkt, intptr_t arg, int flag);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int ac_pkt_fini(ac_cfga_pkt_t *pkt, intptr_t arg, int flag);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void ac_timeout(void *);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int ac_enter_transition(void);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void ac_exit_transition(void);
29949e866e40b95795203f3ee46f44a197c946e4stevel * ac audit message events
29949e866e40b95795203f3ee46f44a197c946e4steveltypedef enum {
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void ac_policy_audit_messages(ac_audit_evt_t event, ac_cfga_pkt_t *pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic char *ac_ostate_typestr(sysc_cfga_ostate_t ostate, ac_audit_evt_t event);
29949e866e40b95795203f3ee46f44a197c946e4stevel/* The memory ioctl interface version of this driver. */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic ac_mem_version_t ac_mem_version = AC_MEM_ADMIN_VERSION;
29949e866e40b95795203f3ee46f44a197c946e4stevel * Configuration data structures
29949e866e40b95795203f3ee46f44a197c946e4stevel 0, /* streamtab */
29949e866e40b95795203f3ee46f44a197c946e4stevel D_MP | D_NEW | D_HOTPLUG, /* Driver compatibility flag */
29949e866e40b95795203f3ee46f44a197c946e4stevel 0, /* refcnt */
29949e866e40b95795203f3ee46f44a197c946e4stevel * Driver globals
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic kstat_t *ac_picN_ksp[AC_NUM_PICS]; /* performance picN kstats */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int ac_attachcnt = 0; /* number of instances attached */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic kmutex_t ac_attachcnt_mutex; /* ac_attachcnt lock - attach/detach */
29949e866e40b95795203f3ee46f44a197c946e4stevel ((struct ac_soft_state *)ddi_get_soft_state(acp, (I)))
29949e866e40b95795203f3ee46f44a197c946e4stevel &mod_driverops, /* Type of module. This one is a driver */
29949e866e40b95795203f3ee46f44a197c946e4stevel * These are the module initialization routines.
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((error = ddi_soft_state_init(&acp, sizeof (struct ac_soft_state),
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Initialize global mutex */
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_init(&ac_attachcnt_mutex, NULL, MUTEX_DRIVER, NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_init(&ac_hot_plug_mode_mutex, NULL, MUTEX_DRIVER, NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevelac_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
29949e866e40b95795203f3ee46f44a197c946e4stevel if (ddi_soft_state_zalloc(acp, instance) != DDI_SUCCESS) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "ddi_soft_state_zalloc failed for ac%d",
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Set the dip in the soft state */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Get the board number from this nodes parent */
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((softsp->board = (int)ddi_getprop(DDI_DEV_T_ANY, softsp->pdip,
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "ac%d: unable to retrieve %s property",
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki " softsp=0x%p\n", instance, (void *)devi, (void *)softsp));
29949e866e40b95795203f3ee46f44a197c946e4stevel /* map in the registers for this device. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (ddi_map_regs(softsp->dip, 0, (caddr_t *)&softsp->ac_base, 0, 0)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "ac%d: unable to map registers", instance);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Setup the pointers to the hardware registers */
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->ac_memctl = (uint64_t *)((char *)softsp->ac_base +
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->ac_memdecode0 = (uint64_t *)((char *)softsp->ac_base +
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->ac_memdecode1 = (uint64_t *)((char *)softsp->ac_base +
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->ac_counter = (uint64_t *)((char *)softsp->ac_base +
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->ac_mccr = (uint32_t *)((char *)softsp->ac_base +
29949e866e40b95795203f3ee46f44a197c946e4stevel /* nothing to suspend/resume here */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* setup the the AC counter registers to allow for hotplug. */
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "ac%d: Board %d not found in database",
29949e866e40b95795203f3ee46f44a197c946e4stevel /* set the AC rev into the bd list structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (list->sc.type == CPU_BOARD || list->sc.type == MEM_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create the minor nodes */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* purge previous fhc pa database entries */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Inherit Memory Bank Status */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Final Memory Bank Status evaluation and messaging */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* create the kstats for this device. */
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* get the instance of this devi */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* get the soft state pointer for this device node */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* FALLTHROUGH */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (list->sc.type == CPU_BOARD || list->sc.type == MEM_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * Test to see if memory is in use on a CPU/MEM board.
29949e866e40b95795203f3ee46f44a197c946e4stevel * In the case of a DR operation this condition
29949e866e40b95795203f3ee46f44a197c946e4stevel * will have been assured when the board was unconfigured.
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[Bank0].ostate == SYSC_CFGA_OSTATE_CONFIGURED ||
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[Bank1].ostate == SYSC_CFGA_OSTATE_CONFIGURED) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * CPU busy test is done by the DR sequencer before
29949e866e40b95795203f3ee46f44a197c946e4stevel * device detach called.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Flush all E-caches to remove references to this
29949e866e40b95795203f3ee46f44a197c946e4stevel * board's memory.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Do this one CPU at a time to avoid stalls and timeouts
29949e866e40b95795203f3ee46f44a197c946e4stevel * due to all CPUs flushing concurrently.
29949e866e40b95795203f3ee46f44a197c946e4stevel * xc_one returns silently for non-existant CPUs.
29949e866e40b95795203f3ee46f44a197c946e4stevel /* delete the kstat for this driver. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* unmap the registers */
29949e866e40b95795203f3ee46f44a197c946e4stevel ddi_unmap_regs(softsp->dip, 0, (caddr_t *)&softsp->ac_base, 0, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Remove the minor nodes. */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* free the soft state structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevelac_open(dev_t *devp, int flag, int otyp, cred_t *credp)
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Is the instance attached? */
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "ac%d device not attached", instance);
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* DEBUG */
29949e866e40b95795203f3ee46f44a197c946e4stevel * If the board is not configured, hide the memory APs
29949e866e40b95795203f3ee46f44a197c946e4stevel /* verify that otyp is appropriate */
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevelac_close(dev_t devt, int flag, int otyp, cred_t *credp)
29949e866e40b95795203f3ee46f44a197c946e4stevel ac_mem_test_stop_on_close(softsp->board, AC_GETBANK(getminor(devt)));
29949e866e40b95795203f3ee46f44a197c946e4stevelac_pkt_init(ac_cfga_pkt_t *pkt, intptr_t arg, int flag)
29949e866e40b95795203f3ee46f44a197c946e4stevel if (ddi_model_convert_from(flag & FMODELS) == DDI_MODEL_ILP32) {
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* _MULTI_DATAMODEL */
29949e866e40b95795203f3ee46f44a197c946e4stevel pkt->errbuf = kmem_zalloc(SYSC_OUTPUT_LEN, KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevelac_pkt_fini(ac_cfga_pkt_t *pkt, intptr_t arg, int flag)
29949e866e40b95795203f3ee46f44a197c946e4stevel if (ddi_model_convert_from(flag & FMODELS) == DDI_MODEL_ILP32) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((ret != FALSE) && ((pkt->cmd_cfga.outputstr != NULL) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (ddi_copyout(pkt->errbuf, pkt->cmd_cfga.outputstr,
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "ac%d device not attached", instance);
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* DEBUG */
29949e866e40b95795203f3ee46f44a197c946e4stevel * Dispose of the easy ones first.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Specify the revision of this ioctl interface driver.
29949e866e40b95795203f3ee46f44a197c946e4stevel ac_policy_audit_messages(AC_AUDIT_OSTATE_CONFIGURE, pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevel ac_policy_audit_messages(AC_AUDIT_OSTATE_UNCONFIGURE, pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevel * Query usage of a bank of memory.
29949e866e40b95795203f3ee46f44a197c946e4stevel * read a 'page' (or less) of memory safely.
29949e866e40b95795203f3ee46f44a197c946e4stevel * write a 'page' (or less) of memory safely.
29949e866e40b95795203f3ee46f44a197c946e4stevel * create the unix-misc kstat for address controller
29949e866e40b95795203f3ee46f44a197c946e4stevel * using the board number as the instance.
29949e866e40b95795203f3ee46f44a197c946e4stevel /* initialize the named kstats */
29949e866e40b95795203f3ee46f44a197c946e4stevel * Create the picN kstats if we are the first instance
29949e866e40b95795203f3ee46f44a197c946e4stevel * to attach. We use ac_attachcnt as a count of how
29949e866e40b95795203f3ee46f44a197c946e4stevel * many instances have attached. This is protected by
29949e866e40b95795203f3ee46f44a197c946e4stevel * Create the "counter" kstat for each AC instance.
29949e866e40b95795203f3ee46f44a197c946e4stevel * This provides access to the %pcr and %pic
29949e866e40b95795203f3ee46f44a197c946e4stevel * registers for that instance.
29949e866e40b95795203f3ee46f44a197c946e4stevel * The size of this kstat is AC_NUM_PICS + 1 for %pcr
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "ac%d counters: kstat_create failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore (struct kstat_named *)(ac_counters_ksp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* initialize the named kstats */
29949e866e40b95795203f3ee46f44a197c946e4stevel ac_counters_ksp->ks_update = ac_counters_kstat_update;
29949e866e40b95795203f3ee46f44a197c946e4stevel /* update the sofstate */
29949e866e40b95795203f3ee46f44a197c946e4stevel * called from ac_add_kstats() to create a kstat for each %pic
29949e866e40b95795203f3ee46f44a197c946e4stevel * that the AC supports. These (read-only) kstats export the
29949e866e40b95795203f3ee46f44a197c946e4stevel * event names and %pcr masks that each %pic supports.
29949e866e40b95795203f3ee46f44a197c946e4stevel * if we fail to create any of these kstats we must remove any
29949e866e40b95795203f3ee46f44a197c946e4stevel * that we have already created and return;
29949e866e40b95795203f3ee46f44a197c946e4stevel * NOTE: because all AC's use the same events we only need to
29949e866e40b95795203f3ee46f44a197c946e4stevel * create the picN kstats once. All instances can use
29949e866e40b95795203f3ee46f44a197c946e4stevel * the same picN kstats.
29949e866e40b95795203f3ee46f44a197c946e4stevel * The flexibility exists to allow each device specify it's
29949e866e40b95795203f3ee46f44a197c946e4stevel * own events by creating picN kstats with the instance number
29949e866e40b95795203f3ee46f44a197c946e4stevel * set to ddi_get_instance(softsp->dip).
29949e866e40b95795203f3ee46f44a197c946e4stevel * When searching for a picN kstat for a device you should
29949e866e40b95795203f3ee46f44a197c946e4stevel * first search for a picN kstat using the instance number
29949e866e40b95795203f3ee46f44a197c946e4stevel * of the device you are interested in. If that fails you
29949e866e40b95795203f3ee46f44a197c946e4stevel * should use the first picN kstat found for that device.
29949e866e40b95795203f3ee46f44a197c946e4stevel * AC Performance Events.
29949e866e40b95795203f3ee46f44a197c946e4stevel * We declare an array of event-names and event-masks.
29949e866e40b95795203f3ee46f44a197c946e4stevel#define AC_NUM_EVENTS sizeof (ac_events_arr) / sizeof (ac_events_arr[0])
29949e866e40b95795203f3ee46f44a197c946e4stevel * array of clear masks for each pic.
29949e866e40b95795203f3ee46f44a197c946e4stevel * These masks are used to clear the %pcr bits for
29949e866e40b95795203f3ee46f44a197c946e4stevel * each pic.
29949e866e40b95795203f3ee46f44a197c946e4stevel * create the picN kstat. The size of this kstat is
29949e866e40b95795203f3ee46f44a197c946e4stevel * AC_NUM_EVENTS + 1 for the clear_event_mask
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) sprintf(pic_name, "pic%d", pic); /* pic0, pic1 ... */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* remove pic0 kstat if pic1 create fails */
193974072f41a843678abf5f61979c748687e66bSherry Moore (struct kstat_named *)(ac_picN_ksp[pic]->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel * when we are storing pcr_masks we need to shift bits
29949e866e40b95795203f3ee46f44a197c946e4stevel * left by 8 for pic1 events.
29949e866e40b95795203f3ee46f44a197c946e4stevel * for each picN event we need to write a kstat record
29949e866e40b95795203f3ee46f44a197c946e4stevel * (name = EVENT, value.ui64 = PCR_MASK)
29949e866e40b95795203f3ee46f44a197c946e4stevel /* pcr_mask */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* event-name */
29949e866e40b95795203f3ee46f44a197c946e4stevel * we add the clear_pic event and mask as the last
29949e866e40b95795203f3ee46f44a197c946e4stevel * record in the kstat
29949e866e40b95795203f3ee46f44a197c946e4stevel /* pcr mask */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* event-name */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* remove "misc" kstat */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* remove "bus" kstat */
29949e866e40b95795203f3ee46f44a197c946e4stevel * if we are the last instance to detach we need to
29949e866e40b95795203f3ee46f44a197c946e4stevel * remove the picN kstats. We use ac_attachcnt as a
29949e866e40b95795203f3ee46f44a197c946e4stevel * count of how many instances are still attached. This
29949e866e40b95795203f3ee46f44a197c946e4stevel * is protected by a mutex.
29949e866e40b95795203f3ee46f44a197c946e4stevelac_kstat_stat(sysc_cfga_rstate_t rst, sysc_cfga_ostate_t ost)
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Need the NULL check in case kstat is about to be deleted. */
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(softsp->ac_ksp == NULL || ksp == softsp->ac_ksp);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* this is a read-only kstat. Bail out on a write */
29949e866e40b95795203f3ee46f44a197c946e4stevel * copy the current state of the hardware into the
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat structure.
29949e866e40b95795203f3ee46f44a197c946e4stevel acksp->ac_memdecode0.value.ui64 = *softsp->ac_memdecode0;
29949e866e40b95795203f3ee46f44a197c946e4stevel acksp->ac_memdecode1.value.ui64 = *softsp->ac_memdecode1;
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel ac_counters_data = (struct kstat_named *)ksp->ks_data;
29949e866e40b95795203f3ee46f44a197c946e4stevel * We need to start/restart the ac_timeout that will
29949e866e40b95795203f3ee46f44a197c946e4stevel * return the AC counters to hot-plug mode after the
29949e866e40b95795203f3ee46f44a197c946e4stevel * ac_hot_plug_timeout_interval has expired. We tell
29949e866e40b95795203f3ee46f44a197c946e4stevel * ac_reset_timeout() whether this is a kstat_read or a
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat_write call. If this fails we reject the kstat
29949e866e40b95795203f3ee46f44a197c946e4stevel * operation.
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel * Write the %pcr value to the softsp->ac_mccr.
29949e866e40b95795203f3ee46f44a197c946e4stevel * This interface does not support writing to the
29949e866e40b95795203f3ee46f44a197c946e4stevel * Read %pcr and %pic register values and write them
29949e866e40b95795203f3ee46f44a197c946e4stevel * into counters kstat.
29949e866e40b95795203f3ee46f44a197c946e4stevel * ac pic register:
29949e866e40b95795203f3ee46f44a197c946e4stevel * (63:32) = pic1
29949e866e40b95795203f3ee46f44a197c946e4stevel * (31:00) = pic0
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel * Decode the memory state given to us and plug it into the soft state
29949e866e40b95795203f3ee46f44a197c946e4stevelac_get_memory_status(struct ac_soft_state *softsp, enum ac_bank_id id)
29949e866e40b95795203f3ee46f44a197c946e4stevel char *property = (id == Bank0) ? AC_BANK0_STATUS : AC_BANK1_STATUS;
193974072f41a843678abf5f61979c748687e66bSherry Moore *(softsp->ac_memdecode0) : *(softsp->ac_memdecode1);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* determine the memory bank size (in MB) */
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].real_size = softsp->bank[id].use_size =
29949e866e40b95795203f3ee46f44a197c946e4stevel (id == Bank0) ? (grp_size / INTLV0(*softsp->ac_memctl)) :
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].real_size = softsp->bank[id].use_size = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel * decode the memory bank property. set condition based
29949e866e40b95795203f3ee46f44a197c946e4stevel * on the values.
29949e866e40b95795203f3ee46f44a197c946e4stevel if (ddi_prop_op(DDI_DEV_T_ANY, softsp->dip, PROP_LEN_AND_VAL_ALLOC,
29949e866e40b95795203f3ee46f44a197c946e4stevel DDI_PROP_DONTPASS, property, (caddr_t)&propval, &proplen) ==
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].rstate = SYSC_CFGA_RSTATE_CONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate = SYSC_CFGA_OSTATE_CONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].rstate = SYSC_CFGA_RSTATE_CONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].condition = SYSC_CFGA_COND_UNUSABLE;
29949e866e40b95795203f3ee46f44a197c946e4stevel "unknown %smemory state [%s]",
29949e866e40b95795203f3ee46f44a197c946e4stevel /* we don't have the property, deduce the state of memory */
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].rstate = SYSC_CFGA_RSTATE_CONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate = SYSC_CFGA_OSTATE_CONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel /* could be an i/o board... */
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel /* we assume that all other bank statuses are NOT valid */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (softsp->bank[id].rstate == SYSC_CFGA_RSTATE_CONNECTED) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* register existence in the memloc database */
29949e866e40b95795203f3ee46f44a197c946e4stevelac_eval_memory_status(struct ac_soft_state *softsp, enum ac_bank_id id)
193974072f41a843678abf5f61979c748687e66bSherry Moore *(softsp->ac_memdecode0) : *(softsp->ac_memdecode1);
29949e866e40b95795203f3ee46f44a197c946e4stevel * Downgrade the status of any bank that did not get
29949e866e40b95795203f3ee46f44a197c946e4stevel * programmed.
29949e866e40b95795203f3ee46f44a197c946e4stevel if (softsp->bank[id].rstate == SYSC_CFGA_RSTATE_CONNECTED &&
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate == SYSC_CFGA_OSTATE_UNCONFIGURED &&
29949e866e40b95795203f3ee46f44a197c946e4stevel "spare memory bank not valid - it was ",
29949e866e40b95795203f3ee46f44a197c946e4stevel "firmware. Disabling...");
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->bank[id].condition = SYSC_CFGA_COND_UNUSABLE;
29949e866e40b95795203f3ee46f44a197c946e4stevel * Log a message about good banks.
29949e866e40b95795203f3ee46f44a197c946e4stevel if (softsp->bank[id].rstate == SYSC_CFGA_RSTATE_CONNECTED) {
29949e866e40b95795203f3ee46f44a197c946e4stevel "ostate %d condition %d\n",
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->board, id, base_pa, softsp->bank[id].real_size,
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic char *
29949e866e40b95795203f3ee46f44a197c946e4stevelac_ostate_typestr(sysc_cfga_ostate_t ostate, ac_audit_evt_t event)
29949e866e40b95795203f3ee46f44a197c946e4stevelac_policy_audit_messages(ac_audit_evt_t event, ac_cfga_pkt_t *pkt)
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s memory bank %d in slot %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s memory bank %d in slot %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore "memory bank %d in slot %d is %s",
29949e866e40b95795203f3ee46f44a197c946e4stevel "memory bank %d in slot %d not %s",
193974072f41a843678abf5f61979c748687e66bSherry Moore "memory bank %d in slot %d not %s",
193974072f41a843678abf5f61979c748687e66bSherry Moore "unknown audit of memory bank %d in slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel if (mem_info->rstate == SYSC_CFGA_RSTATE_CONNECTED) {
29949e866e40b95795203f3ee46f44a197c946e4stevel *pkt->softsp->ac_memdecode0 : *pkt->softsp->ac_memdecode1;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (npgs == 0 ||
29949e866e40b95795203f3ee46f44a197c946e4stevel if (result == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel while (npgs-- > 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (pkt->cmd_cfga.private != NULL && ddi_copyout(&rstat,
29949e866e40b95795203f3ee46f44a197c946e4stevel * We are in hot-plug mode. A kstat_read is not
29949e866e40b95795203f3ee46f44a197c946e4stevel * going to affect this. return 0 to allow the
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat_read to continue.
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else if ((ac_hot_plug_timeout == (timeout_id_t)NULL) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel * There are no pending timeouts and we have received a
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat_write request so we must be transitioning
29949e866e40b95795203f3ee46f44a197c946e4stevel * from "hot-plug" mode to non "hot-plug" mode.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Try to lock all boards before allowing the kstat_write.
29949e866e40b95795203f3ee46f44a197c946e4stevel /* cannot lock boards so fail */
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel * We need to display a Warning about hot-plugging any
29949e866e40b95795203f3ee46f44a197c946e4stevel * boards. This message is only needed when we are
29949e866e40b95795203f3ee46f44a197c946e4stevel * transitioning out of "hot-plug" mode.
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "This machine is being taken out of "
29949e866e40b95795203f3ee46f44a197c946e4stevel "hot-plug mode.");
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_CONT, "Do not attempt to hot-plug boards "
29949e866e40b95795203f3ee46f44a197c946e4stevel "or power supplies in this system until further notice.");
29949e866e40b95795203f3ee46f44a197c946e4stevel } else if (ac_hot_plug_timeout != (timeout_id_t)NULL) {
29949e866e40b95795203f3ee46f44a197c946e4stevel * There is a pending timeout so we must already be
29949e866e40b95795203f3ee46f44a197c946e4stevel * in non "hot-plug" mode. It doesn't matter if the
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat request is a read or a write.
29949e866e40b95795203f3ee46f44a197c946e4stevel * We need to cancel the existing timeout.
29949e866e40b95795203f3ee46f44a197c946e4stevel * create a new timeout.
29949e866e40b95795203f3ee46f44a197c946e4stevel drv_usectohz(ac_hot_plug_timeout_interval * 1000000));
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* lint */
29949e866e40b95795203f3ee46f44a197c946e4stevel * Foreach ac in the board list we need to
29949e866e40b95795203f3ee46f44a197c946e4stevel * re-program the pcr into "hot-plug" mode.
29949e866e40b95795203f3ee46f44a197c946e4stevel * We also program the pic register with the
29949e866e40b95795203f3ee46f44a197c946e4stevel * bus pause timing
29949e866e40b95795203f3ee46f44a197c946e4stevel * This board must not have an AC.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Skip it and move on.
29949e866e40b95795203f3ee46f44a197c946e4stevel /* program the pcr into hot-plug mode */
29949e866e40b95795203f3ee46f44a197c946e4stevel *softsp->ac_mccr = AC_SET_HOT_PLUG(*softsp->ac_mccr);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* program the pic with the bus pause time value */
29949e866e40b95795203f3ee46f44a197c946e4stevel *softsp->ac_counter = AC_SET_PIC_BUS_PAUSE(softsp->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* get the next board */
29949e866e40b95795203f3ee46f44a197c946e4stevel * It is now safe to start hot-plugging again. We need
29949e866e40b95795203f3ee46f44a197c946e4stevel * to display a message.
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "This machine is now in hot-plug mode.");
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_CONT, "Board and power supply hot-plug operations "
29949e866e40b95795203f3ee46f44a197c946e4stevel "can be resumed.");
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function will acquire the lock and set the in_transition
29949e866e40b95795203f3ee46f44a197c946e4stevel * bit for all the slots. If the slots are being used,
29949e866e40b95795203f3ee46f44a197c946e4stevel * we return FALSE; else set in_transition and return TRUE.
29949e866e40b95795203f3ee46f44a197c946e4stevel /* mutex lock the structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* change the in_transition bit */
29949e866e40b95795203f3ee46f44a197c946e4stevel * clear the in_transition bit for all the slots.