xref: /illumos-gate/usr/src/common/mc/imc/imc_dump.c (revision eb00b1c8)
1*eb00b1c8SRobert Mustacchi /*
2*eb00b1c8SRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*eb00b1c8SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*eb00b1c8SRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*eb00b1c8SRobert Mustacchi  * 1.0 of the CDDL.
6*eb00b1c8SRobert Mustacchi  *
7*eb00b1c8SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*eb00b1c8SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*eb00b1c8SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*eb00b1c8SRobert Mustacchi  */
11*eb00b1c8SRobert Mustacchi 
12*eb00b1c8SRobert Mustacchi /*
13*eb00b1c8SRobert Mustacchi  * Copyright 2019 Joyent, Inc.
14*eb00b1c8SRobert Mustacchi  */
15*eb00b1c8SRobert Mustacchi 
16*eb00b1c8SRobert Mustacchi /*
17*eb00b1c8SRobert Mustacchi  * This implements logic to allow us to dump IMC data for decoding purposes,
18*eb00b1c8SRobert Mustacchi  * such that we can later encode it elsewhere. In general, dumping is done by
19*eb00b1c8SRobert Mustacchi  * the kernel and reconstituting this data is done by user land.
20*eb00b1c8SRobert Mustacchi  */
21*eb00b1c8SRobert Mustacchi 
22*eb00b1c8SRobert Mustacchi #include "imc.h"
23*eb00b1c8SRobert Mustacchi 
24*eb00b1c8SRobert Mustacchi #ifndef _KERNEL
25*eb00b1c8SRobert Mustacchi #include <stdint.h>
26*eb00b1c8SRobert Mustacchi #include <strings.h>
27*eb00b1c8SRobert Mustacchi #endif	/* !_KERNEL */
28*eb00b1c8SRobert Mustacchi 
29*eb00b1c8SRobert Mustacchi 
30*eb00b1c8SRobert Mustacchi static nvlist_t *
imc_dump_sad(imc_sad_t * sad)31*eb00b1c8SRobert Mustacchi imc_dump_sad(imc_sad_t *sad)
32*eb00b1c8SRobert Mustacchi {
33*eb00b1c8SRobert Mustacchi 	uint_t i;
34*eb00b1c8SRobert Mustacchi 	nvlist_t *nvl;
35*eb00b1c8SRobert Mustacchi 	nvlist_t *rules[IMC_MAX_SAD_RULES];
36*eb00b1c8SRobert Mustacchi 	nvlist_t *routes[IMC_MAX_SAD_MCROUTES];
37*eb00b1c8SRobert Mustacchi 
38*eb00b1c8SRobert Mustacchi 	nvl = fnvlist_alloc();
39*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "isad_flags", sad->isad_flags);
40*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "isad_valid", sad->isad_valid);
41*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint64(nvl, "isad_tolm", sad->isad_tolm);
42*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint64(nvl, "isad_tohm", sad->isad_tohm);
43*eb00b1c8SRobert Mustacchi 
44*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sad->isad_nrules; i++) {
45*eb00b1c8SRobert Mustacchi 		nvlist_t *n = fnvlist_alloc();
46*eb00b1c8SRobert Mustacchi 		imc_sad_rule_t *r = &sad->isad_rules[i];
47*eb00b1c8SRobert Mustacchi 
48*eb00b1c8SRobert Mustacchi 		fnvlist_add_boolean_value(n, "isr_enable", r->isr_enable);
49*eb00b1c8SRobert Mustacchi 		fnvlist_add_boolean_value(n, "isr_a7mode", r->isr_a7mode);
50*eb00b1c8SRobert Mustacchi 		fnvlist_add_boolean_value(n, "isr_need_mod3", r->isr_need_mod3);
51*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint64(n, "isr_limit", r->isr_limit);
52*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint32(n, "isr_type", r->isr_type);
53*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint32(n, "isr_imode", r->isr_imode);
54*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint32(n, "isr_mod_mode", r->isr_mod_mode);
55*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint32(n, "isr_mod_type", r->isr_mod_type);
56*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8_array(n, "isr_targets", r->isr_targets,
57*eb00b1c8SRobert Mustacchi 		    r->isr_ntargets);
58*eb00b1c8SRobert Mustacchi 
59*eb00b1c8SRobert Mustacchi 		rules[i] = n;
60*eb00b1c8SRobert Mustacchi 	}
61*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "isad_rules", rules, sad->isad_nrules);
62*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sad->isad_nrules; i++) {
63*eb00b1c8SRobert Mustacchi 		nvlist_free(rules[i]);
64*eb00b1c8SRobert Mustacchi 	}
65*eb00b1c8SRobert Mustacchi 
66*eb00b1c8SRobert Mustacchi 	if (sad->isad_mcroute.ismc_nroutes == 0) {
67*eb00b1c8SRobert Mustacchi 		return (nvl);
68*eb00b1c8SRobert Mustacchi 	}
69*eb00b1c8SRobert Mustacchi 
70*eb00b1c8SRobert Mustacchi 	for (i = 0; i <  sad->isad_mcroute.ismc_nroutes; i++) {
71*eb00b1c8SRobert Mustacchi 		nvlist_t *r = fnvlist_alloc();
72*eb00b1c8SRobert Mustacchi 		imc_sad_mcroute_entry_t *e =
73*eb00b1c8SRobert Mustacchi 		    &sad->isad_mcroute.ismc_mcroutes[i];
74*eb00b1c8SRobert Mustacchi 
75*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(r, "ismce_imc", e->ismce_imc);
76*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(r, "ismce_pchannel", e->ismce_pchannel);
77*eb00b1c8SRobert Mustacchi 		routes[i] = r;
78*eb00b1c8SRobert Mustacchi 	}
79*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "isad_mcroute", routes, i);
80*eb00b1c8SRobert Mustacchi 	for (i = 0; i <  sad->isad_mcroute.ismc_nroutes; i++) {
81*eb00b1c8SRobert Mustacchi 		nvlist_free(routes[i]);
82*eb00b1c8SRobert Mustacchi 	}
83*eb00b1c8SRobert Mustacchi 
84*eb00b1c8SRobert Mustacchi 	return (nvl);
85*eb00b1c8SRobert Mustacchi }
86*eb00b1c8SRobert Mustacchi 
87*eb00b1c8SRobert Mustacchi static nvlist_t *
imc_dump_tad(imc_tad_t * tad)88*eb00b1c8SRobert Mustacchi imc_dump_tad(imc_tad_t *tad)
89*eb00b1c8SRobert Mustacchi {
90*eb00b1c8SRobert Mustacchi 	uint_t i;
91*eb00b1c8SRobert Mustacchi 	nvlist_t *nvl;
92*eb00b1c8SRobert Mustacchi 	nvlist_t *rules[IMC_MAX_TAD_RULES];
93*eb00b1c8SRobert Mustacchi 
94*eb00b1c8SRobert Mustacchi 	nvl = fnvlist_alloc();
95*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "itad_valid", tad->itad_valid);
96*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "itad_flags", tad->itad_flags);
97*eb00b1c8SRobert Mustacchi 	for (i = 0; i < tad->itad_nrules; i++) {
98*eb00b1c8SRobert Mustacchi 		nvlist_t *t = fnvlist_alloc();
99*eb00b1c8SRobert Mustacchi 		imc_tad_rule_t *r = &tad->itad_rules[i];
100*eb00b1c8SRobert Mustacchi 
101*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint64(t, "itr_base", r->itr_base);
102*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint64(t, "itr_limit", r->itr_limit);
103*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(t, "itr_sock_way", r->itr_sock_way);
104*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(t, "itr_chan_way", r->itr_chan_way);
105*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint32(t, "itr_sock_gran", r->itr_sock_gran);
106*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint32(t, "itr_chan_gran", r->itr_chan_gran);
107*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8_array(t, "itr_targets", r->itr_targets,
108*eb00b1c8SRobert Mustacchi 		    r->itr_ntargets);
109*eb00b1c8SRobert Mustacchi 
110*eb00b1c8SRobert Mustacchi 		rules[i] = t;
111*eb00b1c8SRobert Mustacchi 	}
112*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "itad_rules", rules, tad->itad_nrules);
113*eb00b1c8SRobert Mustacchi 	for (i = 0; i < tad->itad_nrules; i++) {
114*eb00b1c8SRobert Mustacchi 		nvlist_free(rules[i]);
115*eb00b1c8SRobert Mustacchi 	}
116*eb00b1c8SRobert Mustacchi 
117*eb00b1c8SRobert Mustacchi 	return (nvl);
118*eb00b1c8SRobert Mustacchi }
119*eb00b1c8SRobert Mustacchi 
120*eb00b1c8SRobert Mustacchi static nvlist_t *
imc_dump_channel(imc_channel_t * chan)121*eb00b1c8SRobert Mustacchi imc_dump_channel(imc_channel_t *chan)
122*eb00b1c8SRobert Mustacchi {
123*eb00b1c8SRobert Mustacchi 	uint_t i;
124*eb00b1c8SRobert Mustacchi 	nvlist_t *nvl;
125*eb00b1c8SRobert Mustacchi 	nvlist_t *dimms[IMC_MAX_DIMMPERCHAN];
126*eb00b1c8SRobert Mustacchi 	nvlist_t *ranks[IMC_MAX_RANK_WAYS];
127*eb00b1c8SRobert Mustacchi 
128*eb00b1c8SRobert Mustacchi 	nvl = fnvlist_alloc();
129*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "ich_valid", chan->ich_valid);
130*eb00b1c8SRobert Mustacchi 	for (i = 0; i < chan->ich_ndimms; i++) {
131*eb00b1c8SRobert Mustacchi 		nvlist_t *d = fnvlist_alloc();
132*eb00b1c8SRobert Mustacchi 		imc_dimm_t *dimm = &chan->ich_dimms[i];
133*eb00b1c8SRobert Mustacchi 
134*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint32(d, "idimm_valid", dimm->idimm_valid);
135*eb00b1c8SRobert Mustacchi 		fnvlist_add_boolean_value(d, "idimm_present",
136*eb00b1c8SRobert Mustacchi 		    dimm->idimm_present);
137*eb00b1c8SRobert Mustacchi 		if (!dimm->idimm_present)
138*eb00b1c8SRobert Mustacchi 			goto add;
139*eb00b1c8SRobert Mustacchi 
140*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(d, "idimm_nbanks", dimm->idimm_nbanks);
141*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(d, "idimm_nranks", dimm->idimm_nranks);
142*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(d, "idimm_width", dimm->idimm_width);
143*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(d, "idimm_density", dimm->idimm_density);
144*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(d, "idimm_nrows", dimm->idimm_nrows);
145*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(d, "idimm_ncolumns", dimm->idimm_ncolumns);
146*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint64(d, "idimm_size", dimm->idimm_size);
147*eb00b1c8SRobert Mustacchi add:
148*eb00b1c8SRobert Mustacchi 		dimms[i] = d;
149*eb00b1c8SRobert Mustacchi 	}
150*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "ich_dimms", dimms, i);
151*eb00b1c8SRobert Mustacchi 	for (i = 0; i < chan->ich_ndimms; i++) {
152*eb00b1c8SRobert Mustacchi 		nvlist_free(dimms[i]);
153*eb00b1c8SRobert Mustacchi 	}
154*eb00b1c8SRobert Mustacchi 
155*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint64_array(nvl, "ich_tad_offsets", chan->ich_tad_offsets,
156*eb00b1c8SRobert Mustacchi 	    chan->ich_ntad_offsets);
157*eb00b1c8SRobert Mustacchi 
158*eb00b1c8SRobert Mustacchi 	for (i = 0; i < chan->ich_nrankileaves; i++) {
159*eb00b1c8SRobert Mustacchi 		uint_t j;
160*eb00b1c8SRobert Mustacchi 		nvlist_t *r = fnvlist_alloc();
161*eb00b1c8SRobert Mustacchi 		nvlist_t *ileaves[IMC_MAX_RANK_INTERLEAVES];
162*eb00b1c8SRobert Mustacchi 		imc_rank_ileave_t *rank = &chan->ich_rankileaves[i];
163*eb00b1c8SRobert Mustacchi 
164*eb00b1c8SRobert Mustacchi 		fnvlist_add_boolean_value(r, "irle_enabled",
165*eb00b1c8SRobert Mustacchi 		    rank->irle_enabled);
166*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(r, "irle_nways", rank->irle_nways);
167*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint8(r, "irle_nwaysbits", rank->irle_nwaysbits);
168*eb00b1c8SRobert Mustacchi 		fnvlist_add_uint64(r, "irle_limit", rank->irle_limit);
169*eb00b1c8SRobert Mustacchi 
170*eb00b1c8SRobert Mustacchi 		for (j = 0; j < rank->irle_nentries; j++) {
171*eb00b1c8SRobert Mustacchi 			nvlist_t *e = fnvlist_alloc();
172*eb00b1c8SRobert Mustacchi 
173*eb00b1c8SRobert Mustacchi 			fnvlist_add_uint8(e, "irle_target",
174*eb00b1c8SRobert Mustacchi 			    rank->irle_entries[j].irle_target);
175*eb00b1c8SRobert Mustacchi 			fnvlist_add_uint64(e, "irle_offset",
176*eb00b1c8SRobert Mustacchi 			    rank->irle_entries[j].irle_offset);
177*eb00b1c8SRobert Mustacchi 			ileaves[j] = e;
178*eb00b1c8SRobert Mustacchi 		}
179*eb00b1c8SRobert Mustacchi 		fnvlist_add_nvlist_array(r, "irle_entries", ileaves, j);
180*eb00b1c8SRobert Mustacchi 		for (j = 0; j < rank->irle_nentries; j++) {
181*eb00b1c8SRobert Mustacchi 			nvlist_free(ileaves[j]);
182*eb00b1c8SRobert Mustacchi 		}
183*eb00b1c8SRobert Mustacchi 
184*eb00b1c8SRobert Mustacchi 		ranks[i] = r;
185*eb00b1c8SRobert Mustacchi 	}
186*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "ich_rankileaves", ranks, i);
187*eb00b1c8SRobert Mustacchi 	for (i = 0; i < chan->ich_nrankileaves; i++) {
188*eb00b1c8SRobert Mustacchi 		nvlist_free(ranks[i]);
189*eb00b1c8SRobert Mustacchi 	}
190*eb00b1c8SRobert Mustacchi 
191*eb00b1c8SRobert Mustacchi 	return (nvl);
192*eb00b1c8SRobert Mustacchi }
193*eb00b1c8SRobert Mustacchi 
194*eb00b1c8SRobert Mustacchi static nvlist_t *
imc_dump_mc(imc_mc_t * mc)195*eb00b1c8SRobert Mustacchi imc_dump_mc(imc_mc_t *mc)
196*eb00b1c8SRobert Mustacchi {
197*eb00b1c8SRobert Mustacchi 	uint_t i;
198*eb00b1c8SRobert Mustacchi 	nvlist_t *nvl;
199*eb00b1c8SRobert Mustacchi 	nvlist_t *channels[IMC_MAX_CHANPERMC];
200*eb00b1c8SRobert Mustacchi 
201*eb00b1c8SRobert Mustacchi 	nvl = fnvlist_alloc();
202*eb00b1c8SRobert Mustacchi 	fnvlist_add_boolean_value(nvl, "icn_ecc", mc->icn_ecc);
203*eb00b1c8SRobert Mustacchi 	fnvlist_add_boolean_value(nvl, "icn_lockstep", mc->icn_lockstep);
204*eb00b1c8SRobert Mustacchi 	fnvlist_add_boolean_value(nvl, "icn_closed", mc->icn_closed);
205*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "icn_dimm_type", mc->icn_dimm_type);
206*eb00b1c8SRobert Mustacchi 
207*eb00b1c8SRobert Mustacchi 	for (i = 0; i < mc->icn_nchannels; i++) {
208*eb00b1c8SRobert Mustacchi 		channels[i] = imc_dump_channel(&mc->icn_channels[i]);
209*eb00b1c8SRobert Mustacchi 	}
210*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "icn_channels", channels, i);
211*eb00b1c8SRobert Mustacchi 	for (i = 0; i < mc->icn_nchannels; i++) {
212*eb00b1c8SRobert Mustacchi 		nvlist_free(channels[i]);
213*eb00b1c8SRobert Mustacchi 	}
214*eb00b1c8SRobert Mustacchi 
215*eb00b1c8SRobert Mustacchi 	return (nvl);
216*eb00b1c8SRobert Mustacchi }
217*eb00b1c8SRobert Mustacchi 
218*eb00b1c8SRobert Mustacchi static nvlist_t *
imc_dump_socket(imc_socket_t * sock)219*eb00b1c8SRobert Mustacchi imc_dump_socket(imc_socket_t *sock)
220*eb00b1c8SRobert Mustacchi {
221*eb00b1c8SRobert Mustacchi 	uint_t i;
222*eb00b1c8SRobert Mustacchi 	nvlist_t *nvl, *sad;
223*eb00b1c8SRobert Mustacchi 	nvlist_t *tad[IMC_MAX_TAD];
224*eb00b1c8SRobert Mustacchi 	nvlist_t *mc[IMC_MAX_IMCPERSOCK];
225*eb00b1c8SRobert Mustacchi 
226*eb00b1c8SRobert Mustacchi 	nvl = fnvlist_alloc();
227*eb00b1c8SRobert Mustacchi 
228*eb00b1c8SRobert Mustacchi 	sad = imc_dump_sad(&sock->isock_sad);
229*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist(nvl, "isock_sad", sad);
230*eb00b1c8SRobert Mustacchi 	nvlist_free(sad);
231*eb00b1c8SRobert Mustacchi 
232*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sock->isock_ntad; i++) {
233*eb00b1c8SRobert Mustacchi 		tad[i] = imc_dump_tad(&sock->isock_tad[i]);
234*eb00b1c8SRobert Mustacchi 	}
235*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "isock_tad", tad, i);
236*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sock->isock_ntad; i++) {
237*eb00b1c8SRobert Mustacchi 		fnvlist_free(tad[i]);
238*eb00b1c8SRobert Mustacchi 	}
239*eb00b1c8SRobert Mustacchi 
240*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "isock_nodeid", sock->isock_nodeid);
241*eb00b1c8SRobert Mustacchi 
242*eb00b1c8SRobert Mustacchi 	for (i = 0; i  < sock->isock_nimc; i++) {
243*eb00b1c8SRobert Mustacchi 		mc[i] = imc_dump_mc(&sock->isock_imcs[i]);
244*eb00b1c8SRobert Mustacchi 	}
245*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(nvl, "isock_imcs", mc, i);
246*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sock->isock_nimc; i++) {
247*eb00b1c8SRobert Mustacchi 		fnvlist_free(mc[i]);
248*eb00b1c8SRobert Mustacchi 	}
249*eb00b1c8SRobert Mustacchi 	return (nvl);
250*eb00b1c8SRobert Mustacchi }
251*eb00b1c8SRobert Mustacchi 
252*eb00b1c8SRobert Mustacchi nvlist_t *
imc_dump_decoder(imc_t * imc)253*eb00b1c8SRobert Mustacchi imc_dump_decoder(imc_t *imc)
254*eb00b1c8SRobert Mustacchi {
255*eb00b1c8SRobert Mustacchi 	uint_t i;
256*eb00b1c8SRobert Mustacchi 	nvlist_t *nvl, *invl;
257*eb00b1c8SRobert Mustacchi 	nvlist_t *sockets[IMC_MAX_SOCKETS];
258*eb00b1c8SRobert Mustacchi 
259*eb00b1c8SRobert Mustacchi 	nvl = fnvlist_alloc();
260*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(nvl, "mc_dump_version", 0);
261*eb00b1c8SRobert Mustacchi 	fnvlist_add_string(nvl, "mc_dump_driver", "imc");
262*eb00b1c8SRobert Mustacchi 
263*eb00b1c8SRobert Mustacchi 	invl = fnvlist_alloc();
264*eb00b1c8SRobert Mustacchi 	fnvlist_add_uint32(invl, "imc_gen", imc->imc_gen);
265*eb00b1c8SRobert Mustacchi 
266*eb00b1c8SRobert Mustacchi 	for (i = 0; i < imc->imc_nsockets; i++) {
267*eb00b1c8SRobert Mustacchi 		sockets[i] = imc_dump_socket(&imc->imc_sockets[i]);
268*eb00b1c8SRobert Mustacchi 	}
269*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist_array(invl, "imc_sockets", sockets, i);
270*eb00b1c8SRobert Mustacchi 	fnvlist_add_nvlist(nvl, "imc", invl);
271*eb00b1c8SRobert Mustacchi 
272*eb00b1c8SRobert Mustacchi 	for (i = 0; i < imc->imc_nsockets; i++) {
273*eb00b1c8SRobert Mustacchi 		nvlist_free(sockets[i]);
274*eb00b1c8SRobert Mustacchi 	}
275*eb00b1c8SRobert Mustacchi 	nvlist_free(invl);
276*eb00b1c8SRobert Mustacchi 
277*eb00b1c8SRobert Mustacchi 	return (nvl);
278*eb00b1c8SRobert Mustacchi }
279*eb00b1c8SRobert Mustacchi 
280*eb00b1c8SRobert Mustacchi static boolean_t
imc_restore_sad(nvlist_t * nvl,imc_sad_t * sad)281*eb00b1c8SRobert Mustacchi imc_restore_sad(nvlist_t *nvl, imc_sad_t *sad)
282*eb00b1c8SRobert Mustacchi {
283*eb00b1c8SRobert Mustacchi 	nvlist_t **rules, **routes;
284*eb00b1c8SRobert Mustacchi 	uint_t i, nroutes;
285*eb00b1c8SRobert Mustacchi 
286*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_uint32(nvl, "isad_flags", &sad->isad_flags) != 0 ||
287*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_uint32(nvl, "isad_valid", &sad->isad_valid) != 0 ||
288*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_uint64(nvl, "isad_tolm", &sad->isad_tolm) != 0 ||
289*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_uint64(nvl, "isad_tohm", &sad->isad_tohm) != 0 ||
290*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(nvl, "isad_rules",
291*eb00b1c8SRobert Mustacchi 	    &rules, &sad->isad_nrules) != 0) {
292*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
293*eb00b1c8SRobert Mustacchi 	}
294*eb00b1c8SRobert Mustacchi 
295*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sad->isad_nrules; i++) {
296*eb00b1c8SRobert Mustacchi 		imc_sad_rule_t *r = &sad->isad_rules[i];
297*eb00b1c8SRobert Mustacchi 		uint8_t *targs;
298*eb00b1c8SRobert Mustacchi 
299*eb00b1c8SRobert Mustacchi 		if (nvlist_lookup_boolean_value(rules[i], "isr_enable",
300*eb00b1c8SRobert Mustacchi 		    &r->isr_enable) != 0 ||
301*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_boolean_value(rules[i], "isr_a7mode",
302*eb00b1c8SRobert Mustacchi 		    &r->isr_a7mode) != 0 ||
303*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_boolean_value(rules[i], "isr_need_mod3",
304*eb00b1c8SRobert Mustacchi 		    &r->isr_need_mod3) != 0 ||
305*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint64(rules[i], "isr_limit",
306*eb00b1c8SRobert Mustacchi 		    &r->isr_limit) != 0 ||
307*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint32(rules[i], "isr_type",
308*eb00b1c8SRobert Mustacchi 		    &r->isr_type) != 0 ||
309*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint32(rules[i], "isr_imode",
310*eb00b1c8SRobert Mustacchi 		    &r->isr_imode) != 0 ||
311*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint32(rules[i], "isr_mod_mode",
312*eb00b1c8SRobert Mustacchi 		    &r->isr_mod_mode) != 0 ||
313*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint32(rules[i], "isr_mod_type",
314*eb00b1c8SRobert Mustacchi 		    &r->isr_mod_type) != 0 ||
315*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8_array(rules[i], "isr_targets", &targs,
316*eb00b1c8SRobert Mustacchi 		    &r->isr_ntargets) != 0 ||
317*eb00b1c8SRobert Mustacchi 		    r->isr_ntargets > IMC_MAX_SAD_RULES) {
318*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
319*eb00b1c8SRobert Mustacchi 		}
320*eb00b1c8SRobert Mustacchi 
321*eb00b1c8SRobert Mustacchi 		bcopy(targs, r->isr_targets, r->isr_ntargets *
322*eb00b1c8SRobert Mustacchi 		    sizeof (uint8_t));
323*eb00b1c8SRobert Mustacchi 	}
324*eb00b1c8SRobert Mustacchi 
325*eb00b1c8SRobert Mustacchi 	/*
326*eb00b1c8SRobert Mustacchi 	 * The mcroutes entry right now is only included conditionally.
327*eb00b1c8SRobert Mustacchi 	 */
328*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_nvlist_array(nvl, "isad_mcroute", &routes,
329*eb00b1c8SRobert Mustacchi 	    &nroutes) == 0) {
330*eb00b1c8SRobert Mustacchi 		if (nroutes > IMC_MAX_SAD_MCROUTES)
331*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
332*eb00b1c8SRobert Mustacchi 		sad->isad_mcroute.ismc_nroutes = nroutes;
333*eb00b1c8SRobert Mustacchi 		for (i = 0; i < nroutes; i++) {
334*eb00b1c8SRobert Mustacchi 			imc_sad_mcroute_entry_t *r =
335*eb00b1c8SRobert Mustacchi 			    &sad->isad_mcroute.ismc_mcroutes[i];
336*eb00b1c8SRobert Mustacchi 			if (nvlist_lookup_uint8(routes[i], "ismce_imc",
337*eb00b1c8SRobert Mustacchi 			    &r->ismce_imc) != 0 ||
338*eb00b1c8SRobert Mustacchi 			    nvlist_lookup_uint8(routes[i], "ismce_pchannel",
339*eb00b1c8SRobert Mustacchi 			    &r->ismce_pchannel) != 0) {
340*eb00b1c8SRobert Mustacchi 				return (B_FALSE);
341*eb00b1c8SRobert Mustacchi 			}
342*eb00b1c8SRobert Mustacchi 		}
343*eb00b1c8SRobert Mustacchi 	}
344*eb00b1c8SRobert Mustacchi 
345*eb00b1c8SRobert Mustacchi 	return (B_TRUE);
346*eb00b1c8SRobert Mustacchi }
347*eb00b1c8SRobert Mustacchi 
348*eb00b1c8SRobert Mustacchi static boolean_t
imc_restore_tad(nvlist_t * nvl,imc_tad_t * tad)349*eb00b1c8SRobert Mustacchi imc_restore_tad(nvlist_t *nvl, imc_tad_t *tad)
350*eb00b1c8SRobert Mustacchi {
351*eb00b1c8SRobert Mustacchi 	nvlist_t **rules;
352*eb00b1c8SRobert Mustacchi 
353*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_uint32(nvl, "itad_valid", &tad->itad_valid) != 0 ||
354*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_uint32(nvl, "itad_flags", &tad->itad_flags) != 0 ||
355*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(nvl, "itad_rules", &rules,
356*eb00b1c8SRobert Mustacchi 	    &tad->itad_nrules) != 0 || tad->itad_nrules > IMC_MAX_TAD_RULES) {
357*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
358*eb00b1c8SRobert Mustacchi 	}
359*eb00b1c8SRobert Mustacchi 
360*eb00b1c8SRobert Mustacchi 	for (uint_t i = 0; i < tad->itad_nrules; i++) {
361*eb00b1c8SRobert Mustacchi 		imc_tad_rule_t *r = &tad->itad_rules[i];
362*eb00b1c8SRobert Mustacchi 		uint8_t *targs;
363*eb00b1c8SRobert Mustacchi 
364*eb00b1c8SRobert Mustacchi 		if (nvlist_lookup_uint64(rules[i], "itr_base",
365*eb00b1c8SRobert Mustacchi 		    &r->itr_base) != 0 ||
366*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint64(rules[i], "itr_limit",
367*eb00b1c8SRobert Mustacchi 		    &r->itr_limit) != 0 ||
368*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(rules[i], "itr_sock_way",
369*eb00b1c8SRobert Mustacchi 		    &r->itr_sock_way) != 0 ||
370*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(rules[i], "itr_chan_way",
371*eb00b1c8SRobert Mustacchi 		    &r->itr_chan_way) != 0 ||
372*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint32(rules[i], "itr_sock_gran",
373*eb00b1c8SRobert Mustacchi 		    &r->itr_sock_gran) != 0 ||
374*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint32(rules[i], "itr_chan_gran",
375*eb00b1c8SRobert Mustacchi 		    &r->itr_chan_gran) != 0 ||
376*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8_array(rules[i], "itr_targets",
377*eb00b1c8SRobert Mustacchi 		    &targs, &r->itr_ntargets) != 0 ||
378*eb00b1c8SRobert Mustacchi 		    r->itr_ntargets > IMC_MAX_TAD_TARGETS) {
379*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
380*eb00b1c8SRobert Mustacchi 		}
381*eb00b1c8SRobert Mustacchi 
382*eb00b1c8SRobert Mustacchi 		bcopy(targs, r->itr_targets, r->itr_ntargets *
383*eb00b1c8SRobert Mustacchi 		    sizeof (uint8_t));
384*eb00b1c8SRobert Mustacchi 	}
385*eb00b1c8SRobert Mustacchi 
386*eb00b1c8SRobert Mustacchi 	return (B_TRUE);
387*eb00b1c8SRobert Mustacchi }
388*eb00b1c8SRobert Mustacchi 
389*eb00b1c8SRobert Mustacchi static boolean_t
imc_restore_channel(nvlist_t * nvl,imc_channel_t * chan)390*eb00b1c8SRobert Mustacchi imc_restore_channel(nvlist_t *nvl, imc_channel_t *chan)
391*eb00b1c8SRobert Mustacchi {
392*eb00b1c8SRobert Mustacchi 	nvlist_t **dimms, **rir;
393*eb00b1c8SRobert Mustacchi 	uint64_t *tadoff;
394*eb00b1c8SRobert Mustacchi 
395*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_uint32(nvl, "ich_valid", &chan->ich_valid) != 0 ||
396*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(nvl, "ich_dimms", &dimms,
397*eb00b1c8SRobert Mustacchi 	    &chan->ich_ndimms) != 0 ||
398*eb00b1c8SRobert Mustacchi 	    chan->ich_ndimms > IMC_MAX_DIMMPERCHAN ||
399*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_uint64_array(nvl, "ich_tad_offsets", &tadoff,
400*eb00b1c8SRobert Mustacchi 	    &chan->ich_ntad_offsets) != 0 ||
401*eb00b1c8SRobert Mustacchi 	    chan->ich_ntad_offsets > IMC_MAX_TAD_RULES ||
402*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(nvl, "ich_rankileaves", &rir,
403*eb00b1c8SRobert Mustacchi 	    &chan->ich_nrankileaves) != 0 ||
404*eb00b1c8SRobert Mustacchi 	    chan->ich_nrankileaves > IMC_MAX_RANK_WAYS) {
405*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
406*eb00b1c8SRobert Mustacchi 	}
407*eb00b1c8SRobert Mustacchi 
408*eb00b1c8SRobert Mustacchi 	for (uint_t i = 0; i < chan->ich_ndimms; i++) {
409*eb00b1c8SRobert Mustacchi 		imc_dimm_t *d = &chan->ich_dimms[i];
410*eb00b1c8SRobert Mustacchi 
411*eb00b1c8SRobert Mustacchi 		if (nvlist_lookup_uint32(dimms[i], "idimm_valid",
412*eb00b1c8SRobert Mustacchi 		    &d->idimm_valid) != 0 ||
413*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_boolean_value(dimms[i], "idimm_present",
414*eb00b1c8SRobert Mustacchi 		    &d->idimm_present) != 0) {
415*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
416*eb00b1c8SRobert Mustacchi 		}
417*eb00b1c8SRobert Mustacchi 
418*eb00b1c8SRobert Mustacchi 		if (!d->idimm_present)
419*eb00b1c8SRobert Mustacchi 			continue;
420*eb00b1c8SRobert Mustacchi 
421*eb00b1c8SRobert Mustacchi 		if (nvlist_lookup_uint8(dimms[i], "idimm_nbanks",
422*eb00b1c8SRobert Mustacchi 		    &d->idimm_nbanks) != 0 ||
423*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(dimms[i], "idimm_nranks",
424*eb00b1c8SRobert Mustacchi 		    &d->idimm_nranks) != 0 ||
425*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(dimms[i], "idimm_width",
426*eb00b1c8SRobert Mustacchi 		    &d->idimm_width) != 0 ||
427*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(dimms[i], "idimm_density",
428*eb00b1c8SRobert Mustacchi 		    &d->idimm_density) != 0 ||
429*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(dimms[i], "idimm_nrows",
430*eb00b1c8SRobert Mustacchi 		    &d->idimm_nrows) != 0 ||
431*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(dimms[i], "idimm_ncolumns",
432*eb00b1c8SRobert Mustacchi 		    &d->idimm_ncolumns) != 0 ||
433*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint64(dimms[i], "idimm_size",
434*eb00b1c8SRobert Mustacchi 		    &d->idimm_size) != 0) {
435*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
436*eb00b1c8SRobert Mustacchi 		}
437*eb00b1c8SRobert Mustacchi 	}
438*eb00b1c8SRobert Mustacchi 
439*eb00b1c8SRobert Mustacchi 	bcopy(tadoff, chan->ich_tad_offsets, chan->ich_ntad_offsets *
440*eb00b1c8SRobert Mustacchi 	    sizeof (uint64_t));
441*eb00b1c8SRobert Mustacchi 
442*eb00b1c8SRobert Mustacchi 	for (uint_t i = 0; i < chan->ich_nrankileaves; i++) {
443*eb00b1c8SRobert Mustacchi 		nvlist_t **ileaves;
444*eb00b1c8SRobert Mustacchi 		imc_rank_ileave_t *r = &chan->ich_rankileaves[i];
445*eb00b1c8SRobert Mustacchi 
446*eb00b1c8SRobert Mustacchi 		if (nvlist_lookup_boolean_value(rir[i], "irle_enabled",
447*eb00b1c8SRobert Mustacchi 		    &r->irle_enabled) != 0 ||
448*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(rir[i], "irle_nways",
449*eb00b1c8SRobert Mustacchi 		    &r->irle_nways) != 0 ||
450*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint8(rir[i], "irle_nwaysbits",
451*eb00b1c8SRobert Mustacchi 		    &r->irle_nwaysbits) != 0 ||
452*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_uint64(rir[i], "irle_limit",
453*eb00b1c8SRobert Mustacchi 		    &r->irle_limit) != 0 ||
454*eb00b1c8SRobert Mustacchi 		    nvlist_lookup_nvlist_array(rir[i], "irle_entries",
455*eb00b1c8SRobert Mustacchi 		    &ileaves, &r->irle_nentries) != 0 ||
456*eb00b1c8SRobert Mustacchi 		    r->irle_nentries > IMC_MAX_RANK_INTERLEAVES) {
457*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
458*eb00b1c8SRobert Mustacchi 		}
459*eb00b1c8SRobert Mustacchi 
460*eb00b1c8SRobert Mustacchi 		for (uint_t j = 0; j < r->irle_nentries; j++) {
461*eb00b1c8SRobert Mustacchi 			imc_rank_ileave_entry_t *ril = &r->irle_entries[j];
462*eb00b1c8SRobert Mustacchi 
463*eb00b1c8SRobert Mustacchi 			if (nvlist_lookup_uint8(ileaves[j], "irle_target",
464*eb00b1c8SRobert Mustacchi 			    &ril->irle_target) != 0 ||
465*eb00b1c8SRobert Mustacchi 			    nvlist_lookup_uint64(ileaves[j], "irle_offset",
466*eb00b1c8SRobert Mustacchi 			    &ril->irle_offset) != 0) {
467*eb00b1c8SRobert Mustacchi 				return (B_FALSE);
468*eb00b1c8SRobert Mustacchi 			}
469*eb00b1c8SRobert Mustacchi 		}
470*eb00b1c8SRobert Mustacchi 	}
471*eb00b1c8SRobert Mustacchi 
472*eb00b1c8SRobert Mustacchi 	return (B_TRUE);
473*eb00b1c8SRobert Mustacchi }
474*eb00b1c8SRobert Mustacchi 
475*eb00b1c8SRobert Mustacchi static boolean_t
imc_restore_mc(nvlist_t * nvl,imc_mc_t * mc)476*eb00b1c8SRobert Mustacchi imc_restore_mc(nvlist_t *nvl, imc_mc_t *mc)
477*eb00b1c8SRobert Mustacchi {
478*eb00b1c8SRobert Mustacchi 	nvlist_t **channels;
479*eb00b1c8SRobert Mustacchi 
480*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_boolean_value(nvl, "icn_ecc", &mc->icn_ecc) != 0 ||
481*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_boolean_value(nvl, "icn_lockstep",
482*eb00b1c8SRobert Mustacchi 	    &mc->icn_lockstep) != 0 ||
483*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_boolean_value(nvl, "icn_closed",
484*eb00b1c8SRobert Mustacchi 	    &mc->icn_closed) != 0 ||
485*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_uint32(nvl, "icn_dimm_type",
486*eb00b1c8SRobert Mustacchi 	    &mc->icn_dimm_type) != 0 ||
487*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(nvl, "icn_channels", &channels,
488*eb00b1c8SRobert Mustacchi 	    &mc->icn_nchannels) != 0 || mc->icn_nchannels > IMC_MAX_CHANPERMC) {
489*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
490*eb00b1c8SRobert Mustacchi 	}
491*eb00b1c8SRobert Mustacchi 
492*eb00b1c8SRobert Mustacchi 	for (uint_t i = 0; i < mc->icn_nchannels; i++) {
493*eb00b1c8SRobert Mustacchi 		if (!imc_restore_channel(channels[i], &mc->icn_channels[i])) {
494*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
495*eb00b1c8SRobert Mustacchi 		}
496*eb00b1c8SRobert Mustacchi 	}
497*eb00b1c8SRobert Mustacchi 
498*eb00b1c8SRobert Mustacchi 	return (B_TRUE);
499*eb00b1c8SRobert Mustacchi }
500*eb00b1c8SRobert Mustacchi 
501*eb00b1c8SRobert Mustacchi static boolean_t
imc_restore_socket(nvlist_t * nvl,imc_socket_t * sock)502*eb00b1c8SRobert Mustacchi imc_restore_socket(nvlist_t *nvl, imc_socket_t *sock)
503*eb00b1c8SRobert Mustacchi {
504*eb00b1c8SRobert Mustacchi 	uint_t i;
505*eb00b1c8SRobert Mustacchi 	nvlist_t *sad, **tads, **imcs;
506*eb00b1c8SRobert Mustacchi 
507*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_nvlist(nvl, "isock_sad", &sad) != 0 ||
508*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(nvl, "isock_tad", &tads,
509*eb00b1c8SRobert Mustacchi 	    &sock->isock_ntad) != 0 ||
510*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_uint32(nvl, "isock_nodeid",
511*eb00b1c8SRobert Mustacchi 	    &sock->isock_nodeid) != 0 ||
512*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(nvl, "isock_imcs", &imcs,
513*eb00b1c8SRobert Mustacchi 	    &sock->isock_nimc) != 0 ||
514*eb00b1c8SRobert Mustacchi 	    sock->isock_ntad > IMC_MAX_TAD ||
515*eb00b1c8SRobert Mustacchi 	    sock->isock_nimc > IMC_MAX_IMCPERSOCK) {
516*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
517*eb00b1c8SRobert Mustacchi 	}
518*eb00b1c8SRobert Mustacchi 
519*eb00b1c8SRobert Mustacchi 	if (!imc_restore_sad(sad, &sock->isock_sad)) {
520*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
521*eb00b1c8SRobert Mustacchi 	}
522*eb00b1c8SRobert Mustacchi 
523*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sock->isock_ntad; i++) {
524*eb00b1c8SRobert Mustacchi 		if (!imc_restore_tad(tads[i], &sock->isock_tad[i])) {
525*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
526*eb00b1c8SRobert Mustacchi 		}
527*eb00b1c8SRobert Mustacchi 	}
528*eb00b1c8SRobert Mustacchi 
529*eb00b1c8SRobert Mustacchi 	for (i = 0; i < sock->isock_nimc; i++) {
530*eb00b1c8SRobert Mustacchi 		if (!imc_restore_mc(imcs[i], &sock->isock_imcs[i])) {
531*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
532*eb00b1c8SRobert Mustacchi 		}
533*eb00b1c8SRobert Mustacchi 	}
534*eb00b1c8SRobert Mustacchi 
535*eb00b1c8SRobert Mustacchi 	return (B_TRUE);
536*eb00b1c8SRobert Mustacchi }
537*eb00b1c8SRobert Mustacchi 
538*eb00b1c8SRobert Mustacchi boolean_t
imc_restore_decoder(nvlist_t * nvl,imc_t * imc)539*eb00b1c8SRobert Mustacchi imc_restore_decoder(nvlist_t *nvl, imc_t *imc)
540*eb00b1c8SRobert Mustacchi {
541*eb00b1c8SRobert Mustacchi 	uint_t i;
542*eb00b1c8SRobert Mustacchi 	uint32_t vers;
543*eb00b1c8SRobert Mustacchi 	nvlist_t *invl, **socks;
544*eb00b1c8SRobert Mustacchi 	char *driver;
545*eb00b1c8SRobert Mustacchi 
546*eb00b1c8SRobert Mustacchi 	bzero(imc, sizeof (imc_t));
547*eb00b1c8SRobert Mustacchi 
548*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_uint32(nvl, "mc_dump_version", &vers) != 0 ||
549*eb00b1c8SRobert Mustacchi 	    vers != 0 ||
550*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_string(nvl, "mc_dump_driver", &driver) != 0 ||
551*eb00b1c8SRobert Mustacchi 	    strcmp(driver, "imc") != 0 ||
552*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist(nvl, "imc", &invl) != 0) {
553*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
554*eb00b1c8SRobert Mustacchi 	}
555*eb00b1c8SRobert Mustacchi 
556*eb00b1c8SRobert Mustacchi 	if (nvlist_lookup_uint32(invl, "imc_gen", &imc->imc_gen) != 0 ||
557*eb00b1c8SRobert Mustacchi 	    nvlist_lookup_nvlist_array(invl, "imc_sockets", &socks,
558*eb00b1c8SRobert Mustacchi 	    &imc->imc_nsockets) != 0 ||
559*eb00b1c8SRobert Mustacchi 	    imc->imc_nsockets > IMC_MAX_SOCKETS) {
560*eb00b1c8SRobert Mustacchi 		return (B_FALSE);
561*eb00b1c8SRobert Mustacchi 	}
562*eb00b1c8SRobert Mustacchi 
563*eb00b1c8SRobert Mustacchi 	for (i = 0; i < imc->imc_nsockets; i++) {
564*eb00b1c8SRobert Mustacchi 		if (!imc_restore_socket(socks[i], &imc->imc_sockets[i]))
565*eb00b1c8SRobert Mustacchi 			return (B_FALSE);
566*eb00b1c8SRobert Mustacchi 	}
567*eb00b1c8SRobert Mustacchi 
568*eb00b1c8SRobert Mustacchi 	return (B_TRUE);
569*eb00b1c8SRobert Mustacchi }
570