Commit 93f81bd4 authored by sam.xiang's avatar sam.xiang

[opensbi] create opensbi from T-Head official:

	repo: https://github.com/T-head-Semi/opensbi
	commit: 89182b257c8798e15e4c685c1af0c2862d528d2a

Change-Id: I7b39d66729e0108661a6f4c9e28acbdb303684ea
parent 92ffedd5
List of OpenSBI Contributors (Alphabetically sorted)
====================================================
* **[Western Digital Corporation](https://www.wdc.com/)**
* Project initiator and maintainer
* Copyright (c) 2019 Western Digital Corporation or its affiliates
* Alistair Francis <alistair@alistair23.me>
* Andreas Schwab <schwab@suse.de>
* Anup Patel <anup.patel@wdc.com>
* Atish Patra <atish.patra@wdc.com>
* Bin Meng <bmeng.cn@gmail.com>
* Damien Le Moal <damien.lemoal@wdc.com>
* Karsten Merker <merker@debian.org>
* Nick Kossifidis <mickflemm@gmail.com>
* Shawn Chang <citypw@gmail.com>
* Xiang Wang <wxjstz@126.com>
The 2-Clause BSD License
SPDX short identifier: BSD-2-Clause
Copyright (c) 2019 Western Digital Corporation or its affiliates and other
contributors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This diff is collapsed.
This diff is collapsed.
Copyright (c) 2019 Western Digital Corporation or its affiliates.
Third Party Notices
===================
This project includes or partly uses code from the following open source
software subject to the following open source licenses.
libfdt
------
Copyright (C) 2016 Free Electrons
Copyright (C) 2016 NextThing Co.
The libfdt source code is disjunctively dual licensed (GPL-2.0+ or
BSD-2-Clause). Some of this project code is used in OpenSBI under the terms of
the BSD 2-Clause license. The full text of this license can be found in the
file [COPYING.BSD](COPYING.BSD).
OpenSBI Contribution Guideline
==============================
All contributions to OpenSBI can be sent in the following ways:
1. Email patches to the OpenSBI mailing list at `opensbi@lists.infradead.org`
2. GitHub Pull Requests (PRs) to the [OpenSBI main repository]
To join the OpenSBI mailing list, please visit the [OpenSBI infradead page].
The OpenSBI maintainers prefer patches via the OpenSBI mailing list
(option 1 above) so that they are visible to a wider audience. All
accepted patches on the OpenSBI mailing list will be taken by any of
the OpenSBI maintainers and merged into the [OpenSBI main repository]
using GitHub PRs.
All contributed work must follow the following rules:
1. OpenSBI code should be written in accordance to the [Linux coding style].
2. This project embraces the [Developer Certificate of Origin (DCO)] for
contributions. This means that you must agree to the following prior to
submitting patches: if you agree with this developer certificate you
acknowledge this by adding a Signed-off-by tag to your patch commit log.
Every submitted patch must have this tag.
3. A commit message must have a subject line, followed by a blank line,
followed by a description of the patch content. A blank line and the author
Signed-off-by tag must follow this description.
4. A commit subject line must start with a prefix followed by a ":". Common
prefixes are for example "lib:", "platform:", "firmware:", "docs:", "utils:"
and "top:".
5. Maintainers should use "Rebase and Merge" when using GitHub to merge pull
requests to avoid creating unnecessary merge commits.
6. Maintainers should avoid creating branches directly in the main
riscv/opensbi repository. Instead prefer using a fork of the riscv/opensbi main
repository and branches within that fork to create pull requests.
7. A maintainer cannot merge his own pull requests in the riscv/opensbi main
repository.
8. A pull request must get at least one review from a maintainer.
9. A pull request must spend at least 24 hours in review to allow for other
developers to review.
-----------------------------------------------------------------------
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
-----------------------------------------------------------------------
[OpenSBI main repository]: https://github.com/riscv/opensbi
[OpenSBI infradead page]: http://lists.infradead.org/mailman/listinfo/opensbi
[Linux coding style]: https://www.kernel.org/doc/html/v4.10/process/coding-style.html
[Developer Certificate of Origin (DCO)]: http://developercertificate.org/
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
OpenSBI as coreboot payload
===========================
[coreboot] is a free/libre and open source firmware platform support multiple
hardware architectures(x86, ARMv7, arm64, PowerPC64, MIPS and RISC-V) and
diverse hardware models. In RISC-V world, coreboot currently support HiFive
Unleashed with OpenSBI as a payload to boot GNU/Linux:
```
SiFive HiFive unleashed's original firmware boot process:
+-----------+
+------+ +------+ +------+ | BBL |
| MSEL |--->| ZSBL |--->| FSBL |--->| +-------+
+------+ +------+ +------+ | | linux |
+---+-------+
coreboot boot process:
+---------------------------------------------------------------------+
| coreboot |
+------+ +------+ | +-----------+ +----------+ +----------+ +-----------------------+
| MSEL |-->| ZSBL |-->| | bootblock |->| romstage |->| ramstage |->| payload ( OpenSBI) |
+------+ +------+ | +-----------+ +----------+ +----------+ | +-------+ |
| | | linux | |
+---------------------------------------------+-------------+-------+-+
```
The upstreaming work is still in progress. There's a [documentation] about how
to build [out-of-tree code] to load OpenSBI.
[coreboot]: https://www.coreboot.org/
[documentation]: https://github.com/hardenedlinux/embedded-iot_profile/blob/master/docs/riscv/hifiveunleashed_coreboot_notes-en.md
[out-of-tree code]: https://github.com/hardenedlinux/coreboot-HiFiveUnleashed
OpenSBI Platform Firmwares
==========================
OpenSBI provides firmware builds for specific platforms. Different types of
firmwares are supported to deal with the differences between different platforms
early boot stage. All firmwares will execute the same initialization procedure
of the platform hardware according to the platform specific code as well as
OpenSBI generic library code. The supported firmwares type will differ in how
the arguments passed by the platform early boot stage are handled, as well as
how the boot stage following the firmware will be handled and executed.
OpenSBI currently supports three different types of firmwares.
Firmware with Dynamic Information (*FW_DYNAMIC*)
------------------------------------------------
The *FW_DYNAMIC* firmware gets information about the next booting stage entry,
e.g. a bootloader or an OS kernel, from previous booting stage at runtime.
A *FW_DYNAMIC* firmware is particularly useful when the booting stage executed
prior to OpenSBI firmware is capable of loading both the OpenSBI firmware
and the booting stage binary to follow OpenSBI firmware.
Firmware with Jump Address (*FW_JUMP*)
--------------------------------------
The *FW_JUMP* firmware assumes a fixed address of the next booting stage
entry, e.g. a bootloader or an OS kernel, without directly including the
binary code for this next stage.
A *FW_JUMP* firmware is particularly useful when the booting stage executed
prior to OpenSBI firmware is capable of loading both the OpenSBI firmware
and the booting stage binary to follow OpenSBI firmware.
Firmware with Payload (*FW_PAYLOAD*)
------------------------------------
The *FW_PAYLOAD* firmware directly includes the binary code for the booting
stage to follow OpenSBI firmware execution. Typically, this payload will be a
bootloader or an OS kernel.
A *FW_PAYLOAD* firmware is particularly useful when the booting stage executed
prior to OpenSBI firmware is not capable of loading both OpenSBI firmware and
the booting stage to follow OpenSBI firmware.
A *FW_PAYLOAD* firmware is also useful for cases where the booting stage prior
to OpenSBI firmware does not pass a *flattened device tree (FDT file)*. In such
case, a *FW_PAYLOAD* firmware allows embedding a flattened device tree in the
.text section of the final firmware.
Firmware Configuration and Compilation
--------------------------------------
All firmware types support the following common compile time configuration
parameters:
* **FW_TEXT_ADDR** - Defines the execution address of the OpenSBI firmware.
This configuration parameter is mandatory.
* **FW_FDT_PATH** - Path to an external flattened device tree binary file to
be embedded in the *.rodata* section of the final firmware. If this option
is not provided then the firmware will expect the FDT to be passed as an
argument by the prior booting stage.
* **FW_FDT_PADDING** - Optional zero bytes padding to the embedded flattened
device tree binary file specified by **FW_FDT_PATH** option.
Additionally, each firmware type as a set of type specific configuration
parameters. Detailed information for each firmware type can be found in the
following documents.
* *[FW_DYNAMIC]*: The *Firmware with Dynamic Information (FW_DYNAMIC)* is
described in more details in the file *fw_dynamic.md*.
* *[FW_JUMP]*: The *Firmware with Jump Address (FW_JUMP)* is described in more
details in the file *fw_jump.md*.
* *[FW_PAYLOAD]*: The *Firmware with Payload (FW_PAYLOAD)* is described in more
details in the file *fw_payload.md*.
[FW_DYNAMIC]: fw_dynamic.md
[FW_JUMP]: fw_jump.md
[FW_PAYLOAD]: fw_payload.md
Providing different payloads to OpenSBI Firmware
------------------------------------------------
OpenSBI firmware can accept various payloads using a compile time option.
Typically, these payloads refer to the next stage boot loader (e.g. U-Boot)
or operating system kernel images (e.g. Linux). By default, OpenSBI
automatically provides a test payload if no specific payload is specified
at compile time.
To specify a payload at compile time, the make variable _FW_PAYLOAD_PATH_ is
used.
```
make PLATFORM=<platform_subdir> FW_PAYLOAD_PATH=<payload path>
```
The instructions to build each payload is different and the details can
be found in the
*docs/firmware/payload_<payload_name>.md* files.
Options for OpenSBI Firmware behaviors
--------------------------------------
An optional compile time flag FW_OPTIONS can be used to control the OpenSBI
firmware run-time behaviors.
```
make PLATFORM=<platform_subdir> FW_OPTIONS=<options>
```
FW_OPTIONS is a bitwise or'ed value of various options, eg: *FW_OPTIONS=0x1*
stands for disabling boot prints from the OpenSBI library.
For all supported options, please check "enum sbi_scratch_options" in the
*include/sbi/sbi_scratch.h* header file.
OpenSBI Firmware with Dynamic Information (FW_DYNAMIC)
======================================================
OpenSBI **firmware with dynamic info (FW_DYNAMIC)** is a firmware which gets
information about next booting stage (e.g. a bootloader or an OS) and runtime
OpenSBI library options from previous booting stage.
The previous booting stage will pass information to *FW_DYNAMIC* by creating
*struct fw_dynamic_info* in memory and passing it's address to *FW_DYNAMIC*
via *a2* register of RISC-V CPU.
A *FW_DYNAMIC* firmware is particularly useful when the booting stage executed
prior to OpenSBI firmware is capable of loading both the OpenSBI firmware and
the booting stage binary to follow OpenSBI firmware.
*FW_DYNAMIC* Compilation
------------------------
A platform can enable *FW_DYNAMIC* firmware using any of the following methods.
1. Specifying `FW_DYNAMIC=y` on the top level `make` command line.
2. Specifying `FW_DYNAMIC=y` in the target platform *config.mk* configuration
file.
The compiled *FW_DYNAMIC* firmware ELF file is named *fw_dynamic.elf*. It's
expanded image file is *fw_dynamic.bin*. Both files are created in the platform
specific build directory under the *build/platform/<platform_subdir>/firmware*
directory.
*FW_DYNAMIC* Firmware Configuration Options
-------------------------------------------
The *FW_DYNAMIC* firmware does not requires any platform specific configuration
parameters because all required information is passed by previous booting stage
at runtime via *struct fw_dynamic_info*.
OpenSBI Firmware with Jump Address (FW_JUMP)
============================================
OpenSBI **firmware with Jump Address (FW_JUMP)** is a firmware which only
handles the address of the next booting stage entry, e.g. a bootloader or an OS
kernel, without directly including the binary code for this next stage.
A *FW_JUMP* firmware is particularly useful when the booting stage executed
prior to the OpenSBI firmware is capable of loading both the OpenSBI firmware
and the booting stage binary to follow the OpenSBI firmware.
*FW_JUMP* Compilation
---------------------
A platform *FW_JUMP* firmware can be enabled by any of the following methods:
1. Specifying `FW_JUMP=y` on the top level `make` command line.
2. Specifying `FW_JUMP=y` in the target platform *config.mk* configuration file.
The compiled *FW_JUMP* firmware ELF file is named *fw_jump.elf*. Its expanded
image file is *fw_jump.bin*. Both files are created in the platform-specific
build directory under the *build/platform/<platform_subdir>/firmware* directory.
*FW_JUMP* Firmware Configuration Options
----------------------------------------
To operate correctly, a *FW_JUMP* firmware requires some configuration
parameters to be defined using either the top level `make` command line or the
target platform *config.mk* configuration file. The possible parameters are as
follows:
* **FW_JUMP_ADDR** - Address of the entry point of the booting stage to be
executed following OpenSBI firmware. This address generally corresponds
exactly to the address where this next booting stage was loaded. This is a
mandatory parameter. Compilation errors will result from not defining this
address.
* **FW_JUMP_FDT_ADDR** - Address where the *flattened device tree (FDT file)*
passed by the prior booting stage will be placed in memory before executing
the booting stage following the OpenSBI firmware. If this option is not
provided, then the OpenSBI firmware will pass the FDT address passed by the
previous booting stage to the next booting stage.
*FW_JUMP* Example
-----------------
The *[qemu/virt]* platform illustrates how to configure and use a *FW_JUMP*
firmware. Detailed information regarding these platforms can be found in the
platform documentation files.
[qemu/virt]: ../platform/qemu_virt.md
OpenSBI Firmware with Payload (FW_PAYLOAD)
==========================================
OpenSBI **firmware with Payload (FW_PAYLOAD)** is a firmware which directly
includes the binary for the booting stage to follow the OpenSBI firmware
execution. Typically, this payload will be a bootloader or an OS kernel.
A *FW_PAYLOAD* firmware is particularly useful when the booting stage executed
prior to the OpenSBI firmware is not capable of loading both the OpenSBI
firmware and the booting stage to follow OpenSBI firmware.
A *FW_PAYLOAD* firmware is also useful for cases where the booting stage prior
to the OpenSBI firmware does not pass a *flattened device tree (FDT file)*. In
such a case, a *FW_PAYLOAD* firmware allows embedding a flattened device tree
in the .text section of the final firmware.
Enabling *FW_PAYLOAD* compilation
---------------------------------
The *FW_PAYLOAD* firmware can be enabled by any of the following methods:
1. Specifying `FW_PAYLOAD=y` on the top level `make` command line.
2. Specifying `FW_PAYLOAD=y` in the target platform *config.mk* configuration
file.
The compiled *FW_PAYLOAD* firmware ELF file is named *fw_jump.elf*. Its
expanded image file is *fw_payload.bin*. Both files are created in the
platform-specific build directory under the
*build/platform/<platform_subdir>/firmware* directory.
Configuration Options
---------------------
A *FW_PAYLOAD* firmware is built according to configuration parameters and
options. These configuration parameters can be defined using either the top
level `make` command line or the target platform *config.mk* configuration
file. The parameters currently defined are as follows:
* **FW_PAYLOAD_OFFSET** - Offset from *FW_TEXT_BASE* where the payload binary
will be linked in the final *FW_PAYLOAD* firmware binary image. This
configuration parameter is mandatory if *FW_PAYLOAD_ALIGN* is not defined.
Compilation errors will result from an incorrect definition of
*FW_PAYLOAD_OFFSET* or of *FW_PAYLOAD_ALIGN*, or if neither of these
parameters are defined.
* **FW_PAYLOAD_ALIGN** - Address alignment constraint where the payload binary
will be linked after the end of the base firmware binary in the final
*FW_PAYLOAD* firmware binary image. This configuration parameter is mandatory
if *FW_PAYLOAD_OFFSET* is not defined. If both *FW_PAYLOAD_OFFSET* and
*FW_PAYLOAD_ALIGN* are defined, *FW_PAYLOAD_OFFSET* is used and
*FW_PAYLOAD_ALIGN* is ignored.
* **FW_PAYLOAD_PATH** - Path to the image file of the next booting stage
binary. If this option is not provided then a simple test payload is
automatically generated and used as a payload. This test payload executes
an infinite `while (1)` loop after printing a message on the platform console.
* **FW_PAYLOAD_FDT_ADDR** - Address where the FDT passed by the prior booting
stage or specified by the *FW_FDT_PATH* parameter and embedded in the
*.rodata* section will be placed before executing the next booting stage,
that is, the payload firmware. If this option is not provided, then the
firmware will pass the FDT address passed by the previous booting stage
to the next booting stage.
*FW_PAYLOAD* Example
--------------------
The *[qemu/virt]* platforms illustrate how to configure and use a *FW_PAYLOAD*
firmware. Detailed information regarding these platforms can be found in the
platform documentation files.
[qemu/virt]: ../platform/qemu_virt.md
Linux as a direct payload to OpenSBI
====================================
OpenSBI has the capability to load a Linux kernel image directly in supervisor
mode. The flattened image generated by the Linux kernel build process can be
provided as a payload to OpenSBI.
Detailed examples can be found in both the [QEMU](../platform/qemu_virt.md)
and the [HiFive Unleashed](../platform/sifive_fu540.md) platform guides.
U-Boot as a payload to OpenSBI
==============================
[U-Boot](https://www.denx.de/wiki/U-Boot) is an open-source primary boot loader.
It can be used as first and/or second stage boot loader in an embedded
environment. In the context of OpenSBI, U-Boot can be specified as a payload to
the OpenSBI firmware, becoming the boot stage following the OpenSBI firmware
execution.
Building and Generating U-Boot images
=====================================
Please refer to the U-Boot build documentation for detailed instructions on
how to build U-Boot image and boot high level operating systems from U-Boot
prompt.
OpenSBI Library Usage
=====================
OpenSBI provides two types of static libraries:
1. *libsbi.a* - A platform-independent generic static library implementing the
interface defined by the SBI specifications. Platform-specific processing
hooks for the execution of this interface must be provided by the firmware or
bootloader linking with this library. This library is installed as
*<install_directory>/lib/libsbi.a*
2. *libsbiutils.a* - A static library that will contain all common code required
by any platform supported in OpenSBI. It will be built by default and included
in libplatsbi.a. This library is installed as
*<install_directory>/lib/libsbiutils.a*.
3. *libplatsbi.a* - An example platform-specific static library integrating
*libsbi.a* with platform-specific hooks. This library is available only for
the platforms supported by OpenSBI. This library is installed as
*<install_directory>/platform/<platform_subdir>/lib/libplatsbi.a*
Implementations may choose either *libsbi.a* or *libplatsbi.a* to link with
their firmware or bootloader. In the case of *libsbi.a*, platform-specific
hooks in the form of a *struct sbi_platform* instance need to be provided.
The platform-specific example firmwares provided by OpenSBI are not mandatory.
An implementation may choose to link the OpenSBI generic static library together
with an M-mode firmware or bootloader providing the hardware-specific hooks.
Since OpenSBI is a statically linked library, users must ensure that the
license of these external components is compatible with the OpenSBI license.
Constraints on OpenSBI usage from external firmware
---------------------------------------------------
Users have to ensure that an external firmware or bootloader linking against
OpenSBI static libraries (*libsbi.a* or *libplatsbi.a*) is compiled with the
same GCC target options *-mabi*, *-march*, and *-mcmodel*.
There are only two constraints on calling any OpenSBI library function from an
external M-mode firmware or bootloader:
1. The RISC-V *MSCRATCH* CSR must point to a valid OpenSBI scratch space
(i.e. a *struct sbi_scratch* instance).
2. The RISC-V *SP* register (i.e. the stack pointer) must be set per-HART
pointing to distinct non-overlapping stacks.
The most important functions from an external firmware or bootloader
perspective are *sbi_init()* and *sbi_trap_handler()*.
In addition to the above constraints, the external firmware or bootloader must
ensure that interrupts are disabled in the *MSTATUS* and *MIE* CSRs when calling
the functions *sbi_init()* and *sbi_trap_handler()*.
The *sbi_init()* function should be called by the external firmware or
bootloader for each HART that is powered-up at boot-time or in response to a
CPU hotplug event.
The *sbi_trap_handler()* function should be called by the external firmware or
bootloader to service the following interrupts and traps:
1. M-mode timer interrupt
2. M-mode software interrupt
3. Illegal instruction trap
4. Misaligned load trap
5. Misaligned store trap
6. Supervisor ecall trap
7. Hypervisor ecall trap
**Note:** external firmwares or bootloaders can be more conservative by
forwarding all traps and interrupts to *sbi_trap_handler()*.
Definitions of OpenSBI Data Types for the External Firmware
-----------------------------------------------------------
OpenSBI can be built as library using external firmware build system such as EDK2
code base (The open source of UEFI firmware implementation) and linked with external
firmware drivers based on the external firmware architecture.
**OPENSBI_EXTERNAL_SBI_TYPES** identifier is introduced to *sbi_types.h* for selecting
external header file during the build preprocess in order to define OpensSBI data types
based on external firmware data type binding.
For example, *bool* is declared as *int* in sbi_types.h. However in EDK2 build system,
*bool* is declared as *BOOLEAN* which is defined as *unsigned char* data type.
External firmware can define **OPENSBI_EXTERNAL_SBI_TYPES** in CFLAGS and specify it to the
header file maintained in its code tree. However, the external build system has to address
the additional include directory for the external header file based on its own build system.
For example,
*-D***OPENSBI_EXTERNAL_SBI_TYPES***=OpensbiTypes.h*
Above tells *sbi_types.h* to refer to *OpensbiTypes.h* instead of using original definitions of
data types.
Andes AE350 SoC Platform
========================
The AE350 AXI/AHB-based platform N25(F)/NX25(F)/D25F/A25/AX25 CPU with level-one
memories,interrupt controller, debug module, AXI and AHB Bus Matrix Controller,
AXI-to-AHB Bridge and a collection of fundamentalAHB/APB bus IP components
pre-integrated together as a system design.The high-quality and configurable
AHB/APB IPs suites a majority embedded systems, and the verified platform serves
as a starting point to jump start SoC designs.
To build platform specific library and firmwares, provide the
*PLATFORM=andes/ae350* parameter to the top level make command.
Platform Options
----------------
The Andes AE350 platform does not have any platform-specific options.
Building Andes AE350 Platform
-----------------------------
To use Linux v5.2 should be used to build Andes AE350 OpenSBI binaries by using
the compile time option FW_FDT_PATH.
AE350's dts is included in https://github.com/andestech/linux/tree/ast-v3_2_0-release-public
**Linux Kernel Payload**
```
make PLATFORM=andes/ae350 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_FDT_PATH=<ae350.dtb path>
```
Ariane FPGA SoC Platform
========================
Ariane is a 6-stage, single issue, in-order CPU which implements the 64-bit
RISC-V instruction set. The Ariane FPGA development platform is based on FPGA
SoC (which currently supports only Genesys 2 board) and is capable of running
Linux.
The FPGA SoC currently contains the following peripherals:
- DDR3 memory controller
- SPI controller to conncet to an SDCard
- Ethernet controller
- JTAG port (see debugging section below)
- Bootrom containing zero stage bootloader and device tree.
To build platform specific library and firmwares, provide the
*PLATFORM=fpga/ariane* parameter to the top level `make` command.
Platform Options
----------------
The *Ariane FPGA* platform does not have any platform-specific options.
Building Ariane FPGA Platform
-----------------------------
**Linux Kernel Payload**
```
make PLATFORM=fpga/ariane FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
```
Booting Ariane FPGA Platform
----------------------------
**Linux Kernel Payload**
As Linux kernel image is embedded in the OpenSBI firmware binary, Ariane will
directly boot into Linux directly after powered on.
OpenPiton FPGA SoC Platform
========================
OpenPiton is the world's first open source, general purpose, multithreaded
manycore processor. It is a tiled manycore framework scalable from one to
1/2 billion cores. Currently, OpenPiton supports the 64bit Ariane RISC-V
processor from ETH Zurich. To this end, Ariane has been equipped with a
different L1 cache subsystem that follows a write-through protocol and that has
support for cache invalidations and atomics.
To build platform specific library and firmwares, provide the
*PLATFORM=fpga/openpiton* parameter to the top level `make` command.
Platform Options
----------------
The *OpenPiton* platform does not have any platform-specific options.
Building Ariane FPGA Platform
-----------------------------
**Linux Kernel Payload**
```
make PLATFORM=fpga/openpiton FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
```
Booting Ariane FPGA Platform
----------------------------
**Linux Kernel Payload**
As Linux kernel image is embedded in the OpenSBI firmware binary, Ariane will
directly boot into Linux directly after powered on.
Generic Platform
================
The **Generic** platform is a flattened device tree (FDT) based platform
where all platform specific functionality is provided based on FDT passed
by previous booting stage. The **Generic** platform allows us to use same
OpenSBI firmware binaries on various emulators, simulators, FPGAs, and
boards.
By default, the generic FDT platform makes following assumptions:
1. platform FW_TEXT_START is 0x80000000
2. platform features are default
3. platform stack size is default
4. platform has no quirks or work-arounds
The above assumptions (except 1) can be overridden by adding special platform
callbacks which will be called based on FDT root node compatible string.
Users of the generic FDT platform will have to ensure that:
1. Various FDT based drivers under lib/utils directory are upto date
based on their platform requirements
2. The FDT passed by previous booting stage has DT compatible strings and
DT properties in sync with the FDT based drivers under lib/utils directory
3. The FDT must have "stdout-path" DT property in the "/chosen" DT node when
a platform has multiple serial ports or consoles
4. On multi-HART platform, the FDT must have a DT node for IPI device and
lib/utils/ipi directory must have corresponding FDT based IPI driver
5. The FDT must have a DT node for timer device and lib/utils/timer directory
must have corresponding FDT based timer driver
To build the platform-specific library and firmware images, provide the
*PLATFORM=generic* parameter to the top level `make` command.
For custom FW_TEXT_START, we can build the platform-specific library and
firmware images by passing *PLATFORM=generic FW_TEXT_START=<custom_text_start>*
parameter to the top level `make` command.
Platform Options
----------------
The *Generic* platform does not have any platform-specific options.
RISC-V Platforms Using Generic Platform
---------------------------------------
* **QEMU RISC-V Virt Machine** (*[qemu_virt.md]*)
* **Spike** (*[spike.md]*)
* **Shakti C-class SoC Platform** (*[shakti_cclass.md]*)
* **T-HEAD C9xx series Processors** (*[thead-c9xx.md]*)
[qemu_virt.md]: qemu_virt.md
[spike.md]: spike.md
[shakti_cclass.md]: shakti_cclass.md
[thead-c9xx.md]: thead-c9xx.md
Nuclei UX600 Platform
=====================
The **Nuclei UX600** is a 64-bit RISC-V Core which is capable of running Linux.
> Nuclei UX600: single core, pipeline as single-issue and 6~9 variable stages, in-order dispatch and out-of-order write-back, running up to >1.2GHz
To build the platform-specific library and firmware images, provide the
*PLATFORM=nuclei/ux600* parameter to the top level `make` command.
Platform Options
----------------
The *Nuclei UX600* platform does not have any platform-specific options.
Building Nuclei UX600 Platform
------------------------------
```
make PLATFORM=nuclei/ux600 clean all
```
OpenSBI Supported Platforms
===========================
OpenSBI currently supports the following virtual and hardware platforms:
* **Generic**: Flattened device tree (FDT) based platform where platform
specific functionality is provided based on the FDT passed by previous
booting stage. More details on this platform can be found in the file
*[generic.md]*.
* **QEMU RISC-V Virt Machine**: Platform support for the QEMU *virt* virtual
RISC-V machine. This virtual machine is intended for RISC-V software
development and tests. More details on this platform can be found in the
file *[qemu_virt.md]*.
* **SiFive FU540 SoC**: Platform support for SiFive FU540 SoC used on the
HiFive Unleashed board, as well as the *sifive_u* QEMU virtual RISC-V
machine. More details on this platform can be found in the file
*[sifive_fu540.md]*.
* **Kendryte K210 SoC**: Platform support for the Kendryte K210 SoC used on
boards such as the Kendryte KD233 or the Sipeed MAIX Dock.
* **Ariane FPGA SoC**: Platform support for the Ariane FPGA SoC used on
Genesys 2 board. More details on this platform can be found in the file
*[fpga-ariane.md]*.
* **Andes AE350 SoC**: Platform support for the Andes's SoC (AE350). More
details on this platform can be found in the file *[andes-ae350.md]*.
* **Spike**: Platform support for the Spike emulator. More
details on this platform can be found in the file *[spike.md]*.
* **OpenPiton FPGA SoC**: Platform support OpenPiton research platform based
on ariane core. More details on this platform can be found in the file
*[fpga-openpiton.md]*.
* **Shakti C-class SoC Platform**: Platform support for Shakti C-class
processor based SOCs. More details on this platform can be found in the
file *[shakti_cclass.md]*.
The code for these supported platforms can be used as example to implement
support for other platforms. The *platform/template* directory also provides
template files for implementing support for a new platform. The *object.mk*,
*config.mk* and *platform.c* template files provides enough comments to
facilitate the implementation.
[generic.md]: generic.md
[qemu_virt.md]: qemu_virt.md
[sifive_fu540.md]: sifive_fu540.md
[fpga-ariane.md]: fpga-ariane.md
[andes-ae350.md]: andes-ae350.md
[thead-c910.md]: thead-c910.md
[spike.md]: spike.md
[fpga-openpiton.md]: fpga-openpiton.md
[shakti_cclass.md]: shakti_cclass.md
QEMU RISC-V Virt Machine Platform
=================================
The **QEMU RISC-V Virt Machine** is a virtual platform created for RISC-V
software development and testing. It is also referred to as
*QEMU RISC-V VirtIO machine* because it uses VirtIO devices for network,
storage, and other types of IO.
To build the platform-specific library and firmware images, provide the
*PLATFORM=generic* parameter to the top level `make` command.
Platform Options
----------------
The *QEMU RISC-V Virt Machine* platform does not have any platform-specific
options.
Execution on QEMU RISC-V 64-bit
-------------------------------
**No Payload Case**
Build:
```
make PLATFORM=generic
```
Run:
```
qemu-system-riscv64 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.bin
```
**U-Boot Payload**
Note: the command line examples here assume that U-Boot was compiled using
the `qemu-riscv64_smode_defconfig` configuration.
Build:
```
make PLATFORM=generic FW_PAYLOAD_PATH=<uboot_build_directory>/u-boot.bin
```
Run:
```
qemu-system-riscv64 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.elf
```
or
```
qemu-system-riscv64 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_jump.bin \
-kernel <uboot_build_directory>/u-boot.bin
```
**Linux Kernel Payload**
Note: We assume that the Linux kernel is compiled using
*arch/riscv/configs/defconfig*.
Build:
```
make PLATFORM=generic FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
```
Run:
```
qemu-system-riscv64 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.elf \
-drive file=<path_to_linux_rootfs>,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda rw console=ttyS0"
```
or
```
qemu-system-riscv64 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_jump.bin \
-kernel <linux_build_directory>/arch/riscv/boot/Image \
-drive file=<path_to_linux_rootfs>,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda rw console=ttyS0"
```
Execution on QEMU RISC-V 32-bit
-------------------------------
**No Payload Case**
Build:
```
make PLATFORM=generic PLATFORM_RISCV_XLEN=32
```
Run:
```
qemu-system-riscv32 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.bin
```
**U-Boot Payload**
Note: the command line examples here assume that U-Boot was compiled using
the `qemu-riscv32_smode_defconfig` configuration.
Build:
```
make PLATFORM=generic PLATFORM_RISCV_XLEN=32 FW_PAYLOAD_PATH=<uboot_build_directory>/u-boot.bin
```
Run:
```
qemu-system-riscv32 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.elf
```
or
```
qemu-system-riscv32 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_jump.bin \
-kernel <uboot_build_directory>/u-boot.bin
```
**Linux Kernel Payload**
Note: We assume that the Linux kernel is compiled using
*arch/riscv/configs/rv32_defconfig*.
Build:
```
make PLATFORM=generic PLATFORM_RISCV_XLEN=32 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
```
Run:
```
qemu-system-riscv32 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.elf \
-drive file=<path_to_linux_rootfs>,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda rw console=ttyS0"
```
or
```
qemu-system-riscv32 -M virt -m 256M -nographic \
-bios build/platform/generic/firmware/fw_jump.bin \
-kernel <linux_build_directory>/arch/riscv/boot/Image \
-drive file=<path_to_linux_rootfs>,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda rw console=ttyS0"
```
Shakti C-class SoC Platform
===========================
C-Class is a member of the SHAKTI family of processors from
Indian Institute of Technology - Madras (IIT-M).
It is an extremely configurable and commercial-grade 5-stage
in-order core supporting the standard RV64GCSUN ISA extensions.
For more details, refer:
* https://gitlab.com/shaktiproject/cores/c-class/blob/master/README.md
* https://c-class.readthedocs.io/en/latest
* https://shakti.org.in
Platform Options
----------------
The *Shakti C-class SoC* platform does not have any platform-specific
options.
Building Shakti C-class Platform
--------------------------------
**Linux Kernel Payload**
```
make PLATFORM=generic FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_FDT_PATH=<shakti.dtb path>
```
**Test Payload**
```
make PLATFORM=generic FW_FDT_PATH=<shakti.dtb path>
```
SiFive FU540 SoC Platform
=========================
The FU540-C000 is the world’s first 4+1 64-bit RISC-V SoC from SiFive.
The HiFive Unleashed development platform is based on FU540-C000 and capable
of running Linux.
With QEMU v4.2 or above release, the 'sifive_u' machine can be used to test
OpenSBI image built for the real hardware as well.
To build platform specific library and firmwares, provide the
*PLATFORM=sifive/fu540* parameter to the top level `make` command.
Platform Options
----------------
The *SiFive FU540 SoC* platform does not have any platform-specific
options.
Building SiFive Fu540 Platform
------------------------------
In order to boot SMP Linux in U-Boot, Linux v5.1 (or higher) and latest
U-Boot v2020.01 (or higher) should be used.
**Linux Kernel Payload**
The HiFive Unleashed device tree(DT) is merged in Linux v5.2 release. This
DT (device tree) is not backward compatible with the DT passed from FSBL.
To use Linux v5.2 (or higher), the pre-built DTB (DT binary) from Linux v5.2
(or higher) should be used to build SiFive FU540 OpenSBI binaries by using
the compile time option *FW_FDT_PATH*.
```
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
or
(For Linux v5.2 or higher)
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_FDT_PATH=<hifive-unleashed-a00.dtb path from Linux kernel>
```
**U-Boot Payload**
The command-line example here assumes that U-Boot was compiled using the
sifive_fu540_defconfig configuration and with U-Boot v2020.01, and up to
v2021.04. sifive_unleashed_defconfig shall be used with v2021.07 or above.
```
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<u-boot_build_dir>/u-boot-dtb.bin
```
For U-Boot v2020.07-rc4 or later releases, SPL support was added in U-Boot.
Please refer to the detailed U-Boot booting guide available at [U-Boot].
Flashing the OpenSBI firmware binary to storage media:
------------------------------------------------------
The first stage boot loader ([FSBL]) expects the storage media to have a GPT
partition table. It tries to look for a partition with following GUID to load
the next stage boot loader (OpenSBI in this case).
```
2E54B353-1271-4842-806F-E436D6AF6985
```
That's why the generated firmware binary in above steps should be copied to
the partition of the sdcard with above GUID.
```
dd if=build/platform/sifive/fu540/firmware/fw_payload.bin of=/dev/disk2s1 bs=1024
```
In my case, it is the first partition is **disk2s1** that has been formatted
with the above specified GUID.
In case of a brand new sdcard, it should be formatted with below partition
tables as described here.
```
sgdisk --clear \
--new=1:2048:67583 --change-name=1:bootloader --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985 \
--new=2:264192: --change-name=2:root --typecode=2:0FC63DAF-8483-4772-8E79-3D69D8477DE4 \
${DISK}
```
Booting SiFive Fu540 Platform
-----------------------------
**Linux Kernel Payload**
As Linux kernel image is embedded in the OpenSBI firmware binary, HiFive
Unleashed will directly boot into Linux directly after powered on.
**U-Boot Payload**
As U-Boot image is used as payload, HiFive Unleashed will boot into a U-Boot
prompt. U-Boot tftp boot method can be used to load kernel image in U-Boot
prompt. Here are the steps do a tftpboot.
1. Set the ip address of the board.
```
setenv ipaddr <ipaddr of the board>
```
2. Set the tftpboot server IP.
```
setenv serverip <ipaddr of the tftp server>
```
3. Set the network gateway address.
```
setenv gatewayip <ipaddress of the network gateway>
```
4. Load the Linux kernel image from the tftp server.
```
tftpboot ${kernel_addr_r} <Image path in tftpboot directory>
```
5. Load the ramdisk image from the tftp server. This is only required if
ramdisk is loaded from tftp server. This step is optional, if rootfs is
already part of the kernel or loaded from an external storage by kernel.
```
tftpboot ${ramdisk_addr_r} <ramdisk path in tftpboot directory>
```
6. Load the pre-compiled device tree via tftpboot.
```
tftpboot ${fdt_addr_r} <hifive-unleashed-a00.dtb path in tftpboot directory>
```
7. Set the boot command-line arguments.
```
setenv bootargs "root=<root partition> rw console=ttySIF0 earlycon=sbi"
```
(Note: root partition should point to
** /dev/ram ** - If a ramdisk is used
** root=/dev/mmcblk0pX ** - If a rootfs is already on some other partition
of sdcard)
8. Now boot into Linux.
```
booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
or
(If ramdisk is not loaded from network)
booti ${kernel_addr_r} - ${fdt_addr_r}
```
**U-Boot & Linux Kernel as a single payload**
At U-Boot prompt execute the following boot command to boot Linux.
```
booti ${kernel_addr_r} - ${fdt_addr_r}
```
QEMU Specific Instructions
--------------------------
If you want to test OpenSBI with QEMU 'sifive_u' machine, please follow the
same instructions above, with the exception of not passing FW_FDT_PATH.
This is because QEMU generates a device tree blob on the fly based on the
command line parameters and it's compatible with the one used in the upstream
Linux kernel.
When U-Boot v2021.07 (or higher) is used as the payload, as the SiFive FU540
DTB for the real hardware is embedded in U-Boot binary itself, due to the same
reason above, we need to switch the U-Boot sifive_unleashed_defconfig
configuration from **CONFIG_OF_SEPARATE** to **CONFIG_OF_PRIOR_STAGE** so that
U-Boot uses the DTB generated by QEMU, and u-boot.bin should be used as the
payload image, like:
```
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<u-boot_build_dir>/u-boot.bin
```
U-Boot v2020.07 release added SPL support to SiFive HiFive Unleashed board,
hence a build error will be seen after you switch to **CONFIG_OF_PRIOR_STAGE**.
```
./tools/mkimage: Can't open arch/riscv/dts/hifive-unleashed-a00.dtb: No such file or directory
./tools/mkimage: failed to build FIT
Makefile:1402: recipe for target 'u-boot.img' failed
make: *** [u-boot.img] Error 1
```
The above errors can be safely ignored as we don't run U-Boot SPL under QEMU.
Run:
```
qemu-system-riscv64 -M sifive_u -m 256M -nographic \
-bios build/platform/sifive/fu540/firmware/fw_payload.bin
```
or
```
qemu-system-riscv64 -M sifive_u -m 256M -nographic \
-bios build/platform/sifive/fu540/firmware/fw_jump.bin \
-kernel <uboot_build_dir>/u-boot.bin
```
While the real hardware operates at the 64-bit mode, it's possible for QEMU to
test the 32-bit OpenSBI firmware. This can be helpful for testing 32-bit SiFive
specific drivers.
[U-Boot]: https://gitlab.denx.de/u-boot/u-boot/blob/master/doc/board/sifive/fu540.rst
[FSBL]: https://github.com/sifive/freedom-u540-c000-bootloader
Spike Simulator Platform
========================
The **Spike** is a RISC-V ISA simulator which implements a functional model
of one or more RISC-V harts. The **Spike** compatible virtual platform is
also available on QEMU. In fact, we can use same OpenSBI firmware binaries
on **Spike** simulator and QEMU Spike machine.
For more details, refer [Spike on GitHub](https://github.com/riscv/riscv-isa-sim)
To build the platform-specific library and firmware images, provide the
*PLATFORM=generic* parameter to the top level `make` command.
Platform Options
----------------
The *Spike* platform does not have any platform-specific options.
Execution on Spike Simulator
----------------------------
**No Payload Case**
Build:
```
make PLATFORM=generic
```
Run:
```
spike build/platform/generic/firmware/fw_payload.elf
```
**Linux Kernel Payload**
Note: We assume that the Linux kernel is compiled using
*arch/riscv/configs/defconfig*.
Build:
```
make PLATFORM=generic FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
```
Run:
```
spike --initrd <path_to_cpio_ramdisk> build/platform/generic/firmware/fw_payload.elf
```
Execution on QEMU RISC-V 64-bit
-------------------------------
**No Payload Case**
Build:
```
make PLATFORM=generic
```
Run:
```
qemu-system-riscv64 -M spike -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.elf
```
**Linux Kernel Payload**
Note: We assume that the Linux kernel is compiled using
*arch/riscv/configs/defconfig*.
Build:
```
make PLATFORM=generic FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
```
Run:
```
qemu-system-riscv64 -M spike -m 256M -nographic \
-bios build/platform/generic/firmware/fw_payload.elf \
-initrd <path_to_cpio_ramdisk> \
-append "root=/dev/ram rw console=hvc0 earlycon=sbi"
```
or
```
qemu-system-riscv64 -M spike -m 256M -nographic \
-bios build/platform/generic/firmware/fw_jump.elf \
-kernel <linux_build_directory>/arch/riscv/boot/Image \
-initrd <path_to_cpio_ramdisk> \
-append "root=/dev/ram rw console=hvc0 earlycon=sbi"
```
T-HEAD C9xx Series Processors
=============================
The **C9xx** series processors are high-performance RISC-V architecture
multi-core processors with AI vector acceleration engine.
For more details, refer [T-HEAD.CN](https://www.t-head.cn/)
To build the platform-specific library and firmware images, provide the
*PLATFORM=generic* parameter to the top level `make` command.
Platform Options
----------------
The *T-HEAD C9xx* does not have any platform-specific compile options
because it use generic platform.
```
CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PIC=y /usr/bin/make
```
The *T-HEAD C9xx* DTB provided to OpenSBI generic firmwares will usually have
"riscv,clint0", "riscv,plic0", "thead,reset-sample" compatible strings.
DTS Example1: (Single core, eg: Allwinner D1 - c906)
----------------------------------------------------
```
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <3000000>;
cpu@0 {
device_type = "cpu";
reg = <0>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcv";
mmu-type = "riscv,sv39";
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
};
soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
ranges;
reset: reset-sample {
compatible = "thead,reset-sample";
plic-delegate = <0x0 0x101ffffc>;
};
clint0: clint@14000000 {
compatible = "riscv,clint0";
interrupts-extended = <
&cpu0_intc 3 &cpu0_intc 7
>;
reg = <0x0 0x14000000 0x0 0x04000000>;
clint,has-no-64bit-mmio;
};
intc: interrupt-controller@10000000 {
#interrupt-cells = <1>;
compatible = "riscv,plic0";
interrupt-controller;
interrupts-extended = <
&cpu0_intc 0xffffffff &cpu0_intc 9
>;
reg = <0x0 0x10000000 0x0 0x04000000>;
reg-names = "control";
riscv,max-priority = <7>;
riscv,ndev = <200>;
};
}
```
DTS Example2: (Multi cores with soc reset-regs)
-----------------------------------------------
```
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <3000000>;
cpu@0 {
device_type = "cpu";
reg = <0>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
cpu@1 {
device_type = "cpu";
reg = <1>;
status = "fail";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu1_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
cpu@2 {
device_type = "cpu";
reg = <2>;
status = "fail";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu2_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
cpu@3 {
device_type = "cpu";
reg = <3>;
status = "fail";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu3_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
};
soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
ranges;
reset: reset-sample {
compatible = "thead,reset-sample";
plic-delegate = <0xff 0xd81ffffc>;
entry-reg = <0xff 0xff019050>;
entry-cnt = <4>;
control-reg = <0xff 0xff015004>;
control-val = <0x1c>;
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc>;
};
clint0: clint@ffdc000000 {
compatible = "riscv,clint0";
interrupts-extended = <
&cpu0_intc 3 &cpu0_intc 7
&cpu1_intc 3 &cpu1_intc 7
&cpu2_intc 3 &cpu2_intc 7
&cpu3_intc 3 &cpu3_intc 7
&cpu4_intc 3 &cpu4_intc 7
>;
reg = <0xff 0xdc000000 0x0 0x04000000>;
clint,has-no-64bit-mmio;
};
intc: interrupt-controller@ffd8000000 {
#interrupt-cells = <1>;
compatible = "riscv,plic0";
interrupt-controller;
interrupts-extended = <
&cpu0_intc 0xffffffff &cpu0_intc 9
&cpu1_intc 0xffffffff &cpu1_intc 9
&cpu2_intc 0xffffffff &cpu2_intc 9
&cpu3_intc 0xffffffff &cpu3_intc 9
>;
reg = <0xff 0xd8000000 0x0 0x04000000>;
reg-names = "control";
riscv,max-priority = <7>;
riscv,ndev = <80>;
};
}
```
DTS Example2: (Multi cores with old reset csrs)
-----------------------------------------------
```
reset: reset-sample {
compatible = "thead,reset-sample";
plic-delegate = <0xff 0xd81ffffc>;
using-csr-reset;
csr-copy = <0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc
0x3b0 0x3b1 0x3b2 0x3b3
0x3b4 0x3b5 0x3b6 0x3b7
0x3a0>;
};
```
OpenSBI Platform Support Guideline
==================================
The OpenSBI platform support allows an implementation to define a set of
platform-specific hooks (hardware manipulation functions) in the form of a
*struct sbi_platform* data structure instance. This instance is required by
the platform-independent *libsbi.a* to execute platform-specific operations.
Each of the reference platform supports provided by OpenSBI defines an instance
of the *struct sbi_platform* data structure. For each supported platform,
*libplatsbi.a* integrates this instance with *libsbi.a* to create a
platform-specific OpenSBI static library. This library is installed
in *<install_directory>/platform/<platform_subdir>/lib/libplatsbi.a*
OpenSBI also provides implementation examples of bootable runtime firmwares for
the supported platforms. These firmwares are linked against *libplatsbi.a*.
Firmware binaries are installed in
*<install_directory>/platform/<platform_subdir>/bin*. These firmwares can be
used as executable runtime firmwares on the supported platforms as a replacement
for the legacy *riskv-pk* boot loader (BBL).
A complete doxygen-style documentation of *struct sbi_platform* and related
APIs is available in the file *include/sbi/sbi_platform.h*.
Adding support for a new platform
---------------------------------
Support for a new platform named *<xyz>* can be added as follows:
1. Create a directory named *<xyz>* under the *platform/* directory.
2. Create a platform configuration file named *config.mk* under the
*platform/<xyz>/* directory. This configuration file will provide
compiler flags, and select firmware options.
3. Create a *platform/<xyz>/objects.mk* file for listing the
platform-specific object files to be compiled.
4. Create a *platform/<xyz>/platform.c* file providing a *struct sbi_platform*
instance.
A platform support code template is available under the *platform/template*
directory. Copying this directory and its content as a new directory named
*<xyz>* under the *platform/* directory will create all the files mentioned
above.
OpenSBI Platform Requirements
=============================
The RISC-V platform requirements for OpenSBI can change over time
with advances in RISC-V specifications and ecosystem.
To handle this, we have two types of RISC-V platform requirements:
1. **Base platform requirements** which apply to all OpenSBI releases
2. **Release specific platform requirements** which apply to a OpenSBI
release and later releases
Currently, we don't have any **Release specific platform requirements**
but such platform requirements will be added in future.
Base Platform Requirements
--------------------------
The base RISC-V platform requirements for OpenSBI are as follows:
1. At least rv32ima or rv64ima required on all HARTs
2. At least one HART should have S-mode support because:
* SBI calls are meant for RISC-V S-mode (Supervisor mode)
* OpenSBI implements SBI calls for S-mode software
3. The MTVEC CSR on all HARTs must support direct mode
4. The PMP CSRs are optional. If PMP CSRs are not implemented then
OpenSBI cannot protect M-mode firmware and secured memory regions
5. The TIME CSR is optional. If TIME CSR is not implemented in
hardware then a 64-bit MMIO counter is required to track time
and emulate TIME CSR
6. Hardware support for injecting M-mode software interrupts on
a multi-HART platform
The RISC-V extensions not covered by rv32ima or rv64ima are optional
for OpenSBI. Although, OpenSBI will detect and handle some of these
optional RISC-V extensions at runtime.
The optional RISC-V extensions handled by OpenSBI at runtime are:
* D-extension: Double precision floating point
* F-extension: Single precision floating point
* H-extension: Hypervisor
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Western Digital Corporation or its affiliates.
#
# Authors:
# Anup Patel <anup.patel@wdc.com>
#
$(platform_build_dir)/firmware/fw_dynamic.o: $(FW_FDT_PATH)
$(platform_build_dir)/firmware/fw_jump.o: $(FW_FDT_PATH)
$(platform_build_dir)/firmware/fw_payload.o: $(FW_FDT_PATH)
$(platform_build_dir)/firmware/fw_payload.o: $(FW_PAYLOAD_PATH_FINAL)
This diff is collapsed.
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
. = FW_TEXT_START;
PROVIDE(_fw_start = .);
. = ALIGN(0x1000); /* Need this to create proper sections */
/* Beginning of the code section */
.text :
{
PROVIDE(_text_start = .);
*(.entry)
*(.text)
. = ALIGN(8);
PROVIDE(_text_end = .);
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
/* End of the code sections */
/* Beginning of the read-only data sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.rodata :
{
PROVIDE(_rodata_start = .);
*(.rodata .rodata.*)
. = ALIGN(8);
PROVIDE(_rodata_end = .);
}
/* End of the read-only data sections */
/* Beginning of the read-write data sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.data :
{
PROVIDE(_data_start = .);
*(.sdata)
*(.sdata.*)
*(.data)
*(.data.*)
*(.readmostly.data)
*(*.data)
. = ALIGN(8);
PROVIDE(_data_end = .);
}
.dynsym : {
PROVIDE(__dyn_sym_start = .);
*(.dynsym)
PROVIDE(__dyn_sym_end = .);
}
.rela.dyn : {
PROVIDE(__rel_dyn_start = .);
*(.rela*)
. = ALIGN(8);
PROVIDE(__rel_dyn_end = .);
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.bss :
{
PROVIDE(_bss_start = .);
*(.sbss)
*(.sbss.*)
*(.bss)
*(.bss.*)
. = ALIGN(8);
PROVIDE(_bss_end = .);
}
/* End of the read-write data sections */
. = ALIGN(0x1000); /* Need this to create proper sections */
PROVIDE(_fw_end = .);
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#include <sbi/fw_dynamic.h>
#include "fw_base.S"
.section .entry, "ax", %progbits
.align 3
_bad_dynamic_info:
wfi
j _bad_dynamic_info
.section .entry, "ax", %progbits
.align 3
.global fw_boot_hart
/*
* This function is called very early even before
* fw_save_info() is called.
* We can only use a0, a1, and a2 registers here.
* The boot HART id should be returned in 'a0'.
*/
fw_boot_hart:
/* Sanity checks */
li a1, FW_DYNAMIC_INFO_MAGIC_VALUE
REG_L a0, FW_DYNAMIC_INFO_MAGIC_OFFSET(a2)
bne a0, a1, _bad_dynamic_info
li a1, FW_DYNAMIC_INFO_VERSION_MAX
REG_L a0, FW_DYNAMIC_INFO_VERSION_OFFSET(a2)
bgt a0, a1, _bad_dynamic_info
/* Read boot HART id */
li a1, 0x2
blt a0, a1, 2f
REG_L a0, FW_DYNAMIC_INFO_BOOT_HART_OFFSET(a2)
ret
2: li a0, -1
ret
.section .entry, "ax", %progbits
.align 3
.global fw_save_info
/*
* We can only use a0, a1, a2, a3, and a4 registers here.
* The a0, a1, and a2 registers will be same as passed by
* previous booting stage.
* Nothing to be returned here.
*/
fw_save_info:
/* Save next arg1 in 'a1' */
lla a4, _dynamic_next_arg1
REG_S a1, (a4)
/* Sanity checks */
li a4, FW_DYNAMIC_INFO_MAGIC_VALUE
REG_L a3, FW_DYNAMIC_INFO_MAGIC_OFFSET(a2)
bne a3, a4, _bad_dynamic_info
li a4, FW_DYNAMIC_INFO_VERSION_MAX
REG_L a3, FW_DYNAMIC_INFO_VERSION_OFFSET(a2)
bgt a3, a4, _bad_dynamic_info
/* Save version == 0x1 fields */
lla a4, _dynamic_next_addr
REG_L a3, FW_DYNAMIC_INFO_NEXT_ADDR_OFFSET(a2)
REG_S a3, (a4)
lla a4, _dynamic_next_mode
REG_L a3, FW_DYNAMIC_INFO_NEXT_MODE_OFFSET(a2)
REG_S a3, (a4)
lla a4, _dynamic_options
REG_L a3, FW_DYNAMIC_INFO_OPTIONS_OFFSET(a2)
REG_S a3, (a4)
/* Save version == 0x2 fields */
li a4, 0x2
REG_L a3, FW_DYNAMIC_INFO_VERSION_OFFSET(a2)
blt a3, a4, 2f
lla a4, _dynamic_boot_hart
REG_L a3, FW_DYNAMIC_INFO_BOOT_HART_OFFSET(a2)
REG_S a3, (a4)
2:
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_arg1
/*
* We can only use a0, a1, and a2 registers here.
* The a0, a1, and a2 registers will be same as passed by
* previous booting stage.
* The next arg1 should be returned in 'a0'.
*/
fw_next_arg1:
lla a0, _dynamic_next_arg1
REG_L a0, (a0)
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_addr
/*
* We can only use a0, a1, and a2 registers here.
* The next address should be returned in 'a0'.
*/
fw_next_addr:
lla a0, _dynamic_next_addr
REG_L a0, (a0)
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_mode
/*
* We can only use a0, a1, and a2 registers here.
* The next address should be returned in 'a0'
*/
fw_next_mode:
lla a0, _dynamic_next_mode
REG_L a0, (a0)
ret
.section .entry, "ax", %progbits
.align 3
.global fw_options
/*
* We can only use a0, a1, and a2 registers here.
* The 'a4' register will have default options.
* The next address should be returned in 'a0'.
*/
fw_options:
lla a0, _dynamic_options
REG_L a0, (a0)
ret
.section .entry, "ax", %progbits
.align 3
_dynamic_next_arg1:
RISCV_PTR 0x0
_dynamic_next_addr:
RISCV_PTR 0x0
_dynamic_next_mode:
RISCV_PTR PRV_S
_dynamic_options:
RISCV_PTR 0x0
_dynamic_boot_hart:
RISCV_PTR -1
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
OUTPUT_ARCH(riscv)
ENTRY(_start)
SECTIONS
{
#include "fw_base.ldS"
PROVIDE(_fw_reloc_end = .);
}
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#include "fw_base.S"
.section .entry, "ax", %progbits
.align 3
.global fw_boot_hart
/*
* This function is called very early even before
* fw_save_info() is called.
* We can only use a0, a1, and a2 registers here.
* The boot HART id should be returned in 'a0'.
*/
fw_boot_hart:
li a0, -1
ret
.section .entry, "ax", %progbits
.align 3
.global fw_save_info
/*
* We can only use a0, a1, a2, a3, and a4 registers here.
* The a0, a1, and a2 registers will be same as passed by
* previous booting stage.
* Nothing to be returned here.
*/
fw_save_info:
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_arg1
/*
* We can only use a0, a1, and a2 registers here.
* The a0, a1, and a2 registers will be same as passed by
* previous booting stage.
* The next arg1 should be returned in 'a0'.
*/
fw_next_arg1:
#ifdef FW_JUMP_FDT_ADDR
li a0, FW_JUMP_FDT_ADDR
#else
add a0, a1, zero
#endif
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_addr
/*
* We can only use a0, a1, and a2 registers here.
* The next address should be returned in 'a0'.
*/
fw_next_addr:
lla a0, _jump_addr
REG_L a0, (a0)
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_mode
/*
* We can only use a0, a1, and a2 registers here.
* The next address should be returned in 'a0'
*/
fw_next_mode:
li a0, PRV_S
ret
.section .entry, "ax", %progbits
.align 3
.global fw_options
/*
* We can only use a0, a1, and a2 registers here.
* The 'a4' register will have default options.
* The next address should be returned in 'a0'.
*/
fw_options:
add a0, zero, zero
ret
#ifndef FW_JUMP_ADDR
#error "Must define FW_JUMP_ADDR"
#endif
.section .entry, "ax", %progbits
.align 3
_jump_addr:
RISCV_PTR FW_JUMP_ADDR
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
OUTPUT_ARCH(riscv)
ENTRY(_start)
SECTIONS
{
#include "fw_base.ldS"
PROVIDE(_fw_reloc_end = .);
}
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#include "fw_base.S"
.section .entry, "ax", %progbits
.align 3
.global fw_boot_hart
/*
* This function is called very early even before
* fw_save_info() is called.
* We can only use a0, a1, and a2 registers here.
* The boot HART id should be returned in 'a0'.
*/
fw_boot_hart:
li a0, -1
ret
.section .entry, "ax", %progbits
.align 3
.global fw_save_info
/*
* We can only use a0, a1, a2, a3, and a4 registers here.
* The a0, a1, and a2 registers will be same as passed by
* previous booting stage.
* Nothing to be returned here.
*/
fw_save_info:
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_arg1
/*
* We can only use a0, a1, and a2 registers here.
* The a0, a1, and a2 registers will be same as passed by
* previous booting stage.
* The next arg1 should be returned in 'a0'.
*/
fw_next_arg1:
#ifdef FW_PAYLOAD_FDT_ADDR
li a0, FW_PAYLOAD_FDT_ADDR
#else
add a0, a1, zero
#endif
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_addr
/*
* We can only use a0, a1, and a2 registers here.
* The next address should be returned in 'a0'.
*/
fw_next_addr:
lla a0, payload_bin
ret
.section .entry, "ax", %progbits
.align 3
.global fw_next_mode
/*
* We can only use a0, a1, and a2 registers here.
* The next address should be returned in 'a0'.
*/
fw_next_mode:
li a0, PRV_S
ret
.section .entry, "ax", %progbits
.align 3
.global fw_options
/*
* We can only use a0, a1, and a2 registers here.
* The 'a4' register will have default options.
* The next address should be returned in 'a0'.
*/
fw_options:
add a0, zero, zero
ret
.section .payload, "ax", %progbits
.align 4
.globl payload_bin
payload_bin:
#ifndef FW_PAYLOAD_PATH
wfi
j payload_bin
#else
.incbin FW_PAYLOAD_PATH
#endif
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
OUTPUT_ARCH(riscv)
ENTRY(_start)
SECTIONS
{
#include "fw_base.ldS"
#ifdef FW_PAYLOAD_OFFSET
. = FW_TEXT_START + FW_PAYLOAD_OFFSET;
#else
. = ALIGN(FW_PAYLOAD_ALIGN);
#endif
.payload :
{
PROVIDE(_payload_start = .);
*(.payload)
. = ALIGN(8);
PROVIDE(_payload_end = .);
}
PROVIDE(_fw_reloc_end = .);
}
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Western Digital Corporation or its affiliates.
#
# Authors:
# Anup Patel <anup.patel@wdc.com>
#
firmware-genflags-y =
firmware-cppflags-y +=
firmware-cflags-y +=
firmware-asflags-y +=
firmware-ldflags-y +=
ifndef FW_PIC
FW_PIC := y
endif
ifeq ($(FW_PIC),y)
firmware-genflags-y += -DFW_PIC
firmware-asflags-y += -fpic
firmware-cflags-y += -fPIE -pie
firmware-ldflags-y += -Wl,--no-dynamic-linker
endif
ifdef FW_TEXT_START
firmware-genflags-y += -DFW_TEXT_START=$(FW_TEXT_START)
endif
ifdef FW_FDT_PATH
firmware-genflags-y += -DFW_FDT_PATH=\"$(FW_FDT_PATH)\"
ifdef FW_FDT_PADDING
firmware-genflags-y += -DFW_FDT_PADDING=$(FW_FDT_PADDING)
endif
endif
firmware-bins-$(FW_DYNAMIC) += fw_dynamic.bin
firmware-bins-$(FW_JUMP) += fw_jump.bin
ifdef FW_JUMP_ADDR
firmware-genflags-$(FW_JUMP) += -DFW_JUMP_ADDR=$(FW_JUMP_ADDR)
endif
ifdef FW_JUMP_FDT_ADDR
firmware-genflags-$(FW_JUMP) += -DFW_JUMP_FDT_ADDR=$(FW_JUMP_FDT_ADDR)
endif
firmware-bins-$(FW_PAYLOAD) += fw_payload.bin
ifdef FW_PAYLOAD_PATH
FW_PAYLOAD_PATH_FINAL=$(FW_PAYLOAD_PATH)
else
FW_PAYLOAD_PATH_FINAL=$(platform_build_dir)/firmware/payloads/test.bin
endif
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_PATH=\"$(FW_PAYLOAD_PATH_FINAL)\"
ifdef FW_PAYLOAD_OFFSET
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_OFFSET=$(FW_PAYLOAD_OFFSET)
endif
ifdef FW_PAYLOAD_ALIGN
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_ALIGN=$(FW_PAYLOAD_ALIGN)
endif
ifdef FW_PAYLOAD_FDT_ADDR
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_FDT_ADDR=$(FW_PAYLOAD_FDT_ADDR)
endif
ifdef FW_OPTIONS
firmware-genflags-y += -DFW_OPTIONS=$(FW_OPTIONS)
endif
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Western Digital Corporation or its affiliates.
#
# Authors:
# Anup Patel <anup.patel@wdc.com>
#
firmware-bins-$(FW_PAYLOAD) += payloads/test.bin
test-y += test_head.o
test-y += test_main.o
%/test.o: $(foreach obj,$(test-y),%/$(obj))
$(call merge_objs,$@,$^)
%/test.dep: $(foreach dep,$(test-y:.o=.dep),%/$(dep))
$(call merge_deps,$@,$^)
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
OUTPUT_ARCH(riscv)
ENTRY(_start)
SECTIONS
{
#ifdef FW_PAYLOAD_OFFSET
. = FW_TEXT_START + FW_PAYLOAD_OFFSET;
#else
. = ALIGN(FW_PAYLOAD_ALIGN);
#endif
PROVIDE(_payload_start = .);
. = ALIGN(0x1000); /* Need this to create proper sections */
/* Beginning of the code section */
.text :
{
PROVIDE(_text_start = .);
*(.entry)
*(.text)
. = ALIGN(8);
PROVIDE(_text_end = .);
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
/* End of the code sections */
/* Beginning of the read-only data sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.rodata :
{
PROVIDE(_rodata_start = .);
*(.rodata .rodata.*)
. = ALIGN(8);
PROVIDE(_rodata_end = .);
}
/* End of the read-only data sections */
/* Beginning of the read-write data sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.data :
{
PROVIDE(_data_start = .);
*(.data)
*(.data.*)
*(.readmostly.data)
*(*.data)
. = ALIGN(8);
PROVIDE(_data_end = .);
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.bss :
{
PROVIDE(_bss_start = .);
*(.bss)
*(.bss.*)
. = ALIGN(8);
PROVIDE(_bss_end = .);
}
/* End of the read-write data sections */
. = ALIGN(0x1000); /* Need this to create proper sections */
PROVIDE(_payload_end = .);
}
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#include <sbi/riscv_encoding.h>
#define __ASM_STR(x) x
#if __riscv_xlen == 64
#define __REG_SEL(a, b) __ASM_STR(a)
#define RISCV_PTR .dword
#elif __riscv_xlen == 32
#define __REG_SEL(a, b) __ASM_STR(b)
#define RISCV_PTR .word
#else
#error "Unexpected __riscv_xlen"
#endif
#define REG_L __REG_SEL(ld, lw)
#define REG_S __REG_SEL(sd, sw)
.section .entry, "ax", %progbits
.align 3
.globl _start
_start:
/* Pick one hart to run the main boot sequence */
lla a3, _hart_lottery
li a2, 1
amoadd.w a3, a2, (a3)
bnez a3, _start_hang
/* Save a0 and a1 */
lla a3, _boot_a0
REG_S a0, 0(a3)
lla a3, _boot_a1
REG_S a1, 0(a3)
/* Zero-out BSS */
lla a4, _bss_start
lla a5, _bss_end
_bss_zero:
REG_S zero, (a4)
add a4, a4, __SIZEOF_POINTER__
blt a4, a5, _bss_zero
_start_warm:
/* Disable and clear all interrupts */
csrw CSR_SIE, zero
csrw CSR_SIP, zero
/* Setup exception vectors */
lla a3, _start_hang
csrw CSR_STVEC, a3
/* Setup stack */
lla a3, _payload_end
li a4, 0x2000
add sp, a3, a4
/* Jump to C main */
lla a3, _boot_a0
REG_L a0, 0(a3)
lla a3, _boot_a1
REG_L a1, 0(a3)
call test_main
/* We don't expect to reach here hence just hang */
j _start_hang
.section .entry, "ax", %progbits
.align 3
.globl _start_hang
_start_hang:
wfi
j _start_hang
.section .entry, "ax", %progbits
.align 3
_hart_lottery:
RISCV_PTR 0
_boot_a0:
RISCV_PTR 0
_boot_a1:
RISCV_PTR 0
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#include <sbi/sbi_ecall_interface.h>
#define SBI_ECALL(__num, __a0, __a1, __a2) \
({ \
register unsigned long a0 asm("a0") = (unsigned long)(__a0); \
register unsigned long a1 asm("a1") = (unsigned long)(__a1); \
register unsigned long a2 asm("a2") = (unsigned long)(__a2); \
register unsigned long a7 asm("a7") = (unsigned long)(__num); \
asm volatile("ecall" \
: "+r"(a0) \
: "r"(a1), "r"(a2), "r"(a7) \
: "memory"); \
a0; \
})
#define SBI_ECALL_0(__num) SBI_ECALL(__num, 0, 0, 0)
#define SBI_ECALL_1(__num, __a0) SBI_ECALL(__num, __a0, 0, 0)
#define SBI_ECALL_2(__num, __a0, __a1) SBI_ECALL(__num, __a0, __a1, 0)
#define sbi_ecall_console_putc(c) SBI_ECALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, (c))
static inline void sbi_ecall_console_puts(const char *str)
{
while (str && *str)
sbi_ecall_console_putc(*str++);
}
#define wfi() \
do { \
__asm__ __volatile__("wfi" ::: "memory"); \
} while (0)
void test_main(unsigned long a0, unsigned long a1)
{
sbi_ecall_console_puts("\nTest payload running\n");
while (1)
wfi();
}
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __FW_DYNAMIC_H__
#define __FW_DYNAMIC_H__
#include <sbi/riscv_asm.h>
/* clang-format off */
/** Offset of magic member in fw_dynamic_info */
#define FW_DYNAMIC_INFO_MAGIC_OFFSET (0 * __SIZEOF_POINTER__)
/** Offset of version member in fw_dynamic_info */
#define FW_DYNAMIC_INFO_VERSION_OFFSET (1 * __SIZEOF_POINTER__)
/** Offset of next_addr member in fw_dynamic_info (version >= 1) */
#define FW_DYNAMIC_INFO_NEXT_ADDR_OFFSET (2 * __SIZEOF_POINTER__)
/** Offset of next_mode member in fw_dynamic_info (version >= 1) */
#define FW_DYNAMIC_INFO_NEXT_MODE_OFFSET (3 * __SIZEOF_POINTER__)
/** Offset of options member in fw_dynamic_info (version >= 1) */
#define FW_DYNAMIC_INFO_OPTIONS_OFFSET (4 * __SIZEOF_POINTER__)
/** Offset of boot_hart member in fw_dynamic_info (version >= 2) */
#define FW_DYNAMIC_INFO_BOOT_HART_OFFSET (5 * __SIZEOF_POINTER__)
/** Expected value of info magic ('OSBI' ascii string in hex) */
#define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f
/** Maximum supported info version */
#define FW_DYNAMIC_INFO_VERSION_MAX 0x2
/** Possible next mode values */
#define FW_DYNAMIC_INFO_NEXT_MODE_U 0x0
#define FW_DYNAMIC_INFO_NEXT_MODE_S 0x1
#define FW_DYNAMIC_INFO_NEXT_MODE_M 0x3
/* clang-format on */
#ifndef __ASSEMBLER__
#include <sbi/sbi_types.h>
/** Representation dynamic info passed by previous booting stage */
struct fw_dynamic_info {
/** Info magic */
unsigned long magic;
/** Info version */
unsigned long version;
/** Next booting stage address */
unsigned long next_addr;
/** Next booting stage mode */
unsigned long next_mode;
/** Options for OpenSBI library */
unsigned long options;
/**
* Preferred boot HART id
*
* It is possible that the previous booting stage uses same link
* address as the FW_DYNAMIC firmware. In this case, the relocation
* lottery mechanism can potentially overwrite the previous booting
* stage while other HARTs are still running in the previous booting
* stage leading to boot-time crash. To avoid this boot-time crash,
* the previous booting stage can specify last HART that will jump
* to the FW_DYNAMIC firmware as the preferred boot HART.
*
* To avoid specifying a preferred boot HART, the previous booting
* stage can set it to -1UL which will force the FW_DYNAMIC firmware
* to use the relocation lottery mechanism.
*/
unsigned long boot_hart;
} __packed;
#endif
#endif
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __RISCV_ASM_H__
#define __RISCV_ASM_H__
#include <sbi/riscv_encoding.h>
/* clang-format off */
#ifdef __ASSEMBLER__
#define __ASM_STR(x) x
#else
#define __ASM_STR(x) #x
#endif
#if __riscv_xlen == 64
#define __REG_SEL(a, b) __ASM_STR(a)
#elif __riscv_xlen == 32
#define __REG_SEL(a, b) __ASM_STR(b)
#else
#error "Unexpected __riscv_xlen"
#endif
#define PAGE_SHIFT (12)
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define REG_L __REG_SEL(ld, lw)
#define REG_S __REG_SEL(sd, sw)
#define SZREG __REG_SEL(8, 4)
#define LGREG __REG_SEL(3, 2)
#if __SIZEOF_POINTER__ == 8
#ifdef __ASSEMBLER__
#define RISCV_PTR .dword
#define RISCV_SZPTR 8
#define RISCV_LGPTR 3
#else
#define RISCV_PTR ".dword"
#define RISCV_SZPTR "8"
#define RISCV_LGPTR "3"
#endif
#elif __SIZEOF_POINTER__ == 4
#ifdef __ASSEMBLER__
#define RISCV_PTR .word
#define RISCV_SZPTR 4
#define RISCV_LGPTR 2
#else
#define RISCV_PTR ".word"
#define RISCV_SZPTR "4"
#define RISCV_LGPTR "2"
#endif
#else
#error "Unexpected __SIZEOF_POINTER__"
#endif
#if (__SIZEOF_INT__ == 4)
#define RISCV_INT __ASM_STR(.word)
#define RISCV_SZINT __ASM_STR(4)
#define RISCV_LGINT __ASM_STR(2)
#else
#error "Unexpected __SIZEOF_INT__"
#endif
#if (__SIZEOF_SHORT__ == 2)
#define RISCV_SHORT __ASM_STR(.half)
#define RISCV_SZSHORT __ASM_STR(2)
#define RISCV_LGSHORT __ASM_STR(1)
#else
#error "Unexpected __SIZEOF_SHORT__"
#endif
/* clang-format on */
#ifndef __ASSEMBLER__
#define csr_swap(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__("csrrw %0, " __ASM_STR(csr) ", %1" \
: "=r"(__v) \
: "rK"(__v) \
: "memory"); \
__v; \
})
#define csr_read(csr) \
({ \
register unsigned long __v; \
__asm__ __volatile__("csrr %0, " __ASM_STR(csr) \
: "=r"(__v) \
: \
: "memory"); \
__v; \
})
#define csr_write(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__("csrw " __ASM_STR(csr) ", %0" \
: \
: "rK"(__v) \
: "memory"); \
})
#define csr_read_set(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__("csrrs %0, " __ASM_STR(csr) ", %1" \
: "=r"(__v) \
: "rK"(__v) \
: "memory"); \
__v; \
})
#define csr_set(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__("csrs " __ASM_STR(csr) ", %0" \
: \
: "rK"(__v) \
: "memory"); \
})
#define csr_read_clear(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__("csrrc %0, " __ASM_STR(csr) ", %1" \
: "=r"(__v) \
: "rK"(__v) \
: "memory"); \
__v; \
})
#define csr_clear(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__("csrc " __ASM_STR(csr) ", %0" \
: \
: "rK"(__v) \
: "memory"); \
})
unsigned long csr_read_num(int csr_num);
void csr_write_num(int csr_num, unsigned long val);
#define wfi() \
do { \
__asm__ __volatile__("wfi" ::: "memory"); \
} while (0)
#define ebreak() \
do { \
__asm__ __volatile__("ebreak" ::: "memory"); \
} while (0)
/* Get current HART id */
#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID))
/* determine CPU extension, return non-zero support */
int misa_extension_imp(char ext);
#define misa_extension(c)\
({\
_Static_assert(((c >= 'A') && (c <= 'Z')),\
"The parameter of misa_extension must be [A-Z]");\
misa_extension_imp(c);\
})
/* Get MXL field of misa, return -1 on error */
int misa_xlen(void);
/* Get RISC-V ISA string representation */
void misa_string(int xlen, char *out, unsigned int out_sz);
int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
unsigned long log2len);
int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
unsigned long *log2len);
#endif /* !__ASSEMBLER__ */
#endif
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __RISCV_ATOMIC_H__
#define __RISCV_ATOMIC_H__
typedef struct {
volatile long counter;
} atomic_t;
#define ATOMIC_INIT(_lptr, val) (_lptr)->counter = (val)
#define ATOMIC_INITIALIZER(val) \
{ \
.counter = (val), \
}
long atomic_read(atomic_t *atom);
void atomic_write(atomic_t *atom, long value);
long atomic_add_return(atomic_t *atom, long value);
long atomic_sub_return(atomic_t *atom, long value);
long atomic_cmpxchg(atomic_t *atom, long oldval, long newval);
long atomic_xchg(atomic_t *atom, long newval);
unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr,
unsigned int newval);
unsigned long atomic_raw_xchg_ulong(volatile unsigned long *ptr,
unsigned long newval);
/**
* Set a bit in an atomic variable and return the new value.
* @nr : Bit to set.
* @atom: atomic variable to modify
*/
int atomic_set_bit(int nr, atomic_t *atom);
/**
* Clear a bit in an atomic variable and return the new value.
* @nr : Bit to set.
* @atom: atomic variable to modify
*/
int atomic_clear_bit(int nr, atomic_t *atom);
/**
* Set a bit in any address and return the new value .
* @nr : Bit to set.
* @addr: Address to modify
*/
int atomic_raw_set_bit(int nr, volatile unsigned long *addr);
/**
* Clear a bit in any address and return the new value .
* @nr : Bit to set.
* @addr: Address to modify
*/
int atomic_raw_clear_bit(int nr, volatile unsigned long *addr);
#endif
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __RISCV_BARRIER_H__
#define __RISCV_BARRIER_H__
/* clang-format off */
#define RISCV_ACQUIRE_BARRIER "\tfence r , rw\n"
#define RISCV_RELEASE_BARRIER "\tfence rw, w\n"
#define RISCV_FENCE(p, s) \
__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
#define RISCV_FENCE_I \
__asm__ __volatile__ ("fence.i" : : : "memory")
/* Read & Write Memory barrier */
#define mb() RISCV_FENCE(iorw,iorw)
/* Read Memory barrier */
#define rmb() RISCV_FENCE(ir,ir)
/* Write Memory barrier */
#define wmb() RISCV_FENCE(ow,ow)
/* SMP Read & Write Memory barrier */
#define smp_mb() RISCV_FENCE(rw,rw)
/* SMP Read Memory barrier */
#define smp_rmb() RISCV_FENCE(r,r)
/* SMP Write Memory barrier */
#define smp_wmb() RISCV_FENCE(w,w)
/* CPU relax for busy loop */
#define cpu_relax() asm volatile ("" : : : "memory")
/* clang-format on */
#define __smp_store_release(p, v) \
do { \
RISCV_FENCE(rw, w); \
*(p) = (v); \
} while (0)
#define __smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = *(p); \
RISCV_FENCE(r, rw); \
___p1; \
})
#endif
#ifndef __RISCV_ELF_H__
#define __RISCV_ELF_H__
#include <sbi/riscv_asm.h>
#define R_RISCV_32 1
#define R_RISCV_64 2
#define R_RISCV_RELATIVE 3
#define RELOC_TYPE __REG_SEL(R_RISCV_64, R_RISCV_32)
#define SYM_INDEX __REG_SEL(0x20, 0x8)
#define SYM_SIZE __REG_SEL(0x18,0x10)
#endif
This diff is collapsed.
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __RISCV_FP_H__
#define __RISCV_FP_H__
#include <sbi/riscv_asm.h>
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_types.h>
#define GET_PRECISION(insn) (((insn) >> 25) & 3)
#define GET_RM(insn) (((insn) >> 12) & 7)
#define PRECISION_S 0
#define PRECISION_D 1
#ifdef __riscv_flen
#define GET_F32_REG(insn, pos, regs) \
({ \
register s32 value asm("a0") = \
SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
ulong tmp; \
asm("1: auipc %0, %%pcrel_hi(get_f32_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
: "=&r"(tmp), "+&r"(value)::"t0"); \
value; \
})
#define SET_F32_REG(insn, pos, regs, val) \
({ \
register u32 value asm("a0") = (val); \
ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
ulong tmp; \
asm volatile( \
"1: auipc %0, %%pcrel_hi(put_f32_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
: "=&r"(tmp) \
: "r"(value), "r"(offset) \
: "t0"); \
})
#define init_fp_reg(i) SET_F32_REG((i) << 3, 3, 0, 0)
#define GET_F64_REG(insn, pos, regs) \
({ \
register ulong value asm("a0") = \
SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
ulong tmp; \
asm("1: auipc %0, %%pcrel_hi(get_f64_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
: "=&r"(tmp), "+&r"(value)::"t0"); \
sizeof(ulong) == 4 ? *(int64_t *)value : (int64_t)value; \
})
#define SET_F64_REG(insn, pos, regs, val) \
({ \
uint64_t __val = (val); \
register ulong value asm("a0") = \
sizeof(ulong) == 4 ? (ulong)&__val : (ulong)__val; \
ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
ulong tmp; \
asm volatile( \
"1: auipc %0, %%pcrel_hi(put_f64_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
: "=&r"(tmp) \
: "r"(value), "r"(offset) \
: "t0"); \
})
#define GET_FCSR() csr_read(CSR_FCSR)
#define SET_FCSR(value) csr_write(CSR_FCSR, (value))
#define GET_FRM() csr_read(CSR_FRM)
#define SET_FRM(value) csr_write(CSR_FRM, (value))
#define GET_FFLAGS() csr_read(CSR_FFLAGS)
#define SET_FFLAGS(value) csr_write(CSR_FFLAGS, (value))
#define SET_FS_DIRTY() ((void)0)
#define GET_F32_RS1(insn, regs) (GET_F32_REG(insn, 15, regs))
#define GET_F32_RS2(insn, regs) (GET_F32_REG(insn, 20, regs))
#define GET_F32_RS3(insn, regs) (GET_F32_REG(insn, 27, regs))
#define GET_F64_RS1(insn, regs) (GET_F64_REG(insn, 15, regs))
#define GET_F64_RS2(insn, regs) (GET_F64_REG(insn, 20, regs))
#define GET_F64_RS3(insn, regs) (GET_F64_REG(insn, 27, regs))
#define SET_F32_RD(insn, regs, val) \
(SET_F32_REG(insn, 7, regs, val), SET_FS_DIRTY())
#define SET_F64_RD(insn, regs, val) \
(SET_F64_REG(insn, 7, regs, val), SET_FS_DIRTY())
#define GET_F32_RS2C(insn, regs) (GET_F32_REG(insn, 2, regs))
#define GET_F32_RS2S(insn, regs) (GET_F32_REG(RVC_RS2S(insn), 0, regs))
#define GET_F64_RS2C(insn, regs) (GET_F64_REG(insn, 2, regs))
#define GET_F64_RS2S(insn, regs) (GET_F64_REG(RVC_RS2S(insn), 0, regs))
#endif
#endif
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __RISCV_IO_H__
#define __RISCV_IO_H__
#include <sbi/riscv_barrier.h>
#include <sbi/sbi_types.h>
static inline void __raw_writeb(u8 val, volatile void *addr)
{
asm volatile("sb %0, 0(%1)" : : "r"(val), "r"(addr));
}
static inline void __raw_writew(u16 val, volatile void *addr)
{
asm volatile("sh %0, 0(%1)" : : "r"(val), "r"(addr));
}
static inline void __raw_writel(u32 val, volatile void *addr)
{
asm volatile("sw %0, 0(%1)" : : "r"(val), "r"(addr));
}
#if __riscv_xlen != 32
static inline void __raw_writeq(u64 val, volatile void *addr)
{
asm volatile("sd %0, 0(%1)" : : "r"(val), "r"(addr));
}
#endif
static inline u8 __raw_readb(const volatile void *addr)
{
u8 val;
asm volatile("lb %0, 0(%1)" : "=r"(val) : "r"(addr));
return val;
}
static inline u16 __raw_readw(const volatile void *addr)
{
u16 val;
asm volatile("lh %0, 0(%1)" : "=r"(val) : "r"(addr));
return val;
}
static inline u32 __raw_readl(const volatile void *addr)
{
u32 val;
asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr));
return val;
}
#if __riscv_xlen != 32
static inline u64 __raw_readq(const volatile void *addr)
{
u64 val;
asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr));
return val;
}
#endif
/* FIXME: These are now the same as asm-generic */
/* clang-format off */
#define __io_rbr() do {} while (0)
#define __io_rar() do {} while (0)
#define __io_rbw() do {} while (0)
#define __io_raw() do {} while (0)
#define readb_relaxed(c) ({ u8 __v; __io_rbr(); __v = __raw_readb(c); __io_rar(); __v; })
#define readw_relaxed(c) ({ u16 __v; __io_rbr(); __v = __raw_readw(c); __io_rar(); __v; })
#define readl_relaxed(c) ({ u32 __v; __io_rbr(); __v = __raw_readl(c); __io_rar(); __v; })
#define writeb_relaxed(v,c) ({ __io_rbw(); __raw_writeb((v),(c)); __io_raw(); })
#define writew_relaxed(v,c) ({ __io_rbw(); __raw_writew((v),(c)); __io_raw(); })
#define writel_relaxed(v,c) ({ __io_rbw(); __raw_writel((v),(c)); __io_raw(); })
#if __riscv_xlen != 32
#define readq_relaxed(c) ({ u64 __v; __io_rbr(); __v = __raw_readq(c); __io_rar(); __v; })
#define writeq_relaxed(v,c) ({ __io_rbw(); __raw_writeq((v),(c)); __io_raw(); })
#endif
#define __io_br() do {} while (0)
#define __io_ar() __asm__ __volatile__ ("fence i,r" : : : "memory");
#define __io_bw() __asm__ __volatile__ ("fence w,o" : : : "memory");
#define __io_aw() do {} while (0)
#define readb(c) ({ u8 __v; __io_br(); __v = __raw_readb(c); __io_ar(); __v; })
#define readw(c) ({ u16 __v; __io_br(); __v = __raw_readw(c); __io_ar(); __v; })
#define readl(c) ({ u32 __v; __io_br(); __v = __raw_readl(c); __io_ar(); __v; })
#define writeb(v,c) ({ __io_bw(); __raw_writeb((v),(c)); __io_aw(); })
#define writew(v,c) ({ __io_bw(); __raw_writew((v),(c)); __io_aw(); })
#define writel(v,c) ({ __io_bw(); __raw_writel((v),(c)); __io_aw(); })
#if __riscv_xlen != 32
#define readq(c) ({ u64 __v; __io_br(); __v = __raw_readq(c); __io_ar(); __v; })
#define writeq(v,c) ({ __io_bw(); __raw_writeq((v),(c)); __io_aw(); })
#endif
/* clang-format on */
#endif
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
* Copyright (c) 2021 Christoph Müllner <cmuellner@linux.com>
*/
#ifndef __RISCV_LOCKS_H__
#define __RISCV_LOCKS_H__
#include <sbi/sbi_types.h>
#define TICKET_SHIFT 16
typedef struct {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
u16 next;
u16 owner;
#else
u16 owner;
u16 next;
#endif
} __aligned(4) spinlock_t;
#define __SPIN_LOCK_UNLOCKED \
(spinlock_t) { 0, 0 }
#define SPIN_LOCK_INIT(x) \
x = __SPIN_LOCK_UNLOCKED
#define SPIN_LOCK_INITIALIZER \
__SPIN_LOCK_UNLOCKED
#define DEFINE_SPIN_LOCK(x) \
spinlock_t SPIN_LOCK_INIT(x)
int spin_lock_check(spinlock_t *lock);
int spin_trylock(spinlock_t *lock);
void spin_lock(spinlock_t *lock);
void spin_unlock(spinlock_t *lock);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __SBI_EMULATE_CSR_H__
#define __SBI_EMULATE_CSR_H__
#include <sbi/sbi_types.h>
struct sbi_trap_regs;
int sbi_emulate_csr_read(int csr_num, struct sbi_trap_regs *regs,
ulong *csr_val);
int sbi_emulate_csr_write(int csr_num, struct sbi_trap_regs *regs,
ulong csr_val);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __SBI_ILLEGAl_INSN_H__
#define __SBI_ILLEGAl_INSN_H__
#include <sbi/sbi_types.h>
struct sbi_trap_regs;
int sbi_illegal_insn_handler(ulong insn, struct sbi_trap_regs *regs);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment