xref: /illumos-gate/usr/src/uts/intel/io/intel_nhm/nhm_init.c (revision 35366b936dd27e7a780ce1c1fccdf6e3c3defe69)
1f657cd55SCheng Sean Ye /*
2f657cd55SCheng Sean Ye  * CDDL HEADER START
3f657cd55SCheng Sean Ye  *
4f657cd55SCheng Sean Ye  * The contents of this file are subject to the terms of the
5f657cd55SCheng Sean Ye  * Common Development and Distribution License (the "License").
6f657cd55SCheng Sean Ye  * You may not use this file except in compliance with the License.
7f657cd55SCheng Sean Ye  *
8f657cd55SCheng Sean Ye  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f657cd55SCheng Sean Ye  * or http://www.opensolaris.org/os/licensing.
10f657cd55SCheng Sean Ye  * See the License for the specific language governing permissions
11f657cd55SCheng Sean Ye  * and limitations under the License.
12f657cd55SCheng Sean Ye  *
13f657cd55SCheng Sean Ye  * When distributing Covered Code, include this CDDL HEADER in each
14f657cd55SCheng Sean Ye  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f657cd55SCheng Sean Ye  * If applicable, add the following below this CDDL HEADER, with the
16f657cd55SCheng Sean Ye  * fields enclosed by brackets "[]" replaced with your own identifying
17f657cd55SCheng Sean Ye  * information: Portions Copyright [yyyy] [name of copyright owner]
18f657cd55SCheng Sean Ye  *
19f657cd55SCheng Sean Ye  * CDDL HEADER END
20f657cd55SCheng Sean Ye  */
21f657cd55SCheng Sean Ye 
22f657cd55SCheng Sean Ye /*
23f657cd55SCheng Sean Ye  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24f657cd55SCheng Sean Ye  * Use is subject to license terms.
25f657cd55SCheng Sean Ye  */
26f657cd55SCheng Sean Ye 
27f657cd55SCheng Sean Ye #include <sys/types.h>
28f657cd55SCheng Sean Ye #include <sys/cmn_err.h>
29f657cd55SCheng Sean Ye #include <sys/errno.h>
30f657cd55SCheng Sean Ye #include <sys/log.h>
31f657cd55SCheng Sean Ye #include <sys/systm.h>
32f657cd55SCheng Sean Ye #include <sys/modctl.h>
33f657cd55SCheng Sean Ye #include <sys/errorq.h>
34f657cd55SCheng Sean Ye #include <sys/controlregs.h>
35f657cd55SCheng Sean Ye #include <sys/fm/util.h>
36f657cd55SCheng Sean Ye #include <sys/fm/protocol.h>
37f657cd55SCheng Sean Ye #include <sys/sysevent.h>
38f657cd55SCheng Sean Ye #include <sys/pghw.h>
39f657cd55SCheng Sean Ye #include <sys/cyclic.h>
40f657cd55SCheng Sean Ye #include <sys/pci_cfgspace.h>
41f657cd55SCheng Sean Ye #include <sys/mc_intel.h>
42f657cd55SCheng Sean Ye #include <sys/cpu_module_impl.h>
43f657cd55SCheng Sean Ye #include <sys/smbios.h>
44f657cd55SCheng Sean Ye #include <sys/pci.h>
45f657cd55SCheng Sean Ye #include "intel_nhm.h"
46f657cd55SCheng Sean Ye #include "nhm_log.h"
47f657cd55SCheng Sean Ye 
48f657cd55SCheng Sean Ye errorq_t *nhm_queue;
49f657cd55SCheng Sean Ye kmutex_t nhm_mutex;
50f657cd55SCheng Sean Ye uint32_t nhm_chipset;
51f657cd55SCheng Sean Ye 
52f657cd55SCheng Sean Ye nhm_dimm_t **nhm_dimms;
53f657cd55SCheng Sean Ye 
54f657cd55SCheng Sean Ye uint64_t nhm_memory_on_ctl[MAX_MEMORY_CONTROLLERS];
55f657cd55SCheng Sean Ye int nhm_patrol_scrub;
56f657cd55SCheng Sean Ye int nhm_demand_scrub;
57f657cd55SCheng Sean Ye int nhm_no_smbios;
58f657cd55SCheng Sean Ye int nhm_smbios_serial;
59f657cd55SCheng Sean Ye int nhm_smbios_manufacturer;
60f657cd55SCheng Sean Ye int nhm_smbios_part_number;
61f657cd55SCheng Sean Ye int nhm_smbios_version;
62f657cd55SCheng Sean Ye int nhm_smbios_label;
63f657cd55SCheng Sean Ye 
64f657cd55SCheng Sean Ye extern char ecc_enabled;
65f657cd55SCheng Sean Ye extern void mem_reg_init(void);
66f657cd55SCheng Sean Ye 
67f657cd55SCheng Sean Ye static void
check_serial_number()68f657cd55SCheng Sean Ye check_serial_number()
69f657cd55SCheng Sean Ye {
70f657cd55SCheng Sean Ye 	nhm_dimm_t *dimmp, *tp;
71f657cd55SCheng Sean Ye 	nhm_dimm_t **dimmpp, **tpp;
72f657cd55SCheng Sean Ye 	nhm_dimm_t **end;
73f657cd55SCheng Sean Ye 	int not_unique;
74f657cd55SCheng Sean Ye 
75f657cd55SCheng Sean Ye 	end = &nhm_dimms[MAX_MEMORY_CONTROLLERS *
76f657cd55SCheng Sean Ye 	    CHANNELS_PER_MEMORY_CONTROLLER * MAX_DIMMS_PER_CHANNEL];
77f657cd55SCheng Sean Ye 	for (dimmpp = nhm_dimms; dimmpp < end; dimmpp++) {
78f657cd55SCheng Sean Ye 		dimmp = *dimmpp;
79f657cd55SCheng Sean Ye 		if (dimmp == NULL)
80f657cd55SCheng Sean Ye 			continue;
81f657cd55SCheng Sean Ye 		not_unique = 0;
82f657cd55SCheng Sean Ye 		for (tpp = dimmpp + 1; tpp < end; tpp++) {
83f657cd55SCheng Sean Ye 			tp = *tpp;
84f657cd55SCheng Sean Ye 			if (tp == NULL)
85f657cd55SCheng Sean Ye 				continue;
86f657cd55SCheng Sean Ye 			if (strncmp(dimmp->serial_number, tp->serial_number,
87f657cd55SCheng Sean Ye 			    sizeof (dimmp->serial_number)) == 0) {
88f657cd55SCheng Sean Ye 				not_unique = 1;
89f657cd55SCheng Sean Ye 				tp->serial_number[0] = 0;
90f657cd55SCheng Sean Ye 			}
91f657cd55SCheng Sean Ye 		}
92f657cd55SCheng Sean Ye 		if (not_unique)
93f657cd55SCheng Sean Ye 			dimmp->serial_number[0] = 0;
94f657cd55SCheng Sean Ye 	}
95f657cd55SCheng Sean Ye }
96f657cd55SCheng Sean Ye 
97f657cd55SCheng Sean Ye static void
dimm_manufacture_data(smbios_hdl_t * shp,id_t id,nhm_dimm_t * dimmp)98f657cd55SCheng Sean Ye dimm_manufacture_data(smbios_hdl_t *shp, id_t id, nhm_dimm_t *dimmp)
99f657cd55SCheng Sean Ye {
100f657cd55SCheng Sean Ye 	smbios_info_t cd;
101f657cd55SCheng Sean Ye 
102f657cd55SCheng Sean Ye 	if (smbios_info_common(shp, id, &cd) == 0) {
103f657cd55SCheng Sean Ye 		if (cd.smbi_serial && nhm_smbios_serial) {
104f657cd55SCheng Sean Ye 			(void) strncpy(dimmp->serial_number, cd.smbi_serial,
105f657cd55SCheng Sean Ye 			    sizeof (dimmp->serial_number));
106f657cd55SCheng Sean Ye 		}
107f657cd55SCheng Sean Ye 		if (cd.smbi_manufacturer && nhm_smbios_manufacturer) {
108f657cd55SCheng Sean Ye 			(void) strncpy(dimmp->manufacturer,
109f657cd55SCheng Sean Ye 			    cd.smbi_manufacturer,
110f657cd55SCheng Sean Ye 			    sizeof (dimmp->manufacturer));
111f657cd55SCheng Sean Ye 		}
112f657cd55SCheng Sean Ye 		if (cd.smbi_part && nhm_smbios_part_number) {
113f657cd55SCheng Sean Ye 			(void) strncpy(dimmp->part_number, cd.smbi_part,
114f657cd55SCheng Sean Ye 			    sizeof (dimmp->part_number));
115f657cd55SCheng Sean Ye 		}
116f657cd55SCheng Sean Ye 		if (cd.smbi_version && nhm_smbios_version) {
117f657cd55SCheng Sean Ye 			(void) strncpy(dimmp->revision, cd.smbi_version,
118f657cd55SCheng Sean Ye 			    sizeof (dimmp->revision));
119f657cd55SCheng Sean Ye 		}
120f657cd55SCheng Sean Ye 	}
121f657cd55SCheng Sean Ye }
122f657cd55SCheng Sean Ye 
123f657cd55SCheng Sean Ye struct dimm_slot {
124f657cd55SCheng Sean Ye 	int controller;
125f657cd55SCheng Sean Ye 	int channel;
126f657cd55SCheng Sean Ye 	int dimm;
127f657cd55SCheng Sean Ye 	int max_dimm;
128f657cd55SCheng Sean Ye };
129f657cd55SCheng Sean Ye 
130f657cd55SCheng Sean Ye static int
dimm_label(smbios_hdl_t * shp,const smbios_struct_t * sp,void * arg)131f657cd55SCheng Sean Ye dimm_label(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg)
132f657cd55SCheng Sean Ye {
133f657cd55SCheng Sean Ye 	nhm_dimm_t *dimmp;
134f657cd55SCheng Sean Ye 	smbios_memdevice_t md;
135f657cd55SCheng Sean Ye 	int slot;
136f657cd55SCheng Sean Ye 	int last_slot;
137f657cd55SCheng Sean Ye 	struct dimm_slot *dsp = (struct dimm_slot *)arg;
138f657cd55SCheng Sean Ye 
139f657cd55SCheng Sean Ye 	slot = (dsp->controller * CHANNELS_PER_MEMORY_CONTROLLER *
140f657cd55SCheng Sean Ye 	    MAX_DIMMS_PER_CHANNEL) + (dsp->channel * MAX_DIMMS_PER_CHANNEL) +
141f657cd55SCheng Sean Ye 	    dsp->dimm;
142f657cd55SCheng Sean Ye 	last_slot = MAX_MEMORY_CONTROLLERS * CHANNELS_PER_MEMORY_CONTROLLER *
143f657cd55SCheng Sean Ye 	    MAX_DIMMS_PER_CHANNEL;
144f657cd55SCheng Sean Ye 	if (slot >= last_slot)
145f657cd55SCheng Sean Ye 		return (0);
146f657cd55SCheng Sean Ye 	dimmp = nhm_dimms[slot];
147f657cd55SCheng Sean Ye 	if (sp->smbstr_type == SMB_TYPE_MEMDEVICE) {
148f657cd55SCheng Sean Ye 		if (smbios_info_memdevice(shp, sp->smbstr_id,
149f657cd55SCheng Sean Ye 		    &md) == 0 && md.smbmd_dloc != NULL) {
150f657cd55SCheng Sean Ye 			if (dimmp == NULL && md.smbmd_size) {
151f657cd55SCheng Sean Ye 				/* skip non existent slot */
152f657cd55SCheng Sean Ye 				dsp->channel++;
153f657cd55SCheng Sean Ye 				if (dsp->dimm == 2)
154f657cd55SCheng Sean Ye 					dsp->max_dimm = 2;
155f657cd55SCheng Sean Ye 				dsp->dimm = 0;
156f657cd55SCheng Sean Ye 				slot = (dsp->controller *
157f657cd55SCheng Sean Ye 				    CHANNELS_PER_MEMORY_CONTROLLER *
158f657cd55SCheng Sean Ye 				    MAX_DIMMS_PER_CHANNEL) +
159f657cd55SCheng Sean Ye 				    (dsp->channel * MAX_DIMMS_PER_CHANNEL);
160f657cd55SCheng Sean Ye 				if (slot >= last_slot)
161f657cd55SCheng Sean Ye 					return (0);
162f657cd55SCheng Sean Ye 
163f657cd55SCheng Sean Ye 				dimmp = nhm_dimms[slot];
164f657cd55SCheng Sean Ye 
165f657cd55SCheng Sean Ye 				if (dimmp == NULL) {
166f657cd55SCheng Sean Ye 					dsp->channel++;
167f657cd55SCheng Sean Ye 					if (dsp->channel ==
168f657cd55SCheng Sean Ye 					    CHANNELS_PER_MEMORY_CONTROLLER) {
169f657cd55SCheng Sean Ye 						dsp->channel = 0;
170f657cd55SCheng Sean Ye 						dsp->controller++;
171f657cd55SCheng Sean Ye 					}
172f657cd55SCheng Sean Ye 					slot = (dsp->controller *
173f657cd55SCheng Sean Ye 					    CHANNELS_PER_MEMORY_CONTROLLER *
174f657cd55SCheng Sean Ye 					    MAX_DIMMS_PER_CHANNEL) +
175f657cd55SCheng Sean Ye 					    (dsp->channel *
176f657cd55SCheng Sean Ye 					    MAX_DIMMS_PER_CHANNEL);
177f657cd55SCheng Sean Ye 					if (slot >= last_slot)
178f657cd55SCheng Sean Ye 						return (0);
179f657cd55SCheng Sean Ye 					dimmp = nhm_dimms[slot];
180f657cd55SCheng Sean Ye 				}
181f657cd55SCheng Sean Ye 			}
182f657cd55SCheng Sean Ye 			if (dimmp) {
183f657cd55SCheng Sean Ye 				if (nhm_smbios_label)
184f657cd55SCheng Sean Ye 					(void) snprintf(dimmp->label,
185f657cd55SCheng Sean Ye 					    sizeof (dimmp->label), "%s",
186f657cd55SCheng Sean Ye 					    md.smbmd_dloc);
187f657cd55SCheng Sean Ye 				dimm_manufacture_data(shp, sp->smbstr_id,
188f657cd55SCheng Sean Ye 				    dimmp);
189f657cd55SCheng Sean Ye 			}
190f657cd55SCheng Sean Ye 		}
191f657cd55SCheng Sean Ye 		dsp->dimm++;
192f657cd55SCheng Sean Ye 		if (dsp->dimm == dsp->max_dimm) {
193f657cd55SCheng Sean Ye 			dsp->dimm = 0;
194f657cd55SCheng Sean Ye 			dsp->channel++;
195f657cd55SCheng Sean Ye 			if (dsp->channel == CHANNELS_PER_MEMORY_CONTROLLER) {
196f657cd55SCheng Sean Ye 				dsp->channel = 0;
197f657cd55SCheng Sean Ye 				dsp->controller++;
198f657cd55SCheng Sean Ye 			}
199f657cd55SCheng Sean Ye 		}
200f657cd55SCheng Sean Ye 	}
201f657cd55SCheng Sean Ye 	return (0);
202f657cd55SCheng Sean Ye }
203f657cd55SCheng Sean Ye 
204f657cd55SCheng Sean Ye void
nhm_smbios()205f657cd55SCheng Sean Ye nhm_smbios()
206f657cd55SCheng Sean Ye {
207f657cd55SCheng Sean Ye 	struct dimm_slot ds;
208f657cd55SCheng Sean Ye 
209f657cd55SCheng Sean Ye 	if (ksmbios != NULL && nhm_no_smbios == 0) {
210f657cd55SCheng Sean Ye 		ds.dimm = 0;
211f657cd55SCheng Sean Ye 		ds.channel = 0;
212f657cd55SCheng Sean Ye 		ds.controller = 0;
213f657cd55SCheng Sean Ye 		ds.max_dimm = MAX_DIMMS_PER_CHANNEL;
214f657cd55SCheng Sean Ye 		(void) smbios_iter(ksmbios, dimm_label, &ds);
215f657cd55SCheng Sean Ye 		check_serial_number();
216f657cd55SCheng Sean Ye 	}
217f657cd55SCheng Sean Ye }
218f657cd55SCheng Sean Ye 
219f657cd55SCheng Sean Ye static void
dimm_prop(nhm_dimm_t * dimmp,uint32_t dod)220f657cd55SCheng Sean Ye dimm_prop(nhm_dimm_t *dimmp, uint32_t dod)
221f657cd55SCheng Sean Ye {
222f657cd55SCheng Sean Ye 	dimmp->dimm_size = DIMMSIZE(dod);
223f657cd55SCheng Sean Ye 	dimmp->nranks = NUMRANK(dod);
224f657cd55SCheng Sean Ye 	dimmp->nbanks = NUMBANK(dod);
225f657cd55SCheng Sean Ye 	dimmp->ncolumn = NUMCOL(dod);
226f657cd55SCheng Sean Ye 	dimmp->nrow = NUMROW(dod);
227f657cd55SCheng Sean Ye 	dimmp->width = DIMMWIDTH;
228f657cd55SCheng Sean Ye }
229f657cd55SCheng Sean Ye 
230f657cd55SCheng Sean Ye void
nhm_scrubber_enable()231f657cd55SCheng Sean Ye nhm_scrubber_enable()
232f657cd55SCheng Sean Ye {
233f657cd55SCheng Sean Ye 	uint32_t mc_ssrcontrol;
234f657cd55SCheng Sean Ye 	uint32_t mc_dimm_clk_ratio_status;
235f657cd55SCheng Sean Ye 	uint64_t cycle_time;
236f657cd55SCheng Sean Ye 	uint32_t interval;
237*35366b93SAdrian Frost 	uint32_t id;
238f657cd55SCheng Sean Ye 	int i;
239f657cd55SCheng Sean Ye 	int hw_scrub = 0;
240f657cd55SCheng Sean Ye 
241f657cd55SCheng Sean Ye 	if (ecc_enabled && (nhm_patrol_scrub || nhm_demand_scrub)) {
242f657cd55SCheng Sean Ye 		for (i = 0; i < MAX_MEMORY_CONTROLLERS; i++) {
243*35366b93SAdrian Frost 			id = MC_CPU_RAS_RD(i);
244*35366b93SAdrian Frost 			if ((id != NHM_CPU_RAS && id != NHM_JF_CPU_RAS &&
245*35366b93SAdrian Frost 			    id != NHM_WM_CPU_RAS) || nhm_memory_on_ctl[i] == 0)
246f657cd55SCheng Sean Ye 				continue;
247f657cd55SCheng Sean Ye 			mc_ssrcontrol = MC_SSR_CONTROL_RD(i);
248f657cd55SCheng Sean Ye 			if (nhm_demand_scrub &&
249f657cd55SCheng Sean Ye 			    (mc_ssrcontrol & DEMAND_SCRUB_ENABLE) == 0) {
250f657cd55SCheng Sean Ye 				mc_ssrcontrol |= DEMAND_SCRUB_ENABLE;
251f657cd55SCheng Sean Ye 				MC_SSR_CONTROL_WR(i, mc_ssrcontrol);
252f657cd55SCheng Sean Ye 			}
253f657cd55SCheng Sean Ye 			if (nhm_patrol_scrub == 0)
254f657cd55SCheng Sean Ye 				continue;
255f657cd55SCheng Sean Ye 			if (SSR_MODE(mc_ssrcontrol) == SSR_IDLE) {
256f657cd55SCheng Sean Ye 				mc_dimm_clk_ratio_status =
257f657cd55SCheng Sean Ye 				    MC_DIMM_CLK_RATIO_STATUS(i);
258f657cd55SCheng Sean Ye 				cycle_time =
259f657cd55SCheng Sean Ye 				    MAX_DIMM_CLK_RATIO(mc_dimm_clk_ratio_status)
260f657cd55SCheng Sean Ye 				    * 80000000;
261f657cd55SCheng Sean Ye 				interval = (uint32_t)((36400ULL * cycle_time) /
262f657cd55SCheng Sean Ye 				    (nhm_memory_on_ctl[i]/64));
263f657cd55SCheng Sean Ye 				MC_SCRUB_CONTROL_WR(i, STARTSCRUB | interval);
264f657cd55SCheng Sean Ye 				MC_SSR_CONTROL_WR(i, mc_ssrcontrol | SSR_SCRUB);
265f657cd55SCheng Sean Ye 			} else if (SSR_MODE(mc_ssrcontrol) == SSR_SPARE) {
266f657cd55SCheng Sean Ye 				hw_scrub = 0;
267f657cd55SCheng Sean Ye 				break;
268f657cd55SCheng Sean Ye 			}
269f657cd55SCheng Sean Ye 			hw_scrub = 1;
270f657cd55SCheng Sean Ye 		}
271f657cd55SCheng Sean Ye 		if (hw_scrub)
272f657cd55SCheng Sean Ye 			cmi_mc_sw_memscrub_disable();
273f657cd55SCheng Sean Ye 	}
274f657cd55SCheng Sean Ye }
275f657cd55SCheng Sean Ye 
276f657cd55SCheng Sean Ye void
init_dimms()277f657cd55SCheng Sean Ye init_dimms()
278f657cd55SCheng Sean Ye {
279f657cd55SCheng Sean Ye 	int i, j, k;
280f657cd55SCheng Sean Ye 	nhm_dimm_t **dimmpp;
281f657cd55SCheng Sean Ye 	nhm_dimm_t *dimmp;
282f657cd55SCheng Sean Ye 	uint32_t dod;
283ee9ef9e5SAdrian Frost 	uint32_t did;
284f657cd55SCheng Sean Ye 
285f657cd55SCheng Sean Ye 	nhm_dimms = (nhm_dimm_t **)kmem_zalloc(sizeof (nhm_dimm_t *) *
286f657cd55SCheng Sean Ye 	    MAX_MEMORY_CONTROLLERS * CHANNELS_PER_MEMORY_CONTROLLER *
287f657cd55SCheng Sean Ye 	    MAX_DIMMS_PER_CHANNEL, KM_SLEEP);
288f657cd55SCheng Sean Ye 	dimmpp = nhm_dimms;
289f657cd55SCheng Sean Ye 	for (i = 0; i < MAX_MEMORY_CONTROLLERS; i++) {
290ee9ef9e5SAdrian Frost 		did = CPU_ID_RD(i);
291*35366b93SAdrian Frost 		if (did != NHM_EP_CPU && did != NHM_WS_CPU &&
292*35366b93SAdrian Frost 		    did != NHM_JF_CPU && did != NHM_WM_CPU) {
293f657cd55SCheng Sean Ye 			dimmpp += CHANNELS_PER_MEMORY_CONTROLLER *
294f657cd55SCheng Sean Ye 			    MAX_DIMMS_PER_CHANNEL;
295f657cd55SCheng Sean Ye 			continue;
296f657cd55SCheng Sean Ye 		}
297f657cd55SCheng Sean Ye 		for (j = 0; j < CHANNELS_PER_MEMORY_CONTROLLER; j++) {
298f657cd55SCheng Sean Ye 			for (k = 0; k < MAX_DIMMS_PER_CHANNEL; k++) {
299f657cd55SCheng Sean Ye 				dod = MC_DOD_RD(i, j, k);
300f657cd55SCheng Sean Ye 				if (DIMMPRESENT(dod)) {
301f657cd55SCheng Sean Ye 					dimmp = (nhm_dimm_t *)
302f657cd55SCheng Sean Ye 					    kmem_zalloc(sizeof (nhm_dimm_t),
303f657cd55SCheng Sean Ye 					    KM_SLEEP);
304f657cd55SCheng Sean Ye 					dimm_prop(dimmp, dod);
305f657cd55SCheng Sean Ye 					(void) snprintf(dimmp->label,
306f657cd55SCheng Sean Ye 					    sizeof (dimmp->label),
307f657cd55SCheng Sean Ye 					    "Socket %d channel %d dimm %d",
308f657cd55SCheng Sean Ye 					    i, j, k);
309f657cd55SCheng Sean Ye 					*dimmpp = dimmp;
310f657cd55SCheng Sean Ye 					nhm_memory_on_ctl[i] +=
311f657cd55SCheng Sean Ye 					    dimmp->dimm_size;
312f657cd55SCheng Sean Ye 				}
313f657cd55SCheng Sean Ye 				dimmpp++;
314f657cd55SCheng Sean Ye 			}
315f657cd55SCheng Sean Ye 		}
316f657cd55SCheng Sean Ye 	}
317f657cd55SCheng Sean Ye }
318f657cd55SCheng Sean Ye 
319f657cd55SCheng Sean Ye 
320f657cd55SCheng Sean Ye int
nhm_init(void)321f657cd55SCheng Sean Ye nhm_init(void)
322f657cd55SCheng Sean Ye {
323f657cd55SCheng Sean Ye 	int slot;
324f657cd55SCheng Sean Ye 
325f657cd55SCheng Sean Ye 	/* return ENOTSUP if there is no PCI config space support. */
326f657cd55SCheng Sean Ye 	if (pci_getl_func == NULL)
327f657cd55SCheng Sean Ye 		return (ENOTSUP);
328f657cd55SCheng Sean Ye 	for (slot = 0; slot < MAX_CPU_NODES; slot++) {
329f657cd55SCheng Sean Ye 		nhm_chipset = CPU_ID_RD(slot);
330*35366b93SAdrian Frost 		if (nhm_chipset == NHM_EP_CPU || nhm_chipset == NHM_WS_CPU ||
331*35366b93SAdrian Frost 		    nhm_chipset == NHM_JF_CPU || nhm_chipset == NHM_WM_CPU)
332f657cd55SCheng Sean Ye 			break;
333f657cd55SCheng Sean Ye 	}
334*35366b93SAdrian Frost 	if (slot == MAX_CPU_NODES) {
335f657cd55SCheng Sean Ye 		return (ENOTSUP);
336f657cd55SCheng Sean Ye 	}
337f657cd55SCheng Sean Ye 	mem_reg_init();
338f657cd55SCheng Sean Ye 	return (0);
339f657cd55SCheng Sean Ye }
340f657cd55SCheng Sean Ye 
341f657cd55SCheng Sean Ye int
nhm_reinit(void)342f657cd55SCheng Sean Ye nhm_reinit(void)
343f657cd55SCheng Sean Ye {
344f657cd55SCheng Sean Ye 	mem_reg_init();
345f657cd55SCheng Sean Ye 	return (0);
346f657cd55SCheng Sean Ye }
347f657cd55SCheng Sean Ye 
348f657cd55SCheng Sean Ye int
nhm_dev_init()349f657cd55SCheng Sean Ye nhm_dev_init()
350f657cd55SCheng Sean Ye {
351f657cd55SCheng Sean Ye 	return (0);
352f657cd55SCheng Sean Ye }
353f657cd55SCheng Sean Ye 
354f657cd55SCheng Sean Ye void
nhm_dev_reinit()355f657cd55SCheng Sean Ye nhm_dev_reinit()
356f657cd55SCheng Sean Ye {
357f657cd55SCheng Sean Ye }
358f657cd55SCheng Sean Ye 
359f657cd55SCheng Sean Ye void
nhm_unload()360f657cd55SCheng Sean Ye nhm_unload()
361f657cd55SCheng Sean Ye {
362f657cd55SCheng Sean Ye }
363