aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/libfdt-wrapper.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2007-12-09 22:28:39 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-10 21:46:14 -0500
commit2f0dfeaa84a8eea56218b77ffc61ed3dd7181847 (patch)
treefe17563bf38c2cc92df7ae997f70ff788eb9fa6b /arch/powerpc/boot/libfdt-wrapper.c
parent1cade99497c881a8c719df561d1bdc96831ff040 (diff)
[POWERPC] Use embedded libfdt in the bootwrapper
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>
Diffstat (limited to 'arch/powerpc/boot/libfdt-wrapper.c')
-rw-r--r--arch/powerpc/boot/libfdt-wrapper.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c
new file mode 100644
index 000000000000..002da16c97c1
--- /dev/null
+++ b/arch/powerpc/boot/libfdt-wrapper.c
@@ -0,0 +1,182 @@
1/*
2 * This file does the necessary interface mapping between the bootwrapper
3 * device tree operations and the interface provided by shared source
4 * files flatdevicetree.[ch].
5 *
6 * Copyright 2007 David Gibson, IBM Corporation.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24#include <stddef.h>
25#include <stdio.h>
26#include <page.h>
27#include <libfdt.h>
28#include "ops.h"
29
30#define DEBUG 0
31#define BAD_ERROR(err) (((err) < 0) \
32 && ((err) != -FDT_ERR_NOTFOUND) \
33 && ((err) != -FDT_ERR_EXISTS))
34
35#define check_err(err) \
36 ({ \
37 if (BAD_ERROR(err) || ((err < 0) && DEBUG)) \
38 printf("%s():%d %s\n\r", __FUNCTION__, __LINE__, \
39 fdt_strerror(err)); \
40 if (BAD_ERROR(err)) \
41 exit(); \
42 (err < 0) ? -1 : 0; \
43 })
44
45#define offset_devp(off) \
46 ({ \
47 int offset = (off); \
48 check_err(offset) ? NULL : (void *)(offset+1); \
49 })
50
51#define devp_offset(devp) (((int)(devp))-1)
52
53static void *fdt;
54static void *buf; /* = NULL */
55
56#define EXPAND_GRANULARITY 1024
57
58static void expand_buf(int minexpand)
59{
60 int size = fdt_totalsize(fdt);
61 int rc;
62
63 size = _ALIGN(size + minexpand, EXPAND_GRANULARITY);
64 buf = platform_ops.realloc(buf, size);
65 if (!buf)
66 fatal("Couldn't find %d bytes to expand device tree\n\r", size);
67 rc = fdt_open_into(fdt, buf, size);
68 if (rc != 0)
69 fatal("Couldn't expand fdt into new buffer: %s\n\r",
70 fdt_strerror(rc));
71
72 fdt = buf;
73}
74
75static void *fdt_wrapper_finddevice(const char *path)
76{
77 return offset_devp(fdt_path_offset(fdt, path));
78}
79
80static int fdt_wrapper_getprop(const void *devp, const char *name,
81 void *buf, const int buflen)
82{
83 const void *p;
84 int len;
85
86 p = fdt_getprop(fdt, devp_offset(devp), name, &len);
87 if (!p)
88 return check_err(len);
89 memcpy(buf, p, min(len, buflen));
90 return len;
91}
92
93static int fdt_wrapper_setprop(const void *devp, const char *name,
94 const void *buf, const int len)
95{
96 int rc;
97
98 rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
99 if (rc == -FDT_ERR_NOSPACE) {
100 expand_buf(len + 16);
101 rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
102 }
103
104 return check_err(rc);
105}
106
107static void *fdt_wrapper_get_parent(const void *devp)
108{
109 return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
110}
111
112static void *fdt_wrapper_create_node(const void *devp, const char *name)
113{
114 int offset;
115
116 offset = fdt_add_subnode(fdt, devp_offset(devp), name);
117 if (offset == -FDT_ERR_NOSPACE) {
118 expand_buf(strlen(name) + 16);
119 offset = fdt_add_subnode(fdt, devp_offset(devp), name);
120 }
121
122 return offset_devp(offset);
123}
124
125static void *fdt_wrapper_find_node_by_prop_value(const void *prev,
126 const char *name,
127 const char *val,
128 int len)
129{
130 return offset_devp(fdt_node_offset_by_prop_value(fdt, devp_offset(prev),
131 name, val, len));
132}
133
134static char *fdt_wrapper_get_path(const void *devp, char *buf, int len)
135{
136 int rc;
137
138 rc = fdt_get_path(fdt, devp_offset(devp), buf, len);
139 if (check_err(rc))
140 return NULL;
141 return buf;
142}
143
144static unsigned long fdt_wrapper_finalize(void)
145{
146 int rc;
147
148 rc = fdt_pack(fdt);
149 if (rc != 0)
150 fatal("Couldn't pack flat tree: %s\n\r",
151 fdt_strerror(rc));
152 return (unsigned long)fdt;
153}
154
155void fdt_init(void *blob)
156{
157 int err;
158
159 dt_ops.finddevice = fdt_wrapper_finddevice;
160 dt_ops.getprop = fdt_wrapper_getprop;
161 dt_ops.setprop = fdt_wrapper_setprop;
162 dt_ops.get_parent = fdt_wrapper_get_parent;
163 dt_ops.create_node = fdt_wrapper_create_node;
164 dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
165 dt_ops.get_path = fdt_wrapper_get_path;
166 dt_ops.finalize = fdt_wrapper_finalize;
167
168 /* Make sure the dt blob is the right version and so forth */
169 fdt = blob;
170 err = fdt_open_into(fdt, fdt, fdt_totalsize(blob));
171 if (err == -FDT_ERR_NOSPACE) {
172 int bufsize = fdt_totalsize(fdt) + 4;
173 buf = malloc(bufsize);
174 err = fdt_open_into(fdt, buf, bufsize);
175 }
176
177 if (err != 0)
178 fatal("fdt_init(): %s\n\r", fdt_strerror(err));
179
180 if (buf)
181 fdt = buf;
182}