4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * This plugin creates memory configuration nodes and properties in the
31 * PICL tree for Grover/Grover+ platform.
33 * Subtree of memory-controller in the physical aspect.
34 * memory-controller --- memory-module
35 * However, there is no memory controller node on Grover. Thus we need to
36 * create it under platform.
38 * Subtree of memory in the logical aspect.
39 * memory --- memory-segment
40 * Add property _memory-module_ at memory-segment referring to the
41 * memory-module since memory-segment equals to memory-module on Grover.
44 * Create all nodes and properties, or none if it fails in physical and
45 * logical memory tree respectively. It keeps on creating logical
46 * memory tree although it falis on physical logical tree, but no link to
50 * It depends on PICL devtree plugin.
62 #include <sys/types.h>
63 #include <sys/obpdefs.h>
64 #include "piclmemcfg.h"
65 #include "memcfg_impl.h"
67 static void piclmemcfg_register(void);
68 static void piclmemcfg_init(void);
69 static void piclmemcfg_fini(void);
71 #pragma init(piclmemcfg_register)
73 static picld_plugin_reg_t my_reg_info
= {
74 PICLD_PLUGIN_VERSION_1
,
75 PICLD_PLUGIN_NON_CRITICAL
,
82 * Create logical memory tree
83 * memory --- memory-segment
86 create_logical_tree(picl_nodehdl_t memh
, mmodinfo_t
*mmodinfo
)
89 picl_nodehdl_t
*memsegh
;
90 ptree_propinfo_t propinfo
;
91 uint32_t ifactor
= INTERLEAVEFACTOR
;
93 int err
= PICL_SUCCESS
;
95 if ((memsegh
= alloca(sizeof (picl_nodehdl_t
) * TOTAL_MEM_SLOTS
)) ==
97 return (PICL_FAILURE
);
99 for (i
= 0; i
< TOTAL_MEM_SLOTS
; i
++) {
101 * It means no segment for the slot if size is zero
103 if (mmodinfo
[i
].size
== 0) {
109 * Create memory-segment node under memory
111 err
= ptree_create_and_add_node(memh
, PICL_NAME_MEMORY_SEGMENT
,
112 PICL_CLASS_MEMORY_SEGMENT
, &msegh
);
113 if (err
!= PICL_SUCCESS
)
117 * For undo easily later
122 * Add property, Size to memory-segment node
124 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
125 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
,
126 sizeof (mmodinfo
[i
].size
), PICL_PROP_SIZE
, NULL
, NULL
);
127 if (err
!= PICL_SUCCESS
)
130 err
= ptree_create_and_add_prop(msegh
, &propinfo
,
131 &mmodinfo
[i
].size
, NULL
);
132 if (err
!= PICL_SUCCESS
)
136 * Add property, BaseAddress to memory-segment node
138 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
139 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
,
140 sizeof (mmodinfo
[i
].base
), PICL_PROP_BASEADDRESS
, NULL
,
142 if (err
!= PICL_SUCCESS
)
145 err
= ptree_create_and_add_prop(msegh
, &propinfo
,
146 &mmodinfo
[i
].base
, NULL
);
147 if (err
!= PICL_SUCCESS
)
151 * Add property, InterleaveFactor to memory-segment node
153 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
154 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
, sizeof (ifactor
),
155 PICL_PROP_INTERLEAVE_FACTOR
, NULL
, NULL
);
156 if (err
!= PICL_SUCCESS
)
159 err
= ptree_create_and_add_prop(msegh
, &propinfo
, &ifactor
,
161 if (err
!= PICL_SUCCESS
)
165 * Add reference property to the memory module if memory
166 * module node handle is not NULL.
168 if (mmodinfo
[i
].memmodh
== NULL
)
171 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
172 PICL_PTYPE_REFERENCE
, PICL_READ
, sizeof (picl_nodehdl_t
),
173 PICL_REFPROP_MEMORY_MODULE
, NULL
, NULL
);
174 if (err
!= PICL_SUCCESS
)
177 err
= ptree_create_and_add_prop(msegh
, &propinfo
,
178 &mmodinfo
[i
].memmodh
, NULL
);
179 if (err
!= PICL_SUCCESS
)
183 if (err
!= PICL_SUCCESS
) {
185 * Undo in the logical memory tree
187 for (i
= 0; i
< TOTAL_MEM_SLOTS
; i
++) {
188 if (memsegh
[i
] == NULL
)
191 (void) ptree_delete_node(memsegh
[i
]);
192 (void) ptree_destroy_node(memsegh
[i
]);
200 * Create physical memory tree
201 * memory-controller --- memory-module
204 create_physical_tree(picl_nodehdl_t plfh
, mmodinfo_t
*mmodinfo
)
206 picl_nodehdl_t mch
, memmodh
;
207 ptree_propinfo_t propinfo
;
209 int err
= PICL_SUCCESS
;
213 * Create memory-controller node under platform
215 err
= ptree_create_and_add_node(plfh
, PICL_NAME_MEMORY_CONTROLLER
,
216 PICL_CLASS_MEMORY_CONTROLLER
, &mch
);
217 if (err
!= PICL_SUCCESS
)
221 * Create memory-module nodes and properties
222 * Get all memory modules with dimm
224 for (i
= 0; i
< TOTAL_MEM_SLOTS
; i
++) {
226 * It means no dimm on the slot if size is zero
228 if (mmodinfo
[i
].size
== 0)
231 /* Create memory-module node under memory-controller */
232 err
= ptree_create_and_add_node(mch
, PICL_NAME_MEMORY_MODULE
,
233 PICL_CLASS_MEMORY_MODULE
, &memmodh
);
234 if (err
!= PICL_SUCCESS
)
238 * Update memory module node handle at mmodinfo
240 mmodinfo
[i
].memmodh
= memmodh
;
243 * Add property, Size to memory-module node
245 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
246 PICL_PTYPE_UNSIGNED_INT
, PICL_READ
,
247 sizeof (mmodinfo
[i
].size
), PICL_PROP_SIZE
, NULL
, NULL
);
248 if (err
!= PICL_SUCCESS
)
251 err
= ptree_create_and_add_prop(memmodh
, &propinfo
,
252 &mmodinfo
[i
].size
, NULL
);
253 if (err
!= PICL_SUCCESS
)
257 * Add property, ID to memory-module node
259 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
260 PICL_PTYPE_INT
, PICL_READ
, sizeof (id
), PICL_PROP_ID
,
262 if (err
!= PICL_SUCCESS
)
266 err
= ptree_create_and_add_prop(memmodh
, &propinfo
, &id
, NULL
);
267 if (err
!= PICL_SUCCESS
)
271 if (err
!= PICL_SUCCESS
) {
273 * Clear out the saved memory module node handle so that
274 * logical memory tree won't link to memory module.
276 for (i
= 0; i
< TOTAL_MEM_SLOTS
; i
++)
277 mmodinfo
[i
].memmodh
= NULL
;
280 * Undo in the physical memory tree
282 (void) ptree_delete_node(mch
);
283 (void) ptree_destroy_node(mch
);
290 * Get the memory module and memory segment information from
291 * property reg of memory node.
293 * mmodinfo will be updated. Also, the pointers to mseginfo and
294 * the number of segments will be passed to the caller.
297 get_reg_info(picl_nodehdl_t plfh
, picl_nodehdl_t memh
,
298 mmodinfo_t
*mmodinfo
)
300 picl_prophdl_t proph
;
301 ptree_propinfo_t pinfo
;
309 * Check if the #size-cells of the platform node is 2
311 err
= ptree_get_propval_by_name(plfh
, OBP_PROP_SIZE_CELLS
, &pval
,
314 if (err
== PICL_PROPNOTFOUND
)
315 pval
= SUPPORTED_NUM_CELL_SIZE
;
316 else if (err
!= PICL_SUCCESS
)
320 * don't know to handle other vals
322 if (pval
!= SUPPORTED_NUM_CELL_SIZE
)
323 return (PICL_FAILURE
);
326 * Get property reg of memory node
328 err
= ptree_get_prop_by_name(memh
, OBP_REG
, &proph
);
329 if (err
!= PICL_SUCCESS
)
332 err
= ptree_get_propinfo(proph
, &pinfo
);
333 if (err
!= PICL_SUCCESS
)
336 if ((memspec
= alloca(pinfo
.piclinfo
.size
)) == NULL
)
337 return (PICL_FAILURE
);
339 nregspec
= pinfo
.piclinfo
.size
/ sizeof (*memspec
);
341 if ((nregspec
== 0) || (nregspec
> TOTAL_MEM_SLOTS
))
342 return (PICL_FAILURE
);
344 err
= ptree_get_propval(proph
, memspec
, pinfo
.piclinfo
.size
);
345 if (err
!= PICL_SUCCESS
)
349 for (i
= 0; i
< nregspec
; i
++) {
351 mmodinfo
[i
].base
= memspec
[i
].physaddr
;
352 mmodinfo
[i
].size
= memspec
[i
].size
;
356 return (PICL_SUCCESS
);
360 * executed as part of .init when the plugin is dlopen()ed
363 piclmemcfg_register(void)
365 (void) picld_plugin_register(&my_reg_info
);
369 * Init entry point of the plugin
370 * Creates the PICL nodes and properties in the physical and logical aspects.
373 piclmemcfg_init(void)
375 picl_nodehdl_t plfh
, memh
;
376 mmodinfo_t mmodinfo
[TOTAL_MEM_SLOTS
];
381 if ((ptree_get_node_by_path(PLATFORM_PATH
, &plfh
)) != PICL_SUCCESS
) {
382 syslog(LOG_ERR
, EM_INIT_FAILED
);
387 * Find the memory node
389 if ((ptree_get_node_by_path(MEMORY_PATH
, &memh
)) != PICL_SUCCESS
) {
390 syslog(LOG_ERR
, EM_INIT_FAILED
);
395 * Initialize the mmodinfo and get segment information from reg
397 (void) memset(mmodinfo
, 0, sizeof (mmodinfo
));
399 if ((get_reg_info(plfh
, memh
, mmodinfo
)) != PICL_SUCCESS
) {
400 syslog(LOG_ERR
, EM_INIT_FAILED
);
405 * Create subtree of memory-controller in the physical aspect.
406 * memory-controller --- memory-module
408 if ((create_physical_tree(plfh
, mmodinfo
)) != PICL_SUCCESS
)
409 syslog(LOG_ERR
, EM_PHYSIC_MEM_TREE_FAILED
);
412 * Create subtree of memory in the logical aspect.
413 * memory --- memory-segment
415 if ((create_logical_tree(memh
, mmodinfo
)) != PICL_SUCCESS
)
416 syslog(LOG_ERR
, EM_LOGIC_MEM_TREE_FAILED
);
420 * fini entry point of the plugin
423 piclmemcfg_fini(void)