cms.c revision a31148363f598def767ac48c5d82e1572e44b935
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2010, Intel Corporation.
* All rights reserved.
*/
#include <sys/cpu_module_ms_impl.h>
#include <sys/x86_archext.h>
/*
* Set to prevent model-specific support from initialising.
*/
int cms_no_model_specific = 0;
/*
* Subdirectory (relative to the module search path) in which we will
* look for model-specific modules.
*/
#define CPUMOD_MS_SUBDIR "cpu"
/*
* Cpu model-specific modules have filenames beginning with the following.
*/
#define CPUMOD_MS_PREFIX "cpu_ms"
struct cms_cpuid {
const char *vendor;
};
#define CMS_MATCH_VENDOR 0 /* Just match on vendor */
/*
* Structure used to keep track of modules we have loaded.
*/
typedef struct cms {
} cms_t;
static kmutex_t cms_load_lock;
/*
* We stash a cms_t and associated private data via cmi_hdl_setspecific.
*/
struct cms_ctl {
void *cs_cmsdata;
};
static cms_t *
{
}
void *
{
}
static void
{
}
static void
{
}
/*
* Hold the module in memory. We call to CPU modules without using the
* stubs mechanism, so these modules must be manually held in memory.
* The mod_ref acts as if another loaded module has a dependency on us.
*/
static void
{
cms->cms_refcnt++;
}
static void
{
if (--cms->cms_refcnt == 0) {
}
}
static cms_ops_t *
{
NULL) {
return (NULL);
}
return (NULL);
}
return (ops);
}
static cms_t *
{
return (cms);
}
return (NULL);
} else {
if (!CMS_API_VERSION_CHKMAGIC(apiver)) {
"invalid: _cms_api_version 0x%x has bad magic",
return (NULL);
}
}
if (apiver != CMS_API_VERSION) {
"version %d, kernel requires API version %d",
return (NULL);
}
return (NULL);
return (cms);
}
static int
{
if (match >= CMS_MATCH_VENDOR &&
return (0);
if (match >= CMS_MATCH_FAMILY &&
return (0);
if (match >= CMS_MATCH_MODEL &&
return (0);
if (match >= CMS_MATCH_STEPPING &&
return (0);
return (1);
}
static int
{
return (CMI_HDL_WALK_DONE);
} else {
return (CMI_HDL_WALK_NEXT);
}
}
/*
* Look to see if we've already got a module loaded for a CPU just
* like this one. If we do, then we'll re-use it.
*/
static cms_t *
{
if (dhdl) {
}
return (cms);
}
/*
* Try to find or load a module that offers model-specific support for
* a module we look in CPUMOD_MS_SUBDIR first for a match on
* on vendor alone.
*/
static cms_t *
{
int modid;
uint_t s[3];
s[0] = cmi_hdl_family(hdl);
/*
* Have we already loaded a module for a cpu with the same
*/
return (cms);
}
if (modid == -1)
return (NULL);
if (cms)
return (cms);
}
static cms_t *
{
int err;
int i;
for (i = CMS_MATCH_STEPPING; i >= CMS_MATCH_VENDOR; i--) {
int suffixlevel;
return (NULL);
/*
* A module has loaded and has a _cms_ops structure, and the
* module has been held for this instance. Call the cms_init
* entry point - we expect success (0) or ENOTSUP.
*/
if (boothowto & RB_VERBOSE) {
printf("initialized model-specific "
"module '%s' on chip %d core %d "
"strand %d\n",
}
return (cms);
"module '%s' on chip %d core %d strand %d: err=%d",
}
/*
* The module failed or declined to init, so release
* it and potentially change i to be equal to he number
* of suffices actually used in the last module path.
*/
i = suffixlevel;
}
return (NULL);
}
void
{
void *data;
if (cms_no_model_specific != 0)
return;
}
}
void
{
}
}
{
}
void
{
}
void
{
}
{
return (0);
}
{
return (def);
}
{
return (B_FALSE);
}
{
return (def);
}
{
return (B_FALSE);
}
{
return (def);
}
void
{
}
{
else
return (-1ULL); /* poll all banks by default */
}
void
{
}
{
else
return (CMSERR_NOTSUP);
}
{
else
return (0);
}
{
else
return (NULL);
}
void
const char **leafclsp)
{
return;
leafclsp);
}
}
nvlist_t *
{
else
return (NULL);
}
{
} else {
return (B_FALSE);
}
}
void
{
}