52 Commits
v0.1 ... v0.3

Author SHA1 Message Date
Anup Patel
ca20ac0cd4 include: Bump-up version to 0.3
This patch updates OpenSBI version to 0.3 as part of
release preparation.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-26 22:24:59 +05:30
Alistair Francis
42e9ad556d Makefile: Set the platform variables before parsing the platforms
Ensure the platform variable PLATFORM_RISCV_XLEN is set before we parse
the platform files.

This fixes the 32-bit openSBI FW_JUMP_ADDR.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-26 19:23:26 +05:30
Anup Patel
a1ffba1ac9 include: Bump-up version to 0.2
This patch increases OpenSBI version to 0.2.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-22 11:33:22 +05:30
Anup Patel
d022c5d3ae scripts: Add script for creating binary archive
This patch adds scripts/create-binary-archive.sh which helps
us create a common tarball containing headers, static library
and firmware ELFs for all platforms.

This script can be used for release purpose OR for compile
testing all platforms.

Example usage commands are as follows:

1) Binary release archive for 32bit systems
./scripts/create-binary-archive.sh -s "bin" -x 32 -d

2) Binary release archive for 64bit systems
./scripts/create-binary-archive.sh -s "bin" -d

3) Compile test for 32bit systems
./scripts/create-binary-archive.sh -x 32 -t

4) Compile test for 64bit systems
./scripts/create-binary-archive.sh -t

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-22 11:28:41 +05:30
Anup Patel
889e746fd7 Makefile: Rename compile_ld() to compile_elf()
The compile_ld() is actually used to create ELF files so
the name is misleading hence this patch renames it to
compile_elf(). We also rename LDFLAGS to ELFFLAGS because
these will be used for ELF creation only.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-22 11:28:41 +05:30
Atish Patra
fde1c42db3 doc: Fix root partition details for fu540.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-22 09:58:55 +05:30
Anup Patel
122d00ba67 firmware: Improve low-level trap handler for M-mode to M-mode traps
This patch extends our low-level trap handler in fw_base.S for
handling M-mode to M-mode traps without overwritting stack.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-20 12:02:40 +05:30
Anup Patel
ce6189f7a5 include: Add PRILX define to help print unsigned long
The unsigned long is always machine word size. This means it is
4 bytes on 32bit system and 8 bytes on 64bit system.

This patch adds PRILX define for sbi_printf() which will help us
print unsigned long without worrying whether it is 32bit or 64bit
system.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-20 12:02:40 +05:30
Sergi Granell
db5b25af49 template: Fix some callback names 2019-02-19 18:22:58 +05:30
Sergi Granell
72a8272066 template: Remove trailing ';' 2019-02-19 18:22:58 +05:30
Sergi Granell
4b92518959 template: Fix typo in platform_final_init
There was a space instead of '_' in the function `platform_final_init`.
2019-02-19 18:22:58 +05:30
Atish Patra
d046974cf6 docs: Update unleashed platform guide.
Following updates to fu540 platform guide.

1. Update a section about flashing the firmware binary
to sdcard with correct partition identifier.
2. Refer the individual payload section.
3. Update uboot booting section.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-19 18:22:26 +05:30
Atish Patra
0db43770b3 docs: Add a payload section describing different payloads.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-19 18:22:26 +05:30
Atish Patra
3265310b05 docs: Wrap text to 80 columns.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-19 18:22:26 +05:30
Atish Patra
34bf6d4a0f docs: Update about toolchain section.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-19 18:22:26 +05:30
Anup Patel
6a3dc84f66 Makefile: Use sed instead of awk to parse OpenSBI version
This patch replaces use of awk with sed in top-level makefile
to parse OpenSBI version from include/sbi/sbi_version.h.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-19 13:47:18 +05:30
Anup Patel
f4a17177ce Makefile: Fix error evaluating OPENSBI_CC_XLEN
We get following error evaluating OPENSBI_CC_XLEN on
Ubuntu-18.04:
/bin/sh: 1: Bad substitution

