cmi.c revision 8a40a695ee676a322b094e9afe5375567bfb51e3
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * CDDL HEADER START
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * The contents of this file are subject to the terms of the
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * Common Development and Distribution License (the "License").
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * You may not use this file except in compliance with the License.
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * See the License for the specific language governing permissions
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * and limitations under the License.
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * When distributing Covered Code, include this CDDL HEADER in each
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * If applicable, add the following below this CDDL HEADER, with the
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * fields enclosed by brackets "[]" replaced with your own identifying
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * information: Portions Copyright [yyyy] [name of copyright owner]
3ad553a7dabf3c8bcb69dd1ceeb13938fa526aedgavinm * CDDL HEADER END
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Use is subject to license terms.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#pragma ident "%Z%%M% %I% %E% SMI"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Public interface to routines implemented by CPU modules
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * If cleared for debugging we will not attempt to load a model-specific
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * cpu module but will load the generic cpu module instead.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If cleared for debugging, we will suppress panicking on fatal hardware
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * errors. This should *only* be used for debugging; it use can and will
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * cause data corruption if actual hardware errors are detected by the system.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi strcmp(cpuid_getvendorstr(c1), cpuid_getvendorstr(c2)) == 0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (cmi = cmi_list; cmi != NULL; cmi = cmi->cmi_next) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((ops = modlookup_by_modctl(modp, "_cmi_ops")) == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmn_err(CE_WARN, "CPU module %s is invalid: no _cmi_ops "
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Hold the module in memory. We call to CPU modules without using the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * stubs mechanism, so these modules must be manually held in memory.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * The mod_ref acts as if another loaded module has a dependency on us.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Look to see if we've already got a module loaded for a CPU just
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * like this one. If we do, then we'll re-use it.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < NCPU; i++) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cp2->cpu_m.mcpu_cmi != NULL && cmi_cpu_match(cp, cp2)) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If we can't find a match, attempt to load the appropriate module.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If that also fails, try to load the generic CPU module.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modid = modload_qualified(CPUMOD_SUBDIR, CPUMOD_PREFIX,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cpuid_getvendorstr(cp), ".", s, sizeof (s) / sizeof (s[0]));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modid = modload(CPUMOD_SUBDIR, CPUMOD_PREFIX ".generic");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((modid = modload(CPUMOD_SUBDIR, CPUMOD_PREFIX ".generic")) == -1)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Load a CPU module for the specified CPU, and then call its cmi_init routine.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If the module returns ENOTSUP, try using the generic CPU module instead.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If all else fails, we return -1 and the caller will panic or halt.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmn_err(CE_WARN, "CPU module %s failed to init CPU %d: err=%d",
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi ? cmi->cmi_modp->mod_modname : "<>", cp->cpu_id, err);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmn_err(CE_WARN, "CPU module %s failed to init CPU %d: err=%d",
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi ? cmi->cmi_modp->mod_modname : "<>", cp->cpu_id, err);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi panic("failed to load module for CPU %u", CPU->cpu_id);
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * Called just once from start_other_cpus when all processors are started.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * This will not be called for each cpu, so the registered op must not
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm * assume it is called as such.
8a40a695ee676a322b094e9afe5375567bfb51e3gavinmcmi_scrubber_enable(cpu_t *cp, uint64_t base, uint64_t ilen, int cscontig)
8a40a695ee676a322b094e9afe5375567bfb51e3gavinm return (CMI_OPS(cp)->cmi_scrubber_enable(CMI_DATA(cp), base, ilen,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err = CMI_OPS(CPU)->cmi_mca_inject(CMI_DATA(CPU), regs, nregs);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mc_register(cpu_t *cp, const cmi_mc_ops_t *mcops, void *mcdata)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi CMI_OPS(cp)->cmi_mc_register(CMI_DATA(cp), mcops, mcdata);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mc_patounum(uint64_t pa, uint32_t synd, int syndtype, mc_unum_t *up)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (mcops = CMI_OPS(cp)->cmi_mc_getops(CMI_DATA(cp))) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (mcops->cmi_mc_patounum(CMI_DATA(cp), pa, synd, syndtype, up));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mc_unumtopa(mc_unum_t *up, nvlist_t *nvl, uint64_t *pap)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1); /* only convert from one or the other form */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (mcops = CMI_OPS(cp)->cmi_mc_getops(CMI_DATA(cp))) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (mcops->cmi_mc_unumtopa(CMI_DATA(cp), up, nvl, pap));