[POWERPC] Use embedded libfdt in the bootwrapper
authorDavid Gibson <david@gibson.dropbear.id.au>
Mon, 10 Dec 2007 03:28:39 +0000 (14:28 +1100)
committerPaul Mackerras <paulus@samba.org>
Tue, 11 Dec 2007 02:46:14 +0000 (13:46 +1100)
This incorporates libfdt (from the source embedded in an earlier
commit) into the wrapper.a library used by the bootwrapper.  This
includes adding a libfdt_env.h file, which the libfdt sources need in
order to integrate into the bootwrapper environment, and a
libfdt-wrapper.c which provides glue to connect the bootwrapper's
abstract device tree callbacks to the libfdt functions.

In addition, this changes the various wrapper and platform files to
use libfdt functions instead of the older flatdevtree.c library.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
18 files changed:
arch/powerpc/boot/Makefile
arch/powerpc/boot/bamboo.c
arch/powerpc/boot/cuboot-52xx.c
arch/powerpc/boot/cuboot-83xx.c
arch/powerpc/boot/cuboot-85xx.c
arch/powerpc/boot/cuboot-8xx.c
arch/powerpc/boot/cuboot-hpc2.c
arch/powerpc/boot/cuboot-pq2.c
arch/powerpc/boot/cuboot-sequoia.c
arch/powerpc/boot/ebony.c
arch/powerpc/boot/ep88xc.c
arch/powerpc/boot/holly.c
arch/powerpc/boot/libfdt-wrapper.c [new file with mode: 0644]
arch/powerpc/boot/libfdt_env.h [new file with mode: 0644]
arch/powerpc/boot/ops.h
arch/powerpc/boot/prpmc2800.c
arch/powerpc/boot/ps3.c
arch/powerpc/boot/treeboot-walnut.c

index e1c73e9afa5997dddb79f0356d493fd09745cbcc..2d2c9843ce934816d475590695f6661ba8fd92c0 100644 (file)
@@ -33,7 +33,7 @@ ifeq ($(call cc-option-yn, -fstack-protector),y)
 BOOTCFLAGS     += -fno-stack-protector
 endif
 
-BOOTCFLAGS     += -I$(obj) -I$(srctree)/$(obj)
+BOOTCFLAGS     += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
 
 $(obj)/4xx.o: BOOTCFLAGS += -mcpu=440
 $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
@@ -46,7 +46,9 @@ zliblinuxheader := zlib.h zconf.h zutil.h
 $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
        $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
 
+src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
 src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
+               $(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \
                ns16550.c serial.c simple_alloc.c div64.S util.S \
                gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
                4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
@@ -101,8 +103,10 @@ quiet_cmd_bootar = BOOTAR  $@
       cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
 
 $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE
+       $(Q)mkdir -p $(dir $@)
        $(call if_changed_dep,bootcc)
 $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE
+       $(Q)mkdir -p $(dir $@)
        $(call if_changed_dep,bootas)
 
 $(obj)/wrapper.a: $(obj-wlib) FORCE
index f61fcdab1c7c59bf0f649f1e0e434a06431b6612..e634359d98e9375ce66570f2d7b2c4daff2be2fc 100644 (file)
@@ -42,6 +42,6 @@ void bamboo_init(void *mac0, void *mac1)
        platform_ops.exit = ibm44x_dbcr_reset;
        bamboo_mac0 = mac0;
        bamboo_mac1 = mac1;
-       ft_init(_dtb_start, 0, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
 }
index 9256a26d40e4c8f1033d72f976bd961f619e77ea..a8611546a656338820ffb2d83448c03954f331cb 100644 (file)
@@ -53,7 +53,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
 {
        CUBOOT_INIT();
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
        platform_ops.fixups = platform_fixups;
 }
index a0505509abcc40ed3eff8121e8a8b56f4e40bdf0..acd860ed7393222fbcbbe469d5ce39ec55d55140 100644 (file)
@@ -52,7 +52,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
 {
        CUBOOT_INIT();
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
        platform_ops.fixups = platform_fixups;
 }
index 345dcbecef0fc81d14a41e1d14bf85bec2410afb..943779ed19be08f3988559ad305fe4125f3b3f26 100644 (file)
@@ -53,7 +53,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
 {
        CUBOOT_INIT();
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
        platform_ops.fixups = platform_fixups;
 }
index 0e82015a5f95d42add314aa7e5c6fb3cbaa0b0aa..c202c8868bd6df3b3ad5e448e0d983dc0036098f 100644 (file)
@@ -41,7 +41,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
 {
        CUBOOT_INIT();
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
        platform_ops.fixups = platform_fixups;
 }
index d333898bca308fa41985537f1491a99f1b296edc..1b8953259d75d39ad6d464c47f977c05bb47b293 100644 (file)
@@ -42,7 +42,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                unsigned long r6, unsigned long r7)
 {
        CUBOOT_INIT();
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
        platform_ops.fixups = platform_fixups;
 }
