mirror of https://github.com/ipxe/ipxe.git
[fdt] Identify free space (if any) at end of parsed tree
Signed-off-by: Michael Brown <mcb30@ipxe.org>master
parent
0a48bb3214
commit
d853448887
|
@ -458,10 +458,11 @@ int fdt_mac ( struct fdt *fdt, unsigned int offset,
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) {
|
int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) {
|
||||||
const uint8_t *end;
|
const uint8_t *nul;
|
||||||
|
size_t end;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if ( sizeof ( fdt ) > max_len ) {
|
if ( sizeof ( *hdr ) > max_len ) {
|
||||||
DBGC ( fdt, "FDT length %#zx too short for header\n",
|
DBGC ( fdt, "FDT length %#zx too short for header\n",
|
||||||
max_len );
|
max_len );
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -470,6 +471,7 @@ int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) {
|
||||||
/* Record device tree location */
|
/* Record device tree location */
|
||||||
fdt->hdr = hdr;
|
fdt->hdr = hdr;
|
||||||
fdt->len = be32_to_cpu ( hdr->totalsize );
|
fdt->len = be32_to_cpu ( hdr->totalsize );
|
||||||
|
fdt->used = sizeof ( *hdr );
|
||||||
if ( fdt->len > max_len ) {
|
if ( fdt->len > max_len ) {
|
||||||
DBGC ( fdt, "FDT has invalid length %#zx / %#zx\n",
|
DBGC ( fdt, "FDT has invalid length %#zx / %#zx\n",
|
||||||
fdt->len, max_len );
|
fdt->len, max_len );
|
||||||
|
@ -507,6 +509,9 @@ int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) {
|
||||||
DBGC ( fdt, "FDT structure block is misaligned\n" );
|
DBGC ( fdt, "FDT structure block is misaligned\n" );
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
end = ( fdt->structure + fdt->structure_len );
|
||||||
|
if ( fdt->used < end )
|
||||||
|
fdt->used = end;
|
||||||
|
|
||||||
/* Record strings block location */
|
/* Record strings block location */
|
||||||
fdt->strings = be32_to_cpu ( hdr->off_dt_strings );
|
fdt->strings = be32_to_cpu ( hdr->off_dt_strings );
|
||||||
|
@ -518,11 +523,14 @@ int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) {
|
||||||
DBGC ( fdt, "FDT strings block exceeds table\n" );
|
DBGC ( fdt, "FDT strings block exceeds table\n" );
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
end = ( fdt->strings + fdt->strings_len );
|
||||||
|
if ( fdt->used < end )
|
||||||
|
fdt->used = end;
|
||||||
|
|
||||||
/* Shrink strings block to ensure NUL termination safety */
|
/* Shrink strings block to ensure NUL termination safety */
|
||||||
end = ( fdt->raw + fdt->strings + fdt->strings_len );
|
nul = ( fdt->raw + fdt->strings + fdt->strings_len );
|
||||||
for ( ; fdt->strings_len ; fdt->strings_len-- ) {
|
for ( ; fdt->strings_len ; fdt->strings_len-- ) {
|
||||||
if ( *(--end) == '\0' )
|
if ( *(--nul) == '\0' )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( fdt->strings_len != be32_to_cpu ( hdr->size_dt_strings ) ) {
|
if ( fdt->strings_len != be32_to_cpu ( hdr->size_dt_strings ) ) {
|
||||||
|
@ -530,6 +538,21 @@ int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) {
|
||||||
fdt->strings, ( fdt->strings + fdt->strings_len ) );
|
fdt->strings, ( fdt->strings + fdt->strings_len ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Record memory reservation block location */
|
||||||
|
fdt->reservations = be32_to_cpu ( hdr->off_mem_rsvmap );
|
||||||
|
DBGC ( fdt, "FDT memory reservations at +[%#04x,...)\n",
|
||||||
|
fdt->reservations );
|
||||||
|
if ( fdt->used <= fdt->reservations ) {
|
||||||
|
/* No size field exists: assume whole table is used */
|
||||||
|
fdt->used = fdt->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Identify free space (if any) */
|
||||||
|
if ( fdt->used < fdt->len ) {
|
||||||
|
DBGC ( fdt, "FDT free space at +[%#04zx,%#04zx)\n",
|
||||||
|
fdt->used, fdt->len );
|
||||||
|
}
|
||||||
|
|
||||||
/* Print model name (for debugging) */
|
/* Print model name (for debugging) */
|
||||||
DBGC ( fdt, "FDT model is \"%s\"\n", fdt_string ( fdt, 0, "model" ) );
|
DBGC ( fdt, "FDT model is \"%s\"\n", fdt_string ( fdt, 0, "model" ) );
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ struct fdt {
|
||||||
};
|
};
|
||||||
/** Length of tree */
|
/** Length of tree */
|
||||||
size_t len;
|
size_t len;
|
||||||
|
/** Used length of tree */
|
||||||
|
size_t used;
|
||||||
/** Offset to structure block */
|
/** Offset to structure block */
|
||||||
unsigned int structure;
|
unsigned int structure;
|
||||||
/** Length of structure block */
|
/** Length of structure block */
|
||||||
|
@ -92,6 +94,8 @@ struct fdt {
|
||||||
unsigned int strings;
|
unsigned int strings;
|
||||||
/** Length of strings block */
|
/** Length of strings block */
|
||||||
size_t strings_len;
|
size_t strings_len;
|
||||||
|
/** Offset to memory reservation block */
|
||||||
|
unsigned int reservations;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct image_tag fdt_image __image_tag;
|
extern struct image_tag fdt_image __image_tag;
|
||||||
|
|
Loading…
Reference in New Issue