Allwinner T7 share the same CCM/UART base address with H6.
Add support for it in uart0-helloworld-sdboot.
Signed-off-by: qianfan Zhao <qianfanguijin@163.com>
The Allwinner A523 has 128KiB of MCU0 SRAM, which the BootROM will not
touch. The BROM will use some memory in SRAM A2, which it also clears
upon entering FEL mode, starting from address 0x44000. The lowest
allocation seems to be the IRQ stack growing down from 0x45400.
So we won't touch any of that memory, but can freely use the full 128KB
of the primary SRAM for payloads. This means we won't need to swap any
buffers for preserving BROM stacks.
We put the SPL thunk code just below 0x44000, to leave as much SRAM for
the payload as possible.
The rest of the SoC is pretty standard, although the watchdogs are now
in separate MMIO frames, not part of some timer block anymore.
The secure boot mode will prevent even reading the BootROM, so we can
use an address in there to test for the secure boot state. However, even
though a simple "smc #0" will return to its caller, the NS bit is still
set, so we are still in non-secure state afterwards. So leave this bit
out for now until we figure out how to switch to secure state properly.
Signed-off-by: Andre Przywara <osp@andrep.de>
When reading from the SID device using the normal memory access method,
we upload our "readl" routine (via fel_readl_n()), which expects a number
of *words* to read. However length is given in *bytes*, so we read four
times as much, and overflow our key buffer, clobbering the return address.
This is typically fatal:
===============
$ ./sunxi-fel sid
02c05200:12345678:34567890:76543210
Segmentation fault (core dumped)
$
===============
Fix this by giving the number of (32-bit) words instead. We already
checked that length is a multiple of 4, so we can just divide.
Signed-off-by: Andre Przywara <osp@andrep.de>
As over time we gain support for more and more SoCs, it would be
convenient to know which SoCs a particular build actually supports.
Add a "list-socs" command, that just iterates over the soc_info table
and outputs the SoC ID and the name for each entry.
Signed-off-by: Andre Przywara <osp@andrep.de>
At the moment we can search for a specific SoC in our supported SoC
table by looking for its SoC ID, but we cannot otherwise enumerate all
supported SoCs.
Add a get_next_soc() function that allows iterating over our (internal)
table: The first call will take NULL as an argument, subsequent calls
pass in the pointer returned by the previous call. When we reach the end
of the list, the function returns NULL.
Signed-off-by: Andre Przywara <osp@andrep.de>
The Allwinner H616 ships in at least two die variants, sometime under a
different name (H618, T507), but sometimes labeled as a normal "H616".
The die variants differ in their CPU cluster control subsystem, which
affects the location of the RVBAR shadow register used to reset the core
into 64-bit mode. We use that in the "reset64" command, but also as part
of the boot process using the "uboot" command, on ARMv8 cores.
Add code to detect the die variant by reading the VER_REG MMIO register,
where the original die reports 0x00 in the lower 8 bits, but the newer
die variants apparently 0x02. In the latter case let the aw_rmr_request()
function use the alternative RVBAR address to do the 64-bit switch.
This matches what we do in U-Boot and Trusted Firmware.
Signed-off-by: Andre Przywara <osp@andrep.de>
The generic_2k_sid_maps, describing the SID sections for chips where we
don't have any specific information yet, was missing the terminating
NULL section, so we would run off into to woods, beyond the array limit.
This would most commonly result in a segfault:
$ sunxi-fel sid-dump
....
00000000 00000000 00000000 00000000
Segmentation fault (core dumped)
=================
Add the NULL sentinel to terminate the loop correctly.
Signed-off-by: Andre Przywara <osp@andrep.de>
The new sid-dump command was missing documentation. Add it to the
internal usage() function as well as to the manpage.
Clarify on the existing sid-registers command on the way, and add
a stanza for the wdreset command.
Signed-off-by: Andre Przywara <osp@andrep.de>
At the moment we only have a SID map for the R40. Add a generic
placeholder map, covering the 2048 bits that most SoCs have (at least).
The linux-sunxi Wiki page [1] for the SID register layout describes
entries for the H6 and "SoCs before H6". Add those tables as well, and
use the latter one for some SoCs which were released the closest to the
H6 (H3, A64, H5).
If people have more information, more specific maps can be added.
[1] https://linux-sunxi.org/SID_Register_Guide#eFUSE_Region_Overview
Signed-off-by: Andre Przywara <osp@andrep.de>
At the moment we have two functions reading the SID eFuses:
fel_get_sid_root_key() to read the "root key" (the first 128 bits), and
fel_get_sid() to read an arbitrary range. The latter does not use the
MMIO register workaround on affected SoCs, while the former only reads
that specific range of bits.
Unify the two functions into one that combines the advantanges of both:
we can read any range of eFuses, and it uses the MMIO register access
method, if needed. Switch the users to use the new function.
Signed-off-by: Andre Przywara <osp@andrep.de>
To workaround a hardware erratum on the H3 SoC, we use an MMIO register
based assembly routine to dump the SID registers, if needed. This is
hard-coded to read the first four 32-bit words of the SID fuses.
For the sid-dump command we need to access any arbitrary regions of the
fuses, so extend the routine to take a start and an end address to dump.
This changes the assembly source in the thunks/ directory:
- We load the start address into r1, instead of zeroing it. The start
address is put right after the SIO MMIO base address, at the end of
the code.
- When storing the read value into the result buffer, we automatically
increase the pointer register (r3), instead of adding the offset
address, since this is now no longer zero based.
- To check for the end, we read the end pointer (stored at the end of
the code, right after the offset), and compare against that instead of
the hardcoded value of 16.
This assembly file was put through the thunks Makefile, and the resulting
content was copied from thunks/sid_read_root.h into fel_lib.c.
For now we are still putting the constant values of 0 and 16 in, but
this time from the C code.
Signed-off-by: Andre Przywara <osp@andrep.de>
The prebuilt blob of uart0-helloworld-sdboot isn't updated for a long
time.
Update it with one built with 5cf618a216 ("Merge pull request #180
from ChalesYu/a63-220729").
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
The F1C100s series of SoCs has some subtle differences in its UART
setup:
- The UART is at a previously unused address.
- The base clock is not APB2, but APB1.
- The input clock is not 24 MHz, but CPU clock / 2 / 2.
- The clock and reset gates are different bits at different addresses.
Add support for all those differences, tied to the F1C100s SoC ID.
Also change the GCC target architecture for uart0-helloworld-sdboot to
ARMv5, since this is now the oldest support architecture revision.
When the compiler defaulted to ARMv7, it was generating ubfx instructions,
which were only introduced in ARMv6.
Signed-off-by: Andre Przywara <osp@andrep.de>
The V5 is (yet another) example of a more recent SoC with A7 cores, so
it goes with the H6 memory map and peripherals, but with 32-bit cores.
Add basic support, to facilitate development.
Signed-off-by: Andre Przywara <osp@andrep.de>
Clock and UART wise it's very similar to the V853, but UART0 is only on
pins PE2/3, using pinmux 6, with no other muxes other than PortF.
Signed-off-by: Andre Przywara <osp@andrep.de>
This SoC is using the same die as the RISC-V D1, but we don't support
non-ARM yet. The memory map and peripherals (watchdog) are very similar
to the V853, also the BROM enabled the instruction cache, so requires
the same I cache hack.
Signed-off-by: Andre Przywara <osp@andrep.de>
Allwinner V853 has a GPIO controller with the new register map, a brand
new GPIO base address and the same CCM/UART base address with R329.
Add support for it in uart0-helloworld-sdboot, also as the first SoC
that utilizes GPIO V2.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
GPIO controllers in some new Allwinner SoCs has altered register map.
Add basical support for the new GPIO controller register map.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
Allwinner V853 is a new SoC from Allwinner that has I-Cache enabled
(thus broken FEL write-and-execute) in BROM.
Add support for it.
The SRAM infomation was gathered by reverse engineering its BROM and
checking its SRAM usage, confirmed by the manual.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
[Andre: fix watchdog]
Signed-off-by: Andre Przywara <osp@andrep.de>
On some new Allwinner SoCs, I-Cache is enabled by BROM but FEL write
command cannot correctly invalidate I-Cache, so thunks will not get
properly executed.
Implement a hack that tries to disable I-Cache each time trying to write
data via FEL, to prevent stall thunks in I-Cache.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
The sunxi-boards.git repository has been fixed to address the two
remaining issues in the .fex files there, so we can run our fex compiler
tests on the unpatched repository content.
Remove the patch file, as it is no longer needed and won't apply
anymore anyway on the current sunxi-boards master.
Signed-off-by: Andre Przywara <osp@andrep.de>
The suniv SoCs has a SPI controller like the one in H3, but with base
address like sun4i and no SPI module clock in CCU.
Add support for it.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
Signed-off-by: Andre Przywara <osp@andrep.de>
The original fel-remotefunc-spi-data-transfer.h contains code only
suitable for ARMv7+. The F1C100s family is ARM9 (ARMv5TE), so rebuild it:
$ ./fel-remotefunc-compiler.rb fel-remotefunc-spi-data-transfer.{c,h}
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Andre Przywara <osp@andrep.de>
Allwinner also has ARM926EJ-S (ARMv5TE) based SoCs.
Consider them when set -march parameter. Also switch to -Os, since we
are more interested in compact code - performance is secondary when doing
mostly MMIO anyway.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Andre Przywara <osp@andrep.de>
Allwinner F1C100s is one of the new ARM9 SoCs produced by Allwinner.
Add support for it in FEL.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Andre Przywara <osp@andrep.de>
Some bits are not meaningful both in ARMv5 and ARMv7/8, however they're
read as 0 in ARMv5 but 1 in ARMv7/8.
Ignore them.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Andre Przywara <osp@andrep.de>
Almost all thunks are already ARMv5 safe, so we can just require this
architecture on the gas command line, to enforce compatibility with the
F1Cx00 series. This prevents accidental changes in the future.
The RMR thunk uses the ARMv7 only DSB/ISB instructions, but this runs on
ARMv8 cores only anyway, so we just force ARMv7 for this file, and avoid
code changes.
Signed-off-by: Andre Przywara <osp@andrep.de>
Currently the thunk we upload into the SRAM is using DSB and ISB
instructions, which were introduced in ARMv7. Also it relies on
movw/movt pairs, which became available in ARMv6T2.
The Allwinner F1Cx00 SoCs are using an ARMv5TE compliant core, so they
do not know these instructions.
Change the code to be ARMv5TE compliant, so it can run on all relevant
Allwinner ARM cores:
- One movw is just used to compare two bits, replace that with a
tst/tsteq sequence to skip the load.
- The other movw/movt pairs get replaced with ldr's, that load from
literal storage at the end of the code (from Icenowy).
- The DSB and ISB get replaced with their CP15 MCR counterparts. Those
are deprecated in ARMv7, but still work, when the CP15BEN bit is set
in SCTLR. We check for this in fel.c (from Icenowy). ISB is not
implemented on the ARM926, so make this conditional. A simple branch
takes care of the desired pipeline flush for the old SoC.
Also remove the rather pointless Ruby prolog that generates the header
file. We have a less awkward version of this in the Makefile, and need
that for the other thunks there anyway, so it's just duplicated code.
Embedding a header generator in Ruby in an assembly file is a cute
gimmick, but serves no purpose anymore.
This is based on work by Icenowy, who put a similar solution in a
separate file.
Originally-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Andre Przywara <osp@andrep.de>
It seems like travis-ci.org is gone, replaced by travis-ci.com, but
apparently that's not truly free anymore: it requires a registered account
plus credit card, and is only granted a one-time free credit allowance,
with the option to get this extended by explicit request. As a result
the current CI stopped working a while ago, and was broken anyway (it
failed building already, and make check on its own doesn't pass on
master anymore).
Github itself seems to offer an alternative, so let's add a control file
for that to get some basic CI back.
This builds the host and misc tools on a standard Ubuntu system, and
runs make check.
Signed-off-by: Andre Przywara <osp@andrep.de>
"make check" uses the .fex files in the sunxi-boards repository to
verify the validity of our FEX compiler.
To overcome an existing issue, there was one patch file applied to the
mainline repository content. However this was merged into mainline
sunxi-boards a while ago, so remove that patch file, as trying to apply
the patch actually fails the current test early.
Also some new files (H6 boards) have been added meanwhile, but they are
apparently buggy:
- pine64_h64.fex contains some apparently bogus characters before the
leading comment, possibly an artefact of its extraction.
- One DRAM TPR6 parameter seems to contain an extra trailing 0, making
the value larger than 32 bit, and not matching the TPR6 values for
other A31 boards. Just remove that, as the compiler rightfully
complains about that.
This allows the "make check" command to pass again.
Signed-off-by: Andre Przywara <osp@andrep.de>
Some .fex files (for instance those for the H6 in sunxi-boards) contain
a trailing semicolon on some lines, after the end quote of a string
value.
This confuses the parser and messes up our "make check" tests, so remove
the semicolon both in the parser, but also in the unify-fex test
conditioning tool, to make the tests pass.
Signed-off-by: Andre Przywara <osp@andrep.de>
These files were all originally by Bernhard in 2016 via these commits:
8445d71 unify-fex: Use int64_t and portable format specifiers for its output
f957f89 fextest: Add a dedicated rule for (CI-)testing sunxi-boards
6ec3876 tests: Improve code coverage by testing corner cases
cd5a0a3 tests: Improve on testing fexc
5cbb0c9 tests: Introduce a basic testing framework
and have not otherwise been touched. The header was added to unify-fex.c when
it was added in cd5a0a3303 ("tests: Improve on testing fexc") but not to the
other files.
The license in unify-fex.c is the GPLv2+ which corresponds to the content of
LICENSE.md both at the time and now. I think therefore that it is appropriate
to duplicate the header into the other files (changing only the character used
for comments to suit)
Newer fex files like orangepi_oneplus.fex from the sunxi-boards repo fail
conversion to the binary format:
--------------------------
E: orangepi_oneplus.fex:258: invalid character at 4.
--------------------------
This is because they contain a '-' character in section and key names, and
also '/' characters in some section names, which our compiler denies.
Relax the section and key filter to allow '-' and '/' as well.
Signed-off-by: Andre Przywara <osp@andrep.de>
Some functions are only used internally in fel_lib.c, consequently their
prototypes are not exported in fel_lib.h.
Mark those functions as "static", to make this clear to the reader and
improve the generated code.
Signed-off-by: Andre Przywara <osp@andrep.de>
The aw_usb_read() function is meant to *fill* the buffer given to it, so
marking the pointer as "const" in the parameters list is wrong.
Some compilers (for instance GCC 11) spot this and issue a warning:
----------------------------------
fel_lib.c: In function ‘aw_read_fel_status’:
fel_lib.c:190:9: warning: ‘buf’ may be used uninitialized [-Wmaybe-uninitialize]
190 | aw_usb_read(dev, buf, sizeof(buf));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fel_lib.c:168:13: note: by argument 2 of type ‘const void *’ to ‘aw_usb_read’ declared here
168 | static void aw_usb_read(feldev_handle *dev, const void *data, size_t len)
| ^~~~~~~~~~~
fel_lib.c:189:14: note: ‘buf’ declared here
189 | char buf[8];
| ^~~
----------------------------------
Drop the 'const' specifier, and use the right USB bulk transfer wrapper
to make this work. The usb_bulk_send() function just happened to work
before because the actual libusb bulk transfer function is bidirectional.
Signed-off-by: Andre Przywara <osp@andrep.de>