forked from Mirrors/opensbi
Compare commits
52 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ca20ac0cd4 | ||
![]() |
42e9ad556d | ||
![]() |
a1ffba1ac9 | ||
![]() |
d022c5d3ae | ||
![]() |
889e746fd7 | ||
![]() |
fde1c42db3 | ||
![]() |
122d00ba67 | ||
![]() |
ce6189f7a5 | ||
![]() |
db5b25af49 | ||
![]() |
72a8272066 | ||
![]() |
4b92518959 | ||
![]() |
d046974cf6 | ||
![]() |
0db43770b3 | ||
![]() |
3265310b05 | ||
![]() |
34bf6d4a0f | ||
![]() |
6a3dc84f66 | ||
![]() |
f4a17177ce | ||
![]() |
4e774f5470 | ||
![]() |
148423d141 | ||
![]() |
918c1354b7 | ||
![]() |
51e543511a | ||
![]() |
b44878b773 | ||
![]() |
16426420b5 | ||
![]() |
3c53950b00 | ||
![]() |
868e20df8b | ||
![]() |
5cd69a496b | ||
![]() |
ae4e0de700 | ||
![]() |
afbb0cdf80 | ||
![]() |
d369e721e8 | ||
![]() |
286b80768b | ||
![]() |
35e617385f | ||
![]() |
28d1dd2430 | ||
![]() |
70a474d2c2 | ||
![]() |
4cb4d46875 | ||
![]() |
c5467fce46 | ||
![]() |
84169e2e69 | ||
![]() |
ab12d6ef8f | ||
![]() |
01fe779113 | ||
![]() |
b1b7e49c63 | ||
![]() |
7b3da0ef0d | ||
![]() |
76c759df6a | ||
![]() |
4f32b13802 | ||
![]() |
f9b033e577 | ||
![]() |
f4cf6da7ff | ||
![]() |
9f44d07df5 | ||
![]() |
a5f06b30c1 | ||
![]() |
5a91fec1a8 | ||
![]() |
b4c72deba9 | ||
![]() |
93f806af32 | ||
![]() |
190a80dc40 | ||
![]() |
9a72e5006c | ||
![]() |
c0addfe751 |
110
Makefile
110
Makefile
@@ -8,9 +8,9 @@
|
||||
#
|
||||
|
||||
# Select Make Options:
|
||||
# o Do not use make's built-in rules and variables
|
||||
# o Do not use make's built-in rules
|
||||
# o Do not print "Entering directory ...";
|
||||
MAKEFLAGS += -rR --no-print-directory
|
||||
MAKEFLAGS += -r --no-print-directory
|
||||
|
||||
# Find out source, build, and install directories
|
||||
src_dir=$(CURDIR)
|
||||
@@ -51,8 +51,37 @@ export lib_dir=$(CURDIR)/lib
|
||||
export firmware_dir=$(CURDIR)/firmware
|
||||
|
||||
# Find library version
|
||||
OPENSBI_VERSION_MAJOR=`grep MAJOR $(include_dir)/sbi/sbi_version.h | awk '{ print $$3 }'`
|
||||
OPENSBI_VERSION_MINOR=`grep MINOR $(include_dir)/sbi/sbi_version.h | awk '{ print $$3 }'`
|
||||
OPENSBI_VERSION_MAJOR=`grep MAJOR $(include_dir)/sbi/sbi_version.h | sed 's/.*MAJOR.*\([0-9][0-9]*\)/\1/'`
|
||||
OPENSBI_VERSION_MINOR=`grep MINOR $(include_dir)/sbi/sbi_version.h | sed 's/.*MINOR.*\([0-9][0-9]*\)/\1/'`
|
||||
|
||||
# Setup compilation commands
|
||||
ifdef CROSS_COMPILE
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
CPP = $(CROSS_COMPILE)cpp
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
else
|
||||
CC ?= gcc
|
||||
CPP ?= cpp
|
||||
AR ?= ar
|
||||
LD ?= ld
|
||||
OBJCOPY ?= objcopy
|
||||
endif
|
||||
AS = $(CC)
|
||||
DTC = dtc
|
||||
|
||||
# Guess the compillers xlen
|
||||
OPENSBI_CC_XLEN := $(shell TMP=`$(CC) -dumpmachine | sed 's/riscv\([0-9][0-9]\).*/\1/'`; echo $${TMP})
|
||||
|
||||
# Setup platform XLEN
|
||||
ifndef PLATFORM_RISCV_XLEN
|
||||
ifeq ($(OPENSBI_CC_XLEN), 32)
|
||||
PLATFORM_RISCV_XLEN = 32
|
||||
else
|
||||
PLATFORM_RISCV_XLEN = 64
|
||||
endif
|
||||
endif
|
||||
|
||||
# Setup list of objects.mk files
|
||||
ifdef PLATFORM
|
||||
@@ -92,6 +121,22 @@ deps-y+=$(platform-common-objs-path-y:.o=.dep)
|
||||
deps-y+=$(lib-objs-path-y:.o=.dep)
|
||||
deps-y+=$(firmware-objs-path-y:.o=.dep)
|
||||
|
||||
# Setup platform ABI, ISA and Code Model
|
||||
ifndef PLATFORM_RISCV_ABI
|
||||
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||
PLATFORM_RISCV_ABI = ilp$(PLATFORM_RISCV_XLEN)
|
||||
else
|
||||
PLATFORM_RISCV_ABI = lp$(PLATFORM_RISCV_XLEN)
|
||||
endif
|
||||
endif
|
||||
ifndef PLATFORM_RISCV_ISA
|
||||
PLATFORM_RISCV_ISA = rv$(PLATFORM_RISCV_XLEN)imafdc
|
||||
endif
|
||||
ifndef PLATFORM_RISCV_CODE_MODEL
|
||||
PLATFORM_RISCV_CODE_MODEL = medany
|
||||
endif
|
||||
|
||||
# Setup compilation commands flags
|
||||
GENFLAGS = -I$(platform_dir)/include
|
||||
GENFLAGS += -I$(platform_common_dir)/include
|
||||
GENFLAGS += -I$(include_dir)
|
||||
@@ -99,27 +144,11 @@ GENFLAGS += $(platform-common-genflags-y)
|
||||
GENFLAGS += $(platform-genflags-y)
|
||||
GENFLAGS += $(firmware-genflags-y)
|
||||
|
||||
# Setup compilation commands
|
||||
ifdef CROSS_COMPILE
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
CPP = $(CROSS_COMPILE)cpp
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
else
|
||||
CC ?= gcc
|
||||
CPP ?= cpp
|
||||
AR ?= ar
|
||||
LD ?= ld
|
||||
OBJCOPY ?= objcopy
|
||||
endif
|
||||
AS = $(CC)
|
||||
DTC = dtc
|
||||
|
||||
# Setup compilation commands flags
|
||||
CFLAGS = -g -Wall -Werror -nostdlib -fno-strict-aliasing -O2
|
||||
CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
||||
CFLAGS += -mno-save-restore -mstrict-align
|
||||
CFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA)
|
||||
CFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL)
|
||||
CFLAGS += $(GENFLAGS)
|
||||
CFLAGS += $(platform-cflags-y)
|
||||
CFLAGS += $(firmware-cflags-y)
|
||||
@@ -131,17 +160,21 @@ CPPFLAGS += $(firmware-cppflags-y)
|
||||
ASFLAGS = -g -Wall -nostdlib -D__ASSEMBLY__
|
||||
ASFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
||||
ASFLAGS += -mno-save-restore -mstrict-align
|
||||
ASFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA)
|
||||
ASFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL)
|
||||
ASFLAGS += $(GENFLAGS)
|
||||
ASFLAGS += $(platform-asflags-y)
|
||||
ASFLAGS += $(firmware-asflags-y)
|
||||
|
||||
ARFLAGS = rcs
|
||||
|
||||
LDFLAGS += -g -Wall -nostdlib -Wl,--build-id=none -N
|
||||
LDFLAGS += $(platform-ldflags-y)
|
||||
LDFLAGS += $(firmware-ldflags-y)
|
||||
ELFFLAGS += -Wl,--build-id=none -N -static-libgcc -lgcc
|
||||
ELFFLAGS += $(platform-ldflags-y)
|
||||
ELFFLAGS += $(firmware-ldflags-y)
|
||||
|
||||
MERGEFLAGS += -r
|
||||
MERGEFLAGS += -b elf$(PLATFORM_RISCV_XLEN)-littleriscv
|
||||
MERGEFLAGS += -m elf$(PLATFORM_RISCV_XLEN)lriscv
|
||||
|
||||
DTCFLAGS = -O dtb
|
||||
|
||||
@@ -180,7 +213,7 @@ compile_cpp = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
$(CPP) $(CPPFLAGS) -x c $(2) | grep -v "\#" > $(1)
|
||||
compile_cc_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
echo " CC-DEP $(subst $(build_dir)/,,$(1))"; \
|
||||
echo -n `dirname $(1)`/ > $(1) && \
|
||||
echo `dirname $(1)`/ \\ > $(1) && \
|
||||
$(CC) $(CFLAGS) $(call dynamic_flags,$(1),$(2)) \
|
||||
-MM $(2) >> $(1) || rm -f $(1)
|
||||
compile_cc = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
@@ -188,15 +221,15 @@ compile_cc = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
$(CC) $(CFLAGS) $(call dynamic_flags,$(1),$(2)) -c $(2) -o $(1)
|
||||
compile_as_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
echo " AS-DEP $(subst $(build_dir)/,,$(1))"; \
|
||||
echo -n `dirname $(1)`/ > $(1) && \
|
||||
echo `dirname $(1)`/ \\ > $(1) && \
|
||||
$(AS) $(ASFLAGS) $(call dynamic_flags,$(1),$(2)) \
|
||||
-MM $(2) >> $(1) || rm -f $(1)
|
||||
compile_as = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
echo " AS $(subst $(build_dir)/,,$(1))"; \
|
||||
$(AS) $(ASFLAGS) $(call dynamic_flags,$(1),$(2)) -c $(2) -o $(1)
|
||||
compile_ld = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
echo " LD $(subst $(build_dir)/,,$(1))"; \
|
||||
$(CC) $(3) $(LDFLAGS) -Wl,-T$(2) -o $(1)
|
||||
compile_elf = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
echo " ELF $(subst $(build_dir)/,,$(1))"; \
|
||||
$(CC) $(CFLAGS) $(3) $(ELFFLAGS) -Wl,-T$(2) -o $(1)
|
||||
compile_ar = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
||||
echo " AR $(subst $(build_dir)/,,$(1))"; \
|
||||
$(AR) $(ARFLAGS) $(1) $(2)
|
||||
@@ -225,7 +258,7 @@ $(build_dir)/%.bin: $(build_dir)/%.elf
|
||||
$(call compile_objcopy,$@,$<)
|
||||
|
||||
$(build_dir)/%.elf: $(build_dir)/%.o $(build_dir)/%.elf.ld $(build_dir)/$(platform_subdir)/lib/libplatsbi.a
|
||||
$(call compile_ld,$@,$@.ld,$< $(build_dir)/$(platform_subdir)/lib/libplatsbi.a)
|
||||
$(call compile_elf,$@,$@.ld,$< $(build_dir)/$(platform_subdir)/lib/libplatsbi.a)
|
||||
|
||||
$(build_dir)/$(platform_subdir)/%.ld: $(src_dir)/%.ldS
|
||||
$(call compile_cpp,$@,$<)
|
||||
@@ -285,6 +318,21 @@ all-deps-2 = $(if $(findstring clean,$(MAKECMDGOALS)),,$(all-deps-1))
|
||||
# Include external dependency of firmwares after default Makefile rules
|
||||
include $(src_dir)/firmware/external_deps.mk
|
||||
|
||||
# Convenient "make run" command for emulated platforms
|
||||
.PHONY: run
|
||||
run: all
|
||||
ifneq ($(platform-runcmd),)
|
||||
$(platform-runcmd) $(RUN_ARGS)
|
||||
else
|
||||
ifdef PLATFORM
|
||||
@echo Platform $(PLATFORM) doesn't specify a run command
|
||||
@false
|
||||
else
|
||||
@echo Run command only available when targeting a platform
|
||||
@false
|
||||
endif
|
||||
endif
|
||||
|
||||
install_targets-y = install_libsbi
|
||||
ifdef PLATFORM
|
||||
install_targets-y += install_libplatsbi
|
||||
|
88
README.md
88
README.md
@@ -1,39 +1,62 @@
|
||||
RISC-V Open Source Supervisor Binary Interface (OpenSBI)
|
||||
========================================================
|
||||
|
||||
The **RISC-V Supervisor Binary Interface (SBI)** is a recommended interface
|
||||
The **RISC-V Supervisor Binary Interface (SBI)** is the recommended interface
|
||||
between:
|
||||
|
||||
1. A platform specific firmware running in M-mode and a general purpose OS,
|
||||
hypervisor or bootloader running in S-mode or HS-mode.
|
||||
2. A hypervisor running in HS-mode and a general purpose OS or bootloader
|
||||
executed in VS-mode.
|
||||
1. A platform specific firmware running in M-mode and bootloader, hypervisor or
|
||||
a general purpose OS executing in S-mode or HS-mode.
|
||||
2. A hypervisor running in HS-mode and a bootloader or a general purpose OS
|
||||
executing in VS-mode.
|
||||
|
||||
The *RISC-V SBI specification* is maintained as an independent project by the
|
||||
RISC-V Foundation in [Github].
|
||||
|
||||
OpenSBI aims to provides an open-source and extensible implementation of the
|
||||
RISC-V SBI specification for case 1 mentioned above. OpenSBI implementation
|
||||
can be easily extended by RISC-V platform or System-on-Chip vendors to fit a
|
||||
The goal of the OpenSBI project is to provide an open-source reference
|
||||
implementation of the RISC-V SBI specifications for platform specific firmwares
|
||||
executing in M-mode (case 1 mentioned above). OpenSBI implementation can be
|
||||
easily extended by RISC-V platform and system-on-chip vendors to fit a
|
||||
particular hardware configuration.
|
||||
|
||||
OpenSBI provides three different components:
|
||||
1. *libsbi.a* - A generic OpenSBI static library
|
||||
2. *libplatsbi.a* - A platform specific OpenSBI static library, that is,
|
||||
libsbi.a plus platform specific hooks
|
||||
3. *firmwares* - Platform specific bootable firmware binaries
|
||||
The main component of OpenSBI is provided in the form of a platform independent
|
||||
static library **libsbi.a** implementing the SBI interface. A firmware or
|
||||
bootloader implementation can link against this library to ensure conformance
|
||||
with the SBI interface specifications. *libsbi.a* also defines an interface for
|
||||
integrating with platform specific operations provided by the platform firmware
|
||||
implementation (e.g. console access functions, inter-processor interrupts
|
||||
control, etc).
|
||||
|
||||
Building and Installing the generic OpenSBI static library
|
||||
----------------------------------------------------------
|
||||
To illustrate the use of *libsbi.a* library, OpenSBI also provides a set of
|
||||
platform specific support examples. For each example, a platform
|
||||
specific static library *libplatsbi.a* can be compiled. This library implements
|
||||
SBI calls processing by integrating *libsbi.a* with necessary platform dependent
|
||||
hardware manipulation functions. For all supported platforms, OpenSBI also
|
||||
provides several runtime firmware examples built using the platform
|
||||
*libplatsbi.a*. These example firmwares can be used to replace the legacy
|
||||
*riskv-pk* bootloader (aka BBL) and enable the use of well known bootloaders
|
||||
such as [U-Boot].
|
||||
|
||||
*libsbi.a* can be natively compiled or cross-compiled on a host with a
|
||||
different base architecture than RISC-V.
|
||||
Required Toolchain
|
||||
------------------
|
||||
|
||||
OpenSBI can be compiled natively or cross-compiled on a x86 host. For
|
||||
cross-compilation, you can build your tool chain or just download from
|
||||
the [bootlin] (https://toolchains.bootlin.com/).
|
||||
|
||||
Please note that only 64bit version of toolchain is available in bootlin
|
||||
for now.
|
||||
|
||||
Building and Installing OpenSBI Platform Independent Library
|
||||
------------------------------------------------------------
|
||||
|
||||
OpenSBI platform independent static library *libsbi.a* can be natively compiled
|
||||
or cross-compiled on a host with a different base architecture than RISC-V.
|
||||
|
||||
For cross-compiling, the environment variable *CROSS_COMPILE* must be defined
|
||||
to specify the name prefix of the RISC-V compiler toolchain executables, e.g.
|
||||
*riscv64-unknown-elf-* if the gcc executable used is *riscv64-unknown-elf-gcc*.
|
||||
|
||||
To build the generic OpenSBI library *libsbi.a*, simply execute:
|
||||
To build *libsbi.a* simply execute:
|
||||
```
|
||||
make
|
||||
```
|
||||
@@ -58,18 +81,18 @@ path, run:
|
||||
make I=<install_directory> install
|
||||
```
|
||||
|
||||
Building and Installing the platform specific static library and firmwares
|
||||
--------------------------------------------------------------------------
|
||||
Building and Installing a Reference Platform Static Library and Firmwares
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
The platform specific *libplatsbi.a* static library and the platform firmwares
|
||||
are only built if the *PLATFORM=<platform_subdir>* argument is specified on
|
||||
the make command line. *<platform_subdir>* must specify the relative path from
|
||||
OpenSBI code directory to one of the leaf directories under the *platform*
|
||||
directory. For example, to compile the platform library and firmwares for QEMU
|
||||
RISC-V *virt* machine, *<platform_subdir>* should be *qemu/virt*.
|
||||
When the *PLATFORM=<platform_subdir>* argument is specified on the make command
|
||||
line, the platform specific static library *libplatsbi.a* and firmware examples
|
||||
are built for the platform *<platform_subdir>* present in the directory
|
||||
*platform* in OpenSBI top directory. For example, to compile the platform
|
||||
library and firmware examples for QEMU RISC-V *virt* machine,
|
||||
*<platform_subdir>* should be *qemu/virt*.
|
||||
|
||||
To build *libsbi.a*, *libplatsbi.a* and the firmwares for a specific platform,
|
||||
run:
|
||||
To build *libsbi.a*, *libplatsbi.a* and the firmwares for one of the supported
|
||||
platform, run:
|
||||
```
|
||||
make PLATFORM=<platform_subdir>
|
||||
```
|
||||
@@ -112,7 +135,7 @@ A copy of this license with OpenSBI copyright can be found in the file
|
||||
[COPYING.BSD].
|
||||
|
||||
All source files in OpenSBI contain the 2-Clause BSD license SPDX short
|
||||
indentifier in place of the full license text.
|
||||
identifier in place of the full license text.
|
||||
|
||||
```
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
@@ -144,11 +167,11 @@ Detailed documentation of various aspects of OpenSBI can be found under the
|
||||
*docs* directory. The documentation covers the following topics.
|
||||
|
||||
* [Contribution Guideline]: Guideline for contributing code to OpenSBI project
|
||||
* [Platform Support Guide]: Guideline for implementing support for new platforms
|
||||
* [Library Usage]: API documentation of OpenSBI static library *libsbi.a*
|
||||
* [Platform Support Guide]: Guideline for implementing support for new platforms
|
||||
* [Platform Documentation]: Documentation of the platforms currently supported.
|
||||
* [Firmware Documentation]: Documentation for the different types of firmware
|
||||
build supported by OpenSBI.
|
||||
examples build supported by OpenSBI.
|
||||
|
||||
OpenSBI source code is also well documented. For source level documentation,
|
||||
doxygen style is used. Please refer to [Doxygen manual] for details on this
|
||||
@@ -191,11 +214,12 @@ make I=<install_directory> install_docs
|
||||
*refman.pdf* will be installed under *<install_directory>/docs*.
|
||||
|
||||
[Github]: https://github.com/riscv/riscv-sbi-doc
|
||||
[U-Boot]: https://www.denx.de/wiki/U-Boot/SourceCode
|
||||
[COPYING.BSD]: COPYING.BSD
|
||||
[SPDX]: http://spdx.org/licenses/
|
||||
[Contribution Guideline]: docs/contributing.md
|
||||
[Platform Support Guide]: docs/platform_guide.md
|
||||
[Library Usage]: docs/library_usage.md
|
||||
[Platform Support Guide]: docs/platform_guide.md
|
||||
[Platform Documentation]: docs/platform/platform.md
|
||||
[Firmware Documentation]: docs/firmware/fw.md
|
||||
[Doxygen manual]: http://www.stack.nl/~dimitri/doxygen/manual.html
|
||||
|
@@ -5,7 +5,7 @@ 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 types will differ in how
|
||||
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.
|
||||
|
||||
@@ -58,3 +58,20 @@ following documents.
|
||||
|
||||
[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.
|
||||
|
11
docs/firmware/payload_linux.md
Normal file
11
docs/firmware/payload_linux.md
Normal file
@@ -0,0 +1,11 @@
|
||||
Linux as a direct payload to OpenSBI
|
||||
====================================
|
||||
|
||||
OpenSBI has the capability to load Linux kernel image directly in supervisor
|
||||
mode. The flattened image generated by the Linux kernel build process can be
|
||||
provided as payload to OpenSBI.
|
||||
|
||||
Detailed examples and platform guides can be found in both [QEMU](
|
||||
../platform/qemu_virt.md) and [HiFive Unleashed](../platform/sifive_fu540.md)
|
||||
platform guide respectively.
|
||||
|
38
docs/firmware/payload_uboot.md
Normal file
38
docs/firmware/payload_uboot.md
Normal file
@@ -0,0 +1,38 @@
|
||||
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
|
||||
OpenSBI firmware, becoming the boot stage following OpenSBI firmware
|
||||
execution.
|
||||
|
||||
The current stable upstream code of U-boot does not yet include all patches
|
||||
necessary to fully support OpenSBI. To use U-Boot as an OpenSBI payload, the
|
||||
following out-of-tree patch series must be applied to the upstream U-Boot source
|
||||
code.
|
||||
|
||||
HiFive Unleashed support for U-Boot
|
||||
|
||||
https://lists.denx.de/pipermail/u-boot/2019-February/358058.html
|
||||
|
||||
This patch series enables a single CPU to execute U-Boot. As a result, the next
|
||||
stage boot code such as Linux kernel can also only execute a single CPU. U-Boot
|
||||
SMP support for RISC-V can be enabled with the following additional patches.
|
||||
|
||||
https://lists.denx.de/pipermail/u-boot/2019-February/358393.html
|
||||
|
||||
Building and Generating U-Boot images
|
||||
=====================================
|
||||
Please refer to U-Boot build documentation for detailed instructions on how to build U-Boot images.
|
||||
|
||||
Once U-Boot images are built, Linux kernel image need to be converted to a format
|
||||
that U-Boot understands.
|
||||
|
||||
```
|
||||
<uboot-dir>/tools/mkimage -A riscv -O linux -T kernel -C none -a 0x80200000 -e 0x80200000 -n Linux -d \
|
||||
<linux_build_directory>arch/riscv/boot/Image \
|
||||
<linux_build_directory>/arch/riscv/boot/uImage
|
||||
```
|
||||
|
||||
Copy the uImage to your tftpboot server path if network boot is required.
|
@@ -1,30 +1,36 @@
|
||||
OpenSBI Library Usage Guideline
|
||||
===============================
|
||||
OpenSBI Library Usage
|
||||
=====================
|
||||
|
||||
OpenSBI provides two types of static libraries:
|
||||
|
||||
1. *libsbi.a* - A generic OpenSBI static library installed at
|
||||
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. *libplatsbi.a* - A platform specific OpenSBI static library, that is,
|
||||
libsbi.a plus platform specific hooks installed at
|
||||
2. *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*
|
||||
|
||||
The platform specific firmwares provided by OpenSBI are not mandatory. Users
|
||||
can always link OpenSBI as static library to their favorite M-mode firmware
|
||||
or bootloader provided that it has a license compatible with OpenSBI license.
|
||||
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 needs to be provided.
|
||||
|
||||
Users can choose either *libsbi.a* or *libplatsbi.a* to link with their
|
||||
firmware or bootloader but with *libsbi.a* platform specific hooks (i.e.
|
||||
*struct sbi_platform* instance) will have to be provided.
|
||||
The platform specific example firmwares provided by OpenSBI are not mandatory.
|
||||
An implementation may choose to link OpenSBI generic static library together
|
||||
with an M-mode firmware or bootloader providing hardware specific hooks. Since
|
||||
OpenSBI is a statically linked library, users must ensure that the license of
|
||||
these external components is compatible with OpenSBI license.
|
||||
|
||||
Constraints on OpenSBI usage from external firmware
|
||||
---------------------------------------------------
|
||||
|
||||
Users have to ensure that external firmware or bootloader and OpenSBI static
|
||||
library (*libsbi.a* or *libplatsbi.a*) are compiled with the same GCC target
|
||||
options *-mabi*, *-march*, and *-mcmodel*.
|
||||
Users have to ensure that an external firmware or bootloader linking against
|
||||
OpenSBI static libraries (*libsbi.a* or *libplatsbi.a*) are compiled with the
|
||||
same GCC target options *-mabi*, *-march*, and *-mcmodel*.
|
||||
|
||||
There are only two constraints on calling any OpenSBI function from an
|
||||
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
|
||||
@@ -35,15 +41,16 @@ external M-mode firmware or bootloader:
|
||||
The most important functions from an external firmware or bootloader
|
||||
perspective are *sbi_init()* and *sbi_trap_handler()*.
|
||||
|
||||
In addition to above constraints, the external firmware or bootloader must
|
||||
In addition to the above constraints, the external firmware or bootloader must
|
||||
ensure that interrupts are disabled in *MSTATUS* and *MIE* CSRs when calling
|
||||
*sbi_init()* and *sbi_trap_handler()* functions.
|
||||
the functions *sbi_init()* and *sbi_trap_handler()*.
|
||||
|
||||
The *sbi_init()* should be called by the external firmware or bootloader
|
||||
when a HART is powered-up at boot-time or in response to a CPU hotplug event.
|
||||
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()* should be called by the external firmware or
|
||||
bootloader for the following interrupts and traps:
|
||||
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
|
||||
@@ -54,4 +61,5 @@ bootloader for the following interrupts and traps:
|
||||
7. Hypervisor ecall trap
|
||||
|
||||
**Note:** external firmwares or bootloaders can be more conservative by
|
||||
forwarding all traps and interrupts to *sbi_trap_handler()*
|
||||
forwarding all traps and interrupts to *sbi_trap_handler()*.
|
||||
|
||||
|
@@ -50,7 +50,7 @@ or
|
||||
```
|
||||
qemu-system-riscv64 -M virt -m 256M -display none -serial stdio \
|
||||
-kernel build/platform/qemu/virt/firmware/fw_jump.elf \
|
||||
-device loader,file=<uboot_build_directory>/u-boot.bin,addr=0x80200000
|
||||
-device loader,file=<uboot_build_directory>/u-boot.bin,addr=0x80400000
|
||||
```
|
||||
|
||||
**Linux Kernel Payload**
|
||||
@@ -75,7 +75,7 @@ or
|
||||
```
|
||||
qemu-system-riscv64 -M virt -m 256M -display none -serial stdio \
|
||||
-kernel build/platform/qemu/virt/firmware/fw_jump.elf \
|
||||
-device loader,file=<linux_build_directory>/arch/riscv/boot/Image,addr=0x80200000 \
|
||||
-device loader,file=<linux_build_directory>/arch/riscv/boot/Image,addr=0x80400000 \
|
||||
-drive file=<path_to_linux_rootfs>,format=raw,id=hd0 \
|
||||
-device virtio-blk-device,drive=hd0 \
|
||||
-append "root=/dev/vda rw console=ttyS0"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
SiFive FU540 SoC Platform
|
||||
==========================
|
||||
The FU540-C000 is the world’s first 4+1 64-bit RISC‑V SoC from SiFive.
|
||||
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.
|
||||
|
||||
@@ -13,59 +13,47 @@ Platform Options
|
||||
As hart0 in the FU540 doesn't have an MMU, only harts 1-4 boot by default.
|
||||
A hart mask i.e. *FU540_ENABLED_HART_MASK* compile time option is provided to
|
||||
select any other hart for booting. Please keep in mind that this is not
|
||||
platform wide option. It can only be specificd for FU540 platform in following way.
|
||||
platform wide option. It can only be specified for FU540 platform in following way.
|
||||
|
||||
```
|
||||
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=Image FU540_ENABLED_HART_MASK=0x02
|
||||
```
|
||||
This will let the board boot only hart1 instead of default 1-4.
|
||||
|
||||
Booting SiFive Fu540 Platform
|
||||
Building SiFive Fu540 Platform
|
||||
-----------------------------
|
||||
|
||||
As of this writing, the required Linux kernel and U-Boot patches are not
|
||||
accepted in mainline. Please follow the below instructions to cherry-pick
|
||||
them into your repository.
|
||||
|
||||
[U-Boot patches](../firmware/payload_uboot.md)
|
||||
|
||||
[Linux kernel patches](../firmware/payload_linux.md)
|
||||
|
||||
**Linux Kernel Payload**
|
||||
|
||||
Build:
|
||||
|
||||
```
|
||||
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
|
||||
```
|
||||
|
||||
Flash:
|
||||
The generated firmware binary should be copied to the first partition of the sdcard.
|
||||
|
||||
```
|
||||
dd if=build/platform/sifive/fu540/firmware/fw_payload.bin of=/dev/disk2s1 bs=1024
|
||||
```
|
||||
|
||||
**U-Boot Payload**
|
||||
|
||||
Note: U-Boot doesn't have SMP support. So you can only boot single cpu with non-smp
|
||||
kernel configuration using U-Boot.
|
||||
|
||||
Build:
|
||||
The command-line example here assumes that U-Boot was compiled using sifive_fu540_defconfig configuration.
|
||||
|
||||
The commandline example here assumes that U-Boot was compiled using sifive_fu540_defconfig configuration.
|
||||
With SMP support enabled in U-Boot:
|
||||
|
||||
```
|
||||
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<u-boot_build_dir>/u-boot.bin
|
||||
```
|
||||
|
||||
Without SMP support enabled in U-Boot:
|
||||
```
|
||||
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<u-boot_build_dir>/u-boot.bin FU540_ENABLED_HART_MASK=0x02
|
||||
```
|
||||
|
||||
Flash:
|
||||
The generated firmware binary should be copied to the first partition of the sdcard.
|
||||
|
||||
```
|
||||
dd if=build/platform/sifive/fu540/firmware/fw_payload.bin of=/dev/disk2s1 bs=1024
|
||||
```
|
||||
U-Boot tftp boot method can be used to load kernel image in U-Boot prompt.
|
||||
|
||||
Note: As the U-Boot & Linux kernel patches are not in upstream it, you can cherry-pick from here.
|
||||
|
||||
U-Boot patchset:
|
||||
https://lists.denx.de/pipermail/u-boot/2019-January/355941.html
|
||||
|
||||
Linux kernel patchset:
|
||||
https://lkml.org/lkml/2019/1/8/192
|
||||
|
||||
**U-Boot & Linux Kernel as a single payload**
|
||||
|
||||
A single monolithic image containing both U-Boot & Linux can also be used if network boot setup is
|
||||
@@ -78,8 +66,9 @@ mkimage -A riscv -O linux -T kernel -C none -a 0x80200000 -e 0x80200000 -n Linux
|
||||
<linux_build_directory>/arch/riscv/boot/uImage
|
||||
```
|
||||
|
||||
2. Create a temporary image with u-boot.bin as the first payload. The commandline example here assumes
|
||||
that U-Boot was compiled using sifive_fu540_defconfig configuration.
|
||||
2. Create a temporary image with u-boot.bin as the first payload. The command-line
|
||||
example here assumes that U-Boot was compiled using sifive_fu540_defconfig
|
||||
configuration.
|
||||
```
|
||||
dd if=~/workspace/u-boot-riscv/u-boot.bin of=/tmp/temp.bin bs=1M
|
||||
```
|
||||
@@ -87,16 +76,127 @@ dd if=~/workspace/u-boot-riscv/u-boot.bin of=/tmp/temp.bin bs=1M
|
||||
```
|
||||
dd if=<linux_build_directory>/arch/riscv/boot/uImage of=/tmp/temp.bin bs=1M seek=4
|
||||
```
|
||||
4. Compile OpenSBI with temp.bin (generated in step 3) as payload and single hart enabled.
|
||||
4. Compile OpenSBI with temp.bin (generated in step 3) as payload.
|
||||
```
|
||||
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=/tmp/temp.bin FU540_ENABLED_HART_MASK=0x02
|
||||
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=/tmp/temp.bin
|
||||
```
|
||||
5. The generated firmware binary should be copied to the first partition of the sdcard.
|
||||
|
||||
Flashing the OpenSBI firmware binary to storage media:
|
||||
-----------------------------------------------------
|
||||
The first stage boot loader([FSBL](https://github.com/sifive/freedom-u540-c000-bootloader))
|
||||
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
|
||||
```
|
||||
6. At U-Boot prompt execute following boot command to boot non-SMP linux.
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
bootm 0x80600000 - 0x82200000
|
||||
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 mac address of the board.
|
||||
|
||||
```
|
||||
setenv ethaddr <mac address of the board>
|
||||
```
|
||||
2. Set the ip address of the board.
|
||||
|
||||
```
|
||||
setenv ipaddr <ipaddr of the board>
|
||||
```
|
||||
3. Set the tftpboot server IP.
|
||||
|
||||
```
|
||||
setenv serverip <ipaddr of the tftp server>
|
||||
```
|
||||
4. Set the network gateway address.
|
||||
|
||||
```
|
||||
setenv gatewayip <ipaddress of the network gateway>
|
||||
```
|
||||
5. Load the Linux kernel image from the tftp server.
|
||||
|
||||
```
|
||||
tftpboot ${kernel_addr_r} /sifive/fu540/uImage
|
||||
```
|
||||
|
||||
6. 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} /sifive/fu540/uRamdisk
|
||||
```
|
||||
7. Set the boot command-line arguments.
|
||||
|
||||
```
|
||||
setenv bootargs "root=<root partition> rw console=ttySIF0 earlycon=sbi"
|
||||
```
|
||||
|
||||
N.B. 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.
|
||||
|
||||
```
|
||||
bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdtcontroladdr}
|
||||
|
||||
```
|
||||
or (if ramdisk is not loaded from network)
|
||||
```
|
||||
bootm ${kernel_addr_r} - ${fdtcontroladdr}
|
||||
```
|
||||
|
||||
**U-Boot & Linux Kernel as a single payload**
|
||||
|
||||
At U-Boot prompt execute the following boot command to boot Linux.
|
||||
|
||||
```
|
||||
bootm ${kernel_addr_r} - ${fdtcontroladdr}
|
||||
```
|
||||
Booting SiFive Fu540 Platform with Microsemi Expansion board
|
||||
------------------------------------------------------------
|
||||
|
||||
Until the Linux kernel has in-tree support for device trees and mainline u-boot
|
||||
is fully supported on the HiFive Unleashed you can follow these steps to boot
|
||||
Linux with the Microsemi expansion board. This method should not be copied on
|
||||
future boards and is considered a temporary solution until we can use a more
|
||||
standardised boot flow.
|
||||
|
||||
To boot the Linux kernel with a device tree that has support for the Microsemi
|
||||
Expansion board you can include the following line when compiling the firmware:
|
||||
```
|
||||
FW_PAYLOAD_FDT="HiFiveUnleashed-MicroSemi-Expansion.dtb"
|
||||
```
|
||||
|
@@ -1,22 +1,31 @@
|
||||
OpenSBI Platform Support Guideline
|
||||
==================================
|
||||
|
||||
The OpenSBI platform support is a set of platform specific hooks provided
|
||||
in the form of a *struct sbi_platform* instance. It is required by:
|
||||
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
|
||||
platform independent *libsbi.a* to execute platform specific operations.
|
||||
|
||||
1. *libplatsbi.a* - A platform specific OpenSBI static library, that is,
|
||||
libsbi.a plus a *struct sbi_platform* instance installed at
|
||||
*<install_directory>/platform/<platform_subdir>/lib/libplatsbi.a*
|
||||
2. *firmwares* - Platform specific bootable firmware binaries installed at
|
||||
*<install_directory>/platform/<platform_subdir>/bin*
|
||||
Each of the reference platform support provided by OpenSBI define 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 sbi/sbi_platform.h.
|
||||
APIs is available in the file *include/sbi/sbi_platform.h*.
|
||||
|
||||
Adding a new platform support
|
||||
-----------------------------
|
||||
|
||||
The support of a new platform named *<xyz>* can be added as follows:
|
||||
Support for a new platform named *<xyz>* can be added as follows:
|
||||
|
||||
1. Create a directory named *<xyz>* under *platform/* directory
|
||||
2. Create a platform configuration file named *config.mk* under
|
||||
@@ -27,6 +36,7 @@ The support of a new platform named *<xyz>* can be added as follows:
|
||||
4. Create *platform/<xyz>/platform.c* file providing a *struct sbi_platform*
|
||||
instance
|
||||
|
||||
A template platform support code is available under the *platform/template*.
|
||||
Copying this directory as new directory named *<xyz>* under *platform/*
|
||||
directory will create all the files mentioned above.
|
||||
A template platform support code 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.
|
||||
|
@@ -22,7 +22,7 @@ _start:
|
||||
* Jump to warm-boot if this is not the first core booting,
|
||||
* that is, for mhartid != 0
|
||||
*/
|
||||
csrr a6, mhartid
|
||||
csrr a6, CSR_MHARTID
|
||||
blt zero, a6, _wait_for_boot_hart
|
||||
|
||||
/* Zero-out BSS */
|
||||
@@ -69,7 +69,11 @@ _prev_arg1_override_done:
|
||||
add t0, a1, zero
|
||||
and t0, t0, a3
|
||||
/* t2 = source FDT size in big-endian */
|
||||
#if __riscv_xlen == 64
|
||||
lwu t2, 4(t0)
|
||||
#else
|
||||
lw t2, 4(t0)
|
||||
#endif
|
||||
/* t3 = bit[15:8] of FDT size */
|
||||
add t3, t2, zero
|
||||
srli t3, t3, 16
|
||||
@@ -122,21 +126,26 @@ _wait_for_boot_hart:
|
||||
|
||||
_start_warm:
|
||||
/* Disable and clear all interrupts */
|
||||
csrw mie, zero
|
||||
csrw mip, zero
|
||||
csrw CSR_MIE, zero
|
||||
csrw CSR_MIP, zero
|
||||
|
||||
/* Preload per-HART details
|
||||
* s6 -> HART ID
|
||||
* s7 -> HART Count
|
||||
* s8 -> HART Stack Size
|
||||
*/
|
||||
csrr s6, mhartid
|
||||
csrr s6, CSR_MHARTID
|
||||
la a4, platform
|
||||
#if __riscv_xlen == 64
|
||||
lwu s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
|
||||
lwu s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
|
||||
#else
|
||||
lw s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
|
||||
lw s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
|
||||
#endif
|
||||
|
||||
/* HART ID should be within expected limit */
|
||||
csrr s6, mhartid
|
||||
csrr s6, CSR_MHARTID
|
||||
bge s6, s7, _start_hang
|
||||
|
||||
/* Setup scratch space */
|
||||
@@ -147,7 +156,7 @@ _start_warm:
|
||||
sub tp, tp, a5
|
||||
li a5, SBI_SCRATCH_SIZE
|
||||
sub tp, tp, a5
|
||||
csrw mscratch, tp
|
||||
csrw CSR_MSCRATCH, tp
|
||||
|
||||
/* Initialize scratch space */
|
||||
la a4, _fw_start
|
||||
@@ -172,17 +181,18 @@ _start_warm:
|
||||
la a4, _hartid_to_scratch
|
||||
REG_S a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
|
||||
REG_S zero, SBI_SCRATCH_IPI_TYPE_OFFSET(tp)
|
||||
REG_S zero, SBI_SCRATCH_TMP0_OFFSET(tp)
|
||||
|
||||
/* Setup stack */
|
||||
add sp, tp, zero
|
||||
|
||||
/* Setup trap handler */
|
||||
la a4, _trap_handler
|
||||
csrw mtvec, a4
|
||||
csrw CSR_MTVEC, a4
|
||||
|
||||
/* Initialize SBI runtime */
|
||||
csrr a0, mscratch
|
||||
call sbi_init
|
||||
csrr a0, CSR_MSCRATCH
|
||||
Call sbi_init
|
||||
|
||||
/* We don't expect to reach here hence just hang */
|
||||
j _start_hang
|
||||
@@ -202,8 +212,13 @@ _hartid_to_scratch:
|
||||
* s2 -> Temporary
|
||||
*/
|
||||
la s2, platform
|
||||
#if __riscv_xlen == 64
|
||||
lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
|
||||
lwu s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
|
||||
#else
|
||||
lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
|
||||
lw s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
|
||||
#endif
|
||||
mul s2, s2, s0
|
||||
la s1, _fw_end
|
||||
add s1, s1, s2
|
||||
@@ -228,42 +243,64 @@ _start_hang:
|
||||
.section .entry, "ax", %progbits
|
||||
.globl _trap_handler
|
||||
_trap_handler:
|
||||
/* Swap SP and MSCRATCH */
|
||||
csrrw sp, mscratch, sp
|
||||
/* Swap TP and MSCRATCH */
|
||||
csrrw tp, CSR_MSCRATCH, tp
|
||||
|
||||
/* Save T0 in scratch space */
|
||||
REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp)
|
||||
|
||||
/* Check which mode we came from */
|
||||
csrr t0, CSR_MSTATUS
|
||||
srl t0, t0, MSTATUS_MPP_SHIFT
|
||||
and t0, t0, PRV_M
|
||||
xori t0, t0, PRV_M
|
||||
beq t0, zero, _trap_handler_m_mode
|
||||
|
||||
/* We came from S-mode or U-mode */
|
||||
_trap_handler_s_mode:
|
||||
/* Set T0 to original SP */
|
||||
add t0, sp, zero
|
||||
|
||||
/* Setup exception stack */
|
||||
add sp, tp, -(SBI_TRAP_REGS_SIZE)
|
||||
|
||||
/* Jump to code common for all modes */
|
||||
j _trap_handler_all_mode
|
||||
|
||||
/* We came from M-mode */
|
||||
_trap_handler_m_mode:
|
||||
/* Set T0 to original SP */
|
||||
add t0, sp, zero
|
||||
|
||||
/* Re-use current SP as exception stack */
|
||||
add sp, sp, -(SBI_TRAP_REGS_SIZE)
|
||||
|
||||
/* Save RA, T0, T1, and T2 */
|
||||
REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
|
||||
REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
|
||||
REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
|
||||
REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
|
||||
|
||||
/* Save original SP and restore MSCRATCH */
|
||||
add t0, sp, SBI_TRAP_REGS_SIZE
|
||||
csrrw t0, mscratch, t0
|
||||
_trap_handler_all_mode:
|
||||
/* Save original SP (from T0) on stack */
|
||||
REG_S t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
|
||||
|
||||
/* Save MEPC and MSTATUS CSRs */
|
||||
csrr t0, mepc
|
||||
csrr t1, mstatus
|
||||
/* Restore T0 from scratch space */
|
||||
REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp)
|
||||
|
||||
/*
|
||||
* Note: Fast path trap handling can be done here
|
||||
* using SP, RA, T0, T1, and T2 registers where
|
||||
* T0 <- MEPC
|
||||
* T1 <- MSTATUS
|
||||
*/
|
||||
/* Save T0 on stack */
|
||||
REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
|
||||
|
||||
/* Swap TP and MSCRATCH */
|
||||
csrrw tp, CSR_MSCRATCH, tp
|
||||
|
||||
/* Save MEPC and MSTATUS CSRs */
|
||||
csrr t0, CSR_MEPC
|
||||
REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
|
||||
REG_S t1, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
|
||||
csrr t0, CSR_MSTATUS
|
||||
REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
|
||||
|
||||
/* Save all general regisers except SP, RA, T0, T1, and T2 */
|
||||
/* Save all general regisers except SP and T0 */
|
||||
REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
|
||||
REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
|
||||
REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
|
||||
REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
|
||||
REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
|
||||
REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
|
||||
REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
|
||||
REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
|
||||
REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
|
||||
@@ -291,12 +328,15 @@ _trap_handler:
|
||||
|
||||
/* Call C routine */
|
||||
add a0, sp, zero
|
||||
csrr a1, mscratch
|
||||
csrr a1, CSR_MSCRATCH
|
||||
call sbi_trap_handler
|
||||
|
||||
/* Restore all general regisers except SP, RA, T0, T1, T2, and T3 */
|
||||
/* Restore all general regisers except SP and T0 */
|
||||
REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
|
||||
REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
|
||||
REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
|
||||
REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
|
||||
REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
|
||||
REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
|
||||
REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
|
||||
REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
|
||||
@@ -322,26 +362,14 @@ _trap_handler:
|
||||
REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
|
||||
REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
|
||||
|
||||
/* Load T0 and T1 with MEPC and MSTATUS */
|
||||
REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
|
||||
REG_L t1, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
|
||||
|
||||
/*
|
||||
* Note: Jump here after fast trap handling
|
||||
* using SP, RA, T0, T1, and T2
|
||||
* T0 <- MEPC
|
||||
* T1 <- MSTATUS
|
||||
*/
|
||||
|
||||
/* Restore MEPC and MSTATUS CSRs */
|
||||
csrw mepc, t0
|
||||
csrw mstatus, t1
|
||||
REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
|
||||
csrw CSR_MEPC, t0
|
||||
REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
|
||||
csrw CSR_MSTATUS, t0
|
||||
|
||||
/* Restore RA, T0, T1, and T2 */
|
||||
REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
|
||||
/* Restore T0 */
|
||||
REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
|
||||
REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
|
||||
REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
|
||||
|
||||
/* Restore SP */
|
||||
REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "fw_base.S"
|
||||
|
||||
.align 3
|
||||
.align 4
|
||||
.section .entry, "ax", %progbits
|
||||
.global fw_prev_arg1
|
||||
fw_prev_arg1:
|
||||
@@ -21,7 +21,7 @@ fw_prev_arg1:
|
||||
#endif
|
||||
ret
|
||||
|
||||
.align 3
|
||||
.align 4
|
||||
.section .entry, "ax", %progbits
|
||||
.global fw_next_arg1
|
||||
fw_next_arg1:
|
||||
@@ -33,7 +33,7 @@ fw_next_arg1:
|
||||
#endif
|
||||
ret
|
||||
|
||||
.align 3
|
||||
.align 4
|
||||
.section .entry, "ax", %progbits
|
||||
.global fw_next_addr
|
||||
fw_next_addr:
|
||||
@@ -41,17 +41,15 @@ fw_next_addr:
|
||||
la a0, payload_bin
|
||||
ret
|
||||
|
||||
#define str(s) #s
|
||||
#define stringify(s) str(s)
|
||||
|
||||
#ifdef FW_PAYLOAD_FDT_PATH
|
||||
.align 3
|
||||
.align 4
|
||||
.section .text, "ax", %progbits
|
||||
.globl fdt_bin
|
||||
fdt_bin:
|
||||
.incbin stringify(FW_PAYLOAD_FDT_PATH)
|
||||
.incbin FW_PAYLOAD_FDT_PATH
|
||||
#endif
|
||||
|
||||
.align 4
|
||||
.section .payload, "ax", %progbits
|
||||
.globl payload_bin
|
||||
payload_bin:
|
||||
@@ -59,5 +57,5 @@ payload_bin:
|
||||
wfi
|
||||
j payload_bin
|
||||
#else
|
||||
.incbin stringify(FW_PAYLOAD_PATH)
|
||||
.incbin FW_PAYLOAD_PATH
|
||||
#endif
|
||||
|
@@ -31,7 +31,7 @@ FW_PAYLOAD_PATH_FINAL=$(FW_PAYLOAD_PATH)
|
||||
else
|
||||
FW_PAYLOAD_PATH_FINAL=$(build_dir)/$(platform_subdir)/firmware/payloads/test.bin
|
||||
endif
|
||||
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_PATH=$(FW_PAYLOAD_PATH_FINAL)
|
||||
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
|
||||
@@ -45,7 +45,7 @@ FW_PAYLOAD_FDT_PATH=$(build_dir)/$(platform_subdir)/$(FW_PAYLOAD_FDT)
|
||||
endif
|
||||
endif
|
||||
ifdef FW_PAYLOAD_FDT_PATH
|
||||
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_FDT_PATH=$(FW_PAYLOAD_FDT_PATH)
|
||||
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_FDT_PATH=\"$(FW_PAYLOAD_FDT_PATH)\"
|
||||
endif
|
||||
ifdef FW_PAYLOAD_FDT_ADDR
|
||||
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_FDT_ADDR=$(FW_PAYLOAD_FDT_ADDR)
|
||||
|
@@ -7,6 +7,7 @@
|
||||
* Anup Patel <anup.patel@wdc.com>
|
||||
*/
|
||||
|
||||
#include <sbi/riscv_encoding.h>
|
||||
#define __ASM_STR(x) x
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
@@ -48,12 +49,12 @@ _bss_zero:
|
||||
|
||||
_start_warm:
|
||||
/* Disable and clear all interrupts */
|
||||
csrw sie, zero
|
||||
csrw sip, zero
|
||||
csrw CSR_SIE, zero
|
||||
csrw CSR_SIP, zero
|
||||
|
||||
/* Setup exception vectors */
|
||||
la a3, _start_hang
|
||||
csrw stvec, a3
|
||||
csrw CSR_STVEC, a3
|
||||
|
||||
/* Setup stack */
|
||||
la a3, _payload_end
|
||||
|
@@ -10,6 +10,8 @@
|
||||
#ifndef __RISCV_ASM_H__
|
||||
#define __RISCV_ASM_H__
|
||||
|
||||
#include <sbi/riscv_encoding.h>
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#define __ASM_STR(x) x
|
||||
#else
|
||||
@@ -144,17 +146,17 @@ do { \
|
||||
|
||||
static inline int misa_extension(char ext)
|
||||
{
|
||||
return csr_read(misa) & (1 << (ext - 'A'));
|
||||
return csr_read(CSR_MISA) & (1 << (ext - 'A'));
|
||||
}
|
||||
|
||||
static inline int misa_xlen(void)
|
||||
{
|
||||
return ((long)csr_read(misa) < 0) ? 64 : 32;
|
||||
return ((long)csr_read(CSR_MISA) < 0) ? 64 : 32;
|
||||
}
|
||||
|
||||
static inline void misa_string(char *out, unsigned int out_sz)
|
||||
{
|
||||
unsigned long i, val = csr_read(misa);
|
||||
unsigned long i, val = csr_read(CSR_MISA);
|
||||
|
||||
for (i = 0; i < 26; i++) {
|
||||
if (val & (1 << i)) {
|
||||
|
@@ -195,10 +195,18 @@
|
||||
#define RISCV_PGSHIFT 12
|
||||
#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
|
||||
|
||||
#define CSR_USTATUS 0x0
|
||||
#define CSR_FFLAGS 0x1
|
||||
#define CSR_FRM 0x2
|
||||
#define CSR_FCSR 0x3
|
||||
#define CSR_CYCLE 0xc00
|
||||
#define CSR_UIE 0x4
|
||||
#define CSR_UTVEC 0x5
|
||||
#define CSR_USCRATCH 0x40
|
||||
#define CSR_UEPC 0x41
|
||||
#define CSR_UCAUSE 0x42
|
||||
#define CSR_UTVAL 0x43
|
||||
#define CSR_UIP 0x44
|
||||
#define CSR_TIME 0xc01
|
||||
#define CSR_INSTRET 0xc02
|
||||
#define CSR_HPMCOUNTER3 0xc03
|
||||
|
@@ -43,12 +43,12 @@
|
||||
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(fcsr)
|
||||
#define SET_FCSR(value) csr_write(fcsr, (value))
|
||||
#define GET_FRM() csr_read(frm)
|
||||
#define SET_FRM(value) csr_write(frm, (value))
|
||||
#define GET_FFLAGS() csr_read(fflags)
|
||||
#define SET_FFLAGS(value) csr_write(fflags, (value))
|
||||
#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)
|
||||
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET (7 * __SIZEOF_POINTER__)
|
||||
/** Offset of ipi_type member in sbi_scratch */
|
||||
#define SBI_SCRATCH_IPI_TYPE_OFFSET (8 * __SIZEOF_POINTER__)
|
||||
/** Offset of tmp0 member in sbi_scratch */
|
||||
#define SBI_SCRATCH_TMP0_OFFSET (9 * __SIZEOF_POINTER__)
|
||||
/** Maximum size of sbi_scratch */
|
||||
#define SBI_SCRATCH_SIZE 256
|
||||
|
||||
@@ -57,11 +59,13 @@ struct sbi_scratch {
|
||||
unsigned long hartid_to_scratch;
|
||||
/** IPI type (or flags) */
|
||||
unsigned long ipi_type;
|
||||
/** Temporary storage */
|
||||
unsigned long tmp0;
|
||||
} __packed;
|
||||
|
||||
/** Get pointer to sbi_scratch for current HART */
|
||||
#define sbi_scratch_thishart_ptr() \
|
||||
((struct sbi_scratch *)csr_read(mscratch))
|
||||
((struct sbi_scratch *)csr_read(CSR_MSCRATCH))
|
||||
|
||||
/** Get Arg1 of next booting stage for current HART */
|
||||
#define sbi_scratch_thishart_arg1_ptr() \
|
||||
|
@@ -29,11 +29,13 @@ typedef long s64;
|
||||
typedef unsigned long u64;
|
||||
typedef long int64_t;
|
||||
typedef unsigned long uint64_t;
|
||||
#define PRILX "016lx"
|
||||
#elif __riscv_xlen == 32
|
||||
typedef long long s64;
|
||||
typedef unsigned long long u64;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#define PRILX "08lx"
|
||||
#else
|
||||
#error "Unexpected __riscv_xlen"
|
||||
#endif
|
||||
|
@@ -20,9 +20,9 @@ static inline type load_##type(const type *addr, ulong mepc) \
|
||||
register ulong __mepc asm ("a2") = mepc; \
|
||||
register ulong __mstatus asm ("a3"); \
|
||||
type val; \
|
||||
asm ("csrrs %0, mstatus, %3\n" \
|
||||
asm ("csrrs %0, "STR(CSR_MSTATUS)", %3\n" \
|
||||
#insn " %1, %2\n" \
|
||||
"csrw mstatus, %0" \
|
||||
"csrw "STR(CSR_MSTATUS)", %0" \
|
||||
: "+&r" (__mstatus), "=&r" (val) \
|
||||
: "m" (*addr), "r" (MSTATUS_MPRV), "r" (__mepc)); \
|
||||
return val; \
|
||||
@@ -33,9 +33,9 @@ static inline void store_##type(type *addr, type val, ulong mepc) \
|
||||
{ \
|
||||
register ulong __mepc asm ("a2") = mepc; \
|
||||
register ulong __mstatus asm ("a3"); \
|
||||
asm volatile ("csrrs %0, mstatus, %3\n" \
|
||||
asm volatile ("csrrs %0, "STR(CSR_MSTATUS)", %3\n" \
|
||||
#insn " %1, %2\n" \
|
||||
"csrw mstatus, %0" \
|
||||
"csrw "STR(CSR_MSTATUS)", %0" \
|
||||
: "+&r" (__mstatus) \
|
||||
: "r" (val), "m" (*addr), "r" (MSTATUS_MPRV), "r" (__mepc)); \
|
||||
}
|
||||
@@ -76,17 +76,25 @@ static inline ulong get_insn(ulong mepc, ulong *mstatus)
|
||||
register ulong __mstatus asm ("a3");
|
||||
ulong val;
|
||||
#ifndef __riscv_compressed
|
||||
asm ("csrrs %[mstatus], mstatus, %[mprv]\n"
|
||||
asm ("csrrs %[mstatus], "STR(CSR_MSTATUS)", %[mprv]\n"
|
||||
#if __riscv_xlen == 64
|
||||
STR(LWU) " %[insn], (%[addr])\n"
|
||||
"csrw mstatus, %[mstatus]"
|
||||
#else
|
||||
STR(LW) " %[insn], (%[addr])\n"
|
||||
#endif
|
||||
"csrw "STR(CSR_MSTATUS)", %[mstatus]"
|
||||
: [mstatus] "+&r" (__mstatus), [insn] "=&r" (val)
|
||||
: [mprv] "r" (MSTATUS_MPRV | MSTATUS_MXR), [addr] "r" (__mepc));
|
||||
#else
|
||||
ulong rvc_mask = 3, tmp;
|
||||
asm ("csrrs %[mstatus], mstatus, %[mprv]\n"
|
||||
asm ("csrrs %[mstatus], "STR(CSR_MSTATUS)", %[mprv]\n"
|
||||
"and %[tmp], %[addr], 2\n"
|
||||
"bnez %[tmp], 1f\n"
|
||||
#if __riscv_xlen == 64
|
||||
STR(LWU) " %[insn], (%[addr])\n"
|
||||
#else
|
||||
STR(LW) " %[insn], (%[addr])\n"
|
||||
#endif
|
||||
"and %[tmp], %[insn], %[rvc_mask]\n"
|
||||
"beq %[tmp], %[rvc_mask], 2f\n"
|
||||
"sll %[insn], %[insn], %[xlen_minus_16]\n"
|
||||
@@ -99,7 +107,7 @@ static inline ulong get_insn(ulong mepc, ulong *mstatus)
|
||||
"lhu %[tmp], 2(%[addr])\n"
|
||||
"sll %[tmp], %[tmp], 16\n"
|
||||
"add %[insn], %[insn], %[tmp]\n"
|
||||
"2: csrw mstatus, %[mstatus]"
|
||||
"2: csrw "STR(CSR_MSTATUS)", %[mstatus]"
|
||||
: [mstatus] "+&r" (__mstatus), [insn] "=&r" (val), [tmp] "=&r" (tmp)
|
||||
: [mprv] "r" (MSTATUS_MPRV | MSTATUS_MXR), [addr] "r" (__mepc),
|
||||
[rvc_mask] "r" (rvc_mask), [xlen_minus_16] "i" (__riscv_xlen - 16));
|
||||
|
@@ -11,6 +11,6 @@
|
||||
#define __SBI_VERSION_H__
|
||||
|
||||
#define OPENSBI_VERSION_MAJOR 0
|
||||
#define OPENSBI_VERSION_MINOR 1
|
||||
#define OPENSBI_VERSION_MINOR 3
|
||||
|
||||
#endif
|
||||
|
@@ -39,7 +39,7 @@ int sbi_ecall_handler(u32 hartid, ulong mcause,
|
||||
case SBI_ECALL_SET_TIMER:
|
||||
#if __riscv_xlen == 32
|
||||
sbi_timer_event_start(scratch,
|
||||
(((u64)regs->a1 << 32) || (u64)regs->a0));
|
||||
(((u64)regs->a1 << 32) | (u64)regs->a0));
|
||||
#else
|
||||
sbi_timer_event_start(scratch, (u64)regs->a0);
|
||||
#endif
|
||||
|
@@ -23,13 +23,13 @@ int sbi_emulate_csr_read(int csr_num,
|
||||
ulong cen = -1UL;
|
||||
|
||||
if (EXTRACT_FIELD(mstatus, MSTATUS_MPP) == PRV_U)
|
||||
cen = csr_read(scounteren);
|
||||
cen = csr_read(CSR_SCOUNTEREN);
|
||||
|
||||
switch (csr_num) {
|
||||
case CSR_CYCLE:
|
||||
if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(mcycle);
|
||||
*csr_val = csr_read(CSR_MCYCLE);
|
||||
break;
|
||||
case CSR_TIME:
|
||||
if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
|
||||
@@ -39,51 +39,50 @@ int sbi_emulate_csr_read(int csr_num,
|
||||
case CSR_INSTRET:
|
||||
if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(minstret);
|
||||
*csr_val = csr_read(CSR_MINSTRET);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER3:
|
||||
if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(mhpmcounter3);
|
||||
*csr_val = csr_read(CSR_MHPMCOUNTER3);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER4:
|
||||
if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(mhpmcounter4);
|
||||
*csr_val = csr_read(CSR_MHPMCOUNTER4);
|
||||
break;
|
||||
#if __riscv_xlen == 32
|
||||
case CSR_CYCLEH:
|
||||
if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(mcycleh);
|
||||
*csr_val = csr_read(CSR_MCYCLEH);
|
||||
break;
|
||||
case CSR_TIMEH:
|
||||
if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
|
||||
return -1;
|
||||
*csr_val = sbi_timer_value(scratch);
|
||||
*csr_val = *csr_val >> 32;
|
||||
*csr_val = sbi_timer_value(scratch) >> 32;
|
||||
break;
|
||||
case CSR_INSTRETH:
|
||||
if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(minstreth);
|
||||
*csr_val = csr_read(CSR_MINSTRETH);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER3H:
|
||||
if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(mhpmcounter3h);
|
||||
*csr_val = csr_read(CSR_MHPMCOUNTER3H);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER4H:
|
||||
if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
|
||||
return -1;
|
||||
*csr_val = csr_read(mhpmcounter4h);
|
||||
*csr_val = csr_read(CSR_MHPMCOUNTER4H);
|
||||
break;
|
||||
#endif
|
||||
case CSR_MHPMEVENT3:
|
||||
*csr_val = csr_read(mhpmevent3);
|
||||
*csr_val = csr_read(CSR_MHPMEVENT3);
|
||||
break;
|
||||
case CSR_MHPMEVENT4:
|
||||
*csr_val = csr_read(mhpmevent4);
|
||||
*csr_val = csr_read(CSR_MHPMEVENT4);
|
||||
break;
|
||||
default:
|
||||
sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
|
||||
@@ -101,36 +100,36 @@ int sbi_emulate_csr_write(int csr_num,
|
||||
{
|
||||
switch (csr_num) {
|
||||
case CSR_CYCLE:
|
||||
csr_write(mcycle, csr_val);
|
||||
csr_write(CSR_MCYCLE, csr_val);
|
||||
break;
|
||||
case CSR_INSTRET:
|
||||
csr_write(minstret, csr_val);
|
||||
csr_write(CSR_MINSTRET, csr_val);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER3:
|
||||
csr_write(mhpmcounter3, csr_val);
|
||||
csr_write(CSR_MHPMCOUNTER3, csr_val);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER4:
|
||||
csr_write(mhpmcounter4, csr_val);
|
||||
csr_write(CSR_MHPMCOUNTER4, csr_val);
|
||||
break;
|
||||
#if __riscv_xlen == 32
|
||||
case CSR_CYCLEH:
|
||||
csr_write(mcycleh, csr_val);
|
||||
csr_write(CSR_MCYCLEH, csr_val);
|
||||
break;
|
||||
case CSR_INSTRETH:
|
||||
csr_write(minstreth, csr_val);
|
||||
csr_write(CSR_MINSTRETH, csr_val);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER3H:
|
||||
csr_write(mhpmcounter3h, csr_val);
|
||||
csr_write(CSR_MHPMCOUNTER3H, csr_val);
|
||||
break;
|
||||
case CSR_MHPMCOUNTER4H:
|
||||
csr_write(mhpmcounter4h, csr_val);
|
||||
csr_write(CSR_MHPMCOUNTER4H, csr_val);
|
||||
break;
|
||||
#endif
|
||||
case CSR_MHPMEVENT3:
|
||||
csr_write(mhpmevent3, csr_val);
|
||||
csr_write(CSR_MHPMEVENT3, csr_val);
|
||||
break;
|
||||
case CSR_MHPMEVENT4:
|
||||
csr_write(mhpmevent4, csr_val);
|
||||
csr_write(CSR_MHPMEVENT4, csr_val);
|
||||
break;
|
||||
default:
|
||||
sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
unsigned int sbi_current_hartid()
|
||||
{
|
||||
return (u32)csr_read(mhartid);
|
||||
return (u32)csr_read(CSR_MHARTID);
|
||||
}
|
||||
|
||||
static void mstatus_init(struct sbi_scratch *scratch, u32 hartid)
|
||||
@@ -32,21 +32,21 @@ static void mstatus_init(struct sbi_scratch *scratch, u32 hartid)
|
||||
|
||||
/* Enable FPU */
|
||||
if (misa_extension('D') || misa_extension('F'))
|
||||
csr_write(mstatus, MSTATUS_FS);
|
||||
csr_write(CSR_MSTATUS, MSTATUS_FS);
|
||||
|
||||
/* Enable user/supervisor use of perf counters */
|
||||
if (misa_extension('S') &&
|
||||
sbi_platform_has_scounteren(plat))
|
||||
csr_write(scounteren, -1);
|
||||
csr_write(CSR_SCOUNTEREN, -1);
|
||||
if (sbi_platform_has_mcounteren(plat))
|
||||
csr_write(mcounteren, -1);
|
||||
csr_write(CSR_MCOUNTEREN, -1);
|
||||
|
||||
/* Disable all interrupts */
|
||||
csr_write(mie, 0);
|
||||
csr_write(CSR_MIE, 0);
|
||||
|
||||
/* Disable S-mode paging */
|
||||
if (misa_extension('S'))
|
||||
csr_write(sptbr, 0);
|
||||
csr_write(CSR_SATP, 0);
|
||||
}
|
||||
|
||||
static int fp_init(u32 hartid)
|
||||
@@ -60,17 +60,17 @@ static int fp_init(u32 hartid)
|
||||
if (!misa_extension('D') && !misa_extension('F'))
|
||||
return 0;
|
||||
|
||||
if (!(csr_read(mstatus) & MSTATUS_FS))
|
||||
if (!(csr_read(CSR_MSTATUS) & MSTATUS_FS))
|
||||
return SBI_EINVAL;
|
||||
|
||||
#ifdef __riscv_flen
|
||||
for (i = 0; i < 32; i++)
|
||||
init_fp_reg(i);
|
||||
csr_write(fcsr, 0);
|
||||
csr_write(CSR_FCSR, 0);
|
||||
#else
|
||||
fd_mask = (1 << ('F' - 'A')) | (1 << ('D' - 'A'));
|
||||
csr_clear(misa, fd_mask);
|
||||
if (csr_read(misa) & fd_mask)
|
||||
csr_clear(CSR_MISA, fd_mask);
|
||||
if (csr_read(CSR_MISA) & fd_mask)
|
||||
return SBI_ENOTSUPP;
|
||||
#endif
|
||||
|
||||
@@ -96,12 +96,12 @@ static int delegate_traps(struct sbi_scratch *scratch, u32 hartid)
|
||||
(1U << CAUSE_LOAD_PAGE_FAULT) |
|
||||
(1U << CAUSE_STORE_PAGE_FAULT);
|
||||
|
||||
csr_write(mideleg, interrupts);
|
||||
csr_write(medeleg, exceptions);
|
||||
csr_write(CSR_MIDELEG, interrupts);
|
||||
csr_write(CSR_MEDELEG, exceptions);
|
||||
|
||||
if (csr_read(mideleg) != interrupts)
|
||||
if (csr_read(CSR_MIDELEG) != interrupts)
|
||||
return SBI_EFAIL;
|
||||
if (csr_read(medeleg) != exceptions)
|
||||
if (csr_read(CSR_MEDELEG) != exceptions)
|
||||
return SBI_EFAIL;
|
||||
|
||||
return 0;
|
||||
@@ -230,22 +230,22 @@ void __attribute__((noreturn)) sbi_hart_switch_mode(unsigned long arg0,
|
||||
sbi_hart_hang();
|
||||
}
|
||||
|
||||
val = csr_read(mstatus);
|
||||
val = csr_read(CSR_MSTATUS);
|
||||
val = INSERT_FIELD(val, MSTATUS_MPP, next_mode);
|
||||
val = INSERT_FIELD(val, MSTATUS_MPIE, 0);
|
||||
|
||||
csr_write(mstatus, val);
|
||||
csr_write(mepc, next_addr);
|
||||
csr_write(CSR_MSTATUS, val);
|
||||
csr_write(CSR_MEPC, next_addr);
|
||||
|
||||
if (next_mode == PRV_S) {
|
||||
csr_write(stvec, next_addr);
|
||||
csr_write(sscratch, 0);
|
||||
csr_write(sie, 0);
|
||||
csr_write(satp, 0);
|
||||
csr_write(CSR_STVEC, next_addr);
|
||||
csr_write(CSR_SSCRATCH, 0);
|
||||
csr_write(CSR_SIE, 0);
|
||||
csr_write(CSR_SATP, 0);
|
||||
} else if (next_mode == PRV_U) {
|
||||
csr_write(utvec, next_addr);
|
||||
csr_write(uscratch, 0);
|
||||
csr_write(uie, 0);
|
||||
csr_write(CSR_UTVEC, next_addr);
|
||||
csr_write(CSR_USCRATCH, 0);
|
||||
csr_write(CSR_UIE, 0);
|
||||
}
|
||||
|
||||
register unsigned long a0 asm ("a0") = arg0;
|
||||
@@ -304,7 +304,7 @@ void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid)
|
||||
sbi_hart_hang();
|
||||
|
||||
/* Set MSIE bit to receive IPI */
|
||||
csr_set(mie, MIP_MSIP);
|
||||
csr_set(CSR_MIE, MIP_MSIP);
|
||||
|
||||
do {
|
||||
spin_lock(&coldboot_wait_bitmap_lock);
|
||||
@@ -312,14 +312,14 @@ void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid)
|
||||
spin_unlock(&coldboot_wait_bitmap_lock);
|
||||
|
||||
wfi();
|
||||
mipval = csr_read(mip);
|
||||
mipval = csr_read(CSR_MIP);
|
||||
|
||||
spin_lock(&coldboot_wait_bitmap_lock);
|
||||
coldboot_wait_bitmap &= ~(1UL << hartid);
|
||||
spin_unlock(&coldboot_wait_bitmap_lock);
|
||||
} while (!(mipval && MIP_MSIP));
|
||||
|
||||
csr_clear(mip, MIP_MSIP);
|
||||
csr_clear(CSR_MIP, MIP_MSIP);
|
||||
}
|
||||
|
||||
void sbi_hart_wake_coldboot_harts(struct sbi_scratch *scratch, u32 hartid)
|
||||
|
@@ -127,7 +127,7 @@ int sbi_illegal_insn_handler(u32 hartid, ulong mcause,
|
||||
|
||||
if (unlikely((insn & 3) != 3)) {
|
||||
if (insn == 0) {
|
||||
mstatus = csr_read(mstatus);
|
||||
mstatus = csr_read(CSR_MSTATUS);
|
||||
insn = get_insn(regs->mepc, &mstatus);
|
||||
}
|
||||
if ((insn & 3) != 3)
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*
|
||||
* Authors:
|
||||
* Anup Patel <anup.patel@wdc.com>
|
||||
* Nick Kossifidis <mick@ics.forth.gr>
|
||||
*/
|
||||
|
||||
#include <sbi/riscv_asm.h>
|
||||
@@ -18,35 +19,55 @@
|
||||
#include <sbi/sbi_timer.h>
|
||||
#include <sbi/sbi_unpriv.h>
|
||||
|
||||
static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid, u32 event)
|
||||
{
|
||||
struct sbi_scratch *remote_scratch = NULL;
|
||||
struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
|
||||
if (sbi_platform_hart_disabled(plat, hartid))
|
||||
return -1;
|
||||
|
||||
/* Set IPI type on remote hart's scratch area and
|
||||
* trigger the interrupt
|
||||
*/
|
||||
remote_scratch = sbi_hart_id_to_scratch(scratch, hartid);
|
||||
atomic_raw_set_bit(event, &remote_scratch->ipi_type);
|
||||
mb();
|
||||
sbi_platform_ipi_send(plat, hartid);
|
||||
if (event != SBI_IPI_EVENT_SOFT)
|
||||
sbi_platform_ipi_sync(plat, hartid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sbi_ipi_send_many(struct sbi_scratch *scratch,
|
||||
ulong *pmask, u32 event)
|
||||
{
|
||||
ulong i, m;
|
||||
struct sbi_scratch *oth;
|
||||
ulong mask = sbi_hart_available_mask();
|
||||
struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
u32 hartid = sbi_current_hartid();
|
||||
|
||||
if (pmask)
|
||||
mask &= load_ulong(pmask, csr_read(mepc));
|
||||
mask &= load_ulong(pmask, csr_read(CSR_MEPC));
|
||||
|
||||
/* send IPIs to every other hart on the set */
|
||||
for (i = 0, m = mask; m; i++, m >>= 1)
|
||||
if ((m & 1UL) && (i != hartid))
|
||||
sbi_ipi_send(scratch, i, event);
|
||||
|
||||
/* If the current hart is on the set, send an IPI
|
||||
* to it as well
|
||||
*/
|
||||
if (mask & (1UL << hartid))
|
||||
sbi_ipi_send(scratch, hartid, event);
|
||||
|
||||
/* send IPIs to everyone */
|
||||
for (i = 0, m = mask; m; i++, m >>= 1) {
|
||||
if ((m & 1) && !sbi_platform_hart_disabled(plat, i)) {
|
||||
oth = sbi_hart_id_to_scratch(scratch, i);
|
||||
atomic_raw_set_bit(event, &oth->ipi_type);
|
||||
mb();
|
||||
sbi_platform_ipi_send(plat, i);
|
||||
if (event != SBI_IPI_EVENT_SOFT)
|
||||
sbi_platform_ipi_sync(plat, i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sbi_ipi_clear_smode(struct sbi_scratch *scratch)
|
||||
{
|
||||
csr_clear(mip, MIP_SSIP);
|
||||
csr_clear(CSR_MIP, MIP_SSIP);
|
||||
}
|
||||
|
||||
void sbi_ipi_process(struct sbi_scratch *scratch)
|
||||
@@ -64,7 +85,7 @@ void sbi_ipi_process(struct sbi_scratch *scratch)
|
||||
ipi_event = __ffs(ipi_type);
|
||||
switch (ipi_event) {
|
||||
case SBI_IPI_EVENT_SOFT:
|
||||
csr_set(mip, MIP_SSIP);
|
||||
csr_set(CSR_MIP, MIP_SSIP);
|
||||
break;
|
||||
case SBI_IPI_EVENT_FENCE_I:
|
||||
__asm__ __volatile("fence.i");
|
||||
@@ -83,7 +104,7 @@ void sbi_ipi_process(struct sbi_scratch *scratch)
|
||||
int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot)
|
||||
{
|
||||
/* Enable software interrupts */
|
||||
csr_set(mie, MIP_MSIP);
|
||||
csr_set(CSR_MIE, MIP_MSIP);
|
||||
|
||||
return sbi_platform_ipi_init(sbi_platform_ptr(scratch),
|
||||
cold_boot);
|
||||
|
@@ -26,9 +26,9 @@ int sbi_misaligned_load_handler(u32 hartid, ulong mcause,
|
||||
struct sbi_scratch *scratch)
|
||||
{
|
||||
union reg_data val;
|
||||
ulong mstatus = csr_read(mstatus);
|
||||
ulong mstatus = csr_read(CSR_MSTATUS);
|
||||
ulong insn = get_insn(regs->mepc, &mstatus);
|
||||
ulong addr = csr_read(mtval);
|
||||
ulong addr = csr_read(CSR_MTVAL);
|
||||
int i, fp = 0, shift = 0, len = 0;
|
||||
|
||||
if ((insn & INSN_MASK_LW) == INSN_MATCH_LW) {
|
||||
@@ -112,9 +112,9 @@ int sbi_misaligned_store_handler(u32 hartid, ulong mcause,
|
||||
struct sbi_scratch *scratch)
|
||||
{
|
||||
union reg_data val;
|
||||
ulong mstatus = csr_read(mstatus);
|
||||
ulong mstatus = csr_read(CSR_MSTATUS);
|
||||
ulong insn = get_insn(regs->mepc, &mstatus);
|
||||
ulong addr = csr_read(mtval);
|
||||
ulong addr = csr_read(CSR_MTVAL);
|
||||
int i, len = 0;
|
||||
|
||||
val.data_ulong = GET_RS2(insn, regs);
|
||||
|
@@ -5,11 +5,13 @@
|
||||
*
|
||||
* Authors:
|
||||
* Anup Patel <anup.patel@wdc.com>
|
||||
* Nick Kossifidis <mick@ics.forth.gr>
|
||||
*/
|
||||
|
||||
#include <sbi/sbi_hart.h>
|
||||
#include <sbi/sbi_platform.h>
|
||||
#include <sbi/sbi_system.h>
|
||||
#include <sbi/sbi_ipi.h>
|
||||
|
||||
int sbi_system_early_init(struct sbi_scratch *scratch, bool cold_boot)
|
||||
{
|
||||
@@ -34,6 +36,12 @@ void __attribute__((noreturn)) sbi_system_reboot(struct sbi_scratch *scratch,
|
||||
void __attribute__((noreturn)) sbi_system_shutdown(struct sbi_scratch *scratch,
|
||||
u32 type)
|
||||
{
|
||||
/* First try the platform-specific method */
|
||||
sbi_platform_system_shutdown(sbi_platform_ptr(scratch), type);
|
||||
|
||||
/* If that fails (or is not implemented) send an IPI on every
|
||||
* hart to hang and then hang the current hart */
|
||||
sbi_ipi_send_many(scratch, NULL, SBI_IPI_EVENT_HALT);
|
||||
|
||||
sbi_hart_hang();
|
||||
}
|
||||
|
@@ -56,14 +56,14 @@ void sbi_timer_event_start(struct sbi_scratch *scratch, u64 next_event)
|
||||
{
|
||||
sbi_platform_timer_event_start(sbi_platform_ptr(scratch),
|
||||
next_event);
|
||||
csr_clear(mip, MIP_STIP);
|
||||
csr_set(mie, MIP_MTIP);
|
||||
csr_clear(CSR_MIP, MIP_STIP);
|
||||
csr_set(CSR_MIE, MIP_MTIP);
|
||||
}
|
||||
|
||||
void sbi_timer_process(struct sbi_scratch *scratch)
|
||||
{
|
||||
csr_clear(mie, MIP_MTIP);
|
||||
csr_set(mip, MIP_STIP);
|
||||
csr_clear(CSR_MIE, MIP_MTIP);
|
||||
csr_set(CSR_MIP, MIP_STIP);
|
||||
}
|
||||
|
||||
int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)
|
||||
|
@@ -26,41 +26,41 @@ static void __noreturn sbi_trap_error(const char *msg,
|
||||
{
|
||||
sbi_printf("%s: hart%d: %s (error %d)\n",
|
||||
__func__, hartid, msg, rc);
|
||||
sbi_printf("%s: hart%d: mcause=0x%lx mtval=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: mcause=0x%"PRILX" mtval=0x%"PRILX"\n",
|
||||
__func__, hartid, mcause, mtval);
|
||||
sbi_printf("%s: hart%d: mepc=0x%lx mstatus=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: mepc=0x%"PRILX" mstatus=0x%"PRILX"\n",
|
||||
__func__, hartid, regs->mepc, regs->mstatus);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "ra", regs->ra, "sp", regs->sp);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "gp", regs->gp, "tp", regs->tp);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s0", regs->s0, "s1", regs->s1);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a0", regs->a0, "a1", regs->a1);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a2", regs->a2, "a3", regs->a3);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a4", regs->a4, "a5", regs->a5);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a6", regs->a6, "a7", regs->a7);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s2", regs->s2, "s3", regs->s3);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s4", regs->s4, "s5", regs->s5);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s6", regs->s6, "s7", regs->s7);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s8", regs->s8, "s9", regs->s9);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s10", regs->s10, "s11", regs->s11);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t0", regs->t0, "t1", regs->t1);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t2", regs->t2, "t3", regs->t3);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t4", regs->t4, "t5", regs->t5);
|
||||
sbi_printf("%s: hart%d: %s=0x%lx\n",
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t6", regs->t6);
|
||||
|
||||
sbi_hart_hang();
|
||||
@@ -89,12 +89,12 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
||||
return SBI_ENOTSUPP;
|
||||
|
||||
/* Update S-mode exception info */
|
||||
csr_write(stval, tval);
|
||||
csr_write(sepc, epc);
|
||||
csr_write(scause, cause);
|
||||
csr_write(CSR_STVAL, tval);
|
||||
csr_write(CSR_SEPC, epc);
|
||||
csr_write(CSR_SCAUSE, cause);
|
||||
|
||||
/* Set MEPC to S-mode exception vector base */
|
||||
regs->mepc = csr_read(stvec);
|
||||
regs->mepc = csr_read(CSR_STVEC);
|
||||
|
||||
/* Initial value of new MSTATUS */
|
||||
new_mstatus = regs->mstatus;
|
||||
@@ -141,7 +141,7 @@ void sbi_trap_handler(struct sbi_trap_regs *regs,
|
||||
int rc = SBI_ENOTSUPP;
|
||||
const char *msg = "trap handler failed";
|
||||
u32 hartid = sbi_current_hartid();
|
||||
ulong mcause = csr_read(mcause);
|
||||
ulong mcause = csr_read(CSR_MCAUSE);
|
||||
|
||||
if (mcause & (1UL << (__riscv_xlen - 1))) {
|
||||
mcause &= ~(1UL << (__riscv_xlen - 1));
|
||||
@@ -183,6 +183,6 @@ void sbi_trap_handler(struct sbi_trap_regs *regs,
|
||||
|
||||
trap_error:
|
||||
if (rc) {
|
||||
sbi_trap_error(msg, rc, hartid, mcause, csr_read(mtval), regs);
|
||||
sbi_trap_error(msg, rc, hartid, mcause, csr_read(CSR_MTVAL), regs);
|
||||
}
|
||||
}
|
||||
|
@@ -87,7 +87,15 @@ static volatile u64 *clint_time_cmp;
|
||||
|
||||
u64 clint_timer_value(void)
|
||||
{
|
||||
#if __riscv_xlen == 64
|
||||
return readq_relaxed(clint_time_val);
|
||||
#else
|
||||
u64 tmp;
|
||||
tmp = readl_relaxed((void *)clint_time_val + 0x04);
|
||||
tmp <<= 32;
|
||||
tmp |= readl_relaxed(clint_time_val);
|
||||
return tmp;
|
||||
#endif
|
||||
}
|
||||
|
||||
void clint_timer_event_stop(void)
|
||||
@@ -98,7 +106,12 @@ void clint_timer_event_stop(void)
|
||||
return;
|
||||
|
||||
/* Clear CLINT Time Compare */
|
||||
#if __riscv_xlen == 64
|
||||
writeq_relaxed(-1ULL, &clint_time_cmp[target_hart]);
|
||||
#else
|
||||
writel_relaxed(-1UL, &clint_time_cmp[target_hart]);
|
||||
writel_relaxed(-1UL, (void *)(&clint_time_cmp[target_hart]) + 0x04);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clint_timer_event_start(u64 next_event)
|
||||
@@ -109,7 +122,13 @@ void clint_timer_event_start(u64 next_event)
|
||||
return;
|
||||
|
||||
/* Program CLINT Time Compare */
|
||||
#if __riscv_xlen == 64
|
||||
writeq_relaxed(next_event, &clint_time_cmp[target_hart]);
|
||||
#else
|
||||
u32 mask = -1UL;
|
||||
writel_relaxed(next_event & mask, &clint_time_cmp[target_hart]);
|
||||
writel_relaxed(next_event >> 32, (void *)(&clint_time_cmp[target_hart]) + 0x04);
|
||||
#endif
|
||||
}
|
||||
|
||||
int clint_warm_timer_init(void)
|
||||
@@ -121,7 +140,12 @@ int clint_warm_timer_init(void)
|
||||
return -1;
|
||||
|
||||
/* Clear CLINT Time Compare */
|
||||
#if __riscv_xlen == 64
|
||||
writeq_relaxed(-1ULL, &clint_time_cmp[target_hart]);
|
||||
#else
|
||||
writel_relaxed(-1UL, &clint_time_cmp[target_hart]);
|
||||
writel_relaxed(-1UL, (void *)(&clint_time_cmp[target_hart]) + 0x04);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -9,8 +9,8 @@
|
||||
|
||||
# Compiler flags
|
||||
platform-cppflags-y =
|
||||
platform-cflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-asflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-cflags-y =
|
||||
platform-asflags-y =
|
||||
platform-ldflags-y =
|
||||
|
||||
# Common drivers to enable
|
||||
|
@@ -88,7 +88,7 @@
|
||||
#define SPI1_BASE_ADDR (0x53000000U)
|
||||
#define SPI3_BASE_ADDR (0x54000000U)
|
||||
|
||||
#define read_cycle() csr_read(mcycle)
|
||||
#define read_cycle() csr_read(CSR_MCYCLE)
|
||||
|
||||
/*
|
||||
* PLIC External Interrupt Numbers
|
||||
|
@@ -9,10 +9,14 @@
|
||||
|
||||
# Compiler flags
|
||||
platform-cppflags-y =
|
||||
platform-cflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-asflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-cflags-y =
|
||||
platform-asflags-y =
|
||||
platform-ldflags-y =
|
||||
|
||||
# Command for platform specific "make run"
|
||||
platform-runcmd = qemu-system-riscv$(PLATFORM_RISCV_XLEN) -M sifive_u -m 256M \
|
||||
-nographic -kernel $(build_dir)/platform/qemu/sifive_u/firmware/fw_payload.elf
|
||||
|
||||
# Common drivers to enable
|
||||
PLATFORM_IRQCHIP_PLIC=y
|
||||
PLATFORM_SERIAL_SIFIVE_UART=y
|
||||
@@ -21,10 +25,22 @@ PLATFORM_SYS_CLINT=y
|
||||
# Blobs to build
|
||||
FW_TEXT_START=0x80000000
|
||||
FW_JUMP=y
|
||||
FW_JUMP_ADDR=0x80200000
|
||||
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||
# This needs to be 4MB alligned for 32-bit system
|
||||
FW_JUMP_ADDR=0x80400000
|
||||
else
|
||||
# This needs to be 2MB alligned for 64-bit system
|
||||
FW_JUMP_ADDR=0x80200000
|
||||
endif
|
||||
FW_JUMP_FDT_ADDR=0x82200000
|
||||
FW_PAYLOAD=y
|
||||
FW_PAYLOAD_OFFSET=0x200000
|
||||
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||
# This needs to be 4MB alligned for 32-bit system
|
||||
FW_PAYLOAD_OFFSET=0x400000
|
||||
else
|
||||
# This needs to be 2MB alligned for 64-bit system
|
||||
FW_PAYLOAD_OFFSET=0x200000
|
||||
endif
|
||||
FW_PAYLOAD_FDT_ADDR=0x82200000
|
||||
|
||||
# External Libraries to include
|
||||
|
@@ -9,10 +9,14 @@
|
||||
|
||||
# Compiler flags
|
||||
platform-cppflags-y =
|
||||
platform-cflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-asflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-cflags-y =
|
||||
platform-asflags-y =
|
||||
platform-ldflags-y =
|
||||
|
||||
# Command for platform specific "make run"
|
||||
platform-runcmd = qemu-system-riscv$(PLATFORM_RISCV_XLEN) -M virt -m 256M \
|
||||
-nographic -kernel $(build_dir)/platform/qemu/virt/firmware/fw_payload.elf
|
||||
|
||||
# Common drivers to enable
|
||||
PLATFORM_IRQCHIP_PLIC=y
|
||||
PLATFORM_SERIAL_UART8250=y
|
||||
@@ -21,10 +25,22 @@ PLATFORM_SYS_CLINT=y
|
||||
# Blobs to build
|
||||
FW_TEXT_START=0x80000000
|
||||
FW_JUMP=y
|
||||
FW_JUMP_ADDR=0x80200000
|
||||
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||
# This needs to be 4MB alligned for 32-bit system
|
||||
FW_JUMP_ADDR=0x80400000
|
||||
else
|
||||
# This needs to be 2MB alligned for 64-bit system
|
||||
FW_JUMP_ADDR=0x80200000
|
||||
endif
|
||||
FW_JUMP_FDT_ADDR=0x82200000
|
||||
FW_PAYLOAD=y
|
||||
FW_PAYLOAD_OFFSET=0x200000
|
||||
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||
# This needs to be 4MB alligned for 32-bit system
|
||||
FW_PAYLOAD_OFFSET=0x400000
|
||||
else
|
||||
# This needs to be 2MB alligned for 64-bit system
|
||||
FW_PAYLOAD_OFFSET=0x200000
|
||||
endif
|
||||
FW_PAYLOAD_FDT_ADDR=0x82200000
|
||||
|
||||
# External Libraries to include
|
||||
|
@@ -5,9 +5,11 @@
|
||||
*
|
||||
* Authors:
|
||||
* Anup Patel <anup.patel@wdc.com>
|
||||
* Nick Kossifidis <mick@ics.forth.gr>
|
||||
*/
|
||||
|
||||
#include <sbi/riscv_encoding.h>
|
||||
#include <sbi/riscv_io.h>
|
||||
#include <sbi/sbi_const.h>
|
||||
#include <sbi/sbi_hart.h>
|
||||
#include <sbi/sbi_platform.h>
|
||||
@@ -19,6 +21,8 @@
|
||||
#define VIRT_HART_STACK_SIZE 8192
|
||||
|
||||
#define VIRT_TEST_ADDR 0x100000
|
||||
#define VIRT_TEST_FINISHER_FAIL 0x3333
|
||||
#define VIRT_TEST_FINISHER_PASS 0x5555
|
||||
|
||||
#define VIRT_CLINT_ADDR 0x2000000
|
||||
|
||||
@@ -122,7 +126,11 @@ static int virt_timer_init(bool cold_boot)
|
||||
|
||||
static int virt_system_down(u32 type)
|
||||
{
|
||||
/* For now nothing to do. */
|
||||
/* Tell the "finisher" that the simulation
|
||||
* was successful so that QEMU exits
|
||||
*/
|
||||
writew(VIRT_TEST_FINISHER_PASS, (void *)VIRT_TEST_ADDR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
588
platform/sifive/fu540/HiFiveUnleashed-MicroSemi-Expansion.dts
Normal file
588
platform/sifive/fu540/HiFiveUnleashed-MicroSemi-Expansion.dts
Normal file
@@ -0,0 +1,588 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <0x2>;
|
||||
#size-cells = <0x2>;
|
||||
compatible = "sifive,fu540g", "sifive,fu500";
|
||||
model = "sifive,hifive-unleashed-a00";
|
||||
|
||||
aliases {
|
||||
serial0 = "/soc/serial@10010000";
|
||||
serial1 = "/soc/serial@10011000";
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "/soc/serial@10010000:115200";
|
||||
};
|
||||
|
||||
firmware {
|
||||
sifive,fsbl = "2018-03-20";
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
timebase-frequency = <0xf4240>;
|
||||
|
||||
cpu@0 {
|
||||
clock-frequency = <0x0>;
|
||||
compatible = "sifive,rocket0", "riscv";
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <0x40>;
|
||||
i-cache-sets = <0x80>;
|
||||
i-cache-size = <0x4000>;
|
||||
next-level-cache = <0x1 0x2>;
|
||||
reg = <0x0>;
|
||||
riscv,isa = "rv64imac";
|
||||
sifive,dtim = <0x3>;
|
||||
sifive,itim = <0x4>;
|
||||
status = "masked";
|
||||
|
||||
interrupt-controller {
|
||||
#interrupt-cells = <0x1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
linux,phandle = <0xf>;
|
||||
phandle = <0xf>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
clock-frequency = <0x0>;
|
||||
compatible = "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <0x40>;
|
||||
d-cache-sets = <0x40>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-tlb-sets = <0x1>;
|
||||
d-tlb-size = <0x20>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <0x40>;
|
||||
i-cache-sets = <0x40>;
|
||||
i-cache-size = <0x8000>;
|
||||
i-tlb-sets = <0x1>;
|
||||
i-tlb-size = <0x20>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <0x1 0x2>;
|
||||
reg = <0x1>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
sifive,itim = <0x5>;
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
|
||||
interrupt-controller {
|
||||
#interrupt-cells = <0x1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
linux,phandle = <0x10>;
|
||||
phandle = <0x10>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu@2 {
|
||||
clock-frequency = <0x0>;
|
||||
compatible = "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <0x40>;
|
||||
d-cache-sets = <0x40>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-tlb-sets = <0x1>;
|
||||
d-tlb-size = <0x20>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <0x40>;
|
||||
i-cache-sets = <0x40>;
|
||||
i-cache-size = <0x8000>;
|
||||
i-tlb-sets = <0x1>;
|
||||
i-tlb-size = <0x20>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <0x1 0x2>;
|
||||
reg = <0x2>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
sifive,itim = <0x6>;
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
|
||||
interrupt-controller {
|
||||
#interrupt-cells = <0x1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
linux,phandle = <0x11>;
|
||||
phandle = <0x11>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu@3 {
|
||||
clock-frequency = <0x0>;
|
||||
compatible = "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <0x40>;
|
||||
d-cache-sets = <0x40>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-tlb-sets = <0x1>;
|
||||
d-tlb-size = <0x20>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <0x40>;
|
||||
i-cache-sets = <0x40>;
|
||||
i-cache-size = <0x8000>;
|
||||
i-tlb-sets = <0x1>;
|
||||
i-tlb-size = <0x20>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <0x1 0x2>;
|
||||
reg = <0x3>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
sifive,itim = <0x7>;
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
|
||||
interrupt-controller {
|
||||
#interrupt-cells = <0x1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
linux,phandle = <0x12>;
|
||||
phandle = <0x12>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu@4 {
|
||||
clock-frequency = <0x0>;
|
||||
compatible = "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <0x40>;
|
||||
d-cache-sets = <0x40>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-tlb-sets = <0x1>;
|
||||
d-tlb-size = <0x20>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <0x40>;
|
||||
i-cache-sets = <0x40>;
|
||||
i-cache-size = <0x8000>;
|
||||
i-tlb-sets = <0x1>;
|
||||
i-tlb-size = <0x20>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <0x1 0x2>;
|
||||
reg = <0x4>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
sifive,itim = <0x8>;
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
|
||||
interrupt-controller {
|
||||
#interrupt-cells = <0x1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
linux,phandle = <0x13>;
|
||||
phandle = <0x13>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x80000000 0x2 0x0>;
|
||||
linux,phandle = <0xe>;
|
||||
phandle = <0xe>;
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <0x2>;
|
||||
#size-cells = <0x2>;
|
||||
compatible = "SiFive,FU540G-soc", "fu500-soc", "sifive-soc", "simple-bus";
|
||||
ranges;
|
||||
|
||||
refclk {
|
||||
#clock-cells = <0x0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <0x1fca055>;
|
||||
clock-output-names = "xtal";
|
||||
linux,phandle = <0x9>;
|
||||
phandle = <0x9>;
|
||||
};
|
||||
|
||||
prci@10000000 {
|
||||
compatible = "sifive,aloeprci0";
|
||||
reg = <0x0 0x10000000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <0x9>;
|
||||
#clock-cells = <0x1>;
|
||||
linux,phandle = <0xa>;
|
||||
phandle = <0xa>;
|
||||
};
|
||||
|
||||
tlclk {
|
||||
compatible = "fixed-factor-clock";
|
||||
clocks = <0xa 0x0>;
|
||||
#clock-cells = <0x0>;
|
||||
clock-div = <0x2>;
|
||||
clock-mult = <0x1>;
|
||||
linux,phandle = <0x16>;
|
||||
phandle = <0x16>;
|
||||
};
|
||||
|
||||
cadence-gemgxl-mgmt@100a0000 {
|
||||
compatible = "sifive,cadencegemgxlmgmt0";
|
||||
reg = <0x0 0x100a0000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
#clock-cells = <0x0>;
|
||||
linux,phandle = <0x14>;
|
||||
phandle = <0x14>;
|
||||
};
|
||||
|
||||
bus-blocker@100b8000 {
|
||||
compatible = "sifive,bus-blocker0";
|
||||
reg = <0x0 0x100b8000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
|
||||
cache-controller@2010000 {
|
||||
cache-block-size = <0x40>;
|
||||
cache-level = <0x2>;
|
||||
cache-sets = <0x800>;
|
||||
cache-size = <0x200000>;
|
||||
cache-unified;
|
||||
compatible = "sifive,ccache0", "cache";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x1 0x2 0x3>;
|
||||
next-level-cache = <0xc 0xd 0xe>;
|
||||
reg = <0x0 0x2010000 0x0 0x1000 0x0 0x8000000 0x0 0x2000000>;
|
||||
reg-names = "control", "sideband";
|
||||
linux,phandle = <0x2>;
|
||||
phandle = <0x2>;
|
||||
};
|
||||
|
||||
cadence-ddr-mgmt@100c0000 {
|
||||
compatible = "sifive,cadenceddrmgmt0";
|
||||
reg = <0x0 0x100c0000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
|
||||
chiplink@40000000 {
|
||||
#address-cells = <0x2>;
|
||||
#size-cells = <0x2>;
|
||||
compatible = "sifive,chiplink", "simple-bus";
|
||||
ranges = <0x0 0x60000000 0x0 0x60000000 0x0 0x20000000 0x30 0x0 0x30 0x0 0x10 0x0 0x0 0x40000000 0x0 0x40000000 0x0 0x20000000 0x20 0x0 0x20 0x0 0x10 0x0>;
|
||||
linux,phandle = <0xd>;
|
||||
phandle = <0xd>;
|
||||
};
|
||||
|
||||
dma@3000000 {
|
||||
#dma-cells = <0x1>;
|
||||
compatible = "riscv,dma0";
|
||||
dma-channels = <0x4>;
|
||||
dma-requests = <0x0>;
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e>;
|
||||
reg = <0x0 0x3000000 0x0 0x100000>;
|
||||
reg-names = "control";
|
||||
riscv,dma-pools = <0x1>;
|
||||
};
|
||||
|
||||
dtim@1000000 {
|
||||
compatible = "sifive,dtim0";
|
||||
reg = <0x0 0x1000000 0x0 0x2000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0x3>;
|
||||
phandle = <0x3>;
|
||||
};
|
||||
|
||||
ememoryotp@10070000 {
|
||||
compatible = "sifive,ememoryotp0";
|
||||
reg = <0x0 0x10070000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
|
||||
error-device@18000000 {
|
||||
compatible = "sifive,error0";
|
||||
reg = <0x0 0x18000000 0x0 0x8000000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0x1>;
|
||||
phandle = <0x1>;
|
||||
};
|
||||
|
||||
ethernet@10090000 {
|
||||
compatible = "cdns,macb";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x35>;
|
||||
reg = <0x0 0x10090000 0x0 0x2000>;
|
||||
reg-names = "control";
|
||||
local-mac-address = [70 b3 d5 92 f0 1f];
|
||||
phy-mode = "gmii";
|
||||
clock-names = "pclk", "hclk", "tx_clk";
|
||||
clocks = <0xa 0x1 0xa 0x1 0x14>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
|
||||
ethernet-phy@0 {
|
||||
reg = <0x0>;
|
||||
reset-gpios = <0x15 0xc 0x1>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio@10060000 {
|
||||
compatible = "sifive,gpio0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16>;
|
||||
reg = <0x0 0x10060000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
gpio-controller;
|
||||
#gpio-cells = <0x2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <0x2>;
|
||||
linux,phandle = <0x15>;
|
||||
phandle = <0x15>;
|
||||
};
|
||||
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <0x15 0xa 0x1>;
|
||||
};
|
||||
|
||||
i2c@10030000 {
|
||||
compatible = "sifive,i2c0", "opencores,i2c-ocores";
|
||||
reg = <0x0 0x10030000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <0x16>;
|
||||
reg-shift = <0x2>;
|
||||
reg-io-width = <0x1>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
};
|
||||
|
||||
interrupt-controller@c000000 {
|
||||
#interrupt-cells = <0x1>;
|
||||
compatible = "riscv,plic0";
|
||||
interrupt-controller;
|
||||
interrupts-extended = <0xf 0xffffffff 0x10 0xffffffff 0x10 0x9 0x11 0xffffffff 0x11 0x9 0x12 0xffffffff 0x12 0x9 0x13 0xffffffff 0x13 0x9>;
|
||||
reg = <0x0 0xc000000 0x0 0x4000000>;
|
||||
reg-names = "control";
|
||||
riscv,max-priority = <0x7>;
|
||||
riscv,ndev = <0x35>;
|
||||
linux,phandle = <0xb>;
|
||||
phandle = <0xb>;
|
||||
};
|
||||
|
||||
itim@1800000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x0 0x1800000 0x0 0x4000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0x4>;
|
||||
phandle = <0x4>;
|
||||
};
|
||||
|
||||
itim@1808000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x0 0x1808000 0x0 0x8000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0x5>;
|
||||
phandle = <0x5>;
|
||||
};
|
||||
|
||||
itim@1810000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x0 0x1810000 0x0 0x8000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0x6>;
|
||||
phandle = <0x6>;
|
||||
};
|
||||
|
||||
itim@1818000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x0 0x1818000 0x0 0x8000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0x7>;
|
||||
phandle = <0x7>;
|
||||
};
|
||||
|
||||
itim@1820000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x0 0x1820000 0x0 0x8000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0x8>;
|
||||
phandle = <0x8>;
|
||||
};
|
||||
|
||||
memory-controller@100b0000 {
|
||||
compatible = "sifive,aloeddr0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x1f>;
|
||||
reg = <0x0 0x100b0000 0x0 0x4000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
|
||||
pci@2000000000 {
|
||||
#address-cells = <0x3>;
|
||||
#interrupt-cells = <0x1>;
|
||||
#size-cells = <0x2>;
|
||||
compatible = "ms-pf,axi-pcie-host";
|
||||
device_type = "pci";
|
||||
bus-range = <0x01 0x7f>;
|
||||
interrupt-map = < 0 0 0 1 0x17 1
|
||||
0 0 0 2 0x17 2
|
||||
0 0 0 3 0x17 3
|
||||
0 0 0 4 0x17 4>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x20>;
|
||||
ranges = <0x2000000 0x0 0x40000000 0x0 0x40000000 0x0 0x20000000>;
|
||||
reg = < 0x20 0x30000000 0x0 0x4000000
|
||||
0x20 0x0 0x0 0x100000 >;
|
||||
reg-names = "control", "apb";
|
||||
|
||||
ms_pcie_intc {
|
||||
#address-cells = <0x0>;
|
||||
#interrupt-cells = <0x1>;
|
||||
interrupt-controller;
|
||||
linux,phandle = <0x17>;
|
||||
phandle = <0x17>;
|
||||
};
|
||||
};
|
||||
|
||||
pinctrl@10080000 {
|
||||
compatible = "sifive,pinctrl0";
|
||||
reg = <0x0 0x10080000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
|
||||
pwm@10020000 {
|
||||
compatible = "sifive,pwm0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x2a 0x2b 0x2c 0x2d>;
|
||||
reg = <0x0 0x10020000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <0x16>;
|
||||
sifive,approx-period = <0xf4240>;
|
||||
#pwm-cells = <0x2>;
|
||||
linux,phandle = <0x18>;
|
||||
phandle = <0x18>;
|
||||
};
|
||||
|
||||
pwm@10021000 {
|
||||
compatible = "sifive,pwm0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x2e 0x2f 0x30 0x31>;
|
||||
reg = <0x0 0x10021000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <0x16>;
|
||||
sifive,approx-period = <0xf4240>;
|
||||
#pwm-cells = <0x2>;
|
||||
};
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
heartbeat {
|
||||
pwms = <0x18 0x0 0x0>;
|
||||
max-brightness = <0xff>;
|
||||
linux,default-trigger = "heartbeat";
|
||||
};
|
||||
|
||||
mtd {
|
||||
pwms = <0x18 0x1 0x0>;
|
||||
max-brightness = <0xff>;
|
||||
linux,default-trigger = "mtd";
|
||||
};
|
||||
|
||||
netdev {
|
||||
pwms = <0x18 0x2 0x0>;
|
||||
max-brightness = <0xff>;
|
||||
linux,default-trigger = "netdev";
|
||||
};
|
||||
|
||||
panic {
|
||||
pwms = <0x18 0x3 0x0>;
|
||||
max-brightness = <0xff>;
|
||||
linux,default-trigger = "panic";
|
||||
};
|
||||
};
|
||||
|
||||
rom@1000 {
|
||||
compatible = "sifive,modeselect0";
|
||||
reg = <0x0 0x1000 0x0 0x1000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
rom@10000 {
|
||||
compatible = "sifive,maskrom0";
|
||||
reg = <0x0 0x10000 0x0 0x8000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
rom@a000000 {
|
||||
compatible = "ucbbar,cacheable-zero0";
|
||||
reg = <0x0 0xa000000 0x0 0x2000000>;
|
||||
reg-names = "mem";
|
||||
linux,phandle = <0xc>;
|
||||
phandle = <0xc>;
|
||||
};
|
||||
|
||||
serial@10010000 {
|
||||
compatible = "sifive,uart0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x4>;
|
||||
reg = <0x0 0x10010000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <0x16>;
|
||||
};
|
||||
|
||||
serial@10011000 {
|
||||
compatible = "sifive,uart0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x5>;
|
||||
reg = <0x0 0x10011000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <0x16>;
|
||||
};
|
||||
|
||||
spi@10040000 {
|
||||
compatible = "sifive,spi0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x33>;
|
||||
reg = <0x0 0x10040000 0x0 0x1000 0x0 0x20000000 0x0 0x10000000>;
|
||||
reg-names = "control", "mem";
|
||||
clocks = <0x16>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
|
||||
flash@0 {
|
||||
compatible = "issi,is25wp256d", "jedec,spi-nor";
|
||||
reg = <0x0>;
|
||||
spi-max-frequency = <0x2faf080>;
|
||||
m25p,fast-read;
|
||||
spi-tx-bus-width = <0x4>;
|
||||
spi-rx-bus-width = <0x4>;
|
||||
};
|
||||
};
|
||||
|
||||
spi@10041000 {
|
||||
compatible = "sifive,spi0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x34>;
|
||||
reg = <0x0 0x10041000 0x0 0x1000 0x0 0x30000000 0x0 0x10000000>;
|
||||
reg-names = "control", "mem";
|
||||
clocks = <0x16>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
};
|
||||
|
||||
spi@10050000 {
|
||||
compatible = "sifive,spi0";
|
||||
interrupt-parent = <0xb>;
|
||||
interrupts = <0x6>;
|
||||
reg = <0x0 0x10050000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <0x16>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
|
||||
mmc@0 {
|
||||
compatible = "mmc-spi-slot";
|
||||
reg = <0x0>;
|
||||
spi-max-frequency = <0x1312d00>;
|
||||
voltage-ranges = <0xce4 0xce4>;
|
||||
disable-wp;
|
||||
gpios = <0x15 0xb 0x1>;
|
||||
};
|
||||
};
|
||||
|
||||
teststatus@4000 {
|
||||
compatible = "sifive,test0";
|
||||
reg = <0x0 0x4000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
};
|
||||
};
|
@@ -9,8 +9,8 @@
|
||||
|
||||
# Compiler flags
|
||||
platform-cppflags-y =
|
||||
platform-cflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-asflags-y =-mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-cflags-y =
|
||||
platform-asflags-y =
|
||||
platform-ldflags-y =
|
||||
|
||||
# Common drivers to enable
|
||||
|
@@ -80,6 +80,7 @@ static void fu540_modify_dt(void *fdt)
|
||||
|
||||
plic_fdt_fixup(fdt, "riscv,plic0");
|
||||
}
|
||||
|
||||
static int fu540_final_init(bool cold_boot)
|
||||
{
|
||||
void *fdt;
|
||||
|
@@ -8,17 +8,29 @@
|
||||
platform-cppflags-y =
|
||||
|
||||
# C Compiler and assembler flags.
|
||||
# For a 64 bits platform, this will likely be:
|
||||
# -mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
# For a 32 bits platform, this will likely be:
|
||||
# -mabi=lp32 -march=rv32imafdc -mcmodel=medlow
|
||||
platform-cflags-y = -mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-asflags-y = -mabi=lp64 -march=rv64imafdc -mcmodel=medany
|
||||
platform-cflags-y =
|
||||
platform-asflags-y =
|
||||
|
||||
# Linker flags: additional libraries and object files that the platform
|
||||
# code needs can be added here
|
||||
platform-ldflags-y =
|
||||
|
||||
#
|
||||
# Command for platform specific "make run"
|
||||
# Useful for development and debugging on plaftform simulator (such as QEMU)
|
||||
#
|
||||
# platform-runcmd = your_platform_run.sh
|
||||
|
||||
#
|
||||
# Platform RISC-V XLEN, ABI, ISA and Code Model configuration.
|
||||
# These are optional parameters but platforms can optionaly provide it.
|
||||
# Some of these are guessed based on GCC compiler capabilities
|
||||
#
|
||||
# PLATFORM_RISCV_XLEN = 64
|
||||
# PLATFORM_RISCV_ABI = lp64
|
||||
# PLATFORM_RISCV_ISA = rv64imafdc
|
||||
# PLATFORM_RISCV_CODE_MODEL = medany
|
||||
|
||||
#
|
||||
# OpenSBI implements generic drivers for some common generic hardware. The
|
||||
# drivers currently available are the RISC-V Platform Level Interrupt
|
||||
@@ -39,7 +51,13 @@ FW_TEXT_START=0x80000000
|
||||
# as needed.
|
||||
#
|
||||
FW_JUMP=<y|n>
|
||||
FW_JUMP_ADDR=0x80200000
|
||||
# This needs to be 4MB aligned for 32-bit support
|
||||
# This needs to be 2MB aligned for 64-bit support
|
||||
# ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||
# FW_JUMP_ADDR=0x80400000
|
||||
# else
|
||||
# FW_JUMP_ADDR=0x80200000
|
||||
# endif
|
||||
# FW_JUMP_FDT_ADDR=0x82200000
|
||||
|
||||
#
|
||||
@@ -48,7 +66,13 @@ FW_JUMP_ADDR=0x80200000
|
||||
# as needed.
|
||||
#
|
||||
FW_PAYLOAD=<y|n>
|
||||
# This needs to be 4MB aligned for 32-bit support
|
||||
# This needs to be 2MB aligned for 64-bit support
|
||||
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||
FW_PAYLOAD_OFFSET=0x400000
|
||||
else
|
||||
FW_PAYLOAD_OFFSET=0x200000
|
||||
endif
|
||||
# FW_PAYLOAD_ALIGN=0x1000
|
||||
# FW_PAYLOAD_PATH="path to next boot stage binary image file"
|
||||
# FW_PAYLOAD_FDT_PATH="path to platform flattened device tree file"
|
||||
|
@@ -27,7 +27,7 @@ static int platform_early_init(bool cold_boot)
|
||||
/*
|
||||
* Platform final initialization.
|
||||
*/
|
||||
static int platform final_init(bool cold_boot);
|
||||
static int platform_final_init(bool cold_boot)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -215,7 +215,7 @@ struct sbi_platform platform = {
|
||||
.hart_stack_size = 4096,
|
||||
.disabled_hart_mask = 0,
|
||||
|
||||
.early_init = platform_final_init,
|
||||
.early_init = platform_early_init,
|
||||
.final_init = platform_final_init,
|
||||
|
||||
.pmp_region_count = platform_pmp_region_count,
|
||||
@@ -236,7 +236,7 @@ struct sbi_platform platform = {
|
||||
.timer_event_start = platform_timer_event_start,
|
||||
.timer_event_stop = platform_timer_event_stop,
|
||||
|
||||
.system_reboot = platform_system_down,
|
||||
.system_shutdown = platform_system_down
|
||||
.system_reboot = platform_system_reboot,
|
||||
.system_shutdown = platform_system_shutdown
|
||||
};
|
||||
|
||||
|
135
scripts/create-binary-archive.sh
Executable file
135
scripts/create-binary-archive.sh
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/bin/bash
|
||||
|
||||
function usage()
|
||||
{
|
||||
echo "Usage:"
|
||||
echo " $0 [options]"
|
||||
echo "Options:"
|
||||
echo " -h Display help or usage"
|
||||
echo " -p <opensbi_source_path> OpenSBI source path"
|
||||
echo " -o <build_output_path> Build output path"
|
||||
echo " -d Build and install documentation"
|
||||
echo " -t Build only with no archive created"
|
||||
echo " -j <num_threads> Number of threads for Make (Default: 1)"
|
||||
echo " -s <archive_suffix> Archive name suffix (Default: unknown)"
|
||||
echo " -x <riscv_xlen> RISC-V XLEN (Default: 64)"
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Command line options
|
||||
BUILD_NUM_THREADS=1
|
||||
BUILD_OUTPUT_PATH="$(pwd)/build"
|
||||
BUILD_OPENSBI_SOURCE_PATH="$(pwd)"
|
||||
BUILD_DOCS="no"
|
||||
BUILD_ONLY="no"
|
||||
BUILD_ARCHIVE_SUFFIX="unknown"
|
||||
BUILD_RISCV_XLEN=64
|
||||
|
||||
while getopts "hdtj:o:p:s:x:" o; do
|
||||
case "${o}" in
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
d)
|
||||
BUILD_DOCS="yes"
|
||||
;;
|
||||
t)
|
||||
BUILD_ONLY="yes"
|
||||
;;
|
||||
j)
|
||||
BUILD_NUM_THREADS=${OPTARG}
|
||||
;;
|
||||
o)
|
||||
BUILD_OUTPUT_PATH=${OPTARG}
|
||||
;;
|
||||
p)
|
||||
BUILD_OPENSBI_SOURCE_PATH=${OPTARG}
|
||||
;;
|
||||
s)
|
||||
BUILD_ARCHIVE_SUFFIX=${OPTARG}
|
||||
;;
|
||||
x)
|
||||
BUILD_RISCV_XLEN=${OPTARG}
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ -z "${BUILD_OPENSBI_SOURCE_PATH}" ]; then
|
||||
echo "Must specify OpenSBI source path"
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ ! -d "${BUILD_OPENSBI_SOURCE_PATH}" ]; then
|
||||
echo "OpenSBI source path does not exist"
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -z "${BUILD_ARCHIVE_SUFFIX}" ]; then
|
||||
echo "Archive suffice cannot be empty"
|
||||
usage
|
||||
fi
|
||||
|
||||
# Get version of OpenSBI
|
||||
BUILD_VERSION_MAJOR=$(grep MAJOR "${BUILD_OPENSBI_SOURCE_PATH}/include/sbi/sbi_version.h" | sed 's/.*MAJOR.*\([0-9][0-9]*\)/\1/')
|
||||
BUILD_VERSION_MINOR=$(grep MINOR "${BUILD_OPENSBI_SOURCE_PATH}/include/sbi/sbi_version.h" | sed 's/.*MINOR.*\([0-9][0-9]*\)/\1/')
|
||||
|
||||
# Setup archive name
|
||||
BUILD_ARCHIVE_NAME="opensbi-${BUILD_VERSION_MAJOR}.${BUILD_VERSION_MINOR}-rv${BUILD_RISCV_XLEN}-${BUILD_ARCHIVE_SUFFIX}"
|
||||
|
||||
# Setup platform list
|
||||
case "${BUILD_RISCV_XLEN}" in
|
||||
32)
|
||||
# Setup 32bit platform list
|
||||
BUILD_PLATFORM_SUBDIR=("qemu/virt")
|
||||
BUILD_PLATFORM_SUBDIR+=("qemu/sifive_u")
|
||||
;;
|
||||
64)
|
||||
# Setup 64bit platform list
|
||||
BUILD_PLATFORM_SUBDIR=("qemu/virt")
|
||||
BUILD_PLATFORM_SUBDIR+=("qemu/sifive_u")
|
||||
BUILD_PLATFORM_SUBDIR+=("sifive/fu540")
|
||||
BUILD_PLATFORM_SUBDIR+=("kendryte/k210")
|
||||
;;
|
||||
*)
|
||||
echo "Invalid RISC-V XLEN"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
# Ensure output directory is present
|
||||
mkdir -p "${BUILD_OUTPUT_PATH}"
|
||||
|
||||
# Build and install generic library
|
||||
echo "Build and install generic library XLEN=${BUILD_RISCV_XLEN}"
|
||||
echo ""
|
||||
make -C "${BUILD_OPENSBI_SOURCE_PATH}" O="${BUILD_OUTPUT_PATH}" I="${BUILD_OUTPUT_PATH}/${BUILD_ARCHIVE_NAME}" PLATFORM_RISCV_XLEN="${BUILD_RISCV_XLEN}" install_libsbi -j "${BUILD_NUM_THREADS}"
|
||||
echo ""
|
||||
|
||||
# Build and install relevant platforms
|
||||
for INDEX in $(seq 0 1 "$(expr ${#BUILD_PLATFORM_SUBDIR[*]} - 1)")
|
||||
do
|
||||
echo "Build and install PLATFORM=${BUILD_PLATFORM_SUBDIR[${INDEX}]} XLEN=${BUILD_RISCV_XLEN}"
|
||||
echo ""
|
||||
make -C "${BUILD_OPENSBI_SOURCE_PATH}" O="${BUILD_OUTPUT_PATH}" I="${BUILD_OUTPUT_PATH}/${BUILD_ARCHIVE_NAME}" PLATFORM="${BUILD_PLATFORM_SUBDIR[${INDEX}]}" PLATFORM_RISCV_XLEN="${BUILD_RISCV_XLEN}" install_libplatsbi install_firmwares -j "${BUILD_NUM_THREADS}"
|
||||
echo ""
|
||||
done
|
||||
|
||||
# Build and install docs
|
||||
if [ "${BUILD_DOCS}" == "yes" ]; then
|
||||
echo "Build and install docs"
|
||||
echo ""
|
||||
make -C "${BUILD_OPENSBI_SOURCE_PATH}" O="${BUILD_OUTPUT_PATH}" I="${BUILD_OUTPUT_PATH}/${BUILD_ARCHIVE_NAME}" install_docs
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Create archive file
|
||||
if [ "${BUILD_ONLY}" == "no" ]; then
|
||||
echo "Create archive ${BUILD_ARCHIVE_NAME}.tar.xz"
|
||||
echo ""
|
||||
tar -C "${BUILD_OUTPUT_PATH}" -cJvf "${BUILD_OUTPUT_PATH}/${BUILD_ARCHIVE_NAME}.tar.xz" "${BUILD_ARCHIVE_NAME}"
|
||||
echo ""
|
||||
fi
|
Reference in New Issue
Block a user