mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-26 00:59:55 +00:00
FDT lib improvements
This commit is contained in:
1 parent
c3c14cffef
commit
a6649f5b8e
2 files changed
+81
-33
No files matched your search
+77
-31
@@ -268,7 +268,7 @@ static grub_uint32_t *find_prop (void *fdt, unsigned int nodeoffset,
|
|||||||
the size allocated for the FDT; if this function is called before the other
|
the size allocated for the FDT; if this function is called before the other
|
||||||
functions in this file and returns success, the other functions are
|
functions in this file and returns success, the other functions are
|
||||||
guaranteed not to access memory locations outside the allocated memory. */
|
guaranteed not to access memory locations outside the allocated memory. */
|
||||||
int grub_fdt_check_header_nosize (void *fdt)
|
int grub_fdt_check_header_nosize (const void *fdt)
|
||||||
{
|
{
|
||||||
if (((grub_addr_t) fdt & 0x7) || (grub_fdt_get_magic (fdt) != FDT_MAGIC)
|
if (((grub_addr_t) fdt & 0x7) || (grub_fdt_get_magic (fdt) != FDT_MAGIC)
|
||||||
|| (grub_fdt_get_version (fdt) < FDT_SUPPORTED_VERSION)
|
|| (grub_fdt_get_version (fdt) < FDT_SUPPORTED_VERSION)
|
||||||
@@ -286,7 +286,7 @@ int grub_fdt_check_header_nosize (void *fdt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int grub_fdt_check_header (void *fdt, unsigned int size)
|
int grub_fdt_check_header (const void *fdt, unsigned int size)
|
||||||
{
|
{
|
||||||
if (size < sizeof (grub_fdt_header_t)
|
if (size < sizeof (grub_fdt_header_t)
|
||||||
|| (grub_fdt_get_totalsize (fdt) > size)
|
|| (grub_fdt_get_totalsize (fdt) > size)
|
||||||
@@ -295,41 +295,29 @@ int grub_fdt_check_header (void *fdt, unsigned int size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a direct sub-node of a given parent node. */
|
static const grub_uint32_t *
|
||||||
int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
|
advance_token (const void *fdt, const grub_uint32_t *token, const grub_uint32_t *end, int skip_current)
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
grub_uint32_t *token, *end;
|
for (; token < end; skip_current = 0)
|
||||||
char *node_name;
|
|
||||||
|
|
||||||
if (parentoffset & 0x3)
|
|
||||||
return -1;
|
|
||||||
token = (void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt)
|
|
||||||
+ parentoffset);
|
|
||||||
end = (void *) struct_end (fdt);
|
|
||||||
if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE))
|
|
||||||
return -1;
|
|
||||||
SKIP_NODE_NAME(node_name, token, end);
|
|
||||||
while (token < end)
|
|
||||||
{
|
{
|
||||||
switch (grub_be_to_cpu32(*token))
|
switch (grub_be_to_cpu32 (*token))
|
||||||
{
|
{
|
||||||
case FDT_BEGIN_NODE:
|
case FDT_BEGIN_NODE:
|
||||||
node_name = (char *) (token + 1);
|
if (skip_current)
|
||||||
if (node_name + grub_strlen (name) >= (char *) end)
|
{
|
||||||
return -1;
|
token = get_next_node (fdt, (char *) (token + 1));
|
||||||
if (!grub_strcmp (node_name, name))
|
continue;
|
||||||
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
|
}
|
||||||
- grub_fdt_get_off_dt_struct (fdt));
|
char *ptr;
|
||||||
token = get_next_node (fdt, node_name);
|
for (ptr = (char *) (token + 1); *ptr && ptr < (char *) end; ptr++);
|
||||||
if (!token)
|
if (ptr >= (char *) end)
|
||||||
return -1;
|
return 0;
|
||||||
break;
|
return token;
|
||||||
case FDT_PROP:
|
case FDT_PROP:
|
||||||
/* Skip property token and following data (len, nameoff and property
|
/* Skip property token and following data (len, nameoff and property
|
||||||
value). */
|
value). */
|
||||||
if (token >= end - 1)
|
if (token >= end - 1)
|
||||||
return -1;
|
return 0;
|
||||||
token += prop_entry_size(grub_be_to_cpu32(*(token + 1)))
|
token += prop_entry_size(grub_be_to_cpu32(*(token + 1)))
|
||||||
/ sizeof(*token);
|
/ sizeof(*token);
|
||||||
break;
|
break;
|
||||||
@@ -337,10 +325,68 @@ int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
|
|||||||
token++;
|
token++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int grub_fdt_next_node (const void *fdt, unsigned int currentoffset)
|
||||||
|
{
|
||||||
|
const grub_uint32_t *token = (const grub_uint32_t *) fdt + (currentoffset + grub_fdt_get_off_dt_struct (fdt)) / 4;
|
||||||
|
token = advance_token (fdt, token, (const void *) struct_end (fdt), 1);
|
||||||
|
if (!token)
|
||||||
|
return -1;
|
||||||
|
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
|
||||||
|
- grub_fdt_get_off_dt_struct (fdt));
|
||||||
|
}
|
||||||
|
|
||||||
|
int grub_fdt_first_node (const void *fdt, unsigned int parentoffset)
|
||||||
|
{
|
||||||
|
const grub_uint32_t *token, *end;
|
||||||
|
char *node_name;
|
||||||
|
|
||||||
|
if (parentoffset & 0x3)
|
||||||
|
return -1;
|
||||||
|
token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt)
|
||||||
|
+ parentoffset);
|
||||||
|
end = (const void *) struct_end (fdt);
|
||||||
|
if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE))
|
||||||
|
return -1;
|
||||||
|
SKIP_NODE_NAME(node_name, token, end);
|
||||||
|
token = advance_token (fdt, token, end, 0);
|
||||||
|
if (!token)
|
||||||
|
return -1;
|
||||||
|
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
|
||||||
|
- grub_fdt_get_off_dt_struct (fdt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find a direct sub-node of a given parent node. */
|
||||||
|
int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
const grub_uint32_t *token, *end;
|
||||||
|
const char *node_name;
|
||||||
|
int skip_current = 0;
|
||||||
|
|
||||||
|
if (parentoffset & 0x3)
|
||||||
|
return -1;
|
||||||
|
token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt)
|
||||||
|
+ parentoffset);
|
||||||
|
end = (const void *) struct_end (fdt);
|
||||||
|
if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE))
|
||||||
|
return -1;
|
||||||
|
SKIP_NODE_NAME(node_name, token, end);
|
||||||
|
while (1) {
|
||||||
|
token = advance_token (fdt, token, end, skip_current);
|
||||||
|
if (!token)
|
||||||
|
return -1;
|
||||||
|
skip_current = 1;
|
||||||
|
node_name = (const char *) token + 1;
|
||||||
|
if (grub_strcmp (node_name, name) == 0)
|
||||||
|
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
|
||||||
|
- grub_fdt_get_off_dt_struct (fdt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset,
|
int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset,
|
||||||
|
|||||||
+4
-2
@@ -96,10 +96,12 @@ struct grub_fdt_empty_tree {
|
|||||||
grub_fdt_set_header(fdt, size_dt_struct, value)
|
grub_fdt_set_header(fdt, size_dt_struct, value)
|
||||||
|
|
||||||
int grub_fdt_create_empty_tree (void *fdt, unsigned int size);
|
int grub_fdt_create_empty_tree (void *fdt, unsigned int size);
|
||||||
int grub_fdt_check_header (void *fdt, unsigned int size);
|
int grub_fdt_check_header (const void *fdt, unsigned int size);
|
||||||
int grub_fdt_check_header_nosize (void *fdt);
|
int grub_fdt_check_header_nosize (const void *fdt);
|
||||||
int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
|
int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
int grub_fdt_first_node (const void *fdt, unsigned int parentoffset);
|
||||||
|
int grub_fdt_next_node (const void *fdt, unsigned int currentoffset);
|
||||||
int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset,
|
int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user