
On 3 Apr 2018, at 12:39, Icenowy Zheng icenowy@aosc.io wrote:
于 2018年4月3日 GMT+08:00 下午6:13:17, Andre Przywara <andre.przywara@arm.com mailto:andre.przywara@arm.com> 写到:
Hi,
On 03/04/18 10:29, Maxime Ripard wrote:
On Thu, Mar 29, 2018 at 01:21:38PM +0100, Andre Przywara wrote:
Hi,
On 29/03/18 10:37, Maxime Ripard wrote:
On Wed, Mar 28, 2018 at 07:31:51PM +0800, Icenowy Zheng wrote:
于 2018年3月28日 GMT+08:00 下午7:28:07, Maxime Ripard
> On Mon, Mar 26, 2018 at 03:11:04PM +0800, Icenowy Zheng wrote: >> >> >> 于 2018年3月26日 GMT+08:00 下午3:06:33, Maxime Ripard > maxime.ripard@bootlin.com 写到: >>> On Fri, Mar 23, 2018 at 05:41:43PM +0800, Icenowy Zheng wrote: >>>> >>>> >>>> 于 2018年3月23日 GMT+08:00 下午5:40:41, Maxime Ripard >>> maxime.ripard@bootlin.com 写到: >>>>> On Fri, Mar 23, 2018 at 04:18:56PM +0800, Icenowy Zheng
wrote:
>>>>>> The get_ram_size() function in U-Boot can only deal with
memory
>>> size >>>>>> smaller than 2GiB. To enable the support of 3GiB DRAM on
newer
>>> 64-bit >>>>>> SoCs, an alternative way to detect DRAM size is needed. >>>>> >>>>> Why not just fixing get_ram_size then? >>>> >>>> Even if it's fixed it won't support 3GiB DRAM at all. >>> >>> Why? >> >> It has an assumption that the size is pow of 2. > > I guess this would be fixable too? (or one could create a variant > without that assumption).
I don't think its principle allows such kind of fix, as it just checks writing then reading at some offset that is pow if 2.
You could do have a bunch of algorithm actually. One would be to
write
the address in memory and try to detect where exactly it starts to loop.
You could do a bisection in the opposite direction once you settled for the upper limit (so you would have for example a workable 2G, a non-workable 4G, and then you try intervals that you always divide
by
two, so testing then 3G (that works), then halfway between 3G and
4G,
etc.
For hacking it, see my implementation in v1, which assumes the only size supported bigger than 2GiB is 3GiB (which is acceptable on sunxi, but might not work on other platforms).
As Andre said, that function has another big problem -- it detects memory with writing to it. This is risky.
How is it risky when it's done by the SPL?
Originally that was my confusion as well: It's not the SPL calling
that
function. The DRAM controller init function in there knows very precisely how much DRAM we have, but we don't communicate this to
U-Boot
proper. So U-Boot *proper* goes ahead and probes the DRAM. This
means it
could step into secure memory, for instance. On sunxi64 we have the
ATF
running between SPL and U-Boot, also all kind of secure payloads
could
already have been registered. So I wonder if it would be easier to somehow pass on this *one* word
of
information between SPL and U-Boot proper to avoid calling this
function
altogether?
That would definitely make sense yes.
So since the SPL loads the DT anyway (from the FIT image) and puts it at the end of the U-Boot (proper) binary, wouldn't it be the easiest to just patch the actual DRAM size in there? IIRC we don't have any FDT write code in the SPL at the moment, and pulling it in would probably push it over the edge again, but: We should be able to somewhat short-cut it, if it's just about to actually *patch* an existing value, as of:
- make sure we have a memory node and a reg property in the DT
- in the SPL learn the fdt offset of that reg property
- <hack> patch in the memory size into the second word </hack>
- teach U-Boot proper to read the memory size from the DT
- optionally look at #address-cells and #size-cells to make this
"second word hack" more robust
This could actually be a rather generic patch, just with some "avoid libfdt write library" hack to address our size issue. Maybe we already have something like that for some platform (Rockchip comes to mind?)
Rockchip recalculates the memory size with the parameters in GRF when running the main U-Boot, so both TPL/SPL and miniloader can load mainline U-Boot.
More accurately, the GRF currently is used to store an encoded DRAM configuration and the next stage can rely on this being there.
If the memory is initialised by miniloader, U-Boot reads the GRF and calculates the memory size from that. If U-Boot sets up DRAM, then it also populates the GRF registers.
With more and more SOCs moving away from miniloader, there’s a good chance that this will change at some point in the future and the GRF may not necessarily be populated anymore.
—Philipp.