OpenSolaris

You are not signed in. Sign in or register.
Model-Specific CPU Module Implementation
========================================

Interface: 

Introduction
------------

The CPU model-specific interface in  is mostly
a wrapper into implementation modules that contain the model-specific
information.

Structures
----------

A cms_ops_t details the entry points ofa module:

typedef struct cms_ops {
	int (*cms_init)(cpu_t *, void **);
	void (*cms_post_startup)(void);
	void (*cms_post_mpstartup)(void);
	size_t (*cms_logout_size)(void *);
	uint64_t (*cms_mcgctl_val)(void *, int, uint64_t);
	boolean_t (*cms_bankctl_skipinit)(void *, int);
	uint64_t (*cms_bankctl_val)(void *, int, uint64_t);
	boolean_t (*cms_bankstatus_skipinit)(void *, int);
	uint64_t (*cms_bankstatus_val)(void *, int, uint64_t);
	void (*cms_mca_init)(void *, int);
	uint64_t (*cms_poll_ownermask)(void *, hrtime_t);
	void (*cms_bank_logout)(void *, int, uint64_t, uint64_t, uint64_t,
	    void *);
	uint32_t (*cms_error_action)(void *, int, int, uint64_t, uint64_t,
	    uint64_t, void *);
	void *(*cms_disp_match)(void *, int, uint64_t, uint64_t, uint64_t,
	    void *);
	void (*cms_ereport_class)(void *, void *, const char **, const char **);
	nvlist_t *(*cms_ereport_detector)(void *, void *, nv_alloc_t *);
	boolean_t (*cms_ereport_includestack)(void *, void *);
	void (*cms_ereport_add_logout)(void *, nvlist_t *, nv_alloc_t *, int,
	    uint64_t, uint64_t, uint64_t, void *, void *);
	cms_errno_t (*cms_msrinject)(void *, uint_t, uint64_t);
} cms_ops_t;

cms_init entry point
--------------------

	int (*cms_init)(cpu_t *, void **);

This is called from cms_init for a module whose pathname has matched
the searchpath used by cms_init and which we want to give an opportunity
to initialize;  if it fails or declines to initialize then cms_load
can decide whether to attempt another module or to fallback to
no model-specfic support.

If this module wants to choose to initialize for the indicated CPU
it should return 0;  if not it should return ENOTSUP or other
descriptive non-zero code.

The second argument may be filled with a cookie that will be quoted
in the arguments of other API members;  for example intialization code
could allocate a data structure for this cpu and return the address
of the structure as the cookie.

cms_post_startup entry point
----------------------------

	void (*cms_post_startup)(void);

Called from cms_post_startup when the boot cpu has completed startup.

cms_post_mpstartup entry point
------------------------------

	void (*cms_post_mpstartup)(void);

Called from cms_post_mpstartup when all cpus have completed startup.

cms_logout_size entry point
---------------------------

	size_t (*cms_logout_size)(void *);


Called from cms_logout_size to determine the size of an additional
model-specific error telemetry logout area to provide for the use
of model-specific error logout (i.e., capture of error telemetry).
This area is allocated once for all banks, not per MCA bank.  A pointer
to it is provided in further API members such as cms_bank_logout and
cms_disp_match.

cms_mcgctl_val entry point
--------------------------

	uint64_t (*cms_mcgctl_val)(void *, int, uint64_t);

Called from cms_mcgctl_val to determine an appropriate MCG_CTL
initialization value.  The second argument is the proposed/default
value, which the implementation may choose to clear or add bits to
or to ignore and return an entirely self-constructed value.

cms_bankctl_skipinit entry point
--------------------------------

	boolean_t (*cms_bankctl_skipinit)(void *, int);

Called from cms_bankctl_skipinit to determine if initialization of this
MCA bank number should be skipped.

cms_bankctl_val entry point
---------------------------

	uint64_t (*cms_bankctl_val)(void *, int, uint64_t);

Called from cms_bankctl_val to obtain an appropriate MCi_CTL
initialization value for the indicated MCA bank number.  The last
argument is a proposed/default value.

cms_bankstatus_skipinit entry point
-----------------------------------

	boolean_t (*cms_bankstatus_skipinit)(void *, int);

Called from cms_bankstatus_skipinit to determine if MCA intiialization
should or should not write to MCi_STATUS of the indicated bank.

cms_bankstatus_val entry point
------------------------------

	uint64_t (*cms_bankstatus_val)(void *, int, uint64_t);

