[PATCH] Fix detection of odd memory configurations on sunxi

Jernej Škrabec jernej.skrabec at gmail.com
Sun Oct 5 08:38:32 CEST 2025


Dne nedelja, 5. oktober 2025 ob 08:10:27 Srednjeevropski poletni čas je Jernej Škrabec napisal(a):
> Hi Andre!
> 
> Dne nedelja, 5. oktober 2025 ob 02:40:21 Srednjeevropski poletni čas je Andre Przywara napisal(a):
> > On Mon, 11 Aug 2025 09:35:19 +0200
> > Rudi Horn <dyn-git at rudi-horn.de> wrote:
> > 
> > Hi Rudi,
> > 
> > thanks for sending a patch to address this long-standing issue!
> > 
> > But ... ;-)
> > 
> > > I encountered a bug where u-boot detects that my OrangePI zero 3 (with 
> > > 1.5GB) has 2GB and crashes.
> > 
> > As Jernej already said, this is a known limitation: we simply don't
> > support not-power-of-2 DRAM sizes at the moment.
> > 
> > > The orangepi u-boot source code contains an additional
> > > modification in the `mctl_calc_size` which removes a quarter of the 
> > > memory the
> > > calculated last address cannot be written to:
> > > 
> > > https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
> > > 
> > > I'm not entirely sure if there is some specific logic that applies to this
> > > modifier, but it does fix the issue on my system.
> > 
> > So can someone shed some light on how this is supposed to work? If I
> > understand the code correctly, it checks for *aliasing* between the
> > first and the last word of DRAM, which doesn't make much sense to me: I
> > would expect a simple write/verify to see if the last quarter of DRAM
> > is for real, or to check for a known aliasing pattern with this "odd"
> > setup (as in: last quarter is aliased to first or third quarter or
> > something), but checking those two words for aliasing seems wrong.
> 
> Hm... I've never tested this patch on HW, so you might have a point. Still,
> I think testing for aliasing makes sense. Just writing and reading might
> not be enough due to possible caching (not necessarily in CPU).

I see where the confusion comes from. Rudi tried to replicate OrangePi code
but inadvertently used function for aliasing check instead of write/verify
as noticed by Andre.

While probably using OrangePi approach [1] would work fine, I learned to
distrust simple write/verify checks, especially when size is only 1 word.
I would be still more confortable to use current aliasing check, which uses
16 words check.

Best regards,
Jernej

[1] https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_helpers.c#L48-L63

