xref: /illumos-gate/usr/src/uts/intel/io/mc-amd/mcamd_drv.c (revision 3299f39fdcbdab4be7a9c70daa3873f2b78a398d)
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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 #include <sys/conf.h>
27 #include <sys/ddi.h>
28 #include <sys/ddifm.h>
29 #include <sys/sunddi.h>
30 #include <sys/sunndi.h>
31 #include <sys/stat.h>
32 #include <sys/modctl.h>
33 #include <sys/types.h>
34 #include <sys/cpuvar.h>
35 #include <sys/cmn_err.h>
36 #include <sys/kmem.h>
37 #include <sys/cred.h>
38 #include <sys/ksynch.h>
39 #include <sys/rwlock.h>
40 #include <sys/pghw.h>
41 #include <sys/open.h>
42 #include <sys/policy.h>
43 #include <sys/x86_archext.h>
44 #include <sys/cpu_module.h>
45 #include <qsort.h>
46 #include <sys/pci_cfgspace.h>
47 #include <sys/mc.h>
48 #include <sys/mc_amd.h>
49 #include <sys/smbios.h>
50 #include <sys/pci.h>
51 #include <mcamd.h>
52 #include <mcamd_dimmcfg.h>
53 #include <mcamd_pcicfg.h>
54 #include <mcamd_api.h>
55 #include <sys/fm/cpu/AMD.h>
56 #include <sys/fm/smb/fmsmb.h>
57 #include <sys/fm/protocol.h>
58 #include <sys/fm/util.h>
59 
60 /*
61  * Set to prevent mc-amd from attaching.
62  */
63 int mc_no_attach = 0;
64 
65 /*
66  * Of the 754/939/940 packages, only socket 940 supports quadrank registered
67  * dimms.  Unfortunately, no memory-controller register indicates the
68  * presence of quadrank dimm support or presence (i.e., in terms of number
69  * of slots per cpu, and chip-select lines per slot,  The following may be set
70  * in /etc/system to indicate the presence of quadrank support on a motherboard.
71  *
72  * There is no need to set this for F(1207) and S1g1.
73  */
74 int mc_quadranksupport = 0;
75 
76 mc_t *mc_list, *mc_last;
77 krwlock_t mc_lock;
78 int mc_hold_attached = 1;
79 
80 #define	MAX(m, n) ((m) >= (n) ? (m) : (n))
81 #define	MIN(m, n) ((m) <= (n) ? (m) : (n))
82 
83 /*
84  * The following tuneable is used to determine the DRAM scrubbing rate.
85  * The values range from 0x00-0x16 as described in the BKDG.  Zero
86  * disables DRAM scrubbing.  Values above zero indicate rates in descending
87  * order.
88  *
89  * The default value below is used on several Sun systems.  In the future
90  * this code should assign values dynamically based on memory sizing.
91  */
92 uint32_t mc_scrub_rate_dram = 0xd;	/* 64B every 163.8 us; 1GB per 45 min */
93 
94 enum {
95 	MC_SCRUB_BIOSDEFAULT,	/* retain system default value */
96 	MC_SCRUB_FIXED,		/* assign mc_scrub_rate_* values */
97 	MC_SCRUB_MAX		/* assign max of system and tunables */
98 } mc_scrub_policy = MC_SCRUB_MAX;
99 
100 static void
101 mc_snapshot_destroy(mc_t *mc)
102 {
103 	ASSERT(RW_LOCK_HELD(&mc_lock));
104 
105 	if (mc->mc_snapshot == NULL)
106 		return;
107 
108 	kmem_free(mc->mc_snapshot, mc->mc_snapshotsz);
109 	mc->mc_snapshot = NULL;
110 	mc->mc_snapshotsz = 0;
111 	mc->mc_snapshotgen++;
112 }
113 
114 static int
115 mc_snapshot_update(mc_t *mc)
116 {
117 	ASSERT(RW_LOCK_HELD(&mc_lock));
118 
119 	if (mc->mc_snapshot != NULL)
120 		return (0);
121 
122 	if (nvlist_pack(mc->mc_nvl, &mc->mc_snapshot, &mc->mc_snapshotsz,
123 	    NV_ENCODE_XDR, KM_SLEEP) != 0)
124 		return (-1);
125 
126 	return (0);
127 }
128 
129 static mc_t *
130 mc_lookup_by_chipid(int chipid)
131 {
132 	mc_t *mc;
133 
134 	ASSERT(RW_LOCK_HELD(&mc_lock));
135 
136 	for (mc = mc_list; mc != NULL; mc = mc->mc_next) {
137 		if (mc->mc_props.mcp_num  == chipid)
138 			return (mc);
139 	}
140 
141 	return (NULL);
142 }
143 
144 /*
145  * Read config register pairs into the two arrays provided on the given
146  * handle and at offsets as follows:
147  *
148  *	Index	Array r1 offset			Array r2 offset
149  *	0	r1addr				r2addr
150  *	1	r1addr + incr			r2addr + incr
151  *	2	r1addr + 2 * incr		r2addr + 2 * incr
152  *	...
153  *	n - 1	r1addr + (n - 1) * incr		r2addr + (n - 1) * incr
154  *
155  * The number of registers to read into the r1 array is r1n; the number
156  * for the r2 array is r2n.
157  */
158 static void
159 mc_prop_read_pair(mc_pcicfg_hdl_t cfghdl, uint32_t *r1, off_t r1addr,
160     int r1n, uint32_t *r2, off_t r2addr, int r2n, off_t incr)
161 {
162 	int i;
163 
164 	for (i = 0; i < MAX(r1n, r2n); i++, r1addr += incr, r2addr += incr) {
165 		if (i < r1n)
166 			r1[i] = mc_pcicfg_get32(cfghdl, r1addr);
167 		if (i < r2n)
168 			r2[i] = mc_pcicfg_get32(cfghdl, r2addr);
169 	}
170 }
171 
172 /*ARGSUSED*/
173 static int
174 mc_nvl_add_socket_cb(cmi_hdl_t whdl, void *arg1, void *arg2, void *arg3)
175 {
176 	uint32_t skt = *((uint32_t *)arg1);
177 	cmi_hdl_t *hdlp = (cmi_hdl_t *)arg2;
178 
179 	if (cmi_hdl_getsockettype(whdl) == skt) {
180 		cmi_hdl_hold(whdl);	/* short-term hold */
181 		*hdlp = whdl;
182 		return (CMI_HDL_WALK_DONE);
183 	} else {
184 		return (CMI_HDL_WALK_NEXT);
185 	}
186 }
187 
188 static void
189 mc_nvl_add_socket(nvlist_t *nvl, mc_t *mc)
190 {
191 	cmi_hdl_t hdl = NULL;
192 	const char *s;
193 
194 	cmi_hdl_walk(mc_nvl_add_socket_cb, (void *)&mc->mc_socket,
195 	    (void *)&hdl, NULL);
196 	if (hdl == NULL)
197 		s = "Unknown";  /* no cpu for this chipid found */
198 	else
199 		s = cmi_hdl_getsocketstr(hdl);
200 
201 	(void) nvlist_add_string(nvl, "socket", s);
202 
203 	if (hdl != NULL)
204 		cmi_hdl_rele(hdl);
205 }
206 
207 static uint32_t
208 mc_ecc_enabled(mc_t *mc)
209 {
210 	uint32_t rev = mc->mc_props.mcp_rev;
211 	union mcreg_nbcfg nbcfg;
212 
213 	MCREG_VAL32(&nbcfg) = mc->mc_cfgregs.mcr_nbcfg;
214 
215 	return (MC_REV_MATCH(rev, MC_F_REVS_BCDE) ?
216 	    MCREG_FIELD_F_preF(&nbcfg, EccEn) :
217 	    MCREG_FIELD_F_revFG(&nbcfg, EccEn));
218 }
219 
220 static uint32_t
221 mc_ck_enabled(mc_t *mc)
222 {
223 	uint32_t rev = mc->mc_props.mcp_rev;
224 	union mcreg_nbcfg nbcfg;
225 
226 	MCREG_VAL32(&nbcfg) = mc->mc_cfgregs.mcr_nbcfg;
227 
228 	return (MC_REV_MATCH(rev, MC_F_REVS_BCDE) ?
229 	    MCREG_FIELD_F_preF(&nbcfg, ChipKillEccEn) :
230 	    MCREG_FIELD_F_revFG(&nbcfg, ChipKillEccEn));
231 }
232 
233 static void
234 mc_nvl_add_ecctype(nvlist_t *nvl, mc_t *mc)
235 {
236 	(void) nvlist_add_string(nvl, "ecc-type", mc_ecc_enabled(mc) ?
237 	    (mc_ck_enabled(mc) ? "ChipKill 128/16" : "Normal 64/8") : "None");
238 }
239 
240 static void
241 mc_nvl_add_prop(nvlist_t *nvl, void *node, mcamd_propcode_t code, int reqval)
242 {
243 	int valfound;
244 	uint64_t value;
245 	const char *name = mcamd_get_propname(code);
246 
247 	valfound = mcamd_get_numprop(NULL, (mcamd_node_t *)node, code, &value);
248 
249 	ASSERT(name != NULL && valfound);
250 	if (name != NULL && valfound && (!reqval || value != MC_INVALNUM))
251 		(void) nvlist_add_uint64(nvl, name, value);
252 }
253 
254 static void
255 mc_nvl_add_cslist(nvlist_t *mcnvl, mc_t *mc)
256 {
257 	mc_cs_t *mccs = mc->mc_cslist;
258 	nvlist_t *cslist[MC_CHIP_NCS];
259 	int nelem, i;
260 
261 	for (nelem = 0; mccs != NULL; mccs = mccs->mccs_next, nelem++) {
262 		nvlist_t **csp = &cslist[nelem];
263 		char csname[MCDCFG_CSNAMELEN];
264 
265 		(void) nvlist_alloc(csp, NV_UNIQUE_NAME, KM_SLEEP);
266 		mc_nvl_add_prop(*csp, mccs, MCAMD_PROP_NUM, 0);
267 		mc_nvl_add_prop(*csp, mccs, MCAMD_PROP_BASE_ADDR, 0);
268 		mc_nvl_add_prop(*csp, mccs, MCAMD_PROP_MASK, 0);
269 		mc_nvl_add_prop(*csp, mccs, MCAMD_PROP_SIZE, 0);
270 
271 		/*
272 		 * It is possible for an mc_cs_t not to have associated
273 		 * DIMM info if mcdcfg_lookup failed.
274 		 */
275 		if (mccs->mccs_csl[0] != NULL) {
276 			mc_nvl_add_prop(*csp, mccs, MCAMD_PROP_CSDIMM1, 1);
277 			mcdcfg_csname(mc->mc_socket, mccs->mccs_csl[0], csname,
278 			    sizeof (csname));
279 			(void) nvlist_add_string(*csp, "dimm1-csname", csname);
280 		}
281 
282 		if (mccs->mccs_csl[1] != NULL) {
283 			mc_nvl_add_prop(*csp, mccs, MCAMD_PROP_CSDIMM2, 1);
284 			mcdcfg_csname(mc->mc_socket, mccs->mccs_csl[1], csname,
285 			    sizeof (csname));
286 			(void) nvlist_add_string(*csp, "dimm2-csname", csname);
287 		}
288 	}
289 
290 	/* Add cslist nvlist array even if zero members */
291 	(void) nvlist_add_nvlist_array(mcnvl, "cslist", cslist, nelem);
292 	for (i = 0; i < nelem; i++)
293 		nvlist_free(cslist[i]);
294 }
295 
296 static void
297 mc_nvl_add_dimmlist(nvlist_t *mcnvl, mc_t *mc)
298 {
299 	nvlist_t *dimmlist[MC_CHIP_NDIMM];
300 	mc_dimm_t *mcd;
301 	int nelem, i;
302 
303 	for (nelem = 0, mcd = mc->mc_dimmlist; mcd != NULL;
304 	    mcd = mcd->mcd_next, nelem++) {
305 		nvlist_t **dimmp = &dimmlist[nelem];
306 		uint64_t csnums[MC_CHIP_DIMMRANKMAX];
307 		char csname[4][MCDCFG_CSNAMELEN];
308 		char *csnamep[4];
309 		int ncs = 0;
310 
311 		(void) nvlist_alloc(dimmp, NV_UNIQUE_NAME, KM_SLEEP);
312 
313 		mc_nvl_add_prop(*dimmp, mcd, MCAMD_PROP_NUM, 1);
314 		mc_nvl_add_prop(*dimmp, mcd, MCAMD_PROP_SIZE, 1);
315 
316 		for (i = 0; i < MC_CHIP_DIMMRANKMAX; i++) {
317 			if (mcd->mcd_cs[i] != NULL) {
318 				csnums[ncs] =
319 				    mcd->mcd_cs[i]->mccs_props.csp_num;
320 				mcdcfg_csname(mc->mc_socket, mcd->mcd_csl[i],
321 				    csname[ncs], MCDCFG_CSNAMELEN);
322 				csnamep[ncs] = csname[ncs];
323 				ncs++;
324 			}
325 		}
326 
327 		(void) nvlist_add_uint64_array(*dimmp, "csnums", csnums, ncs);
328 		(void) nvlist_add_string_array(*dimmp, "csnames", csnamep, ncs);
329 	}
330 
331 	/* Add dimmlist nvlist array even if zero members */
332 	(void) nvlist_add_nvlist_array(mcnvl, "dimmlist", dimmlist, nelem);
333 	for (i = 0; i < nelem; i++)
334 		nvlist_free(dimmlist[i]);
335 }
336 
337 static void
338 mc_nvl_add_htconfig(nvlist_t *mcnvl, mc_t *mc)
339 {
340 	mc_cfgregs_t *mcr = &mc->mc_cfgregs;
341 	union mcreg_htroute *htrp = (union mcreg_htroute *)&mcr->mcr_htroute[0];
342 	union mcreg_nodeid *nip = (union mcreg_nodeid *)&mcr->mcr_htnodeid;
343 	union mcreg_unitid *uip = (union mcreg_unitid *)&mcr->mcr_htunitid;
344 	int ndcnt = HT_COHERENTNODES(nip);
345 	uint32_t BCRte[MC_CHIP_MAXNODES];
346 	uint32_t RPRte[MC_CHIP_MAXNODES];
347 	uint32_t RQRte[MC_CHIP_MAXNODES];
348 	nvlist_t *nvl;
349 	int i;
350 
351 	(void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
352 
353 	(void) nvlist_add_uint32(nvl, "NodeId", MCREG_FIELD_CMN(nip, NodeId));
354 	(void) nvlist_add_uint32(nvl, "CoherentNodes", HT_COHERENTNODES(nip));
355 	(void) nvlist_add_uint32(nvl, "SbNode", MCREG_FIELD_CMN(nip, SbNode));
356 	(void) nvlist_add_uint32(nvl, "LkNode", MCREG_FIELD_CMN(nip, LkNode));
357 	(void) nvlist_add_uint32(nvl, "SystemCoreCount",
358 	    HT_SYSTEMCORECOUNT(nip));
359 
360 	(void) nvlist_add_uint32(nvl, "C0Unit", MCREG_FIELD_CMN(uip, C0Unit));
361 	(void) nvlist_add_uint32(nvl, "C1Unit", MCREG_FIELD_CMN(uip, C1Unit));
362 	(void) nvlist_add_uint32(nvl, "McUnit", MCREG_FIELD_CMN(uip, McUnit));
363 	(void) nvlist_add_uint32(nvl, "HbUnit", MCREG_FIELD_CMN(uip, HbUnit));
364 	(void) nvlist_add_uint32(nvl, "SbLink", MCREG_FIELD_CMN(uip, SbLink));
365 
366 	if (ndcnt <= MC_CHIP_MAXNODES) {
367 		for (i = 0; i < ndcnt; i++, htrp++) {
368 			BCRte[i] = MCREG_FIELD_CMN(htrp, BCRte);
369 			RPRte[i] = MCREG_FIELD_CMN(htrp, RPRte);
370 			RQRte[i] = MCREG_FIELD_CMN(htrp, RQRte);
371 		}
372 
373 		(void) nvlist_add_uint32_array(nvl, "BroadcastRoutes",
374 		    &BCRte[0], ndcnt);
375 		(void) nvlist_add_uint32_array(nvl, "ResponseRoutes",
376 		    &RPRte[0], ndcnt);
377 		(void) nvlist_add_uint32_array(nvl, "RequestRoutes",
378 		    &RQRte[0], ndcnt);
379 	}
380 
381 	(void) nvlist_add_nvlist(mcnvl, "htconfig", nvl);
382 	nvlist_free(nvl);
383 }
384 
385 static nvlist_t *
386 mc_nvl_create(mc_t *mc)
387 {
388 	nvlist_t *mcnvl;
389 
390 	(void) nvlist_alloc(&mcnvl, NV_UNIQUE_NAME, KM_SLEEP);
391 
392 	/*
393 	 * Since this nvlist is used in populating the topo tree changes
394 	 * made here may propogate through to changed property names etc
395 	 * in the topo tree.  Some properties in the topo tree will be
396 	 * contracted via ARC, so be careful what you change here.
397 	 */
398 	(void) nvlist_add_uint8(mcnvl, MC_NVLIST_VERSTR, MC_NVLIST_VERS1);
399 
400 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_NUM, 0);
401 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_REV, 0);
402 	(void) nvlist_add_string(mcnvl, "revname", mc->mc_revname);
403 	mc_nvl_add_socket(mcnvl, mc);
404 	mc_nvl_add_ecctype(mcnvl, mc);
405 
406 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_BASE_ADDR, 0);
407 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_LIM_ADDR, 0);
408 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_ILEN, 0);
409 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_ILSEL, 0);
410 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_CSINTLVFCTR, 0);
411 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_DRAMHOLE_SIZE, 0);
412 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_ACCESS_WIDTH, 0);
413 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_CSBANKMAPREG, 0);
414 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_BANKSWZL, 0);
415 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_MOD64MUX, 0);
416 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_SPARECS, 1);
417 	mc_nvl_add_prop(mcnvl, mc, MCAMD_PROP_BADCS, 1);
418 
419 	mc_nvl_add_cslist(mcnvl, mc);
420 	mc_nvl_add_dimmlist(mcnvl, mc);
421 	mc_nvl_add_htconfig(mcnvl, mc);
422 
423 	return (mcnvl);
424 }
425 
426 /*
427  * Link a dimm to its associated chip-selects and chip-select lines.
428  * Total the size of all ranks of this dimm.
429  */
430 static void
431 mc_dimm_csadd(mc_t *mc, mc_dimm_t *mcd, mc_cs_t *mccs, const mcdcfg_csl_t *csl)
432 {
433 	int factor = (mc->mc_props.mcp_accwidth == 128) ? 2 : 1;
434 	uint64_t sz = 0;
435 	int i;
436 
437 	/* Skip to first unused rank slot */
438 	for (i = 0; i < MC_CHIP_DIMMRANKMAX; i++) {
439 		if (mcd->mcd_cs[i] == NULL) {
440 			mcd->mcd_cs[i] = mccs;
441 			mcd->mcd_csl[i] = csl;
442 			sz += mccs->mccs_props.csp_size / factor;
443 			break;
444 		} else {
445 			sz += mcd->mcd_cs[i]->mccs_props.csp_size / factor;
446 		}
447 	}
448 
449 	ASSERT(i != MC_CHIP_DIMMRANKMAX);
450 
451 	mcd->mcd_size = sz;
452 }
453 
454 /*
455  * Create a dimm structure and call to link it to its associated chip-selects.
456  */
457 static mc_dimm_t *
458 mc_dimm_create(mc_t *mc, uint_t num)
459 {
460 	mc_dimm_t *mcd = kmem_zalloc(sizeof (mc_dimm_t), KM_SLEEP);
461 
462 	mcd->mcd_hdr.mch_type = MC_NT_DIMM;
463 	mcd->mcd_mc = mc;
464 	mcd->mcd_num = num;
465 
466 	return (mcd);
467 }
468 
469 /*
470  * The chip-select structure includes an array of dimms associated with
471  * that chip-select.  This function fills that array, and also builds
472  * the list of all dimms on this memory controller mc_dimmlist.  The
473  * caller has filled a structure with all there is to know about the
474  * associated dimm(s).
475  */
476 static void
477 mc_csdimms_create(mc_t *mc, mc_cs_t *mccs, mcdcfg_rslt_t *rsltp)
478 {
479 	mc_dimm_t *found[MC_CHIP_DIMMPERCS];
480 	mc_dimm_t *mcd;
481 	int nfound = 0;
482 	int i;
483 
484 	/*
485 	 * Has some other chip-select already created this dimm or dimms?
486 	 * If so then link to the dimm(s) from the mccs_dimm array,
487 	 * record their topo numbers in the csp_dimmnums array, and link
488 	 * the dimm(s) to the additional chip-select.
489 	 */
490 	for (mcd = mc->mc_dimmlist; mcd != NULL; mcd = mcd->mcd_next) {
491 		for (i = 0; i < rsltp->ndimm; i++) {
492 			if (mcd->mcd_num == rsltp->dimm[i].toponum)
493 				found[nfound++] = mcd;
494 		}
495 	}
496 	ASSERT(nfound == 0 || nfound == rsltp->ndimm);
497 
498 	for (i = 0; i < rsltp->ndimm; i++) {
499 		if (nfound == 0) {
500 			mcd = mc_dimm_create(mc, rsltp->dimm[i].toponum);
501 			if (mc->mc_dimmlist == NULL)
502 				mc->mc_dimmlist = mcd;
503 			else
504 				mc->mc_dimmlast->mcd_next = mcd;
505 			mc->mc_dimmlast = mcd;
506 		} else {
507 			mcd = found[i];
508 		}
509 
510 		mccs->mccs_dimm[i] = mcd;
511 		mccs->mccs_csl[i] = rsltp->dimm[i].cslp;
512 		mccs->mccs_props.csp_dimmnums[i] = mcd->mcd_num;
513 		mc_dimm_csadd(mc, mcd, mccs, rsltp->dimm[i].cslp);
514 
515 	}
516 
517 	/* The rank number is constant across all constituent dimm(s) */
518 	mccs->mccs_props.csp_dimmrank = rsltp->dimm[0].cslp->csl_rank;
519 }
520 
521 /*
522  * mc_dimmlist_create is called after we have discovered all enabled
523  * (and spare or testfailed on revs F and G) chip-selects on the
524  * given memory controller.  For each chip-select we must derive
525  * the associated dimms, remembering that a chip-select csbase/csmask
526  * pair may be associated with up to 2 chip-select lines (in 128 bit mode)
527  * and that any one dimm may be associated with 1, 2, or 4 chip-selects
528  * depending on whether it is single, dual or quadrank.
529  */
530 static void
531 mc_dimmlist_create(mc_t *mc)
532 {
533 	union mcreg_dramcfg_hi *drcfghip =
534 	    (union mcreg_dramcfg_hi *)(&mc->mc_cfgregs.mcr_dramcfghi);
535 	mc_props_t *mcp = &mc->mc_props;
536 	uint32_t rev = mcp->mcp_rev;
537 	mc_cs_t *mccs;
538 	int r4 = 0, s4 = 0;
539 
540 	/*
541 	 * Are we dealing with quadrank registered dimms?
542 	 *
543 	 * For socket 940 we can't tell and we'll assume we're not.
544 	 * This can be over-ridden by the admin in /etc/system by setting
545 	 * mc_quadranksupport nonzero.  A possible optimisation in systems
546 	 * that export an SMBIOS table would be to count the number of
547 	 * dimm slots per cpu - more than 4 would indicate no quadrank support
548 	 * and 4 or fewer would indicate that if we see any of the upper
549 	 * chip-selects enabled then a quadrank dimm is present.
550 	 *
551 	 * For socket F(1207) we can check a bit in the dram config high reg.
552 	 *
553 	 * Other socket types do not support registered dimms.
554 	 */
555 	if (mc->mc_socket == X86_SOCKET_940)
556 		r4 = mc_quadranksupport != 0;
557 	else if (mc->mc_socket == X86_SOCKET_F1207)
558 		r4 = MCREG_FIELD_F_revFG(drcfghip, FourRankRDimm);
559 
560 	/*
561 	 * Are we dealing with quadrank SO-DIMMs?  These are supported
562 	 * in AM2 and S1g1 packages only, but in all rev F/G cases we
563 	 * can detect their presence via a bit in the dram config high reg.
564 	 */
565 	if (MC_REV_MATCH(rev, MC_F_REVS_FG))
566 		s4 = MCREG_FIELD_F_revFG(drcfghip, FourRankSODimm);
567 
568 	for (mccs = mc->mc_cslist; mccs != NULL; mccs = mccs->mccs_next) {
569 		mcdcfg_rslt_t rslt;
570 
571 		/*
572 		 * If lookup fails we will not create dimm structures for
573 		 * this chip-select.  In the mc_cs_t we will have both
574 		 * csp_dimmnum members set to MC_INVALNUM and patounum
575 		 * code will see from those that we do not have dimm info
576 		 * for this chip-select.
577 		 */
578 		if (mcdcfg_lookup(rev, mcp->mcp_mod64mux, mcp->mcp_accwidth,
579 		    mccs->mccs_props.csp_num, mc->mc_socket,
580 		    r4, s4, &rslt) < 0)
581 			continue;
582 
583 		mc_csdimms_create(mc, mccs, &rslt);
584 	}
585 }
586 
587 static mc_cs_t *
588 mc_cs_create(mc_t *mc, uint_t num, uint64_t base, uint64_t mask, size_t sz,
589     int csbe, int spare, int testfail)
590 {
591 	mc_cs_t *mccs = kmem_zalloc(sizeof (mc_cs_t), KM_SLEEP);
592 	mccs_props_t *csp = &mccs->mccs_props;
593 	int i;
594 
595 	mccs->mccs_hdr.mch_type = MC_NT_CS;
596 	mccs->mccs_mc = mc;
597 	csp->csp_num = num;
598 	csp->csp_base = base;
599 	csp->csp_mask = mask;
600 	csp->csp_size = sz;
601 	csp->csp_csbe = csbe;
602 	csp->csp_spare = spare;
603 	csp->csp_testfail = testfail;
604 
605 	for (i = 0; i < MC_CHIP_DIMMPERCS; i++)
606 		csp->csp_dimmnums[i] = MC_INVALNUM;
607 
608 	if (spare)
609 		mc->mc_props.mcp_sparecs = num;
610 
611 	return (mccs);
612 }
613 
614 /*
615  * For any cs# of this mc marked TestFail generate an ereport with
616  * resource identifying the associated dimm(s).
617  */
618 static void
619 mc_report_testfails(mc_t *mc)
620 {
621 	mc_unum_t unum;
622 	mc_cs_t *mccs;
623 	int i;
624 
625 	for (mccs = mc->mc_cslist; mccs != NULL; mccs = mccs->mccs_next) {
626 		if (mccs->mccs_props.csp_testfail) {
627 			unum.unum_board = 0;
628 			unum.unum_chip = mc->mc_props.mcp_num;
629 			unum.unum_mc = 0;
630 			unum.unum_chan = MC_INVALNUM;
631 			unum.unum_cs = mccs->mccs_props.csp_num;
632 			unum.unum_rank = mccs->mccs_props.csp_dimmrank;
633 			unum.unum_offset = MCAMD_RC_INVALID_OFFSET;
634 			for (i = 0; i < MC_CHIP_DIMMPERCS; i++)
635 				unum.unum_dimms[i] = MC_INVALNUM;
636 
637 			mcamd_ereport_post(mc, FM_EREPORT_CPU_AMD_MC_TESTFAIL,
638 			    &unum,
639 			    FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_MC_TESTFAIL);
640 		}
641 	}
642 }
643 
644 /*
645  * Function 0 - HyperTransport Technology Configuration
646  */
647 static void
648 mc_mkprops_htcfg(mc_pcicfg_hdl_t cfghdl, mc_t *mc)
649 {
650 	union mcreg_nodeid nodeid;
651 	off_t offset;
652 	int i;
653 
654 	mc->mc_cfgregs.mcr_htnodeid = MCREG_VAL32(&nodeid) =
655 	    mc_pcicfg_get32(cfghdl, MC_HT_REG_NODEID);
656 
657 	mc->mc_cfgregs.mcr_htunitid = mc_pcicfg_get32(cfghdl, MC_HT_REG_UNITID);
658 
659 	for (i = 0, offset = MC_HT_REG_RTBL_NODE_0;
660 	    i < HT_COHERENTNODES(&nodeid);
661 	    i++, offset += MC_HT_REG_RTBL_INCR)
662 		mc->mc_cfgregs.mcr_htroute[i] = mc_pcicfg_get32(cfghdl, offset);
663 }
664 
665 /*
666  * Function 1 Configuration - Address Map (see BKDG 3.4.4 DRAM Address Map)
667  *
668  * Read the Function 1 Address Map for each potential DRAM node.  The Base
669  * Address for a node gives the starting system address mapped at that node,
670  * and the limit gives the last valid address mapped at that node.  Regions for
671  * different nodes should not overlap, unless node-interleaving is enabled.
672  * The base register also indicates the node-interleaving settings (IntlvEn).
673  * The limit register includes IntlvSel which determines which 4K blocks will
674  * be routed to this node and the destination node ID for addresses that fall
675  * within the [base, limit] range - this must match the pair number.
676  */
677 static void
678 mc_mkprops_addrmap(mc_pcicfg_hdl_t cfghdl, mc_t *mc)
679 {
680 	union mcreg_drambase basereg;
681 	union mcreg_dramlimit limreg;
682 	mc_props_t *mcp = &mc->mc_props;
683 	mc_cfgregs_t *mcr = &mc->mc_cfgregs;
684 	union mcreg_dramhole hole;
685 	int nodeid = mc->mc_props.mcp_num;
686 
687 	mcr->mcr_drambase = MCREG_VAL32(&basereg) = mc_pcicfg_get32(cfghdl,
688 	    MC_AM_REG_DRAMBASE_0 + nodeid * MC_AM_REG_DRAM_INCR);
689 
690 	mcr->mcr_dramlimit = MCREG_VAL32(&limreg) = mc_pcicfg_get32(cfghdl,
691 	    MC_AM_REG_DRAMLIM_0 + nodeid * MC_AM_REG_DRAM_INCR);
692 
693 	/*
694 	 * Derive some "cooked" properties for nodes that have a range of
695 	 * physical addresses that are read or write enabled and for which
696 	 * the DstNode matches the node we are attaching.
697 	 */
698 	if (MCREG_FIELD_CMN(&limreg, DRAMLimiti) != 0 &&
699 	    MCREG_FIELD_CMN(&limreg, DstNode) == nodeid &&
700 	    (MCREG_FIELD_CMN(&basereg, WE) || MCREG_FIELD_CMN(&basereg, RE))) {
701 		mcp->mcp_base = MC_DRAMBASE(&basereg);
702 		mcp->mcp_lim = MC_DRAMLIM(&limreg);
703 		mcp->mcp_ilen = MCREG_FIELD_CMN(&basereg, IntlvEn);
704 		mcp->mcp_ilsel = MCREG_FIELD_CMN(&limreg, IntlvSel);
705 	}
706 
707 	/*
708 	 * The Function 1 DRAM Hole Address Register tells us which node(s)
709 	 * own the DRAM space that is hoisted above 4GB, together with the
710 	 * hole base and offset for this node.  This was introduced in
711 	 * revision E.
712 	 */
713 	if (MC_REV_ATLEAST(mc->mc_props.mcp_rev, MC_F_REV_E)) {
714 		mcr->mcr_dramhole = MCREG_VAL32(&hole) =
715 		    mc_pcicfg_get32(cfghdl, MC_AM_REG_HOLEADDR);
716 
717 		if (MCREG_FIELD_CMN(&hole, DramHoleValid))
718 			mcp->mcp_dramhole_size = MC_DRAMHOLE_SIZE(&hole);
719 	}
720 }
721 
722 /*
723  * Read some function 3 parameters via PCI Mechanism 1 accesses (which
724  * will serialize any NB accesses).
725  */
726 static void
727 mc_getmiscctl(mc_t *mc)
728 {
729 	uint32_t rev = mc->mc_props.mcp_rev;
730 	union mcreg_nbcfg nbcfg;
731 	union mcreg_sparectl sparectl;
732 
733 	mc->mc_cfgregs.mcr_nbcfg = MCREG_VAL32(&nbcfg) =
734 	    mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG);
735 
736 	if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
737 		mc->mc_cfgregs.mcr_sparectl = MCREG_VAL32(&sparectl) =
738 		    mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL,
739 		    MC_CTL_REG_SPARECTL);
740 
741 		if (MCREG_FIELD_F_revFG(&sparectl, SwapDone)) {
742 			mc->mc_props.mcp_badcs =
743 			    MCREG_FIELD_F_revFG(&sparectl, BadDramCs);
744 		}
745 	}
746 }
747 
748 static int
749 csbasecmp(mc_cs_t **csapp, mc_cs_t **csbpp)
750 {
751 	uint64_t basea = (*csapp)->mccs_props.csp_base;
752 	uint64_t baseb = (*csbpp)->mccs_props.csp_base;
753 
754 	if (basea == baseb)
755 		return (0);
756 	else if (basea < baseb)
757 		return (-1);
758 	else
759 		return (1);
760 }
761 
762 /*
763  * The following are for use in simulating TestFail for a chip-select
764  * without poking at the hardware (which tends to get upset if you do
765  * since the BIOS needs to restart to map a failed cs out).  For internal
766  * testing only!  Note that setting these does not give the full experience -
767  * the select chip-select *is* enabled and can give errors etc and the
768  * patounum logic will get confused.
769  */
770 int testfail_mcnum = -1;
771 int testfail_csnum = -1;
772 
773 /*
774  * Function 2 configuration - DRAM Controller
775  */
776 static void
777 mc_mkprops_dramctl(mc_pcicfg_hdl_t cfghdl, mc_t *mc)
778 {
779 	union mcreg_csbase base[MC_CHIP_NCS];
780 	union mcreg_csmask mask[MC_CHIP_NCS];
781 	union mcreg_dramcfg_lo drcfg_lo;
782 	union mcreg_dramcfg_hi drcfg_hi;
783 	union mcreg_drammisc drmisc;
784 	union mcreg_bankaddrmap baddrmap;
785 	mc_props_t *mcp = &mc->mc_props;
786 	mc_cfgregs_t *mcr = &mc->mc_cfgregs;
787 	int maskdivisor;
788 	int wide = 0;
789 	uint32_t rev = mc->mc_props.mcp_rev;
790 	int i;
791 	mcamd_hdl_t hdl;
792 
793 	mcamd_mkhdl(&hdl);	/* to call into common code */
794 
795 	/*
796 	 * Read Function 2 DRAM Configuration High and Low registers.  The High
797 	 * part is mostly concerned with memory clocks etc and we'll not have
798 	 * any use for that.  The Low component tells us if ECC is enabled,
799 	 * if we're in 64- or 128-bit MC mode, how the upper chip-selects
800 	 * are mapped, which chip-select pairs are using x4 parts, etc.
801 	 */
802 	MCREG_VAL32(&drcfg_lo) = mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGLO);
803 	MCREG_VAL32(&drcfg_hi) = mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMCFGHI);
804 	mcr->mcr_dramcfglo = MCREG_VAL32(&drcfg_lo);
805 	mcr->mcr_dramcfghi = MCREG_VAL32(&drcfg_hi);
806 
807 	/*
808 	 * Note the DRAM controller width.  The 64/128 bit is in a different
809 	 * bit position for revision F and G.
810 	 */
811 	if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
812 		wide = MCREG_FIELD_F_revFG(&drcfg_lo, Width128);
813 	} else {
814 		wide = MCREG_FIELD_F_preF(&drcfg_lo, Width128);
815 	}
816 	mcp->mcp_accwidth = wide ? 128 : 64;
817 
818 	/*
819 	 * Read Function 2 DRAM Controller Miscellaenous Regsiter for those
820 	 * revs that support it.  This include the Mod64Mux indication on
821 	 * these revs - for rev E it is in DRAM config low.
822 	 */
823 	if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
824 		mcr->mcr_drammisc = MCREG_VAL32(&drmisc) =
825 		    mc_pcicfg_get32(cfghdl, MC_DC_REG_DRAMMISC);
826 		mcp->mcp_mod64mux = MCREG_FIELD_F_revFG(&drmisc, Mod64Mux);
827 	} else if (MC_REV_MATCH(rev, MC_F_REV_E)) {
828 		mcp->mcp_mod64mux = MCREG_FIELD_F_preF(&drcfg_lo, Mod64BitMux);
829 	}
830 
831 	/*
832 	 * Read Function 2 DRAM Bank Address Mapping.  This encodes the
833 	 * type of DIMM module in use for each chip-select pair.
834 	 * Prior ro revision F it also tells us whether BankSwizzle mode
835 	 * is enabled - in rev F that has moved to dram config hi register.
836 	 */
837 	mcp->mcp_csbankmapreg = MCREG_VAL32(&baddrmap) =
838 	    mc_pcicfg_get32(cfghdl, MC_DC_REG_BANKADDRMAP);
839 
840 	/*
841 	 * Determine whether bank swizzle mode is active.  Bank swizzling was
842 	 * introduced as an option in rev E,  but the bit that indicates it
843 	 * is enabled has moved in revs F/G.
844 	 */
845 	if (MC_REV_MATCH(rev, MC_F_REV_E)) {
846 		mcp->mcp_bnkswzl =
847 		    MCREG_FIELD_F_preF(&baddrmap, BankSwizzleMode);
848 	} else if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
849 		mcp->mcp_bnkswzl = MCREG_FIELD_F_revFG(&drcfg_hi,
850 		    BankSwizzleMode);
851 	}
852 
853 	/*
854 	 * Read the DRAM CS Base and DRAM CS Mask registers.  Revisions prior
855 	 * to F have an equal number of base and mask registers; revision F
856 	 * has twice as many base registers as masks.
857 	 */
858 	maskdivisor = MC_REV_MATCH(rev, MC_F_REVS_FG) ? 2 : 1;
859 
860 	mc_prop_read_pair(cfghdl,
861 	    (uint32_t *)base, MC_DC_REG_CSBASE_0, MC_CHIP_NCS,
862 	    (uint32_t *)mask, MC_DC_REG_CSMASK_0, MC_CHIP_NCS / maskdivisor,
863 	    MC_DC_REG_CS_INCR);
864 
865 	/*
866 	 * Create a cs node for each enabled chip-select as well as
867 	 * any appointed online spare chip-selects and for any that have
868 	 * failed test.
869 	 */
870 	for (i = 0; i < MC_CHIP_NCS; i++) {
871 		mc_cs_t *mccs;
872 		uint64_t csbase, csmask;
873 		size_t sz;
874 		int csbe, spare, testfail;
875 
876 		if (MC_REV_MATCH(rev, MC_F_REVS_FG)) {
877 			csbe = MCREG_FIELD_F_revFG(&base[i], CSEnable);
878 			spare = MCREG_FIELD_F_revFG(&base[i], Spare);
879 			testfail = MCREG_FIELD_F_revFG(&base[i], TestFail);
880 		} else {
881 			csbe = MCREG_FIELD_F_preF(&base[i], CSEnable);
882 			spare = 0;
883 			testfail = 0;
884 		}
885 
886 		/* Testing hook */
887 		if (testfail_mcnum != -1 && testfail_csnum != -1 &&
888 		    mcp->mcp_num == testfail_mcnum && i == testfail_csnum) {
889 			csbe = spare = 0;
890 			testfail = 1;
891 			cmn_err(CE_NOTE, "Pretending MC %d CS %d failed test",
892 			    testfail_mcnum, testfail_csnum);
893 		}
894 
895 		/*
896 		 * If the chip-select is not enabled then skip it unless
897 		 * it is a designated online spare or is marked with TestFail.
898 		 */
899 		if (!csbe && !(spare || testfail))
900 			continue;
901 
902 		/*
903 		 * For an enabled or spare chip-select the Bank Address Mapping
904 		 * register will be valid as will the chip-select mask.  The
905 		 * base will not be valid but we'll read and store it anyway.
906 		 * We will not know whether the spare is already swapped in
907 		 * until MC function 3 attaches.
908 		 */
909 		if (csbe || spare) {
910 			if (mcamd_cs_size(&hdl, (mcamd_node_t *)mc, i, &sz) < 0)
911 				continue;
912 			csbase = MC_CSBASE(&base[i], rev);
913 			csmask = MC_CSMASK(&mask[i / maskdivisor], rev);
914 		} else {
915 			sz = 0;
916 			csbase = csmask = 0;
917 		}
918 
919 		mccs = mc_cs_create(mc, i, csbase, csmask, sz,
920 		    csbe, spare, testfail);
921 
922 		if (mc->mc_cslist == NULL)
923 			mc->mc_cslist = mccs;
924 		else
925 			mc->mc_cslast->mccs_next = mccs;
926 		mc->mc_cslast = mccs;
927 
928 		mccs->mccs_cfgregs.csr_csbase = MCREG_VAL32(&base[i]);
929 		mccs->mccs_cfgregs.csr_csmask =
930 		    MCREG_VAL32(&mask[i / maskdivisor]);
931 
932 		/*
933 		 * Check for cs bank interleaving - some bits clear in the
934 		 * lower mask.  All banks must/will have the same lomask bits
935 		 * if cs interleaving is active.
936 		 */
937 		if (csbe && !mcp->mcp_csintlvfctr) {
938 			int bitno, ibits = 0;
939 			for (bitno = MC_CSMASKLO_LOBIT(rev);
940 			    bitno <= MC_CSMASKLO_HIBIT(rev); bitno++) {
941 				if (!(csmask & (1 << bitno)))
942 					ibits++;
943 			}
944 			mcp->mcp_csintlvfctr = 1 << ibits;
945 		}
946 	}
947 
948 	/*
949 	 * If there is no chip-select interleave on this node determine
950 	 * whether the chip-select ranks are contiguous or if there
951 	 * is a hole.
952 	 */
953 	if (mcp->mcp_csintlvfctr == 1) {
954 		mc_cs_t *csp[MC_CHIP_NCS];
955 		mc_cs_t *mccs;
956 		int ncsbe = 0;
957 
958 		for (mccs = mc->mc_cslist; mccs != NULL;
959 		    mccs = mccs->mccs_next) {
960 			if (mccs->mccs_props.csp_csbe)
961 				csp[ncsbe++] = mccs;
962 		}
963 
964 		if (ncsbe != 0) {
965 			qsort((void *)csp, ncsbe, sizeof (mc_cs_t *),
966 			    (int (*)(const void *, const void *))csbasecmp);
967 
968 			for (i = 1; i < ncsbe; i++) {
969 				if (csp[i]->mccs_props.csp_base !=
970 				    csp[i - 1]->mccs_props.csp_base +
971 				    csp[i - 1]->mccs_props.csp_size)
972 					mc->mc_csdiscontig = 1;
973 			}
974 		}
975 	}
976 
977 
978 	/*
979 	 * Since we do not attach to MC function 3 go ahead and read some
980 	 * config parameters from it now.
981 	 */
982 	mc_getmiscctl(mc);
983 
984 	/*
985 	 * Now that we have discovered all enabled/spare/testfail chip-selects
986 	 * we divine the associated DIMM configuration.
987 	 */
988 	mc_dimmlist_create(mc);
989 }
990 
991 typedef struct mc_bind_map {
992 	const char *bm_bindnm;	 /* attachment binding name */
993 	enum mc_funcnum bm_func; /* PCI config space function number for bind */
994 	const char *bm_model;	 /* value for device node model property */
995 	void (*bm_mkprops)(mc_pcicfg_hdl_t, mc_t *);
996 } mc_bind_map_t;
997 
998 /*
999  * Do not attach to MC function 3 - agpgart already attaches to that.
1000  * Function 3 may be a good candidate for a nexus driver to fan it out
1001  * into virtual devices by functionality.  We will use pci_mech1_getl
1002  * to retrieve the function 3 parameters we require.
1003  */
1004 
1005 static const mc_bind_map_t mc_bind_map[] = {
1006 	{ MC_FUNC_HTCONFIG_BINDNM, MC_FUNC_HTCONFIG,
1007 	    "AMD Memory Controller (HT Configuration)", mc_mkprops_htcfg },
1008 	{ MC_FUNC_ADDRMAP_BINDNM, MC_FUNC_ADDRMAP,
1009 	    "AMD Memory Controller (Address Map)", mc_mkprops_addrmap },
1010 	{ MC_FUNC_DRAMCTL_BINDNM, MC_FUNC_DRAMCTL,
1011 	    "AMD Memory Controller (DRAM Controller & HT Trace)",
1012 	    mc_mkprops_dramctl },
1013 	NULL
1014 };
1015 
1016 /*ARGSUSED*/
1017 static int
1018 mc_open(dev_t *devp, int flag, int otyp, cred_t *credp)
1019 {
1020 	if (otyp != OTYP_CHR)
1021 		return (EINVAL);
1022 
1023 	rw_enter(&mc_lock, RW_READER);
1024 	if (mc_lookup_by_chipid(getminor(*devp)) == NULL) {
1025 		rw_exit(&mc_lock);
1026 		return (EINVAL);
1027 	}
1028 	rw_exit(&mc_lock);
1029 
1030 	return (0);
1031 }
1032 
1033 /*ARGSUSED*/
1034 static int
1035 mc_close(dev_t dev, int flag, int otyp, cred_t *credp)
1036 {
1037 	return (0);
1038 }
1039 
1040 /*
1041  * Enable swap from chip-select csnum to the spare chip-select on this
1042  * memory controller (if any).
1043  */
1044 
1045 int mc_swapdonetime = 30;	/* max number of seconds to wait for SwapDone */
1046 
1047 static int
1048 mc_onlinespare(mc_t *mc, int csnum)
1049 {
1050 	mc_props_t *mcp = &mc->mc_props;
1051 	union mcreg_sparectl sparectl;
1052 	union mcreg_scrubctl scrubctl;
1053 	mc_cs_t *mccs;
1054 	hrtime_t tmax;
1055 	int i = 0;
1056 
1057 	ASSERT(RW_WRITE_HELD(&mc_lock));
1058 
1059 	if (!MC_REV_MATCH(mcp->mcp_rev, MC_F_REVS_FG))
1060 		return (ENOTSUP);	/* MC rev does not offer online spare */
1061 	else if (mcp->mcp_sparecs == MC_INVALNUM)
1062 		return (ENODEV);	/* Supported, but no spare configured */
1063 	else if (mcp->mcp_badcs != MC_INVALNUM)
1064 		return (EBUSY);		/* Spare already swapped in */
1065 	else if (csnum == mcp->mcp_sparecs)
1066 		return (EINVAL);	/* Can't spare the spare! */
1067 
1068 	for (mccs = mc->mc_cslist; mccs != NULL; mccs = mccs->mccs_next) {
1069 		if (mccs->mccs_props.csp_num == csnum)
1070 			break;
1071 	}
1072 	if (mccs == NULL)
1073 		return (EINVAL);	/* nominated bad CS does not exist */
1074 
1075 	/*
1076 	 * If the DRAM Scrubber is not enabled then the swap cannot succeed.
1077 	 */
1078 	MCREG_VAL32(&scrubctl) = mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL,
1079 	    MC_CTL_REG_SCRUBCTL);
1080 	if (MCREG_FIELD_CMN(&scrubctl, DramScrub) == 0)
1081 		return (ENODEV);	/* DRAM scrubber not enabled */
1082 
1083 	/*
1084 	 * Read Online Spare Comtrol Register again, just in case our
1085 	 * state does not reflect reality.
1086 	 */
1087 	MCREG_VAL32(&sparectl) = mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL,
1088 	    MC_CTL_REG_SPARECTL);
1089 
1090 	if (MCREG_FIELD_F_revFG(&sparectl, SwapDone))
1091 		return (EBUSY);
1092 
1093 	/* Write to the BadDramCs field */
1094 	MCREG_FIELD_F_revFG(&sparectl, BadDramCs) = csnum;
1095 	mc_pcicfg_put32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL,
1096 	    MCREG_VAL32(&sparectl));
1097 
1098 	/* And request that the swap to the spare start */
1099 	MCREG_FIELD_F_revFG(&sparectl, SwapEn) = 1;
1100 	mc_pcicfg_put32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL,
1101 	    MCREG_VAL32(&sparectl));
1102 
1103 	/*
1104 	 * Poll for SwapDone - we have disabled notification by interrupt.
1105 	 * Swap takes "several CPU cycles, depending on the DRAM speed, but
1106 	 * is performed in the background" (Family 0Fh Bios Porting Guide).
1107 	 * We're in a slow ioctl path so there is no harm in waiting around
1108 	 * a bit - consumers of the ioctl must be aware that it may take
1109 	 * a moment.  We will poll for up to mc_swapdonetime seconds,
1110 	 * limiting that to 120s.
1111 	 *
1112 	 * The swap is performed by the DRAM scrubber (which must be enabled)
1113 	 * whose scrub rate is accelerated for the duration of the swap.
1114 	 * The maximum swap rate is 40.0ns per 64 bytes, so the maximum
1115 	 * supported cs size of 16GB would take 10.7s at that max rate
1116 	 * of 25000000 scrubs/second.
1117 	 */
1118 	tmax = gethrtime() + MIN(mc_swapdonetime, 120) * 1000000000ULL;
1119 	do {
1120 		if (i++ < 20)
1121 			delay(drv_usectohz(100000));	/* 0.1s for up to 2s */
1122 		else
1123 			delay(drv_usectohz(500000));	/* 0.5s */
1124 
1125 		MCREG_VAL32(&sparectl) = mc_pcicfg_get32_nohdl(mc,
1126 		    MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL);
1127 	} while (!MCREG_FIELD_F_revFG(&sparectl, SwapDone) &&
1128 	    gethrtime() < tmax);
1129 
1130 	if (!MCREG_FIELD_F_revFG(&sparectl, SwapDone))
1131 		return (ETIME);		/* Operation timed out */
1132 
1133 	mcp->mcp_badcs = csnum;
1134 	mc->mc_cfgregs.mcr_sparectl = MCREG_VAL32(&sparectl);
1135 	mc->mc_spareswaptime = gethrtime();
1136 
1137 	return (0);
1138 }
1139 
1140 /*ARGSUSED*/
1141 static int
1142 mc_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp)
1143 {
1144 	int rc = 0;
1145 	mc_t *mc;
1146 
1147 	if (cmd != MC_IOC_SNAPSHOT_INFO && cmd != MC_IOC_SNAPSHOT &&
1148 	    cmd != MC_IOC_ONLINESPARE_EN)
1149 		return (EINVAL);
1150 
1151 	rw_enter(&mc_lock, RW_READER);
1152 
1153 	if ((mc = mc_lookup_by_chipid(getminor(dev))) == NULL) {
1154 		rw_exit(&mc_lock);
1155 		return (EINVAL);
1156 	}
1157 
1158 	switch (cmd) {
1159 	case MC_IOC_SNAPSHOT_INFO: {
1160 		mc_snapshot_info_t mcs;
1161 
1162 		if (mc_snapshot_update(mc) < 0) {
1163 			rw_exit(&mc_lock);
1164 			return (EIO);
1165 		}
1166 
1167 		mcs.mcs_size = mc->mc_snapshotsz;
1168 		mcs.mcs_gen = mc->mc_snapshotgen;
1169 
1170 		if (ddi_copyout(&mcs, (void *)arg, sizeof (mc_snapshot_info_t),
1171 		    mode) < 0)
1172 			rc = EFAULT;
1173 		break;
1174 	}
1175 
1176 	case MC_IOC_SNAPSHOT:
1177 		if (mc_snapshot_update(mc) < 0) {
1178 			rw_exit(&mc_lock);
1179 			return (EIO);
1180 		}
1181 
1182 		if (ddi_copyout(mc->mc_snapshot, (void *)arg, mc->mc_snapshotsz,
1183 		    mode) < 0)
1184 			rc = EFAULT;
1185 		break;
1186 
1187 	case MC_IOC_ONLINESPARE_EN:
1188 		if (drv_priv(credp) != 0) {
1189 			rw_exit(&mc_lock);
1190 			return (EPERM);
1191 		}
1192 
1193 		if (!rw_tryupgrade(&mc_lock)) {
1194 			rw_exit(&mc_lock);
1195 			return (EAGAIN);
1196 		}
1197 
1198 		if ((rc = mc_onlinespare(mc, (int)arg)) == 0) {
1199 			mc_snapshot_destroy(mc);
1200 			nvlist_free(mc->mc_nvl);
1201 			mc->mc_nvl = mc_nvl_create(mc);
1202 		}
1203 
1204 		break;
1205 	}
1206 
1207 	rw_exit(&mc_lock);
1208 
1209 	return (rc);
1210 }
1211 
1212 static struct cb_ops mc_cb_ops = {
1213 	mc_open,
1214 	mc_close,
1215 	nodev,		/* not a block driver */
1216 	nodev,		/* no print routine */
1217 	nodev,		/* no dump routine */
1218 	nodev,		/* no read routine */
1219 	nodev,		/* no write routine */
1220 	mc_ioctl,
1221 	nodev,		/* no devmap routine */
1222 	nodev,		/* no mmap routine */
1223 	nodev,		/* no segmap routine */
1224 	nochpoll,	/* no chpoll routine */
1225 	ddi_prop_op,
1226 	0,		/* not a STREAMS driver */
1227 	D_NEW | D_MP,	/* safe for multi-thread/multi-processor */
1228 };
1229 
1230 /*ARGSUSED*/
1231 static int
1232 mc_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
1233 {
1234 	int rc = DDI_SUCCESS;
1235 	mc_t *mc;
1236 
1237 	if (infocmd != DDI_INFO_DEVT2DEVINFO &&
1238 	    infocmd != DDI_INFO_DEVT2INSTANCE) {
1239 		*result = NULL;
1240 		return (DDI_FAILURE);
1241 	}
1242 
1243 	rw_enter(&mc_lock, RW_READER);
1244 
1245 	if ((mc = mc_lookup_by_chipid(getminor((dev_t)arg))) == NULL ||
1246 	    mc->mc_funcs[MC_FUNC_DEVIMAP].mcf_devi == NULL) {
1247 		rc = DDI_FAILURE;
1248 	} else if (infocmd == DDI_INFO_DEVT2DEVINFO) {
1249 		*result = mc->mc_funcs[MC_FUNC_DEVIMAP].mcf_devi;
1250 	} else {
1251 		*result = (void *)(uintptr_t)
1252 		    mc->mc_funcs[MC_FUNC_DEVIMAP].mcf_instance;
1253 	}
1254 
1255 	rw_exit(&mc_lock);
1256 
1257 	return (rc);
1258 }
1259 
1260 /*ARGSUSED2*/
1261 static int
1262 mc_fm_handle(dev_info_t *dip, ddi_fm_error_t *fmerr, const void *arg)
1263 {
1264 	pci_ereport_post(dip, fmerr, NULL);
1265 	return (fmerr->fme_status);
1266 }
1267 
1268 static void
1269 mc_fm_init(dev_info_t *dip)
1270 {
1271 	int fmcap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE;
1272 	ddi_fm_init(dip, &fmcap, NULL);
1273 	pci_ereport_setup(dip);
1274 	ddi_fm_handler_register(dip, mc_fm_handle, NULL);
1275 }
1276 
1277 static void
1278 mc_read_smbios(mc_t *mc, dev_info_t *dip)
1279 {
1280 
1281 	uint16_t bdf;
1282 	pci_regspec_t *pci_rp = NULL;
1283 	uint32_t phys_hi;
1284 	int m = 0;
1285 	uint_t chip_inst;
1286 	int rc = 0;
1287 
1288 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
1289 	    (caddr_t)&pci_rp, &m) == DDI_SUCCESS) {
1290 		phys_hi = pci_rp->pci_phys_hi;
1291 		bdf = (uint16_t)(PCI_REG_BDFR_G(phys_hi) >>
1292 		    PCI_REG_FUNC_SHIFT);
1293 		kmem_free(pci_rp, m);
1294 		pci_rp = NULL;
1295 
1296 		rc = fm_smb_mc_chipinst(bdf, &chip_inst);
1297 		if (rc == 0) {
1298 			mc->smb_chipid = chip_inst;
1299 		} else {
1300 #ifdef DEBUG
1301 			cmn_err(CE_NOTE, "!mc read smbios chip info failed");
1302 #endif /* DEBUG */
1303 			return;
1304 		}
1305 		mc->smb_bboard = fm_smb_mc_bboards(bdf);
1306 #ifdef DEBUG
1307 		if (mc->smb_bboard == NULL)
1308 			cmn_err(CE_NOTE,
1309 			    "!mc read smbios base boards info failed");
1310 #endif /* DEBUG */
1311 	}
1312 
1313 	if (pci_rp != NULL)
1314 		kmem_free(pci_rp, m);
1315 }
1316 
1317 /*ARGSUSED*/
1318 static int
1319 mc_create_cb(cmi_hdl_t whdl, void *arg1, void *arg2, void *arg3)
1320 {
1321 	chipid_t chipid = *((chipid_t *)arg1);
1322 	cmi_hdl_t *hdlp = (cmi_hdl_t *)arg2;
1323 
1324 	if (cmi_hdl_chipid(whdl) == chipid) {
1325 		cmi_hdl_hold(whdl);	/* short-term hold */
1326 		*hdlp = whdl;
1327 		return (CMI_HDL_WALK_DONE);
1328 	} else {
1329 		return (CMI_HDL_WALK_NEXT);
1330 	}
1331 }
1332 
1333 static mc_t *
1334 mc_create(chipid_t chipid, dev_info_t *dip)
1335 {
1336 	mc_t *mc;
1337 	cmi_hdl_t hdl = NULL;
1338 
1339 	ASSERT(RW_WRITE_HELD(&mc_lock));
1340 
1341 	/*
1342 	 * Find a handle for one of a chip's CPU.
1343 	 *
1344 	 * We can use one of the chip's CPUs since all cores
1345 	 * of a chip share the same revision and socket type.
1346 	 */
1347 	cmi_hdl_walk(mc_create_cb, (void *)&chipid, (void *)&hdl, NULL);
1348 	if (hdl == NULL)
1349 		return (NULL);	/* no cpu for this chipid found! */
1350 
1351 	mc = kmem_zalloc(sizeof (mc_t), KM_SLEEP);
1352 
1353 	mc->mc_hdr.mch_type = MC_NT_MC;
1354 	mc->mc_props.mcp_num = chipid;
1355 	mc->mc_props.mcp_sparecs = MC_INVALNUM;
1356 	mc->mc_props.mcp_badcs = MC_INVALNUM;
1357 
1358 	mc->mc_props.mcp_rev = cmi_hdl_chiprev(hdl);
1359 	mc->mc_revname = cmi_hdl_chiprevstr(hdl);
1360 	mc->mc_socket = cmi_hdl_getsockettype(hdl);
1361 
1362 	mc_read_smbios(mc, dip);
1363 
1364 	if (mc_list == NULL)
1365 		mc_list = mc;
1366 	if (mc_last != NULL)
1367 		mc_last->mc_next = mc;
1368 
1369 	mc->mc_next = NULL;
1370 	mc_last = mc;
1371 
1372 	cmi_hdl_rele(hdl);
1373 
1374 	return (mc);
1375 }
1376 
1377 /*
1378  * Return the maximum scrubbing rate between r1 and r2, where r2 is extracted
1379  * from the specified 'cfg' register value using 'mask' and 'shift'.  If a
1380  * value is zero, scrubbing is off so return the opposite value.  Otherwise
1381  * the maximum rate is the smallest non-zero value of the two values.
1382  */
1383 static uint32_t
1384 mc_scrubber_max(uint32_t r1, uint32_t cfg, uint32_t mask, uint32_t shift)
1385 {
1386 	uint32_t r2 = (cfg & mask) >> shift;
1387 
1388 	if (r1 != 0 && r2 != 0)
1389 		return (MIN(r1, r2));
1390 
1391 	return (r1 ? r1 : r2);
1392 }
1393 
1394 
1395 /*
1396  * Enable the memory scrubber.  We must use the mc_pcicfg_{get32,put32}_nohdl
1397  * interfaces since we do not bind to function 3.
1398  */
1399 cmi_errno_t
1400 mc_scrubber_enable(mc_t *mc)
1401 {
1402 	mc_props_t *mcp = &mc->mc_props;
1403 	chipid_t chipid = (chipid_t)mcp->mcp_num;
1404 	uint32_t rev = (uint32_t)mcp->mcp_rev;
1405 	mc_cfgregs_t *mcr = &mc->mc_cfgregs;
1406 	union mcreg_scrubctl scrubctl;
1407 	union mcreg_dramscrublo dalo;
1408 	union mcreg_dramscrubhi dahi;
1409 
1410 	mcr->mcr_scrubctl = MCREG_VAL32(&scrubctl) =
1411 	    mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBCTL);
1412 
1413 	mcr->mcr_scrubaddrlo = MCREG_VAL32(&dalo) =
1414 	    mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_LO);
1415 
1416 	mcr->mcr_scrubaddrhi = MCREG_VAL32(&dahi) =
1417 	    mc_pcicfg_get32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_HI);
1418 
1419 	if (mc_scrub_policy == MC_SCRUB_BIOSDEFAULT)
1420 		return (MCREG_FIELD_CMN(&scrubctl, DramScrub) !=
1421 		    AMD_NB_SCRUBCTL_RATE_NONE ?
1422 		    CMI_SUCCESS : CMIERR_MC_NOMEMSCRUB);
1423 
1424 	/*
1425 	 * Disable DRAM scrubbing while we fiddle.
1426 	 */
1427 	MCREG_FIELD_CMN(&scrubctl, DramScrub) = AMD_NB_SCRUBCTL_RATE_NONE;
1428 	mc_pcicfg_put32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBCTL,
1429 	    MCREG_VAL32(&scrubctl));
1430 
1431 	/*
1432 	 * Setup DRAM Scrub Address Low and High registers for the
1433 	 * base address of this node, and to select srubber redirect.
1434 	 */
1435 	MCREG_FIELD_CMN(&dalo, ScrubReDirEn) = 1;
1436 	MCREG_FIELD_CMN(&dalo, ScrubAddrLo) =
1437 	    AMD_NB_SCRUBADDR_MKLO(mcp->mcp_base);
1438 
1439 	MCREG_FIELD_CMN(&dahi, ScrubAddrHi) =
1440 	    AMD_NB_SCRUBADDR_MKHI(mcp->mcp_base);
1441 
1442 	mc_pcicfg_put32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_LO,
1443 	    MCREG_VAL32(&dalo));
1444 	mc_pcicfg_put32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBADDR_HI,
1445 	    MCREG_VAL32(&dahi));
1446 
1447 	if (mc_scrub_rate_dram > AMD_NB_SCRUBCTL_RATE_MAX) {
1448 		cmn_err(CE_WARN, "mc_scrub_rate_dram is too large; "
1449 		    "resetting to 0x%x\n", AMD_NB_SCRUBCTL_RATE_MAX);
1450 		mc_scrub_rate_dram = AMD_NB_SCRUBCTL_RATE_MAX;
1451 	}
1452 
1453 	switch (mc_scrub_policy) {
1454 	case MC_SCRUB_FIXED:
1455 		/* Use the system value checked above */
1456 		break;
1457 
1458 	default:
1459 		cmn_err(CE_WARN, "Unknown mc_scrub_policy value %d - "
1460 		    "using default policy of MC_SCRUB_MAX", mc_scrub_policy);
1461 		/*FALLTHRU*/
1462 
1463 	case MC_SCRUB_MAX:
1464 		mc_scrub_rate_dram = mc_scrubber_max(mc_scrub_rate_dram,
1465 		    mcr->mcr_scrubctl, AMD_NB_SCRUBCTL_DRAM_MASK,
1466 		    AMD_NB_SCRUBCTL_DRAM_SHIFT);
1467 		break;
1468 	}
1469 
1470 	/*
1471 	 * OPTERON_ERRATUM_99:
1472 	 * This erratum applies on revisions D and earlier.
1473 	 * This erratum also applies on revisions E and later,
1474 	 * if BIOS uses chip-select hoisting instead of DRAM hole
1475 	 * mapping.
1476 	 *
1477 	 * Do not enable the dram scrubber if the chip-select ranges
1478 	 * for the node are not contiguous.
1479 	 */
1480 	if (mc_scrub_rate_dram != AMD_NB_SCRUBCTL_RATE_NONE &&
1481 	    mc->mc_csdiscontig) {
1482 		cmn_err(CE_CONT, "?Opteron DRAM scrubber disabled on revision "
1483 		    "%s chip %d because DRAM hole is present on this node",
1484 		    mc->mc_revname, chipid);
1485 		mc_scrub_rate_dram = AMD_NB_SCRUBCTL_RATE_NONE;
1486 	}
1487 
1488 	/*
1489 	 * OPTERON_ERRATUM_101:
1490 	 * This erratum applies on revisions D and earlier.
1491 	 *
1492 	 * If the DRAM Base Address register's IntlvEn field indicates that
1493 	 * node interleaving is enabled, we must disable the DRAM scrubber
1494 	 * and return zero to indicate that Solaris should use s/w instead.
1495 	 */
1496 	if (mc_scrub_rate_dram != AMD_NB_SCRUBCTL_RATE_NONE &&
1497 	    mcp->mcp_ilen != 0 &&
1498 	    !X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_E)) {
1499 		cmn_err(CE_CONT, "?Opteron DRAM scrubber disabled on revision "
1500 		    "%s chip %d because DRAM memory is node-interleaved",
1501 		    mc->mc_revname, chipid);
1502 		mc_scrub_rate_dram = AMD_NB_SCRUBCTL_RATE_NONE;
1503 	}
1504 
1505 	if (mc_scrub_rate_dram != AMD_NB_SCRUBCTL_RATE_NONE) {
1506 		MCREG_FIELD_CMN(&scrubctl, DramScrub) = mc_scrub_rate_dram;
1507 		mc_pcicfg_put32_nohdl(mc, MC_FUNC_MISCCTL, MC_CTL_REG_SCRUBCTL,
1508 		    MCREG_VAL32(&scrubctl));
1509 	}
1510 
1511 	return (mc_scrub_rate_dram != AMD_NB_SCRUBCTL_RATE_NONE ?
1512 	    CMI_SUCCESS : CMIERR_MC_NOMEMSCRUB);
1513 }
1514 
1515 /*ARGSUSED*/
1516 static int
1517 mc_attach_cb(cmi_hdl_t whdl, void *arg1, void *arg2, void *arg3)
1518 {
1519 	mc_t *mc = (mc_t *)arg1;
1520 	mcamd_prop_t chipid = *((mcamd_prop_t *)arg2);
1521 
1522 	if (cmi_hdl_chipid(whdl) == chipid) {
1523 		mcamd_mc_register(whdl, mc);
1524 	}
1525 
1526 	return (CMI_HDL_WALK_NEXT);
1527 }
1528 
1529 static int mc_sw_scrub_disabled = 0;
1530 
1531 static int
1532 mc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1533 {
1534 	mc_pcicfg_hdl_t cfghdl;
1535 	const mc_bind_map_t *bm;
1536 	const char *bindnm;
1537 	char *unitstr = NULL;
1538 	enum mc_funcnum func;
1539 	long unitaddr;
1540 	int chipid, rc;
1541 	mc_t *mc;
1542 
1543 	/*
1544 	 * This driver has no hardware state, but does
1545 	 * claim to have a reg property, so it will be
1546 	 * called on suspend.  It is probably better to
1547 	 * make sure it doesn't get called on suspend,
1548 	 * but it is just as easy to make sure we just
1549 	 * return DDI_SUCCESS if called.
1550 	 */
1551 	if (cmd == DDI_RESUME)
1552 		return (DDI_SUCCESS);
1553 
1554 	if (cmd != DDI_ATTACH || mc_no_attach != 0)
1555 		return (DDI_FAILURE);
1556 
1557 	bindnm = ddi_binding_name(dip);
1558 	for (bm = mc_bind_map; bm->bm_bindnm != NULL; bm++) {
1559 		if (strcmp(bindnm, bm->bm_bindnm) == 0) {
1560 			func = bm->bm_func;
1561 			break;
1562 		}
1563 	}
1564 
1565 	if (bm->bm_bindnm == NULL)
1566 		return (DDI_FAILURE);
1567 
1568 	/*
1569 	 * We need the device number, which corresponds to the processor node
1570 	 * number plus 24.  The node number can then be used to associate this
1571 	 * memory controller device with a given processor chip.
1572 	 */
1573 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
1574 	    DDI_PROP_DONTPASS, "unit-address", &unitstr) != DDI_PROP_SUCCESS) {
1575 		cmn_err(CE_WARN, "failed to find unit-address for %s", bindnm);
1576 		return (DDI_FAILURE);
1577 	}
1578 
1579 	rc = ddi_strtol(unitstr, NULL, 16, &unitaddr);
1580 	ASSERT(rc == 0 && unitaddr >= MC_AMD_DEV_OFFSET);
1581 
1582 	if (rc != 0 || unitaddr < MC_AMD_DEV_OFFSET) {
1583 		cmn_err(CE_WARN, "failed to parse unit address %s for %s\n",
1584 		    unitstr, bindnm);
1585 		ddi_prop_free(unitstr);
1586 		return (DDI_FAILURE);
1587 	}
1588 	ddi_prop_free(unitstr);
1589 
1590 	chipid = unitaddr - MC_AMD_DEV_OFFSET;
1591 
1592 	rw_enter(&mc_lock, RW_WRITER);
1593 
1594 	for (mc = mc_list; mc != NULL; mc = mc->mc_next) {
1595 		if (mc->mc_props.mcp_num == chipid)
1596 			break;
1597 	}
1598 
1599 	/* Integrate this memory controller device into existing set */
1600 	if (mc == NULL) {
1601 		mc = mc_create(chipid, dip);
1602 
1603 		if (mc == NULL) {
1604 			/*
1605 			 * We don't complain here because this is a legitimate
1606 			 * path for MP systems.  On those machines, we'll attach
1607 			 * before all CPUs have been initialized, and thus the
1608 			 * chip verification in mc_create will fail.  We'll be
1609 			 * reattached later for those CPUs.
1610 			 */
1611 			rw_exit(&mc_lock);
1612 			return (DDI_FAILURE);
1613 		}
1614 	} else {
1615 		mc_snapshot_destroy(mc);
1616 	}
1617 
1618 	/* Beyond this point, we're committed to creating this node */
1619 
1620 	mc_fm_init(dip);
1621 
1622 	ASSERT(mc->mc_funcs[func].mcf_devi == NULL);
1623 	mc->mc_funcs[func].mcf_devi = dip;
1624 	mc->mc_funcs[func].mcf_instance = ddi_get_instance(dip);
1625 
1626 	mc->mc_ref++;
1627 
1628 	/*
1629 	 * Add the common properties to this node, and then add any properties
1630 	 * that are specific to this node based upon its configuration space.
1631 	 */
1632 	(void) ddi_prop_update_string(DDI_DEV_T_NONE,
1633 	    dip, "model", (char *)bm->bm_model);
1634 
1635 	(void) ddi_prop_update_int(DDI_DEV_T_NONE,
1636 	    dip, "chip-id", mc->mc_props.mcp_num);
1637 
1638 	if (bm->bm_mkprops != NULL &&
1639 	    mc_pcicfg_setup(mc, bm->bm_func, &cfghdl) == DDI_SUCCESS) {
1640 		bm->bm_mkprops(cfghdl, mc);
1641 		mc_pcicfg_teardown(cfghdl);
1642 	}
1643 
1644 	/*
1645 	 * If this is the last node to be attached for this memory controller,
1646 	 * then create the minor node, enable scrubbers, and register with
1647 	 * cpu module(s) for this chip.
1648 	 */
1649 	if (func == MC_FUNC_DEVIMAP) {
1650 		mc_props_t *mcp = &mc->mc_props;
1651 		int dram_present = 0;
1652 
1653 		if (ddi_create_minor_node(dip, "mc-amd", S_IFCHR,
1654 		    mcp->mcp_num, "ddi_mem_ctrl",
1655 		    0) != DDI_SUCCESS) {
1656 			cmn_err(CE_WARN, "failed to create minor node for chip "
1657 			    "%d memory controller\n",
1658 			    (chipid_t)mcp->mcp_num);
1659 		}
1660 
1661 		/*
1662 		 * Register the memory controller for every CPU of this chip.
1663 		 *
1664 		 * If there is memory present on this node and ECC is enabled
1665 		 * attempt to enable h/w memory scrubbers for this node.
1666 		 * If we are successful in enabling *any* hardware scrubbers,
1667 		 * disable the software memory scrubber.
1668 		 */
1669 		cmi_hdl_walk(mc_attach_cb, (void *)mc, (void *)&mcp->mcp_num,
1670 		    NULL);
1671 
1672 		if (mcp->mcp_lim != mcp->mcp_base) {
1673 			/*
1674 			 * This node may map non-dram memory alone, so we
1675 			 * must check for an enabled chip-select to be
1676 			 * sure there is dram present.
1677 			 */
1678 			mc_cs_t *mccs;
1679 
1680 			for (mccs = mc->mc_cslist; mccs != NULL;
1681 			    mccs = mccs->mccs_next) {
1682 				if (mccs->mccs_props.csp_csbe) {
1683 					dram_present = 1;
1684 					break;
1685 				}
1686 			}
1687 		}
1688 
1689 		if (dram_present && !mc_ecc_enabled(mc)) {
1690 			/*
1691 			 * On a single chip system there is no point in
1692 			 * scrubbing if there is no ECC on the single node.
1693 			 * On a multichip system, necessarily Opteron using
1694 			 * registered ECC-capable DIMMs, if there is memory
1695 			 * present on a node but no ECC there then we'll assume
1696 			 * ECC is disabled for all nodes and we will not enable
1697 			 * the scrubber and wll also disable the software
1698 			 * memscrub thread.
1699 			 */
1700 			rc = 1;
1701 		} else if (!dram_present) {
1702 			/* No memory on this node - others decide memscrub */
1703 			rc = 0;
1704 		} else {
1705 			/*
1706 			 * There is memory on this node and ECC is enabled.
1707 			 * Call via the cpu module to enable memory scrubbing
1708 			 * on this node - we could call directly but then
1709 			 * we may overlap with a request to enable chip-cache
1710 			 * scrubbing.
1711 			 */
1712 			rc = mc_scrubber_enable(mc);
1713 		}
1714 
1715 		if (rc == CMI_SUCCESS && !mc_sw_scrub_disabled++)
1716 			cmi_mc_sw_memscrub_disable();
1717 
1718 		mc_report_testfails(mc);
1719 	}
1720 
1721 	/*
1722 	 * Update nvlist for as far as we have gotten in attach/init.
1723 	 */
1724 	nvlist_free(mc->mc_nvl);
1725 	mc->mc_nvl = mc_nvl_create(mc);
1726 
1727 	rw_exit(&mc_lock);
1728 	return (DDI_SUCCESS);
1729 }
1730 
1731 /*ARGSUSED*/
1732 static int
1733 mc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1734 {
1735 	/*
1736 	 * See the comment about suspend in
1737 	 * mc_attach().
1738 	 */
1739 	if (cmd == DDI_SUSPEND)
1740 		return (DDI_SUCCESS);
1741 	else
1742 		return (DDI_FAILURE);
1743 }
1744 
1745 
1746 static struct dev_ops mc_ops = {
1747 	DEVO_REV,		/* devo_rev */
1748 	0,			/* devo_refcnt */
1749 	mc_getinfo,		/* devo_getinfo */
1750 	nulldev,		/* devo_identify */
1751 	nulldev,		/* devo_probe */
1752 	mc_attach,		/* devo_attach */
1753 	mc_detach,		/* devo_detach */
1754 	nodev,			/* devo_reset */
1755 	&mc_cb_ops,		/* devo_cb_ops */
1756 	NULL,			/* devo_bus_ops */
1757 	NULL,			/* devo_power */
1758 	ddi_quiesce_not_needed,		/* devo_quiesce */
1759 };
1760 
1761 static struct modldrv modldrv = {
1762 	&mod_driverops,
1763 	"Memory Controller for AMD processors",
1764 	&mc_ops
1765 };
1766 
1767 static struct modlinkage modlinkage = {
1768 	MODREV_1,
1769 	(void *)&modldrv,
1770 	NULL
1771 };
1772 
1773 int
1774 _init(void)
1775 {
1776 	/*
1777 	 * Refuse to load if there is no PCI config space support.
1778 	 */
1779 	if (pci_getl_func == NULL)
1780 		return (ENOTSUP);
1781 
1782 	rw_init(&mc_lock, NULL, RW_DRIVER, NULL);
1783 	return (mod_install(&modlinkage));
1784 }
1785 
1786 int
1787 _info(struct modinfo *modinfop)
1788 {
1789 	return (mod_info(&modlinkage, modinfop));
1790 }
1791 
1792 int
1793 _fini(void)
1794 {
1795 	int rc;
1796 
1797 	if ((rc = mod_remove(&modlinkage)) != 0)
1798 		return (rc);
1799 
1800 	rw_destroy(&mc_lock);
1801 	return (0);
1802 }
1803