[PATCH v2 0/7] Allow showing the memory map

This little series adds a new 'memmap' command, intended to show the layout of memory within U-Boot and how much memory is available for loading images.
Changes in v2: - Split into its own patch - Modify the existing 'meminfo' command instead
Simon Glass (7): common: Fix up malloc() comment in reserve_noncached() common: Tidy up how malloc() is inited am65x: Use map_to_sysmem() to convert from pointer global_data: Add some more accessors bootstage: Allow counting memory without strings cmd: Move meminfo command into its own file cmd: Update the meminfo command to show the memory map
arch/arm/mach-k3/am65x/am654_init.c | 11 +-- cmd/Kconfig | 1 + cmd/Makefile | 1 + cmd/mem.c | 19 ----- cmd/meminfo.c | 72 ++++++++++++++++ common/board_f.c | 8 +- common/board_r.c | 3 +- common/bootstage.c | 16 ++-- common/dlmalloc.c | 8 +- common/spl/spl.c | 4 +- doc/usage/cmd/meminfo.rst | 126 ++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + include/asm-generic/global_data.h | 30 +++++++ include/bootstage.h | 5 +- include/malloc.h | 8 ++ test/cmd/Makefile | 3 +- test/cmd/meminfo.c | 38 +++++++++ 17 files changed, 308 insertions(+), 46 deletions(-) create mode 100644 cmd/meminfo.c create mode 100644 doc/usage/cmd/meminfo.rst create mode 100644 test/cmd/meminfo.c

