At the moment we limit the maximum SPL load size to 32 KB, because this
was a BROM limit in previous SoCs.
Newer SoCs (H6 and later) lift this limit, but also this tool is not
bound by the BROM limit, since we can load any size.
Use the just introduced SRAM size to establish an upper limit for the
SPL size, then limit this as we go if any part of the memory is used for
the FEL backup buffers.
Given the buffer addresses chosen wisely, this can drastically increase
the maximum SPL load size, even on those SoCs with a 32KB BROM limit.
Signed-off-by: Andre Przywara <osp@andrep.de>
At the moment we always use a 32KB offset to place the U-Boot image
after the SPL.
Newer SoCs can (and will) have bigger SPLs, so we need to become more
flexible with this offset.
Read the actual SPL size, and assume the U-Boot payload is located right
behind the SPL, if the SPL size is bigger than 32KB.
We use at least 32KB, because this is how U-Boot is doing it today, even
when the SPL size is actually smaller than that.
Signed-off-by: Andre Przywara <osp@andrep.de>
We have a check to avoid that the SPL accidentally overwrites the thunk
buffer we use to execute code on the board.
Unfortunately this compares the SPL *size* against the thunk *address*,
which is only valid when the SPL starts at 0 (older 32-bit SoCs).
Factor in the SoC dependent SPL start address, to make this check work
properly on newer (64-bit) SoCs.
Signed-off-by: Andre Przywara <osp@andrep.de>
Currently we check the U-Boot (legacy!) image header checksum very early
and bail out with an error message if it does not match.
Move that check later into the function, *after* we have established
that we are actually dealing with such an U-Boot image.
This avoids confusing error messages in case there is no U-Boot image
used at all.
Signed-off-by: Andre Przywara <osp@andrep.de>
Every addition of a new feature to the SPL header currently requires us
to update the FEL tool, to teach it about the new supported maximum
value. Many times the FEL tool doesn't really care, but complains
anyway - and refuses to load.
Let's introduce semantic versioning [1] for this field, where backwards
compatible additions just increase a minor number, but incompatible
changes require bumping the major version.
We have 8 bits for the SPL header version, let's split this to have 3 bits
for the major and 5 bit for the minor version number.
[1] https://semver.org
Signed-off-by: Andre Przywara <osp@andrep.de>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Using the new AAPCS function remote execution support, add support to
read from and write to SPI flash connected to a device.
This allows flashing boot code to a device.
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
[Andre: adjust to upstream changes]
Signed-off-by: Andre Przywara <osp@andrep.de>
This patch adds a wrapper script, which can automatically compile
and wrap a small C function, taking care of all the necessary
function arguments marshalling.
The functions 'aw_fel_remotefunc_prepare/aw_fel_remotefunc_execute'
allow using such functions in the sunxi-fel tool to get this code
executed remotely on the device.
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
[Andre: adjust to match upstream changes]
Signed-off-by: Andre Przywara <osp@andrep.de>
A U-Boot image has two CRCs, one to cover the data and that we already
check, and one to cover the header.
Since we're not checking the latter, let's make sure it's the case.
Tested-by: Frank Kunz <mailinglists@kunz-im-inter.net>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
The current code checks that the transferred size is matching the size
reported in the image header.
Unfortunately, the transferred image might be padded, which doesn't change
anything at the functional level, but will make that check trigger since
the actual image will be smaller than the transferred data.
Change that logic to first check that the transferred size isn't less that
the header image size, which will still be an error, and then check for the
CRC of the image itself. This will prove to be an more robust integrity
check than what we have right now anyway.
The CRC used in the image header is the CRC32 algorithm, that is
implemented in the zlib, which is installed on most devices on the planet,
so we can just use that implementation instead of rolling our own.
Tested-by: Frank Kunz <mailinglists@kunz-im-inter.net>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
The U-Boot image parsing code so far has been relying on hardcoded offsets
directly into the image's buffer.
While that works, it's a bit obscure and isn't practical to understand and
modify.
Let's add the structure definition, and convert the code to use it.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
The version 2 of SPL added the possibility to add a device tree name in
the header, with adding some pad and using a reserved word.
As FEL boot currently doesn't need the device tree name, directly raise
the maximum supported version number to 2.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
If an SoC has the "secure boot" fuse burned, it will enter FEL mode in
non-secure state, so with the SCR.NS bit set. Since in this mode the
secure/non-secure state restrictions are actually observed, we suffer
from several restrictions:
- No access to the SID information (both via memory mapped and "register").
- No access to secure SRAM (SRAM A2 on H3/A64/H5).
- No access to the secure side of the GIC, so it can't be configured to
be accessible from non-secure world.
- No RMR trigger on ARMv8 cores to bring the core into AArch64.
Those limitations make a board pretty useless for many applications.
However it has been found out that a simple "smc" call will immediately
return from monitor mode, but with the NS bit cleared, so access to all
secure peripherals is suddenly possible.
Add all the necessary support code for doing a runtime check and
activating this workaround. Affected SoCs need to have the "smc"
workaround enabled in their soc_info struct.
Signed-off-by: Andre Przywara <osp@andrep.de>
["sunxi-fel smc" command changed to automatic detection by Siarhei]
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
The patch also introduces a "sid-register" command for diagnostic
purposes. It allows to use/enforce the workaround method for other
SoCs, to check if there are any inconsistencies with the values
read from memory.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
H3 SID controller has some bug, that makes the initial value at
0x01c14200 wrong.
This commit workarounds this bug by reading them with register access
first.
Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
Reviewed-by: Bernhard Nortmann <bernhard.nortmann@web.de>
This is a preparatory step. Instead of using memory-based access,
we might want to retrieve SID keys (e-fuses) via SID registers.
For this, it's convenient if the plain base address is available.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
For unknown option-style arguments (starting with '-'), exit after
printing an error message.
This avoids situations where sunxi-fel would not report incorrect
options (with no FEL device attached/detected) and fail with
"Allwinner USB FEL device not found" instead, which is undesirable.
TODO: Might have to eventually migrate this to some better argument
parsing, e.g. getopt(3) or something similar.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
fel:
- Minor review of ARM scratch code
- POSIX conformance: Use nanosleep() instead of deprecated usleep()
README:
- revert Unicode dash to standard ASCII
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
"./sunxi-fel --list" enumerates Allwinner USB devices that
are in FEL mode. For each device detected, the SoC name/ID
and - if available - the SID key will be printed to stdout.
The utility then exits with status code 0 (upon success),
or 1 if no devices were found.
The current implementation treats the list feature as an option,
to be able to handle it *before* the first attempt to call
feldev_open() - which could fail (with no FEL devices connected).
However, a "list" alias is available for users who expect this
to be 'command' syntax, so "./sunxi-fel list" works too.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
open_fel_device() will automatically provide this member field,
based on the SoC ID from FEL/BROM version data. The field will
either receive a human-readable identifier, or the ID in 4-digit
hexadecimal representation (for unknown SoCs).
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
The feldev_handle struct returned by feldev_open() will now contain
this additional data, so the main application no longer needs to care
about retrieving that.
aw_fel_get_version() has thus become a static (= 'private') function.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
The FEL utility had accumulated enough (mostly USB-related)
"low-level" code to justify moving that to a separate code unit.
This will allow us to keep better focus on the higher level
functionality in fel.c.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
This moves claiming / releasing the interface into the respective
"open" / "close" functions. The USB code in main() is now trimmed
down to:
feldev_init();
handle = open_fel_device(...);
feldev_done(handle);
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
We move USB endpoint detection into the feldev_claim() routine, so
higher level code is no longer involved with that. Also make use of
the "detached" flag within feldev_handle, instead of relying on an
isolated variable.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
This enables us to move forward to a cleaner implementation,
where the "core" fel.c code will become independent of direct
libusb usage. After moving USB code to a separate module,
in the end the libusb handle could become an 'opaque' field of
feldev_handle.
The "device" handle might also be extended later, to provide
(FEL) version data and SoC-specific information (chip ID, SRAM
info, human-readable name).
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
The R40 is marketed as the successor to the A20. The SRAM layout is the
same as the A20, but there doesn't seem to be a secure SRAM block.
The SID block is at a completely different address. The layout is the
same as the newer SoCs, with the e-fuses at an offset of 0x200.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
These functions solve the problem that large readl/writel
transfers might be limited by insufficient (scratch) buffer
size. To solve this, chunks of no more than LCODE_MAX_WORDS
get transferred individually.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
This patch reduces on FEL protocol overhead for the 'multiple'
readl/writel transfers (functions that do word-aligned memory
access on the SoC). The ARM "scratch" code now takes a word count
and is able to work with buffered data, so the host is no longer
required to transfer single words in a piecemeal fashion.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
While at it, modify the former "sram_info" identifiers
to carry a broader "soc_info" meaning.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
The previous timeout of 60 seconds was mostly based on scenarios
where large ("write") transfers take place. But it could easily
become annoying if users are awaiting completion of simpler
commands like "read" or "hexdump", and for some reason FEL fails
to respond.
Therefore I've decided to lower the timeout value to 10 seconds,
adjust the maximum chunk size accordingly and - while at it -
improve the source comments documenting their relationship.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
For Windows portable_endian.h relies on and includes <winsock2.h>.
Thus it needs to be requested first, otherwise other includes might
pull in <windows.h> and cause a preprocessor warning / compilation
failure (observed with MinGW).
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
This commit renames the function pointer of type progress_cb_t
for file_upload(). That might help to avoid potential confusion
with other routines that use a boolean "progress" parameter to
indicate whether progress information is desired (at all).
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
Until now, the function would always pass `true` as the "progress"
parameter to aw_write_buffer(). This has the potential drawback
of limiting the maximum USB transfer size.
By selectively passing `false` instead (with no progress function
active), we hint that aw_write_buffer() and subsequent routines
don't have to care about callbacks; so that usb_bulk_send() is
free to select a transfer size of AW_USB_MAX_BULK_SEND.
Reviewed-by: Bernhard Nortmann <bernhard.nortmann@web.de>
This way we don't have to introduce new options for retrieving
version info. For those programs that do not output their usage
by default (e.g. because they would process stdin), you may pass
a "-?" option to get help - and thus version information.
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
* fel: Add the ability to pass uEnv-style data via FEL
The corresponding format is recognized by having the environment
data (= text) start with a special "#=uEnv" marker. Upon transfer
of such a file, sunxi-fel will detect this condition, and set a
field in the SPL header accordingly - which in turn also requests
U-Boot to auto-import it (i.e. merge with the default environment).
(Note that this requires a U-Boot version that knows about the
new meaning of this field, namely v2016.09 or later. Older U-Boot
versions will fail to import the uEnv-style data.)
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
This commit adds a new "reset64 <addr>" command "rmr32" that could
be helpful with new 64-bit SoCs. It takes an entry point (address)
parameter, stores it via RVBAR and then issues a RMR write to
request a warm boot into AArch64 mode.
For now, this is useful with the boot process of A64, where we might
wish to transfer control to a 64-bit binary (for ATF or U-Boot).
See e.g. http://linux-sunxi.org/Pine64#Boot_sequence
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
The SCTLR bits are somewhat different because the V bit is set
to 0 on A64 (Low exception vectors, base address 0x00000000) and
the UNK bit (Reads of this bit return an UNKNOWN value) is also not
the same as on the other SoCs. So the SCTLR check can be relaxed.
Changes in v2:
- Because the SRAM A and SRAM C reside back-to-back in the address
space, it is possible to use 40 KiB of SRAM by the SPL for its
code+data+stack. So the FEL backup storage is moved from 0x18000
to 0x1A000 to support this.
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
This allows the SRAM section A2 to be exclusively used by
the OpenRISC core.
There are no substantial differences between H3 and A10/A13/A20.
It just has 64 KiB of SRAM starting at the address 0x0 instead
of 48 KiB.
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>