[PATCH] board_f: show_dram_config: Print also real DRAM size
Simon Glass
sjg at chromium.org
Mon Sep 12 15:34:47 CEST 2022
Hi Pali,
On Sun, 11 Sept 2022 at 03:39, Pali Rohár <pali at kernel.org> wrote:
>
> 32-bit U-Boot builds cannot use more than around 2 GB of DDR memory. But on
> some platforms/boards it is possible to connect also 4 GB SODIMM DDR memory.
> U-Boot currently prints only effective size of RAM which can use, which may
> be misleading as somebody would expect that this line prints total size of
> connected DDR modules. So change show_dram_config code to prints both real
> and effective DRAM size if they are different. If they are same then print
> just one number like before. It is possible that effective size is just few
> bytes smaller than the real size, so print both numbers only in case
> function print_size() prints formats them differently.
>
> Signed-off-by: Pali Rohár <pali at kernel.org>
> ---
> common/board_f.c | 31 ++++++++++++++++++++++++++++++-
> 1 file changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/common/board_f.c b/common/board_f.c
> index 9e34fbee147e..3131a06db940 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -54,6 +54,7 @@
> #include <asm/sections.h>
> #include <dm/root.h>
> #include <linux/errno.h>
> +#include <linux/log2.h>
>
> /*
> * Pointer to initial global data area
> @@ -213,6 +214,30 @@ static int announce_dram_init(void)
> return 0;
> }
>
> +/*
> + * Check if the sizes in their natural units written in decimal format with
> + * one fraction number are same.
> + */
> +static int sizes_near(unsigned long long size1, unsigned long long size2)
> +{
> + unsigned int size1_scale = ilog2(size1) / 10 * 10;
> + unsigned int size1_val = (10 * size1 + ((1ULL << size1_scale) >> 1)) >> size1_scale;
> + unsigned int size2_scale = ilog2(size2) / 10 * 10;
> + unsigned int size2_val = (10 * size2 + ((1ULL << size2_scale) >> 1)) >> size2_scale;
Can you put that expression into a function with a comment, etc.? It
is a bit hard to understand.
> +
> + if (size1_val == 10240) {
> + size1_val = 10;
> + size1_scale += 10;
> + }
> +
> + if (size2_val == 10240) {
> + size2_val = 10;
> + size2_scale += 10;
> + }
If you are doing the same thing to each, why bother? It should not
affect the expression below, should it? :
> +
> + return size1_scale == size2_scale && size1_val == size2_val;
> +}
> +
> static int show_dram_config(void)
> {
> unsigned long long size;
> @@ -229,7 +254,11 @@ static int show_dram_config(void)
> }
> debug("\nDRAM: ");
>
> - print_size(size, "");
> + print_size(gd->ram_size, "");
> + if (!sizes_near(gd->ram_size, size)) {
> + printf(" (effective ");
> + print_size(size, ")");
> + }
> board_add_ram_info(0);
> putc('\n');
>
> --
> 2.20.1
>
Can we make this testable somehow? You could put the new code into a
lib/ function, perhaps, and call it from a C unit test in test/lib ?
Regards,
Simon
More information about the U-Boot
mailing list