index 61574f3272ddb9f8429f30b6c533e91e5c408de0..f56ac6cae9f3b291c1744a21958dc27d2e487a28 100644 (file)
@@ -255,7 +255,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
 {
        CUBOOT_INIT();
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
        platform_ops.fixups = pq2_platform_fixups;
 }
index ec635e0bd4ec240630a585421aa04759a92f8d74..cf78260fcf3f584e50787bb03d4423926691c58e 100644 (file)
@@ -51,6 +51,6 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
        CUBOOT_INIT();
        platform_ops.fixups = sequoia_fixups;
        platform_ops.exit = ibm44x_dbcr_reset;
-       ft_init(_dtb_start, 0, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
 }
index 86c0f5df0a86358925d3d0b8c19b91c79a3fa5e5..ee31be5e633e108a4d0d20e207d340ddcee84214 100644 (file)
@@ -146,6 +146,6 @@ void ebony_init(void *mac0, void *mac1)
        platform_ops.exit = ibm44x_dbcr_reset;
        ebony_mac0 = mac0;
        ebony_mac1 = mac1;
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
 }
index 6b87cdce3fe7312cc6d3e45ac55d4136e23a66c1..a400f540715541ba550a973febe007e9e0a57712 100644 (file)
@@ -45,7 +45,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
        mem_size *= 1024 * 1024;
        simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
 
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
 
        planetcore_set_stdout_path(table);
 
index 199e783aea4d3c3fa4a71ef995203f86174a88ed..58013b923178e38b8675121c1f48c34395d73a95 100644 (file)
@@ -28,6 +28,6 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
        u32 heapsize = 0x8000000 - (u32)_end; /* 128M */
 
        simple_alloc_init(_end, heapsize, 32, 64);
-       ft_init(_dtb_start, 0, 4);
+       fdt_init(_dtb_start);
        serial_console_init();
 }
diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c
new file mode 100644 (file)
index 0000000..002da16
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * This file does the necessary interface mapping between the bootwrapper
+ * device tree operations and the interface provided by shared source
+ * files flatdevicetree.[ch].
+ *
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * This library 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 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 <stddef.h>
+#include <stdio.h>
+#include <page.h>
+#include <libfdt.h>
+#include "ops.h"
+
+#define DEBUG  0
+#define BAD_ERROR(err) (((err) < 0) \
+                        && ((err) != -FDT_ERR_NOTFOUND) \
+                        && ((err) != -FDT_ERR_EXISTS))
+
+#define check_err(err) \
+       ({ \
+               if (BAD_ERROR(err) || ((err < 0) && DEBUG)) \
+                       printf("%s():%d  %s\n\r", __FUNCTION__, __LINE__, \
+                              fdt_strerror(err)); \
+               if (BAD_ERROR(err)) \
+                       exit(); \
+               (err < 0) ? -1 : 0; \
+       })
+
+#define offset_devp(off)       \
+       ({ \
+               int offset = (off); \
+               check_err(offset) ? NULL : (void *)(offset+1); \
+       })
+
+#define devp_offset(devp)      (((int)(devp))-1)
+
+static void *fdt;
+static void *buf; /* = NULL */
+
+#define EXPAND_GRANULARITY     1024
+
+static void expand_buf(int minexpand)
+{
+       int size = fdt_totalsize(fdt);
+       int rc;
+
+       size = _ALIGN(size + minexpand, EXPAND_GRANULARITY);
+       buf = platform_ops.realloc(buf, size);
+       if (!buf)
+               fatal("Couldn't find %d bytes to expand device tree\n\r", size);
+       rc = fdt_open_into(fdt, buf, size);
+       if (rc != 0)
+               fatal("Couldn't expand fdt into new buffer: %s\n\r",
+                     fdt_strerror(rc));
+
+       fdt = buf;
+}
+
+static void *fdt_wrapper_finddevice(const char *path)
+{
+       return offset_devp(fdt_path_offset(fdt, path));
+}
+
+static int fdt_wrapper_getprop(const void *devp, const char *name,
+                              void *buf, const int buflen)
+{
+       const void *p;
+       int len;
+
+       p = fdt_getprop(fdt, devp_offset(devp), name, &len);
+       if (!p)
+               return check_err(len);
+       memcpy(buf, p, min(len, buflen));
+       return len;
+}
+
+static int fdt_wrapper_setprop(const void *devp, const char *name,
+                              const void *buf, const int len)
+{
+       int rc;
+
+       rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
+       if (rc == -FDT_ERR_NOSPACE) {
+               expand_buf(len + 16);
+               rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
+       }
+
+       return check_err(rc);
+}
+
+static void *fdt_wrapper_get_parent(const void *devp)
+{
+       return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
+}
+
+static void *fdt_wrapper_create_node(const void *devp, const char *name)
+{
+       int offset;
+
+       offset = fdt_add_subnode(fdt, devp_offset(devp), name);
+       if (offset == -FDT_ERR_NOSPACE) {
+               expand_buf(strlen(name) + 16);
+               offset = fdt_add_subnode(fdt, devp_offset(devp), name);
+       }
+
+       return offset_devp(offset);
+}
+
+static void *fdt_wrapper_find_node_by_prop_value(const void *prev,
+                                                const char *name,
+                                                const char *val,
+                                                int len)
+{
+       return offset_devp(fdt_node_offset_by_prop_value(fdt, devp_offset(prev),
+                                                        name, val, len));
+}
+
+static char *fdt_wrapper_get_path(const void *devp, char *buf, int len)
+{
+       int rc;
+
+       rc = fdt_get_path(fdt, devp_offset(devp), buf, len);
+       if (check_err(rc))
+               return NULL;
+       return buf;
+}
+
+static unsigned long fdt_wrapper_finalize(void)
+{
+       int rc;
+
+       rc = fdt_pack(fdt);
+       if (rc != 0)
+               fatal("Couldn't pack flat tree: %s\n\r",
+                     fdt_strerror(rc));
+       return (unsigned long)fdt;
+}
+
+void fdt_init(void *blob)
+{
+       int err;
+
+       dt_ops.finddevice = fdt_wrapper_finddevice;
+       dt_ops.getprop = fdt_wrapper_getprop;
+       dt_ops.setprop = fdt_wrapper_setprop;
+       dt_ops.get_parent = fdt_wrapper_get_parent;
+       dt_ops.create_node = fdt_wrapper_create_node;
+       dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
+       dt_ops.get_path = fdt_wrapper_get_path;
+       dt_ops.finalize = fdt_wrapper_finalize;
+
+       /* Make sure the dt blob is the right version and so forth */
+       fdt = blob;
+       err = fdt_open_into(fdt, fdt, fdt_totalsize(blob));
+       if (err == -FDT_ERR_NOSPACE) {
+               int bufsize = fdt_totalsize(fdt) + 4;
+               buf = malloc(bufsize);
+               err = fdt_open_into(fdt, buf, bufsize);
+       }
+
+       if (err != 0)
+               fatal("fdt_init(): %s\n\r", fdt_strerror(err));
+
+       if (buf)
+               fdt = buf;
+}
diff --git a/arch/powerpc/boot/libfdt_env.h b/arch/powerpc/boot/libfdt_env.h
new file mode 100644 (file)
index 0000000..a4b0fc9
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
+#define _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
+
+#include <types.h>
+#include <string.h>
+
+typedef u32 uint32_t;
+typedef u64 uint64_t;
+
+#define fdt16_to_cpu(x)                (x)
+#define cpu_to_fdt16(x)                (x)
+#define fdt32_to_cpu(x)                (x)
+#define cpu_to_fdt32(x)                (x)
+#define fdt64_to_cpu(x)                (x)
+#define cpu_to_fdt64(x)                (x)
+
+#endif /* _ARCH_POWERPC_BOOT_LIBFDT_ENV_H */
index a180b6505f477c8e1422be0ba64eadeeed1d5ff5..28df2c5a97619c53f17dbbcfd80b61db3af3a5c0 100644 (file)
@@ -80,6 +80,7 @@ extern struct loader_info loader_info;
 
 void start(void);
 int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
+void fdt_init(void *blob);
 int serial_console_init(void);
 int ns16550_console_init(void *devp, struct serial_console_data *scdp);
 int mpsc_console_init(void *devp, struct serial_console_data *scdp);
index 9614e1db9daec7fca76586d8fd252ce556bd86ed..05c3245b30d7472aa9e995b4919e06f3b75aabe0 100644 (file)
@@ -547,8 +547,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
        if (!dtb)
                exit();
        memmove(dtb, _dtb_start, dt_size);
-       if (ft_init(dtb, dt_size, 16))
-               exit();
+       fdt_init(dtb);
 
        bridge_base = mv64x60_get_bridge_base();
 
index d6661151b49426b86256e6d932b051f0129a27a1..3b0ac4d006ec857385e04e873487577b549ac6e5 100644 (file)
@@ -131,7 +131,7 @@ void platform_init(void)
        printf("\n-- PS3 bootwrapper --\n");
 
        simple_alloc_init(_end, heapsize, 32, 64);
-       ft_init(_dtb_start, 0, 4);
+       fdt_init(_dtb_start);
 
        chosen = finddevice("/chosen");
 
index bb2c309d70fcdafaf7b32c1495afe67daf6c7ea7..70ffce343c0a651e1f339e5e3c7548bed078e444 100644 (file)
@@ -128,6 +128,6 @@ void platform_init(void)
        simple_alloc_init(_end, avail_ram, 32, 32);
        platform_ops.fixups = walnut_fixups;
        platform_ops.exit = ibm40x_dbcr_reset;
-       ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+       fdt_init(_dtb_start);
        serial_console_init();
 }