initial commit

This commit is contained in:
Jose Martins 2021-04-03 16:08:01 +01:00
commit 18e02bf834
No known key found for this signature in database
GPG Key ID: 3563CF212152F2F5
71 changed files with 13246 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
wrkdir*

347
COPYING Normal file
View File

@ -0,0 +1,347 @@
This guide is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as published by
the Free Software Foundation described below.
-------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

121
Makefile Normal file
View File

@ -0,0 +1,121 @@
SHELL:=bash
bao_demos:=$(abspath .)
platform_dir:=$(bao_demos)/platforms/$(PLATFORM)
demo_dir:=$(bao_demos)/demos/$(DEMO)
SHELL:=/bin/bash
ifeq ($(filter clean distclean, $(MAKECMDGOALS)),)
ifndef CROSS_COMPILE
$(error No CROSS_COMPILE prefix defined)
endif
endif
ifeq ($(filter distclean, $(MAKECMDGOALS)),)
ifndef PLATFORM
$(error No target PLATFORM defined)
endif
ifeq ($(wildcard $(platform_dir)),)
$(error Target platform $(PLATFORM) is not supported)
endif
ifndef DEMO
$(error No target DEMO defined.)
endif
ifeq ($(wildcard $(demo_dir)),)
$(error Target demo $(DEMO) is not supported)
endif
ifeq ($(wildcard $(demo_dir)/configs/$(PLATFORM).c),)
$(error The $(DEMO) demo is not supported by the $(PLATFORM) platform)
endif
endif
# utility functions
ifeq ($(NO_INSTRUCTIONS),)
define print-instructions
@for i in {1..80}; do printf "-"; done ; printf "\n"
@cat $(strip $1) | sed -n '/instruction#$(strip $2)/,/instruction#./p' |\
sed '1d;$d' | head -n -1 |\
sed -r -e 's/(.*)\[(.*)\]\((http.*)\)(.*)/\1\2 (\3)\4/g' |\
sed -r -e 's/(.*)\[(.*)\]\((\.\/(\.\.\/)*)(.*)\)(.*)/\1\2 (\.\/\5)\6/g' |\
pandoc --to plain --wrap=preserve | $(environment) envsubst
-@if [ $(strip $3) = false ];\
then printf "\n(Press return to continue)\r"; read -s dummy;\
else for i in {1..80}; do printf "-"; done ; printf "\n"; fi
endef
endif
# setup working directories
wrkdir:=$(bao_demos)/wrkdir
wrkdir_src:=$(wrkdir)/srcs
wrkdir_imgs:=$(wrkdir)/imgs
wrkdir_plat_imgs:=$(wrkdir_imgs)/$(PLATFORM)
wrkdir_demo_imgs:=$(wrkdir_plat_imgs)/$(DEMO)
wrkdirs=$(wrkdir) $(wrkdir_src) $(wrkdir_plat_imgs) $(wrkdir_demo_imgs)
environment:=BAO_DEMOS=$(bao_demos)
environment+=BAO_DEMOS_WRKDIR=$(wrkdir)
environment+=BAO_DEMOS_WRKDIR_SRC=$(wrkdir_src)
environment+=BAO_DEMOS_WRKDIR_PLAT=$(wrkdir_plat_imgs)
environment+=BAO_DEMOS_WRKDIR_IMGS=$(wrkdir_demo_imgs)
environment+=BAO_DEMOS_SDCARD_DEV=/dev/yoursdcarddev
environment+=BAO_DEMOS_SDCARD=/media/$$USER/boot
all: platform
bao_repo:=https://github.com/bao-project/bao-hypervisor
bao_version:=master
bao_src:=$(wrkdir_src)/bao
bao_cfg_repo:=$(wrkdir_demo_imgs)/config
wrkdirs+=$(bao_cfg_repo)
bao_cfg:=$(bao_cfg_repo)/$(DEMO).c
bao_image:=$(wrkdir_demo_imgs)/bao.bin
include $(platform_dir)/make.mk
include $(demo_dir)/make.mk
ifeq ($(filter clean distclean, $(MAKECMDGOALS)),)
$(shell mkdir -p $(wrkdirs))
endif
guests: $(guest_images)
$(bao_src):
git clone --branch $(bao_version) $(bao_repo) $(bao_src)
$(bao_cfg): | $(bao_cfg_repo)
cp -L $(bao_demos)/demos/$(DEMO)/configs/$(PLATFORM).c $(bao_cfg)
bao $(bao_image): $(guest_images) $(bao_cfg) $(bao_src)
$(MAKE) -C $(bao_src)\
PLATFORM=$(PLATFORM)\
CONFIG_REPO=$(bao_cfg_repo)\
CONFIG=$(DEMO) CONFIG_BUILTIN=y\
CPPFLAGS=-DBAO_DEMOS_WRKDIR_IMGS=$(wrkdir_demo_imgs)
cp $(bao_src)/bin/$(PLATFORM)/builtin-configs/$(DEMO)/bao.bin $(bao_image)
bao_clean:
$(MAKE) -C $(bao_src) clean\
PLATFORM=$(PLATFORM)\
CONFIG_REPO=$(bao_cfg_repo)\
CONFIG=$(DEMO)
platform: $(bao_image)
guests_clean bao_clean platform_clean:
clean: guests_clean bao_clean platform_clean
-@rm -rf $(wrkdir)/imgs/$(PLAT)/$(DEMO)
distclean:
rm -rf $(wrkdir)
.PHONY: all clean guests bao paltform
.NOTPARALLEL:

254
README.md Normal file
View File

@ -0,0 +1,254 @@
# Bao Hypervisor Demo Guide
This tutorial provides a step-by-step guide on how to run different demo
configurations of the Bao hypervisor featuring multiple guest operating
systems and targeting several supported platforms. The available demos are:
* [Single-guest Baremetal](demos/baremetal/README.md)
* [Dual-guest Linux+FreeRTOS](demos/linux+freertos/README.md)
---
**NOTE**
This tutorial assumes you are running a standard Linux distro (e.g.
Debian) and using bash.
If you have any doubts, questions, feedback, or suggestions regarding
this guide, please raise an issue in GitHub or contact us via
info@bao-project.org.
If you run into any problem while following this guide, we ask you to raise
an issue on Github, but first please make sure you are using the same or
newer/compatible versions of the tools and software listed in
[Appendix II](#Appendix-II) (not all are needed for all target platforms).
---
## -1. Install dependencies
```
sudo apt install ninja-build u-boot-tools pandoc
```
## 0. Download and setup the toolchain
Download the latest bare-metal cross-compile toolchain for your target
architecture:
a) For Armv8-A, use the **aarch64-none-elf-** toolchain.
Download it from the [Arm Developer's][arm-toolchains] website.
b) For RISC-V, use the **riscv64-unknown-elf-** toolchain.
Download it from [SiFive's Freedom Tools][riscv-toolchains] github reposiroty.
Install the toolchain. Then, set the **CROSS_COMPILE** environment variable
with the reference toolchain prefix path:
```
export CROSS_COMPILE=/path/to/toolchain/install/dir/bin/your-toolchain-prefix-
```
## 1. Setup base environment
Clone this repo and cd to it:
```
git clone https://github.com/bao-project/bao-demos
cd bao-demos
```
Depending on your target platform and demo, setup the **PLATFORM** and **DEMO**
environment variables using the IDs in [Appendix I](#Appendix-I). For example,
for a system configuration targeting the ZCU102 board and featuring a dual-guest
Linux+FreeRTOS demo:
```
export PLATFORM=zcu102
export DEMO=linux+freertos
```
At this point you have two options:
## A) Use automated make
Just execute:
```
make -j$(nproc)
```
And all the needed source and images will be automatically downloaded and built.
The makefiles will also print some instructions for you to carry out when it is
not possible to automate a given step for some reason (e.g. download behind
authentication wall). It will also print the instructions on how to deploy the
images on your target platform. To quiet instructions pass `NO_INSTRUCTIONS=1`
to make.
---
**WARNING**
The makefiles will automatically accept EULAs on your behalf for some of the
downloaded firmware. If you wish to be prompted for to accept them manually,
pass `ALWAYS_ASK=1` to make.
---
If you are targetting an emulator platform like QEMU, after building
you can start it with:
```
make run
```
In this case, if you don't have qemu for the target architecture installed,
it will build it for you.
---
**NOTE**
These makefiles are intended **ONLY to automate** this guide's steps; not to be
used as any kind of build system during development.
---
## B) Follow the step-by-step guide
As an alternative we provide a step-by-step guide you can follow to build all
the necessary software and deploy it to your target platform.
### B.1) Setup ARCH manually
Setup the *ARCH* environment variable manually according to the tables
[Appendix I](#Appendix-I). For example, for the ZCU102 plataform:
```
export ARCH=aarch64
```
### B.1) Create working directory
Create the working directories where you'll place the needed source code and
final images:
```
export BAO_DEMOS=$(realpath .)
export BAO_DEMOS_WRKDIR=$BAO_DEMOS/wrkdir
export BAO_DEMOS_WRKDIR_SRC=$BAO_DEMOS_WRKDIR/srcs
export BAO_DEMOS_WRKDIR_PLAT=$BAO_DEMOS_WRKDIR/imgs/$PLATFORM
export BAO_DEMOS_WRKDIR_IMGS=$BAO_DEMOS_WRKDIR_PLAT/$DEMO
mkdir -p $BAO_DEMOS_WRKDIR
mkdir -p $BAO_DEMOS_WRKDIR_SRC
mkdir -p $BAO_DEMOS_WRKDIR_IMGS
```
### B.2) Build guests
Build guests according to the target demo:
* [Single Baremetal Guest](demos/baremetal/README.md)
* [Dual-guest Linux+FreeRTOS](demos/linux+freertos/README.md)
### B.3) Build Bao
Clone Bao's repo to the the working directory:
```
export BAO_DEMOS_BAO=$BAO_DEMOS_WRKDIR_SRC/bao
git clone https://github.com/bao-project/bao-hypervisor $BAO_DEMOS_BAO\
--branch master
```
Copy your config to the working directory:
```
mkdir -p $BAO_DEMOS_WRKDIR_IMGS/config
cp -L $BAO_DEMOS/demos/$DEMO/configs/$PLATFORM.c\
$BAO_DEMOS_WRKDIR_IMGS/config/$DEMO.c
```
Build it:
```
make -C $BAO_DEMOS_BAO\
PLATFORM=$PLATFORM\
CONFIG_REPO=$BAO_DEMOS_WRKDIR_IMGS/config\
CONFIG=$DEMO\
CONFIG_BUILTIN=y\
CPPFLAGS=-DBAO_DEMOS_WRKDIR_IMGS=$BAO_DEMOS_WRKDIR_IMGS
```
And copy the resulting binary into the final image directory:
```
cp $BAO_DEMOS_BAO/bin/$PLATFORM/builtin-configs/$DEMO/bao.bin\
$BAO_DEMOS_WRKDIR_IMGS
```
### B.4) Build Firmware and Deploy
Build the firmware and deploy the system according to the target platform:
#### AArch64 platforms:
* [Xilinx ZCU102/4](platforms/zcu104/README.md)
* [NXP i.MX8QM](platforms/imx8qm/README.md)
* [Nvidia TX2](platforms/tx2/README.md)
* [Raspberry 4 Model B](platforms/rpi4/README.md)
* [QEMU virt](platforms/qemu-aarch64-virt/README.md)
#### RISC-V platforms:
* [QEMU virt](platforms/qemu-riscv64-virt/README.md)
---
## Appendix I
| | PLATFORM | ARCH
|--|--|--|
| Xilinx ZCU102 | zcu102 | aarch64
| Xilinx ZCU104 | zcu104 | aarch64
| NXP i.MX8QM | imx8qm | aarch64
| Nvidia TX2 | tx2 | aarch64
| Raspberry 4 Model B | rpi4 | aarch64
| QEMU Aarch64 virt | qemu-aarch64-virt | aarch64
| QEMU RV64 virt | qemu-riscv64-virt | riscv
<!-- TODO -->
<!-- | NXP i.MX8MQ | imx8mq | -->
<!-- | Avnet Ultra96 | ultra96 | -->
<!-- | Rocket on ZynqMP | rocket-fpga | -->
<!-- | Rocket on Firesim | rocket-firesim | -->
<!-- | Hikey 960 | hikey960 | -->
<!-- | Rock 960 | rock960 | -->
| | DEMO |
|--|--|
| Baremetal guest | baremetal |
| Linux+FreeRTOS | linux+freertos |
<!-- TODO: Add Accepted Platform/Demos table -->
---
## Appendix II
| Tool | Version |
|--|--|
| aarch64-none-elf-gcc | 9.2.1 |
| riscv64-unknown-elf-gcc | 10.1.0 |
| make | 4.2.1 |
| dtc | 1.5.0 |
| gcc | 9.3.0 |
| mkimage | 20.10 |
| cmake | 3.16.3 |
| ninja | 1.10.1 |
<!-- Links -->
[arm-toolchains]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
[riscv-toolchains]: https://github.com/sifive/freedom-tools/releases

9
demos/README.md Normal file
View File

@ -0,0 +1,9 @@
# Bao Hypervisor Demos
The following demos are available:
* [Bare Metal Application](../demos/baremetal/README.md)
* [Dual-Guest Linux+FreeRTOS](../demos/linux+freertos/README.md)
More demos, showcasing different Bao features, guests and configurations will
be available in the future.

16
demos/baremetal/README.md Normal file
View File

@ -0,0 +1,16 @@
# Bare metal application Demo
This demo features a multi-threaded bare metal application running over bao
on all available cores. The application prints to the first available UART.
It configures a periodic timer interrupt in the first core and, each time this
interrupt is triggered, it forwards an IPI to the next core. Each time a core
receives an IPI it will forward it to the next core, until there are no more
cores to interrupt.
The application also setups an RX UART interrupt that might be forwarded to just
one or multiple cores, depending on the capabilities of the platform's interrupt
controller. Each time it receives a character, it will print a message.
Follow the [build instructions](../../guests/baremetal/README.md) to compile the
bare metal application to your target platform.

View File

@ -0,0 +1,58 @@
#include <config.h>
VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
struct config config = {
CONFIG_HEADER
.vmlist_size = 1,
.vmlist = {
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(baremetal_image),
.size = VM_IMAGE_SIZE(baremetal_image)
},
.entry = 0x00000000,
.platform = {
.cpu_num = 6,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x4000000
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* lpuart0 */
.pa = 0x5a060000,
.va = 0xff000000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {377}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicr_addr = 0xF9020000,
}
}
},
}
},
};

View File

@ -0,0 +1,58 @@
#include <config.h>
VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
struct config config = {
CONFIG_HEADER
.vmlist_size = 1,
.vmlist = {
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(baremetal_image),
.size = VM_IMAGE_SIZE(baremetal_image)
},
.entry = 0x00000000,
.platform = {
.cpu_num = 4,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x4000000
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* PL011 */
.pa = 0x9000000,
.va = 0xFF010000,
.size = 0x10000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {33}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicr_addr = 0xF9020000,
}
}
},
}
},
};

View File

@ -0,0 +1,48 @@
#include <config.h>
VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
struct config config = {
CONFIG_HEADER
.vmlist_size = 1,
.vmlist = {
{
.image = {
.base_addr = 0x80200000,
.load_addr = VM_IMAGE_OFFSET(baremetal_image),
.size = VM_IMAGE_SIZE(baremetal_image)
},
.entry = 0x80200000,
.platform = {
.cpu_num = 4,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x80000000,
.size = 0x1000000 //128MB
}
},
.dev_num = 1,
.devs = (struct dev_region[]) {
{
.pa = 0x10000000,
.va = 0x10000000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {10}
},
},
.arch = {
.plic_base = 0xc000000,
}
},
},
}
};

58
demos/baremetal/configs/rpi4.c Executable file
View File

@ -0,0 +1,58 @@
#include <config.h>
VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
struct config config = {
CONFIG_HEADER
.vmlist_size = 1,
.vmlist = {
{
.image = {
.base_addr = 0x80000,
.load_addr = VM_IMAGE_OFFSET(baremetal_image),
.size = VM_IMAGE_SIZE(baremetal_image)
},
.entry = 0x80000,
.platform = {
.cpu_num = 4,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x80000,
.size = 0x4000000
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* UART1 */
.pa = 0xfe215000,
.va = 0xfe215000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {125}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicc_addr = 0xF9020000,
}
}
},
}
},
};

