Most Allwinner SoCs, including all recent ones, contain an OpenRISC CPU in addition to their ARM cores. This CPU is in the RTC power domain and is responsible for system suspend/resume/reset/shutdown, dynamic frequency scaling for the ARM cores, and controlling the external power management IC (PMIC).
Allwinner provides no source code for their "scp.bin" firmware, other than in an encrypted tarball, so reverse-engineering their released binaries was required to understand the hardware interfaces used by this firmware.
This firmware attempts to completely replace the proprietary firmware provided
by Allwinner. It is designed to be compatible with mainline versions of Linux,
u-boot, and ATF. While initially only developed on and for the sun50i
series
(A64/H64/H5/R18), ideally it could be backported for use on other SoC
platforms.
This firmware is currently a work in progress! It is buggy and missing major functionality! Moreover, due to sharing SRAM A2 with ATF (explained below), you likely cannot install it anyway.
This firm is designed to be flexible yet extremely lightweight. It borrows heavily from ideas in both Linux and ATF for its layout and driver model. The code is divided into directories based on major function:
board
: These files contain configuration for each board supported by this firmware. They determine which subdirectory ofplatform
is used (for SoC-internal devices) and which external devices are enabled.common
: Files in this directory contain the main logic of the firmware, as well as glue code for connecting drivers, handling exceptions, etc.drivers
: This directory contains a subdirectory for each class of drivers.drivers/<class>
: These directories contain all of the drivers of a class, as well as generic dispatch code (indrivers/<class>/<class>.c
).
include
: This directory contains headers for code incommon
andlib
, as well as standalone definitions.include/arch
: These headers expose functionality of the CPU architecture that are not dependent on a specific hardware implementation.include/drivers
: These headers specify the interface for each class of drivers. Also included are headers for drivers that share macros with platform-specific device definitions.
lib
: This directory contains standalone code that does not depend on other outside code (with few exceptions). This code should be easily reusable in other projects.platform
: This directory contains a subdirectory for each supported platform, which refers to a family of SoCs with a similar programming interface.platform/<platform>
: This directory contains source files for device definitions and an early console implementation for each platform.platform/<platform>/include
: This directory contains headers with platform-specific macro definitions, such as memory addresses of devices and register layouts that change between platforms.
scripts
: These files are used to assist in building and linking the firmware, but contain no code themselves.tools
: Each file here is a self-contained program intended to be run on the host machine (in Linux userspace on the ARM cores) to gather information, manipulate hardware, load firmware, or for other reasons.
The build system uses a linker script to coalesce driver and device definitions together in the final binary, so they can be initialized and probed iteratively.
Building this firmware requires a cross-compiler targeting the or1k
architecture. Prebuilt toolchains can be downloaded from the OpenRISC
organization on GitHub, or you can manually build one with
musl-cross-make. If your cross toolchain has a different
tuple, or is not in your PATH
, edit the top of the Makefile
to provide
the appropriate full path or prefix.
While this firmware should ideally support any SoC with the ARISC core present, there are several limiting factors to doing so:
- Changing memory map for device access between SoCs.
- Differences in SRAM area location and size between SOCs (in some cases, SRAM may be too small to fit this firmware).
- Different PMICs used with different hardware generations.
- Variations in connection to external voltage regulators, buttons, LEDs, etc.
- Hardware bugs, if any.
Thus, this firmware is designed and implemented with the sun50i
family (A64
and H5) first in mind, and other SoCs second.
In order to support external devices, the firmware needs to know some
information about the layout of the board and the connections to port L GPIO
pins. Therefore, the supported boards are enumerated in the boards
directory,
and specifying a board with the BOARD
make
variable is required to build
the firmware. You can also specify BOARD
in a config.mk
file, that will be
included by the main Makefile
.
The ARISC firmware must run from SRAM A2, because
- The OpenRISC CPU has its special exception vector area at the beginning of SRAM A2.
- SRAM A2 is the only memory on a bus directly connected to the ARISC core (in other words, using any other memory would prevent turning some busses off during suspend).
- SRAM A1 is not accessible from the OpenRISC core on some SoCs.
Unfortunately, on sun50i
SoCs, ATF currently takes up the entirety of SRAM
A2. Fortunately, it can be made smaller. This version of ATF has
been patched to put its dynamically-allocated data in SRAM A1. This leaves half
of SRAM A2 for the ARISC firmware. You'll also need a patched version of
U-Boot that loads ATF to the right place. You can use the build
system in our meta-repository to automatically generate an SPI
flash image containing the correct versions of all firmware components.
All contributions to this project must be released under the open-source
license used by the project. To help ensure this, all commits you make must be
accompanied by your real name and a Signed-off-by
tag asserting authorship
and permission to contribute, per the Developer Certificate of Origin.
This tag can be added automatically by git
using git commit -s
.
The code in this project is formatted with uncrustify
. You will need a recent
version of that program (possibly compiled from its git repository) to
format any changes you make. You can use the target make format
to correctly
format your code. Other files should be wrapped to 79 columns.
Please run make check
to check your changes before submitting a pull request.
Additionally, please ensure your changes work on real hardware before
submitting them.