> 
> I should have some board with non-power-of-2 RAM size somewhere. I'll try
> to find it and test this.
> 
> > 
> > And indeed the code also fires on a board with 512MB and 4GB, capping
> > the memory there as well (resulting in 384 MB and 3GB, respectively).
> > This is somewhat expected, as we never would expect aliasing between
> > those two particular words, I'd say.
> > 
> > So since I don't have a board with an "uneven" DRAM size, can you
> > please test some ideas to detect this RAM setup?
> > - Read the content of the first word to not exist (@1.5GB), then write
> >   something else there, and see if you can read this back? Don't forget
> >   a write barrier (dsb();) when doing so.
> > - Write some test pattern to some known good DRAM locations, like the
> >   beginning of DRAM, @512MB, @1GB, and see if any of those values pop
> >   up @1.5GB, to see if there is an aliasing pattern?
> > - Can you post the exact label on that DRAM chip, so that we can see if
> >   we find a datasheet? I'd be curious about the actual organisation of
> >   the DRAM array.
> > 
> > Jernej, do you happen to know how those DRAM chips are organised? Do
> > they just feature a non-power-of-2 number of rows or columns?
> 
> I don't know details how such chips are organized internally. However,
> number of rows and columns was never power-of-2.
> 
> Btw, I think I saw 3 GB DRAM boards too somewhere, but not sure where.
> Quick search confirms that 24 Gb DRAM chips also exists, so I would leave
> this check as general 3/4 size fixup, not limited to any capacity.
> 
> > 
> > Oh, and also this patch was heavily malformed - line breaks and spaces
> > instead of tabs. Please try to fix this. Simplest is probably "git
> > format-patch", then sending this via "git send-email". Your email
> > server seems to be postfix, so you could just give the SMTP details and
> > credentials to git.
> > 
> > Cheers,
> > Andre
> > 
> > 
> > > 
> > > I propose the following patch, but am open to any further suggestions.
> > > 
> > > Thanks,
> > > Rudi Horn
> > > 
> > > Note: Submitted in my personal capacity and is not affiliated with my 
> > > employer.
> > > 
> > > 
> > >  From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> > > From: Rudi Horn <dyn-git at rudi-horn.de>
> > > Date: Mon, 11 Aug 2025 08:58:34 +0200
> > > Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> > >   configurations
> > > 
> > > Fix detection of odd memory configurations. Previously 1.5GB devices were
> > > incorrectly detected as 2GB devices, causing u-boot to crash.
> > > 
> > > Signed-off-by: Rudi Horn <dyn-git at rudi-horn.de>
> > > ---
> > >   arch/arm/include/asm/arch-sunxi/dram.h |  1 +
> > >   arch/arm/mach-sunxi/dram_dw_helpers.c  | 10 +++++++++-
> > >   arch/arm/mach-sunxi/dram_helpers.c     |  8 ++++++++
> > >   3 files changed, 18 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm/include/asm/arch-sunxi/dram.h 
> > > b/arch/arm/include/asm/arch-sunxi/dram.h
> > > index 0eccb1e6c28..7580421ca77 100644
> > > --- a/arch/arm/include/asm/arch-sunxi/dram.h
> > > +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> > > @@ -44,6 +44,7 @@
> > >   unsigned long sunxi_dram_init(void);
> > >   void mctl_await_completion(u32 *reg, u32 mask, u32 val);
> > >   bool mctl_mem_matches(u32 offset);
> > > +bool mctl_mem_matches_upto(u32 offset);
> > >   bool mctl_mem_matches_base(u32 offset, ulong base);
> > > 
> > >   #endif /* _SUNXI_DRAM_H */
> > > diff --git a/arch/arm/mach-sunxi/dram_dw_helpers.c 
> > > b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > index 24767354935..5bcd2672465 100644
> > > --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct 
> > > dram_config *config)
> > >          u8 width = config->bus_full_width ? 4 : 2;
> > > 
> > >          /* 8 banks */
> > > -       return (1ULL << (config->cols + config->rows + 3)) * width * 
> > > config->ranks;
> > > +       unsigned long size = (1ULL << (config->cols + config->rows + 3)) 
> > > * width * config->ranks;
> > > +
> > > +       /* some memory configurations such as 1.5GB rely on this to 
> > > compute the correct size */
> > > +       if (!mctl_mem_matches_upto(size)) {
> > > +               size = (size * 3) / 4;
> > > +               debug("capping memory at 0x%lx\n", size);
> > > +       }
> > > +
> > > +  return size;
> > >   }
> > > diff --git a/arch/arm/mach-sunxi/dram_helpers.c 
> > > b/arch/arm/mach-sunxi/dram_helpers.c
> > > index 83dbe4ca98f..68c75fa07a6 100644
> > > --- a/arch/arm/mach-sunxi/dram_helpers.c
> > > +++ b/arch/arm/mach-sunxi/dram_helpers.c
> > > @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> > >   {
> > >          return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> > >   }
> > > +
> > > +/*
> > > + * Test if memory at offset matches memory at end of DRAM
> > > + */
> > > +bool mctl_mem_matches_upto(u32 offset)
> > > +{
> > > +       return mctl_mem_matches_base(offset - sizeof(u32), 
> > > CFG_SYS_SDRAM_BASE);
> > > +}
> > >   #endif
> > > --
> > > 2.43.0
> > > 
> > 
> > 
> 
> 
> 
> 
> 






More information about the U-Boot mailing list