cmi.c revision 7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fe
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Use is subject to license terms.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#pragma ident "%Z%%M% %I% %E% SMI"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Public interface to routines implemented by CPU modules
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/x86_archext.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/cpu_module_impl.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/fm/util.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/reboot.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/modctl.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/param.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/cmn_err.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/systm.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/types.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#define CPUMOD_SUBDIR "cpu"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#define CPUMOD_PREFIX "cpu"
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#define CMI_OPS(cpu) \
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (cpu)->cpu_m.mcpu_cmi->cmi_ops
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#define CMI_DATA(cpu) \
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (cpu)->cpu_m.mcpu_cmidata
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
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 */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint cmi_panic_on_uncorrectable_error = 1;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic cmi_t *cmi_list;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic kmutex_t cmi_load_lock;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_cpu_match(cpu_t *c1, cpu_t *c2)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (cpuid_getfamily(c1) == cpuid_getfamily(c2) &&
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cpuid_getmodel(c1) == cpuid_getmodel(c2) &&
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cpuid_getstep(c1) == cpuid_getstep(c2) &&
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi strcmp(cpuid_getvendorstr(c1), cpuid_getvendorstr(c2)) == 0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic cmi_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_load_modctl(modctl_t *modp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uintptr_t ops;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi_t *cmi;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ASSERT(MUTEX_HELD(&cmi_load_lock));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (cmi = cmi_list; cmi != NULL; cmi = cmi->cmi_next) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (cmi->cmi_modp == modp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (cmi);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((ops = modlookup_by_modctl(modp, "_cmi_ops")) == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmn_err(CE_WARN, "CPU module %s is invalid: no _cmi_ops "
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "found\n", modp->mod_modname);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
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 */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mutex_enter(&mod_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modp->mod_ref++;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mutex_exit(&mod_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi = kmem_zalloc(sizeof (cmi_t), KM_SLEEP);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi->cmi_ops = (const cmi_ops_t *)ops;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi->cmi_modp = modp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi->cmi_next = cmi_list;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi_list = cmi;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (cmi);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic cmi_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_load_module(cpu_t *cp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modctl_t *modp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi_t *cmi;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i, modid;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t s[3];
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
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 */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ASSERT(MUTEX_HELD(&cmi_load_lock));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mutex_enter(&cpu_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < NCPU; i++) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cpu_t *cp2 = cpu[i];
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (cp2 != NULL && cp2 != cp &&
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cp2->cpu_m.mcpu_cmi != NULL && cmi_cpu_match(cp, cp2)) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mutex_exit(&cpu_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (cp2->cpu_m.mcpu_cmi);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mutex_exit(&cpu_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
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 */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi s[0] = cpuid_getfamily(cp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi s[1] = cpuid_getmodel(cp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi s[2] = cpuid_getstep(cp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modid = modload_qualified(CPUMOD_SUBDIR, CPUMOD_PREFIX,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cpuid_getvendorstr(cp), ".", s, sizeof (s) / sizeof (s[0]));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (modid == -1)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modid = modload(CPUMOD_SUBDIR, CPUMOD_PREFIX ".generic");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (modid == -1)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modp = mod_hold_by_id(modid);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi = cmi_load_modctl(modp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mod_release_mod(modp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (cmi);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic cmi_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_load_generic(void)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modctl_t *modp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi_t *cmi;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int modid;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((modid = modload(CPUMOD_SUBDIR, CPUMOD_PREFIX ".generic")) == -1)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi modp = mod_hold_by_id(modid);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi = cmi_load_modctl(modp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mod_release_mod(modp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (cmi);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
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 */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_load(cpu_t *cp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err = ENOENT;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi_t *cmi;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi void *data;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mutex_enter(&cmi_load_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((cmi = cmi_load_module(cp)) == NULL || (
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (err = cmi->cmi_ops->cmi_init(cp, &data)) != 0 && err != ENOTSUP)) {
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 mutex_exit(&cmi_load_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (err != 0 && ((cmi = cmi_load_generic()) == NULL ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (err = cmi->cmi_ops->cmi_init(cp, &data)) != 0)) {
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 mutex_exit(&cmi_load_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ASSERT(cp->cpu_m.mcpu_cmi == NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cp->cpu_m.mcpu_cmi = cmi;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cp->cpu_m.mcpu_cmidata = data;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmi->cmi_refcnt++;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mutex_exit(&cmi_load_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (boothowto & RB_VERBOSE) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi printf("cpuid %d: initialized cpumod: %s\n",
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cp->cpu_id, cmi->cmi_modp->mod_modname);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_init(void)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (cmi_load(CPU) < 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi panic("failed to load module for CPU %u", CPU->cpu_id);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_post_init(void)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi CMI_OPS(CPU)->cmi_post_init(CMI_DATA(CPU));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_faulted_enter(cpu_t *cp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi CMI_OPS(cp)->cmi_faulted_enter(CMI_DATA(cp));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_faulted_exit(cpu_t *cp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi CMI_OPS(cp)->cmi_faulted_exit(CMI_DATA(cp));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_scrubber_enable(cpu_t *cp, uint64_t base, uint64_t ilen)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (CMI_OPS(cp)->cmi_scrubber_enable(CMI_DATA(cp), base, ilen));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mca_init(void)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi CMI_OPS(CPU)->cmi_mca_init(CMI_DATA(CPU));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mca_trap(struct regs *rp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (CMI_OPS(CPU)->cmi_mca_trap(CMI_DATA(CPU), rp)) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (cmi_panic_on_uncorrectable_error)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi fm_panic("Unrecoverable Machine-Check Exception");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi else
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cmn_err(CE_WARN, "suppressing panic from fatal #mc");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mca_inject(cmi_mca_regs_t *regs, uint_t nregs)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi kpreempt_disable();
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err = CMI_OPS(CPU)->cmi_mca_inject(CMI_DATA(CPU), regs, nregs);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi kpreempt_enable();
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (err);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mca_poke(void)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi CMI_OPS(CPU)->cmi_mca_poke(CMI_DATA(CPU));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mc_register(cpu_t *cp, const cmi_mc_ops_t *mcops, void *mcdata)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi CMI_OPS(cp)->cmi_mc_register(CMI_DATA(cp), mcops, mcdata);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mc_patounum(uint64_t pa, uint32_t synd, int syndtype, mc_unum_t *up)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const struct cmi_mc_ops *mcops;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cpu_t *cp = CPU;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (CMI_OPS(cp) == NULL ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (mcops = CMI_OPS(cp)->cmi_mc_getops(CMI_DATA(cp))) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1); /* not registered yet */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (mcops->cmi_mc_patounum(CMI_DATA(cp), pa, synd, syndtype, up));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindicmi_mc_unumtopa(mc_unum_t *up, nvlist_t *nvl, uint64_t *pap)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const struct cmi_mc_ops *mcops;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi cpu_t *cp = CPU;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (up != NULL && nvl != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1); /* only convert from one or the other form */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (CMI_OPS(cp) == NULL ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (mcops = CMI_OPS(cp)->cmi_mc_getops(CMI_DATA(cp))) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1); /* not registered yet */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (mcops->cmi_mc_unumtopa(CMI_DATA(cp), up, nvl, pap));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}