[U-Boot] [PATCH 2/9] sunxi: Move SPL s_init() code to board_init_f()

Simon Glass sjg at chromium.org
Sun Feb 1 21:59:41 CET 2015


Hi Siarhei,

On 1 February 2015 at 11:37, Siarhei Siamashka <siarhei.siamashka at gmail.com>
wrote:
> On Sun, 1 Feb 2015 10:00:43 -0700
> Simon Glass <sjg at chromium.org> wrote:
>
>> Hi Siarhei,
>>
>> On 1 February 2015 at 09:45, Siarhei Siamashka
>> <siarhei.siamashka at gmail.com> wrote:
>> > On Sun, 1 Feb 2015 09:29:53 -0700
>> > Simon Glass <sjg at chromium.org> wrote:
>> >
>> >> Hi,
>> >>
>> >> On 30 January 2015 at 10:53, Siarhei Siamashka
>> >> <siarhei.siamashka at gmail.com> wrote:
>> >> > On Mon, 29 Dec 2014 09:15:36 -0700
>> >> > Simon Glass <sjg at chromium.org> wrote:
>> >> >
>> >> >> Hi Ian,
>> >> >>
>> >> >> On 28 December 2014 at 02:19, Ian Campbell <ijc at hellion.org.uk>
wrote:
>> >> >> > On Tue, 2014-12-23 at 12:04 -0700, Simon Glass wrote:
>> >> >> >
>> >> >> >> +void board_init_f(ulong dummy)
>> >> >> >> +{
>> >> >> > [...]
>> >> >> >> + /* Clear the BSS. */
>> >> >> >> + memset(__bss_start, 0, __bss_end - __bss_start);
>> >> >> >> +
>> >> >> >> + board_init_r(NULL, 0);
>> >> >> >
>> >> >> > The previous (__weak) version of board_init_f also sets gd,
which you've
>> >> >> > also removed from s_init here and not added back anywhere
(indeed, this
>> >> >> > is the point...). But where is gd initialised now?
>> >> >>
>> >> >> It's still in start.S, I've just removed this duplicate.
>> >> >>
>> >> >> >
>> >> >> > The patch generally looks good, two quick questions: has it been
tested
>> >> >> > in both FEL and regular mode, and has it been tested with a
"legacy" as
>> >> >> > well as a driver model system? (I might be able to find time in
a day or
>> >> >> > two to answer these myself, but for now I'll just ask).
>> >> >>
>> >> >> I haven't tried FEL, I only just heard of it in your email. I'll
see
>> >> >> if I can figure out how to test that.
>> >> >
>> >> > Just like Ian suspected, this patch has messed up the FEL boot mode
>> >> > support.
>> >> >
>> >> > In a nutshell, FEL is a special USB protocol (accessible on a USB
OTG
>> >> > connector), which is implemented by the boot ROM and activated by
>> >> > holding a special hardware button pressed and rebooting the device.
>> >> > FEL supports commands to read/write device RAM and execute code on
>> >> > the device. It is designed for device unbricking and firmware
recovery.
>> >>
>> >> If I understand it correctly, this is the same function that is
>> >> available on Exynos5, Tegra, MX6 and probably others.
>> >>
>> >> >
>> >> > In particular, the FEL boot mode support is very useful for
debugging
>> >> > u-boot and kernel problems on tablets (the SD card slot can be used
>> >> > for the UART console, while the system is booted over a micro-USB
cable
>> >> > with the help of FEL):
>> >> > http://linux-sunxi.org/File:MSI_Primo81_and_MicroSD_breakout.jpg
>> >> >
>> >> > In u-boot it is used in the following way:
>> >> > 1. The SPL code is uploaded from the linux PC to the device SRAM via
>> >> > a FEL command (using the 'fel' program from sunxi-tools).
>> >> > 2. The SPL code is executed via a FEL command and expected to
>> >> > initialize the DRAM controller. The code is executed as a
>> >> > normal C or assembly function, which needs to return control
>> >> > back to the BROM code when it is done. Right now this
>> >> > function is s_init().
>> >>
>> >> Isn't this just another way of loading SPL then? What is so special /
>> >> different about FEL?
>> >
>> > I'm not very familiar with the other platforms, but the special part
>> > here is "needs to return control back to the BROM code when it is
done".
>> >
>> > We are relying on the FEL USB protocol implementation, which is
>> > hardcoded in BROM. FEL is used to upload data over USB to the device
>> > memory. And FEL needs to be used twice. Once for uploading data to SRAM
>> > and running the SPL. And one more time for uploading the rest of the
>> > data to DRAM.
>> >
>> > As we naturally can't modify the Allwinner code in BROM, here u-boot
>> > needs to play according to the FEL rules and not the other way around.
>> >
>> > As I see it, an alternative solution would be to implement USB OTG
>> > support and the FEL protocol (or some other protocol) in the u-boot
>> > SPL and stop relying on BROM code for uploading data to DRAM. Until
>> > this is done, the sunxi FEL variant of SPL needs to return control to
>> > the BROM code nicely after it has initialized DRAM and abstain from
>> > doing anything else.
>> >
>> > I hope that this clarifies the situation.
>>
>> Exynos calls back into its IROM also from SPL, when it sees that it is
>> in USB A-A mode. See arch/arm/cpu/armv7/exynos/spl_boot.c where you
>> will find a table of IROM entry points.
>
> I think that the difference is a matter of who calls whom. In the
> case of Exynos, the SPL can call iROM functions. But in the case of
> Allwinner, the whole SPL works as a kind of plugin, which is called
> from the BROM code.
>
> I'm not sure if the Allwinner BROM can be used in the same way as
> the Exynos iROM, because the Allwinner BROM is not documented at all
> as far as I know. Exynos probably has a better documentation.
>
>> I think it is fine to use the BROM and FEL, I am just concerned that
>> we need to stop using gdata and make FEL fit within the existing SPL
>> sequence. We need to avoid an SOC-specific hack, and if such a hack is
>> needed, it should be localised to sunxi and not rely on gdata, etc.
>
> Yes, I agree. At least in the long term.
>
> But in the short term it would be very nice to get the FEL boot
> mode working again in the v2015.04 release.

I agree on that last point - but I think we should get this working
properly (without gdata) in the short term. We missed the last merge window
with our SPL fixes and I'm pretty determined that we don't miss this one.

>
>> When you say 'return back to BROM', what exactly is a 'return'? Does
>> it mean that you need to jump to a return address in one of the
>> registers, or something else?
>
> The return address to the BROM code is in the 'lr' register. Just like
> in the case of calling any normal function.

OK I see. It does not seem radically different from how Exynos works, in
that all exynos does after the USB download completes is jump to U-Boot.

>
>> Can you point me to the code that does this and instructions on
>> how to use it? Then I could try it out and try to understand it better.
>
> A comprehensive FEL usage guide is supposed to be in the linux-sunxi
> wiki. But it might be not very up to date with the mainline u-boot
> usage.
>
> Anyway, first just clone the https://github.com/linux-sunxi/sunxi-tools
> repository and build it. This will provide you with the x86 binary of
> the 'fel' tool, which is used on your desktop PC to talk with the
> device.
>
> Then connect the device to your PC using a "USB A to USB mini/micro B"
> cable. And reset the board while keeping the "FEL" button pressed. The
> button might be labelled as "UPGRADE" on your pcduino3 board:
> http://linux-sunxi.org/LinkSprite_pcDuino_V3#FEL_mode
>
> Then just run "fel ver" command:
> http://linux-sunxi.org/FEL#Running_the_fel_tool
>
> If everything is fine, it should respond with something like this:
> AWUSBFEX soc=00162500(A13) 00000001 ver=0001 44 08 scratchpad=00007e00
> 00000000 00000000
>
> Now you can use "write" commands to upload data to SRAM. And "exe"
> command to execute functions on the device (works as some kind of RPC):
> http://linux-sunxi.org/FEL/USBBoot#Manual_loading
>
> As a simple test, you can upload just a single "bx lr" instruction
> (compiled in ARM mode) to the address 0x2000 and try to execute it.
> In the case if your code screws up something and does not return
> control to the BROM correctly, then the "fel" tool can't communicate
> over USB anymore and just timeouts. Regarding the address space, you
> can use SRAM addresses starting from 0x2000 up to something like 0x5E00
> (that's where the stack pointer is set). This was a description of a
> "bare metal" FEL usage.
>
> Now as for the u-boot support. You can compile and run u-boot in the FEL
> mode configuration on pcduino3 in the following way:
>
> make CROSS_COMPILE=arm-none-gnueabi- Linksprite_pcDuino3_felconfig
> make CROSS_COMPILE=arm-none-gnueabi- -j2
>
> fel write 0x2000 spl/u-boot-spl.bin
> fel exe 0x2000
>
> sleep 1 # Wait for DRAM initialization to complete

i.e. wait for U-Boot SPL to return to the BROM?

>
> fel write 0x4a000000 u-boot.bin
> fel exe 0x4a000000
>
> Please note the use of '*_felconfig' instead of '*_defconfig'.
> And also right now the FEL mode support is broken. That's why the
> http://lists.denx.de/pipermail/u-boot/2015-January/203282.html
> patchset tried to address this problem.
>

OK that looks like an excellent guide, thank you. I will make some time to
take a more detailed look at this as soon as I can, but definitely in the
next few days.

>> >> > 3. As the DRAM is initialized and available now, the main u-boot
>> >> > binary is now uploaded to DRAM via FEL. Together with boot.scr,
>> >> > the kernel, the dtb file and optionally initramfs as needed.
>> >> > 4. The main u-boot binary is executed via a FEL command, but never
>> >> > returns back to BROM anymore.
>> >> >
>> >> > More details are available in the linux-sunxi wiki:
>> >> > http://linux-sunxi.org/FEL
>> >> > http://linux-sunxi.org/FEL/Protocol
>> >> > http://linux-sunxi.org/FEL/USBBoot
>> >> >
>> >> > I have submitted a patch to fix this regression:
>> >> > https://patchwork.ozlabs.org/patch/434826/
>> >> >
>> >> > If you encounter problems and/or need help when testing FEL, please
>> >> > let me know.
>> >>
>> >> OK I commented on that patch.
>> >
>> > Thanks.

Regards,
Simon


More information about the U-Boot mailing list