Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
cfa4c9d8
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cfa4c9d8
编写于
11月 23, 2007
作者:
W
Wolfgang Denk
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'testing' of
git://www.denx.de/git/u-boot-fdt
上级
98e2867c
91623528
变更
22
展开全部
隐藏空白更改
内联
并排
Showing
22 changed file
with
1793 addition
and
781 deletion
+1793
-781
board/cm5200/cm5200.c
board/cm5200/cm5200.c
+1
-1
board/freescale/mpc832xemds/pci.c
board/freescale/mpc832xemds/pci.c
+1
-1
board/freescale/mpc8349emds/pci.c
board/freescale/mpc8349emds/pci.c
+2
-2
board/freescale/mpc8349itx/pci.c
board/freescale/mpc8349itx/pci.c
+2
-2
board/freescale/mpc8360emds/pci.c
board/freescale/mpc8360emds/pci.c
+1
-1
common/cmd_fdt.c
common/cmd_fdt.c
+44
-32
common/fdt_support.c
common/fdt_support.c
+161
-22
cpu/mpc5xxx/cpu.c
cpu/mpc5xxx/cpu.c
+9
-31
cpu/mpc8260/cpu.c
cpu/mpc8260/cpu.c
+4
-26
cpu/mpc83xx/cpu.c
cpu/mpc83xx/cpu.c
+2
-2
cpu/mpc83xx/pci.c
cpu/mpc83xx/pci.c
+2
-2
include/fdt.h
include/fdt.h
+16
-35
include/fdt_support.h
include/fdt_support.h
+16
-0
include/libfdt.h
include/libfdt.h
+641
-74
libfdt/Makefile
libfdt/Makefile
+1
-1
libfdt/fdt.c
libfdt/fdt.c
+84
-18
libfdt/fdt_ro.c
libfdt/fdt_ro.c
+391
-344
libfdt/fdt_rw.c
libfdt/fdt_rw.c
+197
-74
libfdt/fdt_strerror.c
libfdt/fdt_strerror.c
+43
-16
libfdt/fdt_sw.c
libfdt/fdt_sw.c
+62
-35
libfdt/fdt_wip.c
libfdt/fdt_wip.c
+48
-46
libfdt/libfdt_internal.h
libfdt/libfdt_internal.h
+65
-16
未找到文件。
board/cm5200/cm5200.c
浏览文件 @
cfa4c9d8
...
...
@@ -276,7 +276,7 @@ static void ft_blob_update(void *blob, bd_t *bd)
memory_data
[
0
]
=
cpu_to_be32
(
bd
->
bi_memstart
);
memory_data
[
1
]
=
cpu_to_be32
(
bd
->
bi_memsize
);
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/memory"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/memory"
);
if
(
nodeoffset
>=
0
)
{
ret
=
fdt_setprop
(
blob
,
nodeoffset
,
"reg"
,
memory_data
,
sizeof
(
memory_data
));
...
...
board/freescale/mpc832xemds/pci.c
浏览文件 @
cfa4c9d8
...
...
@@ -269,7 +269,7 @@ ft_pci_setup(void *blob, bd_t *bd)
int
err
;
int
tmp
[
2
];
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
hose
[
0
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
hose
[
0
].
last_busno
);
...
...
board/freescale/mpc8349emds/pci.c
浏览文件 @
cfa4c9d8
...
...
@@ -396,7 +396,7 @@ ft_pci_setup(void *blob, bd_t *bd)
int
err
;
int
tmp
[
2
];
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
pci_hose
[
0
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
pci_hose
[
0
].
last_busno
);
...
...
@@ -408,7 +408,7 @@ ft_pci_setup(void *blob, bd_t *bd)
tmp
,
sizeof
(
tmp
[
0
]));
}
#ifdef CONFIG_MPC83XX_PCI2
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8600"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8600"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
pci_hose
[
1
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
pci_hose
[
1
].
last_busno
);
...
...
board/freescale/mpc8349itx/pci.c
浏览文件 @
cfa4c9d8
...
...
@@ -342,7 +342,7 @@ ft_pci_setup(void *blob, bd_t *bd)
int
err
;
int
tmp
[
2
];
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
pci_hose
[
0
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
pci_hose
[
0
].
last_busno
);
...
...
@@ -354,7 +354,7 @@ ft_pci_setup(void *blob, bd_t *bd)
tmp
,
sizeof
(
tmp
[
0
]));
}
#ifdef CONFIG_MPC83XX_PCI2
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
pci_hose
[
1
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
pci_hose
[
1
].
last_busno
);
...
...
board/freescale/mpc8360emds/pci.c
浏览文件 @
cfa4c9d8
...
...
@@ -269,7 +269,7 @@ ft_pci_setup(void *blob, bd_t *bd)
int
err
;
int
tmp
[
2
];
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
hose
[
0
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
hose
[
0
].
last_busno
);
...
...
common/cmd_fdt.c
浏览文件 @
cfa4c9d8
...
...
@@ -44,7 +44,7 @@ DECLARE_GLOBAL_DATA_PTR;
static
int
fdt_valid
(
void
);
static
int
fdt_parse_prop
(
char
*
pathp
,
char
*
prop
,
char
*
newval
,
char
*
data
,
int
*
len
);
static
int
fdt_print
(
char
*
pathp
,
char
*
prop
,
int
depth
);
static
int
fdt_print
(
c
onst
c
har
*
pathp
,
char
*
prop
,
int
depth
);
/*
* Flattened Device Tree command, see the help for parameter definitions.
...
...
@@ -75,7 +75,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
/*
* Optional new length
*/
len
=
simple_strtoul
(
argv
[
3
],
NULL
,
16
);
len
=
simple_strtoul
(
argv
[
3
],
NULL
,
16
);
if
(
len
<
fdt_totalsize
(
fdt
))
{
printf
(
"New length %d < existing length %d, "
"ignoring.
\n
"
,
...
...
@@ -162,12 +162,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
pathp
=
argv
[
2
];
nodep
=
argv
[
3
];
nodeoffset
=
fdt_
find_node_by_path
(
fdt
,
pathp
);
nodeoffset
=
fdt_
path_offset
(
fdt
,
pathp
);
if
(
nodeoffset
<
0
)
{
/*
* Not found or something else bad happened.
*/
printf
(
"libfdt fdt_
find_node_by_path
() returned %s
\n
"
,
printf
(
"libfdt fdt_
path_offset
() returned %s
\n
"
,
fdt_strerror
(
nodeoffset
));
return
1
;
}
...
...
@@ -202,12 +202,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
prop
=
argv
[
3
];
newval
=
argv
[
4
];
nodeoffset
=
fdt_
find_node_by_path
(
fdt
,
pathp
);
nodeoffset
=
fdt_
path_offset
(
fdt
,
pathp
);
if
(
nodeoffset
<
0
)
{
/*
* Not found or something else bad happened.
*/
printf
(
"libfdt fdt_
find_node_by_path
() returned %s
\n
"
,
printf
(
"libfdt fdt_
path_offset
() returned %s
\n
"
,
fdt_strerror
(
nodeoffset
));
return
1
;
}
...
...
@@ -229,6 +229,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
char
*
pathp
;
/* path */
char
*
prop
;
/* property */
int
ret
;
/* return value */
static
char
root
[
2
]
=
"/"
;
/*
* list is an alias for print, but limited to 1 level
...
...
@@ -241,7 +242,10 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
* Get the starting path. The root node is an oddball,
* the offset is zero and has no name.
*/
pathp
=
argv
[
2
];
if
(
argc
==
2
)
pathp
=
root
;
else
pathp
=
argv
[
2
];
if
(
argc
>
3
)
prop
=
argv
[
3
];
else
...
...
@@ -262,12 +266,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
* Get the path. The root node is an oddball, the offset
* is zero and has no name.
*/
nodeoffset
=
fdt_
find_node_by_path
(
fdt
,
argv
[
2
]);
nodeoffset
=
fdt_
path_offset
(
fdt
,
argv
[
2
]);
if
(
nodeoffset
<
0
)
{
/*
* Not found or something else bad happened.
*/
printf
(
"libfdt fdt_
find_node_by_path
() returned %s
\n
"
,
printf
(
"libfdt fdt_
path_offset
() returned %s
\n
"
,
fdt_strerror
(
nodeoffset
));
return
1
;
}
...
...
@@ -518,21 +522,21 @@ static void print_data(const void *data, int len)
switch
(
len
)
{
case
1
:
/* byte */
printf
(
"<%02x>"
,
(
*
(
u8
*
)
data
)
&
0xff
);
printf
(
"<
0x
%02x>"
,
(
*
(
u8
*
)
data
)
&
0xff
);
break
;
case
2
:
/* half-word */
printf
(
"<%04x>"
,
be16_to_cpu
(
*
(
u16
*
)
data
)
&
0xffff
);
printf
(
"<
0x
%04x>"
,
be16_to_cpu
(
*
(
u16
*
)
data
)
&
0xffff
);
break
;
case
4
:
/* word */
printf
(
"<%08x>"
,
be32_to_cpu
(
*
(
u32
*
)
data
)
&
0xffffffffU
);
printf
(
"<
0x
%08x>"
,
be32_to_cpu
(
*
(
u32
*
)
data
)
&
0xffffffffU
);
break
;
case
8
:
/* double-word */
#if __WORDSIZE == 64
printf
(
"<%016llx>"
,
be64_to_cpu
(
*
(
uint64_t
*
)
data
));
printf
(
"<
0x
%016llx>"
,
be64_to_cpu
(
*
(
uint64_t
*
)
data
));
#else
printf
(
"<%08x "
,
be32_to_cpu
(
*
(
u32
*
)
data
)
&
0xffffffffU
);
printf
(
"<
0x
%08x "
,
be32_to_cpu
(
*
(
u32
*
)
data
)
&
0xffffffffU
);
data
+=
4
;
printf
(
"%08x>"
,
be32_to_cpu
(
*
(
u32
*
)
data
)
&
0xffffffffU
);
printf
(
"
0x
%08x>"
,
be32_to_cpu
(
*
(
u32
*
)
data
)
&
0xffffffffU
);
#endif
break
;
default:
/* anything else... hexdump */
...
...
@@ -551,25 +555,25 @@ static void print_data(const void *data, int len)
* Recursively print (a portion of) the fdt. The depth parameter
* determines how deeply nested the fdt is printed.
*/
static
int
fdt_print
(
char
*
pathp
,
char
*
prop
,
int
depth
)
static
int
fdt_print
(
c
onst
c
har
*
pathp
,
char
*
prop
,
int
depth
)
{
static
int
offstack
[
MAX_LEVEL
];
static
char
tabs
[
MAX_LEVEL
+
1
]
=
"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t
"
"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t
"
;
void
*
nodep
;
/* property node pointer */
const
void
*
nodep
;
/* property node pointer */
int
nodeoffset
;
/* node offset from libfdt */
int
nextoffset
;
/* next node offset from libfdt */
uint32_t
tag
;
/* tag */
int
len
;
/* length of the property */
int
level
=
0
;
/* keep track of nesting level */
const
struct
fdt_property
*
fdt_prop
;
nodeoffset
=
fdt_
find_node_by_path
(
fdt
,
pathp
);
nodeoffset
=
fdt_
path_offset
(
fdt
,
pathp
);
if
(
nodeoffset
<
0
)
{
/*
* Not found or something else bad happened.
*/
printf
(
"libfdt fdt_
find_node_by_path
() returned %s
\n
"
,
printf
(
"libfdt fdt_
path_offset
() returned %s
\n
"
,
fdt_strerror
(
nodeoffset
));
return
1
;
}
...
...
@@ -599,45 +603,52 @@ static int fdt_print(char *pathp, char *prop, int depth)
* The user passed in a node path and no property,
* print the node and all subnodes.
*/
offstack
[
0
]
=
nodeoffset
;
while
(
level
>=
0
)
{
tag
=
fdt_next_tag
(
fdt
,
nodeoffset
,
&
nextoffset
,
&
pathp
);
tag
=
fdt_next_tag
(
fdt
,
nodeoffset
,
&
nextoffset
);
switch
(
tag
)
{
case
FDT_BEGIN_NODE
:
if
(
level
<=
depth
)
pathp
=
fdt_get_name
(
fdt
,
nodeoffset
,
NULL
);
if
(
level
<=
depth
)
{
if
(
pathp
==
NULL
)
pathp
=
"/* NULL pointer error */"
;
if
(
*
pathp
==
'\0'
)
pathp
=
"/"
;
/* root is nameless */
printf
(
"%s%s {
\n
"
,
&
tabs
[
MAX_LEVEL
-
level
],
pathp
);
}
level
++
;
offstack
[
level
]
=
nodeoffset
;
if
(
level
>=
MAX_LEVEL
)
{
printf
(
"Aaaiii <splat> nested too deep. "
"Aborting.
\n
"
);
printf
(
"Nested too deep, aborting.
\n
"
);
return
1
;
}
break
;
case
FDT_END_NODE
:
level
--
;
if
(
level
<=
depth
)
if
(
level
<=
depth
)
printf
(
"%s};
\n
"
,
&
tabs
[
MAX_LEVEL
-
level
]);
if
(
level
==
0
)
{
level
=
-
1
;
/* exit the loop */
}
break
;
case
FDT_PROP
:
nodep
=
fdt_getprop
(
fdt
,
offstack
[
level
],
pathp
,
&
len
);
fdt_prop
=
fdt_offset_ptr
(
fdt
,
nodeoffset
,
sizeof
(
*
fdt_prop
));
pathp
=
fdt_string
(
fdt
,
fdt32_to_cpu
(
fdt_prop
->
nameoff
));
len
=
fdt32_to_cpu
(
fdt_prop
->
len
);
nodep
=
fdt_prop
->
data
;
if
(
len
<
0
)
{
printf
(
"libfdt fdt_getprop(): %s
\n
"
,
fdt_strerror
(
len
));
return
1
;
}
else
if
(
len
==
0
)
{
/* the property has no value */
if
(
level
<=
depth
)
if
(
level
<=
depth
)
printf
(
"%s%s;
\n
"
,
&
tabs
[
MAX_LEVEL
-
level
],
pathp
);
}
else
{
if
(
level
<=
depth
)
{
if
(
level
<=
depth
)
{
printf
(
"%s%s="
,
&
tabs
[
MAX_LEVEL
-
level
],
pathp
);
...
...
@@ -647,11 +658,12 @@ static int fdt_print(char *pathp, char *prop, int depth)
}
break
;
case
FDT_NOP
:
printf
(
"/* NOP */
\n
"
,
&
tabs
[
MAX_LEVEL
-
level
]);
break
;
case
FDT_END
:
return
1
;
default:
if
(
level
<=
depth
)
if
(
level
<=
depth
)
printf
(
"Unknown tag 0x%08X
\n
"
,
tag
);
return
1
;
}
...
...
common/fdt_support.c
浏览文件 @
cfa4c9d8
...
...
@@ -44,6 +44,32 @@ struct fdt_header *fdt;
/********************************************************************/
/**
* fdt_find_and_setprop: Find a node and set it's property
*
* @fdt: ptr to device tree
* @node: path of node
* @prop: property name
* @val: ptr to new value
* @len: length of new property value
* @create: flag to create the property if it doesn't exist
*
* Convenience function to directly set a property given the path to the node.
*/
int
fdt_find_and_setprop
(
void
*
fdt
,
const
char
*
node
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
)
{
int
nodeoff
=
fdt_path_offset
(
fdt
,
node
);
if
(
nodeoff
<
0
)
return
nodeoff
;
if
((
!
create
)
&&
(
fdt_get_property
(
fdt
,
nodeoff
,
prop
,
0
)
==
NULL
))
return
0
;
/* create flag not set; so exit quietly */
return
fdt_setprop
(
fdt
,
nodeoff
,
prop
,
val
,
len
);
}
int
fdt_chosen
(
void
*
fdt
,
ulong
initrd_start
,
ulong
initrd_end
,
int
force
)
{
int
nodeoffset
;
...
...
@@ -58,34 +84,23 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
}
if
(
initrd_start
&&
initrd_end
)
{
struct
fdt_reserve_entry
re
;
int
used
;
int
total
;
uint64_t
addr
,
size
;
int
total
=
fdt_num_mem_rsv
(
fdt
);
int
j
;
err
=
fdt_num_reservemap
(
fdt
,
&
used
,
&
total
);
if
(
err
<
0
)
{
printf
(
"fdt_chosen: %s
\n
"
,
fdt_strerror
(
err
));
return
err
;
}
if
(
used
>=
total
)
{
printf
(
"WARNING: "
"no room in the reserved map (%d of %d)
\n
"
,
used
,
total
);
return
-
1
;
}
/*
* Look for an existing entry and update it. If we don't find
* the entry, we will j be the next available slot.
*/
for
(
j
=
0
;
j
<
used
;
j
++
)
{
err
=
fdt_get_reservemap
(
fdt
,
j
,
&
re
);
if
(
re
.
address
==
initrd_start
)
{
for
(
j
=
0
;
j
<
total
;
j
++
)
{
err
=
fdt_get_mem_rsv
(
fdt
,
j
,
&
addr
,
&
size
);
if
(
addr
==
initrd_start
)
{
fdt_del_mem_rsv
(
fdt
,
j
);
break
;
}
}
err
=
fdt_replace_reservemap_entry
(
fdt
,
j
,
initrd_start
,
initrd_end
-
initrd_start
+
1
);
err
=
fdt_add_mem_rsv
(
fdt
,
initrd_start
,
initrd_end
-
initrd_start
+
1
);
if
(
err
<
0
)
{
printf
(
"fdt_chosen: %s
\n
"
,
fdt_strerror
(
err
));
return
err
;
...
...
@@ -95,7 +110,7 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
/*
* Find the "chosen" node.
*/
nodeoffset
=
fdt_
find_node_by_path
(
fdt
,
"/chosen"
);
nodeoffset
=
fdt_
path_offset
(
fdt
,
"/chosen"
);
/*
* If we have a "chosen" node already the "force the writing"
...
...
@@ -182,7 +197,7 @@ int fdt_env(void *fdt)
* See if we already have a "u-boot-env" node, delete it if so.
* Then create a new empty node.
*/
nodeoffset
=
fdt_
find_node_by_path
(
fdt
,
"/u-boot-env"
);
nodeoffset
=
fdt_
path_offset
(
fdt
,
"/u-boot-env"
);
if
(
nodeoffset
>=
0
)
{
err
=
fdt_del_node
(
fdt
,
nodeoffset
);
if
(
err
<
0
)
{
...
...
@@ -304,7 +319,7 @@ int fdt_bd_t(void *fdt)
* See if we already have a "bd_t" node, delete it if so.
* Then create a new empty node.
*/
nodeoffset
=
fdt_
find_node_by_path
(
fdt
,
"/bd_t"
);
nodeoffset
=
fdt_
path_offset
(
fdt
,
"/bd_t"
);
if
(
nodeoffset
>=
0
)
{
err
=
fdt_del_node
(
fdt
,
nodeoffset
);
if
(
err
<
0
)
{
...
...
@@ -348,4 +363,128 @@ int fdt_bd_t(void *fdt)
}
#endif
/* ifdef CONFIG_OF_HAS_BD_T */
void
do_fixup_by_path
(
void
*
fdt
,
const
char
*
path
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
)
{
#if defined(DEBUG)
int
i
;
debug
(
"Updating property '%s/%s' = "
,
node
,
prop
);
for
(
i
=
0
;
i
<
len
;
i
++
)
debug
(
" %.2x"
,
*
(
u8
*
)(
val
+
i
));
debug
(
"
\n
"
);
#endif
int
rc
=
fdt_find_and_setprop
(
fdt
,
path
,
prop
,
val
,
len
,
create
);
if
(
rc
)
printf
(
"Unable to update property %s:%s, err=%s
\n
"
,
path
,
prop
,
fdt_strerror
(
rc
));
}
void
do_fixup_by_path_u32
(
void
*
fdt
,
const
char
*
path
,
const
char
*
prop
,
u32
val
,
int
create
)
{
val
=
cpu_to_fdt32
(
val
);
do_fixup_by_path
(
fdt
,
path
,
prop
,
&
val
,
sizeof
(
val
),
create
);
}
void
do_fixup_by_prop
(
void
*
fdt
,
const
char
*
pname
,
const
void
*
pval
,
int
plen
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
)
{
int
off
;
#if defined(DEBUG)
int
i
;
debug
(
"Updating property '%s/%s' = "
,
node
,
prop
);
for
(
i
=
0
;
i
<
len
;
i
++
)
debug
(
" %.2x"
,
*
(
u8
*
)(
val
+
i
));
debug
(
"
\n
"
);
#endif
off
=
fdt_node_offset_by_prop_value
(
fdt
,
-
1
,
pname
,
pval
,
plen
);
while
(
off
!=
-
FDT_ERR_NOTFOUND
)
{
if
(
create
||
(
fdt_get_property
(
fdt
,
off
,
prop
,
0
)
!=
NULL
))
fdt_setprop
(
fdt
,
off
,
prop
,
val
,
len
);
off
=
fdt_node_offset_by_prop_value
(
fdt
,
off
,
pname
,
pval
,
plen
);
}
}
void
do_fixup_by_prop_u32
(
void
*
fdt
,
const
char
*
pname
,
const
void
*
pval
,
int
plen
,
const
char
*
prop
,
u32
val
,
int
create
)
{
val
=
cpu_to_fdt32
(
val
);
do_fixup_by_prop
(
fdt
,
pname
,
pval
,
plen
,
prop
,
&
val
,
4
,
create
);
}
void
do_fixup_by_compat
(
void
*
fdt
,
const
char
*
compat
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
)
{
int
off
=
-
1
;
#if defined(DEBUG)
int
i
;
debug
(
"Updating property '%s/%s' = "
,
node
,
prop
);
for
(
i
=
0
;
i
<
len
;
i
++
)
debug
(
" %.2x"
,
*
(
u8
*
)(
val
+
i
));
debug
(
"
\n
"
);
#endif
off
=
fdt_node_offset_by_compatible
(
fdt
,
-
1
,
compat
);
while
(
off
!=
-
FDT_ERR_NOTFOUND
)
{
if
(
create
||
(
fdt_get_property
(
fdt
,
off
,
prop
,
0
)
!=
NULL
))
fdt_setprop
(
fdt
,
off
,
prop
,
val
,
len
);
off
=
fdt_node_offset_by_compatible
(
fdt
,
off
,
compat
);
}
}
void
do_fixup_by_compat_u32
(
void
*
fdt
,
const
char
*
compat
,
const
char
*
prop
,
u32
val
,
int
create
)
{
val
=
cpu_to_fdt32
(
val
);
do_fixup_by_compat
(
fdt
,
compat
,
prop
,
&
val
,
4
,
create
);
}
void
fdt_fixup_ethernet
(
void
*
fdt
,
bd_t
*
bd
)
{
int
node
;
const
char
*
path
;
node
=
fdt_path_offset
(
fdt
,
"/aliases"
);
if
(
node
>=
0
)
{
#if defined(CONFIG_HAS_ETH0)
path
=
fdt_getprop
(
fdt
,
node
,
"ethernet0"
,
NULL
);
if
(
path
)
{
do_fixup_by_path
(
fdt
,
path
,
"mac-address"
,
bd
->
bi_enetaddr
,
6
,
0
);
do_fixup_by_path
(
fdt
,
path
,
"local-mac-address"
,
bd
->
bi_enetaddr
,
6
,
1
);
}
#endif
#if defined(CONFIG_HAS_ETH1)
path
=
fdt_getprop
(
fdt
,
node
,
"ethernet1"
,
NULL
);
if
(
path
)
{
do_fixup_by_path
(
fdt
,
path
,
"mac-address"
,
bd
->
bi_enet1addr
,
6
,
0
);
do_fixup_by_path
(
fdt
,
path
,
"local-mac-address"
,
bd
->
bi_enet1addr
,
6
,
1
);
}
#endif
#if defined(CONFIG_HAS_ETH2)
path
=
fdt_getprop
(
fdt
,
node
,
"ethernet2"
,
NULL
);
if
(
path
)
{
do_fixup_by_path
(
fdt
,
path
,
"mac-address"
,
bd
->
bi_enet2addr
,
6
,
0
);
do_fixup_by_path
(
fdt
,
path
,
"local-mac-address"
,
bd
->
bi_enet2addr
,
6
,
1
);
}
#endif
#if defined(CONFIG_HAS_ETH3)
path
=
fdt_getprop
(
fdt
,
node
,
"ethernet3"
,
NULL
);
if
(
path
)
{
do_fixup_by_path
(
fdt
,
path
,
"mac-address"
,
bd
->
bi_enet3addr
,
6
,
0
);
do_fixup_by_path
(
fdt
,
path
,
"local-mac-address"
,
bd
->
bi_enet3addr
,
6
,
1
);
}
#endif
}
}
#endif
/* CONFIG_OF_LIBFDT */
cpu/mpc5xxx/cpu.c
浏览文件 @
cfa4c9d8
...
...
@@ -35,6 +35,7 @@
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
#include <libfdt_env.h>
#include <fdt_support.h>
#endif
DECLARE_GLOBAL_DATA_PTR
;
...
...
@@ -114,42 +115,19 @@ unsigned long get_tbclk (void)
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_OF_LIBFDT
static
void
do_fixup
(
void
*
fdt
,
const
char
*
node
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
)
{
#if defined(DEBUG)
int
i
;
debug
(
"Updating property '%s/%s' = "
,
node
,
prop
);
for
(
i
=
0
;
i
<
len
;
i
++
)
debug
(
" %.2x"
,
*
(
u8
*
)(
val
+
i
));
debug
(
"
\n
"
);
#endif
int
rc
=
fdt_find_and_setprop
(
fdt
,
node
,
prop
,
val
,
len
,
create
);
if
(
rc
)
printf
(
"Unable to update property %s:%s, err=%s
\n
"
,
node
,
prop
,
fdt_strerror
(
rc
));
}
static
void
do_fixup_u32
(
void
*
fdt
,
const
char
*
node
,
const
char
*
prop
,
u32
val
,
int
create
)
{
val
=
cpu_to_fdt32
(
val
);
do_fixup
(
fdt
,
node
,
prop
,
&
val
,
sizeof
(
val
),
create
);
}
void
ft_cpu_setup
(
void
*
blob
,
bd_t
*
bd
)
{
int
div
=
in_8
((
void
*
)
CFG_MBAR
+
0x204
)
&
0x0020
?
8
:
4
;
char
*
cpu_path
=
"/cpus/"
OF_CPU
;
char
*
eth_path
=
"/"
OF_SOC
"/ethernet@3000"
;
do_fixup_u32
(
blob
,
cpu_path
,
"timebase-frequency"
,
OF_TBCLK
,
1
);
do_fixup_u32
(
blob
,
cpu_path
,
"bus-frequency"
,
bd
->
bi_busfreq
,
1
);
do_fixup_u32
(
blob
,
cpu_path
,
"clock-frequency"
,
bd
->
bi_intfreq
,
1
);
do_fixup_u32
(
blob
,
"/"
OF_SOC
,
"bus-frequency"
,
bd
->
bi_ipbfreq
,
1
);
do_fixup_u32
(
blob
,
"/"
OF_SOC
,
"system-frequency"
,
bd
->
bi_busfreq
*
div
,
1
);
do_fixup
(
blob
,
eth_path
,
"mac-address"
,
bd
->
bi_enetaddr
,
6
,
0
);
do_fixup
(
blob
,
eth_path
,
"local-mac-address"
,
bd
->
bi_enetaddr
,
6
,
0
);
do_fixup_
by_path_
u32
(
blob
,
cpu_path
,
"timebase-frequency"
,
OF_TBCLK
,
1
);
do_fixup_
by_path_
u32
(
blob
,
cpu_path
,
"bus-frequency"
,
bd
->
bi_busfreq
,
1
);
do_fixup_
by_path_
u32
(
blob
,
cpu_path
,
"clock-frequency"
,
bd
->
bi_intfreq
,
1
);
do_fixup_
by_path_
u32
(
blob
,
"/"
OF_SOC
,
"bus-frequency"
,
bd
->
bi_ipbfreq
,
1
);
do_fixup_
by_path_
u32
(
blob
,
"/"
OF_SOC
,
"system-frequency"
,
bd
->
bi_busfreq
*
div
,
1
);
do_fixup
_by_path
(
blob
,
eth_path
,
"mac-address"
,
bd
->
bi_enetaddr
,
6
,
0
);
do_fixup
_by_path
(
blob
,
eth_path
,
"local-mac-address"
,
bd
->
bi_enetaddr
,
6
,
0
);
}
#endif
cpu/mpc8260/cpu.c
浏览文件 @
cfa4c9d8
...
...
@@ -50,6 +50,7 @@
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
#include <libfdt_env.h>
#include <fdt_support.h>
#endif
DECLARE_GLOBAL_DATA_PTR
;
...
...
@@ -300,35 +301,12 @@ void watchdog_reset (void)
/* ------------------------------------------------------------------------- */
#if defined(CONFIG_OF_LIBFDT)
static
void
do_fixup
(
void
*
fdt
,
const
char
*
node
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
)
{
#if defined(DEBUG)
int
i
;
debug
(
"Updating property '%s/%s' = "
,
node
,
prop
);
for
(
i
=
0
;
i
<
len
;
i
++
)
debug
(
" %.2x"
,
*
(
u8
*
)(
val
+
i
));
debug
(
"
\n
"
);
#endif
int
rc
=
fdt_find_and_setprop
(
fdt
,
node
,
prop
,
val
,
len
,
create
);
if
(
rc
)
printf
(
"Unable to update property %s:%s, err=%s
\n
"
,
node
,
prop
,
fdt_strerror
(
rc
));
}
static
void
do_fixup_u32
(
void
*
fdt
,
const
char
*
node
,
const
char
*
prop
,
u32
val
,
int
create
)
{
val
=
cpu_to_fdt32
(
val
);
do_fixup
(
fdt
,
node
,
prop
,
&
val
,
sizeof
(
val
),
create
);
}
void
ft_cpu_setup
(
void
*
blob
,
bd_t
*
bd
)
{
char
*
cpu_path
=
"/cpus/"
OF_CPU
;
do_fixup_u32
(
blob
,
cpu_path
,
"bus-frequency"
,
bd
->
bi_busfreq
,
1
);
do_fixup_u32
(
blob
,
cpu_path
,
"timebase-frequency"
,
OF_TBCLK
,
1
);
do_fixup_u32
(
blob
,
cpu_path
,
"clock-frequency"
,
bd
->
bi_intfreq
,
1
);
do_fixup_
by_path_
u32
(
blob
,
cpu_path
,
"bus-frequency"
,
bd
->
bi_busfreq
,
1
);
do_fixup_
by_path_
u32
(
blob
,
cpu_path
,
"timebase-frequency"
,
OF_TBCLK
,
1
);
do_fixup_
by_path_
u32
(
blob
,
cpu_path
,
"clock-frequency"
,
bd
->
bi_intfreq
,
1
);
}
#endif
/* CONFIG_OF_LIBFDT */
cpu/mpc83xx/cpu.c
浏览文件 @
cfa4c9d8
...
...
@@ -529,7 +529,7 @@ ft_cpu_setup(void *blob, bd_t *bd)
int
tmp
[
2
];
for
(
j
=
0
;
j
<
(
sizeof
(
fixup_props
)
/
sizeof
(
fixup_props
[
0
]));
j
++
)
{
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
fixup_props
[
j
].
node
);
nodeoffset
=
fdt_
path_offset
(
blob
,
fixup_props
[
j
].
node
);
if
(
nodeoffset
>=
0
)
{
err
=
fixup_props
[
j
].
set_fn
(
blob
,
nodeoffset
,
fixup_props
[
j
].
prop
,
bd
);
...
...
@@ -544,7 +544,7 @@ ft_cpu_setup(void *blob, bd_t *bd)
}
/* update, or add and update /memory node */
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/memory"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/memory"
);
if
(
nodeoffset
<
0
)
{
nodeoffset
=
fdt_add_subnode
(
blob
,
0
,
"memory"
);
if
(
nodeoffset
<
0
)
...
...
cpu/mpc83xx/pci.c
浏览文件 @
cfa4c9d8
...
...
@@ -179,7 +179,7 @@ void ft_pci_setup(void *blob, bd_t *bd)
if
(
pci_num_buses
<
1
)
return
;
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8500"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
pci_hose
[
0
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
pci_hose
[
0
].
last_busno
);
...
...
@@ -194,7 +194,7 @@ void ft_pci_setup(void *blob, bd_t *bd)
if
(
pci_num_buses
<
2
)
return
;
nodeoffset
=
fdt_
find_node_by_path
(
blob
,
"/"
OF_SOC
"/pci@8600"
);
nodeoffset
=
fdt_
path_offset
(
blob
,
"/"
OF_SOC
"/pci@8600"
);
if
(
nodeoffset
>=
0
)
{
tmp
[
0
]
=
cpu_to_be32
(
pci_hose
[
0
].
first_busno
);
tmp
[
1
]
=
cpu_to_be32
(
pci_hose
[
0
].
last_busno
);
...
...
include/fdt.h
浏览文件 @
cfa4c9d8
/*
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 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
*/
#ifndef _FDT_H
#define _FDT_H
#ifndef __ASSEMBLY__
struct
fdt_header
{
uint32_t
magic
;
/* magic word FDT_MAGIC */
uint32_t
totalsize
;
/* total size of DT block */
uint32_t
off_dt_struct
;
/* offset to structure */
uint32_t
off_dt_strings
;
/* offset to strings */
uint32_t
off_mem_rsvmap
;
/* offset to memory reserve map */
uint32_t
version
;
/* format version */
uint32_t
last_comp_version
;
/* last compatible version */
/* version 2 fields below */
uint32_t
boot_cpuid_phys
;
/* Which physical CPU id we're
uint32_t
magic
;
/* magic word FDT_MAGIC */
uint32_t
totalsize
;
/* total size of DT block */
uint32_t
off_dt_struct
;
/* offset to structure */
uint32_t
off_dt_strings
;
/* offset to strings */
uint32_t
off_mem_rsvmap
;
/* offset to memory reserve map */
uint32_t
version
;
/* format version */
uint32_t
last_comp_version
;
/* last compatible version */
/* version 2 fields below */
uint32_t
boot_cpuid_phys
;
/* Which physical CPU id we're
booting on */
/* version 3 fields below */
uint32_t
size_dt_strings
;
/* size of the strings block */
uint32_t
size_dt_strings
;
/* size of the strings block */
/* version 17 fields below */
uint32_t
size_dt_struct
;
/* size of the structure block */
uint32_t
size_dt_struct
;
/* size of the structure block */
};
struct
fdt_reserve_entry
{
...
...
@@ -60,12 +41,12 @@ struct fdt_property {
#endif
/* !__ASSEMBLY */
#define FDT_MAGIC 0xd00dfeed
/* 4: version, 4: total size */
#define FDT_MAGIC 0xd00dfeed
/* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(uint32_t)
#define FDT_BEGIN_NODE 0x1
/* Start node: full name */
#define FDT_END_NODE 0x2
/* End node */
#define FDT_PROP 0x3
/* Property: name off,
#define FDT_BEGIN_NODE 0x1
/* Start node: full name */
#define FDT_END_NODE 0x2
/* End node */
#define FDT_PROP 0x3
/* Property: name off,
size, content */
#define FDT_NOP 0x4
/* nop */
#define FDT_END 0x9
...
...
include/fdt_support.h
浏览文件 @
cfa4c9d8
...
...
@@ -29,6 +29,22 @@
#include <fdt.h>
int
fdt_chosen
(
void
*
fdt
,
ulong
initrd_start
,
ulong
initrd_end
,
int
force
);
void
do_fixup_by_path
(
void
*
fdt
,
const
char
*
path
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
);
void
do_fixup_by_path_u32
(
void
*
fdt
,
const
char
*
path
,
const
char
*
prop
,
u32
val
,
int
create
);
void
do_fixup_by_prop
(
void
*
fdt
,
const
char
*
pname
,
const
void
*
pval
,
int
plen
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
);
void
do_fixup_by_prop_u32
(
void
*
fdt
,
const
char
*
pname
,
const
void
*
pval
,
int
plen
,
const
char
*
prop
,
u32
val
,
int
create
);
void
do_fixup_by_compat
(
void
*
fdt
,
const
char
*
compat
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
);
void
do_fixup_by_compat_u32
(
void
*
fdt
,
const
char
*
compat
,
const
char
*
prop
,
u32
val
,
int
create
);
void
fdt_fixup_ethernet
(
void
*
fdt
,
bd_t
*
bd
);
#ifdef CONFIG_OF_HAS_UBOOT_ENV
int
fdt_env
(
void
*
fdt
);
...
...
include/libfdt.h
浏览文件 @
cfa4c9d8
此差异已折叠。
点击以展开。
libfdt/Makefile
浏览文件 @
cfa4c9d8
...
...
@@ -27,7 +27,7 @@ LIB = $(obj)libfdt.a
SOBJS
=
COBJS-
y
+=
fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
COBJS-
$(CONFIG_OF_LIBFDT)
+=
fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
COBJS
:=
$
(
COBJS-y
)
SRCS
:=
$(SOBJS:.o=.S)
$(COBJS:.o=.c)
...
...
libfdt/fdt.c
浏览文件 @
cfa4c9d8
...
...
@@ -2,23 +2,52 @@
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 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.
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
*
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
.
*
a) 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
.
*
* 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
* 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
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if CONFIG_OF_LIBFDT
#include "libfdt_env.h"
#include <fdt.h>
...
...
@@ -45,9 +74,9 @@ int fdt_check_header(const void *fdt)
return
0
;
}
void
*
fdt_offset_ptr
(
const
void
*
fdt
,
int
offset
,
int
len
)
const
void
*
fdt_offset_ptr
(
const
void
*
fdt
,
int
offset
,
int
len
)
{
void
*
p
;
const
void
*
p
;
if
(
fdt_version
(
fdt
)
>=
0x11
)
if
(((
offset
+
len
)
<
offset
)
...
...
@@ -61,6 +90,45 @@ void *fdt_offset_ptr(const void *fdt, int offset, int len)
return
p
;
}
uint32_t
fdt_next_tag
(
const
void
*
fdt
,
int
offset
,
int
*
nextoffset
)
{
const
uint32_t
*
tagp
,
*
lenp
;
uint32_t
tag
;
const
char
*
p
;
if
(
offset
%
FDT_TAGSIZE
)
return
-
1
;
tagp
=
fdt_offset_ptr
(
fdt
,
offset
,
FDT_TAGSIZE
);
if
(
!
tagp
)
return
FDT_END
;
/* premature end */
tag
=
fdt32_to_cpu
(
*
tagp
);
offset
+=
FDT_TAGSIZE
;
switch
(
tag
)
{
case
FDT_BEGIN_NODE
:
/* skip name */
do
{
p
=
fdt_offset_ptr
(
fdt
,
offset
++
,
1
);
}
while
(
p
&&
(
*
p
!=
'\0'
));
if
(
!
p
)
return
FDT_END
;
break
;
case
FDT_PROP
:
lenp
=
fdt_offset_ptr
(
fdt
,
offset
,
sizeof
(
*
lenp
));
if
(
!
lenp
)
return
FDT_END
;
/* skip name offset, length and value */
offset
+=
2
*
FDT_TAGSIZE
+
fdt32_to_cpu
(
*
lenp
);
break
;
}
if
(
nextoffset
)
*
nextoffset
=
ALIGN
(
offset
,
FDT_TAGSIZE
);
return
tag
;
}
const
char
*
_fdt_find_string
(
const
char
*
strtab
,
int
tabsize
,
const
char
*
s
)
{
int
len
=
strlen
(
s
)
+
1
;
...
...
@@ -86,5 +154,3 @@ int fdt_move(const void *fdt, void *buf, int bufsize)
memmove
(
buf
,
fdt
,
fdt_totalsize
(
fdt
));
return
0
;
}
#endif
/* CONFIG_OF_LIBFDT */
libfdt/fdt_ro.c
浏览文件 @
cfa4c9d8
此差异已折叠。
点击以展开。
libfdt/fdt_rw.c
浏览文件 @
cfa4c9d8
...
...
@@ -2,23 +2,52 @@
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 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.
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
*
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
.
*
a) 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
.
*
* 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
* 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
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if CONFIG_OF_LIBFDT
#include "libfdt_env.h"
#include <fdt.h>
...
...
@@ -26,25 +55,32 @@
#include "libfdt_internal.h"
static
int
_blocks_misordered
(
const
void
*
fdt
,
int
mem_rsv_size
,
int
struct_size
)
{
return
(
fdt_off_mem_rsvmap
(
fdt
)
<
ALIGN
(
sizeof
(
struct
fdt_header
),
8
))
||
(
fdt_off_dt_struct
(
fdt
)
<
(
fdt_off_mem_rsvmap
(
fdt
)
+
mem_rsv_size
))
||
(
fdt_off_dt_strings
(
fdt
)
<
(
fdt_off_dt_struct
(
fdt
)
+
struct_size
))
||
(
fdt_totalsize
(
fdt
)
<
(
fdt_off_dt_strings
(
fdt
)
+
fdt_size_dt_strings
(
fdt
)));
}
static
int
rw_check_header
(
void
*
fdt
)
{
int
err
;
if
((
err
=
fdt_check_header
(
fdt
)))
return
err
;
if
(
fdt_version
(
fdt
)
<
0x11
)
if
(
fdt_version
(
fdt
)
<
17
)
return
-
FDT_ERR_BADVERSION
;
if
(
fdt_off_mem_rsvmap
(
fdt
)
<
ALIGN
(
sizeof
(
struct
fdt_header
),
8
))
return
-
FDT_ERR_BADLAYOUT
;
if
(
fdt_off_dt_struct
(
fdt
)
<
(
fdt_off_mem_rsvmap
(
fdt
)
+
sizeof
(
struct
fdt_reserve_entry
)))
return
-
FDT_ERR_BADLAYOUT
;
if
(
fdt_off_dt_strings
(
fdt
)
<
(
fdt_off_dt_struct
(
fdt
)
+
fdt_size_dt_struct
(
fdt
)))
return
-
FDT_ERR_BADLAYOUT
;
if
(
fdt_totalsize
(
fdt
)
<
(
fdt_off_dt_strings
(
fdt
)
+
fdt_size_dt_strings
(
fdt
)))
if
(
_blocks_misordered
(
fdt
,
sizeof
(
struct
fdt_reserve_entry
),
fdt_size_dt_struct
(
fdt
)))
return
-
FDT_ERR_BADLAYOUT
;
if
(
fdt_version
(
fdt
)
>
17
)
fdt_set_version
(
fdt
,
17
);
return
0
;
}
...
...
@@ -72,6 +108,19 @@ static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
return
0
;
}
static
int
_blob_splice_mem_rsv
(
void
*
fdt
,
struct
fdt_reserve_entry
*
p
,
int
oldn
,
int
newn
)
{
int
delta
=
(
newn
-
oldn
)
*
sizeof
(
*
p
);
int
err
;
err
=
_blob_splice
(
fdt
,
p
,
oldn
*
sizeof
(
*
p
),
newn
*
sizeof
(
*
p
));
if
(
err
)
return
err
;
fdt_set_off_dt_struct
(
fdt
,
fdt_off_dt_struct
(
fdt
)
+
delta
);
fdt_set_off_dt_strings
(
fdt
,
fdt_off_dt_strings
(
fdt
)
+
delta
);
return
0
;
}
static
int
_blob_splice_struct
(
void
*
fdt
,
void
*
p
,
int
oldlen
,
int
newlen
)
{
...
...
@@ -81,8 +130,8 @@ static int _blob_splice_struct(void *fdt, void *p,
if
((
err
=
_blob_splice
(
fdt
,
p
,
oldlen
,
newlen
)))
return
err
;
fdt_set_
header
(
fdt
,
size_dt_struc
t
,
fdt_size_dt_struct
(
fdt
)
+
delta
);
fdt_set_
header
(
fdt
,
off_dt_strings
,
fdt_off_dt_strings
(
fdt
)
+
delta
);
fdt_set_
size_dt_struct
(
fd
t
,
fdt_size_dt_struct
(
fdt
)
+
delta
);
fdt_set_
off_dt_strings
(
fdt
,
fdt_off_dt_strings
(
fdt
)
+
delta
);
return
0
;
}
...
...
@@ -94,7 +143,7 @@ static int _blob_splice_string(void *fdt, int newlen)
if
((
err
=
_blob_splice
(
fdt
,
p
,
0
,
newlen
)))
return
err
;
fdt_set_
header
(
fdt
,
size_dt_strings
,
fdt_size_dt_strings
(
fdt
)
+
newlen
);
fdt_set_
size_dt_strings
(
fdt
,
fdt_size_dt_strings
(
fdt
)
+
newlen
);
return
0
;
}
...
...
@@ -120,13 +169,47 @@ static int _find_add_string(void *fdt, const char *s)
return
(
new
-
strtab
);
}
int
fdt_add_mem_rsv
(
void
*
fdt
,
uint64_t
address
,
uint64_t
size
)
{
struct
fdt_reserve_entry
*
re
;
int
err
;
if
((
err
=
rw_check_header
(
fdt
)))
return
err
;
re
=
_fdt_mem_rsv_w
(
fdt
,
fdt_num_mem_rsv
(
fdt
));
err
=
_blob_splice_mem_rsv
(
fdt
,
re
,
0
,
1
);
if
(
err
)
return
err
;
re
->
address
=
cpu_to_fdt64
(
address
);
re
->
size
=
cpu_to_fdt64
(
size
);
return
0
;
}
int
fdt_del_mem_rsv
(
void
*
fdt
,
int
n
)
{
struct
fdt_reserve_entry
*
re
=
_fdt_mem_rsv_w
(
fdt
,
n
);
int
err
;
if
((
err
=
rw_check_header
(
fdt
)))
return
err
;
if
(
n
>=
fdt_num_mem_rsv
(
fdt
))
return
-
FDT_ERR_NOTFOUND
;
err
=
_blob_splice_mem_rsv
(
fdt
,
re
,
1
,
0
);
if
(
err
)
return
err
;
return
0
;
}
static
int
_resize_property
(
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
,
int
len
,
struct
fdt_property
**
prop
)
{
int
oldlen
;
int
err
;
*
prop
=
fdt_get_property
(
fdt
,
nodeoffset
,
name
,
&
oldlen
);
*
prop
=
fdt_get_property
_w
(
fdt
,
nodeoffset
,
name
,
&
oldlen
);
if
(
!
(
*
prop
))
return
oldlen
;
...
...
@@ -148,7 +231,7 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
int
namestroff
;
int
err
;
tag
=
fdt_next_tag
(
fdt
,
nodeoffset
,
&
nextoffset
,
NULL
);
tag
=
fdt_next_tag
(
fdt
,
nodeoffset
,
&
nextoffset
);
if
(
tag
!=
FDT_BEGIN_NODE
)
return
-
FDT_ERR_BADOFFSET
;
...
...
@@ -156,7 +239,7 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
if
(
namestroff
<
0
)
return
namestroff
;
*
prop
=
_fdt_offset_ptr
(
fdt
,
nextoffset
);
*
prop
=
_fdt_offset_ptr
_w
(
fdt
,
nextoffset
);
proplen
=
sizeof
(
**
prop
)
+
ALIGN
(
len
,
FDT_TAGSIZE
);
err
=
_blob_splice_struct
(
fdt
,
*
prop
,
0
,
proplen
);
...
...
@@ -188,32 +271,6 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
return
0
;
}
/**
* fdt_find_and_setprop: Find a node and set it's property
*
* @fdt: ptr to device tree
* @node: path of node
* @prop: property name
* @val: ptr to new value
* @len: length of new property value
* @create: flag to create the property if it doesn't exist
*
* Convenience function to directly set a property given the path to the node.
*/
int
fdt_find_and_setprop
(
void
*
fdt
,
const
char
*
node
,
const
char
*
prop
,
const
void
*
val
,
int
len
,
int
create
)
{
int
nodeoff
=
fdt_find_node_by_path
(
fdt
,
node
);
if
(
nodeoff
<
0
)
return
nodeoff
;
if
((
!
create
)
&&
(
fdt_get_property
(
fdt
,
nodeoff
,
prop
,
0
)
==
NULL
))
return
0
;
/* create flag not set; so exit quietly */
return
fdt_setprop
(
fdt
,
nodeoff
,
prop
,
val
,
len
);
}
int
fdt_delprop
(
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
)
{
struct
fdt_property
*
prop
;
...
...
@@ -221,7 +278,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
RW_CHECK_HEADER
(
fdt
);
prop
=
fdt_get_property
(
fdt
,
nodeoffset
,
name
,
&
len
);
prop
=
fdt_get_property
_w
(
fdt
,
nodeoffset
,
name
,
&
len
);
if
(
!
prop
)
return
len
;
...
...
@@ -248,13 +305,13 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
return
offset
;
/* Try to place the new node after the parent's properties */
fdt_next_tag
(
fdt
,
parentoffset
,
&
nextoffset
,
NULL
);
/* skip the BEGIN_NODE */
fdt_next_tag
(
fdt
,
parentoffset
,
&
nextoffset
);
/* skip the BEGIN_NODE */
do
{
offset
=
nextoffset
;
tag
=
fdt_next_tag
(
fdt
,
offset
,
&
nextoffset
,
NULL
);
tag
=
fdt_next_tag
(
fdt
,
offset
,
&
nextoffset
);
}
while
(
tag
==
FDT_PROP
);
nh
=
_fdt_offset_ptr
(
fdt
,
offset
);
nh
=
_fdt_offset_ptr
_w
(
fdt
,
offset
);
nodelen
=
sizeof
(
*
nh
)
+
ALIGN
(
namelen
+
1
,
FDT_TAGSIZE
)
+
FDT_TAGSIZE
;
err
=
_blob_splice_struct
(
fdt
,
nh
,
0
,
nodelen
);
...
...
@@ -279,46 +336,112 @@ int fdt_del_node(void *fdt, int nodeoffset)
{
int
endoffset
;
RW_CHECK_HEADER
(
fdt
);
endoffset
=
_fdt_node_end_offset
(
fdt
,
nodeoffset
);
if
(
endoffset
<
0
)
return
endoffset
;
return
_blob_splice_struct
(
fdt
,
_fdt_offset_ptr
(
fdt
,
nodeoffset
),
return
_blob_splice_struct
(
fdt
,
_fdt_offset_ptr
_w
(
fdt
,
nodeoffset
),
endoffset
-
nodeoffset
,
0
);
}
int
fdt_open_into
(
void
*
fdt
,
void
*
buf
,
int
bufsize
)
static
void
_packblocks
(
const
void
*
fdt
,
void
*
buf
,
int
mem_rsv_size
,
int
struct_size
)
{
int
mem_rsv_off
,
struct_off
,
strings_off
;
mem_rsv_off
=
ALIGN
(
sizeof
(
struct
fdt_header
),
8
);
struct_off
=
mem_rsv_off
+
mem_rsv_size
;
strings_off
=
struct_off
+
struct_size
;
memmove
(
buf
+
mem_rsv_off
,
fdt
+
fdt_off_mem_rsvmap
(
fdt
),
mem_rsv_size
);
fdt_set_off_mem_rsvmap
(
buf
,
mem_rsv_off
);
memcpy
(
buf
+
struct_off
,
fdt
+
fdt_off_dt_struct
(
fdt
),
struct_size
);
fdt_set_off_dt_struct
(
buf
,
struct_off
);
fdt_set_size_dt_struct
(
buf
,
struct_size
);
memcpy
(
buf
+
strings_off
,
fdt
+
fdt_off_dt_strings
(
fdt
),
fdt_size_dt_strings
(
fdt
));
fdt_set_off_dt_strings
(
buf
,
strings_off
);
fdt_set_size_dt_strings
(
buf
,
fdt_size_dt_strings
(
fdt
));
}
int
fdt_open_into
(
const
void
*
fdt
,
void
*
buf
,
int
bufsize
)
{
int
err
;
int
mem_rsv_size
,
struct_size
;
int
newsize
;
void
*
tmp
;
err
=
fdt_
move
(
fdt
,
buf
,
bufsize
);
err
=
fdt_
check_header
(
fdt
);
if
(
err
)
return
err
;
fdt
=
buf
;
mem_rsv_size
=
(
fdt_num_mem_rsv
(
fdt
)
+
1
)
*
sizeof
(
struct
fdt_reserve_entry
);
fdt_set_header
(
fdt
,
totalsize
,
bufsize
);
if
(
fdt_version
(
fdt
)
>=
17
)
{
struct_size
=
fdt_size_dt_struct
(
fdt
);
}
else
{
struct_size
=
0
;
while
(
fdt_next_tag
(
fdt
,
struct_size
,
&
struct_size
)
!=
FDT_END
)
;
}
/* FIXME: re-order if necessary */
if
(
!
_blocks_misordered
(
fdt
,
mem_rsv_size
,
struct_size
))
{
/* no further work necessary */
err
=
fdt_move
(
fdt
,
buf
,
bufsize
);
if
(
err
)
return
err
;
fdt_set_version
(
buf
,
17
);
fdt_set_size_dt_struct
(
buf
,
struct_size
);
fdt_set_totalsize
(
buf
,
bufsize
);
return
0
;
}
err
=
rw_check_header
(
fdt
);
if
(
err
)
return
err
;
/* Need to reorder */
newsize
=
ALIGN
(
sizeof
(
struct
fdt_header
),
8
)
+
mem_rsv_size
+
struct_size
+
fdt_size_dt_strings
(
fdt
);
if
(
bufsize
<
newsize
)
return
-
FDT_ERR_NOSPACE
;
if
(((
buf
+
newsize
)
<=
fdt
)
||
(
buf
>=
(
fdt
+
fdt_totalsize
(
fdt
))))
{
tmp
=
buf
;
}
else
{
tmp
=
(
void
*
)
fdt
+
fdt_totalsize
(
fdt
);
if
((
tmp
+
newsize
)
>
(
buf
+
bufsize
))
return
-
FDT_ERR_NOSPACE
;
}
_packblocks
(
fdt
,
tmp
,
mem_rsv_size
,
struct_size
);
memmove
(
buf
,
tmp
,
newsize
);
fdt_set_magic
(
buf
,
FDT_MAGIC
);
fdt_set_totalsize
(
buf
,
bufsize
);
fdt_set_version
(
buf
,
17
);
fdt_set_last_comp_version
(
buf
,
16
);
fdt_set_boot_cpuid_phys
(
buf
,
fdt_boot_cpuid_phys
(
fdt
));
return
0
;
}
int
fdt_pack
(
void
*
fdt
)
{
int
mem_rsv_size
;
int
err
;
err
=
rw_check_header
(
fdt
);
if
(
err
)
return
err
;
/* FIXME: pack components */
fdt_set_header
(
fdt
,
totalsize
,
_blob_data_size
(
fdt
));
mem_rsv_size
=
(
fdt_num_mem_rsv
(
fdt
)
+
1
)
*
sizeof
(
struct
fdt_reserve_entry
);
_packblocks
(
fdt
,
fdt
,
mem_rsv_size
,
fdt_size_dt_struct
(
fdt
));
fdt_set_totalsize
(
fdt
,
_blob_data_size
(
fdt
));
return
0
;
}
#endif
/* CONFIG_OF_LIBFDT */
libfdt/fdt_strerror.c
浏览文件 @
cfa4c9d8
...
...
@@ -2,23 +2,52 @@
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 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.
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
*
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
.
*
a) 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
.
*
* 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
* 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
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if CONFIG_OF_LIBFDT
#include "libfdt_env.h"
#include <fdt.h>
...
...
@@ -65,5 +94,3 @@ const char *fdt_strerror(int errval)
return
"<unknown error>"
;
}
#endif
/* CONFIG_OF_LIBFDT */
libfdt/fdt_sw.c
浏览文件 @
cfa4c9d8
...
...
@@ -2,23 +2,52 @@
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 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.
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
*
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
.
*
a) 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
.
*
* 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
* 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
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if CONFIG_OF_LIBFDT
#include "libfdt_env.h"
#include <fdt.h>
...
...
@@ -44,8 +73,8 @@ static void *grab_space(void *fdt, int len)
if
((
offset
+
len
<
offset
)
||
(
offset
+
len
>
spaceleft
))
return
NULL
;
fdt_set_
header
(
fdt
,
size_dt_struc
t
,
offset
+
len
);
return
fdt_offset_ptr
(
fdt
,
offset
,
len
);
fdt_set_
size_dt_struct
(
fd
t
,
offset
+
len
);
return
fdt_offset_ptr
_w
(
fdt
,
offset
,
len
);
}
int
fdt_create
(
void
*
buf
,
int
bufsize
)
...
...
@@ -57,15 +86,15 @@ int fdt_create(void *buf, int bufsize)
memset
(
buf
,
0
,
bufsize
);
fdt_set_
header
(
fdt
,
magic
,
SW_MAGIC
);
fdt_set_
header
(
fdt
,
version
,
FDT_LAST_SUPPORTED_VERSION
);
fdt_set_
header
(
fdt
,
last_comp_version
,
FDT_FIRST_SUPPORTED_VERSION
);
fdt_set_
header
(
fdt
,
totalsize
,
bufsize
);
fdt_set_
magic
(
fdt
,
SW_MAGIC
);
fdt_set_
version
(
fdt
,
FDT_LAST_SUPPORTED_VERSION
);
fdt_set_
last_comp_version
(
fdt
,
FDT_FIRST_SUPPORTED_VERSION
);
fdt_set_
totalsize
(
fdt
,
bufsize
);
fdt_set_
header
(
fdt
,
off_mem_rsvmap
,
ALIGN
(
sizeof
(
struct
fdt_header
),
sizeof
(
struct
fdt_reserve_entry
)));
fdt_set_
header
(
fdt
,
off_dt_struc
t
,
fdt_off_mem_rsvmap
(
fdt
));
fdt_set_
header
(
fdt
,
off_dt_strings
,
bufsize
);
fdt_set_
off_mem_rsvmap
(
fdt
,
ALIGN
(
sizeof
(
struct
fdt_header
),
sizeof
(
struct
fdt_reserve_entry
)));
fdt_set_
off_dt_struct
(
fd
t
,
fdt_off_mem_rsvmap
(
fdt
));
fdt_set_
off_dt_strings
(
fdt
,
bufsize
);
return
0
;
}
...
...
@@ -85,11 +114,11 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
if
((
offset
+
sizeof
(
*
re
))
>
fdt_totalsize
(
fdt
))
return
-
FDT_ERR_NOSPACE
;
re
=
(
struct
fdt_reserve_entry
*
)(
(
void
*
)
fdt
+
offset
);
re
=
(
struct
fdt_reserve_entry
*
)(
fdt
+
offset
);
re
->
address
=
cpu_to_fdt64
(
addr
);
re
->
size
=
cpu_to_fdt64
(
size
);
fdt_set_
header
(
fdt
,
off_dt_struc
t
,
offset
+
sizeof
(
*
re
));
fdt_set_
off_dt_struct
(
fd
t
,
offset
+
sizeof
(
*
re
));
return
0
;
}
...
...
@@ -152,7 +181,7 @@ static int find_add_string(void *fdt, const char *s)
return
0
;
/* no more room :( */
memcpy
(
strtab
+
offset
,
s
,
len
);
fdt_set_
header
(
fdt
,
size_dt_strings
,
strtabsize
+
len
);
fdt_set_
size_dt_strings
(
fdt
,
strtabsize
+
len
);
return
offset
;
}
...
...
@@ -202,14 +231,14 @@ int fdt_finish(void *fdt)
oldstroffset
=
fdt_totalsize
(
fdt
)
-
fdt_size_dt_strings
(
fdt
);
newstroffset
=
fdt_off_dt_struct
(
fdt
)
+
fdt_size_dt_struct
(
fdt
);
memmove
(
p
+
newstroffset
,
p
+
oldstroffset
,
fdt_size_dt_strings
(
fdt
));
fdt_set_
header
(
fdt
,
off_dt_strings
,
newstroffset
);
fdt_set_
off_dt_strings
(
fdt
,
newstroffset
);
/* Walk the structure, correcting string offsets */
offset
=
0
;
while
((
tag
=
fdt_next_tag
(
fdt
,
offset
,
&
nextoffset
,
NULL
))
!=
FDT_END
)
{
while
((
tag
=
fdt_next_tag
(
fdt
,
offset
,
&
nextoffset
))
!=
FDT_END
)
{
if
(
tag
==
FDT_PROP
)
{
struct
fdt_property
*
prop
=
fdt_offset_ptr
(
fdt
,
offset
,
sizeof
(
*
prop
));
struct
fdt_property
*
prop
=
fdt_offset_ptr_w
(
fdt
,
offset
,
sizeof
(
*
prop
));
int
nameoff
;
if
(
!
prop
)
...
...
@@ -223,9 +252,7 @@ int fdt_finish(void *fdt)
}
/* Finally, adjust the header */
fdt_set_
header
(
fdt
,
totalsize
,
newstroffset
+
fdt_size_dt_strings
(
fdt
));
fdt_set_
header
(
fdt
,
magic
,
FDT_MAGIC
);
fdt_set_
totalsize
(
fdt
,
newstroffset
+
fdt_size_dt_strings
(
fdt
));
fdt_set_
magic
(
fdt
,
FDT_MAGIC
);
return
0
;
}
#endif
/* CONFIG_OF_LIBFDT */
libfdt/fdt_wip.c
浏览文件 @
cfa4c9d8
...
...
@@ -2,23 +2,52 @@
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 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.
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
*
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
.
*
a) 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
.
*
* 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
* 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
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if CONFIG_OF_LIBFDT
#include "libfdt_env.h"
#include <fdt.h>
...
...
@@ -32,7 +61,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
void
*
propval
;
int
proplen
;
propval
=
fdt_getprop
(
fdt
,
nodeoffset
,
name
,
&
proplen
);
propval
=
fdt_getprop
_w
(
fdt
,
nodeoffset
,
name
,
&
proplen
);
if
(
!
propval
)
return
proplen
;
...
...
@@ -56,7 +85,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
struct
fdt_property
*
prop
;
int
len
;
prop
=
fdt_get_property
(
fdt
,
nodeoffset
,
name
,
&
len
);
prop
=
fdt_get_property
_w
(
fdt
,
nodeoffset
,
name
,
&
len
);
if
(
!
prop
)
return
len
;
...
...
@@ -71,12 +100,12 @@ int _fdt_node_end_offset(void *fdt, int nodeoffset)
uint32_t
tag
;
int
offset
,
nextoffset
;
tag
=
fdt_next_tag
(
fdt
,
nodeoffset
,
&
nextoffset
,
NULL
);
tag
=
fdt_next_tag
(
fdt
,
nodeoffset
,
&
nextoffset
);
if
(
tag
!=
FDT_BEGIN_NODE
)
return
-
FDT_ERR_BADOFFSET
;
do
{
offset
=
nextoffset
;
tag
=
fdt_next_tag
(
fdt
,
offset
,
&
nextoffset
,
NULL
);
tag
=
fdt_next_tag
(
fdt
,
offset
,
&
nextoffset
);
switch
(
tag
)
{
case
FDT_END
:
...
...
@@ -110,33 +139,6 @@ int fdt_nop_node(void *fdt, int nodeoffset)
if
(
endoffset
<
0
)
return
endoffset
;
nop_region
(
fdt_offset_ptr
(
fdt
,
nodeoffset
,
0
),
endoffset
-
nodeoffset
);
nop_region
(
fdt_offset_ptr
_w
(
fdt
,
nodeoffset
,
0
),
endoffset
-
nodeoffset
);
return
0
;
}
/*
* Replace a reserve map entry in the nth slot.
*/
int
fdt_replace_reservemap_entry
(
void
*
fdt
,
int
n
,
uint64_t
addr
,
uint64_t
size
)
{
struct
fdt_reserve_entry
*
re
;
int
used
;
int
total
;
int
err
;
err
=
fdt_num_reservemap
(
fdt
,
&
used
,
&
total
);
if
(
err
!=
0
)
return
err
;
if
(
n
>=
total
)
return
-
FDT_ERR_NOSPACE
;
re
=
(
struct
fdt_reserve_entry
*
)
(
fdt
+
fdt_off_mem_rsvmap
(
fdt
)
+
(
n
*
sizeof
(
struct
fdt_reserve_entry
)));
re
->
address
=
cpu_to_fdt64
(
addr
);
re
->
size
=
cpu_to_fdt64
(
size
);
return
0
;
}
#endif
/* CONFIG_OF_LIBFDT */
libfdt/libfdt_internal.h
浏览文件 @
cfa4c9d8
...
...
@@ -4,19 +4,51 @@
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 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
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
* a) 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
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <fdt.h>
...
...
@@ -26,13 +58,30 @@
#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0)
#define streq(p, q) (strcmp((p), (q)) == 0)
int
_fdt_check_header
(
const
void
*
fd
t
);
uint32_t
_fdt_next_tag
(
const
void
*
fdt
,
int
startoffset
,
int
*
nextoffse
t
);
const
char
*
_fdt_find_string
(
const
char
*
strtab
,
int
tabsize
,
const
char
*
s
);
int
_fdt_node_end_offset
(
void
*
fdt
,
int
nodeoffset
);
static
inline
void
*
_fdt_offset_ptr
(
const
struct
fdt_header
*
fdt
,
int
offset
)
static
inline
const
void
*
_fdt_offset_ptr
(
const
void
*
fdt
,
int
offset
)
{
return
fdt
+
fdt_off_dt_struct
(
fdt
)
+
offset
;
}
static
inline
void
*
_fdt_offset_ptr_w
(
void
*
fdt
,
int
offset
)
{
return
(
void
*
)
_fdt_offset_ptr
(
fdt
,
offset
);
}
static
inline
const
struct
fdt_reserve_entry
*
_fdt_mem_rsv
(
const
void
*
fdt
,
int
n
)
{
const
struct
fdt_reserve_entry
*
rsv_table
=
fdt
+
fdt_off_mem_rsvmap
(
fdt
);
return
rsv_table
+
n
;
}
static
inline
struct
fdt_reserve_entry
*
_fdt_mem_rsv_w
(
void
*
fdt
,
int
n
)
{
return
(
void
*
)
fdt
+
fdt_off_dt_struct
(
fdt
)
+
offset
;
return
(
void
*
)
_fdt_mem_rsv
(
fdt
,
n
)
;
}
#define SW_MAGIC (~FDT_MAGIC)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录