dtc/fstree.c
David Gibson 15ad6d862e dtc: Automatically pick a sensible boot_cpuid_phys
Currently, when in -Idts -Odtb or -Ifs -Odtb modes, dtc always
defaults to using 0 as the value for the boot_cpuid_phys header field.
That's correct quite often, but there are some systems where there is
no CPU with hardware ID of 0, or where we don't want to use the CPU
with hardware ID 0 at all (e.g. for AMP-style partitioning).  The only
way to override this default currently, is with the -b command line
option.

This patch improves dtc to instead base the default boot_cpuid_phys
value on the reg property of the first listed subnode of /cpus.  This
means that dtc will get boot_cpuid_phys correct by default in a
greater proportion of cases (since the boot cpu is usually listed
first, and this way at least the boot_cpuid_phys default will match
some existing cpu node).  If the node doesn't exist or has an invalid
'reg' property (missing or not 4 bytes in length), then
boot_cpuid_phys is set to 0.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2010-02-19 08:36:23 -06:00

92 lines
2.2 KiB
C

/*
* (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include "dtc.h"
#include <dirent.h>
#include <sys/stat.h>
static struct node *read_fstree(const char *dirname)
{
DIR *d;
struct dirent *de;
struct stat st;
struct node *tree;
d = opendir(dirname);
if (!d)
die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
tree = build_node(NULL, NULL);
while ((de = readdir(d)) != NULL) {
char *tmpnam;
if (streq(de->d_name, ".")
|| streq(de->d_name, ".."))
continue;
tmpnam = join_path(dirname, de->d_name);
if (lstat(tmpnam, &st) < 0)
die("stat(%s): %s\n", tmpnam, strerror(errno));
if (S_ISREG(st.st_mode)) {
struct property *prop;
FILE *pfile;
pfile = fopen(tmpnam, "r");
if (! pfile) {
fprintf(stderr,
"WARNING: Cannot open %s: %s\n",
tmpnam, strerror(errno));
} else {
prop = build_property(xstrdup(de->d_name),
data_copy_file(pfile,
st.st_size),
NULL);
add_property(tree, prop);
fclose(pfile);
}
} else if (S_ISDIR(st.st_mode)) {
struct node *newchild;
newchild = read_fstree(tmpnam);
newchild = name_node(newchild, xstrdup(de->d_name),
NULL);
add_child(tree, newchild);
}
free(tmpnam);
}
return tree;
}
struct boot_info *dt_from_fs(const char *dirname)
{
struct node *tree;
tree = read_fstree(dirname);
tree = name_node(tree, "", NULL);
return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
}