xref: /illumos-gate/usr/src/common/mc/mc-amd/mcamd_api.h (revision bea83d026ee1bd1b2a2419e1d0232f107a5d7d9b)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _MCAMD_API_H
28 #define	_MCAMD_API_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*
33  * Primary header file for mcamd_* routines in $SRC/common/mc.  The
34  * routines not implemented there are required to be implemented in the
35  * kernel or userland consumer of this interface (such as the mc-amd driver).
36  * The common code must use the wrapper functions provided by the consumer
37  * to navigate the MC tree, get properties etc.
38  */
39 
40 #if defined(_KERNEL)
41 #include <sys/systm.h>
42 #include <sys/sunddi.h>
43 #else
44 #include <string.h>
45 #include <assert.h>
46 #endif
47 
48 #include <sys/types.h>
49 #include <sys/mc.h>
50 #include <sys/mca_amd.h>
51 #include <sys/mc_amd.h>
52 
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56 
57 /*
58  * Consumers of this common code must implement the following types.
59  */
60 typedef struct mcamd_node mcamd_node_t;
61 struct mcamd_hdl;
62 
63 /*
64  * Properties and raw register values for an mcamd_node_t are retrieved via
65  * mcamd_get_numprop(s) and mcamd_get_cfgreg(s) specifying a property or
66  * register code below.
67  */
68 
69 typedef uint64_t mcamd_prop_t;
70 typedef uint32_t mcamd_cfgreg_t;
71 
72 typedef enum mcamd_propcode {
73 	/*
74 	 * Common properties
75 	 */
76 	MCAMD_PROP_NUM = 0x4000,
77 #define	MCAMD_PROPSTR_NUM		"num"
78 	MCAMD_PROP_SIZE,
79 #define	MCAMD_PROPSTR_SIZE		"size"
80 	MCAMD_PROP_BASE_ADDR,
81 #define	MCAMD_PROPSTR_BASE_ADDR		"base-addr"
82 	/*
83 	 * Memory controller properties
84 	 */
85 	MCAMD_PROP_REV = 0x5000,
86 #define	MCAMD_PROPSTR_REV		"revision"
87 	MCAMD_PROP_LIM_ADDR,
88 #define	MCAMD_PROPSTR_LIM_ADDR		"lim-addr"
89 	MCAMD_PROP_ILEN,
90 #define	MCAMD_PROPSTR_ILEN		"node-ilen"
91 	MCAMD_PROP_ILSEL,
92 #define	MCAMD_PROPSTR_ILSEL		"node-ilsel"
93 	MCAMD_PROP_CSINTLVFCTR,
94 #define	MCAMD_PROPSTR_CSINTLVFCTR	"cs-intlv-factor"
95 	MCAMD_PROP_DRAMHOLE_SIZE,
96 #define	MCAMD_PROPSTR_DRAMHOLE_SIZE	"dram-hole-size"
97 	MCAMD_PROP_ACCESS_WIDTH,
98 #define	MCAMD_PROPSTR_ACCESS_WIDTH	"access-width"
99 	MCAMD_PROP_CSBANKMAPREG,
100 #define	MCAMD_PROPSTR_CSBANKMAPREG	"bank-mapping"
101 	MCAMD_PROP_BANKSWZL,
102 #define	MCAMD_PROPSTR_BANKSWZL		"bankswizzle"
103 	MCAMD_PROP_MOD64MUX,
104 #define	MCAMD_PROPSTR_MOD64MUX		"mismatched-dimm-support"
105 	MCAMD_PROP_SPARECS,
106 #define	MCAMD_PROPSTR_SPARECS		"spare-csnum"
107 	MCAMD_PROP_BADCS,
108 #define	MCAMD_PROPSTR_BADCS		"bad-csnum"
109 	/*
110 	 * Chip-select properties
111 	 */
112 	MCAMD_PROP_MASK = 0x6000,
113 #define	MCAMD_PROPSTR_MASK		"mask"
114 	MCAMD_PROP_CSBE,
115 #define	MCAMD_PROPSTR_CSBE		"cs-bank-enable"
116 	MCAMD_PROP_SPARE,
117 #define	MCAMD_PROPSTR_SPARE		"online-spare"
118 	MCAMD_PROP_TESTFAIL,
119 #define	MCAMD_PROPSTR_TESTFAIL		"failed-test"
120 	MCAMD_PROP_CSDIMM1,
121 #define	MCAMD_PROPSTR_CSDIMM1		"dimm1-num"
122 	MCAMD_PROP_CSDIMM2,
123 #define	MCAMD_PROPSTR_CSDIMM2		"dimm2-num"
124 	MCAMD_PROP_DIMMRANK
125 #define	MCAMD_PROPSTR_DIMMRANK		"dimm-rank"
126 } mcamd_propcode_t;
127 
128 typedef enum mcamd_regcode {
129 	MCAMD_REG_DRAMBASE = 0x7000,
130 	MCAMD_REG_DRAMLIMIT,
131 	MCAMD_REG_DRAMHOLE,
132 	MCAMD_REG_DRAMCFGLO,
133 	MCAMD_REG_DRAMCFGHI,
134 	MCAMD_REG_CSBASE,
135 	MCAMD_REG_CSMASK
136 } mcamd_regcode_t;
137 /*
138  * Flags for mcamd_dprintf
139  */
140 #define	MCAMD_DBG_ERR		0x1
141 #define	MCAMD_DBG_FLOW		0x2
142 
143 typedef union mcamd_dimm_offset_un mcamd_dimm_offset_un_t;
144 
145 /*
146  * Offset definition.  Encode everything in a single uint64_t, allowing some
147  * room for growth in numbers of rows/columns/banks in future MC revisions.
148  * Some consumers will handle this as an opaque uint64 to be passed around,
149  * while others will want to look inside via the union defined below.  Since
150  * we must support a 32-bit kernel we structure this as two uint32_t.
151  */
152 
153 #define	MCAMD_OFFSET_VERSION_0			0x0
154 #define	MCAMD_OFFSET_VERSION			MCAMD_OFFSET_VERSION_0
155 
156 union mcamd_dimm_offset_un {
157 	uint64_t _dou_offset;
158 	struct {
159 		struct {
160 			uint32_t dou_col:20;	/* column address */
161 			uint32_t dou_bank:4;	/* internal sdram bank number */
162 			uint32_t unused:8;
163 		} lo;
164 		struct {
165 			uint32_t dou_row:20;	/* row address */
166 			uint32_t dou_rank:3;	/* cs rank on dimm */
167 			uint32_t unused:4;
168 			uint32_t dou_version:4;	/* offset encoding version */
169 			uint32_t dou_valid:1;	/* set if valid */
170 		} hi;
171 	} _dou_hilo;
172 };
173 
174 #define	do_offset  _dou_offset
175 
176 #define	do_valid _dou_hilo.hi.dou_valid
177 #define	do_version _dou_hilo.hi.dou_version
178 #define	do_rank _dou_hilo.hi.dou_rank
179 #define	do_row _dou_hilo.hi.dou_row
180 #define	do_bank _dou_hilo.lo.dou_bank
181 #define	do_col _dou_hilo.lo.dou_col
182 
183 /*
184  * The following work on an offset treated as a uint64_t.
185  */
186 #define	MCAMD_RC_OFFSET_VALID(offset) (((uint64_t)(offset) & (1ULL << 63)) != 0)
187 #define	MCAMD_RC_OFFSET_VERSION(offset) (((uint64_t)offset >> 59) & 0xf)
188 
189 /*
190  * Value to be used to indicate an invalid offset.
191  */
192 #define	MCAMD_RC_INVALID_OFFSET 0x0
193 
194 /*
195  * Routines provided by the common mcamd code.
196  */
197 extern const char *mcamd_get_propname(mcamd_propcode_t);
198 
199 extern int mcamd_patounum(struct mcamd_hdl *, mcamd_node_t *, uint64_t,
200     uint8_t, uint8_t, uint32_t, int, mc_unum_t *);
201 extern int mcamd_unumtopa(struct mcamd_hdl *, mcamd_node_t *, mc_unum_t *,
202     uint64_t *);
203 extern int mc_pa_to_offset(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *,
204     uint64_t, uint64_t *);
205 extern int mc_offset_to_pa(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *,
206     uint64_t, uint64_t *);
207 
208 extern int mcamd_cs_size(struct mcamd_hdl *, mcamd_node_t *, int, size_t *);
209 
210 extern int mcamd_synd_validate(struct mcamd_hdl *, uint32_t, int);
211 extern int mcamd_eccsynd_decode(struct mcamd_hdl *, uint32_t, uint_t *);
212 extern int mcamd_cksynd_decode(struct mcamd_hdl *, uint32_t, uint_t *,
213     uint_t *);
214 extern int mcamd_cksym_decode(struct mcamd_hdl *, uint_t, int *, int *,
215     int *, int *);
216 
217 extern void *mcamd_set_errno_ptr(struct mcamd_hdl *, int);
218 extern const char *mcamd_strerror(int);
219 extern const char *mcamd_errmsg(struct mcamd_hdl *);
220 
221 /*
222  * Routines to be provided by wrapper code.
223  */
224 extern mcamd_node_t *mcamd_mc_next(struct mcamd_hdl *, mcamd_node_t *,
225     mcamd_node_t *);
226 extern mcamd_node_t *mcamd_cs_next(struct mcamd_hdl *, mcamd_node_t *,
227     mcamd_node_t *);
228 extern mcamd_node_t *mcamd_dimm_next(struct mcamd_hdl *, mcamd_node_t *,
229     mcamd_node_t *);
230 
231 extern mcamd_node_t *mcamd_cs_mc(struct mcamd_hdl *, mcamd_node_t *);
232 extern mcamd_node_t *mcamd_dimm_mc(struct mcamd_hdl *, mcamd_node_t *);
233 
234 extern int mcamd_get_numprop(struct mcamd_hdl *, mcamd_node_t *,
235     mcamd_propcode_t, mcamd_prop_t *);
236 extern int mcamd_get_numprops(struct mcamd_hdl *, ...);
237 extern int mcamd_get_cfgreg(struct mcamd_hdl *, mcamd_node_t *,
238     mcamd_regcode_t, mcamd_cfgreg_t *);
239 extern int mcamd_get_cfgregs(struct mcamd_hdl *, ...);
240 
241 extern int mcamd_errno(struct mcamd_hdl *);
242 extern int mcamd_set_errno(struct mcamd_hdl *, int);
243 extern void mcamd_dprintf(struct mcamd_hdl *, int, const char *, ...);
244 
245 #ifdef __cplusplus
246 }
247 #endif
248 
249 #endif /* _MCAMD_API_H */
250