The function name has changed, so update it.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
common/board_f.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 154675d0e40..2e04a47b546 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -501,9 +501,9 @@ static unsigned long reserve_stack_aligned(size_t size) static int reserve_noncached(void) { /* - * The value of gd->start_addr_sp must match the value of malloc_start - * calculated in board_r.c:initr_malloc(), which is passed to - * dlmalloc.c:mem_malloc_init() and then used by + * The value of gd->start_addr_sp must match the value of + * mem_malloc_start calculated in board_r.c:initr_malloc(), which is + * passed to dlmalloc.c:mem_malloc_init() and then used by * cache.c:noncached_init() * * These calculations must match the code in cache.c:noncached_init()

The call to malloc() is a bit strange. The naming of the arguments suggests that an address is passed, but in fact it is a pointer, at least in the board_init_r() function and SPL equivalent.
Update it to work as described. Add a function comment as well.
Note that this does adjustment does not extend into the malloc() implementation itself, apart from changing mem_malloc_init(), since there are lots of casts and pointers and integers are used interchangeably.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
common/board_r.c | 3 +-- common/dlmalloc.c | 8 +++++--- common/spl/spl.c | 4 +--- include/malloc.h | 8 ++++++++ 4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/common/board_r.c b/common/board_r.c index 1acad069d92..60eba0942d8 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -204,8 +204,7 @@ static int initr_malloc(void) */ start = gd->relocaddr - TOTAL_MALLOC_LEN; gd_set_malloc_start(start); - mem_malloc_init((ulong)map_sysmem(start, TOTAL_MALLOC_LEN), - TOTAL_MALLOC_LEN); + mem_malloc_init(start, TOTAL_MALLOC_LEN); return 0; }
diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 1ac7ce3f43c..cc4d3a0a028 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -16,6 +16,8 @@ #include <asm/global_data.h>
#include <malloc.h> +#include <mapmem.h> +#include <string.h> #include <asm/io.h> #include <valgrind/memcheck.h>
@@ -598,9 +600,9 @@ void *sbrk(ptrdiff_t increment)
void mem_malloc_init(ulong start, ulong size) { - mem_malloc_start = start; - mem_malloc_end = start + size; - mem_malloc_brk = start; + mem_malloc_start = (ulong)map_sysmem(start, size); + mem_malloc_end = mem_malloc_start + size; + mem_malloc_brk = mem_malloc_start;
#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT malloc_init(); diff --git a/common/spl/spl.c b/common/spl/spl.c index c13b2b8f714..fc8b38862e8 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -679,9 +679,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_set_bd();
if (IS_ENABLED(CONFIG_SPL_SYS_MALLOC)) { - mem_malloc_init((ulong)map_sysmem(SPL_SYS_MALLOC_START, - SPL_SYS_MALLOC_SIZE), - SPL_SYS_MALLOC_SIZE); + mem_malloc_init(SPL_SYS_MALLOC_START, SPL_SYS_MALLOC_SIZE); gd->flags |= GD_FLG_FULL_MALLOC_INIT; } if (!(gd->flags & GD_FLG_SPL_INIT)) { diff --git a/include/malloc.h b/include/malloc.h index 07d3e90a855..9e0be482416 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -981,6 +981,14 @@ extern ulong mem_malloc_start; extern ulong mem_malloc_end; extern ulong mem_malloc_brk;
+/** + * mem_malloc_init() - Set up the malloc() pool + * + * Sets the region of memory to be used for all future calls to malloc(), etc. + * + * @start: Start address + * @size: Size in bytes + */ void mem_malloc_init(ulong start, ulong size);
#ifdef __cplusplus

Am 11. Oktober 2024 23:40:26 MESZ schrieb Simon Glass sjg@chromium.org:
The call to malloc() is a bit strange. The naming of the arguments suggests that an address is passed, but in fact it is a pointer, at least in the board_init_r() function and SPL equivalent.
Please, do not push sandbox only code deeper into malloc.
We should strive to get rid of the sandbox only virtual address space whereever we can.
Best regards
Heinrich
Update it to work as described. Add a function comment as well.
Note that this does adjustment does not extend into the malloc() implementation itself, apart from changing mem_malloc_init(), since there are lots of casts and pointers and integers are used interchangeably.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
common/board_r.c | 3 +-- common/dlmalloc.c | 8 +++++--- common/spl/spl.c | 4 +--- include/malloc.h | 8 ++++++++ 4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/common/board_r.c b/common/board_r.c index 1acad069d92..60eba0942d8 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -204,8 +204,7 @@ static int initr_malloc(void) */ start = gd->relocaddr - TOTAL_MALLOC_LEN; gd_set_malloc_start(start);
- mem_malloc_init((ulong)map_sysmem(start, TOTAL_MALLOC_LEN),
TOTAL_MALLOC_LEN);
- mem_malloc_init(start, TOTAL_MALLOC_LEN); return 0;
}
diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 1ac7ce3f43c..cc4d3a0a028 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -16,6 +16,8 @@ #include <asm/global_data.h>
#include <malloc.h> +#include <mapmem.h> +#include <string.h> #include <asm/io.h> #include <valgrind/memcheck.h>
@@ -598,9 +600,9 @@ void *sbrk(ptrdiff_t increment)
void mem_malloc_init(ulong start, ulong size) {
- mem_malloc_start = start;
- mem_malloc_end = start + size;
- mem_malloc_brk = start;
- mem_malloc_start = (ulong)map_sysmem(start, size);
- mem_malloc_end = mem_malloc_start + size;
- mem_malloc_brk = mem_malloc_start;
#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT malloc_init(); diff --git a/common/spl/spl.c b/common/spl/spl.c index c13b2b8f714..fc8b38862e8 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -679,9 +679,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_set_bd();
if (IS_ENABLED(CONFIG_SPL_SYS_MALLOC)) {
mem_malloc_init((ulong)map_sysmem(SPL_SYS_MALLOC_START,
SPL_SYS_MALLOC_SIZE),
SPL_SYS_MALLOC_SIZE);
gd->flags |= GD_FLG_FULL_MALLOC_INIT; } if (!(gd->flags & GD_FLG_SPL_INIT)) {mem_malloc_init(SPL_SYS_MALLOC_START, SPL_SYS_MALLOC_SIZE);
diff --git a/include/malloc.h b/include/malloc.h index 07d3e90a855..9e0be482416 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -981,6 +981,14 @@ extern ulong mem_malloc_start; extern ulong mem_malloc_end; extern ulong mem_malloc_brk;
+/**
- mem_malloc_init() - Set up the malloc() pool
- Sets the region of memory to be used for all future calls to malloc(), etc.
- @start: Start address
- @size: Size in bytes
- */
void mem_malloc_init(ulong start, ulong size);
#ifdef __cplusplus

On Sat, Oct 12, 2024 at 01:25:37AM +0200, Heinrich Schuchardt wrote:
Am 11. Oktober 2024 23:40:26 MESZ schrieb Simon Glass sjg@chromium.org:
The call to malloc() is a bit strange. The naming of the arguments suggests that an address is passed, but in fact it is a pointer, at least in the board_init_r() function and SPL equivalent.
Please, do not push sandbox only code deeper into malloc.
We should strive to get rid of the sandbox only virtual address space whereever we can.
I don't think it's possible to get rid of map_sysmem() and friends, so this is I think quite reasonable as it starts moving the detail from every caller and to the core places where it's needed.

On Fri, Oct 11, 2024 at 03:40:26PM -0600, Simon Glass wrote:
The call to malloc() is a bit strange. The naming of the arguments suggests that an address is passed, but in fact it is a pointer, at least in the board_init_r() function and SPL equivalent.
Update it to work as described. Add a function comment as well.
Note that this does adjustment does not extend into the malloc() implementation itself, apart from changing mem_malloc_init(), since there are lots of casts and pointers and integers are used interchangeably.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Tom Rini trini@konsulko.com

The board_init_f() function for am65x is a bit confusing, since it uses the variable name 'pool_addr' to hold a pointer. It then casts it to an address to pass to mem_alloc_init()
Rename the variable and use mapmem to convert to an address.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/arm/mach-k3/am65x/am654_init.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-k3/am65x/am654_init.c b/arch/arm/mach-k3/am65x/am654_init.c index a4f038029d7..ddcc1355210 100644 --- a/arch/arm/mach-k3/am65x/am654_init.c +++ b/arch/arm/mach-k3/am65x/am654_init.c @@ -8,6 +8,7 @@
#include <fdt_support.h> #include <init.h> +#include <mapmem.h> #include <asm/global_data.h> #include <asm/io.h> #include <spl.h> @@ -165,7 +166,7 @@ void board_init_f(ulong dummy) #if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS) struct udevice *dev; size_t pool_size; - void *pool_addr; + void *pool; int ret; #endif /* @@ -204,14 +205,14 @@ void board_init_f(ulong dummy) * malloc pool of which we use all that's left. */ pool_size = CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr; - pool_addr = malloc(pool_size); - if (!pool_addr) + pool = malloc(pool_size); + if (!pool) panic("ERROR: Can't allocate full malloc pool!\n");
- mem_malloc_init((ulong)pool_addr, (ulong)pool_size); + mem_malloc_init(map_to_sysmem(pool), (ulong)pool_size); gd->flags |= GD_FLG_FULL_MALLOC_INIT; debug("%s: initialized an early full malloc pool at 0x%08lx of 0x%lx bytes\n", - __func__, (unsigned long)pool_addr, (unsigned long)pool_size); + __func__, (unsigned long)pool, (unsigned long)pool_size); /* * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue * regardless of the result of pinctrl. Do this without probing the

Am 11. Oktober 2024 23:40:27 MESZ schrieb Simon Glass sjg@chromium.org:
The board_init_f() function for am65x is a bit confusing, since it uses the variable name 'pool_addr' to hold a pointer. It then casts it to an address to pass to mem_alloc_init()
Rename the variable and use mapmem to convert to an address.
This patch demonstrates that the whole series is going into the wrong direction.
Keep sandbox only virtual addresses out of the malloc library.
Best regards
Heinrich
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/arm/mach-k3/am65x/am654_init.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-k3/am65x/am654_init.c b/arch/arm/mach-k3/am65x/am654_init.c index a4f038029d7..ddcc1355210 100644 --- a/arch/arm/mach-k3/am65x/am654_init.c +++ b/arch/arm/mach-k3/am65x/am654_init.c @@ -8,6 +8,7 @@
#include <fdt_support.h> #include <init.h> +#include <mapmem.h> #include <asm/global_data.h> #include <asm/io.h> #include <spl.h> @@ -165,7 +166,7 @@ void board_init_f(ulong dummy) #if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS) struct udevice *dev; size_t pool_size;
- void *pool_addr;
- void *pool; int ret;
#endif /* @@ -204,14 +205,14 @@ void board_init_f(ulong dummy) * malloc pool of which we use all that's left. */ pool_size = CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr;
- pool_addr = malloc(pool_size);
- if (!pool_addr)
- pool = malloc(pool_size);
- if (!pool) panic("ERROR: Can't allocate full malloc pool!\n");
- mem_malloc_init((ulong)pool_addr, (ulong)pool_size);
- mem_malloc_init(map_to_sysmem(pool), (ulong)pool_size); gd->flags |= GD_FLG_FULL_MALLOC_INIT; debug("%s: initialized an early full malloc pool at 0x%08lx of 0x%lx bytes\n",
__func__, (unsigned long)pool_addr, (unsigned long)pool_size);
/*__func__, (unsigned long)pool, (unsigned long)pool_size);
- Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue
- regardless of the result of pinctrl. Do this without probing the

On Fri, Oct 11, 2024 at 03:40:27PM -0600, Simon Glass wrote:
The board_init_f() function for am65x is a bit confusing, since it uses the variable name 'pool_addr' to hold a pointer. It then casts it to an address to pass to mem_alloc_init()
Rename the variable and use mapmem to convert to an address.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/arm/mach-k3/am65x/am654_init.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-k3/am65x/am654_init.c b/arch/arm/mach-k3/am65x/am654_init.c index a4f038029d7..ddcc1355210 100644 --- a/arch/arm/mach-k3/am65x/am654_init.c +++ b/arch/arm/mach-k3/am65x/am654_init.c @@ -8,6 +8,7 @@
#include <fdt_support.h> #include <init.h> +#include <mapmem.h> #include <asm/global_data.h> #include <asm/io.h> #include <spl.h> @@ -165,7 +166,7 @@ void board_init_f(ulong dummy) #if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS) struct udevice *dev; size_t pool_size;
- void *pool_addr;
- void *pool; int ret;
#endif /* @@ -204,14 +205,14 @@ void board_init_f(ulong dummy) * malloc pool of which we use all that's left. */ pool_size = CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr;
- pool_addr = malloc(pool_size);
- if (!pool_addr)
- pool = malloc(pool_size);
- if (!pool) panic("ERROR: Can't allocate full malloc pool!\n");
- mem_malloc_init((ulong)pool_addr, (ulong)pool_size);
- mem_malloc_init(map_to_sysmem(pool), (ulong)pool_size); gd->flags |= GD_FLG_FULL_MALLOC_INIT; debug("%s: initialized an early full malloc pool at 0x%08lx of 0x%lx bytes\n",
__func__, (unsigned long)pool_addr, (unsigned long)pool_size);
/*__func__, (unsigned long)pool, (unsigned long)pool_size);
- Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue
- regardless of the result of pinctrl. Do this without probing the
I'm confused since I thought patch 2 removed the need for doing map_to_sysmem() games more widely. You also forgot to CC anyone from TI that might have comments on if they find "pool" rather than "pool_addr" more or less confusing and given the recent patch from them about what's printed out about memory size, I would think their feedback would be important.

Hi Tom,
On Fri, 11 Oct 2024 at 19:37, Tom Rini trini@konsulko.com wrote:
On Fri, Oct 11, 2024 at 03:40:27PM -0600, Simon Glass wrote:
The board_init_f() function for am65x is a bit confusing, since it uses the variable name 'pool_addr' to hold a pointer. It then casts it to an address to pass to mem_alloc_init()
Rename the variable and use mapmem to convert to an address.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/arm/mach-k3/am65x/am654_init.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-k3/am65x/am654_init.c b/arch/arm/mach-k3/am65x/am654_init.c index a4f038029d7..ddcc1355210 100644 --- a/arch/arm/mach-k3/am65x/am654_init.c +++ b/arch/arm/mach-k3/am65x/am654_init.c @@ -8,6 +8,7 @@
#include <fdt_support.h> #include <init.h> +#include <mapmem.h> #include <asm/global_data.h> #include <asm/io.h> #include <spl.h> @@ -165,7 +166,7 @@ void board_init_f(ulong dummy) #if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS) struct udevice *dev; size_t pool_size;
void *pool_addr;
void *pool; int ret;
#endif /* @@ -204,14 +205,14 @@ void board_init_f(ulong dummy) * malloc pool of which we use all that's left. */ pool_size = CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr;
pool_addr = malloc(pool_size);
if (!pool_addr)
pool = malloc(pool_size);
if (!pool) panic("ERROR: Can't allocate full malloc pool!\n");
mem_malloc_init((ulong)pool_addr, (ulong)pool_size);
mem_malloc_init(map_to_sysmem(pool), (ulong)pool_size); gd->flags |= GD_FLG_FULL_MALLOC_INIT; debug("%s: initialized an early full malloc pool at 0x%08lx of 0x%lx bytes\n",
__func__, (unsigned long)pool_addr, (unsigned long)pool_size);
__func__, (unsigned long)pool, (unsigned long)pool_size); /* * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue * regardless of the result of pinctrl. Do this without probing the
I'm confused since I thought patch 2 removed the need for doing map_to_sysmem() games more widely.
Right, this patch is not actually needed. It just avoids a cast from a pointer, which is always suspicious.
You also forgot to CC anyone from TI that might have comments on if they find "pool" rather than "pool_addr" more or less confusing and given the recent patch from them about what's printed out about memory size, I would think their feedback would be important.
I did cc them on the first version. I don't mind adding maintainers on follow-on patches, but don't want to spam people. I'll try adding maintainers always, for now.
-- Tom
Regards, Simon

Add accessors for bloblist, bootstage, trace and video to avoid needing more #ifdefs in the C code.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/asm-generic/global_data.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index d6c15e2c406..fcf9fa27117 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -544,6 +544,36 @@ static_assert(sizeof(struct global_data) == GD_SIZE); #define gd_set_upl(val) #endif
+#if CONFIG_IS_ENABLED(BLOBLIST) +#define gd_bloblist() gd->bloblist +#else +#define gd_bloblist() NULL +#endif + +#if CONFIG_IS_ENABLED(BOOTSTAGE) +#define gd_bootstage() gd->bootstage +#else +#define gd_bootstage() NULL +#endif + +#if CONFIG_IS_ENABLED(TRACE) +#define gd_trace_buff() gd->trace_buff +#define gd_trace_size() CONFIG_TRACE_BUFFER_SIZE +#else +#define gd_trace_buff() NULL +#define gd_trace_size() 0 +#endif + +#if CONFIG_IS_ENABLED(VIDEO) +#define gd_video_top() gd->video_top +#define gd_video_bottom() gd->video_bottom +#define gd_video_size() (gd->video_top - gd->video_bottom) +#else +#define gd_video_top() 0 +#define gd_video_bottom() 0 +#define gd_video_size() 0 +#endif + /** * enum gd_flags - global data flags *

The bootstage array includes pointers to strings but not the strings themselves. The strings are added when stashing, but including them in the size calculation gives an inflated view of the amount of space used by the array.
Update this function so it can return the amount of memory used by the bootstage structures themselves, without the strings which they point to.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
common/board_f.c | 2 +- common/bootstage.c | 16 +++++++++------- include/bootstage.h | 5 +++-- 3 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 2e04a47b546..bf4252784a4 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -582,7 +582,7 @@ static int reserve_fdt(void) static int reserve_bootstage(void) { #ifdef CONFIG_BOOTSTAGE - int size = bootstage_get_size(); + int size = bootstage_get_size(true);
gd->start_addr_sp = reserve_stack_aligned(size); gd->boardf->new_bootstage = map_sysmem(gd->start_addr_sp, size); diff --git a/common/bootstage.c b/common/bootstage.c index 49acc9078a6..b1506120f9d 100644 --- a/common/bootstage.c +++ b/common/bootstage.c @@ -520,17 +520,19 @@ int _bootstage_unstash_default(void) } #endif
-int bootstage_get_size(void) +int bootstage_get_size(bool add_strings) { - struct bootstage_data *data = gd->bootstage; - struct bootstage_record *rec; int size; - int i;
size = sizeof(struct bootstage_data); - for (rec = data->record, i = 0; i < data->rec_count; - i++, rec++) - size += strlen(rec->name) + 1; + if (add_strings) { + struct bootstage_data *data = gd->bootstage; + struct bootstage_record *rec; + int i; + + for (rec = data->record, i = 0; i < data->rec_count; i++, rec++) + size += strlen(rec->name) + 1; + }
return size; } diff --git a/include/bootstage.h b/include/bootstage.h index 57792648c49..3300ca0248a 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -371,9 +371,10 @@ int bootstage_unstash(const void *base, int size); /** * bootstage_get_size() - Get the size of the bootstage data * + * @add_strings: true to add the size of attached strings (for stashing) * Return: size of boostage data in bytes */ -int bootstage_get_size(void); +int bootstage_get_size(bool add_strings);
/** * bootstage_init() - Prepare bootstage for use @@ -444,7 +445,7 @@ static inline int bootstage_unstash(const void *base, int size) return 0; /* Pretend to succeed */ }
-static inline int bootstage_get_size(void) +static inline int bootstage_get_size(bool add_strings) { return 0; }