57
demos/baremetal/configs/tx2.c Executable file
View File

@ -0,0 +1,57 @@
#include <config.h>
VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
struct config config = {
CONFIG_HEADER
.vmlist_size = 1,
.vmlist = {
{
.image = {
.base_addr = 0x0,
.load_addr = VM_IMAGE_OFFSET(baremetal_image),
.size = VM_IMAGE_SIZE(baremetal_image)
},
.entry = 0x0,
.platform = {
.cpu_num = 6,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x0,
.size = 0x4000000
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* uarta */
.pa = 0x03100000,
.va = 0x80000000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {144}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicc_addr = 0xF9020000,
}
}
},
}
},
};

View File

@ -0,0 +1 @@
zcu104.c

View File

@ -0,0 +1,59 @@
#include <config.h>
VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
struct config config = {
CONFIG_HEADER
.vmlist_size = 1,
.vmlist = {
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(baremetal_image),
.size = VM_IMAGE_SIZE(baremetal_image)
},
.entry = 0x00000000,
.platform = {
.cpu_num = 4,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x4000000
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* UART0 */
.pa = 0xFF000000,
.va = 0xFF000000,
.size = 0x10000,
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {53}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicc_addr = 0xF9020000,
}
}
},
}
},
};

6
demos/baremetal/make.mk Normal file
View File

@ -0,0 +1,6 @@
include $(bao_demos)/guests/baremetal/make.mk
baremetal_image:=$(wrkdir_demo_imgs)/baremetal.bin
$(eval $(call build-baremetal, $(baremetal_image)))
guest_images:=$(baremetal_image)

View File

@ -0,0 +1,29 @@
# Linux+FreeRTOS Demo
This demo features a dual guest configuration, Linux and FreeRTOS, connected
through inter-VM communication object which is nothing more than a shared
memory region and doorbell mechanism in the form of hardware interrupts.
One of the platform's cores is assigned to FreeRTOS while all others are
used by Linux. The platform's first available UART is also assigned to FreeRTOS.
If anyother UART device is available it is assigned to Linux. If not through a
UART, the Linux guest is also accessible via ssh at the static address
**192.168.42.15**.
You can send messages to FreeRTOS by writing to `/dev/baoipc0`. For example:
```
echo "Hello, Bao!" > /dev/baoipc0
```
The FreeRTOS guest will also send a message to Linux each time it receives a
character in its UART. However, the Linux inter-VM is not configured for Linux
to asynchronously react to it and output this message. You can checkout the last
FreeRTOS message by reading `/dev/baoipc0`:
```
cat /dev/baoipc0
```
Follow the instructions to build [FreeRTOS](../../guests/freertos/README.md)
and [Linux](../../guests/linux/README.md).

View File

@ -0,0 +1,157 @@
#include <config.h>
VM_IMAGE(linux_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/linux.bin));
VM_IMAGE(freertos_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/freertos.bin));
struct config config = {
CONFIG_HEADER
.shmemlist_size = 1,
.shmemlist = (struct shmem[]) {
[0] = { .size = 0x00010000, }
},
.vmlist_size = 2,
.vmlist = {
{
.image = {
.base_addr = 0x80200000,
.load_addr = VM_IMAGE_OFFSET(linux_image),
.size = VM_IMAGE_SIZE(linux_image)
},
.entry = 0x80200000,
.cpu_affinity = 0b110111,
.platform = {
.cpu_num = 5,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x80200000,
.size = 0x20000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0xf0000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
/**
* We are assigning a MU to the linux guest because the linux drivers
* assume linux can directly interact with the SCU to configure its devices.
* Therefore, this guest will be able to configure peripheral not assigned
* to it, as for example, the lpuart0 used by bao and freertos. In the future
* we will have to either move the cores and peripherals belonging to this guest
* to a parate scfw partition or paravirtualise the MUS and interpose the guest
* communication to the SCU to limit which resources it might configure.
*/
.dev_num = 4,
.devs = (struct dev_region[]) {
{
/* lsio_mu1 message unit */
.pa = 0x5d1c0000,
.va = 0x5d1c0000,
.size = 0x10000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {209},
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts = (uint64_t[]) {27}
},
{
/* enet0 clock generator */
.pa = 0x5b230000,
.va = 0x5b230000,
.size = 0x10000,
},
{
/* fec1 */
.pa = 0x5b040000,
.va = 0x5b040000,
.size = 0x10000,
.interrupt_num = 4,
.interrupts = (uint64_t[]) {288, 289, 290, 291},
.id = 0x2,
},
},
.arch = {
.gic = {
.gicd_addr = 0x51a00000,
.gicr_addr = 0x51b00000
},
}
},
},
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(freertos_image),
.size = VM_IMAGE_SIZE(freertos_image)
},
.entry = 0x00000000,
.cpu_affinity = 0b001000,
.platform = {
.cpu_num = 1,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x0,
.size = 0x8000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0x70000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* lpuart0 */
.pa = 0x5a060000,
.va = 0xff000000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {377}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicr_addr = 0xF9020000,
}
}
},
}
},
};

View File

@ -0,0 +1,132 @@
#include <config.h>
VM_IMAGE(linux_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/linux.bin));
VM_IMAGE(freertos_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/freertos.bin));
struct config config = {
CONFIG_HEADER
.shmemlist_size = 1,
.shmemlist = (struct shmem[]) {
[0] = { .size = 0x00010000, }
},
.vmlist_size = 2,
.vmlist = {
{
.image = {
.base_addr = 0x60000000,
.load_addr = VM_IMAGE_OFFSET(linux_image),
.size = VM_IMAGE_SIZE(linux_image)
},
.entry = 0x60000000,
.platform = {
.cpu_num = 3,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x60000000,
.size = 0x40000000,
.place_phys = true,
.phys = 0x60000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0xf0000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* virtio devices */
.pa = 0xa003000,
.va = 0xa003000,
.size = 0x1000,
.interrupt_num = 8,
.interrupts = (uint64_t[]) {72,73,74,75,76,77,78,79}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts = (uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0x8000000,
.gicr_addr = 0x80A0000
}
}
},
},
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(freertos_image),
.size = VM_IMAGE_SIZE(freertos_image)
},
.entry = 0x00000000,
.platform = {
.cpu_num = 1,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x8000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0x70000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* PL011 */
.pa = 0x9000000,
.va = 0xFF010000,
.size = 0x10000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {33}
},
{
.interrupt_num = 1,
.interrupts = (uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicr_addr = 0xF9020000,
}
}
},
}
},
};

View File

@ -0,0 +1,115 @@
#include <config.h>
VM_IMAGE(linux_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/linux.bin));
VM_IMAGE(freertos_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/freertos.bin));
struct config config = {
CONFIG_HEADER
.shmemlist_size = 1,
.shmemlist = (struct shmem[]) {
[0] = { .size = 0x00010000, }
},
.vmlist_size = 2,
.vmlist = {
{
.image = {
.base_addr = 0x90200000,
.load_addr = VM_IMAGE_OFFSET(linux_image),
.size = VM_IMAGE_SIZE(linux_image)
},
.entry = 0x90200000,
.platform = {
.cpu_num = 3,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x90000000,
.size = 0x40000000,
.place_phys = true,
.phys = 0x90000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0xf0000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 1,
.devs = (struct dev_region[]) {
{
/* virtio devices */
.pa = 0x10001000,
.va = 0x10001000,
.size = 0x8000,
.interrupt_num = 8,
.interrupts = (uint64_t[]) {1,2,3,4,5,6,7,8}
},
},
.arch = {
.plic_base = 0xc000000,
}
},
},
{
.image = {
.base_addr = 0x80200000,
.load_addr = VM_IMAGE_OFFSET(freertos_image),
.size = VM_IMAGE_SIZE(freertos_image)
},
.entry = 0x80200000,
.platform = {
.cpu_num = 1,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x80000000,
.size = 0x8000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0x70000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 1,
.devs = (struct dev_region[]) {
{
.pa = 0x10000000,
.va = 0x10000000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {10}
},
},
.arch = {
.plic_base = 0xc000000,
}
},
},
}
};

View File

@ -0,0 +1,134 @@
#include <config.h>
VM_IMAGE(linux_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/linux.bin));
VM_IMAGE(freertos_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/freertos.bin));
struct config config = {
CONFIG_HEADER
.shmemlist_size = 1,
.shmemlist = (struct shmem[]) {
[0] = { .size = 0x00010000, }
},
.vmlist_size = 2,
.vmlist = {
{
.image = {
.base_addr = 0x20000000,
.load_addr = VM_IMAGE_OFFSET(linux_image),
.size = VM_IMAGE_SIZE(linux_image)
},
.entry = 0x20000000,
.platform = {
.cpu_num = 3,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x20000000,
.size = 0x40000000,
.place_phys = true,
.phys = 0x20000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0xf0000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* GENET */
.pa = 0xfd580000,
.va = 0xfd580000,
.size = 0x10000,
.interrupt_num = 2,
.interrupts = (uint64_t[]) {189, 190}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xff841000,
.gicc_addr = 0xff842000,
}
}
},
},
{
.image = {
.base_addr = 0x80000,
.load_addr = VM_IMAGE_OFFSET(freertos_image),
.size = VM_IMAGE_SIZE(freertos_image)
},
.entry = 0x80000,
.platform = {
.cpu_num = 1,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x80000,
.size = 0x8000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0x70000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* UART1 */
.pa = 0xfe215000,
.va = 0xfe215000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {125}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicc_addr = 0xF9020000,
}
}
},
},
},
};

View File

@ -0,0 +1,161 @@
#include <config.h>
VM_IMAGE(linux_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/linux.bin));
VM_IMAGE(freertos_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/freertos.bin));
struct config config = {
CONFIG_HEADER
.shmemlist_size = 1,
.shmemlist = (struct shmem[]) {
[0] = { .size = 0x00010000, }
},
.vmlist_size = 2,
.vmlist = {
{
.image = {
.base_addr = 0x90000000,
.load_addr = VM_IMAGE_OFFSET(linux_image),
.size = VM_IMAGE_SIZE(linux_image)
},
.entry = 0x90000000,
.cpu_affinity = 0b111110,
.platform = {
.cpu_num = 5,
.region_num = 2,
.regions = (struct mem_region[]) {
{
.base = 0x90000000,
.size = 0x40000000,
},
{
/* sysram */
.base = 0x30000000,
.size = 0x50000,
.place_phys = true,
.phys = 0x30000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0xf0000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 5,
.devs = (struct dev_region[]) {
{
/* ethernet */
.pa = 0x02490000,
.va = 0x02490000,
.size = 0x10000,
.interrupt_num = 10,
.interrupts = (uint64_t[]) {226,227,222,218,223,219,224,220,225,221},
.id = 0x1
},
{
/* mailbox hs0 */
.pa = 0x03c00000,
.va = 0x03c00000,
.size = 0xa0000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {208},
},
{
/* bpmp */
.id = 0x32
},
{
/* gpio */
.pa = 0x2200000,
.va = 0x2200000,
.size = 0x20000,
.interrupt_num = 6,
.interrupts = (uint64_t[]) {79,82,85,88,91,212}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0x03881000,
.gicc_addr = 0x03882000,
}
}
},
},
{
.image = {
.base_addr = 0x0,
.load_addr = VM_IMAGE_OFFSET(freertos_image),
.size = VM_IMAGE_SIZE(freertos_image)
},
.entry = 0x0,
.platform = {
.cpu_num = 1,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x0,
.size = 0x8000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0x70000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* uarta */
.pa = 0x03100000,
.va = 0x80000000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {144}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicc_addr = 0xF9020000,
}
}
},
},
},
};

View File

@ -0,0 +1 @@
zcu104.c

View File

@ -0,0 +1,155 @@
#include <config.h>
VM_IMAGE(linux_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/linux.bin));
VM_IMAGE(freertos_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/freertos.bin));
struct config config = {
CONFIG_HEADER
.shmemlist_size = 1,
.shmemlist = (struct shmem[]) {
[0] = { .size = 0x00010000, }
},
.vmlist_size = 2,
.vmlist = {
{
.image = {
.base_addr = 0x00200000,
.load_addr = VM_IMAGE_OFFSET(linux_image),
.size = VM_IMAGE_SIZE(linux_image)
},
.entry = 0x00200000,
.platform = {
.cpu_num = 3,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x40000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0xf0000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 3,
.devs = (struct dev_region[]) {
{
/* UART1 */
.pa = 0xFF010000,
.va = 0xFF010000,
.size = 0x1000,
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {54}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
},
{
/* GEM3 */
.id = 0x877, /* smmu stream id */
.pa = 0xff0e0000,
.va = 0xff0e0000,
.size = 0x1000,
.interrupt_num = 2,
.interrupts =
(uint64_t[]) {95, 96}
},
{
/* PCI */
.id = 0x877, /* smmu stream id */
.pa = 0xff0e0000,
.va = 0xff0e0000,
.size = 0x1000,
.interrupt_num = 2,
.interrupts =
(uint64_t[]) {95, 96}
}
},
.arch = {
.gic = {
.gicc_addr = 0xF9020000,
.gicd_addr = 0xF9010000
},
}
},
},
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(freertos_image),
.size = VM_IMAGE_SIZE(freertos_image)
},
.entry = 0x00000000,
.platform = {
.cpu_num = 1,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x8000000
}
},
.ipc_num = 1,
.ipcs = (struct ipc[]) {
{
.base = 0x70000000,
.size = 0x00010000,
.shmem_id = 0,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {52}
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* UART0 */
.pa = 0xFF000000,
.va = 0xFF000000,
.size = 0x10000,
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {53}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicc_addr = 0xF9020000,
}
}
},
},
}
};

View File

