xref: /onnv-gate/usr/src/uts/i86pc/cpu/amd_opteron/ao.h (revision 10947:2ecbb0a4d189)
11414Scindi /*
21414Scindi  * CDDL HEADER START
31414Scindi  *
41414Scindi  * The contents of this file are subject to the terms of the
51538Sgavinm  * Common Development and Distribution License (the "License").
61538Sgavinm  * You may not use this file except in compliance with the License.
71414Scindi  *
81414Scindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91414Scindi  * or http://www.opensolaris.org/os/licensing.
101414Scindi  * See the License for the specific language governing permissions
111414Scindi  * and limitations under the License.
121414Scindi  *
131414Scindi  * When distributing Covered Code, include this CDDL HEADER in each
141414Scindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151414Scindi  * If applicable, add the following below this CDDL HEADER, with the
161414Scindi  * fields enclosed by brackets "[]" replaced with your own identifying
171414Scindi  * information: Portions Copyright [yyyy] [name of copyright owner]
181414Scindi  *
191414Scindi  * CDDL HEADER END
201414Scindi  */
211414Scindi 
221414Scindi /*
23*10947SSrihari.Venkatesan@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
241414Scindi  * Use is subject to license terms.
251414Scindi  */
261414Scindi 
271414Scindi #ifndef _AO_H
281414Scindi #define	_AO_H
291414Scindi 
301414Scindi #include <sys/types.h>
311414Scindi #include <sys/mc.h>
321414Scindi #include <sys/mca_amd.h>
333164Sgavinm #include <sys/mc_amd.h>
345254Sgavinm #include <sys/cpu_module_ms_impl.h>
351414Scindi #include <sys/nvpair.h>
361414Scindi #include <sys/cyclic.h>
371414Scindi #include <sys/errorq.h>
381414Scindi #include <sys/kobj.h>
391414Scindi #include <sys/fm/util.h>
401414Scindi 
411414Scindi #ifdef __cplusplus
421414Scindi extern "C" {
431414Scindi #endif
441414Scindi 
455254Sgavinm #define	AO_MAX_CHIPS		8
465254Sgavinm 
471414Scindi #define	AO_MCA_MAX_ERRORS	10
481414Scindi 
495254Sgavinm typedef struct ao_ms_data ao_ms_data_t;
501414Scindi 
511414Scindi /*
521414Scindi  * Rather than using torturous conditionals, we match errors using a table of
531414Scindi  * ao_error_disp_t's.  The members in the ao_error_disp_t are matched against
541414Scindi  * the value of MCi_STATUS, with a successful match indicating that the given
551414Scindi  * error occurred.
561414Scindi  *
571414Scindi  * While aed_stat_code will match most of the status code bits, a few of the
581414Scindi  * status code fields are either/or, and are treated separately so as to
591414Scindi  * minimize the number of ao_error_disp_t structures that must be created.
601414Scindi  * For example, the dc.tag_par error can have r4 values drd or dwr.  Rather
611414Scindi  * than creating two ao_error_disp_t's, we use the separate aed_stat_r4_bits
621414Scindi  * field to indicate both AO_MCA_R4_BIT_DRD and AO_MCA_R4_BIT_DWD.  As the
631414Scindi  * matching r4 values are drawn from aed_stat_r4_bits, we don't use the r4
641414Scindi  * bits in aed_stat_code for matching.  Similar reasoning lies behind the
651414Scindi  * creation of the pp and ii fields.
661414Scindi  */
671538Sgavinm #define	AO_AED_PANIC_NEVER	0x00
681538Sgavinm #define	AO_AED_PANIC_IFMCE	0x01
691538Sgavinm #define	AO_AED_PANIC_ALWAYS	0x80
701414Scindi 
715254Sgavinm /*
725254Sgavinm  * The AO_AED_F_* flags tell us how to interpret aspects of the error
735254Sgavinm  * telemetry, such as which bits of the captured address are valid for
745254Sgavinm  * this error.
755254Sgavinm  */
765254Sgavinm 					/* MCi_ADDR ... */
775254Sgavinm #define	AO_AED_F_LINEAR		0x01	/* is a linear address */
785254Sgavinm #define	AO_AED_F_PHYSICAL	0x02	/* is a physical address */
795254Sgavinm #define	AO_AED_F_PAGEALIGNED	0x04	/* aligns to page size */
805254Sgavinm #define	AO_AED_F_L2SETWAY	0x08	/* 3:0 = way, 15/14/13/12:6 = set */
813164Sgavinm 
823164Sgavinm #define	AO_AED_FLAGS_ADDRTYPE	(AO_AED_F_LINEAR | AO_AED_F_PHYSICAL | \
833164Sgavinm     AO_AED_F_PAGEALIGNED | AO_AED_F_L2SETWAY)
841414Scindi 
855254Sgavinm /*
865254Sgavinm  * The AO_AED_ET_* flags group individual error dispositions into
875254Sgavinm  * error types.  This is used to nominate additional telemetry beyond the
885254Sgavinm  * architectural bank registers to capture for this error type.
895254Sgavinm  */
905254Sgavinm #define	AO_AED_ET_MEMECC		0x0001	/* Main memory ECC error */
915254Sgavinm 
921414Scindi typedef struct ao_error_disp {
931414Scindi 	const char *aed_class;		/* ereport class for use if match */
941414Scindi 	uint64_t aed_ereport_members;	/* ereport contents flags if match */
951414Scindi 	uint64_t aed_stat_mask;		/* status msr bits for match */
961414Scindi 	uint64_t aed_stat_mask_res;	/* status mask result for match */
971414Scindi 	uint16_t aed_stat_code;		/* status code for match */
981414Scindi 	uint8_t aed_stat_extcode;	/* extended status code for match */
991414Scindi 	uint8_t aed_stat_pp_bits:4;	/* AO_MCA_PP_BIT_* for pp matching */
1001414Scindi 	uint8_t aed_stat_ii_bits:4;	/* AO_MCA_II_BIT_* for ii matching */
1011414Scindi 	uint16_t aed_stat_r4_bits;	/* AO_MCA_R4_BIT_* for r4 matching */
1023164Sgavinm 	uint8_t aed_addrvalid_hi;	/* most significant valid addr bit */
1033164Sgavinm 	uint8_t aed_addrvalid_lo;	/* least significant valid addr bit */
1041414Scindi 	uint8_t aed_panic_when;		/* extra conditions for panic */
1055254Sgavinm 	uint16_t aed_flags;		/* AO_AED_F_* */
1065254Sgavinm 	uint16_t aed_errtype;		/* AO_AED_ET_* */
1071414Scindi } ao_error_disp_t;
1081414Scindi 
1091414Scindi /*
1105254Sgavinm  * We store non-architectutal config as inherited from the BIOS to assist
1115254Sgavinm  * in troubleshooting.
1121414Scindi  */
1135254Sgavinm struct ao_bios_cfg {
1145254Sgavinm 	uint64_t *bcfg_bank_mask;
1155254Sgavinm };
1161414Scindi 
1171414Scindi /*
1181414Scindi  * The master data structure used to hold MCA-related state.
1191414Scindi  */
1205254Sgavinm typedef struct ao_ms_mca {
1215254Sgavinm 	struct ao_bios_cfg ao_mca_bios_cfg;
1221414Scindi 	kmutex_t ao_mca_poll_lock;	/* keep pollers from colliding */
1231414Scindi 	uint_t ao_mca_flags;		/* AO_MCA_F_* */
1245254Sgavinm } ao_ms_mca_t;
1251414Scindi 
1261414Scindi /*
1275254Sgavinm  * Per-chip shared state
1282869Sgavinm  */
1292869Sgavinm struct ao_chipshared {
1305254Sgavinm 	uint32_t aos_chiprev;
1312869Sgavinm 	volatile ulong_t aos_cfgonce;	/* Config performed once per chip */
1325254Sgavinm 	hrtime_t aos_nb_poll_timestamp;
1335254Sgavinm 	cmi_hdl_t aos_nb_poll_owner;
1345254Sgavinm 	uint64_t aos_bcfg_nb_misc;	/* BIOS value of MC4_MISC MSR */
1352869Sgavinm 	uint32_t aos_bcfg_nb_cfg;	/* BIOS value of NB MCA Config */
1362869Sgavinm 	uint32_t aos_bcfg_nb_sparectl;	/* BIOS value of Online Spare Control */
1373766Sgavinm 	uint32_t aos_bcfg_dcfg_lo;	/* BIOS value of DRAM Config Low */
1383766Sgavinm 	uint32_t aos_bcfg_dcfg_hi;	/* BIOS value of DRAM Config High */
1395254Sgavinm 	uint32_t aos_bcfg_scrubctl;	/* BIOS value of scrub control */
1402869Sgavinm };
1412869Sgavinm 
1425254Sgavinm /* Bit numbers for once-per-chip operations policed by cms_once */
1432869Sgavinm enum ao_cfgonce_bitnum {
1443766Sgavinm 	AO_CFGONCE_NBMCA,
1455254Sgavinm 	AO_CFGONCE_NBCFG,
1463766Sgavinm 	AO_CFGONCE_DRAMCFG
1472869Sgavinm };
1482869Sgavinm 
1492869Sgavinm /*
1505254Sgavinm  * Per-CPU model-specific state
1511414Scindi  */
1525254Sgavinm struct ao_ms_data {
1535254Sgavinm 	cmi_hdl_t ao_ms_hdl;
1545254Sgavinm 	ao_ms_mca_t ao_ms_mca;
1555254Sgavinm 	struct ao_chipshared *ao_ms_shared;
1565254Sgavinm 	uint64_t ao_ms_hwcr_val;
1571414Scindi };
1581414Scindi 
1591414Scindi #ifdef _KERNEL
1601414Scindi 
1611414Scindi struct regs;
1621414Scindi 
1635254Sgavinm /*
1645254Sgavinm  * Our cms_ops operations and function prototypes for all non-NULL members.
1655254Sgavinm  */
1665254Sgavinm extern const cms_ops_t _cms_ops;
1671414Scindi 
1685254Sgavinm extern int ao_ms_init(cmi_hdl_t, void **);
1695254Sgavinm extern void ao_ms_post_startup(cmi_hdl_t);
1705254Sgavinm extern void ao_ms_post_mpstartup(cmi_hdl_t);
1715254Sgavinm extern uint64_t ao_ms_mcgctl_val(cmi_hdl_t, int, uint64_t);
1725254Sgavinm extern boolean_t ao_ms_bankctl_skipinit(cmi_hdl_t, int);
1735254Sgavinm extern uint64_t ao_ms_bankctl_val(cmi_hdl_t, int, uint64_t);
1745254Sgavinm extern void ao_ms_mca_init(cmi_hdl_t, int);
1755254Sgavinm extern uint64_t ao_ms_poll_ownermask(cmi_hdl_t, hrtime_t);
1765254Sgavinm extern uint32_t ao_ms_error_action(cmi_hdl_t, int, int, uint64_t,
1775254Sgavinm     uint64_t, uint64_t, void *);
1785254Sgavinm extern cms_cookie_t ao_ms_disp_match(cmi_hdl_t, int, uint64_t, uint64_t,
1795254Sgavinm     uint64_t, void *);
1805254Sgavinm extern void ao_ms_ereport_class(cmi_hdl_t, cms_cookie_t, const char **,
1815254Sgavinm     const char **);
1825254Sgavinm extern boolean_t ao_ms_ereport_includestack(cmi_hdl_t, cms_cookie_t);
1835254Sgavinm extern void ao_ms_ereport_add_logout(cmi_hdl_t, nvlist_t *,
1845254Sgavinm     nv_alloc_t *, int, uint64_t, uint64_t, uint64_t, void *, void *);
1855254Sgavinm extern cms_errno_t ao_ms_msrinject(cmi_hdl_t, uint_t, uint64_t);
1861414Scindi 
1875254Sgavinm /*
1885254Sgavinm  * Local functions
1895254Sgavinm  */
190*10947SSrihari.Venkatesan@Sun.COM extern void ao_procnode_scrubber_enable(cmi_hdl_t, ao_ms_data_t *);
1911414Scindi extern void ao_pcicfg_write(uint_t, uint_t, uint_t, uint32_t);
1921414Scindi extern uint32_t ao_pcicfg_read(uint_t, uint_t, uint_t);
1935254Sgavinm extern void ao_bankstatus_prewrite(cmi_hdl_t, ao_ms_data_t *);
1945254Sgavinm extern void ao_bankstatus_postwrite(cmi_hdl_t, ao_ms_data_t *);
1952869Sgavinm 
1961414Scindi #endif /* _KERNEL */
1971414Scindi 
1981414Scindi #ifdef __cplusplus
1991414Scindi }
2001414Scindi #endif
2011414Scindi 
2021414Scindi #endif /* _AO_H */
203