In preparation for expanding this command, move it into a separate file. Rename the function to remove the extra underscore. Update the number of arguments to 1, since 3 is incorrect.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Split into its own patch
cmd/Kconfig | 1 + cmd/Makefile | 1 + cmd/mem.c | 19 ------------------- cmd/meminfo.c | 26 ++++++++++++++++++++++++++ 4 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 cmd/meminfo.c
diff --git a/cmd/Kconfig b/cmd/Kconfig index 37894eb80d6..2fd29e9fa88 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -878,6 +878,7 @@ config MD5SUM_VERIFY
config CMD_MEMINFO bool "meminfo" + default y if SANDBOX help Display memory information.
diff --git a/cmd/Makefile b/cmd/Makefile index 91227f1249c..510344509c7 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -110,6 +110,7 @@ obj-$(CONFIG_CMD_LOG) += log.o obj-$(CONFIG_CMD_LSBLK) += lsblk.o obj-$(CONFIG_CMD_MD5SUM) += md5sum.o obj-$(CONFIG_CMD_MEMORY) += mem.o +obj-$(CONFIG_CMD_MEMINFO) += meminfo.o obj-$(CONFIG_CMD_IO) += io.o obj-$(CONFIG_CMD_MII) += mii.o obj-$(CONFIG_CMD_MISC) += misc.o diff --git a/cmd/mem.c b/cmd/mem.c index 4d6fde28531..9e716776393 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -1379,17 +1379,6 @@ U_BOOT_CMD(
#endif
-#ifdef CONFIG_CMD_MEMINFO -static int do_mem_info(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - puts("DRAM: "); - print_size(gd->ram_size, "\n"); - - return 0; -} -#endif - U_BOOT_CMD( base, 2, 1, do_mem_base, "print or set address offset", @@ -1433,14 +1422,6 @@ U_BOOT_CMD( ); #endif /* CONFIG_CMD_MX_CYCLIC */
-#ifdef CONFIG_CMD_MEMINFO -U_BOOT_CMD( - meminfo, 3, 1, do_mem_info, - "display memory information", - "" -); -#endif - #ifdef CONFIG_CMD_RANDOM U_BOOT_CMD( random, 4, 0, do_random, diff --git a/cmd/meminfo.c b/cmd/meminfo.c new file mode 100644 index 00000000000..bb9bcec2e3f --- /dev/null +++ b/cmd/meminfo.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2024 Google LLC + * Written by Simon Glass sjg@chromium.org + */ + +#include <command.h> +#include <display_options.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + puts("DRAM: "); + print_size(gd->ram_size, "\n"); + + return 0; +} + +U_BOOT_CMD( + meminfo, 1, 1, do_meminfo, + "display memory information", + "" +);

On Fri, Oct 11, 2024 at 03:40:30PM -0600, Simon Glass wrote:
In preparation for expanding this command, move it into a separate file. Rename the function to remove the extra underscore. Update the number of arguments to 1, since 3 is incorrect.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Split into its own patch
cmd/Kconfig | 1 + cmd/Makefile | 1 + cmd/mem.c | 19 ------------------- cmd/meminfo.c | 26 ++++++++++++++++++++++++++ 4 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 cmd/meminfo.c
diff --git a/cmd/Kconfig b/cmd/Kconfig index 37894eb80d6..2fd29e9fa88 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -878,6 +878,7 @@ config MD5SUM_VERIFY
config CMD_MEMINFO bool "meminfo"
- default y if SANDBOX
This should be default y for everyone, to keep compatibility, and then your enhancements should be a new option.

U-Boot has a fairly rigid memory map which is normally not visible unless debugging is enabled in board_f.c
Update the 'meminfo' command to show it. This command does not cover arch-specific pieces but gives a good overview of where things are.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Modify the existing 'meminfo' command instead
cmd/meminfo.c | 48 ++++++++++++++- doc/usage/cmd/meminfo.rst | 126 ++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + test/cmd/Makefile | 3 +- test/cmd/meminfo.c | 38 ++++++++++++ 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 doc/usage/cmd/meminfo.rst create mode 100644 test/cmd/meminfo.c
diff --git a/cmd/meminfo.c b/cmd/meminfo.c index bb9bcec2e3f..e9a635bf4bf 100644 --- a/cmd/meminfo.c +++ b/cmd/meminfo.c @@ -4,18 +4,64 @@ * Written by Simon Glass sjg@chromium.org */
+#include <bloblist.h> +#include <bootstage.h> #include <command.h> #include <display_options.h> +#include <malloc.h> +#include <mapmem.h> #include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
+static void print_region(const char *name, ulong base, ulong size, ulong *uptop) +{ + ulong end = base + size; + + printf("%-12s %8lx %8lx %8lx", name, base, size, end); + if (*uptop) + printf(" %8lx", *uptop - end); + putc('\n'); + *uptop = base; +} + static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) + char *const argv[]) { + ulong upto, stk_bot; + puts("DRAM: "); print_size(gd->ram_size, "\n");
+ printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End", + "Gap"); + printf("------------------------------------------------\n"); + upto = 0; + if (IS_ENABLED(CONFIG_VIDEO)) + print_region("video", gd_video_bottom(), + gd_video_size(), &upto); + if (IS_ENABLED(CONFIG_TRACE)) + print_region("trace", map_to_sysmem(gd_trace_buff()), + gd_trace_size(), &upto); + print_region("code", gd->relocaddr, gd->mon_len, &upto); + print_region("malloc", map_to_sysmem((void *)mem_malloc_start), + mem_malloc_end - mem_malloc_start, &upto); + print_region("board_info", map_to_sysmem(gd->bd), + sizeof(struct bd_info), &upto); + print_region("global_data", map_to_sysmem((void *)gd), + sizeof(struct global_data), &upto); + print_region("devicetree", map_to_sysmem(gd->fdt_blob), + fdt_totalsize(gd->fdt_blob), &upto); + if (IS_ENABLED(CONFIG_BOOTSTAGE)) + print_region("bootstage", map_to_sysmem(gd_bootstage()), + bootstage_get_size(false), &upto); + if (IS_ENABLED(CONFIG_BLOBLIST)) + print_region("bloblist", map_to_sysmem(gd_bloblist()), + bloblist_get_total_size(), &upto); + stk_bot = gd->start_addr_sp - CONFIG_STACK_SIZE; + print_region("stack", stk_bot, CONFIG_STACK_SIZE, &upto); + print_region("free", gd->ram_base, stk_bot, &upto); + return 0; }
diff --git a/doc/usage/cmd/meminfo.rst b/doc/usage/cmd/meminfo.rst new file mode 100644 index 00000000000..c628119787e --- /dev/null +++ b/doc/usage/cmd/meminfo.rst @@ -0,0 +1,126 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +.. index:: + single: meminfo (command) + +meminfo command +=============== + +Synopsis +-------- + +:: + + meminfo + +Description +----------- + +The meminfo command shows the amount of memory, the layout of memory used by +U-Boot and the region which is free for use by images. + +The layout of memory is set up before relocation, within the init sequence in +``board_init_f()``, specifically the various ``reserve_...()`` functions. This +'reservation' of memory starts from the top of RAM and proceeds downwards, +ending with the stack. This results in the maximum possible amount of memory +being left free for image-loading. + +The meminfo command writes the DRAM size, then the rest of its outputs in 5 +columns: + +Region + Name of the region + +Base + Base address of the region, i.e. where it starts in memory + +Size + Size of the region, which may be a little smaller than the actual size + reserved, e.g. due to alignment + +End + End of the region. The last byte of the region is one lower than the address + shown here + +Gap + Gap between the end of this region and the base of the one above + +Regions shown are: + +video + Memory reserved for video framebuffers. This reservation happens in the + bind() methods of all video drivers which are present before relocation, + so the size depends on that maximum amount of memory which all such drivers + want to reserve. This may be significantly greater than the amount actually + needed, if the display is ultimately set to a smaller resolution or colour + depth than the maximum supported. + +code + U-Boot's code and Block-Starting Symbol (BSS) region. Before relocation, + U-Boot copies its code to a high region and sets up a BSS immediately after + that. The size of this region is generally therefore ``__bss_end`` - + ``__image_copy_start`` + +malloc + Contains the malloc() heap. The size of this is set by + ``CONFIG_SYS_MALLOC_LEN``. + +board_info + Contains the ``bd_info`` structure, with some information about the current + board. + +global_data + Contains the global-data structure, pointed to by ``gd``. This includes + various pointers, values and flags which control U-Boot. + +devicetree + Contains the flatted devicetree blob (FDT) being used by U-Boot to configure + itself and its devices. + +bootstage + Contains the bootstage records, which keep track of boot time as U-Boot + executes. The size of this is determined by + ``CONFIG_BOOTSTAGE_RECORD_COUNT``, with each record taking approximately + 32 bytes. + +bloblist + Contains the bloblist, which is a list of tables and other data created by + U-Boot while executed. The size of this is determined by + ``CONFIG_BLOBLIST_SIZE``. + +stack + Contains U-Boot's stack, growing downwards from the top. The nominal size of + this region is set by ``CONFIG_STACK_SIZE`` but there is no actual limit + enforced, so the stack can grow behind that. Images should be loaded lower + in memory to avoid any conflict. + +free + Free memory, which is available for loading images. The base address of + this is ``gd->ram_base`` which is generally set by ``CFG_SYS_SDRAM_BASE``. + +Example +------- + +:: + + => meminfo + DRAM: 256 MiB + + Region Base Size End Gap + ------------------------------------------------ + video f000000 1000000 10000000 + code ec3a000 3c5d28 efffd28 2d8 + malloc 8c38000 6002000 ec3a000 0 + board_info 8c37f90 68 8c37ff8 8 + global_data 8c37d80 208 8c37f88 8 + devicetree 8c33000 4d7d 8c37d7d 3 + bootstage 8c32c20 3c8 8c32fe8 18 + bloblist 8c32000 400 8c32400 820 + stack 7c31ff0 1000000 8c31ff0 10 + free 0 7c31ff0 7c31ff0 0 + + +Return value +------------ + +The return value $? is always 0 (true). diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 70563374899..3939add8eaf 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -83,6 +83,7 @@ Shell commands cmd/loads cmd/loadx cmd/loady + cmd/meminfo cmd/mbr cmd/md cmd/mmc diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 8f2134998ad..0f1c8d77dd9 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -18,8 +18,9 @@ obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o obj-$(CONFIG_CMD_HISTORY) += history.o obj-$(CONFIG_CMD_LOADM) += loadm.o -obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o +obj-$(CONFIG_CMD_MEMINFO) += meminfo.o obj-$(CONFIG_CMD_MEMORY) += mem_copy.o +obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o ifdef CONFIG_CMD_PCI obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o endif diff --git a/test/cmd/meminfo.c b/test/cmd/meminfo.c new file mode 100644 index 00000000000..84981305bf0 --- /dev/null +++ b/test/cmd/meminfo.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for 'meminfo' command + * + * Copyright 2024 Google LLC + * Written by Simon Glass sjg@chromium.org + */ + +#include <dm/test.h> +#include <test/cmd.h> +#include <test/ut.h> + +/* Test 'meminfo' command */ +static int cmd_test_meminfo(struct unit_test_state *uts) +{ + ut_assertok(run_command("meminfo", 0)); + ut_assert_nextline("DRAM: 256 MiB"); + ut_assert_nextline_empty(); + + ut_assert_nextline("Region Base Size End Gap"); + ut_assert_nextlinen("-"); + + /* For now we don't worry about checking the values */ + ut_assert_nextlinen("video"); + ut_assert_nextlinen("code"); + ut_assert_nextlinen("malloc"); + ut_assert_nextlinen("board_info"); + ut_assert_nextlinen("global_data"); + ut_assert_nextlinen("devicetree"); + ut_assert_nextlinen("bootstage"); + ut_assert_nextlinen("bloblist"); + ut_assert_nextlinen("stack"); + ut_assert_nextlinen("free"); + ut_assert_console_end(); + + return 0; +} +CMD_TEST(cmd_test_meminfo, UTF_CONSOLE);

Am 11. Oktober 2024 23:40:31 MESZ schrieb Simon Glass sjg@chromium.org:
U-Boot has a fairly rigid memory map which is normally not visible unless debugging is enabled in board_f.c
Update the 'meminfo' command to show it. This command does not cover arch-specific pieces but gives a good overview of where things are.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Modify the existing 'meminfo' command instead
cmd/meminfo.c | 48 ++++++++++++++- doc/usage/cmd/meminfo.rst | 126 ++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + test/cmd/Makefile | 3 +- test/cmd/meminfo.c | 38 ++++++++++++ 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 doc/usage/cmd/meminfo.rst create mode 100644 test/cmd/meminfo.c
diff --git a/cmd/meminfo.c b/cmd/meminfo.c index bb9bcec2e3f..e9a635bf4bf 100644 --- a/cmd/meminfo.c +++ b/cmd/meminfo.c @@ -4,18 +4,64 @@
- Written by Simon Glass sjg@chromium.org
*/
+#include <bloblist.h> +#include <bootstage.h> #include <command.h> #include <display_options.h> +#include <malloc.h> +#include <mapmem.h> #include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
+static void print_region(const char *name, ulong base, ulong size, ulong *uptop) +{
- ulong end = base + size;
- printf("%-12s %8lx %8lx %8lx", name, base, size, end);
- if (*uptop)
printf(" %8lx", *uptop - end);
- putc('\n');
- *uptop = base;
+}
static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
char *const argv[])
{
ulong upto, stk_bot;
puts("DRAM: "); print_size(gd->ram_size, "\n");
printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End",
"Gap");
printf("------------------------------------------------\n");
upto = 0;
if (IS_ENABLED(CONFIG_VIDEO))
print_region("video", gd_video_bottom(),
gd_video_size(), &upto);
if (IS_ENABLED(CONFIG_TRACE))
print_region("trace", map_to_sysmem(gd_trace_buff()),
gd_trace_size(), &upto);
print_region("code", gd->relocaddr, gd->mon_len, &upto);
print_region("malloc", map_to_sysmem((void *)mem_malloc_start),
mem_malloc_end - mem_malloc_start, &upto);
print_region("board_info", map_to_sysmem(gd->bd),
sizeof(struct bd_info), &upto);
print_region("global_data", map_to_sysmem((void *)gd),
sizeof(struct global_data), &upto);
print_region("devicetree", map_to_sysmem(gd->fdt_blob),
fdt_totalsize(gd->fdt_blob), &upto);
if (IS_ENABLED(CONFIG_BOOTSTAGE))
print_region("bootstage", map_to_sysmem(gd_bootstage()),
bootstage_get_size(false), &upto);
if (IS_ENABLED(CONFIG_BLOBLIST))
print_region("bloblist", map_to_sysmem(gd_bloblist()),
bloblist_get_total_size(), &upto);
stk_bot = gd->start_addr_sp - CONFIG_STACK_SIZE;
print_region("stack", stk_bot, CONFIG_STACK_SIZE, &upto);
print_region("free", gd->ram_base, stk_bot, &upto);
return 0;
}
diff --git a/doc/usage/cmd/meminfo.rst b/doc/usage/cmd/meminfo.rst new file mode 100644 index 00000000000..c628119787e --- /dev/null +++ b/doc/usage/cmd/meminfo.rst @@ -0,0 +1,126 @@ +.. SPDX-License-Identifier: GPL-2.0+:
+.. index::
- single: meminfo (command)
+meminfo command +===============
+Synopsis +--------
+::
- meminfo
+Description +-----------
+The meminfo command shows the amount of memory, the layout of memory used by +U-Boot and the region which is free for use by images.
The information offered by this command cannot be used for this purpose as it is incomplete.
Memory allocated in LMB cannot be used to load images. And EFI in future will use LMB for allocations.
The command should be changed to show LMB allocations.
Best regards
Heinrich
+The layout of memory is set up before relocation, within the init sequence in +``board_init_f()``, specifically the various ``reserve_...()`` functions. This +'reservation' of memory starts from the top of RAM and proceeds downwards, +ending with the stack. This results in the maximum possible amount of memory +being left free for image-loading.
+The meminfo command writes the DRAM size, then the rest of its outputs in 5 +columns:
+Region
- Name of the region
+Base
- Base address of the region, i.e. where it starts in memory
+Size
- Size of the region, which may be a little smaller than the actual size
- reserved, e.g. due to alignment
+End
- End of the region. The last byte of the region is one lower than the address
- shown here
+Gap
- Gap between the end of this region and the base of the one above
+Regions shown are:
+video
- Memory reserved for video framebuffers. This reservation happens in the
- bind() methods of all video drivers which are present before relocation,
- so the size depends on that maximum amount of memory which all such drivers
- want to reserve. This may be significantly greater than the amount actually
- needed, if the display is ultimately set to a smaller resolution or colour
- depth than the maximum supported.
+code
- U-Boot's code and Block-Starting Symbol (BSS) region. Before relocation,
- U-Boot copies its code to a high region and sets up a BSS immediately after
- that. The size of this region is generally therefore ``__bss_end`` -
- ``__image_copy_start``
+malloc
- Contains the malloc() heap. The size of this is set by
- ``CONFIG_SYS_MALLOC_LEN``.
+board_info
- Contains the ``bd_info`` structure, with some information about the current
- board.
+global_data
- Contains the global-data structure, pointed to by ``gd``. This includes
- various pointers, values and flags which control U-Boot.
+devicetree
- Contains the flatted devicetree blob (FDT) being used by U-Boot to configure
- itself and its devices.
+bootstage
- Contains the bootstage records, which keep track of boot time as U-Boot
- executes. The size of this is determined by
- ``CONFIG_BOOTSTAGE_RECORD_COUNT``, with each record taking approximately
- 32 bytes.
+bloblist
- Contains the bloblist, which is a list of tables and other data created by
- U-Boot while executed. The size of this is determined by
- ``CONFIG_BLOBLIST_SIZE``.
+stack
- Contains U-Boot's stack, growing downwards from the top. The nominal size of
- this region is set by ``CONFIG_STACK_SIZE`` but there is no actual limit
- enforced, so the stack can grow behind that. Images should be loaded lower
- in memory to avoid any conflict.
+free
- Free memory, which is available for loading images. The base address of
- this is ``gd->ram_base`` which is generally set by ``CFG_SYS_SDRAM_BASE``.
+Example +-------
+::
- => meminfo
- DRAM: 256 MiB
- Region Base Size End Gap
- video f000000 1000000 10000000
- code ec3a000 3c5d28 efffd28 2d8
- malloc 8c38000 6002000 ec3a000 0
- board_info 8c37f90 68 8c37ff8 8
- global_data 8c37d80 208 8c37f88 8
- devicetree 8c33000 4d7d 8c37d7d 3
- bootstage 8c32c20 3c8 8c32fe8 18
- bloblist 8c32000 400 8c32400 820
- stack 7c31ff0 1000000 8c31ff0 10
- free 0 7c31ff0 7c31ff0 0
+Return value +------------
+The return value $? is always 0 (true). diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 70563374899..3939add8eaf 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -83,6 +83,7 @@ Shell commands cmd/loads cmd/loadx cmd/loady
- cmd/meminfo cmd/mbr cmd/md cmd/mmc
diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 8f2134998ad..0f1c8d77dd9 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -18,8 +18,9 @@ obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o obj-$(CONFIG_CMD_HISTORY) += history.o obj-$(CONFIG_CMD_LOADM) += loadm.o -obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o +obj-$(CONFIG_CMD_MEMINFO) += meminfo.o obj-$(CONFIG_CMD_MEMORY) += mem_copy.o +obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o ifdef CONFIG_CMD_PCI obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o endif diff --git a/test/cmd/meminfo.c b/test/cmd/meminfo.c new file mode 100644 index 00000000000..84981305bf0 --- /dev/null +++ b/test/cmd/meminfo.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Test for 'meminfo' command
- Copyright 2024 Google LLC
- Written by Simon Glass sjg@chromium.org
- */
+#include <dm/test.h> +#include <test/cmd.h> +#include <test/ut.h>
+/* Test 'meminfo' command */ +static int cmd_test_meminfo(struct unit_test_state *uts) +{
- ut_assertok(run_command("meminfo", 0));
- ut_assert_nextline("DRAM: 256 MiB");
- ut_assert_nextline_empty();
- ut_assert_nextline("Region Base Size End Gap");
- ut_assert_nextlinen("-");
- /* For now we don't worry about checking the values */
- ut_assert_nextlinen("video");
- ut_assert_nextlinen("code");
- ut_assert_nextlinen("malloc");
- ut_assert_nextlinen("board_info");
- ut_assert_nextlinen("global_data");
- ut_assert_nextlinen("devicetree");
- ut_assert_nextlinen("bootstage");
- ut_assert_nextlinen("bloblist");
- ut_assert_nextlinen("stack");
- ut_assert_nextlinen("free");
- ut_assert_console_end();
- return 0;
+} +CMD_TEST(cmd_test_meminfo, UTF_CONSOLE);