@ -0,0 +1,288 @@
/dts-v1/;
/ {
#size-cells = <0x2>;
#address-cells = <0x2>;
cpus {
#size-cells = <0x0>;
#address-cells = <0x1>;
cpu@0 {
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x0>;
};
cpu@1 {
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x1>;
};
cpu@2 {
reg = <0x2>;
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
};
cpu@3 {
reg = <0x3>;
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
};
cpu@4 {
compatible = "arm,armv8";
device_type = "cpu";
reg = <0x4>;
enable-method = "psci";
};
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
memory@80200000 {
reg = <0x0 0x80200000 0x0 0x20000000>;
device_type = "memory";
};
gic: intc@8000000 {
interrupts = <0x01 0x09 0x04>;
reg = <0x00 0x51a00000 0x00 0x10000 0x00 0x51b00000 0x00 0xf60000>;
#redistributor-regions = <0x01>;
compatible = "arm,gic-v3";
interrupt-controller;
#interrupt-cells = <0x03>;
interrupt-parent = <&gic>;
};
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&gic>;
interrupts = <0x1 0xd 0xf08 0x1 0xe 0xf08 0x1 0xb 0xf08 0x1 0xa 0xf08>;
};
conn_axi_clk: clock-conn-axi {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <333333333>;
clock-output-names = "conn_axi_clk";
};
conn_ipg_clk: clock-conn-ipg {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <83333333>;
clock-output-names = "conn_ipg_clk";
};
xtal32k: clock-xtal32k {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
clock-output-names = "xtal_32KHz";
};
xtal24m: clock-xtal24m {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
clock-output-names = "xtal_24MHz";
};
/**
* We are assigning a mu to the linux guest because the linux drivers
* assume linux can directly interact with the SCU to configure its devices.
* Therefore, this guest will be able to configure peripherals not assigned
* to it, as for example, the lpuart0 used by the hypervisor and possibly
* other guests. In the future we will have to either to move the cores
* belonging to this guest to a separate scfw partition or paravirtualise
* the MU1 and interpose the guest's communcation to the SCU, to limit
* which resource it might configure.
*/
lsio_mu1: mailbox@5d1c0000 {
compatible = "fsl,imx8qm-mu", "fsl,imx6sx-mu";
reg = <0x0 0x5d1c0000 0x0 0x10000>;
interrupt-parent = <&gic>;
interrupts = <0 177 4>;
#mbox-cells = <2>;
status = "okay";
};
scu {
compatible = "fsl,imx-scu";
mbox-names = "tx0", "tx1", "tx2", "tx3",
"rx0", "rx1", "rx2", "rx3",
"gip3";
mboxes = <&lsio_mu1 0 0
&lsio_mu1 0 1
&lsio_mu1 0 2
&lsio_mu1 0 3
&lsio_mu1 1 0
&lsio_mu1 1 1
&lsio_mu1 1 2
&lsio_mu1 1 3
&lsio_mu1 3 3>;
pd: imx8qx-pd {
compatible = "fsl,imx8qm-scu-pd", "fsl,scu-pd";
#power-domain-cells = <1>;
};
clk: clock-controller {
compatible = "fsl,imx8qm-clk", "fsl,scu-clk";
#clock-cells = <2>;
clocks = <&xtal32k &xtal24m>;
clock-names = "xtal_32KHz", "xtal_24Mhz";
};
iomuxc: pinctrl {
compatible = "fsl,imx8qm-iomuxc";
pinctrl-names = "default";
pinctrl_fec1: fec1grp {
fsl,pins = <0xff 0x00 0x14a0
0xa6 0x00 0x6000020
0xa5 0x00 0x6000020
0xf4 0x00 0x6000020
0xf3 0x00 0x6000020
0xf5 0x00 0x6000020
0xf6 0x00 0x6000020
0xf7 0x00 0x6000020
0xf8 0x00 0x6000020
0xf9 0x00 0x6000020
0xfa 0x00 0x6000020
0xfb 0x00 0x6000020
0xfc 0x00 0x6000020
0xfd 0x00 0x6000020
0xfe 0x00 0x6000020>;
};
};
ocotp: imx8qm-ocotp {
compatible = "fsl,imx8qm-scu-ocotp";
#address-cells = <1>;
#size-cells = <1>;
read-only;
fec_mac0: mac@1c4 {
reg = <0x1c4 6>;
};
fec_mac1: mac@1c6 {
reg = <0x1c6 6>;
};
};
};
enet0_lpcg: clock-controller@5b230000 {
compatible = "fsl,imx8qxp-lpcg";
reg = <0x0 0x5b230000 0x0 0x10000>;
#clock-cells = <1>;
clocks = <&clk 251 2>,
<&clk 251 2>,
<&conn_axi_clk>,
<&clk 251 24>,
<&conn_ipg_clk>,
<&conn_ipg_clk>;
bit-offset = <0 4 8 12 16 20>;
clock-output-names = "enet0_lpcg_timer_clk",
"enet0_lpcg_txc_sampling_clk",
"enet0_lpcg_ahb_clk",
"enet0_lpcg_rgmii_txc_clk",
"enet0_lpcg_ipg_clk",
"enet0_lpcg_ipg_s_clk";
power-domains = <&pd 251>;
};
fec1: ethernet@5b040000 {
compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
reg = <0x0 0x5b040000 0x0 0x10000>;
interrupt-parent = <&gic>;
interrupts = <0 258 4>,
<0 256 4>,
<0 257 4>,
<0 259 4>;
clocks = <&enet0_lpcg 4>,
<&enet0_lpcg 2>,
<&enet0_lpcg 3>,
<&enet0_lpcg 0>,
<&enet0_lpcg 1>;
clock-names = "ipg", "ahb", "enet_clk_ref", "ptp", "enet_2x_txclk";
status = "okay";
assigned-clocks = <&clk 251 2>,
<&clk 251 25>;
assigned-clock-rates = <250000000>, <125000000>;
fsl,num-tx-queues=<3>;
fsl,num-rx-queues=<3>;
power-domains = <&pd 251>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec1>;
phy-mode = "rgmii";
phy-handle = <&ethphy0>;
fsl,magic-packet;
nvmem-cells = <&fec_mac0>;
nvmem-cell-names = "mac-address";
fsl,rgmii_rxc_dly;
fsl,rgmii_txc_dly;
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
at803x,eee-disabled;
at803x,vddio-1p8v;
status = "okay";
};
};
};
bao-ipc@f0000000 {
compatible = "bao,ipcshmem";
reg = <0x0 0xf0000000 0x0 0x00010000>;
read-channel = <0x0 0x2000>;
write-channel = <0x2000 0x2000>;
interrupts = <0 52 1>;
interrupt-parent = <&gic>;
id = <0>;
};
/**
* The purpose of this dummy lpuart node is for linux not turning off the
* lpuart that is in use by the hypervisor and possibly other guest.
* By assigning it to the stdout-path in /chosen, the linux pd driver will
* leave it be and not turn it off. As explained previsouly, this is just
* for demonstration purposes and in the future this power resource controls
* will either be blocked by placing linux and its resources in their own
* scfw partition or by having SCU interactions mediated by the hypervisor.
*/
lpuart0_dummy: lpuart0 {
power-domains = <&pd 57>;
};
aliases {
ethernet0 = &fec1;
};
chosen {
bootargs = "clk_ignore_unused ip=192.168.42.15 carrier_timeout=0";
stdout-path = &lpuart0_dummy;
};
};

View File

