Changeset View
Changeset View
Standalone View
Standalone View
sys/contrib/libfdt/fdt_rw.c
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) | ||||
|| (fdt_off_dt_struct(fdt) < | || (fdt_off_dt_struct(fdt) < | ||||
(fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) | (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) | ||||
|| (fdt_off_dt_strings(fdt) < | || (fdt_off_dt_strings(fdt) < | ||||
(fdt_off_dt_struct(fdt) + struct_size)) | (fdt_off_dt_struct(fdt) + struct_size)) | ||||
|| (fdt_totalsize(fdt) < | || (fdt_totalsize(fdt) < | ||||
(fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); | (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); | ||||
} | } | ||||
static int fdt_rw_check_header_(void *fdt) | static int fdt_rw_probe_(void *fdt) | ||||
{ | { | ||||
FDT_CHECK_HEADER(fdt); | FDT_RO_PROBE(fdt); | ||||
if (fdt_version(fdt) < 17) | if (fdt_version(fdt) < 17) | ||||
return -FDT_ERR_BADVERSION; | return -FDT_ERR_BADVERSION; | ||||
if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), | if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), | ||||
fdt_size_dt_struct(fdt))) | fdt_size_dt_struct(fdt))) | ||||
return -FDT_ERR_BADLAYOUT; | return -FDT_ERR_BADLAYOUT; | ||||
if (fdt_version(fdt) > 17) | if (fdt_version(fdt) > 17) | ||||
fdt_set_version(fdt, 17); | fdt_set_version(fdt, 17); | ||||
return 0; | return 0; | ||||
} | } | ||||
#define FDT_RW_CHECK_HEADER(fdt) \ | #define FDT_RW_PROBE(fdt) \ | ||||
{ \ | { \ | ||||
int err_; \ | int err_; \ | ||||
if ((err_ = fdt_rw_check_header_(fdt)) != 0) \ | if ((err_ = fdt_rw_probe_(fdt)) != 0) \ | ||||
return err_; \ | return err_; \ | ||||
} | } | ||||
static inline int fdt_data_size_(void *fdt) | static inline int fdt_data_size_(void *fdt) | ||||
{ | { | ||||
return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); | return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | static int fdt_find_add_string_(void *fdt, const char *s) | ||||
return (new - strtab); | return (new - strtab); | ||||
} | } | ||||
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) | int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) | ||||
{ | { | ||||
struct fdt_reserve_entry *re; | struct fdt_reserve_entry *re; | ||||
int err; | int err; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); | re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); | ||||
err = fdt_splice_mem_rsv_(fdt, re, 0, 1); | err = fdt_splice_mem_rsv_(fdt, re, 0, 1); | ||||
if (err) | if (err) | ||||
return err; | return err; | ||||
re->address = cpu_to_fdt64(address); | re->address = cpu_to_fdt64(address); | ||||
re->size = cpu_to_fdt64(size); | re->size = cpu_to_fdt64(size); | ||||
return 0; | return 0; | ||||
} | } | ||||
int fdt_del_mem_rsv(void *fdt, int n) | int fdt_del_mem_rsv(void *fdt, int n) | ||||
{ | { | ||||
struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); | struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
if (n >= fdt_num_mem_rsv(fdt)) | if (n >= fdt_num_mem_rsv(fdt)) | ||||
return -FDT_ERR_NOTFOUND; | return -FDT_ERR_NOTFOUND; | ||||
return fdt_splice_mem_rsv_(fdt, re, 1, 0); | return fdt_splice_mem_rsv_(fdt, re, 1, 0); | ||||
} | } | ||||
static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, | static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
int fdt_set_name(void *fdt, int nodeoffset, const char *name) | int fdt_set_name(void *fdt, int nodeoffset, const char *name) | ||||
{ | { | ||||
char *namep; | char *namep; | ||||
int oldlen, newlen; | int oldlen, newlen; | ||||
int err; | int err; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); | namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); | ||||
if (!namep) | if (!namep) | ||||
return oldlen; | return oldlen; | ||||
newlen = strlen(name); | newlen = strlen(name); | ||||
err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1), | err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1), | ||||
FDT_TAGALIGN(newlen+1)); | FDT_TAGALIGN(newlen+1)); | ||||
if (err) | if (err) | ||||
return err; | return err; | ||||
memcpy(namep, name, newlen+1); | memcpy(namep, name, newlen+1); | ||||
return 0; | return 0; | ||||
} | } | ||||
int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, | int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, | ||||
int len, void **prop_data) | int len, void **prop_data) | ||||
{ | { | ||||
struct fdt_property *prop; | struct fdt_property *prop; | ||||
int err; | int err; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); | err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); | ||||
if (err == -FDT_ERR_NOTFOUND) | if (err == -FDT_ERR_NOTFOUND) | ||||
err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); | err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); | ||||
if (err) | if (err) | ||||
return err; | return err; | ||||
*prop_data = prop->data; | *prop_data = prop->data; | ||||
Show All 16 Lines | |||||
} | } | ||||
int fdt_appendprop(void *fdt, int nodeoffset, const char *name, | int fdt_appendprop(void *fdt, int nodeoffset, const char *name, | ||||
const void *val, int len) | const void *val, int len) | ||||
{ | { | ||||
struct fdt_property *prop; | struct fdt_property *prop; | ||||
int err, oldlen, newlen; | int err, oldlen, newlen; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); | prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); | ||||
if (prop) { | if (prop) { | ||||
newlen = len + oldlen; | newlen = len + oldlen; | ||||
err = fdt_splice_struct_(fdt, prop->data, | err = fdt_splice_struct_(fdt, prop->data, | ||||
FDT_TAGALIGN(oldlen), | FDT_TAGALIGN(oldlen), | ||||
FDT_TAGALIGN(newlen)); | FDT_TAGALIGN(newlen)); | ||||
if (err) | if (err) | ||||
Show All 9 Lines | int fdt_appendprop(void *fdt, int nodeoffset, const char *name, | ||||
return 0; | return 0; | ||||
} | } | ||||
int fdt_delprop(void *fdt, int nodeoffset, const char *name) | int fdt_delprop(void *fdt, int nodeoffset, const char *name) | ||||
{ | { | ||||
struct fdt_property *prop; | struct fdt_property *prop; | ||||
int len, proplen; | int len, proplen; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
prop = fdt_get_property_w(fdt, nodeoffset, name, &len); | prop = fdt_get_property_w(fdt, nodeoffset, name, &len); | ||||
if (!prop) | if (!prop) | ||||
return len; | return len; | ||||
proplen = sizeof(*prop) + FDT_TAGALIGN(len); | proplen = sizeof(*prop) + FDT_TAGALIGN(len); | ||||
return fdt_splice_struct_(fdt, prop, proplen, 0); | return fdt_splice_struct_(fdt, prop, proplen, 0); | ||||
} | } | ||||
int fdt_add_subnode_namelen(void *fdt, int parentoffset, | int fdt_add_subnode_namelen(void *fdt, int parentoffset, | ||||
const char *name, int namelen) | const char *name, int namelen) | ||||
{ | { | ||||
struct fdt_node_header *nh; | struct fdt_node_header *nh; | ||||
int offset, nextoffset; | int offset, nextoffset; | ||||
int nodelen; | int nodelen; | ||||
int err; | int err; | ||||
uint32_t tag; | uint32_t tag; | ||||
fdt32_t *endtag; | fdt32_t *endtag; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); | offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); | ||||
if (offset >= 0) | if (offset >= 0) | ||||
return -FDT_ERR_EXISTS; | return -FDT_ERR_EXISTS; | ||||
else if (offset != -FDT_ERR_NOTFOUND) | else if (offset != -FDT_ERR_NOTFOUND) | ||||
return offset; | return offset; | ||||
/* Try to place the new node after the parent's properties */ | /* Try to place the new node after the parent's properties */ | ||||
Show All 23 Lines | |||||
{ | { | ||||
return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); | return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); | ||||
} | } | ||||
int fdt_del_node(void *fdt, int nodeoffset) | int fdt_del_node(void *fdt, int nodeoffset) | ||||
{ | { | ||||
int endoffset; | int endoffset; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
endoffset = fdt_node_end_offset_(fdt, nodeoffset); | endoffset = fdt_node_end_offset_(fdt, nodeoffset); | ||||
if (endoffset < 0) | if (endoffset < 0) | ||||
return endoffset; | return endoffset; | ||||
return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset), | return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset), | ||||
endoffset - nodeoffset, 0); | endoffset - nodeoffset, 0); | ||||
} | } | ||||
Show All 24 Lines | |||||
{ | { | ||||
int err; | int err; | ||||
int mem_rsv_size, struct_size; | int mem_rsv_size, struct_size; | ||||
int newsize; | int newsize; | ||||
const char *fdtstart = fdt; | const char *fdtstart = fdt; | ||||
const char *fdtend = fdtstart + fdt_totalsize(fdt); | const char *fdtend = fdtstart + fdt_totalsize(fdt); | ||||
char *tmp; | char *tmp; | ||||
FDT_CHECK_HEADER(fdt); | FDT_RO_PROBE(fdt); | ||||
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) | mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) | ||||
* sizeof(struct fdt_reserve_entry); | * sizeof(struct fdt_reserve_entry); | ||||
if (fdt_version(fdt) >= 17) { | if (fdt_version(fdt) >= 17) { | ||||
struct_size = fdt_size_dt_struct(fdt); | struct_size = fdt_size_dt_struct(fdt); | ||||
} else { | } else { | ||||
struct_size = 0; | struct_size = 0; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | int fdt_open_into(const void *fdt, void *buf, int bufsize) | ||||
return 0; | return 0; | ||||
} | } | ||||
int fdt_pack(void *fdt) | int fdt_pack(void *fdt) | ||||
{ | { | ||||
int mem_rsv_size; | int mem_rsv_size; | ||||
FDT_RW_CHECK_HEADER(fdt); | FDT_RW_PROBE(fdt); | ||||
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) | mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) | ||||
* sizeof(struct fdt_reserve_entry); | * sizeof(struct fdt_reserve_entry); | ||||
fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); | fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); | ||||
fdt_set_totalsize(fdt, fdt_data_size_(fdt)); | fdt_set_totalsize(fdt, fdt_data_size_(fdt)); | ||||
return 0; | return 0; | ||||
} | } |