/* * 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); }
/* * 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)(); }
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; }
/*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); }
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); }
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); } } } }
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); }