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/*
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
89b43686db1fe9681d80a7cf5662730cb9378caeBayard Bell * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/conf.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi_impldefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/obpdefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cmn_err.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kmem.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/debug.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sysmacros.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/autoconf.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/modctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/fhc.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sram.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/promif.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Useful debugging Stuff */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/nexusdebug.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Function protoypes
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sram_attach(dev_info_t *, ddi_attach_cmd_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sram_detach(dev_info_t *, ddi_detach_cmd_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void sram_add_kstats(struct sram_soft_state *);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Configuration data structures
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct cb_ops sram_cb_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* open */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* close */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* strategy */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* print */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* dump */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* read */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* write */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* ioctl */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* devmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* mmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* segmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nochpoll, /* poll */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_prop_op, /* cb_prop_op */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, /* streamtab */
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_MP | D_NEW | D_HOTPLUG, /* Driver compatibility flag */
03831d35f7499c87d51205817c93e9a8d42c4baestevel CB_REV, /* rev */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* cb_aread */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev /* cb_awrite */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct dev_ops sram_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DEVO_REV, /* rev */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, /* refcnt */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_no_info, /* getinfo */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* identify */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* probe */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sram_attach, /* attach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sram_detach, /* detach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* reset */
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sram_cb_ops, /* cb_ops */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (struct bus_ops *)0, /* bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore nulldev, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* quiesce */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Driver globals
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid *sramp; /* sram soft state hook */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct kstat *resetinfo_ksp = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int reset_info_created = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern struct mod_ops mod_driverops;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modldrv modldrv = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel &mod_driverops, /* Type of module. This one is a driver */
193974072f41a843678abf5f61979c748687e66bSherry Moore "Sram Leaf", /* name of module */
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sram_ops, /* driver ops */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modlinkage modlinkage = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MODREV_1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void *)&modldrv,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * These are the module initialization routines.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((error = ddi_soft_state_init(&sramp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (struct sram_soft_state), 1)) == 0 &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (error = mod_install(&modlinkage)) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_fini(&sramp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_fini(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((error = mod_remove(&modlinkage)) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_fini(&sramp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_info(struct modinfo *modinfop)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (mod_info(&modlinkage, modinfop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsram_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct sram_soft_state *softsp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_ATTACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_RESUME:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance = ddi_get_instance(devi);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_soft_state_zalloc(sramp, instance) != DDI_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp = ddi_get_soft_state(sramp, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Set the dip in the soft state */
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp->dip = devi;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* get the board number from this devices parent. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp->pdip = ddi_get_parent(softsp->dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((softsp->board = (int)ddi_getprop(DDI_DEV_T_ANY, softsp->pdip,
03831d35f7499c87d51205817c93e9a8d42c4baestevel DDI_PROP_DONTPASS, OBP_BOARDNUM, -1)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sram%d: unable to retrieve %s property",
193974072f41a843678abf5f61979c748687e66bSherry Moore instance, OBP_BOARDNUM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto bad;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel DPRINTF(SRAM_ATTACH_DEBUG, ("sram%d: devi= 0x%p\n, "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki " softsp=0x%p\n", instance, (void *)devi, (void *)softsp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* map in the registers for this device. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_map_regs(softsp->dip, 0,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (caddr_t *)&softsp->sram_base, 0, 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sram%d: unable to map registers",
193974072f41a843678abf5f61979c748687e66bSherry Moore instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto bad;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* nothing to suspend/resume here */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pm-hardware-state", "no-suspend-resume");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* create the kstats for this device. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sram_add_kstats(softsp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_report_dev(devi);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelbad:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_free(sramp, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsram_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct sram_soft_state *softsp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* get the instance of this devi */
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance = ddi_get_instance(devi);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* get the soft state pointer for this device node */
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp = ddi_get_soft_state(sramp, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_SUSPEND:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_DETACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fhc_bdlist_lock(softsp->board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fhc_bd_detachable(softsp->board))
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel fhc_bdlist_unlock();
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* FALLTHROUGH */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel fhc_bdlist_unlock();
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We do not remove the kstat here. There is only one instance for
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the whole machine, and it must remain in existence while the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * system is running.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* unmap the registers */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_unmap_regs(softsp->dip, 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&softsp->sram_base, 0, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free the soft state structure */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_free(sramp, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_prop_remove_all(devi);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The Reset-info structure passed up by POST has it's own kstat.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * It only needs to get created once. So the first sram instance
03831d35f7499c87d51205817c93e9a8d42c4baestevel * that gets created will check for the OBP property 'reset-info'
03831d35f7499c87d51205817c93e9a8d42c4baestevel * in the root node of the OBP device tree. If this property exists,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * then the reset-info kstat will get created. Otherwise it will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * not get created. This will inform users whether or not a fatal
03831d35f7499c87d51205817c93e9a8d42c4baestevel * hardware reset has recently occurred.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelsram_add_kstats(struct sram_soft_state *softsp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int reset_size; /* size of data collected by POST */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *ksptr; /* memory pointer for byte copy */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *srptr; /* pointer to sram for byte copy */
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel union {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char size[4]; /* copy in word byte-by-byte */
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } rst_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * only one reset_info kstat per system, so don't create it if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * it exists already.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (reset_info_created) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* mark that this code has been run. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel reset_info_created = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* does the root node have a 'fatal-reset-info' property? */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prom_getprop(prom_rootnode(), "fatal-reset-info",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (caddr_t)&softsp->offset) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* XXX - workaround for OBP bug */
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp->reset_info = softsp->sram_base + softsp->offset;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * First read size. In case FW has not word aligned structure,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * copy the unsigned int into a 4 byte union, then read it out as
03831d35f7499c87d51205817c93e9a8d42c4baestevel * an inteeger.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0, srptr = softsp->reset_info; i < 4; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rst_size.size[i] = *srptr++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel reset_size = rst_size.len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the reset size is zero, then POST did not
03831d35f7499c87d51205817c93e9a8d42c4baestevel * record any info.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((uint_t)reset_size == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Check for illegal size values. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((uint_t)reset_size > MX_RSTINFO_SZ) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_NOTE, "sram%d: illegal "
193974072f41a843678abf5f61979c748687e66bSherry Moore "reset_size: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(softsp->dip),
193974072f41a843678abf5f61979c748687e66bSherry Moore reset_size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* create the reset-info kstat */
03831d35f7499c87d51205817c93e9a8d42c4baestevel resetinfo_ksp = kstat_create("unix", 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore RESETINFO_KSTAT_NAME, "misc", KSTAT_TYPE_RAW,
193974072f41a843678abf5f61979c748687e66bSherry Moore reset_size, KSTAT_FLAG_PERSISTENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (resetinfo_ksp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sram%d: kstat_create failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(softsp->dip));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now copy the data into kstat. Don't use block
03831d35f7499c87d51205817c93e9a8d42c4baestevel * copy, the local space sram does not support this.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel srptr = softsp->reset_info;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ksptr = (char *)resetinfo_ksp->ks_data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < reset_size; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel *ksptr++ = *srptr++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_install(resetinfo_ksp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}