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