diff options
Diffstat (limited to 'libfdt/fdt_ro.c')
| -rw-r--r-- | libfdt/fdt_ro.c | 72 | 
1 files changed, 72 insertions, 0 deletions
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 271132487..af3333686 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -329,3 +329,75 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset, char **namep  	return tag;  } + +/* + * Return the number of used reserve map entries and total slots available. + */ +int fdt_num_reservemap(void *fdt, int *used, int *total) +{ +	struct fdt_reserve_entry *re; +	int  start; +	int  end; +	int  err = fdt_check_header(fdt); + +	if (err != 0) +		return err; + +	start = fdt_off_mem_rsvmap(fdt); + +	/* +	 * Convention is that the reserve map is before the dt_struct, +	 * but it does not have to be. +	 */ +	end = fdt_totalsize(fdt); +	if (end > fdt_off_dt_struct(fdt)) +		end = fdt_off_dt_struct(fdt); +	if (end > fdt_off_dt_strings(fdt)) +		end = fdt_off_dt_strings(fdt); + +	/* +	 * Since the reserved area list is zero terminated, you get one fewer. +	 */ +	if (total) +		*total = ((end - start) / sizeof(struct fdt_reserve_entry)) - 1; + +	if (used) { +		*used = 0; +		while (start < end) { +			re = (struct fdt_reserve_entry *)(fdt + start); +			if (re->size == 0) +				return 0;	/* zero size terminates the list */ + +			*used += 1; +			start += sizeof(struct fdt_reserve_entry); +		} +		/* +		 * If we get here, there was no zero size termination. +		 */ +		return -FDT_ERR_BADLAYOUT; +	} +	return 0; +} + +/* + * Return the nth reserve map entry. + */ +int fdt_get_reservemap(void *fdt, int n, 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; +	if (re) { +		*re = *(struct fdt_reserve_entry *) +			_fdt_offset_ptr(fdt, n * sizeof(struct fdt_reserve_entry)); +	} +	return 0; +} +  |