@ -0,0 +1,131 @@
/dts-v1/;
/ {
#size-cells = <0x2>;
#address-cells = <0x2>;
interrupt-parent = <&gic>;
cpus {
#size-cells = <0x0>;
#address-cells = <0x1>;
cpu@0 {
compatible = "arm,cortex-a53", "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x0>;
};
cpu@1 {
compatible = "arm,cortex-a53", "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x1>;
};
cpu@2 {
reg = <0x2>;
compatible = "arm,cortex-a53";
device_type = "cpu";
};
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
memory@60000000 {
device_type = "memory";
reg = <0x0 0x60000000 0x0 0x40000000>;
};
gic: intc@8000000 {
interrupts = <0x01 0x09 0x04>;
reg = <0x00 0x8000000 0x00 0x10000 0x00 0x80a0000 0x00 0xf60000>;
#redistributor-regions = <0x01>;
compatible = "arm,gic-v3";
ranges;
#size-cells = <0x02>;
#address-cells = <0x02>;
interrupt-controller;
#interrupt-cells = <0x03>;
};
timer {
interrupts = <0x1 0xd 0xf04 0x1 0xe 0xf04 0x1 0xb 0xf04 0x1 0xa 0xf04>;
always-on;
compatible = "arm,armv8-timer", "arm,armv7-timer";
};
virtio_mmio@a003000 {
dma-coherent;
interrupts = <0x0 0x28 0x1>;
reg = <0x0 0xa003000 0x0 0x200>;
compatible = "virtio,mmio";
};
virtio_mmio@a003200 {
dma-coherent;
interrupts = <0x0 0x29 0x1>;
reg = <0x0 0xa003200 0x0 0x200>;
compatible = "virtio,mmio";
};
virtio_mmio@a003400 {
dma-coherent;
interrupts = <0x0 0x2a 0x1>;
reg = <0x0 0xa003400 0x0 0x200>;
compatible = "virtio,mmio";
};
virtio_mmio@a003600 {
dma-coherent;
interrupts = <0x0 0x2b 0x1>;
reg = <0x0 0xa003600 0x0 0x200>;
compatible = "virtio,mmio";
};
virtio_mmio@a003800 {
dma-coherent;
interrupts = <0x0 0x2c 0x1>;
reg = <0x0 0xa003800 0x0 0x200>;
compatible = "virtio,mmio";
};
virtio_mmio@a003a00 {
dma-coherent;
interrupts = <0x0 0x2d 0x1>;
reg = <0x0 0xa003a00 0x0 0x200>;
compatible = "virtio,mmio";
};
virtio_mmio@a003c00 {
dma-coherent;
interrupts = <0x0 0x2e 0x1>;
reg = <0x0 0xa003c00 0x0 0x200>;
compatible = "virtio,mmio";
};
virtio_mmio@a003e00 {
dma-coherent;
interrupts = <0x0 0x2f 0x1>;
reg = <0x0 0xa003e00 0x0 0x200>;
compatible = "virtio,mmio";
};
bao-ipc@f0000000 {
compatible = "bao,ipcshmem";
reg = <0x0 0xf0000000 0x0 0x00010000>;
read-channel = <0x0 0x2000>;
write-channel = <0x2000 0x2000>;
interrupts = <0 52 1>;
id = <0>;
};
chosen {
bootargs = "earlycon console=hvc0 ip=192.168.42.15";
};
};

View File

@ -0,0 +1,146 @@
/dts-v1/;
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
cpus {
#address-cells = <0x1>;
#size-cells = <0x0>;
timebase-frequency = <10000000>;
cpu@0 {
device_type = "cpu";
reg = <0x0>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcsu";
mmu-type = "riscv,sv48";
cpu0_intc: interrupt-controller {
#interrupt-cells = <0x1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
cpu@1 {
device_type = "cpu";
reg = <0x1>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcsu";
mmu-type = "riscv,sv48";
cpu1_intc: interrupt-controller {
#interrupt-cells = <0x1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
cpu@2 {
device_type = "cpu";
reg = <0x2>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcsu";
mmu-type = "riscv,sv48";
cpu2_intc: interrupt-controller {
#interrupt-cells = <0x1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
};
memory@90000000 {
device_type = "memory";
reg = <0x0 0x90000000 0x0 0x40000000>;
};
plic: interrupt-controller@c000000 {
riscv,ndev = <60>;
reg = <0x0 0xc000000 0x0 0x4000000>;
interrupts-extended = <
&cpu0_intc 11 &cpu0_intc 9
&cpu1_intc 11 &cpu1_intc 9
&cpu2_intc 11 &cpu2_intc 9
>;
interrupt-controller;
compatible = "riscv,plic0";
#interrupt-cells = <0x1>;
};
virtio_mmio@10008000 {
interrupts = <0x8>;
interrupt-parent = <&plic>;
reg = <0x0 0x10008000 0x0 0x1000>;
compatible = "virtio,mmio";
};
virtio_mmio@10007000 {
interrupts = <0x7>;
interrupt-parent = <&plic>;
reg = <0x0 0x10007000 0x0 0x1000>;
compatible = "virtio,mmio";
};
virtio_mmio@10006000 {
interrupts = <0x6>;
interrupt-parent = <&plic>;
reg = <0x0 0x10006000 0x0 0x1000>;
compatible = "virtio,mmio";
};
virtio_mmio@10005000 {
interrupts = <0x5>;
interrupt-parent = <&plic>;
reg = <0x0 0x10005000 0x0 0x1000>;
compatible = "virtio,mmio";
};
virtio_mmio@10004000 {
interrupts = <0x4>;
interrupt-parent = <&plic>;
reg = <0x0 0x10004000 0x0 0x1000>;
compatible = "virtio,mmio";
};
virtio_mmio@10003000 {
interrupts = <0x3>;
interrupt-parent = <&plic>;
reg = <0x0 0x10003000 0x0 0x1000>;
compatible = "virtio,mmio";
};
virtio_mmio@10002000 {
interrupts = <0x2>;
interrupt-parent = <&plic>;
reg = <0x0 0x10002000 0x0 0x1000>;
compatible = "virtio,mmio";
};
virtio_mmio@10001000 {
interrupts = <0x1>;
interrupt-parent = <&plic>;
reg = <0x0 0x10001000 0x0 0x1000>;
compatible = "virtio,mmio";
};
bao-ipc@f0000000 {
compatible = "bao,ipcshmem";
reg = <0x0 0xf0000000 0x0 0x00010000>;
read-channel = <0x0 0x2000>;
write-channel = <0x2000 0x2000>;
interrupt-parent = <&plic>;
interrupts = <52>;
id = <0>;
};
chosen {
bootargs = "earlycon console=hvc1 ip=192.168.42.15";
};
};

View File

@ -0,0 +1,123 @@
/dts-v1/;
/ {
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
cpus {
#size-cells = <0x0>;
#address-cells = <0x1>;
cpu@0 {
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x0>;
};
cpu@1 {
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x1>;
};
cpu@2 {
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x2>;
};
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
memory@20000000 {
reg = <0x0 0x20000000 0x0 0x40000000>;
device_type = "memory";
};
reserved-memory {
#address-cells = <0x02>;
#size-cells = <0x01>;
ranges;
linux,cma {
compatible = "shared-dma-pool";
size = <0x4000000>;
reusable;
linux,cma-default;
};
};
gic: interrupt-controller@3881000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x0 0xff841000 0x0 0x1000>,
<0x0 0xff842000 0x0 0x2000>;
};
timer {
compatible = "arm,armv8-timer";
interrupts = <0x1 0xd 0xf08 0x1 0xe 0xf08 0x1 0xb 0xf08 0x1 0xa 0xf08>;
};
scb@7c000000 {
compatible = "simple-bus";
#address-cells = <0x02>;
#size-cells = < 0x02 >;
dma-ranges = < 0x00 0x00 0x00 0x00 0x04 0x00 >;
ranges = < 0x00 0x7c000000 0x00 0xfc000000 0x00 0x3800000 0x00 0x40000000 0x00 0xff800000 0x00 0x800000 0x06 0x00 0x06 0x00 0x00 0x40000000 0x00 0x00 0x00 0x00 0x00 0xfc000000 >;
genet: ethernet@7d580000 {
local-mac-address = [dc a6 32 a3 9c 57];
compatible = "brcm,bcm2711-genet-v5", "brcm,genet-v5";
reg = < 0x00 0x7d580000 0x00 0x10000 >;
#address-cells = <0x1>;
#size-cells = <0x1>;
interrupts = <0 157 4>,
<0 158 4>;
status = "okay";
phy-handle = <&phy1>;
phy-mode = "rgmii-rxid";
genet_mdio: mdio@e14 {
compatible = "brcm,genet-mdio-v5";
reg = <0xe14 0x8>;
reg-names = "mdio";
#address-cells = <0x0>;
#size-cells = <0x1>;
phy1: ethernet-phy@1 {
reg = <0x01>;
led-modes = < 0x00 0x08 >;
};
};
};
};
bao-ipc@f0000000 {
compatible = "bao,ipcshmem";
reg = <0x0 0xf0000000 0x0 0x00010000>;
read-channel = <0x0 0x2000>;
write-channel = <0x2000 0x2000>;
interrupts = <0 52 1>;
id = <0>;
};
aliases {
ethernet0 = &genet;
};
chosen {
bootargs = "earlycon clk_ignore_unused ip=192.168.42.15 carrier_timeout=0";
};
};

View File

@ -0,0 +1,198 @@
/dts-v1/;
/ {
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
cpus {
#size-cells = <0x0>;
#address-cells = <0x1>;
cpu@0 {
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x0>;
};
cpu@1 {
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x1>;
};
cpu@2 {
reg = <0x2>;
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
};
cpu@3 {
reg = <0x3>;
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
};
cpu@4 {
reg = <0x4>;
compatible = "arm,armv8";
device_type = "cpu";
enable-method = "psci";
};
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
memory@90000000 {
reg = <0x0 0x90000000 0x0 0x40000000>;
device_type = "memory";
};
sysram@30000000 {
compatible = "nvidia,tegra186-sysram", "mmio-sram";
reg = <0x0 0x30000000 0x0 0x50000>;
#address-cells = <2>;
#size-cells = <2>;
ranges = <0 0x0 0x0 0x30000000 0x0 0x50000>;
cpu_bpmp_tx: shmem@4e000 {
compatible = "nvidia,tegra186-bpmp-shmem";
reg = <0x0 0x4e000 0x0 0x1000>;
label = "cpu-bpmp-tx";
pool;
};
cpu_bpmp_rx: shmem@4f000 {
compatible = "nvidia,tegra186-bpmp-shmem";
reg = <0x0 0x4f000 0x0 0x1000>;
label = "cpu-bpmp-rx";
pool;
};
};
gic: interrupt-controller@3881000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x0 0x03881000 0x0 0x1000>,
<0x0 0x03882000 0x0 0x2000>;
};
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&gic>;
interrupts = <0x1 0xd 0xf08 0x1 0xe 0xf08 0x1 0xb 0xf08 0x1 0xa 0xf08>;
};
hsp_top0: hsp@3c00000 {
compatible = "nvidia,tegra186-hsp";
reg = <0x0 0x03c00000 0x0 0xa0000>;
interrupts = <0 176 4>;
interrupt-names = "doorbell";
#mbox-cells = <2>;
status = "okay";
};
bpmp: bpmp {
compatible = "nvidia,tegra186-bpmp";
mboxes = <&hsp_top0 0 19>;
shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
gpio: gpio@2200000 {
compatible = "nvidia,tegra186-gpio";
reg-names = "security", "gpio";
reg = <0x0 0x2200000 0x0 0x10000>,
<0x0 0x2210000 0x0 0x10000>;
interrupt-parent = <&gic>;
interrupts = <0 47 4>,
<0 50 4>,
<0 53 4>,
<0 56 4>,
<0 59 4>,
<0 180 4>;
#interrupt-cells = <2>;
interrupt-controller;
#gpio-cells = <2>;
gpio-controller;
};
eth: ethernet@2490000 {
compatible = "nvidia,tegra186-eqos",
"snps,dwc-qos-ethernet-4.10";
reg = <0x0 0x02490000 0x0 0x10000>;
interrupts = <0 194 4>, /* common */
<0 195 4>, /* power */
<0 190 4>, /* rx0 */
<0 186 4>, /* tx0 */
<0 191 4>, /* rx1 */
<0 187 4>, /* tx1 */
<0 192 4>, /* rx2 */
<0 188 4>, /* tx2 */
<0 193 4>, /* rx3 */
<0 189 4>; /* tx3 */
clocks = <&bpmp 149>,
<&bpmp 167>,
<&bpmp 168>,
<&bpmp 240>,
<&bpmp 239>;
clock-names = "master_bus", "slave_bus", "rx", "tx", "ptp_ref";
resets = <&bpmp 69>;
reset-names = "eqos";
snps,write-requests = <1>;
snps,read-requests = <3>;
snps,burst-map = <0x7>;
snps,txpbl = <32>;
snps,rxpbl = <8>;
status = "okay";
phy-reset-gpios = <&gpio 0x64 0x1>;
phy-handle = <&phy>;
phy-mode = "rgmii";
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy: phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
interrupt-parent = <&gpio>;
interrupts = <0x65 0x08>;
#phy-cells = <0>;
};
};
};
bao-ipc@f0000000 {
compatible = "bao,ipcshmem";
reg = <0x0 0xf0000000 0x0 0x00010000>;
read-channel = <0x0 0x2000>;
write-channel = <0x2000 0x2000>;
interrupts = <0 52 1>;
id = <0>;
};
aliases {
ethernet0 = &eth;
};
chosen {
bootargs = "clk_ignore_unused ip=192.168.42.15 carrier_timeout=0";
};
};

View File

@ -0,0 +1 @@
zcu104

View File

@ -0,0 +1,154 @@
/dts-v1/;
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
interrupt-parent = <&gic>;
cpus {
#size-cells = <0x0>;
#address-cells = <0x1>;
cpu@0 {
compatible = "arm,cortex-a53", "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x0>;
};
cpu@1 {
compatible = "arm,cortex-a53", "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x1>;
};
cpu@2 {
compatible = "arm,cortex-a53", "arm,armv8";
device_type = "cpu";
enable-method = "psci";
reg = <0x2>;
};
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x40000000>;
};
gic: interrupt-controller@f9010000 {
compatible = "arm,gic-400", "arm,cortex-a15-gic";
#interrupt-cells = <0x3>;
reg = <0x0 0xf9010000 0x0 0x10000 0x0 0xf9020000 0x0 0x20000 0x0 0xf9040000 0x0 0x20000 0x0 0xf9060000 0x0 0x20000>;
interrupt-controller;
interrupt-parent = <0x4>;
interrupts = <0x1 0x9 0xf04>;
};
timer {
compatible = "arm,armv8-timer";
always-on;
interrupts = <0x1 0xd 0xf08 0x1 0xe 0xf08 0x1 0xb 0xf08 0x1 0xa 0xf08>;
};
uartclk: uartclk {
compatible = "fixed-clock";
#clock-cells = <0x0>;
clock-frequency = <100000000>;
phandle = <0x1>;
};
ethclk: ethclk {
compatible = "fixed-clock";
#clock-cells = <0x0>;
clock-frequency = <125000000>;
phandle = <0x2>;
};
amba {
compatible = "simple-bus";
#address-cells = <0x2>;
#size-cells = <0x2>;
ranges;
serial@ff010000 {
u-boot,dm-pre-reloc;
compatible = "cdns,uart-r1p12", "xlnx,xuartps";
status = "okay";
interrupts = <0x0 0x16 0x4>;
reg = <0x0 0xff010000 0x0 0x1000>;
clock-names = "uart_clk", "pclk";
clocks = <&uartclk &uartclk>;
};
ethernet@ff0e0000 {
compatible = "cdns,zynqmp-gem", "cdns,gem";
status = "okay";
interrupt-parent = <&gic>;
interrupts = <0x0 0x3f 0x4 0x0 0x3f 0x4>;
reg = <0x0 0xff0e0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk", "rx_clk";
phy-mode = "rgmii-id";
#address-cells = <0x1>;
#size-cells = <0x0>;
clocks = <&ethclk &ethclk &ethclk &ethclk>;
phy-handle = <&phy>;
phy: phy@c {
reg = <0xc>;
ti,rx-internal-delay = <0x8>;
ti,tx-internal-delay = <0xa>;
ti,fifo-depth = <0x1>;
ti,dp83867-rxctrl-strap-quirk;
};
};
zynqmp_phy@fd400000 {
compatible = "xlnx,zynqmp-psgtr-v1.1";
status = "disabled";
reg = <0x0 0xfd400000 0x0 0x40000 0x0 0xfd3d0000 0x0 0x1000>;
reg-names = "serdes", "siou";
lane0 {
#phy-cells = <0x4>;
};
lane1 {
#phy-cells = <0x4>;
};
lane2 {
#phy-cells = <0x4>;
};
lane3 {
#phy-cells = <0x4>;
};
};
};
bao-ipc@f0000000 {
compatible = "bao,ipcshmem";
reg = <0x0 0xf0000000 0x0 0x00010000>;
read-channel = <0x0 0x2000>;
write-channel = <0x2000 0x2000>;
interrupts = <0 52 1>;
id = <0>;
};
aliases {
ethernet0 = "/amba/ethernet@ff0e0000";
serial0 = "/amba/serial@ff010000";
};
chosen {
bootargs = "earlycon console=ttyPS0,115200n8 clk_ignore_unused ip=192.168.42.15 carrier_timeout=0";
stdout-path = "serial0:115200n8";
};
};

View File

@ -0,0 +1,11 @@
include $(bao_demos)/guests/linux/make.mk
include $(bao_demos)/guests/freertos/make.mk
linux_image=$(wrkdir_demo_imgs)/linux.bin
linux_dts=$(bao_demos)/demos/$(DEMO)/devicetrees/$(PLATFORM)/linux.dts
$(eval $(call build-linux, $(linux_image), $(linux_dts)))
freertos_image:=$(wrkdir_demo_imgs)/freertos.bin
$(eval $(call build-freertos, $(freertos_image)))
guest_images:=$(linux_image) $(freertos_image)

16
guests/README.md Normal file
View File

@ -0,0 +1,16 @@
## Bao Guests
At the moment we are supporting three type of guests:
- Bare-metal applcations
- FreeRTOS
- Linux
Other OSs have been run over bao including:
- Erika Enterprise 3
- Android
- Zephyr
We are not actively supporting it, but we are working on providing an example
for each of them in this guide.

View File

@ -0,0 +1,21 @@
# Bao Bare-Metal Guest
Setup an environment variable for the baremetal app source code:
```
export BAO_DEMOS_BAREMETAL=$BAO_DEMOS_WRKDIR_SRC/baremetal
```
Clone and build the bao bare-metal guest application:
```
git clone https://github.com/bao-project/bao-baremetal-guest.git\
$BAO_DEMOS_BAREMETAL
make -C $BAO_DEMOS_BAREMETAL PLATFORM=$PLATFORM
```
Copy the resulting binary to the final image's directory:
```
cp $BAO_DEMOS_BAREMETAL/build/$PLATFORM/baremetal.bin $BAO_DEMOS_WRKDIR_IMGS
```

14
guests/baremetal/make.mk Normal file
View File

@ -0,0 +1,14 @@
baremetal_src:=$(wrkdir_src)/baremetal
baremetal_repo:=https://github.com/bao-project/bao-baremetal-guest.git
$(baremetal_src):
git clone $(baremetal_repo) $@
baremetal_bin:=$(baremetal_src)/build/$(PLATFORM)/baremetal.bin
baremetal $(baremetal_bin): $(baremetal_src)
$(MAKE) -C $(baremetal_src) PLATFORM=$(PLATFORM)
define build-baremetal
$(strip $1): $(baremetal_bin)
cp $$< $$@
endef

22
guests/freertos/README.md Normal file
View File

@ -0,0 +1,22 @@
# FreeRTOS Guest
Setup an environment variable for the FreeRTOS repo:
```
export BAO_DEMOS_FREERTOS=$BAO_DEMOS_WRKDIR_SRC/freertos
```
Then clone and build the freertos:
```
git clone --recursive --shallow-submodules\
https://github.com/bao-project/freertos-over-bao.git\
$BAO_DEMOS_FREERTOS --branch demo
make -C $BAO_DEMOS_FREERTOS PLATFORM=$PLATFORM
```
Finally copy the FreeRTOS image to the final guest image directory:
```
cp $BAO_DEMOS_FREERTOS/build/$PLATFORM/freertos.bin $BAO_DEMOS_WRKDIR_IMGS
```

16
guests/freertos/make.mk Normal file
View File

@ -0,0 +1,16 @@
freertos_src:=$(wrkdir_src)/freertos
freertos_repo:=https://github.com/bao-project/freertos-over-bao.git
$(freertos_src):
git clone --recursive --shallow-submodules --branch demo $(freertos_repo)\
$(freertos_src)
freertos_bin:=$(freertos_src)/build/$(PLATFORM)/freertos.bin
freertos $(freertos_bin): $(freertos_src)
$(MAKE) -C $(freertos_src) PLATFORM=$(PLATFORM)
define build-freertos
$(strip $1): $(freertos_bin)
cp $$< $$@
endef

122
guests/linux/README.md Normal file
View File

@ -0,0 +1,122 @@
# Linux Guest
## 1. Download the Linux kernel source
Setup linux environment variables. Start by the demo resource directory:
```
export BAO_DEMOS_LINUX=$BAO_DEMOS/guests/linux
```
Setup repo and version. Specifically for the NXP iMX platforms use:
```
export BAO_DEMOS_LINUX_REPO=https://source.codeaurora.org/external/imx/linux-imx
export BAO_DEMOS_LINUX_VERSION=rel_imx_5.4.24_2.1.0
```
For all other platforms clone the lastest mainline Linux release:
```
export BAO_DEMOS_LINUX_REPO=https://github.com/torvalds/linux.git
export BAO_DEMOS_LINUX_VERSION=v5.11
```
Setup an environment variable pointing to Linux's source code:
```
export BAO_DEMOS_LINUX_SRC=$BAO_DEMOS_WRKDIR_SRC/linux-$BAO_DEMOS_LINUX_VERSION
```
And make a shallow clone of the target repo:
```
git clone $BAO_DEMOS_LINUX_REPO $BAO_DEMOS_LINUX_SRC\
--depth 1 --branch $BAO_DEMOS_LINUX_VERSION
cd $BAO_DEMOS_LINUX_SRC
git apply $BAO_DEMOS_LINUX/patches/$BAO_DEMOS_LINUX_VERSION/*.patch
```
Finally, setup and environment variable pointing to the target architecture and
platform specific config to be used by buildroot:
```
export BAO_DEMOS_LINUX_CFG_FRAG=$(ls $BAO_DEMOS_LINUX/configs/base.config\
$BAO_DEMOS_LINUX/configs/$ARCH.config\
$BAO_DEMOS_LINUX/configs/$PLATFORM.config 2> /dev/null)
```
## Use Buildroot to build Linux with a built-in initramfs
Setup buildroot environment variables:
```
export BAO_DEMOS_BUILDROOT=$BAO_DEMOS_WRKDIR_SRC/\
buildroot-$ARCH-$BAO_DEMOS_LINUX_VERSION
export BAO_DEMOS_BUILDROOT_DEFCFG=$BAO_DEMOS_LINUX/buildroot/$ARCH.config
export LINUX_OVERRIDE_SRCDIR=$BAO_DEMOS_LINUX_SRC
```
Clone the latest buildroot at the latest stable version:
```
git clone https://github.com/buildroot/buildroot.git $BAO_DEMOS_BUILDROOT\
--depth 1 --branch 2020.11.3
cd $BAO_DEMOS_BUILDROOT
```
Use our provided buildroot defconfig, which itselfs points to the a Linux
kernel defconfig and patches (mainly for the inter-vm communication drivers)
and build:
```
make defconfig BR2_DEFCONFIG=$BAO_DEMOS_BUILDROOT_DEFCFG
make linux-reconfigure all
mv $BAO_DEMOS_BUILDROOT/output/images/Image\
$BAO_DEMOS_BUILDROOT/output/images/Image-$PLATFORM
```
## Build the device tree and wrap it with the kernel image
---
**NOTE**
If your target demo features multiple Linux virtual machines, you will have to
repeat this last step for each of these, which should correspond to
different *.dts* files in *$BAO_DEMOS/$DEMO/devicetrees*.
---
The device tree(s) for your target demo are available in
*$BAO_DEMOS/$DEMO/devicetrees/$PLATFORM*. For a device tree file named
*linux.dts* define a virtual machine variable:
```
export BAO_DEMO_LINUX_VM=linux
```
Then build:
```
dtc $BAO_DEMOS/demos/$DEMO/devicetrees/$PLATFORM/$BAO_DEMO_LINUX_VM.dts >\
$BAO_DEMOS_WRKDIR_IMGS/$BAO_DEMO_LINUX_VM.dtb
```
Wrap the kernel image and device tree blob in a single binary:
```
make -C $BAO_DEMOS_LINUX/lloader\
ARCH=$ARCH\
IMAGE=$BAO_DEMOS_BUILDROOT/output/images/Image-$PLATFORM\
DTB=$BAO_DEMOS_WRKDIR_IMGS/$BAO_DEMO_LINUX_VM.dtb\
TARGET=$BAO_DEMOS_WRKDIR_IMGS/$BAO_DEMO_LINUX_VM.bin
```
---
**NOTE**
The password for `root` is `root`.
---

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
CONFIG_DRM=n

View File

@ -0,0 +1 @@
CONFIG_BAO_SHMEM=y

View File

@ -0,0 +1,2 @@
CONFIG_DRM_IMX_DCSS=n
CONFIG_IMX_LCDIF_CORE=n

View File

@ -0,0 +1,2 @@
CONFIG_BROADCOM_PHY=y
CONFIG_BCMGENET=y

View File

@ -0,0 +1,7 @@
CONFIG_DWMAC_DWC_QOS_ETH=y
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_PLATFORM=y
CONFIG_BCMGENET=n
CONFIG_BROADCOM_PHY=n

36
guests/linux/lloader/Makefile Executable file
View File

@ -0,0 +1,36 @@
ifeq ($(and $(IMAGE), $(DTB), $(TARGET), $(ARCH)),)
ifneq ($(MAKECMDGOALS), clean)
$(error Linux image (IMAGE) and/or device tree (DTB) and/or target name \
(TARGET) and/or architecture (ARCH) not specified)
endif
endif
ARCH?=aarch64
ifeq ($(ARCH), aarch64)
CROSS_COMPILE=aarch64-none-elf-
OPTIONS=-mcmodel=large
else ifeq ($(ARCH), riscv)
CROSS_COMPILE=riscv64-unknown-elf-
OPTIONS=-mcmodel=medany
else
$(error unkown architecture $(ARCH))
endif
LLOADER_ASM:=$(ARCH).S
LLOADER_LD:=$(ARCH).ld
TARGET_ELF:=$(basename $(TARGET)).elf
all: $(TARGET)
clean:
-rm $(TARGET_ELF) $(TARGET)
.PHONY: all clean
$(TARGET): $(TARGET_ELF)
$(CROSS_COMPILE)objcopy -S -O binary $(TARGET_ELF) $(TARGET)
$(TARGET_ELF): $(LLOADER_ASM) $(IMAGE) $(DTB) $(LLOADER_LD)
$(CROSS_COMPILE)gcc -Wl,-build-id=none -nostdlib -T $(LLOADER_LD)\
-o $@ $(OPTIONS) $(LLOADER_ASM) -I. -D IMAGE=$(IMAGE) -D DTB=$(DTB)

37
guests/linux/lloader/aarch64.S Executable file
View File

@ -0,0 +1,37 @@
#define STRINGIFY2(X) #X
#define STRINGIFY(X) STRINGIFY2(X)
.section .nloader, "a"
.global _start
_start:
/* make sure all exceptions disabled */
msr daifset, 0xf
/* make sure mmu disable */
mrs x0, sctlr_el1
mov x1, #1
bic x0, x0, x1
msr sctlr_el1, x0
isb
/* boot protocol */
adr x0, __dtb_start
mov x1, xzr
mov x2, xzr
mov x3, xzr
/* jump to linux */
ldr x4, =_start
ldr x5, =__linux_start
sub x4, x5, x4
adr x5, _start
add x5, x5, x4
br x5
.section .linux, "a"
.incbin STRINGIFY(IMAGE)
.section .dtb, "a"
.incbin STRINGIFY(DTB)

20
guests/linux/lloader/aarch64.ld Executable file
View File

@ -0,0 +1,20 @@
ENTRY(_start)
SECTIONS
{
.nloader : {
KEEP(*(.nloader))
}
.dtb : ALIGN(8) {
__dtb_start = ABSOLUTE(.);
KEEP(*(.dtb))
__dtb_end = .;
}
.linux 0x80000 : {
__linux_start = .;
KEEP(*(.linux))
__linux_end = .;
}
}

22
guests/linux/lloader/riscv.S Executable file
View File

@ -0,0 +1,22 @@
#define STRINGIFY2(X) #X
#define STRINGIFY(X) STRINGIFY2(X)
.section .nloader, "a"
.global _start
_start:
/* boot protocol */
/* We are expecting hartid in a0 */
la a1, __dtb_start
/* jump to linux */
la t0, __linux_start
jalr t0
j .
.section .linux, "a"
.incbin STRINGIFY(IMAGE)
.section .dtb, "a"
.incbin STRINGIFY(DTB)

20
guests/linux/lloader/riscv.ld Executable file
View File

@ -0,0 +1,20 @@
ENTRY(_start)
SECTIONS
{
.nloader : {
KEEP(*(.nloader))
}
.linux : ALIGN(0x200000) {
__linux_start = .;
KEEP(*(.linux))
__linux_end = .;
}
.dtb : ALIGN(0x200000) {
__dtb_start = ABSOLUTE(.);
KEEP(*(.dtb))
__dtb_end = .;
}
}

39
guests/linux/make.mk Normal file
View File

@ -0,0 +1,39 @@
linux_repo?=https://github.com/torvalds/linux.git
linux_version?=v5.11
linux_src:=$(wrkdir_src)/linux-$(linux_version)
linux_cfg_frag:=$(wildcard $(bao_demos)/guests/linux/configs/base.config\
$(bao_demos)/guests/linux/configs/$(ARCH).config\
$(bao_demos)/guests/linux/configs/$(PLATFORM).config)
linux_patches:=$(wildcard $(bao_demos)/guests/linux/patches/$(linux_version)/*.patch)
$(linux_src):
git clone --depth 1 --branch $(linux_version) $(linux_repo) $(linux_src)
git -C $(linux_src) apply "$(linux_patches)"
buildroot_repo:=https://github.com/buildroot/buildroot.git
buildroot_version:=2020.11.3
buildroot_src:=$(wrkdir_src)/buildroot-$(ARCH)-$(linux_version)
buildroot_defcfg:=$(bao_demos)/guests/linux/buildroot/$(ARCH).config
$(buildroot_src):
git clone --depth 1 --branch $(buildroot_version) $(buildroot_repo)\
$(buildroot_src)
buildroot_image:=$(buildroot_src)/output/images/Image-$(PLATFORM)
export LINUX_OVERRIDE_SRCDIR=$(linux_src)
export BAO_DEMOS_LINUX_CFG_FRAG=$(linux_cfg_frag)
linux $(buildroot_image): $(linux_patches) $(linux_cfg_frag) $(buildroot_defcfg) | $(linux_src) $(buildroot_src)
$(MAKE) -C $(buildroot_src) defconfig BR2_DEFCONFIG=$(buildroot_defcfg)
$(MAKE) -C $(buildroot_src) linux-reconfigure all
mv $(buildroot_src)/output/images/Image $(buildroot_image)
lloader_dir:=$(bao_demos)/guests/linux/lloader
define build-linux
$(wrkdir_demo_imgs)/$(basename $(notdir $2)).dtb: $(strip $2)
dtc $$< > $$@
$(strip $1): $(buildroot_image) $(wrkdir_demo_imgs)/$(basename $(notdir $2)).dtb
$(MAKE) -C $(lloader_dir) ARCH=$(ARCH) IMAGE=$(buildroot_image)\
DTB=$(wrkdir_demo_imgs)/$(basename $(notdir $2)).dtb TARGET=$(basename $$@)
endef

View File

@ -0,0 +1,353 @@
From fec89b9845b4d518ed8841f42f41d90370908be6 Mon Sep 17 00:00:00 2001
From: Jose Martins <josemartins90@gmail.com>
Date: Sat, 6 Mar 2021 22:51:24 +0000
Subject: [PATCH] add bao ipcshmem driver
Signed-off-by: Jose Martins <josemartins90@gmail.com>
---
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/bao/Kconfig | 5 +
drivers/bao/Makefile | 2 +
drivers/bao/bao-ipcshmem.c | 288 +++++++++++++++++++++++++++++++++++++
5 files changed, 298 insertions(+)
create mode 100755 drivers/bao/Kconfig
create mode 100644 drivers/bao/Makefile
create mode 100644 drivers/bao/bao-ipcshmem.c
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 3986e201f..6a0bb385b 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -229,4 +229,6 @@ source "drivers/interconnect/Kconfig"
source "drivers/counter/Kconfig"
source "drivers/mxc/Kconfig"
+
+source "drivers/bao/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 5792caca1..61ef5b5fd 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -187,3 +187,4 @@ obj-$(CONFIG_GNSS) += gnss/
obj-$(CONFIG_INTERCONNECT) += interconnect/
obj-$(CONFIG_COUNTER) += counter/
obj-y += mxc/
+obj-$(CONFIG_BAO_SHMEM) += bao/
diff --git a/drivers/bao/Kconfig b/drivers/bao/Kconfig
new file mode 100755
index 000000000..dc5e9fc08
--- /dev/null
+++ b/drivers/bao/Kconfig
@@ -0,0 +1,5 @@
+config BAO_SHMEM
+ tristate "Bao shared memory support"
+
+ help
+ This implements an interface to communicate with bao hosted guests.
diff --git a/drivers/bao/Makefile b/drivers/bao/Makefile
new file mode 100644
index 000000000..f900be88e
--- /dev/null
+++ b/drivers/bao/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_BAO_SHMEM) += bao.o
+bao-objs += bao-ipcshmem.o
diff --git a/drivers/bao/bao-ipcshmem.c b/drivers/bao/bao-ipcshmem.c
new file mode 100644
index 000000000..9a25367b0
--- /dev/null
+++ b/drivers/bao/bao-ipcshmem.c
@@ -0,0 +1,288 @@
+/**
+ * TODO: licsense
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <asm/io.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/platform_device.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+
+#ifdef CONFIG_ARM64
+#include <asm/memory.h>
+#elif CONFIG_RISCV
+#include <asm/sbi.h>
+#endif
+
+#define DEV_NAME "baoipc"
+#define MAX_DEVICES 16
+#define NAME_LEN 32
+
+static dev_t bao_ipcshmem_devt;
+struct class *cl;
+
+struct bao_ipcshmem
+{
+ struct cdev cdev;
+ struct device *dev;
+
+ int id;
+ char label[NAME_LEN];
+ void* read_base;
+ size_t read_size;
+ void* write_base;
+ size_t write_size;
+};
+
+#ifdef CONFIG_ARM64
+static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) {
+ register uint64_t x0 asm("x0") = 1;
+ register uint64_t x1 asm("x1") = dev->id;
+ register uint64_t x2 asm("x2") = 0;
+
+ asm volatile(
+ "hvc 0\t\n"
+ : "=r"(x0)
+ : "r"(x0), "r"(x1), "r"(x2)
+ );
+
+ return x0;
+}
+#elif CONFIG_RISCV
+static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) {
+
+ struct sbiret ret =
+ sbi_ecall(0x08000ba0, 1, dev->id, 0, 0, 0, 0, 0);
+
+ return ret.error;
+}
+#endif
+
+static ssize_t bao_ipcshmem_read_fops(struct file *filp,
+ char *buf, size_t count, loff_t *ppos)
+{
+ struct bao_ipcshmem *bao_ipcshmem = filp->private_data;
+ unsigned long missing = 0;
+ size_t len = 0;
+
+ len = strnlen(bao_ipcshmem->read_base, bao_ipcshmem->read_size);
+
+ if (*ppos >= len) return 0;
+ if ((len - *ppos) < count) count = len - *ppos;
+
+ missing =
+ copy_to_user(buf, bao_ipcshmem->read_base + *ppos, count);
+ if(missing != 0) count = count - missing;
+ *ppos += count;
+
+ return count;
+}
+
+static ssize_t bao_ipcshmem_write_fops(struct file *filp,
+ const char *buf, size_t count, loff_t *ppos)
+{
+ struct bao_ipcshmem *bao_ipcshmem = filp->private_data;
+ unsigned long missing = 0;
+
+ if (*ppos >= bao_ipcshmem->write_size)
+ return 0;
+ if(count > bao_ipcshmem->write_size)
+ count = bao_ipcshmem->write_size;
+ if((*ppos + count) > bao_ipcshmem->write_size)
+ count = bao_ipcshmem->write_size - *ppos;
+
+ missing =
+ copy_from_user(bao_ipcshmem->write_base + *ppos, buf, count);
+ if (missing != 0) count = count - missing;
+ *ppos += count;
+
+ bao_ipcshmem_notify(bao_ipcshmem);
+
+ return count;
+}
+
+static int bao_ipcshmem_open_fops(struct inode *inode, struct file *filp)
+{
+ struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev,
+ struct bao_ipcshmem, cdev);
+ filp->private_data = bao_ipcshmem;
+
+ kobject_get(&bao_ipcshmem->dev->kobj);
+
+ return 0;
+}
+
+static int bao_ipcshmem_release_fops(struct inode *inode, struct file *filp)
+{
+ struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev,
+ struct bao_ipcshmem, cdev);
+ filp->private_data = NULL;
+
+ kobject_put(&bao_ipcshmem->dev->kobj);
+
+ return 0;
+}
+
+static struct file_operations bao_ipcshmem_fops = {
+ .owner = THIS_MODULE,
+ .read = bao_ipcshmem_read_fops,
+ .write = bao_ipcshmem_write_fops,
+ .open = bao_ipcshmem_open_fops,
+ .release = bao_ipcshmem_release_fops
+};
+
+int bao_ipcshmem_register(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct device *dev = &(pdev->dev);
+ struct device_node *np = dev->of_node;
+ struct module *owner = THIS_MODULE;
+ struct resource *r;
+ dev_t devt;
+ resource_size_t shmem_size;
+ u32 write_offset, read_offset, write_size, read_size;
+ bool rd_in_range, wr_in_range, disjoint;
+ void* shmem_base_addr = NULL;
+ int id = -1;
+ struct bao_ipcshmem *bao;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if(r == NULL)
+ return -EINVAL;
+ of_property_read_u32_index(np, "read-channel", 0, &read_offset);
+ of_property_read_u32_index(np, "read-channel", 1, &read_size);
+ of_property_read_u32_index(np, "write-channel", 0, &write_offset);
+ of_property_read_u32_index(np, "write-channel", 1, &write_size);
+
+ rd_in_range = (r->start + read_offset + read_size) < r->end;
+ wr_in_range = (r->start + write_offset + write_size) < r->end;
+ disjoint = ((read_offset + read_size) <= write_offset) ||
+ ((write_offset + write_size) <= read_offset);
+
+ if(!rd_in_range || !wr_in_range || !disjoint) {
+ dev_err(&pdev->dev,"invalid channel layout\n");
+ dev_err(&pdev->dev,"rd_in_range = %d, wr_in_range = %d, disjoint = %d\n",
+ rd_in_range, wr_in_range, disjoint);
+ return -EINVAL;
+ }
+
+ shmem_size = r->end - r->start + 1;
+ shmem_base_addr = memremap(r->start, shmem_size, MEMREMAP_WB);
+ if(shmem_base_addr == NULL)
+ return -ENOMEM;
+
+ of_property_read_u32(np, "id", &id);
+ if (id >= MAX_DEVICES) {
+ dev_err(&pdev->dev,"invalid id %d\n", id);
+ ret = -EINVAL;
+ goto err_unmap;
+ }
+
+ bao = devm_kzalloc(&pdev->dev, sizeof(struct bao_ipcshmem), GFP_KERNEL);
+ if(bao == NULL) {
+ ret = -ENOMEM;
+ goto err_unmap;
+ }
+ snprintf(bao->label, NAME_LEN, "%s%d", DEV_NAME, id);
+ bao->id = id;
+ bao->read_size = read_size;
+ bao->write_size = write_size;
+ bao->read_base = shmem_base_addr + read_offset;
+ bao->write_base = shmem_base_addr + write_offset;
+
+ cdev_init(&bao->cdev, &bao_ipcshmem_fops);
+ bao->cdev.owner = owner;
+
+ devt = MKDEV(MAJOR(bao_ipcshmem_devt), id);
+ ret = cdev_add(&bao->cdev, devt, 1);
+ if (ret) {
+ goto err_unmap;
+ }
+
+ bao->dev = device_create(cl, &pdev->dev, devt, bao, bao->label);
+ if (IS_ERR(bao->dev)) {
+ ret = PTR_ERR(bao->dev);
+ goto err_cdev;
+ }
+ dev_set_drvdata(bao->dev, bao);
+
+ return 0;
+
+err_cdev:
+ cdev_del(&bao->cdev);
+err_unmap:
+ memunmap(shmem_base_addr);
+
+ dev_err(&pdev->dev,"failed initialization\n");
+ return ret;
+}
+
+static int bao_ipcshmem_unregister(struct platform_device *pdev)
+{
+ /* TODO */
+ return 0;
+}
+
+static const struct of_device_id of_bao_ipcshmem_match[] = {
+ {
+ .compatible = "bao,ipcshmem",
+ },
+ {/* sentinel */}};
+MODULE_DEVICE_TABLE(of, of_bao_ipcshmem_match);
+
+static struct platform_driver bao_ipcshmem_driver = {
+ .probe = bao_ipcshmem_register,
+ .remove = bao_ipcshmem_unregister,
+ .driver = {
+ .name = DEV_NAME,
+ .of_match_table = of_bao_ipcshmem_match,
+ },
+};
+
+static int __init bao_ipcshmem_init(void)
+{
+ int ret;
+
+ if ((cl = class_create(THIS_MODULE, DEV_NAME)) == NULL) {
+ ret = -1;
+ pr_err("unable to class_create " DEV_NAME " device\n");
+ return ret;
+ }
+
+ ret = alloc_chrdev_region(&bao_ipcshmem_devt, 0, MAX_DEVICES, DEV_NAME);
+ if (ret < 0) {
+ pr_err("unable to alloc_chrdev_region " DEV_NAME " device\n");
+ return ret;
+ }
+
+ return platform_driver_register(&bao_ipcshmem_driver);
+}
+
+static void __exit bao_ipcshmem_exit(void)
+{
+ platform_driver_unregister(&bao_ipcshmem_driver);
+ unregister_chrdev(bao_ipcshmem_devt, DEV_NAME);
+ class_destroy(cl);
+}
+
+module_init(bao_ipcshmem_init);
+module_exit(bao_ipcshmem_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Cerdeira");
+MODULE_AUTHOR("José Martins");
+MODULE_DESCRIPTION("bao ipc through shared-memory sample driver");
--
2.25.1

View File

@ -0,0 +1,353 @@
From 8b6f77465ca53540dfca7f0fda06620689543c11 Mon Sep 17 00:00:00 2001
From: Jose Martins <josemartins90@gmail.com>
Date: Tue, 16 Feb 2021 16:37:13 +0000
Subject: [PATCH] add bao ipcshmem driver
Signed-off-by: Jose Martins <josemartins90@gmail.com>
---
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/bao/Kconfig | 5 +
drivers/bao/Makefile | 2 +
drivers/bao/bao-ipcshmem.c | 288 +++++++++++++++++++++++++++++++++++++
5 files changed, 298 insertions(+)
create mode 100755 drivers/bao/Kconfig
create mode 100644 drivers/bao/Makefile
create mode 100644 drivers/bao/bao-ipcshmem.c
diff --git a/drivers/Kconfig b/drivers/Kconfig
index dcecc9f6e..1d6358888 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -235,4 +235,6 @@ source "drivers/interconnect/Kconfig"
source "drivers/counter/Kconfig"
source "drivers/most/Kconfig"
+
+source "drivers/bao/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 576228037..5f45b99be 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -189,3 +189,4 @@ obj-$(CONFIG_GNSS) += gnss/
obj-$(CONFIG_INTERCONNECT) += interconnect/
obj-$(CONFIG_COUNTER) += counter/
obj-$(CONFIG_MOST) += most/
+obj-$(CONFIG_BAO_SHMEM) += bao/
diff --git a/drivers/bao/Kconfig b/drivers/bao/Kconfig
new file mode 100755
index 000000000..dc5e9fc08
--- /dev/null
+++ b/drivers/bao/Kconfig
@@ -0,0 +1,5 @@
+config BAO_SHMEM
+ tristate "Bao shared memory support"
+
+ help
+ This implements an interface to communicate with bao hosted guests.
diff --git a/drivers/bao/Makefile b/drivers/bao/Makefile
new file mode 100644
index 000000000..f900be88e
--- /dev/null
+++ b/drivers/bao/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_BAO_SHMEM) += bao.o
+bao-objs += bao-ipcshmem.o
diff --git a/drivers/bao/bao-ipcshmem.c b/drivers/bao/bao-ipcshmem.c
new file mode 100644
index 000000000..9a25367b0
--- /dev/null
+++ b/drivers/bao/bao-ipcshmem.c
@@ -0,0 +1,288 @@
+/**
+ * TODO: licsense
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <asm/io.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/platform_device.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+
+#ifdef CONFIG_ARM64
+#include <asm/memory.h>
+#elif CONFIG_RISCV
+#include <asm/sbi.h>
+#endif
+
+#define DEV_NAME "baoipc"
+#define MAX_DEVICES 16
+#define NAME_LEN 32
+
+static dev_t bao_ipcshmem_devt;
+struct class *cl;
+
+struct bao_ipcshmem
+{
+ struct cdev cdev;
+ struct device *dev;
+
+ int id;
+ char label[NAME_LEN];
+ void* read_base;
+ size_t read_size;
+ void* write_base;
+ size_t write_size;
+};
+
+#ifdef CONFIG_ARM64
+static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) {
+ register uint64_t x0 asm("x0") = 1;
+ register uint64_t x1 asm("x1") = dev->id;
+ register uint64_t x2 asm("x2") = 0;
+
+ asm volatile(
+ "hvc 0\t\n"
+ : "=r"(x0)
+ : "r"(x0), "r"(x1), "r"(x2)
+ );
+
+ return x0;
+}
+#elif CONFIG_RISCV
+static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) {
+
+ struct sbiret ret =
+ sbi_ecall(0x08000ba0, 1, dev->id, 0, 0, 0, 0, 0);
+
+ return ret.error;
+}
+#endif
+
+static ssize_t bao_ipcshmem_read_fops(struct file *filp,
+ char *buf, size_t count, loff_t *ppos)
+{
+ struct bao_ipcshmem *bao_ipcshmem = filp->private_data;
+ unsigned long missing = 0;
+ size_t len = 0;
+
+ len = strnlen(bao_ipcshmem->read_base, bao_ipcshmem->read_size);
+
+ if (*ppos >= len) return 0;
+ if ((len - *ppos) < count) count = len - *ppos;
+
+ missing =
+ copy_to_user(buf, bao_ipcshmem->read_base + *ppos, count);
+ if(missing != 0) count = count - missing;
+ *ppos += count;
+
+ return count;
+}
+
+static ssize_t bao_ipcshmem_write_fops(struct file *filp,
+ const char *buf, size_t count, loff_t *ppos)
+{
+ struct bao_ipcshmem *bao_ipcshmem = filp->private_data;
+ unsigned long missing = 0;
+
+ if (*ppos >= bao_ipcshmem->write_size)
+ return 0;
+ if(count > bao_ipcshmem->write_size)
+ count = bao_ipcshmem->write_size;
+ if((*ppos + count) > bao_ipcshmem->write_size)
+ count = bao_ipcshmem->write_size - *ppos;
+
+ missing =
+ copy_from_user(bao_ipcshmem->write_base + *ppos, buf, count);
+ if (missing != 0) count = count - missing;
+ *ppos += count;
+
+ bao_ipcshmem_notify(bao_ipcshmem);
+
+ return count;
+}
+
+static int bao_ipcshmem_open_fops(struct inode *inode, struct file *filp)
+{
+ struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev,
+ struct bao_ipcshmem, cdev);
+ filp->private_data = bao_ipcshmem;
+
+ kobject_get(&bao_ipcshmem->dev->kobj);
+
+ return 0;
+}
+
+static int bao_ipcshmem_release_fops(struct inode *inode, struct file *filp)
+{
+ struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev,
+ struct bao_ipcshmem, cdev);
+ filp->private_data = NULL;
+
+ kobject_put(&bao_ipcshmem->dev->kobj);
+
+ return 0;
+}
+
+static struct file_operations bao_ipcshmem_fops = {
+ .owner = THIS_MODULE,
+ .read = bao_ipcshmem_read_fops,
+ .write = bao_ipcshmem_write_fops,
+ .open = bao_ipcshmem_open_fops,
+ .release = bao_ipcshmem_release_fops
+};
+
+int bao_ipcshmem_register(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct device *dev = &(pdev->dev);
+ struct device_node *np = dev->of_node;
+ struct module *owner = THIS_MODULE;
+ struct resource *r;
+ dev_t devt;
+ resource_size_t shmem_size;
+ u32 write_offset, read_offset, write_size, read_size;
+ bool rd_in_range, wr_in_range, disjoint;
+ void* shmem_base_addr = NULL;
+ int id = -1;
+ struct bao_ipcshmem *bao;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if(r == NULL)
+ return -EINVAL;
+ of_property_read_u32_index(np, "read-channel", 0, &read_offset);
+ of_property_read_u32_index(np, "read-channel", 1, &read_size);
+ of_property_read_u32_index(np, "write-channel", 0, &write_offset);
+ of_property_read_u32_index(np, "write-channel", 1, &write_size);
+
+ rd_in_range = (r->start + read_offset + read_size) < r->end;
+ wr_in_range = (r->start + write_offset + write_size) < r->end;
+ disjoint = ((read_offset + read_size) <= write_offset) ||
+ ((write_offset + write_size) <= read_offset);
+
+ if(!rd_in_range || !wr_in_range || !disjoint) {
+ dev_err(&pdev->dev,"invalid channel layout\n");
+ dev_err(&pdev->dev,"rd_in_range = %d, wr_in_range = %d, disjoint = %d\n",
+ rd_in_range, wr_in_range, disjoint);
+ return -EINVAL;
+ }
+
+ shmem_size = r->end - r->start + 1;
+ shmem_base_addr = memremap(r->start, shmem_size, MEMREMAP_WB);
+ if(shmem_base_addr == NULL)
+ return -ENOMEM;
+
+ of_property_read_u32(np, "id", &id);
+ if (id >= MAX_DEVICES) {
+ dev_err(&pdev->dev,"invalid id %d\n", id);
+ ret = -EINVAL;
+ goto err_unmap;
+ }
+
+ bao = devm_kzalloc(&pdev->dev, sizeof(struct bao_ipcshmem), GFP_KERNEL);
+ if(bao == NULL) {
+ ret = -ENOMEM;
+ goto err_unmap;
+ }
+ snprintf(bao->label, NAME_LEN, "%s%d", DEV_NAME, id);
+ bao->id = id;
+ bao->read_size = read_size;
+ bao->write_size = write_size;
+ bao->read_base = shmem_base_addr + read_offset;
+ bao->write_base = shmem_base_addr + write_offset;
+
+ cdev_init(&bao->cdev, &bao_ipcshmem_fops);
+ bao->cdev.owner = owner;
+
+ devt = MKDEV(MAJOR(bao_ipcshmem_devt), id);
+ ret = cdev_add(&bao->cdev, devt, 1);
+ if (ret) {
+ goto err_unmap;
+ }
+
+ bao->dev = device_create(cl, &pdev->dev, devt, bao, bao->label);
+ if (IS_ERR(bao->dev)) {
+ ret = PTR_ERR(bao->dev);
+ goto err_cdev;
+ }
+ dev_set_drvdata(bao->dev, bao);
+
+ return 0;
+
+err_cdev:
+ cdev_del(&bao->cdev);
+err_unmap:
+ memunmap(shmem_base_addr);
+
+ dev_err(&pdev->dev,"failed initialization\n");
+ return ret;
+}
+
+static int bao_ipcshmem_unregister(struct platform_device *pdev)
+{
+ /* TODO */
+ return 0;
+}
+
+static const struct of_device_id of_bao_ipcshmem_match[] = {
+ {
+ .compatible = "bao,ipcshmem",
+ },
+ {/* sentinel */}};
+MODULE_DEVICE_TABLE(of, of_bao_ipcshmem_match);
+
+static struct platform_driver bao_ipcshmem_driver = {
+ .probe = bao_ipcshmem_register,
+ .remove = bao_ipcshmem_unregister,
+ .driver = {
+ .name = DEV_NAME,
+ .of_match_table = of_bao_ipcshmem_match,
+ },
+};
+
+static int __init bao_ipcshmem_init(void)
+{
+ int ret;
+
+ if ((cl = class_create(THIS_MODULE, DEV_NAME)) == NULL) {
+ ret = -1;
+ pr_err("unable to class_create " DEV_NAME " device\n");
+ return ret;
+ }
+
+ ret = alloc_chrdev_region(&bao_ipcshmem_devt, 0, MAX_DEVICES, DEV_NAME);
+ if (ret < 0) {
+ pr_err("unable to alloc_chrdev_region " DEV_NAME " device\n");
+ return ret;
+ }
+
+ return platform_driver_register(&bao_ipcshmem_driver);
+}
+
+static void __exit bao_ipcshmem_exit(void)
+{
+ platform_driver_unregister(&bao_ipcshmem_driver);
+ unregister_chrdev(bao_ipcshmem_devt, DEV_NAME);
+ class_destroy(cl);
+}
+
+module_init(bao_ipcshmem_init);
+module_exit(bao_ipcshmem_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Cerdeira");
+MODULE_AUTHOR("José Martins");
+MODULE_DESCRIPTION("bao ipc through shared-memory sample driver");
--
2.25.1

17
platforms/README.md Normal file
View File

@ -0,0 +1,17 @@
## Bao Target Platforms
Bao currently supports a number of Armv8 platforms using the Aarch64 ISA, as
well as RISC-V using RV64:
### AArch64 platforms:
* [Xilinx ZCU102/4](platform/zcu.md)
* [Avnet Ultra96](platform/ultra96.md)
* [NXP i.MX8QM](platform/imx8qm.md)
* [Nvidia TX2](platform/tx2.md)
* [Raspberry 4 Model B](platform/rpi4.md)
* [QEMU virt](platform/qemu-aarch64-virt.md)
### RV64 platforms:
* [QEMU virt](platform/qemu-aarch64-virt.md)
<!-- * [Rocket ???](platform/) -->
<!-- * [Rocket Firesim*](platform/) -->

11
platforms/atf.mk Normal file
View File

@ -0,0 +1,11 @@
atf_repo:=https://github.com/bao-project/arm-trusted-firmware.git
atf_src:=$(wrkdir_src)/arm-trusted-firmware
$(atf_src):
git clone --depth 1 $(atf_repo) $(atf_src)
define build-atf
$(strip $1): $(atf_src)
$(MAKE) -C $(atf_src) bl31 PLAT=$(strip $2) $(strip $3)
cp $(atf_src)/build/$(strip $2)/release/bl31.bin $$@
endef

170
platforms/imx8qm/README.md Normal file
View File

@ -0,0 +1,170 @@
# NXP IMX8QM
## 1) Setup firmware
Creat a directory to put the imx build tools:
```
export BAO_DEMOS_NXP_TOOLS=$BAO_DEMOS_WRKDIR_SRC/nxp-tools
mkdir -p $BAO_DEMOS_NXP_TOOLS/scfw
```
### 1.1) SCFW
```
wget -P $BAO_DEMOS_NXP_TOOLS\
https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-sc-firmware-1.5.0.bin
cd $BAO_DEMOS_NXP_TOOLS
chmod +x imx-sc-firmware-1.5.0.bin
noask=1 ./imx-sc-firmware-1.5.0.bin
```
### 1.2) SECO
Download the and install the seco binary:
```
wget -P $BAO_DEMOS_NXP_TOOLS\
https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-seco-3.6.3.bin
cd $BAO_DEMOS_NXP_TOOLS
chmod a+x imx-seco-3.6.3.bin
noask=1 ./imx-seco-3.6.3.bin
```
## 1.3) Build U-boot
Setup the u-boot directory variable:
```
export BAO_DEMOS_UBOOT=$BAO_DEMOS_WRKDIR_SRC/u-boot
```
Download, configure and build it:
```
git clone https://github.com/u-boot/u-boot.git $BAO_DEMOS_UBOOT\
--depth 1 --branch v2021.01
cd $BAO_DEMOS_UBOOT
make imx8qm_mek_defconfig
make -j $(nproc)
```
And copy the image to the platform's working directory:
```
cp $BAO_DEMOS_UBOOT/u-boot.bin $BAO_DEMOS_WRKDIR_PLAT
```
### 1.4) Build TF-A
Setup the TF-A directory variable:
```
export BAO_DEMOS_ATF=$BAO_DEMOS_WRKDIR_SRC/arm-trusted-firmware
```
Download and build it:
```
git clone https://github.com/bao-project/arm-trusted-firmware.git\
$BAO_DEMOS_ATF --depth 1
cd $BAO_DEMOS_ATF
make PLAT=imx8qm bl31
```
And copy the image to the platform's working directory:
```
cp $BAO_DEMOS_ATF/build/imx8qm/release/bl31.bin $BAO_DEMOS_WRKDIR_PLAT
```
### 1.5) NXP's mkimage tool
```
git clone https://source.codeaurora.org/external/imx/imx-mkimage\
$BAO_DEMOS_NXP_TOOLS/imx-mkimage --depth 1 --branch rel_imx_5.4.24_2.1.0
```
Go to imx-mkimage target platform directory and copy over the scfw seco firmware
as well as the TF-A's bl31 and uboot binaries. Then build firmware binary.
```
cd $BAO_DEMOS_NXP_TOOLS/imx-mkimage
cp $BAO_DEMOS_NXP_TOOLS/imx-sc-firmware-1.5.0/mx8qm-mek-scfw-tcm.bin\
iMX8QM/scfw_tcm.bin
cp $BAO_DEMOS_NXP_TOOLS/imx-seco-3.6.3/firmware/seco/mx8qmb0-ahab-container.img\
iMX8QM
cp $BAO_DEMOS_WRKDIR_PLAT/bl31.bin iMX8QM
cp $BAO_DEMOS_WRKDIR_PLAT/u-boot.bin iMX8QM
make SOC=iMX8QM flash_b0
cp iMX8QM/flash.bin $BAO_DEMOS_WRKDIR_IMGS
```
<!--- instruction#1 -->
## 2) Setup SD card
Finally, [prepare your sd card](./../../platforms/sdcard.md), install the
firmware on it, and copy bao's final image to it:
---
**WARNING**
Make sure the sd card is properly inserted and $BAO_DEMOS_SDCARD_DEV
exists (for example using `ls $BAO_DEMOS_SDCARD_DEV`) before running `dd`!
Otherwise it will simply create the file and not actually write to the card. If
this happens you might need to delete it by using
`sudo rm $BAO_DEMOS_SDCARD_DEV`.
---
```
test -e $BAO_DEMOS_SDCARD_DEV &&\
sudo dd if=$BAO_DEMOS_WRKDIR_IMGS/flash.bin\
of=$BAO_DEMOS_SDCARD_DEV bs=1k seek=32 || echo Failed flashing sd card!
cp $BAO_DEMOS_WRKDIR_IMGS/bao.bin $BAO_DEMOS_SDCARD
umount $BAO_DEMOS_SDCARD
```
<!--- instruction#2 -->
## 3) Setup board
Make sure you have the board configured to boot from SD card. Checkout out the
[Get Started with the i.MX 8QuadMax MEK](https://www.nxp.com/document/guide/get-started-with-the-i-mx-8quadmax-mek:GS-iMX-8QM-MEK)
guide for more information on the boot switch setup.
Insert the sd card in the board's sd slot.
Connect to the UART via the USB cable. If you are using the dual guest
configuration, connect to both available UARTs (in our setup /dev/ttyUSB0)
with baud 115200.
Open a new terminal and connect to it. For example:
```
screen /dev/ttyUSB0 115200
```
Reset the board.
You should be presented with the u-boot prompt.
<!--- instruction#3 -->
## 4) Run u-boot commands
Quickly press any key to skip autoboot. If not possibly press `ctrl-c` until
you get the u-boot prompt. Then load the bao image, and jump to it:
```
fatload mmc 1 0x80200000 bao.bin && go 0x80200000
```
You should see a message from Bao followed by the guests' output on the UART
console.
At this point, depending on your demo, you might be able connect to one of the
guests via ssh by connecting to the board's ethernet RJ54 socket.
<!--- instruction#end -->

58
platforms/imx8qm/make.mk Normal file
View File

@ -0,0 +1,58 @@
ARCH:=aarch64
nxp_tools:=$(wrkdir_src)/nxp-tools
wrkdirs+=$(nxp_tools)
ifeq ($(ALWAYS_ASK),)
noask:=1
endif
scfw:=$(nxp_tools)/imx-sc-firmware-1.5.0/mx8qm-mek-scfw-tcm.bin
scfw_link:=https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-sc-firmware-1.5.0.bin
$(scfw):
wget -P $(nxp_tools) $(scfw_link)
cd $(nxp_tools) && chmod +x imx-sc-firmware-1.5.0.bin
cd $(nxp_tools) && noask=$(noask) ./imx-sc-firmware-1.5.0.bin
seco:=$(nxp_tools)/imx-seco-3.6.3/firmware/seco/mx8qmb0-ahab-container.img
seco_link:=https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-seco-3.6.3.bin
$(seco):
wget -P $(nxp_tools) $(seco_link)
cd $(nxp_tools) && chmod +x imx-seco-3.6.3.bin
cd $(nxp_tools) && noask=$(noask) ./imx-seco-3.6.3.bin
include $(bao_demos)/platforms/uboot.mk
uboot_image:=$(wrkdir_demo_imgs)/u-boot.bin
uboot_defconfig:=imx8qm_mek_defconfig
$(eval $(call build-uboot, $(uboot_image), $(uboot_defconfig)))
include $(bao_demos)/platforms/atf.mk
atf_image:=$(wrkdir_demo_imgs)/bl31.bin
atf_plat:=imx8qm
$(eval $(call build-atf, $(atf_image), $(atf_plat)))
nxp_mkimage:=$(nxp_tools)/imx-mkimage
nxp_mkimage_repo:=https://source.codeaurora.org/external/imx/imx-mkimage
nxp_mkimage_vesion:=rel_imx_5.4.24_2.1.0
$(nxp_mkimage):
git clone --depth 1 --branch $(nxp_mkimage_vesion) $(nxp_mkimage_repo)\
$(nxp_mkimage)
flash_image:=$(wrkdir_demo_imgs)/flash.bin
$(flash_image): $(nxp_mkimage) $(scfw) $(seco) $(atf_image) $(uboot_image)
cp $(scfw) $(nxp_mkimage)/iMX8QM/scfw_tcm.bin
cp $(seco) $(nxp_mkimage)/iMX8QM
cp $(atf_image) $(nxp_mkimage)/iMX8QM
cp $(uboot_image) $(nxp_mkimage)/iMX8QM
cd $(nxp_mkimage) && $(MAKE) SOC=iMX8QM flash_b0
cp $(nxp_mkimage)/iMX8QM/flash.bin $@
# override default linux repo and version
linux_repo:=https://source.codeaurora.org/external/imx/linux-imx
linux_version:=rel_imx_5.4.24_2.1.0
instructions:=$(bao_demos)/platforms/$(PLATFORM)/README.md
platform: $(bao_image) $(flash_image)
$(call print-instructions, $(instructions), 1, false)
$(call print-instructions, $(instructions), 2, false)
$(call print-instructions, $(instructions), 3, true)

15
platforms/opensbi.mk Normal file
View File

@ -0,0 +1,15 @@
opensbi_repo:=https://github.com/bao-project/opensbi.git
opensbi_version:=bao
opensbi_src:=$(wrkdir_src)/opensbi
$(opensbi_src):
git clone --depth 1 --branch $(opensbi_version) $(opensbi_repo) $(opensbi_src)
define build-opensbi-payload
$(strip $1): $(strip $2) $(opensbi_src)
$(MAKE) -C $(opensbi_src) PLATFORM=generic \
FW_PAYLOAD=y \
FW_PAYLOAD_FDT_ADDR=0x80100000\
FW_PAYLOAD_PATH=$(strip $2)
cp $(opensbi_src)/build/platform/generic/firmware/fw_payload.elf $$@
endef

View File

@ -0,0 +1,122 @@
# Qemu Aarch64 virt
## 1) Download build and install Aarch64 qemu
---
**NOTE**
If you already have qemu-system-aarch64 installed or you don't want to compile
it but install it directly using a package manager or some other method, please
make sure you are using version 5.2.0 or higher. If so, you can skip this step.
---
```
export BAO_DEMOS_QEMU=$BAO_DEMOS_WRKDIR_SRC/qemu-$ARCH
git clone https://github.com/qemu/qemu.git $BAO_DEMOS_QEMU --depth 1\
--branch v5.2.0
cd $BAO_DEMOS_QEMU
./configure --target-list=aarch64-softmmu
make -j$(nproc)
sudo make install
```
## 2) Build U-boot
```
export BAO_DEMOS_UBOOT=$BAO_DEMOS_WRKDIR_SRC/u-boot
git clone https://github.com/u-boot/u-boot.git $BAO_DEMOS_UBOOT --depth 1\
--branch v2021.01
cd $BAO_DEMOS_UBOOT
make qemu_arm64_defconfig
```
Now you need to set the Kconfig options:
* CONFIG_TFABOOT=y
* CONFIG_SYS_TEXT_BASE=0x60000000
You can do it via using an interface such as `menuconfig` or just write them
directly to the config file:
```
echo "CONFIG_TFABOOT=y" >> .config
echo "CONFIG_SYS_TEXT_BASE=0x60000000" >> .config
```
Then build it:
```
make -j$(nproc)
```
And copy the image to the platform's working directory:
```
cp $BAO_DEMOS_UBOOT/u-boot.bin $BAO_DEMOS_WRKDIR/imgs/$PLATFORM
```
## 3) Build TF-A
```
export BAO_DEMOS_ATF=$BAO_DEMOS_WRKDIR_SRC/arm-trusted-firmware
git clone https://github.com/bao-project/arm-trusted-firmware.git\
$BAO_DEMOS_ATF --depth 1
cd $BAO_DEMOS_ATF
make PLAT=qemu bl1 fip BL33=$BAO_DEMOS_WRKDIR/imgs/$PLATFORM/u-boot.bin\
QEMU_USE_GIC_DRIVER=QEMU_GICV3
dd if=$BAO_DEMOS_ATF/build/qemu/release/bl1.bin\
of=$BAO_DEMOS_WRKDIR/imgs/$PLATFORM/flash.bin
dd if=$BAO_DEMOS_ATF/build/qemu/release/fip.bin\
of=$BAO_DEMOS_WRKDIR/imgs/$PLATFORM/flash.bin seek=64 bs=4096 conv=notrunc
```
## 4) Run QEMU
```
qemu-system-aarch64 -nographic\
-M virt,secure=on,virtualization=on,gic-version=3 \
-cpu cortex-a53 -smp 4 -m 4G\
-bios $BAO_DEMOS_WRKDIR/imgs/$PLATFORM/flash.bin \
-device loader,file="$BAO_DEMOS_WRKDIR_IMGS/bao.bin",addr=0x50000000,force-raw=on\
-device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22\
-device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3
```
You should see TF-A and U-boot initialization messages.
<!--- instruction#1 -->
## 5) Setup connections and jump to Bao
Qemu will let you know in which pseudo-terminals it placed the virtio serial.
For example:
```
char device redirected to /dev/pts/4 (label serial3)
```
If you are running more than one guest, open a new terminal and connect to it.
For example:
```
screen /dev/pts/4
```
If you are running a Linux guest you can also connect via ssh to it by opening
a new terminal and running:
```
ssh root@localhost -p 5555
```
Finally, make u-boot jump to where the bao image was loaded:
```
go 0x50000000
```
When you want to leave QEMU press `Ctrl-a` then `x`.
<!--- instruction#end -->

View File

@ -0,0 +1,39 @@
ARCH:=aarch64
include $(bao_demos)/platforms/qemu.mk
include $(bao_demos)/platforms/uboot.mk
uboot_defconfig:=qemu_arm64_defconfig
uboot_cfg_frag:="CONFIG_SYS_TEXT_BASE=0x60000000\nCONFIG_TFABOOT=y\n"
uboot_image:=$(wrkdir_plat_imgs)/u-boot.bin
$(eval $(call build-uboot, $(uboot_image), $(uboot_defconfig), $(uboot_cfg_frag)))
atf_plat:=qemu
atf_targets:=bl1 fip
atf_flags+=BL33=$(wrkdir_plat_imgs)/u-boot.bin
atf_flags+=QEMU_USE_GIC_DRIVER=QEMU_GICV3
include $(bao_demos)/platforms/atf.mk
atf-fip:=$(wrkdir_plat_imgs)/flash.bin
$(atf-fip): $(uboot_image) $(atf_src)
$(MAKE) -C $(atf_src) PLAT=$(atf_plat) $(atf_targets) $(atf_flags)
dd if=$(atf_src)/build/qemu/release/bl1.bin of=$(atf-fip)
dd if=$(atf_src)/build/qemu/release/fip.bin of=$(atf-fip) seek=64 bs=4096 conv=notrunc
platform: $(bao_image) $(atf-fip)
instuctions:=$(bao_demos)/platforms/$(PLATFORM)/README.md
run: qemu platform
$(call print-instructions, $(instuctions), 1, false)
@$(qemu_cmd) -nographic\
-M virt,secure=on,virtualization=on,gic-version=3 \
-cpu cortex-a53 -smp 4 -m 4G\
-bios $(atf-fip)\
-device loader,file="$(bao_image)",addr=0x50000000,force-raw=on\
-device virtio-net-device,netdev=net0\
-netdev user,id=net0,net=192.168.42.0/24,hostfwd=tcp:127.0.0.1:5555-:22\
-device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3
.PHONY: run

View File

@ -0,0 +1,86 @@
# Qemu RV64 virt
## 1) Download build and install RV64 qemu
---
**NOTE**
For now you really need to use our patched QEMU because currently RISC-V QEMU
is missing a couple small features from the latest draft Hypervisor
specification that Bao depends on to run correctly. We have submitted patches
to fix these issues which we hope will be merged and available in the next
release.
---
```
export BAO_DEMOS_QEMU=$BAO_DEMOS_WRKDIR_SRC/qemu-$ARCH
git clone https://github.com/josecm/qemu.git $BAO_DEMOS_QEMU --depth 1\
--branch josecm/hyp
cd $BAO_DEMOS_QEMU
./configure --target-list=riscv64-softmmu
make -j$(nproc)
sudo make install
```
## 2) Compile OpenSBI
```
export BAO_DEMOS_OPENSBI=$BAO_DEMOS_WRKDIR_SRC/opensbi
git clone https://github.com/bao-project/opensbi.git $BAO_DEMOS_OPENSBI\
--depth 1
make -C $BAO_DEMOS_OPENSBI PLATFORM=generic \
FW_PAYLOAD=y \
FW_PAYLOAD_FDT_ADDR=0x80100000\
FW_PAYLOAD_PATH=$BAO_DEMOS_WRKDIR_IMGS/bao.bin
cp $BAO_DEMOS_OPENSBI/build/platform/generic/firmware/fw_payload.elf\
$BAO_DEMOS_WRKDIR_IMGS/opensbi.elf
```
## 3) Run QEMU
```
qemu-system-riscv64 -nographic\
-M virt -cpu rv64,priv_spec=v1.10.0,x-h=true -m 4G -smp 4 -serial pty\
-bios $BAO_DEMOS_WRKDIR_IMGS/opensbi.elf\
-device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22\
-device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3 -S
```
<!--- instruction#1 -->
## 4) Setup connections and jump to Bao
Qemu will let you know in which pseudo-terminals it placed the virtio serial.
For example:
```
char device redirected to /dev/pts/4 (label serial3)
```
Open a new terminal and connect to it. For example:
```
screen /dev/pts/4
```
Finally, start the emulation by pressing `Ctrl-a` then `c` in the terminal you
launched qemu to access the monitor console and running:
```
(qemu) cont
```
Then, press `Ctrl-a` and `c` again to be able to interact with the guest
through the serial console.
If you are running a Linux guest you can also connect via ssh to it by opening
a new terminal and running:
```
ssh root@localhost -p 5555
```
When you want to leave QEMU press `Ctrl-a` then `x`.
<!--- instruction#end -->

View File

@ -0,0 +1,20 @@
ARCH:=riscv
include $(bao_demos)/platforms/qemu.mk
include $(bao_demos)/platforms/opensbi.mk
opensbi_image:=$(wrkdir_demo_imgs)/opensbi.elf
$(eval $(call build-opensbi-payload, $(opensbi_image), $(bao_image)))
platform: $(opensbi_image)
instructions:=$(bao_demos)/platforms/$(PLATFORM)/README.md
run: qemu platform
$(call print-instructions, $(instructions), 1, true)
$(qemu_cmd) -nographic\
-M virt -cpu rv64,priv_spec=v1.10.0,x-h=true -m 4G -smp 4\
-bios $(opensbi_image)\
-device virtio-net-device,netdev=net0\
-netdev user,id=net0,net=192.168.42.0/24,hostfwd=tcp:127.0.0.1:5555-:22\
-device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3\
-S

35
platforms/qemu.mk Normal file
View File

@ -0,0 +1,35 @@
ifeq ($(ARCH),riscv)
qemu_arch:=riscv64
else
qemu_arch:=$(ARCH)
endif
qemu_repo:=https://github.com/qemu.git
qemu_version:=v5.2.0
qemu_cmd:=qemu-system-$(qemu_arch)
#override the qemu repo to our patched repo
#TODO: remove this when small riscv bugs on qemu are fixed
qemu_repo:=https://github.com/josecm/qemu.git
qemu_cur_ver:=josecm/hyp
ifeq ($(shell which $(qemu_cmd)),)
qemu_src:=$(wrkdir_src)/qemu
qemu_cmd:=$(qemu_src)/build/$(qemu_cmd)
$(qemu_src):
git clone --depth 1 --branch $(qemu_cur_ver) $(qemu_repo) $(qemu_src)
$(qemu_cmd): | $(qemu_src)
cd $(qemu_src) && ./configure --target-list=$(qemu_arch)-softmmu
$(MAKE) -C $(qemu_src) -j$(nproc)
qemu: $(qemu_cmd)
else
# TODO: add version check if qemu is already installed
qemu:
endif
all:
@printf "\nTo start qemu execute \"make PLATFORM=$(PLATFORM) DEMO=$(DEMO) run\"\n\n"
.PHONY: qemu

100
platforms/rpi4/README.md Normal file
View File

@ -0,0 +1,100 @@
# Raspberry Pi 4 Model B
## 1) Get firmware
Download the lastest firmware files for Raspberry Pi:
```
export BAO_DEMOS_FW=$BAO_DEMOS_WRKDIR_PLAT/firmware
git clone https://github.com/raspberrypi/firmware.git $BAO_DEMOS_FW\
--depth 1 --branch 1.20210201
```
## 2) Build U-boot
```
export BAO_DEMOS_UBOOT=$BAO_DEMOS_WRKDIR_SRC/u-boot
git clone https://github.com/u-boot/u-boot.git $BAO_DEMOS_UBOOT\
--depth 1 --branch v2021.01
cd $BAO_DEMOS_UBOOT
make rpi_4_defconfig
```
Then build it:
```
make -j $(nproc)
```
And copy the image to the platform's working directory:
```
cp $BAO_DEMOS_UBOOT/u-boot.bin $BAO_DEMOS_WRKDIR_PLAT
```
## 3) Build TF-A
```
export BAO_DEMOS_ATF=$BAO_DEMOS_WRKDIR_SRC/arm-trusted-firmware
git clone https://github.com/bao-project/arm-trusted-firmware.git\
$BAO_DEMOS_ATF --depth 1
cd $BAO_DEMOS_ATF
make PLAT=rpi4
```
And copy the image to the platform's working directory:
```
cp $BAO_DEMOS_ATF/build/rpi4/release/bl31.bin $BAO_DEMOS_WRKDIR_PLAT
```
<!--- instruction#1 -->
## 3) Setup SD card
After [preparing your sd card](../../platforms/sdcard.md), copy the firmware
and bao's final image to it:
```
cp -rf $BAO_DEMOS_WRKDIR_PLAT/firmware/boot/* $BAO_DEMOS_SDCARD
cp $BAO_DEMOS/platforms/rpi4/config.txt $BAO_DEMOS_SDCARD
cp $BAO_DEMOS_WRKDIR_PLAT/bl31.bin $BAO_DEMOS_SDCARD
cp $BAO_DEMOS_WRKDIR_PLAT/u-boot.bin $BAO_DEMOS_SDCARD
cp $BAO_DEMOS_WRKDIR_IMGS/bao.bin $BAO_DEMOS_SDCARD
umount $BAO_DEMOS_SDCARD
```
<!--- instruction#2 -->
## 4) Setup board
Insert the sd card in the board's sd slot.
Connect to the Raspberry Pi's UART using a USB-to-TTL adapter to connect to the
Raspberry Pi's GPIO header UART pins. Use a terminal application such as
`screen`. For example:
```
screen /dev/ttyUSB0 115200
```
Turn on/reset your board.
<!--- instruction#3 -->
## 5) Run u-boot commands
Quickly press any key to skip autoboot. If not possibly press `ctrl-c` until
you get the u-boot prompt. Then load the bao image, and jump to it:
```
fatload mmc 0 0x200000 bao.bin; go 0x200000
```
You should see the firmare, bao and its guests printing on the UART.
At this point, depending on your demo, you might be able connect to one of the
guests via ssh by connecting to the board's ethernet RJ54 socket.
<!--- instruction#end -->

View File

@ -0,0 +1,5 @@
enable_uart=1
arm_64bit=1
enable_gic=1
armstub=bl31.bin
kernel=u-boot.bin

25
platforms/rpi4/make.mk Normal file
View File

@ -0,0 +1,25 @@
ARCH:=aarch64
firmware_repo:=https://github.com/raspberrypi/firmware.git
firmware_version:=1.20210201
firmware_images:=$(wrkdir_plat_imgs)/firmware
$(firmware_images):
git clone --depth 1 --branch $(firmware_version) $(firmware_repo) $@
include $(bao_demos)/platforms/uboot.mk
uboot_defconfig:=rpi_4_defconfig
uboot_image:=$(wrkdir_plat_imgs)/u-boot.bin
$(eval $(call build-uboot, $(uboot_image), $(uboot_defconfig)))
atf_image:=$(wrkdir_plat_imgs)/bl31.bin
atf_plat:=rpi4
include $(bao_demos)/platforms/atf.mk
$(eval $(call build-atf, $(atf_image), $(atf_plat)))
instuctions:=$(bao_demos)/platforms/$(PLATFORM)/README.md
platform: $(bao_image) $(uboot_image) $(atf_image) $(firmware_images)
$(call print-instructions, $(instuctions), 1, false)
$(call print-instructions, $(instuctions), 2, false)
$(call print-instructions, $(instuctions), 3, true)

74
platforms/sdcard.md Normal file
View File

@ -0,0 +1,74 @@
## Prepare SD card
First make sure you save all the files currently in the card.
The SD card should be at least.
In this example the sdcard is `/dev/mmcblk0` and the partitions are
`/dev/mmcblk0p1`, `/dev/mmcblk0p2`, etc. Other common names might be TODO.
### i) Make sure all partitions are umounted
```
umount /dev/mmcblk0*
```
### ii) Delete all partitions
```
sudo fdisk /dev/mmcblk0
```
Then run the commands:
* Press `d` until there are no more partitions (if it asks you for the
partition, press `return` for the default)
* Press `w` write changes and exit
### iii) Create partition
```
sudo fdisk /dev/mmcblk0
```
Then run the commands:
* `n` to create a new partition. Select the folowing options:
* `p` to make it a primary partition
* the automatically assined partition number by pressing `return`
* `16384` (this gap is needed for some of the selcted boards)
* the max default size by pressing `return`
* if it asks you to remove the file system signature press `y`
* `a` to make the partition bootbale
* `t` to set the partition type:
* type `c` for W95 FAT32 (LBA)
* `w` to write changes and exit
### iv) Format partition
Format the created partition to a fat filesystem:
```
sudo mkfs.fat /dev/mmcblk0p1 -n boot
```
Remove and insert the sd card to automatically mount it. Setup an environemnt
variable to the mount path:
---
**NOTE**
This guide expects for the sd card mount point to be at **/media/$USER/boot**.
---
Setup environment variables pointing to the sd card device, parition and mount
point, which in our example are:
```
export BAO_DEMOS_SDCARD_DEV=/dev/mmcblk0
export BAO_DEMOS_SDCARD=/media/$USER/boot
```

121
platforms/tx2/README.md Normal file
View File

@ -0,0 +1,121 @@
# Nvidia Tegra TX2
---
**NOTE**
In this guide, we build and flash the TF-A firmware in order to control SMMU
stream ids of peripherals used by some virtual machines, which are not
programmed by default. If you are targeting a demo where no virtual machine
features DMA-capable peripherals (e.g. baremetal demo) you can use the
pre-flashed firmware and skip directly to step 3.
---
## 1) Build TF-A
Download and build TF-A:
```
export BAO_DEMOS_ATF=$BAO_DEMOS_WRKDIR_SRC/arm-trusted-firmware
git clone https://github.com/bao-project/arm-trusted-firmware.git\
$BAO_DEMOS_ATF --depth 1
cd $BAO_DEMOS_ATF
make PLAT=tegra TARGET_SOC=t186 bl31
```
And copy the image to the platform's working directory:
```
cp $BAO_DEMOS_ATF/build/tegra/t186/release/bl31.bin $BAO_DEMOS_WRKDIR_PLAT
```
## 2) Prepare firmware with new TF-A image
For this you will first need to download Nvidia's flashing tools part of the
TX2's [L4T Driver Package (BSP)][tegra-bsp]. Then extract it:
```
export BAO_DEMOS_NVIDIA_TOOLS=$BAO_DEMOS_WRKDIR_SRC/nvidia-tools
mkdir -p $BAO_DEMOS_NVIDIA_TOOLS
wget -P $BAO_DEMOS_NVIDIA_TOOLS/\
https://developer.nvidia.com/embedded/l4t/r32_release_v5.1/\
r32_release_v5.1/t186/tegra186_linux_r32.5.1_aarch64.tbz2
tar xfvm $BAO_DEMOS_NVIDIA_TOOLS/tegra186_linux_r32.5.1_aarch64.tbz2\
-C $BAO_DEMOS_NVIDIA_TOOLS
```
Create the Trusted OS image for the flash tool:
```
$BAO_DEMOS_NVIDIA_TOOLS/Linux_for_Tegra/nv_tegra/tos-scripts/gen_tos_part_img.py\
--monitor $BAO_DEMOS_WRKDIR_PLAT/bl31.bin $BAO_DEMOS_WRKDIR_PLAT/tos.img
```
<!--- instruction#1 -->
## 3) Flash the firmware
Set your board to recovery mode by:
1) Power it off completely. If needed unplug and replug the power cord.
2) Press down the Recovery button. While pressing the Recovery button, press
the Power button. Wait for the board to turn on.
3) Connect to the board using USB through the J28 micro-USB port.
4) Flash the board:
```
cd $BAO_DEMOS_NVIDIA_TOOLS/Linux_for_Tegra
sudo ./flash.sh -k secure-os --image $BAO_DEMOS_WRKDIR_PLAT/tos.img\
--bup jetson-tx2 mmcblk0p1
```
If all goes well you should see the message:
```
*** The [secure-os] has been updated successfully. ***
```
<!--- instruction#2 -->
## 4) Setup SD card
After [preparing your sd card](../../platforms/sdcard.md), copy the firmware
and bao's final image to it:
```
cp $BAO_DEMOS_WRKDIR_IMGS/bao.bin $BAO_DEMOS_SDCARD
umount $BAO_DEMOS_SDCARD
```
<!--- instruction#3 -->
## 5) Setup board
Insert the sd card in the board's sd slot.
Connect to the TX2's UART using a USB-to-TTL adapter. Use a terminal
application such as `screen`. For example:
```
screen /dev/ttyUSB0 115200
```
Turn on/reset your board.
<!--- instruction#4 -->
## 6) Run u-boot commands
You will get u-boot's prompt. Load the bao image, and jump to it:
```
fatload mmc 1 0xa0000000 bao.bin; go 0xa0000000
```
You should see the firmare, bao and its guests printing on the UART.
At this point, depending on your demo, you might be able connect to one of the
guests via ssh by connecting to the board's ethernet RJ54 socket.
<!--- instruction#end -->
<!-- Links -->
[tegra-bsp]: https://developer.nvidia.com/embedded/linux-tegra