On Sat, Oct 12, 2024 at 01:18:19AM +0200, Heinrich Schuchardt wrote:
Am 11. Oktober 2024 23:40:31 MESZ schrieb Simon Glass sjg@chromium.org:
U-Boot has a fairly rigid memory map which is normally not visible unless debugging is enabled in board_f.c
Update the 'meminfo' command to show it. This command does not cover arch-specific pieces but gives a good overview of where things are.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Modify the existing 'meminfo' command instead
cmd/meminfo.c | 48 ++++++++++++++- doc/usage/cmd/meminfo.rst | 126 ++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + test/cmd/Makefile | 3 +- test/cmd/meminfo.c | 38 ++++++++++++ 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 doc/usage/cmd/meminfo.rst create mode 100644 test/cmd/meminfo.c
diff --git a/cmd/meminfo.c b/cmd/meminfo.c index bb9bcec2e3f..e9a635bf4bf 100644 --- a/cmd/meminfo.c +++ b/cmd/meminfo.c @@ -4,18 +4,64 @@
- Written by Simon Glass sjg@chromium.org
*/
+#include <bloblist.h> +#include <bootstage.h> #include <command.h> #include <display_options.h> +#include <malloc.h> +#include <mapmem.h> #include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
+static void print_region(const char *name, ulong base, ulong size, ulong *uptop) +{
- ulong end = base + size;
- printf("%-12s %8lx %8lx %8lx", name, base, size, end);
- if (*uptop)
printf(" %8lx", *uptop - end);
- putc('\n');
- *uptop = base;
+}
static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
char *const argv[])
{
ulong upto, stk_bot;
puts("DRAM: "); print_size(gd->ram_size, "\n");
printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End",
"Gap");
printf("------------------------------------------------\n");
upto = 0;
if (IS_ENABLED(CONFIG_VIDEO))
print_region("video", gd_video_bottom(),
gd_video_size(), &upto);
if (IS_ENABLED(CONFIG_TRACE))
print_region("trace", map_to_sysmem(gd_trace_buff()),
gd_trace_size(), &upto);
print_region("code", gd->relocaddr, gd->mon_len, &upto);
print_region("malloc", map_to_sysmem((void *)mem_malloc_start),
mem_malloc_end - mem_malloc_start, &upto);
print_region("board_info", map_to_sysmem(gd->bd),
sizeof(struct bd_info), &upto);
print_region("global_data", map_to_sysmem((void *)gd),
sizeof(struct global_data), &upto);
print_region("devicetree", map_to_sysmem(gd->fdt_blob),
fdt_totalsize(gd->fdt_blob), &upto);
if (IS_ENABLED(CONFIG_BOOTSTAGE))
print_region("bootstage", map_to_sysmem(gd_bootstage()),
bootstage_get_size(false), &upto);
if (IS_ENABLED(CONFIG_BLOBLIST))
print_region("bloblist", map_to_sysmem(gd_bloblist()),
bloblist_get_total_size(), &upto);
stk_bot = gd->start_addr_sp - CONFIG_STACK_SIZE;
print_region("stack", stk_bot, CONFIG_STACK_SIZE, &upto);
print_region("free", gd->ram_base, stk_bot, &upto);
return 0;
}
diff --git a/doc/usage/cmd/meminfo.rst b/doc/usage/cmd/meminfo.rst new file mode 100644 index 00000000000..c628119787e --- /dev/null +++ b/doc/usage/cmd/meminfo.rst @@ -0,0 +1,126 @@ +.. SPDX-License-Identifier: GPL-2.0+:
+.. index::
- single: meminfo (command)
+meminfo command +===============
+Synopsis +--------
+::
- meminfo
+Description +-----------
+The meminfo command shows the amount of memory, the layout of memory used by +U-Boot and the region which is free for use by images.
The information offered by this command cannot be used for this purpose as it is incomplete.
Memory allocated in LMB cannot be used to load images. And EFI in future will use LMB for allocations.
The command should be changed to show LMB allocations.
I agree, this need to include the lmb information as that's quite likely to be helpful to anyone wondering "well where can I place things then?" when denied being able to load an image somewhere.

