From 548767f42eb00a2bac6f2a1361b7fd49f7b76908 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 16 May 2008 13:22:57 +1000 Subject: dtc: Rework handling of boot_cpuid_phys Currently, dtc will put the nonsense value 0xfeedbeef into the boot_cpuid_phys field of an output blob, unless explicitly given another value with the -b command line option. As well as being a totally unuseful default value, this also means that dtc won't properly preserve the boot_cpuid_phys field in -I dtb -O dtb mode. This patch reworks things to improve the boot_cpuid handling. The new semantics are that the output's boot_cpuid_phys value is: the value given on the command line if -b is used otherwise the value from the input, if in -I dtb mode otherwise 0 Implementation-wise we do the following: - boot_cpuid_phys is added to struct boot_info, so that structure now contains all of the blob's semantic information. - dt_to_blob() and dt_to_asm() output the cpuid given in boot_info - dt_from_blob() fills in boot_info based on the input blob - The other dt_from_*() functions just record 0, but we can change this easily if e.g. we invent a way of specifying the boot cpu in the source format. - main() overrides the cpuid in the boot_info between input and output if -b is given We add some testcases to check this new behaviour. Signed-off-by: David Gibson --- dtc-parser.y | 4 ++-- dtc.c | 12 ++++++++---- dtc.h | 9 ++++----- flattree.c | 14 +++++++------- fstree.c | 2 +- livetree.c | 3 ++- tests/Makefile.tests | 2 +- tests/boot-cpuid.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ tests/dtbs_equal_ordered.c | 7 +++++++ tests/run_tests.sh | 8 ++++++++ 10 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 tests/boot-cpuid.c diff --git a/dtc-parser.y b/dtc-parser.y index 4ab1df9..0bf3fcb 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -85,11 +85,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits); sourcefile: DT_V1 ';' memreserves devicetree { - the_boot_info = build_boot_info($3, $4); + the_boot_info = build_boot_info($3, $4, 0); } | v0_memreserves devicetree { - the_boot_info = build_boot_info($1, $2); + the_boot_info = build_boot_info($1, $2, 0); } ; diff --git a/dtc.c b/dtc.c index 267d581..d8fd43b 100644 --- a/dtc.c +++ b/dtc.c @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) int opt; FILE *outf = NULL; int outversion = DEFAULT_FDT_VERSION; - int boot_cpuid_phys = 0xfeedbeef; + long long cmdline_boot_cpuid = -1; quiet = 0; reservenum = 0; @@ -160,7 +160,7 @@ int main(int argc, char *argv[]) quiet++; break; case 'b': - boot_cpuid_phys = strtol(optarg, NULL, 0); + cmdline_boot_cpuid = strtoll(optarg, NULL, 0); break; case 'v': printf("Version: %s\n", DTC_VERSION); @@ -194,9 +194,13 @@ int main(int argc, char *argv[]) else die("Unknown input format \"%s\"\n", inform); + if (cmdline_boot_cpuid != -1) + bi->boot_cpuid_phys = cmdline_boot_cpuid; + fill_fullpaths(bi->dt, ""); process_checks(force, bi); + if (streq(outname, "-")) { outf = stdout; } else { @@ -209,9 +213,9 @@ int main(int argc, char *argv[]) if (streq(outform, "dts")) { dt_to_source(outf, bi); } else if (streq(outform, "dtb")) { - dt_to_blob(outf, bi, outversion, boot_cpuid_phys); + dt_to_blob(outf, bi, outversion); } else if (streq(outform, "asm")) { - dt_to_asm(outf, bi, outversion, boot_cpuid_phys); + dt_to_asm(outf, bi, outversion); } else if (streq(outform, "null")) { /* do nothing */ } else { diff --git a/dtc.h b/dtc.h index 8935483..762706e 100644 --- a/dtc.h +++ b/dtc.h @@ -232,10 +232,11 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, struct boot_info { struct reserve_info *reservelist; struct node *dt; /* the device tree */ + u32 boot_cpuid_phys; }; struct boot_info *build_boot_info(struct reserve_info *reservelist, - struct node *tree); + struct node *tree, u32 boot_cpuid_phys); /* Checks */ @@ -243,10 +244,8 @@ void process_checks(int force, struct boot_info *bi); /* Flattened trees */ -void dt_to_blob(FILE *f, struct boot_info *bi, int version, - int boot_cpuid_phys); -void dt_to_asm(FILE *f, struct boot_info *bi, int version, - int boot_cpuid_phys); +void dt_to_blob(FILE *f, struct boot_info *bi, int version); +void dt_to_asm(FILE *f, struct boot_info *bi, int version); struct boot_info *dt_from_blob(const char *fname); diff --git a/flattree.c b/flattree.c index fd69293..51f43e7 100644 --- a/flattree.c +++ b/flattree.c @@ -354,8 +354,7 @@ static void make_fdt_header(struct fdt_header *fdt, fdt->size_dt_struct = cpu_to_be32(dtsize); } -void dt_to_blob(FILE *f, struct boot_info *bi, int version, - int boot_cpuid_phys) +void dt_to_blob(FILE *f, struct boot_info *bi, int version) { struct version_info *vi = NULL; int i; @@ -380,7 +379,7 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version, /* Make header */ make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, - boot_cpuid_phys); + bi->boot_cpuid_phys); /* * If the user asked for more space than is used, adjust the totalsize. @@ -446,7 +445,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf) } } -void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys) +void dt_to_asm(FILE *f, struct boot_info *bi, int version) { struct version_info *vi = NULL; int i; @@ -486,7 +485,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys) if (vi->flags & FTF_BOOTCPUID) fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", - boot_cpuid_phys); + bi->boot_cpuid_phys); if (vi->flags & FTF_STRTABSIZE) fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", @@ -784,7 +783,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, struct boot_info *dt_from_blob(const char *fname) { struct dtc_file *dtcf; - u32 magic, totalsize, version, size_dt; + u32 magic, totalsize, version, size_dt, boot_cpuid_phys; u32 off_dt, off_str, off_mem_rsvmap; int rc; char *blob; @@ -856,6 +855,7 @@ struct boot_info *dt_from_blob(const char *fname) off_str = be32_to_cpu(fdt->off_dt_strings); off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap); version = be32_to_cpu(fdt->version); + boot_cpuid_phys = be32_to_cpu(fdt->boot_cpuid_phys); if (off_mem_rsvmap >= totalsize) die("Mem Reserve structure offset exceeds total size\n"); @@ -908,5 +908,5 @@ struct boot_info *dt_from_blob(const char *fname) dtc_close_file(dtcf); - return build_boot_info(reservelist, tree); + return build_boot_info(reservelist, tree, boot_cpuid_phys); } diff --git a/fstree.c b/fstree.c index 0c0bdf0..766b269 100644 --- a/fstree.c +++ b/fstree.c @@ -87,6 +87,6 @@ struct boot_info *dt_from_fs(const char *dirname) tree = read_fstree(dirname); tree = name_node(tree, "", NULL); - return build_boot_info(NULL, tree); + return build_boot_info(NULL, tree, 0); } diff --git a/livetree.c b/livetree.c index 6ba0846..0b250fb 100644 --- a/livetree.c +++ b/livetree.c @@ -165,13 +165,14 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, } struct boot_info *build_boot_info(struct reserve_info *reservelist, - struct node *tree) + struct node *tree, u32 boot_cpuid_phys) { struct boot_info *bi; bi = xmalloc(sizeof(*bi)); bi->reservelist = reservelist; bi->dt = tree; + bi->boot_cpuid_phys = boot_cpuid_phys; return bi; } diff --git a/tests/Makefile.tests b/tests/Makefile.tests index d7c9ebc..df331c4 100644 --- a/tests/Makefile.tests +++ b/tests/Makefile.tests @@ -9,7 +9,7 @@ LIB_TESTS_L = get_mem_rsv \ sw_tree1 \ move_and_save mangle-layout nopulate \ open_pack rw_tree1 set_name setprop del_property del_node \ - string_escapes references path-references \ + string_escapes references path-references boot-cpuid \ dtbs_equal_ordered \ add_subnode_with_nops LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%) diff --git a/tests/boot-cpuid.c b/tests/boot-cpuid.c new file mode 100644 index 0000000..7b5433d --- /dev/null +++ b/tests/boot-cpuid.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include +#include + +#include "tests.h" +#include "testdata.h" + +int main(int argc, char *argv[]) +{ + void *fdt; + uint32_t cpuid; + + test_init(argc, argv); + + if (argc != 3) + CONFIG("Usage: %s ", argv[0]); + + fdt = load_blob(argv[1]); + cpuid = strtoul(argv[2], NULL, 0); + + if (fdt_boot_cpuid_phys(fdt) != cpuid) + FAIL("Incorrect boot_cpuid_phys (0x%x instead of 0x%x)", + fdt_boot_cpuid_phys(fdt), cpuid); + + PASS(); +} diff --git a/tests/dtbs_equal_ordered.c b/tests/dtbs_equal_ordered.c index 0c30ad3..2847bbd 100644 --- a/tests/dtbs_equal_ordered.c +++ b/tests/dtbs_equal_ordered.c @@ -125,6 +125,7 @@ void compare_structure(const void *fdt1, const void *fdt2) int main(int argc, char *argv[]) { void *fdt1, *fdt2; + uint32_t cpuid1, cpuid2; test_init(argc, argv); if (argc != 3) @@ -135,5 +136,11 @@ int main(int argc, char *argv[]) compare_mem_rsv(fdt1, fdt2); compare_structure(fdt1, fdt2); + cpuid1 = fdt_boot_cpuid_phys(fdt1); + cpuid2 = fdt_boot_cpuid_phys(fdt2); + if (cpuid1 != cpuid2) + FAIL("boot_cpuid_phys mismatch 0x%x != 0x%x", + cpuid1, cpuid2); + PASS(); } diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 27dc11a..c187ae9 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -199,6 +199,14 @@ dtc_tests () { run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb + # Check boot_cpuid_phys handling + run_dtc_test -I dts -O dtb -b 17 -o boot_cpuid.test.dtb empty.dts + run_test boot-cpuid boot_cpuid.test.dtb 17 + run_dtc_test -I dtb -O dtb -b 17 -o boot_cpuid_test_tree1.test.dtb test_tree1.dtb + run_test boot-cpuid boot_cpuid_test_tree1.test.dtb 17 + run_dtc_test -I dtb -O dtb -o boot_cpuid_preserved_test_tree1.test.dtb boot_cpuid_test_tree1.test.dtb + run_test dtbs_equal_ordered boot_cpuid_preserved_test_tree1.test.dtb boot_cpuid_test_tree1.test.dtb + # Check -Odts mode preserve all dtb information for tree in test_tree1.dtb dtc_tree1.test.dtb dtc_escapes.test.dtb ; do run_dtc_test -I dtb -O dts -o odts_$tree.test.dts $tree -- cgit v1.1