Example #1
0
/*
 * Our nodename has been set, pass it along to the RMC.
 */
void
plat_nodename_set(void)
{
	rmc_comm_msg_t	req;	/* request */
	int (*rmc_req_res)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t) = NULL;

	/*
	 * find the symbol for the mailbox routine
	 */
	rmc_req_res = (int (*)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t))
	    modgetsymvalue("rmc_comm_request_response", 0);

	if (rmc_req_res == NULL) {
		return;
	}

	/*
	 * construct the message telling the RMC our nodename
	 */
	req.msg_type = DP_SET_CPU_NODENAME;
	req.msg_len = strlen(utsname.nodename) + 1;
	req.msg_bytes = 0;
	req.msg_buf = (caddr_t)utsname.nodename;

	/*
	 * ship it
	 */
	(void) (rmc_req_res)(&req, NULL, 2000);
}
Example #2
0
/*
 * Indicate to the platforms that the utsname.nodename was set.
 */
void
nodename_set(void)
{
    void (*func)(void);

    func = (void (*)(void))modgetsymvalue("plat_nodename_set", 0);
    if (func)
        (*func)();
}
Example #3
0
void
pci_axq_pio_limit(pbm_t *pbm_p)
{
	pci_t *pci_p = pbm_p->pbm_pci_p;
	dev_info_t *dip = pci_p->pci_dip;
	int (*axq_pio_workaround)(dev_info_t *) = NULL;

	axq_pio_workaround =
	    (int (*)(dev_info_t *)) modgetsymvalue(
	    "starcat_axq_pio_workaround", 0);

	if (axq_pio_workaround) {
		pbm_p->pbm_pio_limit = (axq_pio_workaround)(dip);
		pbm_p->pbm_pio_counter = pbm_p->pbm_pio_limit;
	} else
		pbm_p->pbm_pio_limit = 0;
}
Example #4
0
/*ARGSUSED*/
static void
cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
{
	dp_cpu_signature_t signature;
	rmc_comm_msg_t	req;	/* request */
	int (*rmc_req_now)(rmc_comm_msg_t *, uint8_t) = NULL;


	/*
	 * Differentiate a panic reboot from a non-panic reboot in the
	 * setting of the substate of the signature.
	 *
	 * If the new substate is REBOOT and we're rebooting due to a panic,
	 * then set the new substate to a special value indicating a panic
	 * reboot, SIGSUBST_PANIC_REBOOT.
	 *
	 * A panic reboot is detected by a current (previous) signature
	 * state of SIGST_EXIT, and a new signature substate of SIGSUBST_REBOOT.
	 * The domain signature state SIGST_EXIT is used as the panic flow
	 * progresses.
	 *
	 * At the end of the panic flow, the reboot occurs but we should know
	 * one that was involuntary, something that may be quite useful to know
	 * at OBP level.
	 */
	if (state == SIGST_EXIT && sub_state == SIGSUBST_REBOOT) {
		if (current_sgn.state_t.state == SIGST_EXIT &&
		    current_sgn.state_t.sub_state != SIGSUBST_REBOOT)
			sub_state = SIGSUBST_PANIC_REBOOT;
	}

	/*
	 * offline and detached states only apply to a specific cpu
	 * so ignore them.
	 */
	if (state == SIGST_OFFLINE || state == SIGST_DETACHED) {
		return;
	}

	current_sgn.signature = CPU_SIG_BLD(sig, state, sub_state);

	/*
	 * find the symbol for the mailbox routine
	 */
	rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
	    modgetsymvalue("rmc_comm_request_nowait", 0);
	if (rmc_req_now == NULL) {
		return;
	}

	signature.cpu_id = -1;
	signature.sig = sig;
	signature.states = state;
	signature.sub_state = sub_state;
	req.msg_type = DP_SET_CPU_SIGNATURE;
	req.msg_len = (int)(sizeof (signature));
	req.msg_bytes = 0;
	req.msg_buf = (caddr_t)&signature;

	/*
	 * We need to tell the SP that the host is about to stop running.  The
	 * SP will then allow the date to be set at its console, it will change
	 * state of the activity indicator, it will display the correct host
	 * status, and it will stop sending console messages and alerts to the
	 * host communication channel.
	 *
	 * This requires the RMC_COMM_DREQ_URGENT as we want to
	 * be sure activity indicators will reflect the correct status.
	 *
	 * When sub_state SIGSUBST_DUMP is sent, the urgent flag
	 * (RMC_COMM_DREQ_URGENT) is not required as SIGSUBST_PANIC_REBOOT
	 * has already been sent and changed activity indicators.
	 */
	if (state == SIGST_EXIT && (sub_state == SIGSUBST_HALT ||
	    sub_state == SIGSUBST_REBOOT || sub_state == SIGSUBST_ENVIRON ||
	    sub_state == SIGSUBST_PANIC_REBOOT))
		(void) (rmc_req_now)(&req, RMC_COMM_DREQ_URGENT);
	else
		(void) (rmc_req_now)(&req, 0);
}
Example #5
0
void
load_platform_drivers(void)
{
	/*
	 * It is OK to return error because 'us' driver is not available
	 * in all clusters (e.g. missing in Core cluster).
	 */
	(void) i_ddi_attach_hw_nodes("us");


	/*
	 * mc-us3i must stay loaded for plat_get_mem_unum()
	 */
	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
		cmn_err(CE_WARN, "mc-us3i driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));

	/*
	 * load the power button driver
	 */
	if (i_ddi_attach_hw_nodes("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "power button driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("power"));

	/*
	 * load the GPIO driver for the ALOM reset and watchdog lines
	 */
	if (i_ddi_attach_hw_nodes("pmugpio") != DDI_SUCCESS)
		cmn_err(CE_WARN, "pmugpio failed to install");
	else {
		extern int watchdog_enable, watchdog_available;
		extern int disable_watchdog_on_exit;

		/*
		 * Disable an active h/w watchdog timer upon exit to OBP.
		 */
		disable_watchdog_on_exit = 1;

		watchdog_enable = 1;
		watchdog_available = 1;
	}
	(void) ddi_hold_driver(ddi_name_to_major("pmugpio"));

	/*
	 * Figure out which mi2cv dip is shared with OBP for the nvram
	 * device, so the lock can be acquired.
	 */
	shared_mi2cv_dip = e_ddi_hold_devi_by_path(SHARED_MI2CV_PATH, 0);

	/*
	 * Load the environmentals driver (rmclomv)
	 *
	 * We need this driver to handle events from the RMC when state
	 * changes occur in the environmental data.
	 */
	if (i_ddi_attach_hw_nodes("rmc_comm") != DDI_SUCCESS) {
		cmn_err(CE_WARN, "rmc_comm failed to install");
	} else {
		(void) ddi_hold_driver(ddi_name_to_major("rmc_comm"));

		if (e_ddi_hold_devi_by_path(RMCLOMV_PATHNAME, 0) == NULL) {
			cmn_err(CE_WARN, "Could not install rmclomv driver\n");
		}
	}

	/*
	 * These two dummy functions are loaded over the original
	 * todm5823 set and clear_power_alarm functions. On Boston,
	 * these functionalities are not supported.
	 * The load_platform_drivers(void) is called from post_startup()
	 * which is after all the initialization of the tod module is
	 * finished, then we replace 2 of the tod_ops function pointers
	 * with our dummy version.
	 */
	tod_ops.tod_set_power_alarm = dummy_todm5823_set_power_alarm;
	tod_ops.tod_clear_power_alarm = dummy_todm5823_clear_power_alarm;

	/*
	 * create a handle to the rmc_comm_request_nowait() function
	 * inside the rmc_comm module.
	 *
	 * The Seattle/Boston todm5823 driver will use this handle to
	 * use the rmc_comm_request_nowait() function to send time/date
	 * updates to ALOM.
	 */
	rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
	    modgetsymvalue("rmc_comm_request_nowait", 0);
}
Example #6
0
void
load_platform_drivers(void)
{
	extern int		watchdog_available;
	extern int		watchdog_enable;
	dev_info_t 		*dip;		/* dip of the isa driver */
	int			simba_present = 0;
	dev_info_t		*root_child_node;
	major_t	major;

	if (ddi_install_driver("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "Failed to install \"power\" driver.");

	/*
	 * Install Isa driver. This is required for the southbridge IDE
	 * workaround - to reset the IDE channel during IDE bus reset.
	 * Panic the system in case ISA driver could not be loaded or
	 * any problem in accessing its pci config space. Since the register
	 * to reset the channel for IDE is in ISA config space!.
	 */
	root_child_node = ddi_get_child(ddi_root_node());

	while (root_child_node != NULL) {
		if (strcmp(ddi_node_name(root_child_node), "pci") == 0) {
			root_child_node = ddi_get_child(root_child_node);
			if (strcmp(ddi_node_name(root_child_node), "pci") == 0)
				simba_present = 1;
			break;
		}
		root_child_node = ddi_get_next_sibling(root_child_node);
	}

	if (simba_present)
		dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME_WITH_SIMBA,
		    0);
	else
		dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME, 0);

	if (dip == NULL) {
		cmn_err(CE_PANIC, "Could not install the isa driver\n");
		return;
	}

	if (pci_config_setup(dip, &platform_isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}

	/*
	 * Load the blade support chip driver.
	 *
	 */

	if (((major = ddi_name_to_major(BSC_DRV)) == -1) ||
		(ddi_hold_installed_driver(major) == NULL)) {
		cmn_err(CE_WARN, "%s: failed to load", BSC_DRV);
	} else {

		bsc_drv_func_ptr = (void (*)(struct bscv_idi_info *))
		    modgetsymvalue(BSC_DRV_FUNC, 0);

		if (bsc_drv_func_ptr == NULL) {
			cmn_err(CE_WARN, "load_platform_defaults: %s()"
			" not found; signatures will not be updated\n",
			BSC_DRV_FUNC);
			watchdog_available = 0;
			if (watchdog_enable) {
				cmn_err(CE_WARN, "load_platform_defaults: %s()"
			" not found; BSC OS watchdog service not available\n",
				BSC_DRV_FUNC);
			}
		}
	}
}
Example #7
0
static int
rmc_comm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	struct rmc_comm_state *rcs = NULL;
	sig_state_t *current_sgn_p;
	int instance;

	/*
	 * only allow one instance
	 */
	instance = ddi_get_instance(dip);
	if (instance != 0)
		return (DDI_FAILURE);

	switch (cmd) {
	default:
		return (DDI_FAILURE);

	case DDI_RESUME:
		if ((rcs = rmc_comm_getstate(dip, instance,
		    "rmc_comm_attach")) == NULL)
			return (DDI_FAILURE);	/* this "can't happen" */

		rmc_comm_hw_reset(rcs);
		rmc_comm_set_irq(rcs, B_TRUE);
		rcs->dip = dip;

		mutex_enter(&tod_lock);
		if (watchdog_enable && tod_ops.tod_set_watchdog_timer != NULL &&
		    watchdog_was_active) {
			(void) tod_ops.tod_set_watchdog_timer(0);
		}
		mutex_exit(&tod_lock);

		mutex_enter(rcs->dp_state.dp_mutex);
		dp_reset(rcs, INITIAL_SEQID, 1, 1);
		mutex_exit(rcs->dp_state.dp_mutex);

		current_sgn_p = (sig_state_t *)modgetsymvalue(
			"current_sgn", 0);
		if ((current_sgn_p != NULL) &&
			(current_sgn_p->state_t.sig != 0)) {
			CPU_SIGNATURE(current_sgn_p->state_t.sig,
				current_sgn_p->state_t.state,
				current_sgn_p->state_t.sub_state, -1);
		}
		return (DDI_SUCCESS);

	case DDI_ATTACH:
		break;
	}

	/*
	 *  Allocate the soft-state structure
	 */
	if (ddi_soft_state_zalloc(rmc_comm_statep, instance) != DDI_SUCCESS)
		return (DDI_FAILURE);
	if ((rcs = rmc_comm_getstate(dip, instance, "rmc_comm_attach")) ==
	    NULL) {
		rmc_comm_unattach(rcs, dip, instance, 0, 0, 0);
		return (DDI_FAILURE);
	}
	ddi_set_driver_private(dip, rcs);

	rcs->dip = NULL;

	/*
	 *  Set various options from .conf properties
	 */
	rcs->baud = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "baud-rate", 0);
	rcs->debug = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "debug", 0);

	/*
	 * the baud divisor factor tells us how to scale the result of
	 * the SIO_BAUD_TO_DIVISOR macro for platforms which do not
	 * use the standard 24MHz uart clock
	 */
	rcs->baud_divisor_factor = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
	    DDI_PROP_DONTPASS, "baud-divisor-factor", SIO_BAUD_DIVISOR_MIN);

	/*
	 * try to be reasonable if the scale factor contains a silly value
	 */
	if ((rcs->baud_divisor_factor < SIO_BAUD_DIVISOR_MIN) ||
	    (rcs->baud_divisor_factor > SIO_BAUD_DIVISOR_MAX))
	    rcs->baud_divisor_factor = SIO_BAUD_DIVISOR_MIN;

	/*
	 * initialize serial device
	 */
	if (rmc_comm_serdev_init(rcs, dip) != 0) {
		rmc_comm_unattach(rcs, dip, instance, 0, 0, 0);
		return (DDI_FAILURE);
	}

	/*
	 * initialize data protocol
	 */
	rmc_comm_dp_init(rcs);

	/*
	 * initialize driver interface
	 */
	if (rmc_comm_drvintf_init(rcs) != 0) {
		rmc_comm_unattach(rcs, dip, instance, 0, 1, 1);
		return (DDI_FAILURE);
	}

	/*
	 *  Initialise devinfo-related fields
	 */
	rcs->majornum = ddi_driver_major(dip);
	rcs->instance = instance;
	rcs->dip = dip;

	/*
	 * enable interrupts now
	 */
	rmc_comm_set_irq(rcs, B_TRUE);

	/*
	 *  All done, report success
	 */
	ddi_report_dev(dip);
	mutex_enter(&rmc_comm_attach_lock);
	rcs->is_attached = B_TRUE;
	mutex_exit(&rmc_comm_attach_lock);
	return (DDI_SUCCESS);
}