Called from cms_bankstatus_val to obtain an appropriate MCi_STATUS
initialization value for the indicated MCA bank number.  The
last argument is a proposed/default value.

cms_mca_init entry point
------------------------

	void (*cms_mca_init)(void *, int);

Called from cms_mca_init for additional model-specific MCA initialization
on a cpu.  The second argument is the number of MCA banks on this
CPU, as per MCG_CAP.

cms_poll_ownermask entry point
------------------------------

	uint64_t (*cms_poll_ownermask)(void *, hrtime_t);

Called from cms_poll_ownermask to determine which MCA banks a poller
"owns" and should poll at this wakeup.  This should return a bitmask
indexed by bank number in which a bit is set if that MCA bank should
be polled.  Model-specific code is responsible for arbitrating between
multiple resources that share the same MCA resources, such as the
various cores of an AMD chip accessing the shared NorthBridge MCA state.
The second argument is the poller interval in use, and can be used
to timeout a "current owner" that has become unresponsive.  Model-specific
code should attempt to ensure that the "current owner" remains the
same until external events such as reconfiguration or cpu offline
interfere.

cms_bank_logout entry point
---------------------------

	void (*cms_bank_logout)(void *, int, uint64_t, uint64_t, uint64_t,
	    void *);

Called from cms_bank_logout to allow model-specific support to capture
additional model-specific error telemetry at error handling time.
The arguments provide the MCA bank number, the MCi_{STATUS,ADDR,MISC}
values that have already been read, and a pointer to a buffer of size
as previously requested via cms_logout_size which this entry point can
use as it wishes to store model-specific telemetry.  This buffer will
be quoted to other API members during error classification and logging.

cms_error_action entry point
----------------------------

	uint32_t (*cms_error_action)(void *, int, int, uint64_t, uint64_t,
	    uint64_t, void *);

Called from cms_error_action to permit model-specific code to perform
additional error-handling actions and to return an indication of the
final status of the system in terms of the presence of uncorrected
data, whether it has been poisoined, and whether the current context
is affected.

cms_disp_match entry point
--------------------------

	void *(*cms_disp_match)(void *, int, uint64_t, uint64_t, uint64_t,
	    void *);

Called from cms_disp_match to permit model-specific code to classify
the error (based on MCA bank number, MCi_{STATUS,ADDR,MISC} and
the model-specific logout info collect in cms_bank_logout) and
return a cookie that correlate to that classification (such as the
address of a data structure describing the error classification info).
This is called during error logging code, not from error handling.

cms_ereport_class entry point
-----------------------------

	void (*cms_ereport_class)(void *, void *, const char **, const char **);

Called from cms_ereport_class to permit model-specific code to supply
information for an ereport class name.  If it does not choose to
supply such information then the consumer should generate an appropriate
generic or unknown ereport class.

cms_ereport_detector entry point
--------------------------------

	nvlist_t *(*cms_ereport_detector)(void *, void *, nv_alloc_t *);

Called from cms_ereport_detector to permit model-specific code to
generate a model-specific FMRI for the detector of an error.  If
this entry point is not implemented or if it returns NULL then
the consumer should use some generic detector FMRI.

cms_ereport_includestack entry point
------------------------------------

	boolean_t (*cms_ereport_includestack)(void *, void *);

For the error classification previously returned in cms_disp_match
indicate whether stack trace information was captured and whether
it should be included in the ereport payload.  This payload member
is handled differently to those added via the cms_ereport_add_logout
entry point to allow stacks to be added as an easy debug switch.

cms_ereport_add_logout entry point
----------------------------------

	void (*cms_ereport_add_logout)(void *, nvlist_t *, nv_alloc_t *, int,
	    uint64_t, uint64_t, uint64_t, void *, void *);

This is called from cms_ereport_add_logout to allow model-specific
code to add model-specific ereport payload members to teh partially
constructed ereport nvlist.  Further nvlist manipulations are required
to use the nv_alloc_t provided in the arguments.  Other arguments
indicate the MCA bank nnumber, MCi_{STATUS,ADDR,MISC}, model-specific
logout buffer, and classification cookie from cms_disp_match.

cms_msrinject entry point
-------------------------

	cms_errno_t (*cms_msrinject)(void *, uint_t, uint64_t);

Called from cms_msrinject to write the specified MSR to the given
value, possibly wrapped in additional writes to unlock/relock
the register for writing (as determined by model-specific code).
Should return CMS_SUCCESS or an CMS_ERRNO_* indication.