34
platforms/tx2/make.mk Normal file
View File

@ -0,0 +1,34 @@
ARCH:=aarch64
atf_image:=$(wrkdir_plat_imgs)/bl31.bin
include $(bao_demos)/platforms/atf.mk
$(atf_image): $(atf_src)
$(MAKE) -C $(atf_src) bl31 PLAT=tegra TARGET_SOC=t186
cp $(atf_src)/build/tegra/t186/release/bl31.bin $@
nvidia_tools:=$(wrkdir_src)/nvidia-tools
nvidia_tools_flash:=$(nvidia_tools)/Linux_for_Tegra/
wrkdirs+=$(nvidia_tools)
nvidia_tools_flash_link:=https://developer.nvidia.com/embedded/l4t/r32_release_v5.1/r32_release_v5.1/t186/tegra186_linux_r32.5.1_aarch64.tbz2
nvidia_tools_flash_ar:=$(nvidia_tools)/tegra186_linux_r32.5.1_aarch64.tbz2
environment+=BAO_DEMOS_NVIDIA_TOOLS=$(nvidia_tools)
$(nvidia_tools_flash_ar):
wget -P $(nvidia_tools) $(nvidia_tools_flash_link)
$(nvidia_tools_flash): $(nvidia_tools_flash_ar)
tar xfvm $(nvidia_tools_flash_ar) -C $(nvidia_tools)
flash_image:=$(wrkdir_plat_imgs)/tos.img
$(flash_image): $(nvidia_tools_flash) $(atf_image)
$(nvidia_tools_flash)/nv_tegra/tos-scripts/gen_tos_part_img.py\
--monitor $(atf_image) $(flash_image)
instructions:=$(bao_demos)/platforms/$(PLATFORM)/README.md
platform: $(bao_image) $(flash_image)
$(call print-instructions, $(instructions), 1, false)
$(call print-instructions, $(instructions), 2, false)
$(call print-instructions, $(instructions), 3, false)
$(call print-instructions, $(instructions), 4, true)

