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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #ifndef _MCAMD_API_H
29 #define	_MCAMD_API_H
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 /*
34  * Primary header file for mcamd_* routines in $SRC/common/mc.  The
35  * routines not implemented there are required to be implemented in the
36  * kernel or userland consumer of this interface (such as the mc-amd driver).
37  * The common code must use the wrapper functions provided by the consumer
38  * to navigate the MC tree, get properties etc.
39  */
40 
41 #if defined(_KERNEL)
42 #include <sys/systm.h>
43 #include <sys/sunddi.h>
44 #else
45 #include <string.h>
46 #include <assert.h>
47 #endif
48 
49 #include <sys/types.h>
50 #include <sys/mc.h>
51 #include <sys/mca_amd.h>
52 #include <sys/mc_amd.h>
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 /*
59  * Consumers of this common code must implement the following types.
60  */
61 typedef struct mcamd_node mcamd_node_t;
62 struct mcamd_hdl;
63 
64 /*
65  * If changing the properties below be sure to propogate to mcamd_misc.c
66  * in common code, mcamd_subr.c in the mc-amd driver, and mcamd_prop.c
67  * from libmcamd.
68  */
69 
70 #define	MCAMD_PROP_NUM			0
71 #define	MCAMD_PROP_BASE_ADDR		1
72 #define	MCAMD_PROP_LIM_ADDR		2
73 #define	MCAMD_PROP_MASK			3
74 #define	MCAMD_PROP_DRAM_ILEN		4
75 #define	MCAMD_PROP_DRAM_ILSEL		5
76 #define	MCAMD_PROP_DRAM_HOLE		6
77 #define	MCAMD_PROP_DRAM_CONFIG		7
78 #define	MCAMD_PROP_ACCESS_WIDTH		8
79 #define	MCAMD_PROP_LODIMM		9
80 #define	MCAMD_PROP_UPDIMM		10
81 #define	MCAMD_PROP_CSBANKMAP		11
82 #define	MCAMD_PROP_SIZE			12
83 #define	MCAMD_PROP_CSBANK_INTLV		13
84 #define	MCAMD_PROP_CS0			14 /* CS0 to CS3 must be contiguous */
85 #define	MCAMD_PROP_CS1			15
86 #define	MCAMD_PROP_CS2			16
87 #define	MCAMD_PROP_CS3			17
88 #define	MCAMD_PROP_REV			18
89 #define	MCAMD_PROP_DISABLED_CS		19
90 
91 #define	MCAMD_NUMPROPS			20
92 
93 #define	MCAMD_PROPSTR_NUM		"num"
94 #define	MCAMD_PROPSTR_BASE_ADDR		"base-addr"
95 #define	MCAMD_PROPSTR_LIM_ADDR		"lim-addr"
96 #define	MCAMD_PROPSTR_MASK		"mask"
97 #define	MCAMD_PROPSTR_DRAM_ILEN		"dram-ilen"
98 #define	MCAMD_PROPSTR_DRAM_ILSEL	"dram-ilsel"
99 #define	MCAMD_PROPSTR_DRAM_HOLE		"dram-hole"
100 #define	MCAMD_PROPSTR_DRAM_CONFIG	"dram-config"
101 #define	MCAMD_PROPSTR_ACCESS_WIDTH	"access-width"
102 #define	MCAMD_PROPSTR_LODIMM		"lodimm-num"
103 #define	MCAMD_PROPSTR_UPDIMM		"updimm-num"
104 #define	MCAMD_PROPSTR_CSBANKMAP		"bank-mapping"
105 #define	MCAMD_PROPSTR_SIZE		"size"
106 #define	MCAMD_PROPSTR_CSBANK_INTLV	"csbank-intlv"
107 #define	MCAMD_PROPSTR_CS0		"csnum0"
108 #define	MCAMD_PROPSTR_CS1		"csnum1"
109 #define	MCAMD_PROPSTR_CS2		"csnum2"
110 #define	MCAMD_PROPSTR_CS3		"csnum3"
111 #define	MCAMD_PROPSTR_REV		"revision"
112 #define	MCAMD_PROPSTR_DISABLED_CS	"disabled-cs"
113 
114 /*
115  * Flags for mcamd_dprintf
116  */
117 #define	MCAMD_DBG_ERR		0x1
118 #define	MCAMD_DBG_FLOW		0x2
119 
120 typedef union mcamd_dimm_offset_un mcamd_dimm_offset_un_t;
121 
122 /*
123  * Offset definition.  Encode everything in a single uint64_t, allowing some
124  * room for growth in numbers of rows/columns/banks in future MC revisions.
125  * Some consumers will handle this as an opaque uint64 to be passed around,
126  * while others will want to look inside via the union defined below.
127  */
128 
129 #define	MCAMD_OFFSET_VERSION_0			0x0
130 #define	MCAMD_OFFSET_VERSION			MCAMD_OFFSET_VERSION_0
131 
132 union mcamd_dimm_offset_un {
133 	uint64_t _dou_offset;
134 	struct {
135 		struct {
136 			uint32_t dou_col:20;	/* column address */
137 			uint32_t dou_bank:4;	/* internal sdram bank number */
138 			uint32_t unused:8;
139 		} lo;
140 		struct {
141 			uint32_t dou_row:20;	/* row address */
142 			uint32_t dou_rank:3;	/* cs rank on dimm */
143 			uint32_t unused:4;
144 			uint32_t dou_version:4;	/* offset encoding version */
145 			uint32_t dou_valid:1;	/* set if valid */
146 		} hi;
147 	} _dou_hilo;
148 };
149 
150 #define	do_offset  _dou_offset
151 
152 #define	do_valid _dou_hilo.hi.dou_valid
153 #define	do_version _dou_hilo.hi.dou_version
154 #define	do_rank _dou_hilo.hi.dou_rank
155 #define	do_row _dou_hilo.hi.dou_row
156 #define	do_bank _dou_hilo.lo.dou_bank
157 #define	do_col _dou_hilo.lo.dou_col
158 
159 /*
160  * The following work on an offset treated as a uint64_t.
161  */
162 #define	MCAMD_RC_OFFSET_VALID(offset) (((uint64_t)(offset) & (1ULL << 63)) != 0)
163 #define	MCAMD_RC_OFFSET_VERSION(offset) (((uint64_t)offset >> 59) & 0xf)
164 
165 /*
166  * Value to be used to indicate an invalid offset.
167  */
168 #define	MCAMD_RC_INVALID_OFFSET 0x0
169 
170 /*
171  * Routines provided by the common mcamd code.
172  */
173 extern const char *mcamd_get_propname(uint_t);
174 
175 extern int mcamd_patounum(struct mcamd_hdl *, mcamd_node_t *, uint64_t,
176     uint32_t, int, struct mc_unum *);
177 
178 extern int mcamd_unumtopa(struct mcamd_hdl *, mcamd_node_t *, struct mc_unum *,
179     uint64_t *);
180 
181 extern int mcamd_cs_size(struct mcamd_hdl *, mcamd_node_t *, int, size_t *);
182 
183 extern int mcamd_synd_validate(struct mcamd_hdl *, uint32_t, int);
184 extern int mcamd_eccsynd_decode(struct mcamd_hdl *, uint32_t, uint_t *);
185 extern int mcamd_cksynd_decode(struct mcamd_hdl *, uint32_t, uint_t *,
186     uint_t *);
187 extern int mcamd_cksym_decode(struct mcamd_hdl *, uint_t, int *, int *,
188     int *, int *);
189 
190 extern void *mcamd_set_errno_ptr(struct mcamd_hdl *, int);
191 extern const char *mcamd_strerror(int);
192 extern const char *mcamd_errmsg(struct mcamd_hdl *);
193 
194 /*
195  * Routines to be provided by wrapper code.
196  */
197 extern mcamd_node_t *mcamd_mc_next(struct mcamd_hdl *, mcamd_node_t *,
198     mcamd_node_t *);
199 extern mcamd_node_t *mcamd_cs_next(struct mcamd_hdl *, mcamd_node_t *,
200     mcamd_node_t *);
201 extern mcamd_node_t *mcamd_dimm_next(struct mcamd_hdl *, mcamd_node_t *,
202     mcamd_node_t *);
203 
204 extern mcamd_node_t *mcamd_cs_mc(struct mcamd_hdl *, mcamd_node_t *);
205 extern mcamd_node_t *mcamd_dimm_mc(struct mcamd_hdl *, mcamd_node_t *);
206 
207 extern int mcamd_get_numprop(struct mcamd_hdl *, mcamd_node_t *, uint_t,
208     uint64_t *);
209 
210 extern int mcamd_errno(struct mcamd_hdl *);
211 extern int mcamd_set_errno(struct mcamd_hdl *, int);
212 extern void mcamd_dprintf(struct mcamd_hdl *, int, const char *, ...);
213 
214 #ifdef __cplusplus
215 }
216 #endif
217 
218 #endif /* _MCAMD_API_H */
219