This patch fixes above error by using "awk" in string
assigned to OPENSBI_CC_XLEN and it also moves "Setup
compilation commands" before OPENSBI_CC_XLEN.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-19 13:47:18 +05:30
Anup Patel
4e774f5470 lib: Fix mask shift in sbi_ipi_send_many()
The mask shift in for-loop of sbi_ipi_send_many() is
broken with commit 918c1354b7
("lib: Improve delivery of SBI_IPI_EVENT_HALT")

This patch fix it.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-18 18:39:02 +05:30
Nick Kossifidis
148423d141 lib: Fix small typo on sbi_ipi.c 2019-02-18 09:21:58 +05:30
Nick Kossifidis
918c1354b7 lib: Improve delivery of SBI_IPI_EVENT_HALT
When sbi_ipi_send_many gets called with the current hartid
included on pmask (or when pmask is NULL), and we send
a HALT event, since the for loop works sequentially over
all hartids on the mask, we may send a HALT event to the
current hart before the loop finishes. So we will halt
the current hart before it can deliver a HALT IPI to the
rest and some harts will remain active.

Make sure we send an IPI to the current hart after we've
finished with everybody else.

Signed-off-by: Nick Kossifidis <mick@ics.forth.gr>
2019-02-18 09:21:58 +05:30
Nick Kossifidis
51e543511a platform: qemu-virt: Implement system shutdown
In order for QEMU to be compatible with Spike, it implements
a simple protocol used for reporting back the simulation's
status, through the memory-mapped "test finisher" device. We
use that protocol to make QEMU exit on system shutdown.

Signed-off-by: Nick Kossifidis <mick@ics.forth.gr>
2019-02-18 09:21:58 +05:30
Nick Kossifidis
b44878b773 lib: Send IPI for all harts to hang on system shutdown
In case the platform specific method for shutting down
the system fails (or is not implemented), at least make
sure that all harts hang instead of just the current hart.

Signed-off-by: Nick Kossifidis <mick@ics.forth.gr>
2019-02-18 09:21:58 +05:30
Alistair Francis
16426420b5 Makefile: Fix the assignment of OPENSBI_CC_XLEN
Previously OPENSBI_CC_XLEN was not being correctly assigned either 32 or
64. It also was not assigned before config.mk was parsed. Ensure that it
will always be assigned.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-17 16:21:18 +05:30
Alistair Francis
3c53950b00 Merge pull request #59 from avpatel/make-run
Add 'make run' command for platform specific run
2019-02-15 15:02:19 -08:00
Olof Johansson
868e20df8b Makefile: Add 'make run' command for platform specific run
Makes for easy and quick build-run one-stop command.

For now only added for qemu targets. It can be added for
any platform having simulator/emulator (such as QEMU).

Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-15 15:54:44 +05:30
Alistair Francis
5cd69a496b docs: fu540: Add steps for the Microsemi Expansion board
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-15 09:56:47 +05:30
Alistair Francis
ae4e0de700 platform: fu540: Initial commit of Microsemi device tree
Add a device tree for th HiFive Unleashed that includes the Microsemi
PCIe root complex.

Once we have support for u-boot and in tree Linux kernel device trees
this device tree should be removed.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-15 09:56:47 +05:30
Alistair Francis
afbb0cdf80 platform: fu540: Fix missing newline
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-15 09:56:47 +05:30
Alistair Francis
d369e721e8 firmware: Ensure the payloads are 4 bit alligned
We expect the payloads to be 4 bit alligned as we later AND them
with ~0xf. As most of the addresses are manually specified we don't
really need this, but better to be over cautious.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-15 09:56:47 +05:30
Nick Kossifidis
286b80768b Makefile: Make sure ld is always aware of the target abi/emulation
On Makefile merge_objs calls ld without providing any hints
on the target so on a multilib toolchain for example it will
always pick the default one (elf64-littleriscv) which will
then result a failure when compiling on RV32 since the objects
will be 32bits and the target will be 64bits. The same happens
on compile_ld that calls gcc without CFLAGS so it doesn't
get mabi/march.