16
platforms/uboot.mk Normal file
View File

@ -0,0 +1,16 @@
uboot_repo:=https://github.com/u-boot/u-boot.git
uboot_version:=2021.01
uboot_src:=$(wrkdir_src)/u-boot
$(uboot_src):
git clone --depth 1 --branch v$(uboot_version) $(uboot_repo) $(uboot_src)
define build-uboot
$(strip $1): $(uboot_src)
$(MAKE) -C $(uboot_src) $(strip $2)
echo $(strip $3) >> $(uboot_src)/.config
$(MAKE) -C $(uboot_src) -j$(nproc)
cp $(uboot_src)/u-boot.bin $$@
endef
u-boot: $(wrkdir_plat_imgs)/u-boot.bin

1
platforms/zcu102 Symbolic link
View File

@ -0,0 +1 @@
zcu104

View File

@ -0,0 +1,90 @@
# Xilinx ZCU10X
<!--- instruction#1 -->
## 1) Get firmware
Download latest pre-built Zynq UltraScale+ MPSoC Firmware for your target
platform (you will need to sign-in to Xilinx account and provide further
personal information) to $BAO_DEMOS_WRKDIR_SRC:
* [ZCU102](https://www.xilinx.com/member/forms/download/xef.html?filename=2020.2-zcu102-release.tar.xz)
* [ZCU104](https://www.xilinx.com/member/forms/download/xef.html?filename=2020.2-zcu104-release.tar.xz)
<!--- instruction#end -->
Extract it to $BAO_DEMOS_WRKDIR_SRC:
```
tar xvfm $BAO_DEMOS_WRKDIR_SRC/2020.2-$PLATFORM-release.tar.xz\
-C $BAO_DEMOS_WRKDIR_PLAT --wildcards "*BOOT.BIN" --strip-components=1
```
Alternatively, you can [build the firmware from scratch][firmware-from-scratch].
## 2) Prepare a U-boot image
Run mkimage to create the final system image:
```
mkimage -n bao_uboot -A arm64 -O linux -C none -T kernel -a 0x200000\
-e 0x200000 -d $BAO_DEMOS_WRKDIR_IMGS/bao.bin $BAO_DEMOS_WRKDIR_IMGS/bao.img
```
<!--- instruction#2 -->
## 3) Setup SD card
After [preparing your sd card](../../platforms/sdcard.md), copy the firmware and
bao's final image to it:
```
cp $BAO_DEMOS_WRKDIR_PLAT/BOOT.BIN $BAO_DEMOS_SDCARD
cp $BAO_DEMOS_WRKDIR_IMGS/bao.img $BAO_DEMOS_SDCARD
umount $BAO_DEMOS_SDCARD
```
<!--- instruction#3 -->
## 4) Setup board
First make sure you have the board configured to boot from the SD card. If you
are not sure how, check the MPSoC Device Configuration section in the board's
User Guide:
- [ZCU102](https://www.xilinx.com/support/documentation/boards_and_kits/zcu102/ug1182-zcu102-eval-bd.pdf)
- [ZCU104](https://www.xilinx.com/support/documentation/boards_and_kits/zcu104/ug1267-zcu104-eval-bd.pdf)
Insert the sd card in the board's sd slot and connect to the baord via the
available micro-USB JTAG/UART port.
Connect to both UARTs available on the zcu (baud 115200). In our setup:
* /dev/ttyUSB1 and /dev/ttyUSB2 for ZCU104
* /dev/ttyUSB0 and /dev/ttyUSB1 for ZCU102
Open a new terminal and connect to it. For example:
```
screen /dev/ttyUSB1 115200
```
Turn on/reset your board.
<!--- instruction#4 -->
## 5) Run u-boot commands
Quickly press any key to skip autoboot. If not possibly press `ctrl-c` until
you get the u-boot prompt. Then load the bao image, and jump to it:
```
fatload mmc 0 0x200000 bao.img; bootm start 0x200000; bootm loados; bootm go
```
You should see the firmare, bao and its guests printing on the UARTs.
At this point, depending on your demo, you might be able connect to one of the
guests via ssh by connecting to the board's ethernet RJ54 socket.
<!--- instruction#end -->
<!-- Links -->
[firmware-from-scratch]: https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841722/ZCU102+Image+creation+in+OSL+flow

21
platforms/zcu104/make.mk Normal file
View File

@ -0,0 +1,21 @@
ARCH:=aarch64
boot_bin:=$(wrkdir_plat_imgs)/BOOT.BIN
prebuilt_images_tar:=$(wrkdir_src)/2020.2-$(PLATFORM)-release.tar.xz
instuctions:=$(bao_demos)/platforms/$(PLATFORM)/README.md
bao_uboot_image:=$(wrkdir_demo_imgs)/bao.img
$(prebuilt_images_tar):
$(call print-instructions, $(instuctions), 1, false)
$(boot_bin): $(prebuilt_images_tar)
@tar xfvm $< -C $(dir $@) --wildcards "*BOOT.BIN" --strip-components=1
$(bao_uboot_image): $(bao_image)
@mkimage -n bao_uboot -A arm64 -O linux -C none -T kernel -a 0x200000\
-e 0x200000 -d $(bao_image) $@
platform: $(bao_image) $(boot_bin) $(bao_uboot_image)
$(call print-instructions, $(instuctions), 2, false)
$(call print-instructions, $(instuctions), 3, false)
$(call print-instructions, $(instuctions), 4, true)