/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* The PRI plug-in picks up memory configuration data from the PRI
* and injects this into PICL's /platform tree. It only populates
* the logical view of memory: memory, memory-segment, memory-bank.
* It does not populate the /device tree since there are no memory
* controller devices on sun4v.
*/
#include "priplugin.h"
#include "../../common/memcfg/piclmemcfg.h"
static void
static void
static void
/*
* Callback function for picl_walk_tree_by_class().
* NOTE: picl_walk_tree_by_class() maps the return codes PICL_WALK_CONTINUE
* and PICL_WALK_TERMINATE to PICL_SUCCESS.
*/
int
{
return (PICL_WALK_CONTINUE);
/*
* An absence of nodes or failure to obtain memory for searches
* or absence of the /memory node will cause this to fail.
* Return PICL_WALK_SUCCESS to allow the plug-in to continue.
*/
if (num_nodes == 0) {
return (PICL_SUCCESS);
}
return (PICL_SUCCESS);
}
memorylistp = &buf[0];
"add_mem_prop: can't find /memory node in platform tree\n");
return (PICL_SUCCESS);
}
/*
* There should be only one memory node.
* If we can't find what we're looking for in the DAG then
* return PICL_PROPNOTFOUND to get the caller to re-try with
* a different property name.
*/
if (nmemory != 1) {
"add_mem_prop: wrong number of memory dags: expected "
"1, got %d\n", nmemory);
return (PICL_PROPNOTFOUND);
}
if (nsegments == 0) {
"segments: expected >0, got %d\n", nsegments);
return (PICL_PROPNOTFOUND);
}
/*
* Add memory segments, keep running total of system memory.
*/
nbanks = 0;
if (err == PICL_SUCCESS) {
size = 0;
mask = 0;
/*
* Need to pull this out here since it's used for
* the ID.
*/
&segbase))
/*
* Add banks under each segment.
*/
if (nbanks <= 0) {
"found for segment %d\n", j);
} else {
for (k = 0; k < nbanks; ++k) {
err =
if (err == PICL_SUCCESS) {
/*
* Add AddressMatch,
* AddressMask, Size, and
* ID to each bank.
*/
banklistp[k],
mdp,
(segbase >> 32) * j + k);
}
}
}
}
/*
* Add Interleave, BaseAddress, and Size to each segment.
*/
}
/*
* Add TransferSize and Size (total memory) to this node.
*/
return (PICL_WALK_CONTINUE);
}
static void
{
"add_bank_props: can't allocate memory\n");
return;
}
}
&int_value)) {
}
&int_value)) {
}
for (i = 0; i < node_count; ++i) {
(char **)&type);
if (status == -1) {
}
continue;
(char **)&nac) == 0) {
PICL_SUCCESS) {
"nac", nac,
}
}
}
}
}
static uint64_t
{
uint64_t c; /* c accumulates the total bits set in v */
for (c = 0; v; c++)
v &= v - 1; /* clear the least significant bit set */
return (c);
}
static void
{
*size = 0;
}
}
static void
{
/*
* If the top-level node has a size property then use that,
* otherwise use the size that was calculated by the caller
* and passed in.
*/
&int_value)) {
}
}