xref: /illumos-gate/usr/src/uts/intel/io/mc-amd/mcamd.h (revision 5422785d352a2bb398daceab3d1898a8aa64d006)
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 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _MCAMD_H
28 #define	_MCAMD_H
29 
30 /*
31  * Header file for the mc-amd AMD memory-controller driver.  This should be
32  * included from that driver source alone - any more-widely useful definitions
33  * belong in mc_amd.h.
34  */
35 
36 #include <sys/types.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 #include <sys/ksynch.h>
40 #include <sys/mc_amd.h>
41 #include <sys/cpu_module.h>
42 #include <mcamd_api.h>
43 #include <mcamd_err.h>
44 #include <mcamd_dimmcfg.h>
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50 #if	MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM
51 #error	"MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM"
52 #endif
53 
54 /*
55  * The memory controller configuration registers are accessed via PCI bus 0,
56  * device 0x18 + nodeid, functions 0 to 3.  The function numbers are
57  * MC_FUNC_*, defined in mc_amd.h.
58  *
59  * We do not attach to function 3 "Miscellaneous Control" pci1022,1103
60  * since the agpgart driver already attaches to that function; instead we
61  * retrieve what function 3 parameters we require via direct PCI Mechanism 1
62  * accesses
63  *
64  * The memory controller driver attaches to these device nodes, but publishes
65  * a single minor node.  We need to ensure that the minor node can be
66  * consistently mapped back to a single (and the same) device node, so we
67  * need to pick one to be used.  We'll use the dram address map device node,
68  * as it'll be the last to be attached.
69  */
70 #define	MC_FUNC_DEVIMAP		MC_FUNC_DRAMCTL
71 #define	MC_FUNC_NUM		(MC_FUNC_MISCCTL + 1)
72 
73 #define	MC_FUNC_HTCONFIG_BINDNM	"pci1022,1100"
74 #define	MC_FUNC_ADDRMAP_BINDNM	"pci1022,1101"
75 #define	MC_FUNC_DRAMCTL_BINDNM	"pci1022,1102"
76 
77 typedef struct mc_func {
78 	uint_t mcf_instance;
79 	dev_info_t *mcf_devi;
80 } mc_func_t;
81 
82 typedef struct mc_dimm mc_dimm_t;
83 typedef struct mc_cs mc_cs_t;
84 typedef struct mc mc_t;
85 
86 /*
87  * Node types for mch_type below.  These are used in array indexing.
88  */
89 #define	MC_NT_MC		0
90 #define	MC_NT_CS		1
91 #define	MC_NT_DIMM		2
92 #define	MC_NT_NTYPES		3
93 
94 typedef struct mc_hdr {
95 	uint_t mch_type;
96 	union {
97 		mc_t *_mch_mc;
98 		mc_cs_t *_mch_cs;
99 	} _mch_ptr;
100 } mc_hdr_t;
101 
102 #define	mch_mc		_mch_ptr._mch_mc
103 
104 struct mc_dimm {
105 	mc_hdr_t mcd_hdr;			/* id, pointer to parent */
106 	mc_dimm_t *mcd_next;			/* next dimm for this MC */
107 	mc_cs_t *mcd_cs[MC_CHIP_DIMMRANKMAX];	/* associated chip-selects */
108 	const mcdcfg_csl_t *mcd_csl[MC_CHIP_DIMMRANKMAX]; /* cs lines */
109 	mcamd_prop_t mcd_num;			/* dimm number */
110 	mcamd_prop_t mcd_size;			/* dimm size in bytes */
111 };
112 
113 #define	mcd_mc mcd_hdr.mch_mc
114 
115 /*
116  * Chip-select properties.  If a chip-select is associated with just one
117  * dimm (whether it be on the A or B dram channel) that number will be
118  * in csp_dimmnums[0];  if the chip-select is associated with two dimms
119  * then csp_dimmnums[0] has the dimm from channel A and csp_dimmnums[1] has
120  * the partner dimm from channel B.
121  */
122 typedef struct mccs_props {
123 	mcamd_prop_t csp_num;			/* Chip-select number */
124 	mcamd_prop_t csp_base;			/* DRAM CS Base */
125 	mcamd_prop_t csp_mask;			/* DRAM CS Mask */
126 	mcamd_prop_t csp_size;			/* Chip-select bank size */
127 	mcamd_prop_t csp_csbe;			/* Chip-select bank enable */
128 	mcamd_prop_t csp_spare;			/* Spare */
129 	mcamd_prop_t csp_testfail;		/* TestFail */
130 	mcamd_prop_t csp_dimmnums[MC_CHIP_DIMMPERCS]; /* dimm(s) in cs */
131 	mcamd_prop_t csp_dimmrank;		/* rank # on dimms */
132 } mccs_props_t;
133 
134 /*
135  * Chip-select config register values
136  */
137 typedef struct mccs_cfgrefs {
138 	mcamd_cfgreg_t csr_csbase;		/* Raw CS base reg */
139 	mcamd_cfgreg_t csr_csmask;		/* Raw CS mask reg */
140 } mccs_cfgregs_t;
141 
142 struct mc_cs {
143 	mc_hdr_t mccs_hdr;			/* id, pointer to parent */
144 	mc_cs_t *mccs_next;			/* Next chip-select of MC */
145 	mc_dimm_t *mccs_dimm[MC_CHIP_DIMMPERCS]; /* dimms for this cs */
146 	const mcdcfg_csl_t *mccs_csl[MC_CHIP_DIMMPERCS]; /* cs lines */
147 	mccs_props_t mccs_props;		/* Properties */
148 	mccs_cfgregs_t mccs_cfgregs;		/* Raw config values */
149 };
150 
151 #define	mccs_mc	mccs_hdr.mch_mc
152 
153 /*
154  * Memory controller properties.
155  */
156 typedef struct mc_props {
157 	mcamd_prop_t mcp_num;		/* Associated *chip* number */
158 	mcamd_prop_t mcp_rev;		/* Chip revision (MC_REV_*) */
159 	mcamd_prop_t mcp_base;		/* base address for mc's drams */
160 	mcamd_prop_t mcp_lim;		/* limit address for mc's drams */
161 	mcamd_prop_t mcp_ilen;		/* interleave enable */
162 	mcamd_prop_t mcp_ilsel;		/* interleave select */
163 	mcamd_prop_t mcp_csintlvfctr;	/* cs bank interleave factor */
164 	mcamd_prop_t mcp_dramhole_size;	/* DRAM Hole Size */
165 	mcamd_prop_t mcp_accwidth;	/* dram access width (64 or 128) */
166 	mcamd_prop_t mcp_csbankmapreg;	/* chip-select bank mapping reg */
167 	mcamd_prop_t mcp_bnkswzl;	/* BankSwizzle enabled */
168 	mcamd_prop_t mcp_mod64mux;	/* Mismtached DIMMs support enabled */
169 	mcamd_prop_t mcp_sparecs;	/* cs# replaced by online spare */
170 	mcamd_prop_t mcp_badcs;		/* cs# replaced by online spare */
171 } mc_props_t;
172 
173 /*
174  * Memory controller config register values
175  */
176 typedef struct mc_cfgregs {
177 	mcamd_cfgreg_t mcr_htroute[MC_CHIP_MAXNODES];
178 	mcamd_cfgreg_t mcr_htnodeid;
179 	mcamd_cfgreg_t mcr_htunitid;
180 	mcamd_cfgreg_t mcr_drambase;
181 	mcamd_cfgreg_t mcr_dramlimit;
182 	mcamd_cfgreg_t mcr_dramhole;
183 	mcamd_cfgreg_t mcr_dramcfglo;
184 	mcamd_cfgreg_t mcr_dramcfghi;
185 	mcamd_cfgreg_t mcr_drammisc;
186 	mcamd_cfgreg_t mcr_nbcfg;
187 	mcamd_cfgreg_t mcr_sparectl;
188 	mcamd_cfgreg_t mcr_scrubctl;
189 	mcamd_cfgreg_t mcr_scrubaddrlo;
190 	mcamd_cfgreg_t mcr_scrubaddrhi;
191 } mc_cfgregs_t;
192 
193 struct mc {
194 	mc_hdr_t mc_hdr;			/* id */
195 	struct mc *mc_next;			/* next MC instance */
196 	const char *mc_revname;			/* revision name string */
197 	uint32_t mc_socket;			/* Package type */
198 	uint_t mc_ref;				/* reference (attach) count */
199 	mc_func_t mc_funcs[MC_FUNC_NUM];	/* Instance, devinfo, ... */
200 	mc_cs_t *mc_cslist;			/* All active chip-selects */
201 	mc_cs_t *mc_cslast;			/* End of chip-select list */
202 	mc_dimm_t *mc_dimmlist;			/* List of all logical DIMMs, */
203 	mc_dimm_t *mc_dimmlast;			/* linked via mcd_mcnext */
204 	mc_props_t mc_props;			/* Properties */
205 	mc_cfgregs_t mc_cfgregs;		/* Raw config values */
206 	hrtime_t mc_spareswaptime;		/* If initiated by us */
207 	nvlist_t *mc_nvl;			/* nvlist for export */
208 	char *mc_snapshot;			/* packed nvlist for libmc */
209 	size_t mc_snapshotsz;			/* packed nvlist buffer size */
210 	uint_t mc_snapshotgen;			/* snapshot generation number */
211 	int mc_csdiscontig;			/* chip-selects discontiguous */
212 	uint_t smb_chipid;			/* smbios chip instance */
213 	nvlist_t *smb_bboard;			/* smbios chip's parent */
214 };
215 
216 typedef struct mcamd_hdl {
217 	int mcamd_errno;
218 	int mcamd_debug;
219 } mcamd_hdl_t;
220 
221 extern mc_t *mc_list;
222 extern krwlock_t mc_lock;
223 
224 extern void mcamd_mkhdl(mcamd_hdl_t *);
225 extern void mcamd_mc_register(cmi_hdl_t, mc_t *);
226 extern void mcamd_ereport_post(mc_t *, const char *, mc_unum_t *, uint64_t);
227 
228 /*
229  * mcamd_mc_ops prototypes
230  */
231 extern cmi_errno_t mcamd_patounum_wrap(void *, uint64_t, uint8_t, uint8_t,
232     uint32_t, int, mc_unum_t *);
233 extern cmi_errno_t mcamd_unumtopa_wrap(void *, mc_unum_t *, nvlist_t *,
234     uint64_t *);
235 
236 /*
237  * Internal functions
238  */
239 cmi_errno_t mcamd_cmierr(int, mcamd_hdl_t *);
240 
241 #ifdef __cplusplus
242 }
243 #endif
244 
245 #endif /* _MCAMD_H */
246