diff --git a/src/core/fdt.c b/src/core/fdt.c index 199a53497..2ca41bc08 100644 --- a/src/core/fdt.c +++ b/src/core/fdt.c @@ -402,6 +402,46 @@ static int fdt_property ( struct fdt *fdt, unsigned int offset, } } +/** + * Find strings property + * + * @v fdt Device tree + * @v offset Starting node offset + * @v name Property name + * @v count String count to fill in + * @ret string String property, or NULL on error + */ +const char * fdt_strings ( struct fdt *fdt, unsigned int offset, + const char *name, unsigned int *count ) { + struct fdt_descriptor desc; + const char *data; + size_t len; + int rc; + + /* Return a zero count on error */ + *count = 0; + + /* Find property */ + if ( ( rc = fdt_property ( fdt, offset, name, &desc ) ) != 0 ) + return NULL; + + /* Check NUL termination */ + data = desc.data; + if ( desc.len && ( data[ desc.len - 1 ] != '\0' ) ) { + DBGC ( fdt, "FDT unterminated string property \"%s\"\n", + name ); + return NULL; + } + + /* Count number of strings */ + for ( len = desc.len ; len-- ; ) { + if ( data[len] == '\0' ) + (*count)++; + } + + return data; +} + /** * Find string property * @@ -412,21 +452,10 @@ static int fdt_property ( struct fdt *fdt, unsigned int offset, */ const char * fdt_string ( struct fdt *fdt, unsigned int offset, const char *name ) { - struct fdt_descriptor desc; - int rc; + unsigned int count; - /* Find property */ - if ( ( rc = fdt_property ( fdt, offset, name, &desc ) ) != 0 ) - return NULL; - - /* Check NUL termination */ - if ( strnlen ( desc.data, desc.len ) == desc.len ) { - DBGC ( fdt, "FDT unterminated string property \"%s\"\n", - name ); - return NULL; - } - - return desc.data; + /* Find strings property */ + return fdt_strings ( fdt, offset, name, &count ); } /** diff --git a/src/include/ipxe/fdt.h b/src/include/ipxe/fdt.h index 7eec5cd88..1e05c9e2d 100644 --- a/src/include/ipxe/fdt.h +++ b/src/include/ipxe/fdt.h @@ -115,6 +115,8 @@ extern int fdt_path ( struct fdt *fdt, const char *path, unsigned int *offset ); extern int fdt_alias ( struct fdt *fdt, const char *name, unsigned int *offset ); +extern const char * fdt_strings ( struct fdt *fdt, unsigned int offset, + const char *name, unsigned int *count ); extern const char * fdt_string ( struct fdt *fdt, unsigned int offset, const char *name ); extern int fdt_u64 ( struct fdt *fdt, unsigned int offset, const char *name,