Hi all,
On Sat, 12 Oct 2024 at 04:42, Tom Rini trini@konsulko.com wrote:
On Sat, Oct 12, 2024 at 01:18:19AM +0200, Heinrich Schuchardt wrote:
Am 11. Oktober 2024 23:40:31 MESZ schrieb Simon Glass sjg@chromium.org:
U-Boot has a fairly rigid memory map which is normally not visible unless debugging is enabled in board_f.c
Update the 'meminfo' command to show it. This command does not cover arch-specific pieces but gives a good overview of where things are.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Modify the existing 'meminfo' command instead
cmd/meminfo.c | 48 ++++++++++++++- doc/usage/cmd/meminfo.rst | 126 ++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + test/cmd/Makefile | 3 +- test/cmd/meminfo.c | 38 ++++++++++++ 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 doc/usage/cmd/meminfo.rst create mode 100644 test/cmd/meminfo.c
diff --git a/cmd/meminfo.c b/cmd/meminfo.c index bb9bcec2e3f..e9a635bf4bf 100644 --- a/cmd/meminfo.c +++ b/cmd/meminfo.c @@ -4,18 +4,64 @@
- Written by Simon Glass sjg@chromium.org
*/
+#include <bloblist.h> +#include <bootstage.h> #include <command.h> #include <display_options.h> +#include <malloc.h> +#include <mapmem.h> #include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
+static void print_region(const char *name, ulong base, ulong size, ulong *uptop) +{
- ulong end = base + size;
- printf("%-12s %8lx %8lx %8lx", name, base, size, end);
- if (*uptop)
printf(" %8lx", *uptop - end);
- putc('\n');
- *uptop = base;
+}
static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
char *const argv[])
{
ulong upto, stk_bot;
puts("DRAM: "); print_size(gd->ram_size, "\n");
printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End",
"Gap");
printf("------------------------------------------------\n");
upto = 0;
if (IS_ENABLED(CONFIG_VIDEO))
print_region("video", gd_video_bottom(),
gd_video_size(), &upto);
if (IS_ENABLED(CONFIG_TRACE))
print_region("trace", map_to_sysmem(gd_trace_buff()),
gd_trace_size(), &upto);
print_region("code", gd->relocaddr, gd->mon_len, &upto);
print_region("malloc", map_to_sysmem((void *)mem_malloc_start),
mem_malloc_end - mem_malloc_start, &upto);
print_region("board_info", map_to_sysmem(gd->bd),
sizeof(struct bd_info), &upto);
print_region("global_data", map_to_sysmem((void *)gd),
sizeof(struct global_data), &upto);
print_region("devicetree", map_to_sysmem(gd->fdt_blob),
fdt_totalsize(gd->fdt_blob), &upto);
if (IS_ENABLED(CONFIG_BOOTSTAGE))
print_region("bootstage", map_to_sysmem(gd_bootstage()),
bootstage_get_size(false), &upto);
if (IS_ENABLED(CONFIG_BLOBLIST))
print_region("bloblist", map_to_sysmem(gd_bloblist()),
bloblist_get_total_size(), &upto);
stk_bot = gd->start_addr_sp - CONFIG_STACK_SIZE;
print_region("stack", stk_bot, CONFIG_STACK_SIZE, &upto);
print_region("free", gd->ram_base, stk_bot, &upto);
return 0;
}
diff --git a/doc/usage/cmd/meminfo.rst b/doc/usage/cmd/meminfo.rst new file mode 100644 index 00000000000..c628119787e --- /dev/null +++ b/doc/usage/cmd/meminfo.rst @@ -0,0 +1,126 @@ +.. SPDX-License-Identifier: GPL-2.0+:
+.. index::
- single: meminfo (command)
+meminfo command +===============
+Synopsis +--------
+::
- meminfo
+Description +-----------
+The meminfo command shows the amount of memory, the layout of memory used by +U-Boot and the region which is free for use by images.
The information offered by this command cannot be used for this purpose as it is incomplete.
Memory allocated in LMB cannot be used to load images. And EFI in future will use LMB for allocations.
The command should be changed to show LMB allocations.
I agree, this need to include the lmb information as that's quite likely to be helpful to anyone wondering "well where can I place things then?" when denied being able to load an image somewhere.
I think we all agree, but since the LMB patches are not in place should we wait to pull this? Or pull it since it's an improvement anyway and retrifit the LMB and perhaps EFI regions once LMB is good to merge?
Thanks /Ilias
-- Tom