With this patch OpenSBI compiles on RV32 (PLATFORM_RISCV_XLEN=32),
I tested fw_jump.elf on qemu (but it doesn't boot the kernel yet
-bbl also doesn't boot the kernel so it may be something else).

Signed-off-by: Nick Kossifidis <mickflemm@gmail.com>
2019-02-15 08:55:45 +05:30
Atish Patra
35e617385f firmware: Use CSR_<FOO> instead of <foo> for csr*
Some older toolchains may not have all the csr's defined. Update all
the csr functions to use the CSR_ #define values instead of the
toolchain defined values.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-14 09:31:18 +05:30
Atish Patra
28d1dd2430 platform: Use CSR_<FOO> instead of <foo> for csr_*()
Some older toolchains may not have all the csr's defined. Update all
the csr functions to use the CSR_ #define values instead of the
toolchain defined values.

Suggested-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-14 09:31:18 +05:30
Atish Patra
70a474d2c2 lib: Use CSR_<FOO> instead of <foo> for csr_*()
Some older toolchains may not have all the csr's defined. Update all
the csr functions to use the CSR_ #define values instead of the
toolchain defined values.

Suggested-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-14 09:31:18 +05:30
Atish Patra
4cb4d46875 docs: Use normal hyphen instead of non-breaking hyphen
Usage non-breaking hyphen breaks make docs as doxygen doesn't know
how to handle this.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-02-14 09:29:56 +05:30
Anup Patel
c5467fce46 Makefile: Set ABI, ISA and Code Model in top-level make
This patch introduces following optional PLATFORM options:
PLATFORM_RISCV_XLEN -> RISC-V register width
PLATFORM_RISCV_ABI -> RISC-V GCC ABI
PLATFORM_RISCV_ISA -> RISC-V GCC ISA string
PLATFORM_RISCV_CODE_MODEL -> RISC-V GCC Code Model

If the above options are not provided by platform config.mk
or by command-line parameters then:
1. PLATFORM_RISCV_XLEN will be determined using toolchain
capability
2. PLATFORM_RISCV_ABI, PLATFORM_RISCV_ISA, and
PLATFORM_RISCV_CODE_MODEL is set to value best suited for
generic libsbi.a

As a result of these optional PLATFORM options, the
platform-cflags-y and platform-asflags-y is further
simplified for platform config.mk.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-12 15:55:15 +05:30
Anup Patel
84169e2e69 platform: qemu: Set FW_JUMP_ADDR and FW_PAYLOAD_OFFSET as-per XLEN
The current 4MB aligned FW_JUMP_ADDR and FW_PAYLOAD_OFFSET breaks
U-Boot on QEMU virt and sifive_u machines.

Instead of using 4MB aligned for both 32bit and 64bit systems, we
use different values based compiler XLEN. Another advantage of this
approach will be that our fw_payload.bin will smaller for 64bit
systems.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-12 15:55:15 +05:30
Anup Patel
ab12d6ef8f platform: template: Improve comments for FW_JUMP_ADDR and FW_PAYLOAD_OFFSET
Both FW_JUMP_ADDR and FW_PAYLOAD_OFFSET, should be:
1. 4MB aligned for 32bit system
2. 2MB aligned for 64bit system

Explicitly specify the above details in config.mk comments
for template platform.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
2019-02-12 15:55:15 +05:30
Damien Le Moal
01fe779113 docs: improve library usage document
Clarify the libraries descriptions.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
2019-02-08 09:36:06 +05:30
Damien Le Moal
b1b7e49c63 docs: platform guide updates
Clarify platform support description.
Also fix some Typos, grammar and document style.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
2019-02-08 09:36:06 +05:30
Damien Le Moal
7b3da0ef0d top: README.md updates
Clarify OpenSBI components explanation.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
2019-02-08 09:36:06 +05:30
Alistair Francis
76c759df6a Makefile: Ensure lgcc is included
This fixes errors like this:
  undefined reference to `__umoddi3'
when buildilng for 32-bit systems

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Alistair Francis
4f32b13802 firmware: Use lw instead of lwu for 32-bit architectures
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Alistair Francis
f9b033e577 platform: clint: Allow running on 32-bit systems
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Alistair Francis
f4cf6da7ff sbi_emulate_csr: Shift sbi_timer_value directly
csr_val is a tartget length based variable, so on 32-bit devices it's
only 32-bits. To avoid clearing the entire register perform both steps
in a single line.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Alistair Francis
9f44d07df5 platform: qemu/virt: Move kernel start address to 4MB alligned
In order to support 32-bit guests move the start address to a 4MB
allignment. As 64-bit kernels have a requirement on being 2MB alligned
let's just make this the default for both 32 and 64 bit kernels.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Alistair Francis
a5f06b30c1 platform: template: Move kernel start address to 4MB alligned
In order to support 32-bit guests move the start address to a 4MB
allignment. As 64-bit kernels have a requirement on being 2MB alligned
let's just make this the default for both 32 and 64 bit kernels.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Alistair Francis
5a91fec1a8 platform/qemu/virt: Dynamically calculate xlen
The QEMU virt machine can be either 32 or 66 bit. Don't hard code the
CPU bit length and instead let the compiler determine it.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Alistair Francis
b4c72deba9 sbi_ecall: Fix logical OR to be bitwise OR
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2019-02-08 09:18:46 +05:30
Andreas Schwab
93f806af32 firwmare: don't expand macros in FW_PAYLOAD_PATH
Signed-off-by: Andreas Schwab <schwab@suse.de>
2019-02-06 10:39:17 +05:30
Andreas Schwab
190a80dc40 Makefile: don't disable built-in variables
Signed-off-by: Andreas Schwab <schwab@suse.de>
2019-02-06 10:39:17 +05:30
Olof Johansson
9a72e5006c Makefile: Don't rely on "echo -n"
Turns out it doesn't behave as expected on MacOS, it doesn't honor
-n and echoes that to the file instead. Add a slash and just let
the newline be there instead.

Signed-off-by: Olof Johansson <olof@lixom.net>
2019-02-05 18:53:27 +05:30
Olof Johansson
c0addfe751 riscv_asm.h: Use CSR_<FOO> instead of <foo> for csr_read()
Some toolchains might not have all the CSRs available (as seen with
GCC 7.2). So, instead use the defined CSR_ values.

Signed-off-by: Olof Johansson <olof@lixom.net>
2019-02-05 18:53:09 +05:30
41 changed files with 1494 additions and 347 deletions

110
Makefile
View File

@@ -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

View File

@@ -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

View File

@@ -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.

View 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.

View 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.

View File

@@ -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()*.

View File

@@ -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"

View File

@@ -1,6 +1,6 @@
SiFive FU540 SoC Platform
==========================
The FU540-C000 is the worlds first 4+1 64-bit RISCV SoC from SiFive.
The FU540-C000 is the worlds 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"
```

View File

@@ -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.

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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)

View File

@@ -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() \

View File

@@ -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

View File

@@ -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));

View File

@@ -11,6 +11,6 @@
#define __SBI_VERSION_H__
#define OPENSBI_VERSION_MAJOR 0
#define OPENSBI_VERSION_MINOR 1
#define OPENSBI_VERSION_MINOR 3
#endif

View File

@@ -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

View File

@@ -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",

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View 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";
};
};
};

View File

@@ -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

View File

@@ -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;

View File

@@ -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"

View 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
View 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