Hi Ilias,
On Mon, 14 Oct 2024 at 11:57, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi all,
On Sat, 12 Oct 2024 at 04:42, Tom Rini trini@konsulko.com wrote:
On Sat, Oct 12, 2024 at 01:18:19AM +0200, Heinrich Schuchardt wrote:
Am 11. Oktober 2024 23:40:31 MESZ schrieb Simon Glass sjg@chromium.org:
U-Boot has a fairly rigid memory map which is normally not visible unless debugging is enabled in board_f.c
Update the 'meminfo' command to show it. This command does not cover arch-specific pieces but gives a good overview of where things are.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Modify the existing 'meminfo' command instead
cmd/meminfo.c | 48 ++++++++++++++- doc/usage/cmd/meminfo.rst | 126 ++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + test/cmd/Makefile | 3 +- test/cmd/meminfo.c | 38 ++++++++++++ 5 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 doc/usage/cmd/meminfo.rst create mode 100644 test/cmd/meminfo.c
diff --git a/cmd/meminfo.c b/cmd/meminfo.c index bb9bcec2e3f..e9a635bf4bf 100644 --- a/cmd/meminfo.c +++ b/cmd/meminfo.c @@ -4,18 +4,64 @@
- Written by Simon Glass sjg@chromium.org
*/
+#include <bloblist.h> +#include <bootstage.h> #include <command.h> #include <display_options.h> +#include <malloc.h> +#include <mapmem.h> #include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
+static void print_region(const char *name, ulong base, ulong size, ulong *uptop) +{
- ulong end = base + size;
- printf("%-12s %8lx %8lx %8lx", name, base, size, end);
- if (*uptop)
printf(" %8lx", *uptop - end);
- putc('\n');
- *uptop = base;
+}
static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
char *const argv[])
{
ulong upto, stk_bot;
puts("DRAM: "); print_size(gd->ram_size, "\n");
printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End",
"Gap");
printf("------------------------------------------------\n");
upto = 0;
if (IS_ENABLED(CONFIG_VIDEO))
print_region("video", gd_video_bottom(),
gd_video_size(), &upto);
if (IS_ENABLED(CONFIG_TRACE))
print_region("trace", map_to_sysmem(gd_trace_buff()),
gd_trace_size(), &upto);
print_region("code", gd->relocaddr, gd->mon_len, &upto);
print_region("malloc", map_to_sysmem((void *)mem_malloc_start),
mem_malloc_end - mem_malloc_start, &upto);
print_region("board_info", map_to_sysmem(gd->bd),
sizeof(struct bd_info), &upto);
print_region("global_data", map_to_sysmem((void *)gd),
sizeof(struct global_data), &upto);
print_region("devicetree", map_to_sysmem(gd->fdt_blob),
fdt_totalsize(gd->fdt_blob), &upto);
if (IS_ENABLED(CONFIG_BOOTSTAGE))
print_region("bootstage", map_to_sysmem(gd_bootstage()),
bootstage_get_size(false), &upto);
if (IS_ENABLED(CONFIG_BLOBLIST))
print_region("bloblist", map_to_sysmem(gd_bloblist()),
bloblist_get_total_size(), &upto);
stk_bot = gd->start_addr_sp - CONFIG_STACK_SIZE;
print_region("stack", stk_bot, CONFIG_STACK_SIZE, &upto);
print_region("free", gd->ram_base, stk_bot, &upto);
return 0;
}
diff --git a/doc/usage/cmd/meminfo.rst b/doc/usage/cmd/meminfo.rst new file mode 100644 index 00000000000..c628119787e --- /dev/null +++ b/doc/usage/cmd/meminfo.rst @@ -0,0 +1,126 @@ +.. SPDX-License-Identifier: GPL-2.0+:
+.. index::
- single: meminfo (command)
+meminfo command +===============
+Synopsis +--------
+::
- meminfo
+Description +-----------
+The meminfo command shows the amount of memory, the layout of memory used by +U-Boot and the region which is free for use by images.
The information offered by this command cannot be used for this purpose as it is incomplete.
Memory allocated in LMB cannot be used to load images. And EFI in future will use LMB for allocations.
The command should be changed to show LMB allocations.
I agree, this need to include the lmb information as that's quite likely to be helpful to anyone wondering "well where can I place things then?" when denied being able to load an image somewhere.
I think we all agree, but since the LMB patches are not in place should we wait to pull this? Or pull it since it's an improvement anyway and retrifit the LMB and perhaps EFI regions once LMB is good to merge?
I think it can go in now.
But I will say that I am very-much in favour of a setup where the EFI memory appears in the 'meminfo' table, but within the U-Boot area.
Showing lmb is kind-of useless since the areas don't have any names. I am working on a series for that, but it might be a few days...
Regards, Simon
participants (4)
-
Heinrich Schuchardt
-
Ilias Apalodimas
-
Simon Glass
-
Tom Rini